You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							322 lines
						
					
					
						
							8.4 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							322 lines
						
					
					
						
							8.4 KiB
						
					
					
				| #!/bin/sh -e | |
|  | |
| # Configuration | |
| 
 | |
| # Build/install-time directories | |
| dir_build='/var/tmp/astronaut/build'  # Temporary directory to build packages | |
| dir_source='/var/tmp/astronaut/source'  # Directory where the package sources will be placed | |
| dir_install='/var/tmp/astronaut/install'  # Directory where the package will be installed | |
| # The source directory will have subdirs for each different $name, | |
| #   specified inside the satellite file. | |
| # The $dir_install variable will have '{pkg}' replaced with $_satname, | |
| #   which is the filename of the satellite, without the .sat suffix. | |
| 
 | |
| # Runtime directories | |
| dir_sysroot=''  # The root directory of the system | |
| dir_prefix='/usr'  # Prefix directory (for /bin, /lib, /include, /share and such) | |
| 
 | |
| # Default commands | |
| cmd_download='curl -# -L -o {dst} {src}'  # Command to execute to download files | |
| cmd_extract='tar -x -C {dst} -f {src}'  # Command to execute to extract files | |
| 
 | |
| # If we can't find the satellite file,  we'll look in this directory for it. | |
| unset dir_satellites | |
| 
 | |
| # Options are comma-separated and parsed from front to back. | |
| # This means that in '!opt,someotheropt,opt', opt is disabled. | |
| 
 | |
| unset options  # The least-priority global options | |
| package_options() { :; }  # Per-package options function. | |
| # Example for package_options: | |
| # package_options() { | |
| #     case "$1" in | |
| #         package1) echo 'opt1,opt2,opt3' ;; | |
| #         package2) echo 'someotheropts' ;; | |
| #     esac | |
| # } | |
| 
 | |
| # Load any user configuration | |
| [ -f /etc/astronaut.conf ] && . /etc/astronaut.conf | |
| [ -f "$HOME/.astronaut.conf" ] && . "$HOME/.astronaut.conf" | |
| 
 | |
| # Options not in the configuration | |
| _download_only=false | |
| _vcs_only=false | |
| vcs_compile=false | |
| unset _user_options  # Options specified in the command line get the highest priority | |
| #_nuke_dir_install (This can be set from wrappers) | |
| 
 | |
| # Should be specified in the satellite | |
| unset name | |
| unset version | |
| unset update_url | |
| 
 | |
