A small application to manage Lilypond music repositories

Structures output of the scores

+40 -19
+14 -7
compiler/compile.go
··· 46 46 ) 47 47 switch filepath.Ext(scores[i].Path) { 48 48 case ".ly": 49 - msg, err = Lilypond(scores[i].Path) 49 + msg, err = Lilypond(&scores[i]) 50 50 case ".pdf": 51 - if helpers.Exists(scores[i].OutputPath) { 52 - os.Remove(scores[i].OutputPath) 53 - } 54 - if err == nil { 55 - err = os.Link(scores[i].Path, scores[i].OutputPath) 56 - } 51 + err = linkPDF(&scores[i]) 57 52 } 58 53 59 54 if err != nil { ··· 108 103 return nil 109 104 } 110 105 } 106 + 107 + func linkPDF(s *settings.Score) (err error) { 108 + err = helpers.ExistsOrCreate(filepath.Dir(s.OutputPath)) 109 + if err != nil { 110 + return err 111 + } 112 + if helpers.Exists(s.OutputPath) { 113 + os.Remove(s.OutputPath) 114 + } 115 + err = os.Link(s.Path, s.OutputPath) 116 + return 117 + }
+11 -11
compiler/lilypond.go
··· 15 15 package compiler 16 16 17 17 import ( 18 - "os" 19 18 "os/exec" 19 + "path/filepath" 20 20 21 21 log "github.com/Sirupsen/logrus" 22 22 "github.com/jjdekker/ponder/helpers" ··· 37 37 } 38 38 lilypondArgs = append(lilypondArgs, "--loglevel=ERROR") 39 39 lilypondArgs = append(lilypondArgs, "--pdf") 40 - 41 - lilypondArgs = append(lilypondArgs, "--output="+opts.OutputDir) 42 - if !helpers.Exists(opts.OutputDir) { 43 - log.WithFields(log.Fields{"path": opts.OutputDir}).Info("creating output directory") 44 - err := os.MkdirAll(opts.OutputDir, os.ModePerm) 45 - helpers.Check(err, "Could not create output directory") 46 - } 47 40 } 48 41 49 42 // Lilypond runs the lilypond compiler on the given path 50 43 // using the arguments prepared by the PrepareLilypond function 51 - func Lilypond(path string) (string, error) { 52 - cmd := exec.Command(lilypondCmd, append(lilypondArgs, path)...) 44 + func Lilypond(s *settings.Score) (string, error) { 45 + args := append(lilypondArgs, "--output="+filepath.Dir(s.OutputPath)) 46 + err := helpers.ExistsOrCreate(filepath.Dir(s.OutputPath)) 47 + if err != nil { 48 + return "", err 49 + } 50 + args = append(args, s.Path) 51 + 52 + cmd := exec.Command(lilypondCmd, args...) 53 53 log.WithFields(log.Fields{ 54 - "path": path, 54 + "path": s.Path, 55 55 "cmd": cmd, 56 56 }).Info("compiling file using lilypond") 57 57 out, err := cmd.CombinedOutput()
+9
helpers/file_utils.go
··· 55 55 return false 56 56 } 57 57 58 + // ExistsOrCreate will create a directory unless it already Exists 59 + func ExistsOrCreate(path string) (err error) { 60 + if !Exists(path) { 61 + log.WithFields(log.Fields{"path": path}).Info("creating directory") 62 + err = os.MkdirAll(path, os.ModePerm) 63 + } 64 + return 65 + } 66 + 58 67 // LastModified returns the time the file on the path was last modified, 59 68 // if file lookup fails the current time is returned. 60 69 func LastModified(path string) time.Time {
+5 -1
settings/score.go
··· 141 141 return 142 142 } 143 143 file = file[:dot+1] + "pdf" 144 - s.OutputPath = filepath.Join(opts.OutputDir, file) 144 + s.OutputPath = opts.OutputDir 145 + if !opts.FlatOutputDir && len(s.Categories) > 0 { 146 + s.OutputPath = filepath.Join(s.OutputPath, s.Categories[0]) 147 + } 148 + s.OutputPath = filepath.Join(s.OutputPath, file) 145 149 } 146 150 147 151 // Scores aliases a slice of scores
+1
settings/settings.go
··· 38 38 BookScoreTempl string // Override for the partial book template placing scores 39 39 LatexResources []string // Files to be copied to compile the book template 40 40 KeepBookTemplate bool // Leave the LaTeX source for the book in the output directory 41 + FlatOutputDir bool // Keep all output file in a flat output directory 41 42 } 42 43 43 44 // FromFile reads a settings file in json format and returns the Settings struct