Reword "mod"/"addon"/"install" to clearer terms across all commands (fixes #138)

This commit is contained in:
comp500 2023-01-20 18:39:23 +00:00
parent eee067964a
commit 79d3ed3957
11 changed files with 57 additions and 67 deletions

View File

@ -11,14 +11,10 @@ import (
// removeCmd represents the remove command // removeCmd represents the remove command
var removeCmd = &cobra.Command{ var removeCmd = &cobra.Command{
Use: "remove", Use: "remove",
Short: "Remove a mod from the modpack", Short: "Remove an external file from the modpack; equivalent to manually removing the file and running packwiz refresh",
Aliases: []string{"delete", "uninstall", "rm"}, Aliases: []string{"delete", "uninstall", "rm"},
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
if len(args[0]) == 0 {
fmt.Println("You must specify a mod.")
os.Exit(1)
}
fmt.Println("Loading modpack...") fmt.Println("Loading modpack...")
pack, err := core.LoadPack() pack, err := core.LoadPack()
if err != nil { if err != nil {
@ -32,7 +28,7 @@ var removeCmd = &cobra.Command{
} }
resolvedMod, ok := index.FindMod(args[0]) resolvedMod, ok := index.FindMod(args[0])
if !ok { if !ok {
fmt.Println("You don't have this mod installed.") fmt.Println("Can't find this file; please ensure you have run packwiz refresh and use the name of the .pw.toml file (defaults to the project slug)")
os.Exit(1) os.Exit(1)
} }
err = os.Remove(resolvedMod) err = os.Remove(resolvedMod)
@ -40,7 +36,7 @@ var removeCmd = &cobra.Command{
fmt.Println(err) fmt.Println(err)
os.Exit(1) os.Exit(1)
} }
fmt.Println("Removing mod from index...") fmt.Println("Removing file from index...")
err = index.RemoveFile(resolvedMod) err = index.RemoveFile(resolvedMod)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
@ -62,7 +58,7 @@ var removeCmd = &cobra.Command{
os.Exit(1) os.Exit(1)
} }
fmt.Printf("Mod %s removed successfully!\n", args[0]) fmt.Printf("%s removed successfully!\n", args[0])
}, },
} }

View File

