From 9496ad3a7b16413025588a955500c2311c5db38a Mon Sep 17 00:00:00 2001
From: comp500 <comp500@users.noreply.github.com>
Date: Sun, 8 Oct 2023 14:53:07 +0100
Subject: [PATCH 01/17] Pass through warnings from UpdateIndex, don't fetch
 sha256 if we already have it

---
 core/download.go | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/core/download.go b/core/download.go
index 066d956..a926089 100644
--- a/core/download.go
+++ b/core/download.go
@@ -122,6 +122,7 @@ func reuseExistingFile(cacheHandle *CacheIndexHandle, hashesToObtain []string, m
 	file, err := cacheHandle.Open()
 	if err == nil {
 		remainingHashes := cacheHandle.GetRemainingHashes(hashesToObtain)
+		var warnings []error
 		if len(remainingHashes) > 0 {
 			err = teeHashes(remainingHashes, cacheHandle.Hashes, io.Discard, file)
 			if err != nil {
@@ -133,13 +134,14 @@ func reuseExistingFile(cacheHandle *CacheIndexHandle, hashesToObtain []string, m
 				_ = file.Close()
 				return CompletedDownload{}, fmt.Errorf("failed to seek file %s in cache: %w", cacheHandle.Path(), err)
 			}
-			cacheHandle.UpdateIndex()
+			warnings = cacheHandle.UpdateIndex()
 		}
 
 		return CompletedDownload{
-			File:   file,
-			Mod:    mod,
-			Hashes: cacheHandle.Hashes,
+			File:     file,
+			Mod:      mod,
+			Hashes:   cacheHandle.Hashes,
+			Warnings: warnings,
 		}, nil
 	} else {
 		return CompletedDownload{}, fmt.Errorf("failed to read file %s from cache: %w", cacheHandle.Path(), err)
@@ -228,7 +230,10 @@ func getHashListsForDownload(hashesToObtain []string, validateHashFormat string,
 	hashes := make(map[string]string)
 	hashes[validateHashFormat] = validateHash
 
-	cl := []string{cacheHashFormat}
+	var cl []string
+	if cacheHashFormat != validateHashFormat {
+		cl = append(cl, cacheHashFormat)
+	}
 	for _, v := range hashesToObtain {
 		if v != validateHashFormat && v != cacheHashFormat {
 			cl = append(cl, v)

From bee8e601d4abb5249fed1612f3e158e5930a83c8 Mon Sep 17 00:00:00 2001
From: comp500 <comp500@users.noreply.github.com>
Date: Sat, 14 Oct 2023 14:45:28 +0100
Subject: [PATCH 02/17] Clean up empty entries in index (not sure why they can
 exist?)

---
 core/download.go | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/core/download.go b/core/download.go
index a926089..18c60ba 100644
--- a/core/download.go
+++ b/core/download.go
@@ -556,6 +556,33 @@ func (h *CacheIndexHandle) Remove() {
 	return
 }
 
+func removeIndices(hashList []string, indices []int) []string {
+	i := 0
+	for _, v := range hashList {
+		if len(indices) > 0 && i == indices[0] {
+			indices = indices[1:]
+		} else {
+			hashList[i] = v
+			i++
+		}
+	}
+	return hashList[:i]
+}
+
+func removeEmpty(hashList []string) ([]string, []int) {
+	var indices []int
+	i := 0
+	for oldIdx, v := range hashList {
+		if v == "" {
+			indices = append(indices, oldIdx)
+		} else {
+			hashList[i] = v
+			i++
+		}
+	}
+	return hashList[:i], indices
+}
+
 func CreateDownloadSession(mods []*Mod, hashesToObtain []string) (DownloadSession, error) {
 	// Load cache index
 	cacheIndex := CacheIndex{Version: 1, Hashes: make(map[string][]string)}
@@ -592,6 +619,18 @@ func CreateDownloadSession(mods []*Mod, hashesToObtain []string) (DownloadSessio
 		cacheIndex.Hashes[cacheHashFormat] = make([]string, 0)
 	}
 	cacheIndex.cachePath = cachePath
+
+	// Clean up empty entries in index
+	var removedEntries []int
+	cacheIndex.Hashes[cacheHashFormat], removedEntries = removeEmpty(cacheIndex.Hashes[cacheHashFormat])
+	if len(removedEntries) > 0 {
+		for hashFormat, v := range cacheIndex.Hashes {
+			if hashFormat != cacheHashFormat {
+				cacheIndex.Hashes[hashFormat] = removeIndices(v, removedEntries)
+			}
+		}
+	}
+
 	cacheIndex.nextHashIdx = len(cacheIndex.Hashes[cacheHashFormat])
 
 	// Create import folder

From 1f09959be60e351770b1fc1f08603d572825a743 Mon Sep 17 00:00:00 2001
From: comp500 <comp500@users.noreply.github.com>
Date: Sun, 22 Oct 2023 11:32:38 +0100
Subject: [PATCH 03/17] Remove viper settings for acceptable-versions
 --add/--remove flags

---
 settings/acceptable_versions.go | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/settings/acceptable_versions.go b/settings/acceptable_versions.go
index fce06ed..a9ff711 100644
--- a/settings/acceptable_versions.go
+++ b/settings/acceptable_versions.go
@@ -5,7 +5,6 @@ import (
 	"github.com/packwiz/packwiz/cmdshared"
 	"github.com/packwiz/packwiz/core"
 	"github.com/spf13/cobra"
-	"github.com/spf13/viper"
 	"github.com/unascribed/FlexVer/go/flexver"
 	"golang.org/x/exp/slices"
 	"os"
@@ -42,8 +41,7 @@ var acceptableVersionsCommand = &cobra.Command{
 			}
 		}
 		// Check our flags to see if we're adding or removing
-		if viper.GetBool("settings.acceptable-versions.add") {
-			// Adding
+		if flagAdd {
 			acceptableVersion := args[0]
 			// Check if the version is already in the list
 			if slices.Contains(currentVersions, acceptableVersion) {
@@ -64,8 +62,7 @@ var acceptableVersionsCommand = &cobra.Command{
 			// Print success message
 			prettyList := strings.Join(currentVersions, ", ")
 			fmt.Printf("Added %s to acceptable versions list, now %s\n", acceptableVersion, prettyList)
-		} else if viper.GetBool("settings.acceptable-versions.remove") {
-			// Removing
+		} else if flagRemove {
 			acceptableVersion := args[0]
 			// Check if the version is in the list
 			if !slices.Contains(currentVersions, acceptableVersion) {
@@ -136,12 +133,13 @@ var acceptableVersionsCommand = &cobra.Command{
 	},
 }
 
+var flagAdd bool
+var flagRemove bool
+
 func init() {
 	settingsCmd.AddCommand(acceptableVersionsCommand)
 
 	// Add and remove flags for adding or removing specific versions
-	acceptableVersionsCommand.Flags().BoolP("add", "a", false, "Add a version to the list")
-	acceptableVersionsCommand.Flags().BoolP("remove", "r", false, "Remove a version from the list")
-	_ = viper.BindPFlag("settings.acceptable-versions.add", acceptableVersionsCommand.Flags().Lookup("add"))
-	_ = viper.BindPFlag("settings.acceptable-versions.remove", acceptableVersionsCommand.Flags().Lookup("remove"))
+	acceptableVersionsCommand.Flags().BoolVarP(&flagAdd, "add", "a", false, "Add a version to the list")
+	acceptableVersionsCommand.Flags().BoolVarP(&flagRemove, "remove", "r", false, "Remove a version from the list")
 }

From 7e3ca8d9d54ec56d0ceaaca293e502c39d824422 Mon Sep 17 00:00:00 2001
From: comp500 <comp500@users.noreply.github.com>
Date: Sun, 22 Oct 2023 10:38:30 +0000
Subject: [PATCH 04/17] chore: update packwiz vendorSha256

---
 nix/vendor-sha256 | 1 -
 1 file changed, 1 deletion(-)

diff --git a/nix/vendor-sha256 b/nix/vendor-sha256
index b59ccb9..e69de29 100644
--- a/nix/vendor-sha256
+++ b/nix/vendor-sha256
@@ -1 +0,0 @@
-sha256-yL5pWbVqf6mEpgYsItLnv8nwSmoMP+SE0rX/s7u2vCg=

From 0c8beeac2fe7a771bd1ddae81d6737af470599de Mon Sep 17 00:00:00 2001
From: Whovian9369 <Whovian9369@gmail.com>
Date: Fri, 22 Dec 2023 17:17:51 -0500
Subject: [PATCH 05/17] Fix outputting `vendorSha256` to `nix/vendor-sha256`
 (#266)

* Fix outputting `vendorSha256` to `nix/vendor-sha256`

* Add `nix/vendor-sha256` to make tools like `nix run` happy.
---
 nix/prefetcher.nix | 8 +++++++-
 nix/vendor-sha256  | 1 +
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/nix/prefetcher.nix b/nix/prefetcher.nix
index 3f8fb2d..5362219 100644
--- a/nix/prefetcher.nix
+++ b/nix/prefetcher.nix
@@ -3,7 +3,13 @@
   pkgs ? import <nixpkgs> {},
 }:
 pkgs.callPackage (import ./.) {
-  buildGoModule = pkgs.buildGo118Module;
+  ## Keeping `buildGoModule` commented out in case it's needed in the future.
+  ## As of writing, `buildGo121Module` is currently used as the default for
+  ## `buildGoModule` in nixpkgs. `buildGo118Module` seems deprecated and
+  ## entirely removed from nixpkgs, so manually setting that is likely to cause
+  ## issues in the future.
+
+  # buildGoModule = pkgs.buildGo118Module;
   vendorSha256 = sha256;
 }
 // {
diff --git a/nix/vendor-sha256 b/nix/vendor-sha256
index e69de29..b59ccb9 100644
--- a/nix/vendor-sha256
+++ b/nix/vendor-sha256
@@ -0,0 +1 @@
+sha256-yL5pWbVqf6mEpgYsItLnv8nwSmoMP+SE0rX/s7u2vCg=

From e27ddc4b9f663d90edcc4937d38443f095ddd7ee Mon Sep 17 00:00:00 2001
From: Whovian9369 <Whovian9369@gmail.com>
Date: Fri, 22 Dec 2023 20:05:19 -0500
Subject: [PATCH 06/17] Update version of `buildGoModule` used in `flake.nix`

---
 flake.nix | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flake.nix b/flake.nix
index 099840c..7c4fc7f 100644
--- a/flake.nix
+++ b/flake.nix
@@ -32,7 +32,7 @@
         packwiz = pkgs.callPackage ./nix {
           version = substring 0 8 self.rev or "dirty";
           vendorSha256 = readFile ./nix/vendor-sha256;
-          buildGoModule = pkgs.buildGo119Module;
+          buildGoModule = pkgs.buildGoModule;
         };
         # Build packwiz by default when no package name is specified
         default = packwiz;

From d3f58e025a62551ab3d430f2895fcc4bb714ff3a Mon Sep 17 00:00:00 2001
From: Whovian9369 <Whovian9369@gmail.com>
Date: Fri, 22 Dec 2023 21:12:15 -0500
Subject: [PATCH 07/17] Update Nix `flake.lock` to use newer version of Nixpkgs
 `nixos-unstable` branch.

---
 flake.lock | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/flake.lock b/flake.lock
index 63ea6b3..cbc8415 100644
--- a/flake.lock
+++ b/flake.lock
@@ -2,11 +2,11 @@
   "nodes": {
     "nixpkgs": {
       "locked": {
-        "lastModified": 1689444953,
-        "narHash": "sha256-0o56bfb2LC38wrinPdCGLDScd77LVcr7CrH1zK7qvDg=",
+        "lastModified": 1703013332,
+        "narHash": "sha256-+tFNwMvlXLbJZXiMHqYq77z/RfmpfpiI3yjL6o/Zo9M=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "8acef304efe70152463a6399f73e636bcc363813",
+        "rev": "54aac082a4d9bb5bbc5c4e899603abfb76a3f6d6",
         "type": "github"
       },
       "original": {

From 23311218a108a54d9a56d6a6849e3a5670fb001f Mon Sep 17 00:00:00 2001
From: Whovian9369 <Whovian9369@gmail.com>
Date: Fri, 22 Dec 2023 21:23:57 -0500
Subject: [PATCH 08/17] Add some notes to `flake.nix` and `nix/prefetcher.nix`

Notes are to describe `pkgs.buildGoModule` mapping in Nixpkgs.
---
 flake.nix          |  2 ++
 nix/prefetcher.nix | 11 +++++------
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/flake.nix b/flake.nix
index 7c4fc7f..0cb1692 100644
--- a/flake.nix
+++ b/flake.nix
@@ -33,6 +33,8 @@
           version = substring 0 8 self.rev or "dirty";
           vendorSha256 = readFile ./nix/vendor-sha256;
           buildGoModule = pkgs.buildGoModule;
+            # As of writing, `pkgs.buildGoModule` is aliased to
+            # `pkgs.buildGo121Module` in Nixpkgs.
         };
         # Build packwiz by default when no package name is specified
         default = packwiz;
diff --git a/nix/prefetcher.nix b/nix/prefetcher.nix
index 5362219..18ee3f6 100644
--- a/nix/prefetcher.nix
+++ b/nix/prefetcher.nix
@@ -3,13 +3,12 @@
   pkgs ? import <nixpkgs> {},
 }:
 pkgs.callPackage (import ./.) {
-  ## Keeping `buildGoModule` commented out in case it's needed in the future.
-  ## As of writing, `buildGo121Module` is currently used as the default for
-  ## `buildGoModule` in nixpkgs. `buildGo118Module` seems deprecated and
-  ## entirely removed from nixpkgs, so manually setting that is likely to cause
-  ## issues in the future.
 
-  # buildGoModule = pkgs.buildGo118Module;
+  buildGoModule = pkgs.buildGoModule;
+    ## As of writing, `pkgs.buildGoModule` is aliased to
+    ## `pkgs.buildGo121Module` in Nixpkgs.
+    ## `buildGoModule` is set as `pkgs.buildGoModule` to try and work around
+    ## `vendorHash` issues in the future.
   vendorSha256 = sha256;
 }
 // {

From 79cb91a41e6038d5a0447219b79cac94177e7b04 Mon Sep 17 00:00:00 2001
From: Whovian9369 <Whovian9369@gmail.com>
Date: Sat, 23 Dec 2023 21:06:36 -0500
Subject: [PATCH 09/17] Edit `flake.nix`'s `inputs.nixpkgs.url` to be a little
 more verbose.

---
 flake.nix | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flake.nix b/flake.nix
index 0cb1692..fc5c157 100644
--- a/flake.nix
+++ b/flake.nix
@@ -1,5 +1,5 @@
 {
-  inputs.nixpkgs.url = "nixpkgs/nixos-unstable";
+  inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
 
   outputs = {
     self,

From 530dd1499d009df05606ea31a853eca2e7e65924 Mon Sep 17 00:00:00 2001
From: Whovian9369 <Whovian9369@gmail.com>
Date: Sun, 24 Dec 2023 15:38:25 -0500
Subject: [PATCH 10/17] Add a small note to how `inputs.nixpkgs.url` maps to a
 Repo URL.

---
 flake.nix | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/flake.nix b/flake.nix
index fc5c157..31f46ec 100644
--- a/flake.nix
+++ b/flake.nix
@@ -1,5 +1,7 @@
 {
   inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
+    # This maps to https://github.com/NixOS/nixpkgs/tree/nixos-unstable
+    # The `url` option is the pattern of `github:USER_OR_ORG/REPO/BRANCH`
 
   outputs = {
     self,

From 069d32c5de08d48fe5c1c464a150bb0a9bf04d37 Mon Sep 17 00:00:00 2001
From: James Groom <OSSYoshiRulz+GitHub@gmail.com>
Date: Sun, 21 Apr 2024 11:41:22 +0000
Subject: [PATCH 11/17] Respect `-y` for `packwiz init` (#290)

---
 cmd/init.go | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/cmd/init.go b/cmd/init.go
index 9516093..45edd5d 100644
--- a/cmd/init.go
+++ b/cmd/init.go
@@ -222,6 +222,10 @@ func init() {
 
 func initReadValue(prompt string, def string) string {
 	fmt.Print(prompt)
+	if viper.GetBool("non-interactive") {
+		fmt.Printf("%s\n", def)
+		return def
+	}
 	value, err := bufio.NewReader(os.Stdin).ReadString('\n')
 	if err != nil {
 		fmt.Printf("Error reading input: %s\n", err)

From 1c76f798884c0a83b2d1f523215e3782aaaa050f Mon Sep 17 00:00:00 2001
From: comp500 <comp500@users.noreply.github.com>
Date: Sun, 21 Apr 2024 11:42:16 +0000
Subject: [PATCH 12/17] chore: update packwiz vendorSha256

---
 nix/vendor-sha256 | 1 -
 1 file changed, 1 deletion(-)

diff --git a/nix/vendor-sha256 b/nix/vendor-sha256
index b59ccb9..e69de29 100644
--- a/nix/vendor-sha256
+++ b/nix/vendor-sha256
@@ -1 +0,0 @@
-sha256-yL5pWbVqf6mEpgYsItLnv8nwSmoMP+SE0rX/s7u2vCg=

From 62e78d40e929f8d60d7cf3a5bf076c3cbe16d139 Mon Sep 17 00:00:00 2001
From: Omay <70179858+Omay238@users.noreply.github.com>
Date: Sun, 21 Apr 2024 05:43:31 -0600
Subject: [PATCH 13/17] Include primary version in printed acceptable versions
 list (#280)

fix #255
---
 settings/acceptable_versions.go | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/settings/acceptable_versions.go b/settings/acceptable_versions.go
index a9ff711..4853aaf 100644
--- a/settings/acceptable_versions.go
+++ b/settings/acceptable_versions.go
@@ -61,6 +61,7 @@ var acceptableVersionsCommand = &cobra.Command{
 			}
 			// Print success message
 			prettyList := strings.Join(currentVersions, ", ")
+			prettyList += ", " + modpack.Versions["minecraft"]
 			fmt.Printf("Added %s to acceptable versions list, now %s\n", acceptableVersion, prettyList)
 		} else if flagRemove {
 			acceptableVersion := args[0]
@@ -84,6 +85,7 @@ var acceptableVersionsCommand = &cobra.Command{
 			}
 			// Print success message
 			prettyList := strings.Join(currentVersions, ", ")
+			prettyList += ", " + modpack.Versions["minecraft"]
 			fmt.Printf("Removed %s from acceptable versions list, now %s\n", acceptableVersion, prettyList)
 		} else {
 			// Overwriting
@@ -128,6 +130,7 @@ var acceptableVersionsCommand = &cobra.Command{
 			}
 			// Print success message
 			prettyList := strings.Join(acceptableVersionsDeduped, ", ")
+			prettyList += ", " + modpack.Versions["minecraft"]
 			fmt.Printf("Set acceptable versions to %s\n", prettyList)
 		}
 	},

From 5bb680f266262512fac817255d60a38ffaa1d919 Mon Sep 17 00:00:00 2001
From: Omay <70179858+Omay238@users.noreply.github.com>
Date: Sun, 21 Apr 2024 05:44:34 -0600
Subject: [PATCH 14/17] Improve installation instructions in README (#283)

---
 README.md | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index d9ed1d1..315040e 100644
--- a/README.md
+++ b/README.md
@@ -24,7 +24,11 @@ Join my Discord server if you need help [here](https://discord.gg/Csh8zbbhCt)!
 - Creation of remote file metadata from JAR files for CurseForge mods
 
 ## Installation
-Prebuilt binaries are available from [GitHub Actions](https://github.com/packwiz/packwiz/actions) - the UI is a bit terrible, but essentially select the top build, then download the artifact ZIP for your system at the bottom of the page. To run the executable, add the folder where you downloaded it to your PATH environment variable ([see tutorial for Windows here](https://www.howtogeek.com/118594/how-to-edit-your-system-path-for-easy-command-line-access/)) or move it to where you want to use it.
+Prebuilt binaries are available from [GitHub Actions](https://github.com/packwiz/packwiz/actions) - the UI is a bit terrible, but essentially select the top build, then download the artifact ZIP for your system at the bottom of the page.  
+
+Another option is to use [nightly.link](https://nightly.link/packwiz/packwiz/workflows/go/main). Just go to the page, and download the artifact for your system.  
+
+To run the executable, first extract it, then add the folder where you extracted it to your PATH environment variable ([see tutorial for Windows here](https://www.howtogeek.com/118594/how-to-edit-your-system-path-for-easy-command-line-access/)) or move it to where you want to use it.
 
 In future I will have a lot more installation options, but you can also compile from source:
 
@@ -32,4 +36,4 @@ In future I will have a lot more installation options, but you can also compile
 2. Run `go install github.com/packwiz/packwiz@latest`. Be patient, it has to download and compile dependencies as well!
 
 ## Documentation
-See https://packwiz.infra.link/ for the full packwiz documentation!
\ No newline at end of file
+See https://packwiz.infra.link/ for the full packwiz documentation!

From 9cca74476da41dafe85e04090d979921b55d6086 Mon Sep 17 00:00:00 2001
From: James Groom <OSSYoshiRulz+GitHub@gmail.com>
Date: Sun, 21 Apr 2024 11:46:33 +0000
Subject: [PATCH 15/17] Improve r13y of `packwiz modrinth export` by sorting
 `manifestFiles` (#287)

resolves #244
---
 modrinth/export.go | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/modrinth/export.go b/modrinth/export.go
index 295fe62..183b2cb 100644
--- a/modrinth/export.go
+++ b/modrinth/export.go
@@ -9,6 +9,7 @@ import (
 	"golang.org/x/exp/slices"
 	"net/url"
 	"os"
+	"sort"
 	"strconv"
 
 	"github.com/packwiz/packwiz/core"
@@ -172,6 +173,10 @@ var exportCmd = &cobra.Command{
 				}
 			}
 		}
+		// sort by `path` property before serialising to ensure reproducibility
+		sort.Slice(manifestFiles, func(i, j int) bool {
+			return manifestFiles[i].Path < manifestFiles[j].Path
+		})
 
 		err = session.SaveIndex()
 		if err != nil {

From 7b4be47578151c36e784306b36d251ec2590e50c Mon Sep 17 00:00:00 2001
From: Keith <keith@kaioru.co>
Date: Tue, 28 May 2024 03:54:22 +0800
Subject: [PATCH 16/17] Update modrinth url regex to accept 'www.' as well
 (#304)

---
 modrinth/modrinth.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modrinth/modrinth.go b/modrinth/modrinth.go
index 2e920bd..fa38bbc 100644
--- a/modrinth/modrinth.go
+++ b/modrinth/modrinth.go
@@ -186,7 +186,7 @@ func getProjectTypeFolder(projectType string, fileLoaders []string, packLoaders
 
 var urlRegexes = [...]*regexp.Regexp{
 	// Slug/version number regex from https://github.com/modrinth/labrinth/blob/1679a3f844497d756d0cf272c5374a5236eabd42/src/util/validate.rs#L8
-	regexp.MustCompile("^https?://modrinth\\.com/(?P<urlCategory>[^/]+)/(?P<slug>[a-zA-Z0-9!@$()`.+,_\"-]{3,64})(?:/version/(?P<version>[a-zA-Z0-9!@$()`.+,_\"-]{1,32}))?"),
+	regexp.MustCompile("^https?://(www.)?modrinth\\.com/(?P<urlCategory>[^/]+)/(?P<slug>[a-zA-Z0-9!@$()`.+,_\"-]{3,64})(?:/version/(?P<version>[a-zA-Z0-9!@$()`.+,_\"-]{1,32}))?"),
 	// Version/project IDs are more restrictive: [a-zA-Z0-9]+ (base62)
 	regexp.MustCompile("^https?://cdn\\.modrinth\\.com/data/(?P<slug>[a-zA-Z0-9]+)/versions/(?P<versionID>[a-zA-Z0-9]+)/(?P<filename>[^/]+)$"),
 	regexp.MustCompile("^(?P<slug>[a-zA-Z0-9!@$()`.+,_\"-]{3,64})$"),

From 4503e905d76e2a359573c3ff0644f2b0caa32304 Mon Sep 17 00:00:00 2001
From: comp500 <comp500@users.noreply.github.com>
Date: Wed, 28 Aug 2024 18:14:00 +0100
Subject: [PATCH 17/17] Reformat, force line endings to LF for Go files

---
 ,gitattributes               | 1 +
 .gitignore                   | 3 +++
 curseforge/cursedir_other.go | 2 +-
 3 files changed, 5 insertions(+), 1 deletion(-)
 create mode 100644 ,gitattributes

diff --git a/,gitattributes b/,gitattributes
new file mode 100644
index 0000000..a0717e4
--- /dev/null
+++ b/,gitattributes
@@ -0,0 +1 @@
+*.go text eol=lf
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index b4ef2b5..d298506 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,9 @@
 # I use GoLand now
 .idea/
 
+# I no longer have student GoLand
+.vscode/
+
 # Nix build output
 result
 
diff --git a/curseforge/cursedir_other.go b/curseforge/cursedir_other.go
index 8d0134d..822cac2 100644
--- a/curseforge/cursedir_other.go
+++ b/curseforge/cursedir_other.go
@@ -1,4 +1,4 @@
-// +build !windows
+//go:build !windows
 
 package curseforge