Build Helpers
The following helper functions can be useful in your plan to help you build your package correctly. Attach()
specifically is to help with debugging - the other helper functions are to help you in building your package.
Note
plan.ps1
). However in most cases, the standard Powershell cmdlets provide the same functionality. For example: use Resolve-Path
instead of abspath
or Get-Command
instead of exists
.- attach()
plan.sh
only. Attaches your script to an interactive debugging session, which lets you check the state of variables, call arbitrary functions, and turn on higher levels of logging by using theset -x
command and switch.To use attach, add
attach
to any callback or part of your plan.sh file and the debugging session with start up when hab-plan-build comes to that part in the file.
Note
Set-PSBreakpoint
for debugging plan.ps1 functions. You can set its -Command
parameter to any build phase function.- download_file()
plan.sh
only. Downloads a file from a source URL to a local file and uses an optional shasum to determine if an existing file can be used.
download_file <source_url> <local_file> [<shasum>]
If an existing file is present and the third argument is set with a shasum digest, the file will be checked to see if it’s valid. If so, the function ends early and returns 0. Otherwise, the shasums do not match so the file-on-disk is removed and a normal download proceeds as though no previous file existed. This is designed to restart an interrupted download.
Any valid wget
URL will work.
Downloads every time, even if the file exists locally:
download_file http://example.com/file.tar.gz file.tar.gz
Downloads if no local file is found:
download_file http://example.com/file.tar.gz file.tar.gz expected_shasum
File matches checksum: download is skipped, local file is used:
download_file http://example.com/file.tar.gz file.tar.gz expected_shasum
File doesn’t match checksum: local file removed, download attempted:
download_file http://example.com/file.tar.gz file.tar.gz mismatching_shasum
Will return 0 if a file was downloaded or if a valid cached file was found.
- pkg_path_for()/Get-HabPackagePath
- Returns the path for a build or runtime package dependency on stdout from the list of dependencies referenced in
pkg_deps
orpkg_build_deps
. This is useful if you need to install or reference specific dependencies from within a callback, such asdo_build()
ordo_install()
.Here’s an example of how to use this function to retrieve the path to the perl binary in the core/perl package:
_perl_path="$(pkg_path_for core/perl)/bin/perl"
- fix_interpreter()
plan.sh
only. Edits the#!
shebang of the target file in-place. This is useful for changing hard-coded paths defined by your source files to the equivalent path in a Chef Habitat package. You must include the required package that provides the expected path for the shebang in pkg_deps. This function performs a greedy match against the specified interpreter in the target file(s).
To use this function in your plan, you must specify the following arguments:
- The target file or files
- The name of the package that contains the interpreter
- The relative directory and binary path to the interpreter
For example, to replace all the files in node_modules/.bin
that have #!/usr/bin/env
with the coreutils path to bin/env
(/hab/pkgs/core/coreutils/8.24/20160219013458/bin/env), you must quote the wildcard target as shown below.
fix_interpreter "node_modules/.bin/*" core/coreutils bin/env
For a single target, reference the file directly:
fix_interpreter node_modules/.bin/concurrent core/coreutils bin/env
- pkg_interpreter_for()
plan.sh
only. Returns the path for the given package and interpreter by reading it from the INTERPRETERS metadata in the package. The directory of the interpreter needs to be specified, as an interpreter binary might live inbin
,sbin
, orlibexec
, depending on the software.
The following shows how to call pkg_interpreter_for with the package and interpreter arguments specified.
pkg_interpreter_for core/coreutils bin/env
This function will return 0 if the specified package and interpreter were found, and 1 if the package could not be found or the interpreter is not specified for that package.
- pkg_version()
- An optional way to determine the value for
$pkg_version
. The function must print the computed version string to standard output and will be called when the Plan author invokes theupdate_pkg_version()
helper in aplan.sh
orSet-PkgVersion
in aplan.ps1
. - update_pkg_version()/Set-PkgVersion
- Updates the value for
$pkg_version
by calling a Plan author-providedpkg_version()
function. This function must be explicitly called in a Plan in or after thedo_before()
/Invoke-Before
build phase but before thedo_prepare()
/Invoke-Prepare
build phase. The$pkg_version
variable will be updated and any other relevant variables will be recomputed. The following examples show how to use these functions to set a dynamic version number.
This plan concatenates a static file in the source root of the
project to determine the version in the before
phase:
pkg_version() {
cat "$SRC_PATH/version.txt"
}
do_before() {
do_default_before
update_pkg_version
}
function pkg_version {
Get-Content "$SRC_PATH/version.txt"
}
Invoke-Before {
Invoke-DefaultBefore
Set-PkgVersion
}
The pkg_version
function in this plan dynamically creates a version with a date stamp to format the final version string to standard output.
As the downloaded file is required before running the version logic, this helper function is called in the download
build phase:
pkg_version() {
local build_date
# Extract the build date of the certificates file
build_date=$(cat $HAB_CACHE_SRC_PATH/$pkg_filename \
| grep 'Certificate data from Mozilla' \
| sed 's/^## Certificate data from Mozilla as of: //')
date --date="$build_date" "+%Y.%m.%d"
}
do_download() {
do_default_download
update_pkg_version
}
function pkg_version {
# Extract the build date of the certificates file
$matchStr = "## Certificate data from Mozilla as of: "
foreach($line in (Get-Content "$HAB_CACHE_SRC_PATH/$pkg_filename")) {
if($line.StartsWith($matchStr)) {
$build_date = $line.Substring($matchStr.Length)
}
}
[DateTime]::Parse($build_date).ToString("yyyy.mm.dd")
}
function Invoke-Download {
Invoke-DefaultDownload
Set-PkgVersion
}
- abspath()
plan.sh
only. Return the absolute path for a path, which might be absolute or relative.- exists()
plan.sh
only. Checks that the command exists. Returns 0 if it does, 1 if it does not.- build_line()/Write-BuildLine
- Print a line of build output. Takes a string as its only argument.
build_line "Checksum verified - ${pkg_shasum}"
- warn()/Write-Warning
- Print a warning line on stderr. Takes a string as its only argument.
warn "Checksum failed"
- debug()/Write-Debug
- Prints a line only if the
$DEBUG
environment value is set to 1. Thedebug
function takes a string as its only argument.
DEBUG=1
debug "Only if things are set"
- exit_with()
plan.sh
only. Exits the program with an error message and a status code.
exit_with "Something bad happened" 55
- trim()
plan.sh
only. Trims leading and trailing whitespace characters from a bash variable.- record()
plan.sh
only. Takes a session name and command to run as arguments function appends a timestamp to the log file. Alternative to piping build through tee.
# Usage: record <SESSION> [CMD [ARG ...]]
record mysoftware build /src/mysoftware
Was this page helpful?