Skip to content
This repository was archived by the owner on Mar 23, 2021. It is now read-only.

main: tweak flags to be more friendly #32

Merged
merged 1 commit into from
Nov 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions .readme.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ git config --global push.default current
# block: get
GO111MODULE=off go get -u github.com/myitcv/gobin

# actually under the hood we want to install the "current" local version
# else we won't be able to take advantage of changes until they are merged
pushd /self > /dev/null
GOBIN=$GOPATH/bin GOPATH=/gopath go install
popd > /dev/null

# block: fix path
export PATH=$(go env GOPATH)/bin:$PATH
which gobin
Expand All @@ -36,7 +42,7 @@ gobin github.com/rogpeppe/gohack@v1.0.0
gobin -p github.com/rogpeppe/gohack@v1.0.0

# block: gohack run
gobin -r github.com/rogpeppe/gohack@v1.0.0 -help
gobin -run github.com/rogpeppe/gohack@v1.0.0 -help
assert "$? -eq 2" $LINENO

# ====================================
Expand Down Expand Up @@ -69,15 +75,15 @@ gobin -m -p golang.org/x/tools/cmd/stringer@v0.0.0-20181102223251-96e9e165b75e
gobin -m -p golang.org/x/tools/cmd/stringer

# block: stringer help
gobin -m -r golang.org/x/tools/cmd/stringer -help
gobin -m -run golang.org/x/tools/cmd/stringer -help
assert "$? -eq 2" $LINENO

cat <<EOD | gofmt > main.go
package main

import "fmt"

//go:generate gobin -m -r golang.org/x/tools/cmd/stringer -type=Pill
//go:generate gobin -m -run golang.org/x/tools/cmd/stringer -type=Pill

type Pill int

Expand Down
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ script:

