100 lines
2.3 KiB
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
|
|
}
|