| # Some printing functions | |
| _show_help() { | |
| echo "This astronaut will help you build some satellites. | |
| Just describe what he's got to do in a satellite file. | |
| Usage: $0 [-sbipr <dir>] [-Id] [-o <options>] <satellite> | |
|  | |
| -h/? Show this message | |
| -b   Set build directory [WARNING: Will be deleted before build] | |
| -s   Set source directory | |
| -i   Set install directory | |
| -r   Set root directory | |
| -p   Set prefix directory | |
| -I   Nuke install directory before build [WARNING: You will not be prompted] | |
| -d   Only download package files | |
| -v   Only build vcs package if any updates have been made to it | |
| -o   Set package options (comma-separated) | |
|  | |
| Tips: | |
| - Use \`head -n 36 $0 > astronaut.conf.example\` to generate a default configuration file. | |
| - Keep in mind that when specifying options on the command line in a string, the first always takes priority. | |
|     For example, in \"opt,someotheropt,!opt\", opt is enabled, due to it being the first occurrence. | |
| - If you have set \$dir_satellites in the config, you can omit the .sat suffix. | |
| " | |
| } | |
| 
 | |
| _msg() { | |
|     echo "=> $@" | |
| } | |
| 
 | |
| _exiterr() { | |
|     echo "===> Houston, we've got a problem: $@" 1>&2 | |
|     exit 1 | |
| } | |
| 
 | |
| # Gather info | |
| while getopts "h?s:b:i:r:p:IcCdvo:" opt; do | |
|     case "$opt" in | |
|         h|\?) | |
|             _show_help | |
|             exit 0 | |
|             ;; | |
|         s) | |
|             dir_source="$OPTARG" | |
|             ;; | |
|         b) | |
|             dir_build="$OPTARG" | |
|             ;; | |
|         i) | |
|             dir_install="$OPTARG" | |
|             ;; | |
|         r) | |
|             dir_sysroot="$OPTARG" | |
|             ;; | |
|         p) | |
|             dir_prefix="$OPTARG" | |
|             ;; | |
|         I) | |
|             _nuke_dir_install=true | |
|             ;; | |
|         d) | |
|             _download_only=true | |
|             ;; | |
|         v) | |
|             _vcs_only=true | |
|             ;; | |
|         o) | |
|             _user_options="$OPTARG,$_user_options" | |
|             ;; | |
|     esac | |
| done | |
| 
 | |
| shift $((OPTIND-1)) | |
| [ "$1" = "--" ] && shift | |
| 
 | |
| if [ ! "$1" ]; then | |
|     _show_help | |
|     exit 1 | |
| fi | |
| 
 | |
| # Tools for the astronaut | |
| _mksum() { | |
|     echo "$(md5sum "$@" 2> /dev/null | cut -d' ' -f1)" | |
| } | |
| 
 | |
| _safe_sed() { | |
|     echo "$1" | sed 's/[[\.*^$/]/\\&/g' | |
| } | |
| 
 | |
| download() { | |
|     mkdir -p "$dir_source/$name" | |
| 
 | |
|     local filename="$(basename "$1" | cut -d? -f1)" | |
|     local path="$dir_source/$name/$filename" | |
| 
 | |
|     [ "$2" -a -f "$path" ] && local checksum="$(_mksum "$path")" | |
| 
 | |
|     if [ ! -e "$path" -o "$checksum" != "$2" ]; then | |
|         _msg "Downloading $filename" | |
| 
 | |
|         [ "$3" ] && local cmd="$3" || local cmd="$cmd_download" | |
|         eval $(echo "$cmd" | sed -e "s@{dst}@'$(_safe_sed "$path")'@g" -e "s@{src}@'$(_safe_sed "$1")'@g") | |
| 
 | |
|         checksum="$(_mksum "$path")" | |
|         if [ "$2" -a "$checksum" != "$2" ]; then | |
|             _msg "Checksum: $checksum" | |
|             _exiterr 'Checksum failed' | |
|         fi | |
|     fi | |
| } | |
| 
 | |
| extract() { | |
|     _msg "Extracting $1" | |
|     [ "$2" ] && local dest="$2" || local dest='.' | |
|     [ "$3" ] && local cmd="$3" || local cmd="$cmd_extract" | |
|     eval $(echo "$cmd" | sed -e "s@{src}@'$dir_source/$name/$1'@g" -e "s@{dst}@'$dest'@g") | |
| } | |
| 
 | |
| getfile() { | |
|     cp -r "$dir_source/$name/$1" "$dir_build/$1" | |
| } | |
| 
 | |
| extrafile() { | |
|     cp "$(dirname "$_satellite")/extrafiles/$_satname/$1" "$dir_build/$1" | |
| } | |
| 
 | |
| dlextract() { | |
|     download "$1" "$2" | |
|     extract "$(basename "$1" | cut -d? -f1)" | |
| } | |
| 
 | |
| dlfile() { | |
|     download "$1" "$2" | |
|     getfile "$(basename "$1" | cut -d? -f1)" | |
| } | |
| 
 | |
| option() { | |
|     local check=$1 | |
|     shift | |
| 
 | |
|     local negate=false | |
|     local variable=false | |
|     case "$check" in | |
|         *=*) | |
|             local variable=true | |
|             local default="$(echo "$check" | cut -d '=' -f 2)" | |
|             local check="$(echo "$check" | cut -d '=' -f 1)" | |
|             ;; | |
|         !*) | |
|             local negate=true | |
|             local check="$(echo "$check" | cut -c 2-)" | |
|             ;; | |
|     esac | |
| 
 | |
|     local enabled=false | |
|     local opt | |
|     local IFS=','; for option in $options; do | |
|         local option_negate=false | |
|         case "$option" in | |
|             *=*) | |
|                 local value="$(echo "$option" | cut -d '=' -f 2)" | |
|                 local option="$(echo "$option" | cut -d '=' -f 1)" | |
|                 ;; | |
|             !*) | |
|                 local option="$(echo "$option" | cut -c 2-)" | |
|                 local option_negate=true | |
|         esac | |
| 
 | |
|         if [ "$option" = "$check" ]; then | |
|             [ "$option_negate" = true ] && local enabled=false || local enabled=true | |
|             break | |
|         fi | |
|     done | |
| 
 | |
|     if [ "$variable" = true ]; then | |
|         if [ "$enabled" = true ]; then | |
|             echo "$value" | |
|             return | |
|         else | |
|             echo "$default" | |
|             return | |
|         fi | |
|     fi | |
| 
 | |
|     if [ "$negate" = true ]; then | |
|         # Shitty way to do a simple "NOT" operation. | |
|         [ "$enabled" = true ] && local enabled=false || local enabled=true | |
|     fi | |
| 
 | |
|     if [ "$1" ]; then | |
|         if [ "$enabled" = true ]; then | |
|             eval $@ | |
|         fi | |
|     else | |
|         return $([ "$enabled" = true ]) | |
|     fi | |
| } | |
| 
 | |
| import() { | |
|     . "$(dirname "$_satellite")/functions/$1.sh" | |
| } | |
| 
 | |
| # Set some functions in accordance to the _download_only option. | |
| header_end() { :; } | |
| if [ "$_vcs_only" = true ]; then | |
|     header_end() { | |
|         if [ ! "$vcs_compile" = true ]; then | |
|             exit | |
|         fi | |
|     } | |
| fi | |
| if [ "$_download_only" = true ]; then | |
|     # Disable some functions | |
|     extract() { :; } | |
|     getfile() { :; } | |
|     extrafile() { :; } | |
| 
 | |
|     # Exit at the end of the header | |
|     header_end() { exit; } | |
| fi | |
| 
 | |
| _satellite="$1" | |
| _satname="$(basename "$_satellite" .sat)" | |
| 
 | |
| # Try to find the satellite file if it can't be found. | |
| if [ ! -f "$_satellite" ]; then | |
|     if [ -d "$dir_satellites" ]; then | |
|         file="$(find "$dir_satellites" -type f \( -name "$_satname.sat" -o -name "$_satname" \) -print -quit)" | |
|         if [ -f "$file" ]; then | |
|             _satellite="$file" | |
|             _satname="$(basename "$_satellite" .sat)" | |
|         fi | |
|     fi | |
| 
 | |
|     # If it still can't be found, exit. | |
|     if [ ! -f "$_satellite" ]; then | |
|         _exiterr "Can't find satellite" | |
|     fi | |
| fi | |
| 
 | |
| _satellite="$(realpath "$_satellite")" | |
| 
 | |
| # Build the definitive options list | |
| options="$_user_options$(package_options "$_satname"),$options" | |
| 
 | |
| # Create the directories | |
| mkdir -p "$dir_source" | |
| dir_source="$(realpath "$dir_source")" | |
| 
 | |
| if [ "$_download_only" = false ]; then | |
|     # Fix up the install path | |
|     dir_install="$(echo "$dir_install" | sed -e "s@{pkg}@$(_safe_sed "$satname")@g")" | |
| 
 | |
|     # This variable can be set by a wrapper script in need to nuke the install dir. | |
|     if [ "$_nuke_dir_install" = true -a ! -z "$dir_install" ]; then | |
|         rm -rf "$dir_install" | |
|     fi | |
| 
 | |
|     rm -rf "$dir_build" | |
|     mkdir -p "$dir_build" | |
|     mkdir -p "$dir_install" | |
|     dir_build="$(realpath "$dir_build")" | |
|     dir_install="$(realpath "$dir_install")" | |
|     dir_sysroot="$(realpath "$dir_sysroot")" | |
| 
 | |
|     cd "$dir_build" | |
| fi | |
| 
 | |
| # Create the satellite | |
| . "$_satellite"
 | |
| 
 |