diff --git a/README.md b/README.md index 7993924..5526726 100644 --- a/README.md +++ b/README.md @@ -205,7 +205,19 @@ If you want to use your own, specify it with the `--datfile` flag. ``` $ rom64 validate ~/Downloads/n64/Tsumi\ to\ Batsu\ -\ Hoshi\ no\ Keishousha\ \(Japan\).z64 Found 1 datfile entries for ROM serial 'NGUJ' - SHA-1 MATCH 581297B9D5C3A4C33169AE0AAE218C742CD9CBCF Tsumi to Batsu - Hoshi no Keishousha (Japan).z64 +SHA-1 MATCH 581297B9D5C3A4C33169AE0AAE218C742CD9CBCF "Tsumi to Batsu - Hoshi no Keishousha (Japan).z64" +``` + +#### `--rename-validated` + +With this flag, after a ROM's hash has been validated against the datfile, the ROM file will +be renamed to match what's in the datfile, if it doesn't already. + +``` +$ rom64 validate --rename-validated sm64.z64 +Found 1 datfile entries for ROM serial 'NSME' +SHA-1 MATCH 9BEF1128717F958171A4AFAC3ED78EE2BB4E86CE "Super Mario 64 (USA).z64" +Renaming "sm64.z64" => "Super Mario 64 (USA).z64" ``` [dat-o-matic]: https://datomatic.no-intro.org/index.php?page=download&s=24&op=dat diff --git a/cmd/validate.go b/cmd/validate.go index f9c78da..bc41fac 100644 --- a/cmd/validate.go +++ b/cmd/validate.go @@ -2,6 +2,8 @@ package cmd import ( "fmt" + "os" + "path" "github.com/mroach/rom64/dat" "github.com/mroach/rom64/rom" @@ -9,6 +11,7 @@ import ( ) var datFilePath string +var renameValidated bool func init() { var validateCmd = &cobra.Command{ @@ -16,12 +19,12 @@ func init() { Short: "Validate the hash of a ROM against a known-good list", Args: cobra.MinimumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - path := args[0] + romFilePath := args[0] var df dat.DatFile var err error - romfile, err := rom.FromPath(path) + romfile, err := rom.FromPath(romFilePath) if err != nil { return err } @@ -44,26 +47,58 @@ func init() { return err } - fmt.Printf("Found %d datfile entries for ROM serial '%s'\n", len(matches), romfile.Serial()) + var matchCount = len(matches) - if len(matches) > 0 { - for _, match := range matches { - fmt.Printf(" %-5s \033[32m%-6s\033[0m %40s %s\n", "SHA-1", "MATCH", match.SHA1, match.Name) + if matchCount == 0 { + fmt.Println("Could not find a checksum match.") + fmt.Printf("File '%s' has SHA-1 %s", romfile.File.Name, romfile.File.SHA1) + fmt.Println("The datfile has the following entries for this ROM:") + for _, mismatch := range mismatches { + fmt.Printf(" %-5s %50s %s", "SHA-1\n", mismatch.SHA1, mismatch.Name) } - return nil + return fmt.Errorf("%s validation failed", romFilePath) } - fmt.Println("Could not find a checksum match.") - fmt.Printf("File '%s' has SHA-1 %s", romfile.File.Name, romfile.File.SHA1) - fmt.Println("The datfile has the following entries for this ROM:") - for _, mismatch := range mismatches { - fmt.Printf(" %-5s %50s %s", "SHA-1", mismatch.SHA1, mismatch.Name) + fmt.Printf("Found %d datfile entries for ROM serial '%s'\n", matchCount, romfile.Serial()) + + for _, match := range matches { + fmt.Printf("%-5s \033[32m%-6s\033[0m %40s \"%s\"\n", "SHA-1", "MATCH", match.SHA1, match.Name) + } + + if matchCount > 1 { + return fmt.Errorf("Multiple datfile entries found with the same SHA-1 hash. This shouldn't happen. Aborting.") + } + + var match = matches[0] + + if renameValidated { + var correctName = match.Name + if romfile.File.Name == correctName { + fmt.Printf("ROM file already has the correct name \"%s\"\n", correctName) + return nil + } + + var sourcePath = romfile.File.Path + var newPath = path.Join(path.Dir(sourcePath), correctName) + + fmt.Printf("Renaming \"%s\" => \"%s\"\n", romfile.File.Path, newPath) + + if _, err := os.Stat(newPath); err == nil { + return fmt.Errorf("Destination file \"%s\" already exists. Aborting.", newPath) + } + + err = os.Rename(sourcePath, newPath) + if err != nil { + return err + } } - return fmt.Errorf("%s validation failed", path) + + return nil }, } validateCmd.Flags().StringVarP(&datFilePath, "datfile", "d", "", "Load custom DAT file (XML format)") + validateCmd.Flags().BoolVarP(&renameValidated, "rename-validated", "", false, "Rename validated files to match the filename in the datefile.") rootCmd.AddCommand(validateCmd) }