From 40224316b975ae6339c2921cdcc727df5fbdfd1c Mon Sep 17 00:00:00 2001 From: Christof Laenzlinger <6319634+laenzlinger@users.noreply.github.com> Date: Mon, 20 May 2024 21:41:30 +0200 Subject: [PATCH] Clean also generated pdf files (#42) * Clean also generated pdf files * Fix missing error check * docs: adapt command docs * Refactoring: extract file extensions into constants --- Makefile | 6 ++-- README.md | 2 +- cmd/clean.go | 8 +++-- docs/setlist.md | 2 +- docs/setlist_clean.md | 3 +- internal/sheet/sheet.go | 66 ++++++++++++++++++++++++++++------------- 6 files changed, 58 insertions(+), 29 deletions(-) diff --git a/Makefile b/Makefile index c02f7e5..99e7004 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,7 @@ test: ## run tests go test ./... test-integration: clean docker-build ## run integration tests + $(RUN) clean $(RUN) generate sheet --all $(RUN) generate sheet $(RUN) generate list --landscape @@ -35,12 +36,9 @@ lint: ## lint source code clean: ## clean all output files rm -f setlist rm -rf dist - rm -f test/Repertoire/Band/Songs/Frankie\ and\ Johnnie.pdf - rm -f test/Repertoire/Band/Songs/Her\ Song.pdf go clean -testcache - $(RUN) clean -docker-build: build +docker-build: build ## build the ocker container docker build -t $(DOCKER_IMAGE):latest . help: diff --git a/README.md b/README.md index 6a6f25a..50d2e92 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ Repertoire Metadata is maintained in a Markdown [GFM table](https://github.github.com/gfm/#tables-extension-) on the top level -of the Repertoire.md file. See [example]{test/Repertoire/Band/Repertoire.md). +of the Repertoire.md file. See [example](test/Repertoire/Band/Repertoire.md). The Table must have a header row. The only mandatory column is the `Title` column which is used to refer to the song titles diff --git a/cmd/clean.go b/cmd/clean.go index 956947c..d034c5d 100644 --- a/cmd/clean.go +++ b/cmd/clean.go @@ -20,21 +20,25 @@ import ( "os" "github.com/laenzlinger/setlist/internal/config" + "github.com/laenzlinger/setlist/internal/sheet" "github.com/spf13/cobra" ) //nolint:gochecknoglobals // cobra is designed like this var cleanCmd = &cobra.Command{ Use: "clean", - Short: "Clean the target directory", + Short: "Clean generated files.", Long: `The target directory and all its contents will be deleted. + In addtition, all genereted pdf sheets are also deleted. `, Run: func(_ *cobra.Command, _ []string) { os.RemoveAll(config.Target()) + err := sheet.Clean(config.NewBand()) + cobra.CheckErr(err) }, } -//nolint:gochecknoinits // cobra is desigend like this +//nolint:gochecknoinits // cobra is designed like this func init() { rootCmd.AddCommand(cleanCmd) } diff --git a/docs/setlist.md b/docs/setlist.md index 9be5b87..3afd9ff 100644 --- a/docs/setlist.md +++ b/docs/setlist.md @@ -18,6 +18,6 @@ Generate Cheat Sheet or Setlist out of repertoire based on Markdown and PDF file ### SEE ALSO -* [setlist clean](setlist_clean.md) - Clean the target directory +* [setlist clean](setlist_clean.md) - Clean generated files. * [setlist generate](setlist_generate.md) - Generate output diff --git a/docs/setlist_clean.md b/docs/setlist_clean.md index 1cc7750..1d8be92 100644 --- a/docs/setlist_clean.md +++ b/docs/setlist_clean.md @@ -1,10 +1,11 @@ ## setlist clean -Clean the target directory +Clean generated files. ### Synopsis The target directory and all its contents will be deleted. + In addtition, all genereted pdf sheets are also deleted. ``` diff --git a/internal/sheet/sheet.go b/internal/sheet/sheet.go index 044b9e1..331de97 100644 --- a/internal/sheet/sheet.go +++ b/internal/sheet/sheet.go @@ -10,6 +10,7 @@ import ( "os" "os/exec" "path/filepath" + "slices" "sort" "strings" @@ -24,6 +25,12 @@ import ( "github.com/yuin/goldmark/renderer/html" ) +const ( + extPDF = ".pdf" + extODT = ".odt" + extMD = ".md" +) + type Sheet struct { band config.Band name string @@ -32,34 +39,53 @@ type Sheet struct { } func AllForBand(band config.Band) error { - songs := map[string]bool{} + songNames, err := songNames(band, []string{extPDF, extODT, extMD}) + if err != nil { + return err + } + sheets := []Sheet{} + for _, title := range songNames { + s := Sheet{band: band, name: title, content: title} + sheets = append(sheets, s) + } + return merge(sheets, fmt.Sprintf("for all %s songs", band.Name)) +} + +func Clean(band config.Band) error { + songNames, err := songNames(band, []string{extODT, extMD}) + if err != nil { + return err + } + for _, title := range songNames { + s := Sheet{band: band, name: title} + os.Remove(s.pdfFilePath()) + } + return nil +} + +func songNames(band config.Band, extensions []string) ([]string, error) { + songNames := []string{} aSheet := Sheet{band: band} files, err := os.ReadDir(aSheet.sourceDir()) if err != nil { - return fmt.Errorf("failed to list Band directory: %w", err) + return songNames, fmt.Errorf("failed to list Band directory: %w", err) } + songs := map[string]bool{} for _, file := range files { - extraw := filepath.Ext(file.Name()) - ext := strings.ToLower(extraw) - if !file.IsDir() && (ext == ".pdf" || ext == ".odt" || ext == ".md") { + ext := filepath.Ext(file.Name()) + if !file.IsDir() && (slices.Contains(extensions, ext)) { songs[strings.TrimSuffix(filepath.Base(file.Name()), ext)] = true } } if len(songs) == 0 { - return fmt.Errorf("no songs found in %s", aSheet.sourceDir()) + return songNames, fmt.Errorf("no songs found in %s", aSheet.sourceDir()) } - songNames := []string{} for song := range songs { songNames = append(songNames, song) } sort.Strings(songNames) - sheets := []Sheet{} - for _, title := range songNames { - s := Sheet{band: band, name: title, content: title} - sheets = append(sheets, s) - } - return merge(sheets, fmt.Sprintf("for all %s songs", band.Name)) + return songNames, nil } const SectionPrefix = "SECTION:" @@ -113,7 +139,7 @@ func merge(sheets []Sheet, outputFileName string) error { } tmpl.PrepareTarget() - target := filepath.Join(config.Target(), fmt.Sprintf("Cheat Sheet %v.pdf", outputFileName)) + target := filepath.Join(config.Target(), fmt.Sprintf("Cheat Sheet %v%s", outputFileName, extPDF)) err := pdf.MergeCreateFile(files, target, false, nil) if err != nil { @@ -170,7 +196,7 @@ func (s *Sheet) ensurePdf() error { } func (s *Sheet) generateFromOdt() error { - log.Printf("generate from odt source for `%s`", s.name) + log.Printf("generate from %s source for `%s`", extODT, s.name) buf := bytes.NewBuffer([]byte{}) args := []string{"--headless", "--convert-to", "pdf", "--outdir", s.sourceDir(), s.odtFilePath()} if config.RunningInContainer() { @@ -189,7 +215,7 @@ func (s *Sheet) generateFromOdt() error { } func (s *Sheet) generateFromMarkdown() error { - log.Printf("generate from markdown source for `%s`", s.name) + log.Printf("generate from %s source for `%s`", extMD, s.name) file, err := os.Open(s.mdFilePath()) if err != nil { @@ -233,15 +259,15 @@ func (s *Sheet) generateFromMarkdown() error { } func (s *Sheet) pdfFilePath() string { - return filepath.Join(s.pdfDir(), s.name+".pdf") + return filepath.Join(s.pdfDir(), s.name+extPDF) } func (s *Sheet) odtFilePath() string { - return filepath.Join(s.sourceDir(), s.name+".odt") + return filepath.Join(s.sourceDir(), s.name+extODT) } func (s *Sheet) mdFilePath() string { - return filepath.Join(s.sourceDir(), s.name+".md") + return filepath.Join(s.sourceDir(), s.name+extMD) } func (s *Sheet) pdfDir() string { @@ -282,7 +308,7 @@ func cleanupBookmarks(source string) error { var currentSection *pdfcpu.Bookmark for i := range bms { sectionStart := strings.HasPrefix(bms[i].Title, SectionPrefix) - bms[i].Title = strings.TrimPrefix(strings.TrimSuffix(bms[i].Title, ".pdf"), SectionPrefix) + bms[i].Title = strings.TrimPrefix(strings.TrimSuffix(bms[i].Title, extPDF), SectionPrefix) if sectionStart { partitioned = true