diff --git a/README.md b/README.md index d0dc5d6..40d74e9 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ republish it, it would produce the *exact* same hash. ### package.json -It should be noted that gx is meant to *work with* existing `package.json` files. If you are adding a package to gx that already has a `package.json` file in its root, gx will try and work with it. Any shared fields will have the same types, and any fields unique to gx will kept separate. +It should be noted that gx is meant to *work with* existing `package.json` files. If you are adding a package to gx that already has a `package.json` file in its root, gx will try and work with it. Any shared fields will have the same types, and any fields unique to gx will kept separate. E.g. A single `package.json` file could be used to serve both gx and another packaging tool, such as npm. Since gx is **Alpha Quality** there may be some exceptions to the above statements, if you notice one, please file an issue. @@ -300,6 +300,9 @@ in your `package.json` as your `releaseCmd`. To get the above git commit flow, you can set it to: `git commit -a -m \"gx publish $VERSION\"` and gx will replace `$VERSION` with the newly changed version before executing the git commit. +In addition to commiting, it will also publish a git tag, using the default command +`git tag -a "v$VERSION" -m "gx release published as $HASH"`. To change the command you can set +the `tagCmd` field to a command of your choosing. ### Ignoring files from a publish You can use a `.gxignore` file to make gx ignore certain files during a publish. diff --git a/gxutil/pkgfile.go b/gxutil/pkgfile.go index 9105723..59924b8 100644 --- a/gxutil/pkgfile.go +++ b/gxutil/pkgfile.go @@ -21,6 +21,7 @@ type PackageBase struct { Build string `json:"build,omitempty"` Test string `json:"test,omitempty"` ReleaseCmd string `json:"releaseCmd,omitempty"` + TagCmd string `json:"tagCmd,omitempty"` SubtoolRequired bool `json:"subtoolRequired,omitempty"` Language string `json:"language,omitempty"` License string `json:"license"` diff --git a/gxutil/pm.go b/gxutil/pm.go index 2c99ba2..9cc18dc 100644 --- a/gxutil/pm.go +++ b/gxutil/pm.go @@ -23,6 +23,8 @@ const GxVersion = "0.12.1" const PkgFileName = "package.json" +const DefaultTagCmd = "git tag -a \"v$VERSION\" -m \"gx release published as $HASH\"" + var installPathsCache map[string]string var binarySuffix string @@ -208,6 +210,7 @@ func (pm *PM) InitPkg(dir, name, lang string, setup func(*Package)) error { Version: "0.0.0", GxVersion: GxVersion, ReleaseCmd: "git commit -a -m \"gx publish $VERSION\"", + TagCmd: DefaultTagCmd, }, } diff --git a/main.go b/main.go index bd3a0e3..d3ca1b5 100644 --- a/main.go +++ b/main.go @@ -173,34 +173,41 @@ number. This is a soft requirement and can be skipped by specifying the } } - return doPublish(pkg) + if _, err := doPublish(pkg); err != nil { + return err + } + + return nil }, } -func doPublish(pkg *gx.Package) error { +func doPublish(pkg *gx.Package) (string, error) { if !pm.ShellOnline() { - return fmt.Errorf("ipfs daemon isn't running") + return "", fmt.Errorf("ipfs daemon isn't running") } err := gx.TryRunHook("pre-publish", pkg.Language, pkg.SubtoolRequired) if err != nil { - return err + return "", err } hash, err := pm.PublishPackage(cwd, &pkg.PackageBase) if err != nil { - return fmt.Errorf("publishing: %s", err) + return "", fmt.Errorf("publishing: %s", err) } log.Log("package %s published with hash: %s", pkg.Name, hash) // write out version hash err = writeLastPub(pkg.Version, hash) if err != nil { - return err + return "", err + } + + if err := gx.TryRunHook("post-publish", pkg.Language, pkg.SubtoolRequired, hash); err != nil { + return "", err } - err = gx.TryRunHook("post-publish", pkg.Language, pkg.SubtoolRequired, hash) - return err + return hash, nil } func writeLastPub(vers string, hash string) error { @@ -1235,12 +1242,12 @@ var ReleaseCommand = cli.Command{ } fmt.Printf("publishing package...\r") - err = doPublish(pkg) + hash, err := doPublish(pkg) if err != nil { return err } - return runRelease(pkg) + return runRelease(pkg, hash) }, } @@ -1313,20 +1320,45 @@ func splitArgs(in string) []string { return out } -func escapeReleaseCmd(pkg *gx.Package, cmd string) string { - cmd = strings.Replace(cmd, "$VERSION", pkg.Version, -1) +func escapeReleaseCmd(cmd, version, hash string) string { + cmd = strings.Replace(cmd, "$VERSION", version, -1) + cmd = strings.Replace(cmd, "$HASH", hash, -1) return cmd } -func runRelease(pkg *gx.Package) error { +func runRelease(pkg *gx.Package, hash string) error { if pkg.ReleaseCmd == "" { + fmt.Println("no release command defined, skipping") return nil } - replaced := escapeReleaseCmd(pkg, pkg.ReleaseCmd) + commitCmd := escapeReleaseCmd(pkg.ReleaseCmd, pkg.Version, hash) + + if err := runCmd(commitCmd); err != nil { + return fmt.Errorf("failed to commit release: %s", err) + } + + tagCmd := pkg.TagCmd + if tagCmd == "" { + // TODO: maybe don't do this? but otherwise we run into the issue that all existing + // gx configs don't have this defined, and would not start using tags :( + fmt.Println("no tag command defined, using default") + tagCmd = gx.DefaultTagCmd + } + + tagCmd = escapeReleaseCmd(tagCmd, pkg.Version, hash) + if err := runCmd(tagCmd); err != nil { + return fmt.Errorf("failed to tag release: %s", err) + } + + return nil +} + +func runCmd(command string) error { + parts := splitArgs(command) + fmt.Println("exec:", command, parts) - parts := splitArgs(replaced) cmd := exec.Command(parts[0], parts[1:]...) cmd.Stderr = os.Stderr cmd.Stdout = os.Stdout