# https://github.com/golang/go/issues/27868#issuecomment-431413621
- go list all > /dev/null
- go run github.com/myitcv/gobin -m -r myitcv.io/cmd/mdreplace -long -online -w README.md
- go run github.com/myitcv/gobin -m -run myitcv.io/cmd/mdreplace -long -online -w README.md
- test -z "$(git status --porcelain)" || (git status; git diff; false)
105 changes: 57 additions & 48 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ See the [FAQ](https://github.com/myitcv/gobin/wiki/FAQ) for more details.

<!-- END -->

<!-- __JSON: go run github.com/myitcv/gobin -m -r myitcv.io/cmd/egrunner .readme.sh # LONG ONLINE
<!-- __JSON: sh -c "go run github.com/myitcv/gobin -m -run myitcv.io/cmd/egrunner -df=-v=$DOLLAR{GOPATH%%:*}:/gopath -df=-v=${DOLLAR}PWD:/self .readme.sh" # LONG ONLINE

### Installation

Expand All @@ -30,9 +30,9 @@ Update your `PATH` and verify we can find `gobin` in our new `PATH`:
{{PrintBlock "fix path" -}}
```

### Examples: global mode
### Examples

Globally install `gohack`:
Install `gohack`:

```
{{PrintBlock "gohack" -}}
Expand All @@ -56,7 +56,7 @@ Run a specific `gohack` version:
{{PrintBlock "gohack run" | lineEllipsis 4 -}}
```

### Examples: main-module mode
### Examples: using `-m`

Define a module:

Expand Down Expand Up @@ -113,9 +113,9 @@ $ which gobin
/home/gopher/gopath/bin/gobin
```

### Examples: global mode
### Examples

Globally install `gohack`:
Install `gohack`:

```
$ gobin github.com/rogpeppe/gohack
Expand All @@ -139,14 +139,14 @@ $ gobin -p github.com/rogpeppe/gohack@v1.0.0
Run a specific `gohack` version:

```
$ gobin -r github.com/rogpeppe/gohack@v1.0.0 -help
$ gobin -run github.com/rogpeppe/gohack@v1.0.0 -help
The gohack command checks out Go module dependencies
into a directory where they can be edited, and adjusts
the go.mod file appropriately.
...
```

### Examples: main-module mode
### Examples: using `-m`

Define a module:

Expand Down Expand Up @@ -178,7 +178,7 @@ $ gobin -m -p golang.org/x/tools/cmd/stringer
Check the help for `stringer`:

```
$ gobin -m -r golang.org/x/tools/cmd/stringer -help
$ gobin -m -run golang.org/x/tools/cmd/stringer -help
Usage of stringer:
stringer [flags] -type T [directory]
stringer [flags] -type T files... # Must be a single package
Expand All @@ -194,7 +194,7 @@ package main

import "fmt"

//go:generate gobin -m -r golang.org/x/tools/cmd/stringer -type=Pill
//go:generate gobin -m -run golang.org/x/tools/cmd/stringer -type=Pill

type Pill int

Expand Down Expand Up @@ -235,57 +235,71 @@ For headaches, take Ibuprofen
The gobin command installs/runs main packages.

Usage:
gobin [-m] [-r|-p] [-n|-g] packages [run arguments...]
gobin [-m] [-run|-p|-d] [-u|-nonet] packages [run arguments...]

The packages argument to gobin is similar to that of the go tool (in module
mode) with the additional constraint that the list of packages must be main
packages.
The gobin command builds, installs, and possibly runs an executable binary for
each of the named main packages.

By default, gobin is said to operate in global mode. If the -m flag is provided
then it is said to operate in main-module mode, where the path to the main
module's go.mod is given by go env GOMOD.
The packages argument to gobin is similar to that of the go get command (in
module aware mode) with the additional constraint that the list of packages
must be main packages. Each argument takes the form $main_pkg[@$version].

The version "latest" matches the latest available tagged version. If no version
is specified, gobin behaves differently in global and main-module modes. In
global mode, gobin attempts to resolve the latest version available in the
module download cache. In main-module module, gobin attempts to resolve the
current version via the main module's go.mod. If this resolution fails in
either mode, "latest" is assumed and gobin resolves via the network.
By default, gobin will use the main package's module to resolve its
dependencies, unless the -m flag is specified, in which case dependencies will
be resolved using the main module (as given by go env GOMOD).

In global mode, gobin installs the main packages to the directories
gobin/$module@$version/$main_pkg under your user cache directory. See the
documentation for os.UserCacheDir for OS-specific details on how to configure
its location.
This means that gobin $package@v1.2.3 is a repeatable way to install an exact
version of a binary (assuming it has an associated go.mod file).

In main-module mode, gobin installs the main packages to the directories
.gobincache/$module@$version/$main_pkg under the directory containing the main
module's go.mod.
The version "latest" matches the latest available tagged version for the module
containing the main package. If gobin is able to resolve "latest" within the
module download cache it will use that version. Otherwise, gobin will make a
network request to resolve "latest". The -u flag forces gobin to check the
network for the latest tagged version. If the -nonet flag is provided, gobin
will only check the module download cache. Hence, the -u and -nonet flags are
mutually exclusive.

Versions that take the form of a revision identifier (a branch name, for
example) can only be resolved with a network request and hence are incompatible
with -nonet.

If no version is specified for a main package, gobin behaves differently
depending on whether the -m flag is provided. If the -m flag is not provided,
gobin $module is equivalent to gobin $module@latest. If the -m flag is
provided, gobin attempts to resolve the current version via the main module's
go.mod; if this resolution fails, "latest" is assumed as the version.

By default, gobin installs the main packages to $GOBIN (or $GOPATH/bin if GOBIN
is not set, which defaults to $HOME/go/bin if GOPATH is not set).

The -r flag takes exactly one main package argument and runs that package. It
is similar therefore to go run. Any arguments after the single main package
The -run flag takes exactly one main package argument and runs that package.
It is similar therefore to go run. Any arguments after the single main package
will be passed to the main package as command line arguments.

The -p flag prints the cache install path for each of the provided packages
The -p flag prints the gobin cache path for each of the packages' executables
once versions have been resolved.

The -r and -p flags are mutually exclusive.
The -d flag instructs gobin to stop after installing the packages to the gobin
cache; that is, it instructs gobin not to install, run or print the packages.

The -g flag forces gobin to perform a network fetch for the provided main
packages.
The -run, -p and -d flags are mutually exclusive.

The -n flag prevents network access and instead uses the GOPATH module download
cache where required.
It is an error for a non-main package to be provided as a package argument.

The -g and -n flags are mutually exclusive.

The -m flag causes gobin to use the main module (the module containing the
directory where the gobin command is run). The main module is given by go env
GOMOD. Without this flag gobin effectively runs as a "global" tool.
Cache directories
=================

It is an error for a non-main package to be provided as a package argument.
gobin maintains a cache of executables, separate from any executables that may
be installed to $GOBIN.

By default, gobin uses the directories gobin/$module@$version/$main_pkg under
your user cache directory. See the documentation for os.UserCacheDir for
OS-specific details on how to configure its location.

When the -m flag is provided, gobin uses the directories
.gobincache/$module@$version/$main_pkg under the directory containing the main
module's go.mod.

```
<!-- END -->
Expand All @@ -296,8 +310,3 @@ It is an error for a non-main package to be provided as a package argument.
* [mvdan](https://github.com/mvdan)
* [rogpeppe](https://github.com/rogpeppe)

### Notes

In the context of https://github.com/golang/go/issues/24250 and https://github.com/golang/go/issues/27653, this is a WIP
experiment. This project may die, move, etc at any time, until further notice.

80 changes: 47 additions & 33 deletions help.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,56 +17,70 @@ var mainHelpTemplate = `
The gobin command installs/runs main packages.

Usage:
gobin [-m] [-r|-p] [-n|-g] packages [run arguments...]
gobin [-m] [-run|-p|-d] [-u|-nonet] packages [run arguments...]

The packages argument to gobin is similar to that of the go tool (in module
mode) with the additional constraint that the list of packages must be main
packages.
The gobin command builds, installs, and possibly runs an executable binary for
each of the named main packages.

By default, gobin is said to operate in global mode. If the -m flag is provided
then it is said to operate in main-module mode, where the path to the main
module's go.mod is given by go env GOMOD.
The packages argument to gobin is similar to that of the go get command (in
module aware mode) with the additional constraint that the list of packages
must be main packages. Each argument takes the form $main_pkg[@$version].

The version "latest" matches the latest available tagged version. If no version
is specified, gobin behaves differently in global and main-module modes. In
global mode, gobin attempts to resolve the latest version available in the
module download cache. In main-module module, gobin attempts to resolve the
current version via the main module's go.mod. If this resolution fails in
either mode, "latest" is assumed and gobin resolves via the network.
By default, gobin will use the main package's module to resolve its
dependencies, unless the -m flag is specified, in which case dependencies will
be resolved using the main module (as given by go env GOMOD).

In global mode, gobin installs the main packages to the directories
gobin/$module@$version/$main_pkg under your user cache directory. See the
documentation for os.UserCacheDir for OS-specific details on how to configure
its location.
This means that gobin $package@v1.2.3 is a repeatable way to install an exact
version of a binary (assuming it has an associated go.mod file).

In main-module mode, gobin installs the main packages to the directories
.gobincache/$module@$version/$main_pkg under the directory containing the main
module's go.mod.
The version "latest" matches the latest available tagged version for the module
containing the main package. If gobin is able to resolve "latest" within the
module download cache it will use that version. Otherwise, gobin will make a
network request to resolve "latest". The -u flag forces gobin to check the
network for the latest tagged version. If the -nonet flag is provided, gobin
will only check the module download cache. Hence, the -u and -nonet flags are
mutually exclusive.

Versions that take the form of a revision identifier (a branch name, for
example) can only be resolved with a network request and hence are incompatible
with -nonet.

If no version is specified for a main package, gobin behaves differently
depending on whether the -m flag is provided. If the -m flag is not provided,
gobin $module is equivalent to gobin $module@latest. If the -m flag is
provided, gobin attempts to resolve the current version via the main module's
go.mod; if this resolution fails, "latest" is assumed as the version.

By default, gobin installs the main packages to $GOBIN (or $GOPATH/bin if GOBIN
is not set, which defaults to $HOME/go/bin if GOPATH is not set).

The -r flag takes exactly one main package argument and runs that package. It
is similar therefore to go run. Any arguments after the single main package
The -run flag takes exactly one main package argument and runs that package.
It is similar therefore to go run. Any arguments after the single main package
will be passed to the main package as command line arguments.

The -p flag prints the cache install path for each of the provided packages
The -p flag prints the gobin cache path for each of the packages' executables
once versions have been resolved.

The -r and -p flags are mutually exclusive.
The -d flag instructs gobin to stop after installing the packages to the gobin
cache; that is, it instructs gobin not to install, run or print the packages.

The -run, -p and -d flags are mutually exclusive.

The -g flag forces gobin to perform a network fetch for the provided main
packages.
It is an error for a non-main package to be provided as a package argument.

The -n flag prevents network access and instead uses the GOPATH module download
cache where required.

The -g and -n flags are mutually exclusive.
Cache directories
=================

The -m flag causes gobin to use the main module (the module containing the
directory where the gobin command is run). The main module is given by go env
GOMOD. Without this flag gobin effectively runs as a "global" tool.
gobin maintains a cache of executables, separate from any executables that may
be installed to $GOBIN.

It is an error for a non-main package to be provided as a package argument.
By default, gobin uses the directories gobin/$module@$version/$main_pkg under
your user cache directory. See the documentation for os.UserCacheDir for
OS-specific details on how to configure its location.

When the -m flag is provided, gobin uses the directories
.gobincache/$module@$version/$main_pkg under the directory containing the main
module's go.mod.

`[1:]
24 changes: 10 additions & 14 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@ const (
var (
exitCode = 0

fMainMod = flag.Bool("m", false, "use main module")
fRun = flag.Bool("r", false, "run main package")
fPrint = flag.Bool("p", false, "print gobin cache location for main packages")
fGet = flag.Bool("g", false, "force gobin to check the network for main packages")
fNoNet = flag.Bool("n", false, "prevent network access")
fMainMod = flag.Bool("m", false, "use resolve dependencies via the main module (as given by go env GOMOD)")
fRun = flag.Bool("run", false, "run the provided main package")
fPrint = flag.Bool("p", false, "print gobin install cache location for main packages")
fDownload = flag.Bool("d", false, "stop after installing main packages to the gobin install cache")
fUpgrade = flag.Bool("u", false, "check for the latest tagged version of main packages")
fNoNet = flag.Bool("nonet", false, "prevent network access")

fDebug = flag.Bool("debug", false, "print debug information")
)
Expand Down Expand Up @@ -65,7 +66,7 @@ func mainerr() error {
return fmt.Errorf("the -p and -r flags are mutually exclusive")
}

if *fGet && *fNoNet {
if *fUpgrade && *fNoNet {
return fmt.Errorf("the -n and -g flags are mutually exclusive")
}

Expand Down Expand Up @@ -174,16 +175,9 @@ func mainerr() error {
}
}

if !*fGet {
if !*fUpgrade {
// local resolution step
for _, pkg := range allPkgs {
if !*fNoNet && pkg.verPatt == "latest" {
// in case we are allowed to hit the network, that will have the
// definitive answer on latest
netPkgs = append(netPkgs, pkg)
continue
}

proxy := "GOPROXY=file://" + modDlCache

useModCurr := *fMainMod && pkg.verPatt == ""
Expand Down Expand Up @@ -305,6 +299,8 @@ func mainerr() error {
debugf("ran [%v] in [%v] with [GOBIN=%v, GOPROXY=%v] in %v\n", strings.Join(installCmd.Args, " "), pkg.wd, gobin, proxy, time.Now().Sub(start))

switch {
case *fDownload:
// noop
case *fPrint:
fmt.Println(target)
case *fRun:
Expand Down
Loading