Skip to content

Commit

Permalink
Adding basic CLI infrastructure
Browse files Browse the repository at this point in the history
  • Loading branch information
armon committed Dec 19, 2013
1 parent d31e082 commit 1c5a8d0
Show file tree
Hide file tree
Showing 9 changed files with 248 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -21,3 +21,4 @@ _testmain.go

*.exe
*.test
bin/
38 changes: 38 additions & 0 deletions command/version.go
@@ -0,0 +1,38 @@
package command

import (
"bytes"
"fmt"
"github.com/mitchellh/cli"
)

// VersionCommand is a Command implementation prints the version.
type VersionCommand struct {
Revision string
Version string
VersionPrerelease string
Ui cli.Ui
}

func (c *VersionCommand) Help() string {
return ""
}

func (c *VersionCommand) Run(_ []string) int {
var versionString bytes.Buffer
fmt.Fprintf(&versionString, "Consul v%s", c.Version)
if c.VersionPrerelease != "" {
fmt.Fprintf(&versionString, ".%s", c.VersionPrerelease)

if c.Revision != "" {
fmt.Fprintf(&versionString, " (%s)", c.Revision)
}
}

c.Ui.Output(versionString.String())
return 0
}

func (c *VersionCommand) Synopsis() string {
return "Prints the Consul version"
}
10 changes: 10 additions & 0 deletions command/version_test.go
@@ -0,0 +1,10 @@
package command

import (
"github.com/mitchellh/cli"
"testing"
)

func TestVersionCommand_implements(t *testing.T) {
var _ cli.Command = &VersionCommand{}
}
44 changes: 44 additions & 0 deletions commands.go
@@ -0,0 +1,44 @@
package main

import (
"github.com/hashicorp/consul/command"
"github.com/mitchellh/cli"
"os"
"os/signal"
)

// Commands is the mapping of all the available Serf commands.
var Commands map[string]cli.CommandFactory

func init() {
ui := &cli.BasicUi{Writer: os.Stdout}

Commands = map[string]cli.CommandFactory{
"version": func() (cli.Command, error) {
return &command.VersionCommand{
Revision: GitCommit,
Version: Version,
VersionPrerelease: VersionPrerelease,
Ui: ui,
}, nil
},
}
}

// makeShutdownCh returns a channel that can be used for shutdown
// notifications for commands. This channel will send a message for every
// interrupt received.
func makeShutdownCh() <-chan struct{} {
resultCh := make(chan struct{})

signalCh := make(chan os.Signal, 4)
signal.Notify(signalCh, os.Interrupt)
go func() {
for {
<-signalCh
resultCh <- struct{}{}
}
}()

return resultCh
}
43 changes: 43 additions & 0 deletions main.go
@@ -0,0 +1,43 @@
package main

import (
"fmt"
"github.com/mitchellh/cli"
"io/ioutil"
"log"
"os"
)

func main() {
os.Exit(realMain())

This comment has been minimized.

Copy link
@AlekSi

AlekSi Sep 15, 2016

A lot of people in our chat are curious why you decided to extract realMain. A lot of opinions were said, but we don't know if any is correct. Can you tell us the Truth?

}

func realMain() int {
log.SetOutput(ioutil.Discard)

// Get the command line args. We shortcut "--version" and "-v" to
// just show the version.
args := os.Args[1:]
for _, arg := range args {
if arg == "-v" || arg == "--version" {
newArgs := make([]string, len(args)+1)
newArgs[0] = "version"
copy(newArgs[1:], args)
args = newArgs
break
}
}

cli := &cli.CLI{
Args: args,
Commands: Commands,
}

exitCode, err := cli.Run()
if err != nil {
fmt.Fprintf(os.Stderr, "Error executing CLI: %s\n", err.Error())
return 1
}

return exitCode
}
1 change: 1 addition & 0 deletions main_test.go
@@ -0,0 +1 @@
package main
34 changes: 34 additions & 0 deletions scripts/build.sh
@@ -0,0 +1,34 @@
#!/bin/bash
#
# This script builds the application from source.
set -e

