diff options
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/lume/lume.go | 63 | ||||
| -rw-r--r-- | internal/lume/zip.go | 68 |
2 files changed, 97 insertions, 34 deletions
diff --git a/internal/lume/lume.go b/internal/lume/lume.go index f4fc20b..8188488 100644 --- a/internal/lume/lume.go +++ b/internal/lume/lume.go @@ -1,11 +1,13 @@ package lume import ( + "archive/zip" "context" "encoding/json" "expvar" "fmt" "html/template" + "io" "io/fs" "log" "log/slog" @@ -28,13 +30,9 @@ var ( typstLocation string dhallToJSONLocation string - _ fs.FS = (*FS)(nil) - _ fs.ReadFileFS = (*FS)(nil) - _ fs.ReadDirFS = (*FS)(nil) + _ fs.FS = (*FS)(nil) opens = metrics.LabelMap{Label: "name"} - readFiles = metrics.LabelMap{Label: "name"} - readDirs = metrics.LabelMap{Label: "name"} builds = expvar.NewInt("gauge_xesite_builds") updates = expvar.NewInt("gauge_xesite_updates") updateErrors = expvar.NewInt("gauge_xesite_update_errors") @@ -59,8 +57,6 @@ func init() { } expvar.Publish("gauge_xesite_opens", &opens) - expvar.Publish("gauge_xesite_read_files", &readFiles) - expvar.Publish("gauge_xesite_read_dirs", &readDirs) } type FS struct { @@ -72,13 +68,17 @@ type FS struct { miClient *mi.Client fs fs.FS - lock sync.RWMutex + lock sync.Mutex } func (f *FS) Close() error { f.lock.Lock() defer f.lock.Unlock() + if cl, ok := f.fs.(io.Closer); ok { + cl.Close() + } + if f.repo != nil { os.RemoveAll(f.repoDir) } @@ -87,34 +87,11 @@ func (f *FS) Close() error { } func (f *FS) Open(name string) (fs.File, error) { - f.lock.RLock() - defer f.lock.RUnlock() - opens.Add(name, 1) return f.fs.Open(name) } -func (f *FS) ReadDir(name string) ([]fs.DirEntry, error) { - f.lock.RLock() - defer f.lock.RUnlock() - - readDirs.Add(name, 1) - - rdfs := f.fs.(fs.ReadDirFS) - return rdfs.ReadDir(name) -} - -func (f *FS) ReadFile(name string) ([]byte, error) { - f.lock.RLock() - defer f.lock.RUnlock() - - readFiles.Add(name, 1) - - rfs := f.fs.(fs.ReadFileFS) - return rfs.ReadFile(name) -} - type Options struct { Development bool Branch string @@ -270,12 +247,30 @@ func (f *FS) build(ctx context.Context) error { return err } - f.fs = os.DirFS(destDir) dur := time.Since(begin) lastBuildTime.Set(dur.Milliseconds()) slog.Info("built site", "dir", destDir, "time", dur.String()) + zipLoc := filepath.Join(f.opt.DataDir, "site.zip") + + if err := ZipFolder(filepath.Join(cmd.Dir, "_site"), zipLoc); err != nil { + return fmt.Errorf("lume: can't compress site folder: %w", err) + } + + if cl, ok := f.fs.(io.Closer); f.fs != nil && ok { + if err := cl.Close(); err != nil { + slog.Error("failed to close old fs", "err", err) + } + } + + fs, err := zip.OpenReader(zipLoc) + if err != nil { + return fmt.Errorf("lume: can't open zip with site content: %w", err) + } + + f.fs = fs + return nil } @@ -348,8 +343,8 @@ func (f *FS) writeConfig() error { } func (f *FS) Clacks() []string { - f.lock.RLock() - defer f.lock.RUnlock() + f.lock.Lock() + defer f.lock.Unlock() return f.conf.ClackSet } diff --git a/internal/lume/zip.go b/internal/lume/zip.go new file mode 100644 index 0000000..b3b331f --- /dev/null +++ b/internal/lume/zip.go @@ -0,0 +1,68 @@ +package lume + +import ( + "archive/zip" + "io" + "os" + "path/filepath" +) + +// ZipFolder takes a source folder and a target zip file name +// and compresses the folder contents into the zip file +func ZipFolder(source, target string) error { + // Create a zip file + fout, err := os.Create(target) + if err != nil { + return err + } + defer fout.Close() + + // Create a zip writer + w := zip.NewWriter(fout) + defer w.Close() + + // Walk through the source folder + return filepath.Walk(source, func(path string, info os.FileInfo, err error) error { + // Handle errors + if err != nil { + return err + } + + // Skip directories + if info.IsDir() { + return nil + } + + // Open the file + file, err := os.Open(path) + if err != nil { + return err + } + defer file.Close() + + // Create a header from the file info + header, err := zip.FileInfoHeader(info) + if err != nil { + return err + } + + // Set the compression method to deflate + header.Method = zip.Deflate + + // Set the header name to the relative path of the file + header.Name, err = filepath.Rel(source, path) + if err != nil { + return err + } + + // Create a fout for the file header + fout, err := w.CreateHeader(header) + if err != nil { + return err + } + + // Copy the file contents to the writer + _, err = io.Copy(fout, file) + return err + }) +} |
