You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			326 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Bash
		
	
			
		
		
	
	
			326 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Bash
		
	
#!/usr/bin/env bash
 | 
						|
. "$GVM_ROOT/scripts/functions"
 | 
						|
 | 
						|
function show_usage() {
 | 
						|
	echo "Usage: gvm install [version] [options]"
 | 
						|
	echo "    -s,  --source=SOURCE      Install Go from specified source."
 | 
						|
	echo "    -n,  --name=NAME          Override the default name for this version."
 | 
						|
	echo "    -pb, --with-protobuf      Install Go protocol buffers."
 | 
						|
	echo "    -b,  --with-build-tools   Install package build tools."
 | 
						|
	echo "    -B,  --binary             Only install from binary."
 | 
						|
	echo "         --prefer-binary      Attempt a binary install, falling back to source."
 | 
						|
	echo "    -h,  --help               Display this message."
 | 
						|
}
 | 
						|
 | 
						|
read_command_line() {
 | 
						|
	VERSION=$1
 | 
						|
	if [[ "${VERSION:0:1}" != "-" ]]; then
 | 
						|
		shift
 | 
						|
	else
 | 
						|
		display_warning "Invalid version: $1"
 | 
						|
		show_usage
 | 
						|
		exit 1
 | 
						|
	fi
 | 
						|
	GO_SOURCE_URL=https://go.googlecode.com/hg/
 | 
						|
	for i in "$@"; do
 | 
						|
		case $i in
 | 
						|
			-s=*|--source=*)
 | 
						|
				GO_SOURCE_URL=$(echo "$i" | sed 's/[-a-zA-Z0-9]*=//')
 | 
						|
			;;
 | 
						|
			-n=*|--name=*)
 | 
						|
				GO_NAME=$(echo "$i" | sed 's/[-a-zA-Z0-9]*=//')
 | 
						|
			;;
 | 
						|
			-pb|--with-protobuf)
 | 
						|
				INSTALL_PB="true"
 | 
						|
			;;
 | 
						|
			-b|--with-build-tools)
 | 
						|
				INSTALL_BUILD_TOOLS="true"
 | 
						|
			;;
 | 
						|
			-B|--binary)
 | 
						|
				INSTALL_SOURCE="binary"
 | 
						|
			;;
 | 
						|
			--prefer-binary)
 | 
						|
			  INSTALL_SOURCE="prefer-binary"
 | 
						|
			;;
 | 
						|
			-h|--help)
 | 
						|
				show_usage
 | 
						|
				exit 0
 | 
						|
			;;
 | 
						|
			*)
 | 
						|
				display_warning "Invalid option $i"
 | 
						|
				show_usage
 | 
						|
				exit 65 # Bad arguments
 | 
						|
			;;
 | 
						|
		esac
 | 
						|
	done
 | 
						|
}
 | 
						|
 | 
						|
download_source() {
 | 
						|
	GO_CACHE_PATH=$GVM_ROOT/archive/go
 | 
						|
	[[ -d $GO_CACHE_PATH ]] && return
 | 
						|
	display_message "Downloading Go source..."
 | 
						|
	hg clone "$GO_SOURCE_URL" "$GO_CACHE_PATH" >> "$GVM_ROOT/logs/go-download.log"  2>&1 ||
 | 
						|
		display_fatal "Couldn't download Go source. Check the logs $GVM_ROOT/logs/go-download.log"
 | 
						|
}
 | 
						|
 | 
						|
check_tag() {
 | 
						|
	version=$(hg tags -R "$GO_CACHE_PATH" | awk '{print $1}' | $SORT_PATH | $GREP_PATH "$VERSION" | $HEAD_PATH -n 1 | $GREP_PATH -w "$VERSION")
 | 
						|
}
 | 
						|
 | 
						|
update_source() {
 | 
						|
	display_message "Updating Go source..."
 | 
						|
	hg pull -R "$GO_CACHE_PATH" >> "$GVM_ROOT/logs/go-download.log" 2>&1 ||
 | 
						|
		display_fatal "Couldn't get latest Go version info. Check the logs $GVM_ROOT/logs/go-download.log"
 | 
						|
}
 | 
						|
 | 
						|
