diff --git a/cmd/rehash.go b/cmd/rehash.go new file mode 100644 index 0000000..0019d70 --- /dev/null +++ b/cmd/rehash.go @@ -0,0 +1,93 @@ +package cmd + +import ( + "fmt" + "os" + + "github.com/packwiz/packwiz/core" + "github.com/spf13/cobra" + "golang.org/x/exp/slices" +) + +// rehashCmd represents the rehash command +var rehashCmd = &cobra.Command{ + Use: "rehash", + Short: "Migrate all hashes to a specific function", + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + + // Load pack + pack, err := core.LoadPack() + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + // Load index + index, err := pack.LoadIndex() + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + // Load mods + mods, err := index.LoadAllMods() + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + if !slices.Contains([]string{"sha1", "sha512", "sha256"}, args[0]) { + fmt.Printf("Hash format '%s' is not supported\n", args[0]) + os.Exit(1) + } + + session, err := core.CreateDownloadSession(mods, []string{args[0]}) + if err != nil { + fmt.Printf("Error retrieving external files: %v\n", err) + os.Exit(1) + } + for dl := range session.StartDownloads() { + if dl.Error != nil { + fmt.Printf("Error retrieving %s: %v\n", dl.Mod.Name, dl.Error) + } else { + dl.Mod.Download.HashFormat = args[0] + dl.Mod.Download.Hash = dl.Hashes[args[0]] + _, _, err := dl.Mod.Write() + if err != nil { + fmt.Printf("Error saving mod %s: %v\n", dl.Mod.Name, err) + os.Exit(1) + } + } + // TODO pass the hash to index instead of recomputing from scratch + } + + err = index.Refresh() + if err != nil { + fmt.Printf("Error refreshing index: %v\n", err) + os.Exit(1) + } + + err = index.Write() + if err != nil { + fmt.Printf("Error writing index: %v\n", err) + os.Exit(1) + } + + err = pack.UpdateIndexHash() + if err != nil { + fmt.Printf("Error updating index hash: %v\n", err) + os.Exit(1) + } + + err = pack.Write() + if err != nil { + fmt.Printf("Error writing pack: %v\n", err) + os.Exit(1) + } + }, +} + +func init() { + rootCmd.AddCommand(rehashCmd) +} diff --git a/modrinth/modrinth.go b/modrinth/modrinth.go index fa38bbc..71fb7b3 100644 --- a/modrinth/modrinth.go +++ b/modrinth/modrinth.go @@ -361,12 +361,9 @@ func shouldDownloadOnSide(side string) bool { } func getBestHash(v *modrinthApi.File) (string, string) { - // Try preferred hashes first; SHA1 is first as it is required for Modrinth pack exporting - val, exists := v.Hashes["sha1"] - if exists { - return "sha1", val - } - val, exists = v.Hashes["sha512"] + // Try preferred hashes first; SHA1 is required for Modrinth pack exporting, but + // so is SHA512, so we can't win with the current one-hash format + val, exists := v.Hashes["sha512"] if exists { return "sha512", val } @@ -374,6 +371,10 @@ func getBestHash(v *modrinthApi.File) (string, string) { if exists { return "sha256", val } + val, exists = v.Hashes["sha1"] + if exists { + return "sha1", val + } val, exists = v.Hashes["murmur2"] // (not defined in Modrinth pack spec, use with caution) if exists { return "murmur2", val