Files
lst/controller/zip_app.go

100 lines
2.3 KiB
Go

package main
import (
"archive/zip"
"bufio"
"fmt"
"io"
"io/fs"
"os"
"path/filepath"
"strings"
)
// ---- Load ignore patterns ----
func loadIncludePatterns(file string) ([]string, error) {
f, err := os.Open(file)
if err != nil {
return nil, err
}
defer f.Close()
var patterns []string
scanner := bufio.NewScanner(f)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
if line == "" || strings.HasPrefix(line, "#") {
continue
}
patterns = append(patterns, filepath.ToSlash(filepath.Clean(line)))
}
return patterns, scanner.Err()
}
// ---- Simple matcher ----
// (Later swap for github.com/sabhiram/go-gitignore lib for proper rules)
func shouldInclude(path string, includes []string) bool {
cleanPath := filepath.ToSlash(filepath.Clean(path)) // normalize to forward slashes
for _, pat := range includes {
p := filepath.ToSlash(filepath.Clean(pat))
// exact match (file or folder)
if cleanPath == p {
return true
}
// if p is a folder, include all paths under it
if strings.HasPrefix(cleanPath, p+"/") {
return true
}
}
return false
}
// ---- Zip the repo ----
func zipProject(srcDir, zipFile string, includes []string) error {
outFile, err := os.Create(zipFile)
if err != nil {
return err
}
defer outFile.Close()
archive := zip.NewWriter(outFile)
defer archive.Close()
err = filepath.WalkDir(srcDir, func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() {
return nil
}
relPath, _ := filepath.Rel(srcDir, path)
if !shouldInclude(relPath, includes) {
return nil // skip anything not explicitly included
}
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
info, _ := file.Stat()
header, _ := zip.FileInfoHeader(info)
header.Name = relPath
writer, err := archive.CreateHeader(header)
if err != nil {
return err
}
_, err = io.Copy(writer, file)
fmt.Println("Added:", relPath)
return err
})
return err
}