mirror of
https://github.com/packwiz/packwiz.git
synced 2025-05-02 10:36:31 +02:00
feat: add command for arbitrary URLs (#137)
* feat: install command for direct downloads * use sha1 instead of sha256 * apply suggestions * feat: parse urls instead of using hasprefix * stop by default and add force flag * Implement various fixes and improvements Co-authored-by: Tricked <72335827+SkyBlockDev@users.noreply.github.com> Co-authored-by: comp500 <comp500@users.noreply.github.com>
This commit is contained in:
parent
11671421ac
commit
c7c2ca786b
20
core/mod.go
20
core/mod.go
@ -6,6 +6,8 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Mod stores metadata about a mod. This is written to a TOML file for each mod.
|
// Mod stores metadata about a mod. This is written to a TOML file for each mod.
|
||||||
@ -44,7 +46,7 @@ type ModOption struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The three possible values of Side (the side that the mod is on) are "server", "client", and "both".
|
// The three possible values of Side (the side that the mod is on) are "server", "client", and "both".
|
||||||
//noinspection GoUnusedConst
|
// noinspection GoUnusedConst
|
||||||
const (
|
const (
|
||||||
ServerSide = "server"
|
ServerSide = "server"
|
||||||
ClientSide = "client"
|
ClientSide = "client"
|
||||||
@ -129,3 +131,19 @@ func (m Mod) GetFilePath() string {
|
|||||||
func (m Mod) GetDestFilePath() string {
|
func (m Mod) GetDestFilePath() string {
|
||||||
return filepath.Join(filepath.Dir(m.metaFile), filepath.FromSlash(m.FileName))
|
return filepath.Join(filepath.Dir(m.metaFile), filepath.FromSlash(m.FileName))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var slugifyRegex1 = regexp.MustCompile("\\(.*\\)")
|
||||||
|
var slugifyRegex2 = regexp.MustCompile(" - .+")
|
||||||
|
var slugifyRegex3 = regexp.MustCompile("[^a-z\\d]")
|
||||||
|
var slugifyRegex4 = regexp.MustCompile("-+")
|
||||||
|
var slugifyRegex5 = regexp.MustCompile("^-|-$")
|
||||||
|
|
||||||
|
func SlugifyName(name string) string {
|
||||||
|
lower := strings.ToLower(name)
|
||||||
|
noBrackets := slugifyRegex1.ReplaceAllString(lower, "")
|
||||||
|
noSuffix := slugifyRegex2.ReplaceAllString(noBrackets, "")
|
||||||
|
limitedChars := slugifyRegex3.ReplaceAllString(noSuffix, "-")
|
||||||
|
noDuplicateDashes := slugifyRegex4.ReplaceAllString(limitedChars, "-")
|
||||||
|
noLeadingTrailingDashes := slugifyRegex5.ReplaceAllString(noDuplicateDashes, "")
|
||||||
|
return noLeadingTrailingDashes
|
||||||
|
}
|
||||||
|
1
main.go
1
main.go
@ -5,6 +5,7 @@ import (
|
|||||||
"github.com/packwiz/packwiz/cmd"
|
"github.com/packwiz/packwiz/cmd"
|
||||||
_ "github.com/packwiz/packwiz/curseforge"
|
_ "github.com/packwiz/packwiz/curseforge"
|
||||||
_ "github.com/packwiz/packwiz/modrinth"
|
_ "github.com/packwiz/packwiz/modrinth"
|
||||||
|
_ "github.com/packwiz/packwiz/url"
|
||||||
_ "github.com/packwiz/packwiz/utils"
|
_ "github.com/packwiz/packwiz/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -391,7 +391,7 @@ func createFileMeta(mod *modrinthApi.Project, version *modrinthApi.Version, file
|
|||||||
if mod.Slug != nil {
|
if mod.Slug != nil {
|
||||||
path = modMeta.SetMetaPath(filepath.Join(viper.GetString("meta-folder-base"), folder, *mod.Slug+core.MetaExtension))
|
path = modMeta.SetMetaPath(filepath.Join(viper.GetString("meta-folder-base"), folder, *mod.Slug+core.MetaExtension))
|
||||||
} else {
|
} else {
|
||||||
path = modMeta.SetMetaPath(filepath.Join(viper.GetString("meta-folder-base"), folder, *mod.Title+core.MetaExtension))
|
path = modMeta.SetMetaPath(filepath.Join(viper.GetString("meta-folder-base"), folder, core.SlugifyName(*mod.Title)+core.MetaExtension))
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the file already exists, this will overwrite it!!!
|
// If the file already exists, this will overwrite it!!!
|
||||||
|
152
url/install.go
Normal file
152
url/install.go
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
package url
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/packwiz/packwiz/core"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var installCmd = &cobra.Command{
|
||||||
|
Use: "add [name] [url]",
|
||||||
|
Short: "Add an external file from a direct download link, for sites that are not directly supported by packwiz",
|
||||||
|
Aliases: []string{"install", "get"},
|
||||||
|
Args: cobra.ExactArgs(2),
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
pack, err := core.LoadPack()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
dl, err := url.Parse(args[1])
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Failed to parse URL:", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
if dl.Scheme != "https" && dl.Scheme != "http" {
|
||||||
|
fmt.Println("Unsupported URL scheme:", dl.Scheme)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: consider using colors for these warnings but those can have issues on windows
|
||||||
|
force, err := cmd.Flags().GetBool("force")
|
||||||
|
if !force && err == nil {
|
||||||
|
var msg string
|
||||||
|
// TODO: update when github command is added
|
||||||
|
// TODO: make this generic?
|
||||||
|
//if dl.Host == "www.github.com" || dl.Host == "github.com" {
|
||||||
|
// msg = "github add " + args[1]
|
||||||
|
//}
|
||||||
|
if strings.HasSuffix(dl.Host, "modrinth.com") {
|
||||||
|
msg = "modrinth add " + args[1]
|
||||||
|
}
|
||||||
|
if strings.HasSuffix(dl.Host, "curseforge.com") || strings.HasSuffix(dl.Host, "forgecdn.net") {
|
||||||
|
msg = "curseforge add " + args[1]
|
||||||
|
}
|
||||||
|
if msg != "" {
|
||||||
|
fmt.Println("Consider using packwiz", msg, "instead; if you know what you are doing use --force to add this file without update metadata.")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hash, err := getSha1(args[1])
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Failed to retrieve SHA1 hash for file", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
index, err := pack.LoadIndex()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
filename := path.Base(dl.Path)
|
||||||
|
modMeta := core.Mod{
|
||||||
|
Name: args[0],
|
||||||
|
FileName: filename,
|
||||||
|
Download: core.ModDownload{
|
||||||
|
URL: args[1],
|
||||||
|
HashFormat: "sha1",
|
||||||
|
Hash: hash,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
folder := viper.GetString("meta-folder")
|
||||||
|
if folder == "" {
|
||||||
|
folder = "mods"
|
||||||
|
}
|
||||||
|
destPathName, err := cmd.Flags().GetString("meta-name")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
if destPathName == "" {
|
||||||
|
destPathName = core.SlugifyName(args[0])
|
||||||
|
}
|
||||||
|
destPath := modMeta.SetMetaPath(filepath.Join(viper.GetString("meta-folder-base"), folder,
|
||||||
|
destPathName+core.MetaExtension))
|
||||||
|
|
||||||
|
format, hash, err := modMeta.Write()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
err = index.RefreshFileWithHash(destPath, format, hash, true)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
err = index.Write()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
err = pack.UpdateIndexHash()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
err = pack.Write()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
fmt.Printf("Successfully added %s (%s) from: %s\n", args[0], destPath, args[1])
|
||||||
|
}}
|
||||||
|
|
||||||
|
func getSha1(url string) (string, error) {
|
||||||
|
// TODO: hook up to existing cache system? might not be that useful
|
||||||
|
mainHasher, err := core.GetHashImpl("sha1")
|
||||||
|
resp, err := http.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer resp.Body.Close()
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
return "", fmt.Errorf("failed to download: unexpected response status: %v", resp.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = io.Copy(mainHasher, resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return mainHasher.HashToString(mainHasher.Sum(nil)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
urlCmd.AddCommand(installCmd)
|
||||||
|
|
||||||
|
installCmd.Flags().Bool("force", false, "Add a file even if the download URL is supported by packwiz in an alternative command (which may support dependencies and updates)")
|
||||||
|
installCmd.Flags().String("meta-name", "", "Filename to use for the created metadata file (defaults to a name generated from the name you supply)")
|
||||||
|
}
|
15
url/url.go
Normal file
15
url/url.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package url
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/packwiz/packwiz/cmd"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var urlCmd = &cobra.Command{
|
||||||
|
Use: "url",
|
||||||
|
Short: "Add external files from a direct download link, for sites that are not directly supported by packwiz",
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
cmd.Add(urlCmd)
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user