Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gpm bootstrap command #19

Closed
wants to merge 2 commits into from
Closed
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
123 changes: 112 additions & 11 deletions bin/gpm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
set -eu

## Functions/

## Prints out usage information
#
usage() {
cat << EOF
SYNOPSIS
Expand All @@ -27,47 +30,145 @@ SYNOPSIS

USAGE
$ gpm # Same as 'install'.

$ gpm install # Parses the Godeps file, installs dependencies and sets
# them to the appropriate version.

$ gpm bootstrap # Downloads all external top-level packages required by
# your application and generates a Godeps file with their
# latest tags or revisions.

$ gpm version # Outputs version information

$ gpm help # Prints this message
EOF
}

# Iterates over Godep file dependencies and sets
# the specified version on each of them.
## Iterates over Godep file dependencies and sets
## the specified version on each of them.
#
set_dependencies() {
deps=$(sed 's/#.*//;/^\s*$/d' < "Godeps") || echo ""

while read package version; do
(
install_path="${GOPATH%%:*}/src/${package%%/...}"
[[ -e "$install_path/.git/index.lock" ||
-e "$install_path/.hg/store/lock" ||
-e "$install_path/.bzr/checkout/lock" ]] && wait
echo ">> Getting package "$package""
go get -u -d "$package"
echo ">> Setting $package to version $version"
cd $install_path
[ -d .hg ] && hg update -q "$version"
[ -d .git ] && git checkout -q "$version"
[ -d .bzr ] && bzr revert -q -r "$version"
set_package_to_version $package $version
) &
done < <(echo "$deps")
wait
echo ">> All Done"
}

## Sets a given package to a given revision using
## the appropriate VCS.
#
set_package_to_version() {
cd "${GOPATH%%:*}/src/${1%%/...}"

## Avoid multiple processes messing with the same
## package at the same time.
[[ -e "$PWD/.git/index.lock" ||
-e "$PWD/.hg/store/lock" ||
-e "$PWD/.bzr/checkout/lock" ]] && wait

[ -d .hg ] && hg update -q "$2"
[ -d .git ] && git checkout -q "$2"
[ -d .bzr ] && bzr revert -q -r "$2"
}

## Gets external dependencies from the Go project, determines
## their latest tags (or failing that, revisions), creates a
## Godeps file and installs al pertinent packages in their desired
## revisions.
#
bootstrap() {
echo ">> Installing dependencies."
go get -d
dependencies=`go list -f '{{join .Deps "\n"}}' |
xargs go list -f '{{if not .Standard}}{{.ImportPath}}{{end}}'`

while read package; do
#(
version=`find_last_tag_or_HEAD "$package"`
[ -n "$version" ] && (
echo ">> Adding package "$package" version "$version" to Godeps."
echo ""$package" "$version"" >> Godeps
set_package_to_version $package $version
)
#) &
done < <(echo "$dependencies")
#wait
echo ">> All Done."
}

## Returns the latest tag (or, failing that latest revision)
## for an installed package.
#
find_last_tag_or_HEAD() {
cd "${GOPATH%%:*}/src/${1%%/...}"

## If no repo file is found it means we are inside a repo's
## subdirectory tree, we can just ignore this package.
[ ! -d .git ] && [ ! -d .bzr ] && [ ! -d .hg ] &&
echo ">> Ignored $1, not top-level package." 1>&2 && return

[ -d .git ] && (
# FIXME: there should be a better way, but git tags returns in alphabetical order.
version=`git tag |
xargs -I@ git log --format=format:"%ai @%n" -1 @ |
sort |
awk '{print $4}' |
tail -1`


[ -n "$version" ] && echo "$version" && return

version=`git log -n 1 --pretty=oneline | cut -d " " -f 1`
echo ">> No tags on package "$1", setting version to latest revision." 1>&2
echo "$version" && return
)

[ -d .bzr ] && (
version=`bzr tags | tail -1 | cut -d " " -f 1`
[ -n "$version" ] && echo "$version" && return

version=`bzr log -r-1 --log-format=line | cut -d ":" -f 1`
echo ">> No tags on package "$1", setting version to latest revision." 1>&2
echo "$version" && return
)

[ -d .hg ] && (
version=`hg parents --template "{latesttag}"`

[ "$version" != "null" ] && echo "$version" && return

version=`hg log --template "{node}" -l 1`
echo ">> No tags on package "$1", setting version to latest_revision." 1>&2
echo "$version" && return
)

echo " "
}
## /Functions

case "${1:-"install"}" in
"version")
echo ">> gpm v1.0.1"
;;
"install")
[[ -f "Godeps" ]] || (echo ">> Godeps file does not exist." && exit 1)
(which go > /dev/null) || ( echo ">> Go is currently not installed or in your PATH" && exit 1)
(which go > /dev/null) ||
( echo ">> Go is currently not installed or in your PATH" && exit 1)
set_dependencies
;;
"bootstrap")
[[ -f "Godeps" ]] &&
echo ">> A Godeps file exists within this directory." && exit 1
bootstrap
;;
"help")
usage
;;
Expand Down