package github import ( "encoding/json" "errors" "fmt" "io" "os" "path/filepath" "regexp" "github.com/dlclark/regexp2" "github.com/packwiz/packwiz/core" "github.com/spf13/cobra" "github.com/spf13/viper" ) var GithubRegex = regexp.MustCompile(`^https?://(?:www\.)?github\.com/([^/]+/[^/]+)`) // installCmd represents the install command var installCmd = &cobra.Command{ Use: "add [URL|slug]", Short: "Add a project from a GitHub repository URL or slug", Aliases: []string{"install", "get"}, Args: cobra.ArbitraryArgs, Run: func(cmd *cobra.Command, args []string) { pack, err := core.LoadPack() if err != nil { fmt.Println(err) os.Exit(1) } if len(args) == 0 || len(args[0]) == 0 { fmt.Println("You must specify a GitHub repository URL.") os.Exit(1) } // Try interpreting the argument as a slug, or GitHub repository URL. var slug 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" // - "-dev-preshadow.jar" // - "-sources.jar" // In most cases, this will only match one asset. // TODO: Hopefully. regex := `^.+(? 1 { // TODO: also print file names return errors.New("release has more than one asset matching regex") } file := files[0] // Install the file fmt.Printf("Installing %s from release %s\n", file.Name, release.TagName) index, err := pack.LoadIndex() if err != nil { return err } updateMap := make(map[string]map[string]interface{}) updateMap["github"], err = ghUpdateData{ Slug: repo.FullName, 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() Regex: regex, // TODO: ditto! }.ToMap() if err != nil { return err } hash, err := file.getSha256() if err != nil { return err } modMeta := core.Mod{ Name: repo.Name, FileName: file.Name, Side: core.UniversalSide, Download: core.ModDownload{ URL: file.BrowserDownloadURL, HashFormat: "sha256", Hash: hash, }, Update: updateMap, } var path string folder := viper.GetString("meta-folder") if folder == "" { folder = "mods" } path = modMeta.SetMetaPath(filepath.Join(viper.GetString("meta-folder-base"), folder, core.SlugifyName(repo.Name)+core.MetaExtension)) // If the file already exists, this will overwrite it!!! // TODO: Should this be improved? // Current strategy is to go ahead and do stuff without asking, with the assumption that you are using // VCS anyway. format, hash, err := modMeta.Write() if err != nil { return err } err = index.RefreshFileWithHash(path, format, hash, true) if err != nil { return err } err = index.Write() if err != nil { return err } err = pack.UpdateIndexHash() if err != nil { return err } err = pack.Write() if err != nil { return err } fmt.Printf("Project \"%s\" successfully added! (%s)\n", repo.Name, file.Name) return nil } var branchFlag string var regexFlag string func init() { githubCmd.AddCommand(installCmd) 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") }