From d77bbe05b0ad6f6d76e8a158cc47588a15070fab Mon Sep 17 00:00:00 2001 From: ross-spencer Date: Sat, 3 Aug 2024 13:37:39 +0200 Subject: [PATCH 1/2] Make directories if not exist Roy needs to be able to access a nested set of directories. If they don't exist, roy errors. We can mirror `mkdir -p` (create parents if not exist) with `MkDirAll(...)`. --- cmd/roy/roy.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/roy/roy.go b/cmd/roy/roy.go index 00f1829b2..ce83f73b3 100644 --- a/cmd/roy/roy.go +++ b/cmd/roy/roy.go @@ -200,7 +200,7 @@ var ( func savereps() error { file, err := os.Open(config.Reports()) if err != nil { - err = os.Mkdir(config.Reports(), os.ModePerm) + err = os.MkdirAll(config.Reports(), os.ModePerm) if err != nil { return fmt.Errorf("roy: error making reports directory %s", err) } From f66bd70cda39a8e386d759fb3516d04d00143423 Mon Sep 17 00:00:00 2001 From: ross-spencer Date: Sat, 3 Aug 2024 15:15:53 +0200 Subject: [PATCH 2/2] Improve handling of droidXML config A number of calls are made to retrieve the default location of the DROID signature file dynamically. These are turned into a single call in the app init. Further, there is a bit more feedback during harvest to provide the user with more info when a DROID signature file does not exist. --- cmd/roy/roy.go | 25 ++++++++++++++++--------- pkg/pronom/pronom.go | 10 ++++++++-- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/cmd/roy/roy.go b/cmd/roy/roy.go index ce83f73b3..cc3c53791 100644 --- a/cmd/roy/roy.go +++ b/cmd/roy/roy.go @@ -116,11 +116,18 @@ Additional flags: Use a different siegfried home directory. ` +var discoveredDroidFile string + +func init() { + // Retrieve our dynamic defaults. + discoveredDroidFile = config.Droid() +} + var ( // BUILD, ADD flag sets build = flag.NewFlagSet("build | add", flag.ExitOnError) home = build.String("home", config.Home(), "override the default home directory") - droid = build.String("droid", config.Droid(), "set name/path for DROID signature file") + droid = build.String("droid", discoveredDroidFile, "set name/path for DROID signature file") mi = build.String("mi", "", "set name/path for MIMEInfo signature file") fdd = build.String("fdd", "", "set name/path for LOC FDD signature file") locfdd = build.Bool("loc", false, "build a LOC FDD signature file") @@ -158,7 +165,7 @@ var ( // HARVEST harvest = flag.NewFlagSet("harvest", flag.ExitOnError) harvestHome = harvest.String("home", config.Home(), "override the default home directory") - harvestDroid = harvest.String("droid", config.Droid(), "set name/path for DROID signature file") + harvestDroid = harvest.String("droid", discoveredDroidFile, "set name/path for DROID signature file") harvestChanges = harvest.Bool("changes", false, "harvest the latest PRONOM release-notes.xml file") _, htimeout, _, _ = config.HarvestOptions() timeout = harvest.Duration("timeout", htimeout, "set duration before timing-out harvesting requests e.g. 120s") @@ -171,7 +178,7 @@ var ( // INSPECT (roy inspect | roy inspect fmt/121 | roy inspect usr/local/mysig.sig | roy inspect 10) inspect = flag.NewFlagSet("inspect", flag.ExitOnError) inspectHome = inspect.String("home", config.Home(), "override the default home directory") - inspectDroid = inspect.String("droid", config.Droid(), "set name/path for DROID signature file") + inspectDroid = inspect.String("droid", discoveredDroidFile, "set name/path for DROID signature file") inspectReports = inspect.Bool("reports", false, "build signatures from PRONOM reports (rather than DROID xml)") inspectExtend = inspect.String("extend", "", "comma separated list of additional signatures") inspectExtendc = inspect.String("extendc", "", "comma separated list of additional container signatures") @@ -188,7 +195,7 @@ var ( // SETS setsf = flag.NewFlagSet("sets", flag.ExitOnError) setsHome = setsf.String("home", config.Home(), "override the default home directory") - setsDroid = setsf.String("droid", config.Droid(), "set name/path for DROID signature file") + setsDroid = setsf.String("droid", discoveredDroidFile, "set name/path for DROID signature file") setsChanges = setsf.Bool("changes", false, "create a pronom-changes.json sets file") setsList = setsf.String("list", "", "expand comma separated list of format sets") @@ -208,7 +215,7 @@ func savereps() error { file.Close() errs := pronom.Harvest() if len(errs) > 0 { - return fmt.Errorf("roy: errors saving reports to disk %s", errs) + return fmt.Errorf("roy: error saving reports to disk %s", errs) } return nil } @@ -332,7 +339,7 @@ func viewReleases() error { func getOptions() []config.Option { opts := []config.Option{} // build options - if *droid != config.Droid() { + if *droid != discoveredDroidFile { opts = append(opts, config.SetDroid(*droid)) } if *container != config.Container() { @@ -442,7 +449,7 @@ the DROID signature file you should also include a regular signature extension opts = append(opts, config.SetVerbose(!*quiet)) // do the opposite, because the flag is quiet and the setting is verbose! } // inspect options - if *inspectDroid != config.Droid() { + if *inspectDroid != discoveredDroidFile { opts = append(opts, config.SetDroid(*inspectDroid)) } if *inspectMI != "" { @@ -485,7 +492,7 @@ the DROID signature file you should also include a regular signature extension } func setHarvestOptions() { - if *harvestDroid != config.Droid() { + if *harvestDroid != discoveredDroidFile { config.SetDroid(*harvestDroid)() } if *harvestHome != config.Home() { @@ -510,7 +517,7 @@ func setHarvestOptions() { } func setSetsOptions() { - if *setsDroid != config.Droid() { + if *setsDroid != discoveredDroidFile { config.SetDroid(*setsDroid)() } if *setsHome != config.Home() { diff --git a/pkg/pronom/pronom.go b/pkg/pronom/pronom.go index 083b8afa2..0f436b514 100644 --- a/pkg/pronom/pronom.go +++ b/pkg/pronom/pronom.go @@ -20,6 +20,7 @@ import ( "encoding/xml" "fmt" "io/ioutil" + "log" "net/http" "os" "path/filepath" @@ -138,7 +139,7 @@ func (p *pronom) setParseables() error { func newDroid(path string) (*droid, error) { d := &mappings.Droid{} if err := openXML(path, d); err != nil { - return nil, err + return nil, fmt.Errorf("%W: %s", err, path) } return &droid{d, identifier.Blank{}}, nil } @@ -195,7 +196,12 @@ func (p *pronom) setContainers() error { // UTILS // Harvest fetches PRONOM reports listed in the DROID file func Harvest() []error { - d, err := newDroid(config.Droid()) + droidXML := config.Droid() + if droidXML == "" { + return []error{fmt.Errorf("a DROID signature file needs to be downloaded to %s", config.Home())} + } + log.Println("roy: harvesting PRONOM reports for records listed in DROID XML:", droidXML) + d, err := newDroid(droidXML) if err != nil { return []error{err} }