mirror of
https://github.com/packwiz/packwiz.git
synced 2025-04-19 21:16:30 +02:00
github: allow using a regular expression to match assets
safeguard against "undefined behavior" when a release has more than one asset Signed-off-by: unilock <unilock@fennet.rentals>
This commit is contained in:
parent
bae4a6be64
commit
d54da349d5
@ -8,7 +8,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/packwiz/packwiz/core"
|
"github.com/packwiz/packwiz/core"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
@ -39,6 +38,15 @@ var installCmd = &cobra.Command{
|
|||||||
var slug string
|
var slug string
|
||||||
var branch string
|
var branch string
|
||||||
|
|
||||||
|
// Regex to match potential release assets against.
|
||||||
|
// The default will match any asset with a name that does *not* end with:
|
||||||
|
// - "-api.jar"
|
||||||
|
// - "-dev.jar"
|
||||||
|
// - "-sources.jar"
|
||||||
|
// In most cases, this will only match one asset.
|
||||||
|
// TODO: Hopefully.
|
||||||
|
regex := `^.+(?<!-api|-dev|-sources)\.jar$`
|
||||||
|
|
||||||
// Check if the argument is a valid GitHub repository URL; if so, extract the slug from the URL.
|
// Check if the argument is a valid GitHub repository URL; if so, extract the slug from the URL.
|
||||||
// Otherwise, interpret the argument as a slug directly.
|
// Otherwise, interpret the argument as a slug directly.
|
||||||
matches := GithubRegex.FindStringSubmatch(args[0])
|
matches := GithubRegex.FindStringSubmatch(args[0])
|
||||||
@ -58,8 +66,11 @@ var installCmd = &cobra.Command{
|
|||||||
if branchFlag != "" {
|
if branchFlag != "" {
|
||||||
branch = branchFlag
|
branch = branchFlag
|
||||||
}
|
}
|
||||||
|
if regexFlag != "" {
|
||||||
|
regex = regexFlag
|
||||||
|
}
|
||||||
|
|
||||||
err = installMod(repo, branch, pack)
|
err = installMod(repo, branch, regex, pack)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Failed to add project: %s\n", err)
|
fmt.Printf("Failed to add project: %s\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@ -67,13 +78,13 @@ var installCmd = &cobra.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func installMod(repo Repo, branch string, pack core.Pack) error {
|
func installMod(repo Repo, branch string, regex string, pack core.Pack) error {
|
||||||
latestRelease, err := getLatestRelease(repo.FullName, branch)
|
latestRelease, err := getLatestRelease(repo.FullName, branch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get latest release: %v", err)
|
return fmt.Errorf("failed to get latest release: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return installRelease(repo, latestRelease, pack)
|
return installRelease(repo, latestRelease, regex, pack)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getLatestRelease(slug string, branch string) (Release, error) {
|
func getLatestRelease(slug string, branch string) (Release, error) {
|
||||||
@ -108,21 +119,28 @@ func getLatestRelease(slug string, branch string) (Release, error) {
|
|||||||
return releases[0], nil
|
return releases[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func installRelease(repo Repo, release Release, pack core.Pack) error {
|
func installRelease(repo Repo, release Release, regex string, pack core.Pack) error {
|
||||||
var files = release.Assets
|
expr := regexp.MustCompile(regex)
|
||||||
|
|
||||||
if len(files) == 0 {
|
if len(release.Assets) == 0 {
|
||||||
return errors.New("release doesn't have any files attached")
|
return errors.New("release doesn't have any assets attached")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: add some way to allow users to pick which file to install?
|
var files []Asset
|
||||||
var file = files[0]
|
|
||||||
for _, v := range release.Assets {
|
for _, v := range release.Assets {
|
||||||
if strings.HasSuffix(v.Name, ".jar") {
|
if expr.MatchString(v.Name) {
|
||||||
file = v
|
files = append(files, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(files) > 1 {
|
||||||
|
// TODO: also print file names
|
||||||
|
return errors.New("release has more than one asset matching regex")
|
||||||
|
}
|
||||||
|
|
||||||
|
file := files[0]
|
||||||
|
|
||||||
// Install the file
|
// Install the file
|
||||||
fmt.Printf("Installing %s from release %s\n", file.Name, release.TagName)
|
fmt.Printf("Installing %s from release %s\n", file.Name, release.TagName)
|
||||||
index, err := pack.LoadIndex()
|
index, err := pack.LoadIndex()
|
||||||
@ -136,6 +154,7 @@ func installRelease(repo Repo, release Release, pack core.Pack) error {
|
|||||||
Slug: repo.FullName,
|
Slug: repo.FullName,
|
||||||
Tag: release.TagName,
|
Tag: release.TagName,
|
||||||
Branch: release.TargetCommitish, // TODO: if no branch is specified by the user, we shouldn't record it - in order to remain branch-agnostic in getLatestRelease()
|
Branch: release.TargetCommitish, // TODO: if no branch is specified by the user, we shouldn't record it - in order to remain branch-agnostic in getLatestRelease()
|
||||||
|
Regex: regex, // TODO: ditto!
|
||||||
}.ToMap()
|
}.ToMap()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -196,9 +215,11 @@ func installRelease(repo Repo, release Release, pack core.Pack) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var branchFlag string
|
var branchFlag string
|
||||||
|
var regexFlag string
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
githubCmd.AddCommand(installCmd)
|
githubCmd.AddCommand(installCmd)
|
||||||
|
|
||||||
installCmd.Flags().StringVar(&branchFlag, "branch", "", "The GitHub repository branch to retrieve releases for")
|
installCmd.Flags().StringVar(&branchFlag, "branch", "", "The GitHub repository branch to retrieve releases for")
|
||||||
|
installCmd.Flags().StringVar(®exFlag, "regex", "", "The regular expression to match releases against")
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package github
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/mitchellh/mapstructure"
|
"github.com/mitchellh/mapstructure"
|
||||||
@ -13,6 +14,7 @@ type ghUpdateData struct {
|
|||||||
Slug string `mapstructure:"slug"`
|
Slug string `mapstructure:"slug"`
|
||||||
Tag string `mapstructure:"tag"`
|
Tag string `mapstructure:"tag"`
|
||||||
Branch string `mapstructure:"branch"`
|
Branch string `mapstructure:"branch"`
|
||||||
|
Regex string `mapstructure:"regex"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ghUpdater struct{}
|
type ghUpdater struct{}
|
||||||
@ -51,18 +53,29 @@ func (u ghUpdater) CheckUpdate(mods []*core.Mod, pack core.Pack) ([]core.UpdateC
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expr := regexp.MustCompile(data.Regex)
|
||||||
|
|
||||||
if len(newRelease.Assets) == 0 {
|
if len(newRelease.Assets) == 0 {
|
||||||
results[i] = core.UpdateCheck{Error: errors.New("new release doesn't have any assets")}
|
results[i] = core.UpdateCheck{Error: errors.New("new release doesn't have any assets")}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
newFile := newRelease.Assets[0]
|
var newFiles []Asset
|
||||||
|
|
||||||
for _, v := range newRelease.Assets {
|
for _, v := range newRelease.Assets {
|
||||||
if strings.HasSuffix(v.Name, ".jar") {
|
if expr.MatchString(v.Name) {
|
||||||
newFile = v
|
newFiles = append(newFiles, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(newFiles) > 1 {
|
||||||
|
// TODO: also print file names
|
||||||
|
results[i] = core.UpdateCheck{Error: errors.New("release has more than one asset matching regex")}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
newFile := newFiles[0]
|
||||||
|
|
||||||
results[i] = core.UpdateCheck{
|
results[i] = core.UpdateCheck{
|
||||||
UpdateAvailable: true,
|
UpdateAvailable: true,
|
||||||
UpdateString: mod.FileName + " -> " + newFile.Name,
|
UpdateString: mod.FileName + " -> " + newFile.Name,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user