@ -11,13 +11,13 @@ import (
// updateCmd represents the update command // updateCmd represents the update command
var updateCmd = &cobra.Command{ var updateCmd = &cobra.Command{
Use: "update [mod]", Use: "update [name]",
Short: "Update a mod (or all mods) in the modpack", Short: "Update an external file (or all external files) in the modpack",
Aliases: []string{"upgrade"}, Aliases: []string{"upgrade"},
Args: cobra.MaximumNArgs(1), Args: cobra.MaximumNArgs(1),
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
// TODO: --check flag? // TODO: --check flag?
// TODO: specify multiple mods to update at once? // TODO: specify multiple files to update at once?
fmt.Println("Loading modpack...") fmt.Println("Loading modpack...")
pack, err := core.LoadPack() pack, err := core.LoadPack()
@ -39,11 +39,11 @@ var updateCmd = &cobra.Command{
var singleUpdatedName string var singleUpdatedName string
if viper.GetBool("update.all") { if viper.GetBool("update.all") {
updaterMap := make(map[string][]core.Mod) updaterMap := make(map[string][]core.Mod)
fmt.Println("Reading mod files...") fmt.Println("Reading metadata files...")
for _, v := range index.GetAllMods() { for _, v := range index.GetAllMods() {
modData, err := core.LoadMod(v) modData, err := core.LoadMod(v)
if err != nil { if err != nil {
fmt.Printf("Error reading mod file: %s\n", err.Error()) fmt.Printf("Error reading metadata file: %s\n", err.Error())
continue continue
} }
@ -95,7 +95,7 @@ var updateCmd = &cobra.Command{
} }
if !updatesFound { if !updatesFound {
fmt.Println("All mods are up to date!") fmt.Println("All files are up to date!")
return return
} }
@ -126,12 +126,12 @@ var updateCmd = &cobra.Command{
} }
} else { } else {
if len(args) < 1 || len(args[0]) == 0 { if len(args) < 1 || len(args[0]) == 0 {
fmt.Println("Must specify a valid mod, or use the --all flag!") fmt.Println("Must specify a valid file, or use the --all flag!")
os.Exit(1) os.Exit(1)
} }
modPath, ok := index.FindMod(args[0]) modPath, ok := index.FindMod(args[0])
if !ok { if !ok {
fmt.Println("You don't have this mod installed.") fmt.Println("Can't find this file; please ensure you have run packwiz refresh and use the name of the .pw.toml file (defaults to the project slug)")
os.Exit(1) os.Exit(1)
} }
modData, err := core.LoadMod(modPath) modData, err := core.LoadMod(modPath)
@ -207,7 +207,7 @@ var updateCmd = &cobra.Command{
os.Exit(1) os.Exit(1)
} }
if viper.GetBool("update.all") { if viper.GetBool("update.all") {
fmt.Println("Mods updated!") fmt.Println("Files updated!")
} else { } else {
fmt.Printf("\"%s\" updated!\n", singleUpdatedName) fmt.Printf("\"%s\" updated!\n", singleUpdatedName)
} }
@ -217,6 +217,6 @@ var updateCmd = &cobra.Command{
func init() { func init() {
rootCmd.AddCommand(updateCmd) rootCmd.AddCommand(updateCmd)
updateCmd.Flags().BoolP("all", "a", false, "Update all mods") updateCmd.Flags().BoolP("all", "a", false, "Update all external files")
_ = viper.BindPFlag("update.all", updateCmd.Flags().Lookup("all")) _ = viper.BindPFlag("update.all", updateCmd.Flags().Lookup("all"))
} }

View File

@ -40,12 +40,12 @@ func AddToZip(dl core.CompletedDownload, exp *zip.Writer, dir string, indexPath
path, err := filepath.Rel(filepath.Dir(indexPath), dl.Mod.GetDestFilePath()) path, err := filepath.Rel(filepath.Dir(indexPath), dl.Mod.GetDestFilePath())
if err != nil { if err != nil {
fmt.Printf("Error resolving mod file: %v\n", err) fmt.Printf("Error resolving external file: %v\n", err)
return false return false
} }
modFile, err := exp.Create(filepath.ToSlash(filepath.Join(dir, path))) modFile, err := exp.Create(filepath.ToSlash(filepath.Join(dir, path)))
if err != nil { if err != nil {
fmt.Printf("Error creating mod file %s: %v\n", path, err) fmt.Printf("Error creating metadata file %s: %v\n", path, err)
return false return false
} }
_, err = io.Copy(modFile, dl.File) _, err = io.Copy(modFile, dl.File)
@ -67,9 +67,9 @@ func PrintDisclaimer(isCf bool) {
fmt.Println("Disclaimer: you are responsible for ensuring you comply with ALL the licenses, or obtain appropriate permissions, for the files \"added to zip\" below") fmt.Println("Disclaimer: you are responsible for ensuring you comply with ALL the licenses, or obtain appropriate permissions, for the files \"added to zip\" below")
if isCf { if isCf {
fmt.Println("Note that mods bundled within a CurseForge pack must be in the Approved Non-CurseForge Mods list") fmt.Println("Note that mods bundled within a CurseForge pack must be in the Approved Non-CurseForge Mods list")
fmt.Println("packwiz is currently unable to match metadata between mod sites - if any of these are available from CurseForge you should change them to use CurseForge metadata (e.g. by reinstalling them using the cf commands)") fmt.Println("packwiz is currently unable to match metadata between mod sites - if any of these are available from CurseForge you should change them to use CurseForge metadata (e.g. by re-adding them using the cf commands)")
} else { } else {
fmt.Println("packwiz is currently unable to match metadata between mod sites - if any of these are available from Modrinth you should change them to use Modrinth metadata (e.g. by reinstalling them using the mr commands)") fmt.Println("packwiz is currently unable to match metadata between mod sites - if any of these are available from Modrinth you should change them to use Modrinth metadata (e.g. by re-adding them using the mr commands)")
} }
fmt.Println() fmt.Println()
} }

View File

@ -607,14 +607,14 @@ func CreateDownloadSession(mods []*Mod, hashesToObtain []string) (DownloadSessio
dlID := strings.TrimPrefix(mod.Download.Mode, "metadata:") dlID := strings.TrimPrefix(mod.Download.Mode, "metadata:")
pendingMetadata[dlID] = append(pendingMetadata[dlID], mod) pendingMetadata[dlID] = append(pendingMetadata[dlID], mod)
} else { } else {
return nil, fmt.Errorf("unknown download mode %s for mod %s", mod.Download.Mode, mod.Name) return nil, fmt.Errorf("unknown download mode %s for %s", mod.Download.Mode, mod.Name)
} }
} }
for dlID, mods := range pendingMetadata { for dlID, mods := range pendingMetadata {
downloader, ok := MetaDownloaders[dlID] downloader, ok := MetaDownloaders[dlID]
if !ok { if !ok {
return nil, fmt.Errorf("unknown download mode %s for mod %s", mods[0].Download.Mode, mods[0].Name) return nil, fmt.Errorf("unknown download mode %s for %s", mods[0].Download.Mode, mods[0].Name)
} }
meta, err := downloader.GetFilesMetadata(mods) meta, err := downloader.GetFilesMetadata(mods)
if err != nil { if err != nil {

View File

@ -324,7 +324,7 @@ func (u cfUpdater) CheckUpdate(mods []core.Mod, mcVersion string, pack core.Pack
for i, v := range mods { for i, v := range mods {
projectRaw, ok := v.GetParsedUpdateData("curseforge") projectRaw, ok := v.GetParsedUpdateData("curseforge")
if !ok { if !ok {
results[i] = core.UpdateCheck{Error: errors.New("couldn't parse mod data")} results[i] = core.UpdateCheck{Error: errors.New("failed to parse update metadata")}
continue continue
} }
project := projectRaw.(cfUpdateData) project := projectRaw.(cfUpdateData)
@ -349,7 +349,7 @@ func (u cfUpdater) CheckUpdate(mods []core.Mod, mcVersion string, pack core.Pack
for i, v := range mods { for i, v := range mods {
projectRaw, ok := v.GetParsedUpdateData("curseforge") projectRaw, ok := v.GetParsedUpdateData("curseforge")
if !ok { if !ok {
results[i] = core.UpdateCheck{Error: errors.New("couldn't parse mod data")} results[i] = core.UpdateCheck{Error: errors.New("failed to parse update metadata")}
continue continue
} }
project := projectRaw.(cfUpdateData) project := projectRaw.(cfUpdateData)

View File

@ -190,11 +190,11 @@ var importCmd = &cobra.Command{
modIDs[i] = v.ProjectID modIDs[i] = v.ProjectID
} }
fmt.Println("Querying Curse API for mod info...") fmt.Println("Querying Curse API for dependency info...")
modInfos, err := cfDefaultClient.getModInfoMultiple(modIDs) modInfos, err := cfDefaultClient.getModInfoMultiple(modIDs)
if err != nil { if err != nil {
fmt.Printf("Failed to obtain mod information: %s\n", err) fmt.Printf("Failed to obtain project information: %s\n", err)
os.Exit(1) os.Exit(1)
} }
@ -214,7 +214,7 @@ var importCmd = &cobra.Command{
for _, v := range modsList { for _, v := range modsList {
modInfoValue, ok := modInfosMap[v.ProjectID] modInfoValue, ok := modInfosMap[v.ProjectID]
if !ok { if !ok {
fmt.Printf("Failed to obtain mod information for addon/file IDs %d/%d\n", v.ProjectID, v.FileID) fmt.Printf("Failed to obtain information for project/file IDs %d/%d\n", v.ProjectID, v.FileID)
continue continue
} }
@ -238,7 +238,7 @@ var importCmd = &cobra.Command{
modFileInfos, err := cfDefaultClient.getFileInfoMultiple(remainingFileIDs) modFileInfos, err := cfDefaultClient.getFileInfoMultiple(remainingFileIDs)
if err != nil { if err != nil {
fmt.Printf("Failed to obtain mod file information: %s\n", err) fmt.Printf("Failed to obtain project file information: %s\n", err)
os.Exit(1) os.Exit(1)
} }
@ -250,19 +250,19 @@ var importCmd = &cobra.Command{
for _, v := range modsList { for _, v := range modsList {
modInfoValue, ok := modInfosMap[v.ProjectID] modInfoValue, ok := modInfosMap[v.ProjectID]
if !ok { if !ok {
fmt.Printf("Failed to obtain mod information for addon/file IDs %d/%d\n", v.ProjectID, v.FileID) fmt.Printf("Failed to obtain project information for project/file IDs %d/%d\n", v.ProjectID, v.FileID)
continue continue
} }
modFileInfoValue, ok := modFileInfosMap[v.FileID] modFileInfoValue, ok := modFileInfosMap[v.FileID]
if !ok { if !ok {
fmt.Printf("Failed to obtain mod file information for addon/file IDs %d/%d\n", v.ProjectID, v.FileID) fmt.Printf("Failed to obtain project file information for project/file IDs %d/%d\n", v.ProjectID, v.FileID)
continue continue
} }
err = createModFile(modInfoValue, modFileInfoValue, &index, v.OptionalDisabled) err = createModFile(modInfoValue, modFileInfoValue, &index, v.OptionalDisabled)
if err != nil { if err != nil {
fmt.Printf("Failed to save mod \"%s\": %s\n", modInfoValue.Name, err) fmt.Printf("Failed to save project \"%s\": %s\n", modInfoValue.Name, err)
os.Exit(1) os.Exit(1)
} }
@ -272,11 +272,11 @@ var importCmd = &cobra.Command{
referencedModPaths = append(referencedModPaths, ref) referencedModPaths = append(referencedModPaths, ref)
} }
fmt.Printf("Imported mod \"%s\" successfully!\n", modInfoValue.Name) fmt.Printf("Imported dependency \"%s\" successfully!\n", modInfoValue.Name)
successes++ successes++
} }
fmt.Printf("Successfully imported %d/%d mods!\n", successes, len(modsList)) fmt.Printf("Successfully imported %d/%d dependencies!\n", successes, len(modsList))
fmt.Println("Reading override files...") fmt.Println("Reading override files...")
filesList, err := packImport.GetFiles() filesList, err := packImport.GetFiles()

View File

@ -24,9 +24,9 @@ type installableDep struct {
// installCmd represents the install command // installCmd represents the install command
var installCmd = &cobra.Command{ var installCmd = &cobra.Command{
Use: "install [URL|slug|search]", Use: "add [URL|slug|search]",
Short: "Install a project from a CurseForge URL, slug, ID or search", Short: "Add a project from a CurseForge URL, slug, ID or search",
Aliases: []string{"add", "get"}, Aliases: []string{"install", "get"},
Args: cobra.ArbitraryArgs, Args: cobra.ArbitraryArgs,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
pack, err := core.LoadPack() pack, err := core.LoadPack()

View File

@ -12,17 +12,11 @@ import (
// openCmd represents the open command // openCmd represents the open command
var openCmd = &cobra.Command{ var openCmd = &cobra.Command{
Use: "open", Use: "open [name]",
// TODO: change semantics to "project" rather than "mod", as this supports texture packs and misc content as well? Short: "Open the project page for a CurseForge file in your browser",
Short: "Open the project page for a curseforge mod in your browser",
Aliases: []string{"doc"}, Aliases: []string{"doc"},
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
if len(args[0]) == 0 {
fmt.Println("You must specify a mod.")
os.Exit(1)
}
fmt.Println("Loading modpack...") fmt.Println("Loading modpack...")
pack, err := core.LoadPack() pack, err := core.LoadPack()
if err != nil { if err != nil {
@ -36,8 +30,8 @@ var openCmd = &cobra.Command{
} }
resolvedMod, ok := index.FindMod(args[0]) resolvedMod, ok := index.FindMod(args[0])
if !ok { if !ok {
// TODO: should this auto-refresh??????? // TODO: should this auto-refresh?
fmt.Println("You don't have this mod installed.") fmt.Println("Can't find this file; please ensure you have run packwiz refresh and use the name of the .pw.toml file (defaults to the project slug)")
os.Exit(1) os.Exit(1)
} }
modData, err := core.LoadMod(resolvedMod) modData, err := core.LoadMod(resolvedMod)
@ -47,7 +41,7 @@ var openCmd = &cobra.Command{
} }
updateData, ok := modData.GetParsedUpdateData("curseforge") updateData, ok := modData.GetParsedUpdateData("curseforge")
if !ok { if !ok {
fmt.Println("This mod doesn't seem to be a curseforge mod!") fmt.Println("Can't find CurseForge update metadata for this file")
os.Exit(1) os.Exit(1)
} }
cfUpdateData := updateData.(cfUpdateData) cfUpdateData := updateData.(cfUpdateData)

View File

@ -86,7 +86,7 @@ func (c *cfApiClient) makePost(endpoint string, body io.Reader) (*http.Response,
type fileType uint8 type fileType uint8
//noinspection GoUnusedConst // noinspection GoUnusedConst
const ( const (
fileTypeRelease fileType = iota + 1 fileTypeRelease fileType = iota + 1
fileTypeBeta fileTypeBeta
@ -95,7 +95,7 @@ const (
type dependencyType uint8 type dependencyType uint8
//noinspection GoUnusedConst // noinspection GoUnusedConst
const ( const (
dependencyTypeEmbedded dependencyType = iota + 1 dependencyTypeEmbedded dependencyType = iota + 1
dependencyTypeOptional dependencyTypeOptional
@ -107,7 +107,7 @@ const (
type modloaderType uint8 type modloaderType uint8
//noinspection GoUnusedConst // noinspection GoUnusedConst
const ( const (
// modloaderTypeAny should not be passed to the API - it does not work // modloaderTypeAny should not be passed to the API - it does not work
modloaderTypeAny modloaderType = iota modloaderTypeAny modloaderType = iota
@ -138,7 +138,7 @@ var modloaderIds = [...]string{
type hashAlgo uint8 type hashAlgo uint8
//noinspection GoUnusedConst // noinspection GoUnusedConst
const ( const (
hashAlgoSHA1 hashAlgo = iota + 1 hashAlgoSHA1 hashAlgo = iota + 1
hashAlgoMD5 hashAlgoMD5
@ -177,16 +177,16 @@ func (c *cfApiClient) getModInfo(modID uint32) (modInfo, error) {
idStr := strconv.FormatUint(uint64(modID), 10) idStr := strconv.FormatUint(uint64(modID), 10)
resp, err := c.makeGet("/v1/mods/" + idStr) resp, err := c.makeGet("/v1/mods/" + idStr)
if err != nil { if err != nil {
return modInfo{}, fmt.Errorf("failed to request addon data for ID %d: %w", modID, err) return modInfo{}, fmt.Errorf("failed to request project data for ID %d: %w", modID, err)
} }
err = json.NewDecoder(resp.Body).Decode(&infoRes) err = json.NewDecoder(resp.Body).Decode(&infoRes)
if err != nil && err != io.EOF { if err != nil && err != io.EOF {
return modInfo{}, fmt.Errorf("failed to request addon data for ID %d: %w", modID, err) return modInfo{}, fmt.Errorf("failed to request project data for ID %d: %w", modID, err)
} }
if infoRes.Data.ID != modID { if infoRes.Data.ID != modID {
return modInfo{}, fmt.Errorf("unexpected addon ID in CurseForge response: %d (expected %d)", infoRes.Data.ID, modID) return modInfo{}, fmt.Errorf("unexpected project ID in CurseForge response: %d (expected %d)", infoRes.Data.ID, modID)
} }
return infoRes.Data, nil return infoRes.Data, nil
@ -208,12 +208,12 @@ func (c *cfApiClient) getModInfoMultiple(modIDs []uint32) ([]modInfo, error) {
resp, err := c.makePost("/v1/mods", bytes.NewBuffer(modIDsData)) resp, err := c.makePost("/v1/mods", bytes.NewBuffer(modIDsData))
if err != nil { if err != nil {
return []modInfo{}, fmt.Errorf("failed to request addon data: %w", err) return []modInfo{}, fmt.Errorf("failed to request project data: %w", err)
} }
err = json.NewDecoder(resp.Body).Decode(&infoRes) err = json.NewDecoder(resp.Body).Decode(&infoRes)
if err != nil && err != io.EOF { if err != nil && err != io.EOF {
return []modInfo{}, fmt.Errorf("failed to request addon data: %w", err) return []modInfo{}, fmt.Errorf("failed to request project data: %w", err)
} }
return infoRes.Data, nil return infoRes.Data, nil
@ -279,16 +279,16 @@ func (c *cfApiClient) getFileInfo(modID uint32, fileID uint32) (modFileInfo, err
resp, err := c.makeGet("/v1/mods/" + modIDStr + "/files/" + fileIDStr) resp, err := c.makeGet("/v1/mods/" + modIDStr + "/files/" + fileIDStr)
if err != nil { if err != nil {
return modFileInfo{}, fmt.Errorf("failed to request file data for addon ID %d, file ID %d: %w", modID, fileID, err) return modFileInfo{}, fmt.Errorf("failed to request file data for project ID %d, file ID %d: %w", modID, fileID, err)
} }
err = json.NewDecoder(resp.Body).Decode(&infoRes) err = json.NewDecoder(resp.Body).Decode(&infoRes)
if err != nil && err != io.EOF { if err != nil && err != io.EOF {
return modFileInfo{}, fmt.Errorf("failed to request file data for addon ID %d, file ID %d: %w", modID, fileID, err) return modFileInfo{}, fmt.Errorf("failed to request file data for project ID %d, file ID %d: %w", modID, fileID, err)
} }
if infoRes.Data.ID != fileID { if infoRes.Data.ID != fileID {
return modFileInfo{}, fmt.Errorf("unexpected file ID for addon %d in CurseForge response: %d (expected %d)", modID, infoRes.Data.ID, fileID) return modFileInfo{}, fmt.Errorf("unexpected file ID for project %d in CurseForge response: %d (expected %d)", modID, infoRes.Data.ID, fileID)
} }
return infoRes.Data, nil return infoRes.Data, nil
@ -366,7 +366,7 @@ func (c *cfApiClient) getSearch(searchTerm string, slug string, gameID uint32, c
type gameStatus uint8 type gameStatus uint8
//noinspection GoUnusedConst // noinspection GoUnusedConst
const ( const (
gameStatusDraft gameStatus = iota + 1 gameStatusDraft gameStatus = iota + 1
gameStatusTest gameStatusTest
@ -378,7 +378,7 @@ const (
type gameApiStatus uint8 type gameApiStatus uint8
//noinspection GoUnusedConst // noinspection GoUnusedConst
const ( const (
gameApiStatusPrivate gameApiStatus = iota + 1 gameApiStatusPrivate gameApiStatus = iota + 1
gameApiStatusPublic gameApiStatusPublic

View File

@ -115,7 +115,7 @@ var exportCmd = &cobra.Command{
pathForward, err := filepath.Rel(filepath.Dir(indexPath), dl.Mod.GetDestFilePath()) pathForward, err := filepath.Rel(filepath.Dir(indexPath), dl.Mod.GetDestFilePath())
if err != nil { if err != nil {
fmt.Printf("Error resolving mod file: %s\n", err.Error()) fmt.Printf("Error resolving external file: %s\n", err.Error())
// TODO: exit(1)? // TODO: exit(1)?
continue continue
} }
@ -152,7 +152,7 @@ var exportCmd = &cobra.Command{
// Modrinth URLs must be RFC3986 // Modrinth URLs must be RFC3986
u, err := core.ReencodeURL(dl.Mod.Download.URL) u, err := core.ReencodeURL(dl.Mod.Download.URL)
if err != nil { if err != nil {
fmt.Printf("Error re-encoding mod URL: %s\n", err.Error()) fmt.Printf("Error re-encoding download URL: %s\n", err.Error())
u = dl.Mod.Download.URL u = dl.Mod.Download.URL
} }

View File

@ -41,7 +41,7 @@ func (u mrUpdater) CheckUpdate(mods []core.Mod, mcVersion string, pack core.Pack
for i, mod := range mods { for i, mod := range mods {
rawData, ok := mod.GetParsedUpdateData("modrinth") rawData, ok := mod.GetParsedUpdateData("modrinth")
if !ok { if !ok {
results[i] = core.UpdateCheck{Error: errors.New("couldn't parse mod data")} results[i] = core.UpdateCheck{Error: errors.New("failed to parse update metadata")}
continue continue
} }
@ -96,7 +96,7 @@ func (u mrUpdater) DoUpdate(mods []*core.Mod, cachedState []interface{}) error {
algorithm, hash := getBestHash(file) algorithm, hash := getBestHash(file)
if algorithm == "" { if algorithm == "" {
return errors.New("file for mod " + mod.Name + " doesn't have a hash") return errors.New("file for project " + mod.Name + " doesn't have a valid hash")
} }
mod.FileName = *file.Filename mod.FileName = *file.Filename