# Get the parent directory of where this script is.
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ] ; do SOURCE="$(readlink "$SOURCE")"; done
DIR="$( cd -P "$( dirname "$SOURCE" )/.." && pwd )"

# Change into that directory
cd $DIR

# Get the git commit
GIT_COMMIT=$(git rev-parse HEAD)
GIT_DIRTY=$(test -n "`git status --porcelain`" && echo "+CHANGES" || true)

# If we're building on Windows, specify an extension
EXTENSION=""
if [ "$(go env GOOS)" = "windows" ]; then
EXTENSION=".exe"
fi

# Install dependencies
echo "--> Installing dependencies to speed up builds..."
go get ./...

# Build!
echo "--> Building..."
go build \
-ldflags "-X main.GitCommit ${GIT_COMMIT}${GIT_DIRTY}" \
-v \
-o bin/consul${EXTENSION}
cp bin/consul${EXTENSION} $GOPATH/bin
65 changes: 65 additions & 0 deletions scripts/dist.sh
@@ -0,0 +1,65 @@
#!/bin/bash
set -e

# Get the parent directory of where this script is.
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ] ; do SOURCE="$(readlink "$SOURCE")"; done
DIR="$( cd -P "$( dirname "$SOURCE" )/.." && pwd )"

# Change into that dir because we expect that
cd $DIR

# Determine the version that we're building based on the contents
# of packer/version.go.
VERSION=$(grep "const Version " version.go | sed -E 's/.*"(.+)"$/\1/')
VERSIONDIR="${VERSION}"
PREVERSION=$(grep "const VersionPrerelease " version.go | sed -E 's/.*"(.*)"$/\1/')
if [ ! -z $PREVERSION ]; then
PREVERSION="${PREVERSION}.$(date -u +%s)"
VERSIONDIR="${VERSIONDIR}-${PREVERSION}"
fi

echo "Version: ${VERSION} ${PREVERSION}"

# Determine the arch/os combos we're building for
XC_ARCH=${XC_ARCH:-"386 amd64 arm"}
XC_OS=${XC_OS:-linux darwin windows freebsd openbsd}

echo "Arch: ${XC_ARCH}"
echo "OS: ${XC_OS}"

# Make sure that if we're killed, we kill all our subprocseses
trap "kill 0" SIGINT SIGTERM EXIT

# This function builds whatever directory we're in...
goxc \
-arch="$XC_ARCH" \
-os="$XC_OS" \
-d="${DIR}/pkg" \
-pv="${VERSION}" \
-pr="${PREVERSION}" \
$XC_OPTS \
go-install \
xc

# Zip all the packages
mkdir -p ./pkg/${VERSIONDIR}/dist
for PLATFORM in $(find ./pkg/${VERSIONDIR} -mindepth 1 -maxdepth 1 -type d); do
PLATFORM_NAME=$(basename ${PLATFORM})
ARCHIVE_NAME="${VERSIONDIR}_${PLATFORM_NAME}"

if [ $PLATFORM_NAME = "dist" ]; then
continue
fi

pushd ${PLATFORM}
zip ${DIR}/pkg/${VERSIONDIR}/dist/${ARCHIVE_NAME}.zip ./*
popd
done

# Make the checksums
pushd ./pkg/${VERSIONDIR}/dist
shasum -a256 * > ./${VERSIONDIR}_SHA256SUMS
popd

exit 0
12 changes: 12 additions & 0 deletions version.go
@@ -0,0 +1,12 @@
package main

// The git commit that was compiled. This will be filled in by the compiler.
var GitCommit string

// The main version number that is being run at the moment.
const Version = "0.1.0"

// A pre-release marker for the version. If this is "" (empty string)
// then it means that it is a final release. Otherwise, this is a pre-release
// such as "dev" (in development), "beta", "rc1", etc.
const VersionPrerelease = "dev"

0 comments on commit 1c5a8d0

Please sign in to comment.