copy_source() {
 | 
						|
	hg clone -u "$version" "$GO_CACHE_PATH" "$GO_INSTALL_ROOT" >> "$GVM_ROOT/logs/go-$GO_NAME-install.log" 2>&1 ||
 | 
						|
		display_fatal "Couldn't copy source to target folder. Check the logs $GVM_ROOT/logs/go-$GO_NAME-install.log"
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
compile_go() {
 | 
						|
	display_message " * Compiling..."
 | 
						|
	unset GOARCH && unset GOOS && unset GOPATH && unset GOBIN && unset GOROOT &&
 | 
						|
	export GOBIN=$GO_INSTALL_ROOT/bin &&
 | 
						|
	export PATH=$GOBIN:$PATH &&
 | 
						|
	export GOROOT=$GO_INSTALL_ROOT &&
 | 
						|
	#cd $GO_INSTALL_ROOT/src && ./all.bash &> $GVM_ROOT/logs/go-$GO_NAME-compile.log ||
 | 
						|
	cd "$GO_INSTALL_ROOT/src" && ./make.bash &> "$GVM_ROOT/logs/go-$GO_NAME-compile.log" ||
 | 
						|
		(rm -rf "$GO_INSTALL_ROOT" && display_fatal "Failed to compile. Check the logs at $GVM_ROOT/logs/go-$GO_NAME-compile.log")
 | 
						|
}
 | 
						|
 | 
						|
create_enviroment() {
 | 
						|
	new_env_file=$GVM_ROOT/environments/$GO_NAME
 | 
						|
	echo "export GVM_ROOT; GVM_ROOT=\"$GVM_ROOT\"" > "$new_env_file"
 | 
						|
	echo "export gvm_go_name; gvm_go_name=\"$GO_NAME\"" >> "$new_env_file"
 | 
						|
	echo "export gvm_pkgset_name; gvm_pkgset_name=\"global\"" >> "$new_env_file"
 | 
						|
	echo "export GOROOT; GOROOT=\"\$GVM_ROOT/gos/$GO_NAME\"" >> "$new_env_file"
 | 
						|
	echo "export GOPATH; GOPATH=\"\$GVM_ROOT/pkgsets/$GO_NAME/global\"" >> "$new_env_file"
 | 
						|
	echo "export GVM_OVERLAY_PREFIX; GVM_OVERLAY_PREFIX=\"\${GVM_ROOT}/pkgsets/${GO_NAME}/global/overlay\"" >> "$new_env_file"
 | 
						|
	echo "export PATH; PATH=\"\${GVM_ROOT}/pkgsets/${GO_NAME}/global/bin:\${GVM_ROOT}/gos/${GO_NAME}/bin:\${GVM_OVERLAY_PREFIX}/bin:\${GVM_ROOT}/bin:\${PATH}\"" >> "$new_env_file"
 | 
						|
	echo "export LD_LIBRARY_PATH; LD_LIBRARY_PATH=\"\${GVM_OVERLAY_PREFIX}/lib:\${LD_LIBRARY_PATH}\"" >> "$new_env_file"
 | 
						|
	echo "export DYLD_LIBRARY_PATH; DYLD_LIBRARY_PATH=\"\${GVM_OVERLAY_PREFIX}/lib:\${DYLD_LIBRARY_PATH}\"" >> "$new_env_file"
 | 
						|
	echo "export PKG_CONFIG_PATH; PKG_CONFIG_PATH=\"\${GVM_OVERLAY_PREFIX}/lib/pkgconfig:\${PKG_CONFIG_PATH}\"" >> "$new_env_file"
 | 
						|
	. "$GVM_ROOT/scripts/env/use"
 | 
						|
	. "$GVM_ROOT/scripts/env/implode"
 | 
						|
	gvm_use "$GO_NAME" &> /dev/null ||
 | 
						|
		display_fatal "Failed to use installed version"
 | 
						|
	gvm pkgset create global
 | 
						|
	unset GOPATH
 | 
						|
}
 | 
						|
 | 
						|
create_global_package_set() {
 | 
						|
	# Create the global package set folder
 | 
						|
	mkdir -p "$GVM_ROOT/pkgsets/$GO_NAME" >> "$GVM_ROOT/logs/go-$GO_NAME-install.log" 2>&1 ||
 | 
						|
		display_fatal "Couldn't create global package set folder. Check the logs at ${GVM_ROOT}/logs/go-${GO_NAME}-install.log"
 | 
						|
	GVM_OVERLAY_ROOT="${GVM_ROOT}/pkgsets/${GO_NAME}/global/overlay"
 | 
						|
	mkdir -p "${GVM_OVERLAY_ROOT}/lib/pkgconfig" >> "${GVM_ROOT}/logs/go-${GO_NAME}-install.log" 2>&1 ||
 | 
						|
		display_fatal "Couldn't create global overlay library directory. Check the logs at ${GVM_ROOT}/logs/go-${GO_NAME}-install.log"
 | 
						|
	mkdir -p "${GVM_OVERLAY_ROOT}/bin" >> "${GVM_ROOT}/logs/go-${GO_NAME}-install.log" 2>&1 ||
 | 
						|
		display_fatal "Couldn't create global overlay bin directory. Check the logs at ${GVM_ROOT}/logs/go-${GO_NAME}-install.log"
 | 
						|
}
 | 
						|
 | 
						|
install_go() {
 | 
						|
	GO_INSTALL_ROOT=$GVM_ROOT/gos/$GO_NAME
 | 
						|
	trap 'rm -rf $GO_INSTALL_ROOT; display_fatal "Cancelled!"' INT
 | 
						|
 | 
						|
	# Check for existing install
 | 
						|
	if [[ -d "$GO_INSTALL_ROOT" ]]; then
 | 
						|
		if [[ -f "$GO_INSTALL_ROOT/manifest" ]]; then
 | 
						|
			display_message "Already installed!"
 | 
						|
			exit 0
 | 
						|
		fi
 | 
						|
		display_warning "Removing corrupt install..."
 | 
						|
		gvm uninstall "$GO_NAME"
 | 
						|
	fi
 | 
						|
 | 
						|
	if [[ "$version" != "$GO_NAME" ]]; then
 | 
						|
		display_message "Installing $version as $GO_NAME..."
 | 
						|
	else
 | 
						|
		display_message "Installing $version..."
 | 
						|
	fi
 | 
						|
 | 
						|
	create_global_package_set
 | 
						|
	copy_source
 | 
						|
	compile_go
 | 
						|
	create_enviroment
 | 
						|
}
 | 
						|
 | 
						|
download_binary() {
 | 
						|
	mkdir -p $GO_INSTALL_ROOT >> "${GVM_ROOT}/logs/go-${GO_NAME}-download-binary" 2>&1
 | 
						|
 | 
						|
	if [ "$(uname)" == "Darwin" ]; then
 | 
						|
		GVM_OS="darwin"
 | 
						|
		osx_major_version="$(sw_vers -productVersion | cut -d "." -f 2)"
 | 
						|
		if [ "${osx_major_version}" -ge 8 ]; then
 | 
						|
			GVM_OS_VERSION="-osx10.8"
 | 
						|
		elif [ "${osx_major_version}" -ge 6 ]; then
 | 
						|
			GVM_OS_VERSION="-osx10.6"
 | 
						|
		else
 | 
						|
			display_error "Binary Go unavailable for this platform"
 | 
						|
			rm -rf $GO_INSTALL_ROOT
 | 
						|
			rm -f $GO_BINARY_PATH
 | 
						|
			exit 1
 | 
						|
		fi
 | 
						|
	else
 | 
						|
		GVM_OS="linux"
 | 
						|
	fi
 | 
						|
 | 
						|
	if [ "$(uname -m)" == "x86_64" ]; then
 | 
						|
		GVM_ARCH="amd64"
 | 
						|
	else
 | 
						|
		GVM_ARCH="386"
 | 
						|
	fi
 | 
						|
 | 
						|
	GO_BINARY_FILE=${VERSION}.${GVM_OS}-${GVM_ARCH}${GVM_OS_VERSION}.tar.gz
 | 
						|
	GO_BINARY_URL="http://golang.org/dl/${GO_BINARY_FILE}"
 | 
						|
	GO_BINARY_PATH=${GVM_ROOT}/archive/${GO_BINARY_FILE}
 | 
						|
 | 
						|
	if [ ! -f $GO_BINARY_PATH ]; then
 | 
						|
		curl -s -f -L $GO_BINARY_URL > ${GO_BINARY_PATH}
 | 
						|
 | 
						|
		if [[ $? -ne 0 ]]; then
 | 
						|
			display_error "Failed to download binary go from http://golang.org. Trying https://storage.googleapis.com"
 | 
						|
			GO_BINARY_URL="https://storage.googleapis.com/golang/${GO_BINARY_FILE}"
 | 
						|
 | 
						|
			curl -s -f -L $GO_BINARY_URL > ${GO_BINARY_PATH}
 | 
						|
 | 
						|
			if [[ $? -ne 0 ]]; then
 | 
						|
				display_error "Failed to download binary go"
 | 
						|
				rm -rf $GO_INSTALL_ROOT
 | 
						|
				rm -f $GO_BINARY_PATH
 | 
						|
				exit 1
 | 
						|
			fi
 | 
						|
		fi
 | 
						|
	fi
 | 
						|
 | 
						|
	tar zxf ${GO_BINARY_PATH} -C $GO_INSTALL_ROOT --strip-components 1 >> "${GVM_ROOT}/logs/go-${GO_NAME}-download-binary" 2>&1
 | 
						|
 | 
						|
	if [[ $? -ne 0 ]]; then
 | 
						|
		display_error "Failed to extract binary go"
 | 
						|
		rm -rf $GO_INSTALL_ROOT
 | 
						|
		rm -f $GO_BINARY_PATH
 | 
						|
		exit 1
 | 
						|
	fi
 | 
						|
}
 | 
						|
 | 
						|
install_go_binary() {
 | 
						|
	GO_INSTALL_ROOT=$GVM_ROOT/gos/$GO_NAME
 | 
						|
	trap 'rm -rf $GO_INSTALL_ROOT; display_fatal "Cancelled!"' INT
 | 
						|
 | 
						|
	# Check for existing install
 | 
						|
	if [[ -d "$GO_INSTALL_ROOT" ]]; then
 | 
						|
		if [[ -f "$GO_INSTALL_ROOT/manifest" ]]; then
 | 
						|
			display_message "Already installed!"
 | 
						|
			exit 0
 | 
						|
		fi
 | 
						|
		display_warning "Removing corrupt install..."
 | 
						|
		gvm uninstall "$GO_NAME"
 | 
						|
	fi
 | 
						|
 | 
						|
	display_message "Installing $GO_NAME from binary source"
 | 
						|
 | 
						|
	create_global_package_set
 | 
						|
	download_binary
 | 
						|
	create_enviroment
 | 
						|
}
 | 
						|
 | 
						|
install_gpkg() {
 | 
						|
	display_message " * Installing gpkg..."
 | 
						|
	$GVM_GOINSTALL github.com/moovweb/gpkg > "$GVM_ROOT/logs/$GO_NAME-gpkg.log" 2>&1 || return 1
 | 
						|
}
 | 
						|
 | 
						|
install_gb() {
 | 
						|
	display_message " * Installing gb..."
 | 
						|
	$GVM_GOINSTALL github.com/jbussdieker/go-gb/gb > "$GVM_ROOT/logs/$GO_NAME-gb.log" 2>&1 || return 1
 | 
						|
}
 | 
						|
 | 
						|
install_goprotobuf() {
 | 
						|
	which protoc &> /dev/null || display_warning "Could not find protocol buffer compiler
 | 
						|
 | 
						|
  linux: apt-get install protobuf-compiler
 | 
						|
  mac:   brew install protobuf
 | 
						|
"
 | 
						|
	display_message " * Installing goprotobuf..."
 | 
						|
	if [[ "$GVM_GOINSTALL" == "goinstall" ]]; then
 | 
						|
		$GVM_GOINSTALL goprotobuf.googlecode.com/hg/proto > "$GVM_ROOT/logs/$GO_NAME-pb-compiler.log" 2>&1
 | 
						|
		if [[ $? -ne 0 ]]; then
 | 
						|
			display_warning "Failed to install goprotobuf. Check the logs at $GVM_ROOT/logs/$GO_NAME-pb-compiler.log"
 | 
						|
			return 1
 | 
						|
		fi
 | 
						|
		cd "$GVM_ROOT/gos/$GO_NAME/src/pkg/goprotobuf.googlecode.com/hg/compiler"
 | 
						|
		make install >> "$GVM_ROOT/logs/$GO_NAME-pb-compiler.log" 2>&1
 | 
						|
		if [[ $? -ne 0 ]]; then
 | 
						|
			display_warning "Failed to install goprotobuf compiler. Check the logs at $GVM_ROOT/logs/$GO_NAME-pb-compiler.log"
 | 
						|
			return 1
 | 
						|
		fi
 | 
						|
	else
 | 
						|
		$GVM_GOINSTALL code.google.com/p/goprotobuf/proto > "$GVM_ROOT/logs/$GO_NAME-pb-compiler.log" 2>&1
 | 
						|
		if [[ $? -ne 0 ]]; then
 | 
						|
			display_warning "Failed to install goprotobuf. Check the logs at $GVM_ROOT/logs/$GO_NAME-pb-compiler.log"
 | 
						|
			return 1
 | 
						|
		fi
 | 
						|
		$GVM_GOINSTALL code.google.com/p/goprotobuf/protoc-gen-go > "$GVM_ROOT/logs/$GO_NAME-pb-compiler.log" 2>&1
 | 
						|
		if [[ $? -ne 0 ]]; then
 | 
						|
			display_warning "Failed to install goprotobuf compiler. Check the logs at $GVM_ROOT/logs/$GO_NAME-pb-compiler.log"
 | 
						|
			return 1
 | 
						|
		fi
 | 
						|
	fi
 | 
						|
}
 | 
						|
 | 
						|
install_from_source() {
 | 
						|
	download_source
 | 
						|
	check_tag
 | 
						|
	if [[ "$?" == "1" ]]; then
 | 
						|
		update_source
 | 
						|
		check_tag || display_fatal "Unrecognized Go version"
 | 
						|
	fi
 | 
						|
	if [[ "$GO_NAME" == "" ]]; then
 | 
						|
		GO_NAME=$version
 | 
						|
	fi
 | 
						|
	install_go
 | 
						|
 | 
						|
	GVM_GOINSTALL="goinstall"
 | 
						|
	which goinstall &> /dev/null ||
 | 
						|
		GVM_GOINSTALL="go get"
 | 
						|
 | 
						|
	x="$(hg tags -R "$GO_CACHE_PATH")"; echo "${x#*b0819469a6df}" | $GREP_PATH "$version " &> /dev/null
 | 
						|
	if [[ "$?" == "1" ]]; then
 | 
						|
		if [[ "$INSTALL_BUILD_TOOLS" == "true" ]]; then
 | 
						|
			install_gb || display_warning "Failed to install gb"
 | 
						|
			install_gpkg || display_warning "Failed to install gpkg"
 | 
						|
		fi
 | 
						|
		if [[ "$INSTALL_PB" == "true" ]]; then
 | 
						|
			install_goprotobuf
 | 
						|
		fi
 | 
						|
	fi
 | 
						|
 | 
						|
	cd "$GO_INSTALL_ROOT" && find . > manifest
 | 
						|
}
 | 
						|
 | 
						|
main() {
 | 
						|
	trap 'display_fatal "Canceled!"' INT
 | 
						|
	read_command_line "$@"
 | 
						|
	[[ "$VERSION" == "" ]] && display_fatal "No version specified"
 | 
						|
 | 
						|
	if [[ "$GO_NAME" == "" ]]; then
 | 
						|
		GO_NAME=$VERSION
 | 
						|
	fi
 | 
						|
 | 
						|
	if [[ "x$INSTALL_SOURCE" == "xbinary" ]]; then
 | 
						|
		install_go_binary
 | 
						|
	elif [[ "x$INSTALL_SOURCE" == "xprefer-binary" ]]; then
 | 
						|
		install_go_binary || {
 | 
						|
			display_message "Falling back to source installation of $GO_NAME"
 | 
						|
			install_from_source
 | 
						|
		}
 | 
						|
	else
 | 
						|
		install_from_source
 | 
						|
	fi
 | 
						|
 | 
						|
	cd "$GO_INSTALL_ROOT" && find . > manifest
 | 
						|
}
 | 
						|
 | 
						|
main "$@"
 |