github.com/lmb/consul@v1.4.1/build-support/functions/10-util.sh (about)

     1  function err {
     2     if test "${COLORIZE}" -eq 1
     3     then
     4        tput bold
     5        tput setaf 1
     6     fi
     7  
     8     echo "$@" 1>&2
     9  
    10     if test "${COLORIZE}" -eq 1
    11     then
    12        tput sgr0
    13     fi
    14  }
    15  
    16  function status {
    17     if test "${COLORIZE}" -eq 1
    18     then
    19        tput bold
    20        tput setaf 4
    21     fi
    22  
    23     echo "$@"
    24  
    25     if test "${COLORIZE}" -eq 1
    26     then
    27        tput sgr0
    28     fi
    29  }
    30  
    31  function status_stage {
    32     if test "${COLORIZE}" -eq 1
    33     then
    34        tput bold
    35        tput setaf 2
    36     fi
    37  
    38     echo "$@"
    39  
    40     if test "${COLORIZE}" -eq 1
    41     then
    42        tput sgr0
    43     fi
    44  }
    45  
    46  function debug {
    47     if is_set "${BUILD_DEBUG}"
    48     then
    49        if test "${COLORIZE}" -eq 1
    50        then
    51           tput setaf 6
    52        fi
    53        echo "$@"
    54        if test "${COLORIZE}" -eq 1
    55        then
    56           tput sgr0
    57        fi
    58     fi
    59  }
    60  
    61  function sed_i {
    62     if test "$(uname)" == "Darwin"
    63     then
    64        sed -i '' "$@"
    65        return $?
    66     else
    67        sed -i "$@"
    68        return $?
    69     fi
    70  }
    71  
    72  function is_set {
    73     # Arguments:
    74     #   $1 - string value to check its truthiness
    75     #
    76     # Return:
    77     #   0 - is truthy (backwards I know but allows syntax like `if is_set <var>` to work)
    78     #   1 - is not truthy
    79  
    80     local val=$(tr '[:upper:]' '[:lower:]' <<< "$1")
    81     case $val in
    82        1 | t | true | y | yes)
    83           return 0
    84           ;;
    85        *)
    86           return 1
    87           ;;
    88     esac
    89  }
    90  
    91  function have_gpg_key {
    92     # Arguments:
    93     #   $1 - GPG Key id to check if we have installed
    94     #
    95     # Return:
    96     #   0 - success (we can use this key for signing)
    97     #   * - failure (key cannot be used)
    98  
    99     gpg --list-secret-keys $1 > /dev/null 2>&1
   100     return $?
   101  }
   102  
   103  function parse_version {
   104     # Arguments:
   105     #   $1 - Path to the top level Consul source
   106     #   $2 - boolean value for whether the release version should be parsed from the source
   107     #   $3 - boolean whether to use GIT_DESCRIBE and GIT_COMMIT environment variables
   108     #   $4 - boolean whether to omit the version part of the version string. (optional)
   109     #
   110     # Return:
   111     #   0 - success (will write the version to stdout)
   112     #   * - error   (no version output)
   113     #
   114     # Notes:
   115     #   If the GOTAGS environment variable is present then it is used to determine which
   116     #   version file to use for parsing.
   117  
   118     local vfile="${1}/version/version.go"
   119  
   120     # ensure the version file exists
   121     if ! test -f "${vfile}"
   122     then
   123        err "Error - File not found: ${vfile}"
   124        return 1
   125     fi
   126  
   127     local include_release="$2"
   128     local use_git_env="$3"
   129     local omit_version="$4"
   130  
   131     local git_version=""
   132     local git_commit=""
   133  
   134     if test -z "${include_release}"
   135     then
   136        include_release=true
   137     fi
   138  
   139     if test -z "${use_git_env}"
   140     then
   141        use_git_env=true
   142     fi
   143  
   144     if is_set "${use_git_env}"
   145     then
   146        git_version="${GIT_DESCRIBE}"
   147        git_commit="${GIT_COMMIT}"
   148     fi
   149  
   150     # Get the main version out of the source file
   151     version_main=$(awk '$1 == "Version" && $2 == "=" { gsub(/"/, "", $3); print $3 }' < ${vfile})
   152     release_main=$(awk '$1 == "VersionPrerelease" && $2 == "=" { gsub(/"/, "", $3); print $3 }' < ${vfile})
   153  
   154  
   155     # try to determine the version if we have build tags
   156     for tag in "$GOTAGS"
   157     do
   158        for vfile in $(find "${1}/version" -name "version_*.go" 2> /dev/null| sort)
   159        do
   160           if grep -q "// +build $tag" "${vfile}"
   161           then
   162              version_main=$(awk '$1 == "Version" && $2 == "=" { gsub(/"/, "", $3); print $3 }' < ${vfile})
   163              release_main=$(awk '$1 == "VersionPrerelease" && $2 == "=" { gsub(/"/, "", $3); print $3 }' < ${vfile})
   164           fi
   165        done
   166     done
   167  
   168     local version="${version_main}"
   169     # override the version from source with the value of the GIT_DESCRIBE env var if present
   170     if test -n "${git_version}"
   171     then
   172        version="${git_version}"
   173     fi
   174  
   175     local rel_ver=""
   176     if is_set "${include_release}"
   177     then
   178        # Default to pre-release from the source
   179        rel_ver="${release_main}"
   180  
   181        # When no GIT_DESCRIBE env var is present and no release is in the source then we
   182        # are definitely in dev mode
   183        if test -z "${git_version}" -a -z "${rel_ver}" && is_set "${use_git_env}"
   184        then
   185           rel_ver="dev"
   186        fi
   187  
   188        # Add the release to the version
   189        if test -n "${rel_ver}" -a -n "${git_commit}"
   190        then
   191           rel_ver="${rel_ver} (${git_commit})"
   192        fi
   193     fi
   194  
   195     if test -n "${rel_ver}"
   196     then
   197        if is_set "${omit_version}"
   198        then
   199           echo "${rel_ver}" | tr -d "'"
   200        else
   201           echo "${version}-${rel_ver}" | tr -d "'"
   202        fi
   203        return 0
   204     elif ! is_set "${omit_version}"
   205     then
   206        echo "${version}" | tr -d "'"
   207        return 0
   208     else
   209        return 1
   210     fi
   211  }
   212  
   213  function get_version {
   214     # Arguments:
   215     #   $1 - Path to the top level Consul source
   216     #   $2 - Whether the release version should be parsed from source (optional)
   217     #   $3 - Whether to use GIT_DESCRIBE and GIT_COMMIT environment variables
   218     #
   219     # Returns:
   220     #   0 - success (the version is also echoed to stdout)
   221     #   1 - error
   222     #
   223     # Notes:
   224     #   If a VERSION environment variable is present it will override any parsing of the version from the source
   225     #   In addition to processing the main version.go, version_*.go files will be processed if they have
   226     #   a Go build tag that matches the one in the GOTAGS environment variable. This tag processing is
   227     #   primitive though and will not match complex build tags in the files with negation etc.
   228  
   229     local vers="$VERSION"
   230     if test -z "$vers"
   231     then
   232        # parse the OSS version from version.go
   233        vers="$(parse_version ${1} ${2} ${3})"
   234     fi
   235  
   236     if test -z "$vers"
   237     then
   238        return 1
   239     else
   240        echo $vers
   241        return 0
   242     fi
   243  }
   244  
   245  function git_branch {
   246     # Arguments:
   247     #   $1 - Path to the git repo (optional - assumes pwd is git repo otherwise)
   248     #
   249     # Returns:
   250     #   0 - success
   251     #   * - failure
   252     #
   253     # Notes:
   254     #   Echos the current branch to stdout when successful
   255  
   256     local gdir="$(pwd)"
   257     if test -d "$1"
   258     then
   259        gdir="$1"
   260     fi
   261  
   262     pushd "${gdir}" > /dev/null
   263  
   264     local ret=0
   265     local head="$(git status -b --porcelain=v2 | awk '{if ($1 == "#" && $2 =="branch.head") { print $3 }}')" || ret=1
   266  
   267     popd > /dev/null
   268  
   269     test ${ret} -eq 0 && echo "$head"
   270     return ${ret}
   271  }
   272  
   273  function git_upstream {
   274     # Arguments:
   275     #   $1 - Path to the git repo (optional - assumes pwd is git repo otherwise)
   276     #
   277     # Returns:
   278     #   0 - success
   279     #   * - failure
   280     #
   281     # Notes:
   282     #   Echos the current upstream branch to stdout when successful
   283  
   284     local gdir="$(pwd)"
   285     if test -d "$1"
   286     then
   287        gdir="$1"
   288     fi
   289  
   290     pushd "${gdir}" > /dev/null
   291  
   292     local ret=0
   293     local head="$(git status -b --porcelain=v2 | awk '{if ($1 == "#" && $2 =="branch.upstream") { print $3 }}')" || ret=1
   294  
   295     popd > /dev/null
   296  
   297     test ${ret} -eq 0 && echo "$head"
   298     return ${ret}
   299  }
   300  
   301  function git_log_summary {
   302     # Arguments:
   303     #   $1 - Path to the git repo (optional - assumes pwd is git repo otherwise)
   304     #
   305     # Returns:
   306     #   0 - success
   307     #   * - failure
   308     #
   309  
   310     local gdir="$(pwd)"
   311     if test -d "$1"
   312     then
   313        gdir="$1"
   314     fi
   315  
   316     pushd "${gdir}" > /dev/null
   317  
   318     local ret=0
   319  
   320     local head=$(git_branch) || ret=1
   321     local upstream=$(git_upstream) || ret=1
   322     local rev_range="${head}...${upstream}"
   323  
   324     if test ${ret} -eq 0
   325     then
   326        status "Git Changes:"
   327        git log --pretty=oneline ${rev_range} || ret=1
   328  
   329     fi
   330     return $ret
   331  }
   332  
   333  function git_diff {
   334     # Arguments:
   335     #   $1 - Path to the git repo (optional - assumes pwd is git repo otherwise)
   336     #   $2 .. $N - Optional path specification
   337     #
   338     # Returns:
   339     #   0 - success
   340     #   * - failure
   341     #
   342  
   343     local gdir="$(pwd)"
   344     if test -d "$1"
   345     then
   346        gdir="$1"
   347     fi
   348  
   349     shift
   350  
   351     pushd "${gdir}" > /dev/null
   352  
   353     local ret=0
   354  
   355     local head=$(git_branch) || ret=1
   356     local upstream=$(git_upstream) || ret=1
   357  
   358     if test ${ret} -eq 0
   359     then
   360        status "Git Diff - Paths: $@"
   361        git diff ${HEAD} ${upstream} -- "$@" || ret=1
   362     fi
   363     return $ret
   364  }
   365  
   366  function normalize_git_url {
   367     url="${1#https://}"
   368     url="${url#git@}"
   369     url="${url%.git}"
   370     url="$(sed ${SED_EXT} -e 's/([^\/:]*)[:\/](.*)/\1:\2/' <<< "${url}")"
   371     echo "$url"
   372     return 0
   373  }
   374  
   375  function git_remote_url {
   376     # Arguments:
   377     #   $1 - Path to the top level Consul source
   378     #   $2 - Remote name
   379     #
   380     # Returns:
   381     #   0 - success
   382     #   * - error
   383     #
   384     # Note:
   385     #   The push url for the git remote will be echoed to stdout
   386  
   387     if ! test -d "$1"
   388     then
   389        err "ERROR: '$1' is not a directory. git_remote_url must be called with the path to the top level source as the first argument'"
   390        return 1
   391     fi
   392  
   393     if test -z "$2"
   394     then
   395        err "ERROR: git_remote_url must be called with a second argument that is the name of the remote"
   396        return 1
   397     fi
   398  
   399     local ret=0
   400  
   401     pushd "$1" > /dev/null
   402  
   403     local url=$(git remote get-url --push $2 2>&1) || ret=1
   404  
   405     popd > /dev/null
   406  
   407     if test "${ret}" -eq 0
   408     then
   409        echo "${url}"
   410        return 0
   411     fi
   412  }
   413  
   414  function find_git_remote {
   415     # Arguments:
   416     #   $1 - Path to the top level Consul source
   417     #
   418     # Returns:
   419     #   0 - success
   420     #   * - error
   421     #
   422     # Note:
   423     #   The remote name to use for publishing will be echoed to stdout upon success
   424  
   425     if ! test -d "$1"
   426     then
   427        err "ERROR: '$1' is not a directory. find_git_remote must be called with the path to the top level source as the first argument'"
   428        return 1
   429     fi
   430  
   431     need_url=$(normalize_git_url "${PUBLISH_GIT_HOST}:${PUBLISH_GIT_REPO}")
   432     debug "Required normalized remote: ${need_url}"
   433  
   434     pushd "$1" > /dev/null
   435  
   436     local ret=1
   437     for remote in $(git remote)
   438     do
   439        url=$(git remote get-url --push ${remote}) || continue
   440        url=$(normalize_git_url "${url}")
   441  
   442        debug "Testing Remote: ${remote}: ${url}"
   443        if test "${url}" == "${need_url}"
   444        then
   445           echo "${remote}"
   446           ret=0
   447           break
   448        fi
   449     done
   450  
   451     popd > /dev/null
   452     return ${ret}
   453  }
   454  
   455  function git_remote_not_blacklisted {
   456     # Arguments:
   457     #   $1 - path to the repo
   458     #   $2 - the remote name
   459     #
   460     # Returns:
   461     #   0 - not blacklisted
   462     #   * - blacklisted
   463     return 0
   464  }
   465  
   466  function is_git_clean {
   467     # Arguments:
   468     #   $1 - Path to git repo
   469     #   $2 - boolean whether the git status should be output when not clean
   470     #
   471     # Returns:
   472     #   0 - success
   473     #   * - error
   474     #
   475  
   476     if ! test -d "$1"
   477     then
   478        err "ERROR: '$1' is not a directory. is_git_clean must be called with the path to a git repo as the first argument'"
   479        return 1
   480     fi
   481  
   482     local output_status="$2"
   483  
   484     pushd "${1}" > /dev/null
   485  
   486     local ret=0
   487     test -z "$(git status --porcelain=v2 2> /dev/null)" || ret=1
   488  
   489     if is_set "${output_status}" && test "$ret" -ne 0
   490     then
   491        err "Git repo is not clean"
   492        # --porcelain=v1 is the same as --short except uncolorized
   493        git status --porcelain=v1
   494     fi
   495     popd > /dev/null
   496     return ${ret}
   497  }
   498  
   499  function update_git_env {
   500     # Arguments:
   501     #   $1 - Path to git repo
   502     #
   503     # Returns:
   504     #   0 - success
   505     #   * - error
   506     #
   507  
   508     if ! test -d "$1"
   509     then
   510        err "ERROR: '$1' is not a directory. is_git_clean must be called with the path to a git repo as the first argument'"
   511        return 1
   512     fi
   513  
   514     export GIT_COMMIT=$(git rev-parse --short HEAD)
   515     export GIT_DIRTY=$(test -n "$(git status --porcelain)" && echo "+CHANGES")
   516     export GIT_DESCRIBE=$(git describe --tags --always)
   517     export GIT_IMPORT=github.com/hashicorp/consul/version
   518     export GOLDFLAGS="-X ${GIT_IMPORT}.GitCommit=${GIT_COMMIT}${GIT_DIRTY} -X ${GIT_IMPORT}.GitDescribe=${GIT_DESCRIBE}"
   519     return 0
   520  }
   521  
   522  function git_push_ref {
   523     # Arguments:
   524     #   $1 - Path to the top level Consul source
   525     #   $2 - Git ref (optional)
   526     #   $3 - remote (optional - if not specified we will try to determine it)
   527     #
   528     # Returns:
   529     #   0 - success
   530     #   * - error
   531  
   532     if ! test -d "$1"
   533     then
   534        err "ERROR: '$1' is not a directory. push_git_release must be called with the path to the top level source as the first argument'"
   535        return 1
   536     fi
   537  
   538     local sdir="$1"
   539     local ret=0
   540     local remote="$3"
   541  
   542     # find the correct remote corresponding to the desired repo (basically prevent pushing enterprise to oss or oss to enterprise)
   543     if test -z "${remote}"
   544     then
   545        local remote=$(find_git_remote "${sdir}") || return 1
   546        status "Using git remote: ${remote}"
   547     fi
   548  
   549     local ref=""
   550  
   551     pushd "${sdir}" > /dev/null
   552  
   553     if test -z "$2"
   554     then
   555        # If no git ref was provided we lookup the current local branch and its tracking branch
   556        # It must have a tracking upstream and it must be tracking the sanctioned git remote
   557        local head=$(git_branch "${sdir}") || return 1
   558        local upstream=$(git_upstream "${sdir}") || return 1
   559  
   560        # upstream branch for this branch does not track the remote we need to push to
   561        # basically this checks that the upstream (could be something like origin/master) references the correct remote
   562        # if it doesn't then the string modification wont apply and the var will reamin unchanged and equal to itself.
   563        if test "${upstream#${remote}/}" == "${upstream}"
   564        then
   565           err "ERROR: Upstream branch '${upstream}' does not track the correct remote '${remote}' - cannot push"
   566           ret=1
   567        fi
   568        ref="refs/heads/${head}"
   569     else
   570        # A git ref was provided - get the full ref and make sure it isn't ambiguous and also to
   571        # be able to determine whether its a branch or tag we are pushing
   572        ref_out=$(git rev-parse --symbolic-full-name "$2" --)
   573  
   574        # -ne 2 because it should have the ref on one line followed by a line with '--'
   575        if test "$(wc -l <<< "${ref_out}")" -ne 2
   576        then
   577           err "ERROR: Git ref '$2' is ambiguous"
   578           debug "${ref_out}"
   579           ret=1
   580        else
   581           ref=$(head -n 1 <<< "${ref_out}")
   582        fi
   583     fi
   584  
   585     if test ${ret} -eq 0
   586     then
   587        case "${ref}" in
   588           refs/tags/*)
   589              status "Pushing tag ${ref#refs/tags/} to ${remote}"
   590              ;;
   591           refs/heads/*)
   592              status "Pushing local branch ${ref#refs/tags/} to ${remote}"
   593              ;;
   594           *)
   595              err "ERROR: git_push_ref func is refusing to push ref that isn't a branch or tag"
   596              return 1
   597        esac
   598  
   599        if ! git push "${remote}" "${ref}"
   600        then
   601           err "ERROR: Failed to push ${ref} to remote: ${remote}"
   602           ret=1
   603        fi
   604     fi
   605  
   606     popd > /dev/null
   607  
   608     return $ret
   609  }
   610  
   611  function update_version {
   612     # Arguments:
   613     #   $1 - Path to the version file
   614     #   $2 - Version string
   615     #   $3 - PreRelease version (if unset will become an empty string)
   616     #
   617     # Returns:
   618     #   0 - success
   619     #   * - error
   620  
   621     if ! test -f "$1"
   622     then
   623        err "ERROR: '$1' is not a regular file. update_version must be called with the path to a go version file"
   624        return 1
   625     fi
   626  
   627     if test -z "$2"
   628     then
   629        err "ERROR: The version specified was empty"
   630        return 1
   631     fi
   632  
   633     local vfile="$1"
   634     local version="$2"
   635     local prerelease="$3"
   636  
   637     sed_i ${SED_EXT} -e "s/(Version[[:space:]]*=[[:space:]]*)\"[^\"]*\"/\1\"${version}\"/g" -e "s/(VersionPrerelease[[:space:]]*=[[:space:]]*)\"[^\"]*\"/\1\"${prerelease}\"/g" "${vfile}"
   638     return $?
   639  }
   640  
   641  function set_changelog_version {
   642     # Arguments:
   643     #   $1 - Path to top level Consul source
   644     #   $2 - Version to put into the Changelog
   645     #   $3 - Release Date
   646     #
   647     # Returns:
   648     #   0 - success
   649     #   * - error
   650  
   651     local changelog="${1}/CHANGELOG.md"
   652     local version="$2"
   653     local rel_date="$3"
   654  
   655     if ! test -f "${changelog}"
   656     then
   657        err "ERROR: File not found: ${changelog}"
   658        return 1
   659     fi
   660  
   661     if test -z "${version}"
   662     then
   663        err "ERROR: Must specify a version to put into the changelog"
   664        return 1
   665     fi
   666  
   667     if test -z "${rel_date}"
   668     then
   669        rel_date=$(date +"%B %d, %Y")
   670     fi
   671  
   672     sed_i ${SED_EXT} -e "s/## UNRELEASED/## ${version} (${rel_date})/" "${changelog}"
   673     return $?
   674  }
   675  
   676  function unset_changelog_version {
   677     # Arguments:
   678     #   $1 - Path to top level Consul source
   679     #
   680     # Returns:
   681     #   0 - success
   682     #   * - error
   683  
   684     local changelog="${1}/CHANGELOG.md"
   685  
   686     if ! test -f "${changelog}"
   687     then
   688        err "ERROR: File not found: ${changelog}"
   689        return 1
   690     fi
   691  
   692     sed_i ${SED_EXT} -e "1 s/^## [0-9]+\.[0-9]+\.[0-9]+ \([^)]*\)/## UNRELEASED/" "${changelog}"
   693     return $?
   694  }
   695  
   696  function add_unreleased_to_changelog {
   697     # Arguments:
   698     #   $1 - Path to top level Consul source
   699     #
   700     # Returns:
   701     #   0 - success
   702     #   * - error
   703  
   704     local changelog="${1}/CHANGELOG.md"
   705  
   706     if ! test -f "${changelog}"
   707     then
   708        err "ERROR: File not found: ${changelog}"
   709        return 1
   710     fi
   711  
   712     # Check if we are already in unreleased mode
   713     if head -n 1 "${changelog}" | grep -q -c UNRELEASED
   714     then
   715        return 0
   716     fi
   717  
   718     local tfile="$(mktemp) -t "CHANGELOG.md_")"
   719     (
   720        echo -e "## UNRELEASED\n" > "${tfile}" &&
   721        cat "${changelog}" >> "${tfile}" &&
   722        cp "${tfile}" "${changelog}"
   723     )
   724     local ret=$?
   725     rm "${tfile}"
   726     return $ret
   727  }
   728  
   729  function set_release_mode {
   730     # Arguments:
   731     #   $1 - Path to top level Consul source
   732     #   $2 - The version of the release
   733     #   $3 - The release date
   734     #   $4 - The pre-release version
   735     #
   736     #
   737     # Returns:
   738     #   0 - success
   739     #   * - error
   740  
   741     if ! test -d "$1"
   742     then
   743        err "ERROR: '$1' is not a directory. set_release_mode must be called with the path to a git repo as the first argument"
   744        return 1
   745     fi
   746  
   747     if test -z "$2"
   748     then
   749        err "ERROR: The version specified was empty"
   750        return 1
   751     fi
   752  
   753     local sdir="$1"
   754     local vers="$2"
   755     local rel_date="$(date +"%B %d, %Y")"
   756  
   757     if test -n "$3"
   758     then
   759        rel_date="$3"
   760     fi
   761  
   762     local changelog_vers="${vers}"
   763     if test -n "$4"
   764     then
   765        changelog_vers="${vers}-$4"
   766     fi
   767  
   768     status_stage "==> Updating CHANGELOG.md with release info: ${changelog_vers} (${rel_date})"
   769     set_changelog_version "${sdir}" "${changelog_vers}" "${rel_date}" || return 1
   770  
   771     status_stage "==> Updating version/version.go"
   772     if ! update_version "${sdir}/version/version.go" "${vers}" "$4"
   773     then
   774        unset_changelog_version "${sdir}"
   775        return 1
   776     fi
   777  
   778     return 0
   779  }
   780  
   781  function set_dev_mode {
   782     # Arguments:
   783     #   $1 - Path to top level Consul source
   784     #
   785     # Returns:
   786     #   0 - success
   787     #   * - error
   788  
   789     if ! test -d "$1"
   790     then
   791        err "ERROR: '$1' is not a directory. set_dev_mode must be called with the path to a git repo as the first argument'"
   792        return 1
   793     fi
   794  
   795     local sdir="$1"
   796     local vers="$(parse_version "${sdir}" false false)"
   797  
   798     status_stage "==> Setting VersionPreRelease back to 'dev'"
   799     update_version "${sdir}/version/version.go" "${vers}" dev || return 1
   800  
   801     status_stage "==> Adding new UNRELEASED label in CHANGELOG.md"
   802     add_unreleased_to_changelog "${sdir}" || return 1
   803  
   804     return 0
   805  }
   806  
   807  function git_staging_empty {
   808     # Arguments:
   809     #   $1 - Path to git repo
   810     #
   811     # Returns:
   812     #   0 - success (nothing staged)
   813     #   * - error (staged files)
   814  
   815     if ! test -d "$1"
   816     then
   817        err "ERROR: '$1' is not a directory. commit_dev_mode must be called with the path to a git repo as the first argument'"
   818        return 1
   819     fi
   820  
   821     pushd "$1" > /dev/null
   822  
   823     declare -i ret=0
   824  
   825     for status in $(git status --porcelain=v2 | awk '{print $2}' | cut -b 1)
   826     do
   827        if test "${status}" != "."
   828        then
   829           ret=1
   830           break
   831        fi
   832     done
   833  
   834     popd > /dev/null
   835     return ${ret}
   836  }
   837  
   838  function commit_dev_mode {
   839     # Arguments:
   840     #   $1 - Path to top level Consul source
   841     #
   842     # Returns:
   843     #   0 - success
   844     #   * - error
   845  
   846     if ! test -d "$1"
   847     then
   848        err "ERROR: '$1' is not a directory. commit_dev_mode must be called with the path to a git repo as the first argument'"
   849        return 1
   850     fi
   851  
   852     status "Checking for previously staged files"
   853     git_staging_empty "$1" || return 1
   854  
   855     declare -i ret=0
   856  
   857     pushd "$1" > /dev/null
   858  
   859     status "Staging CHANGELOG.md and version_*.go files"
   860     git add CHANGELOG.md && git add version/version*.go
   861     ret=$?
   862  
   863     if test ${ret} -eq 0
   864     then
   865        status "Adding Commit"
   866        git commit -m "Putting source back into Dev Mode"
   867        ret=$?
   868     fi
   869  
   870     popd >/dev/null
   871     return ${ret}
   872  }
   873  
   874  function gpg_detach_sign {
   875     # Arguments:
   876     #   $1 - File to sign
   877     #   $2 - Alternative GPG key to use for signing
   878     #
   879     # Returns:
   880     #   0 - success
   881     #   * - failure
   882  
   883     # determine whether the gpg key to use is being overridden
   884     local gpg_key=${HASHICORP_GPG_KEY}
   885     if test -n "$2"
   886     then
   887        gpg_key=$2
   888     fi
   889  
   890     gpg --default-key "${gpg_key}" --detach-sig --yes -v  "$1"
   891     return $?
   892  }
   893  
   894  function shasum_directory {
   895     # Arguments:
   896     #   $1 - Path to directory containing the files to shasum
   897     #   $2 - File to output sha sums to
   898     #
   899     # Returns:
   900     #   0 - success
   901     #   * - failure
   902  
   903     if ! test -d "$1"
   904     then
   905        err "ERROR: '$1' is not a directory and shasum_release requires passing a directory as the first argument"
   906        return 1
   907     fi
   908  
   909     if test -z "$2"
   910     then
   911        err "ERROR: shasum_release requires a second argument to be the filename to output the shasums to but none was given"
   912        return 1
   913     fi
   914  
   915     pushd $1 > /dev/null
   916     shasum -a256 * > "$2"
   917     ret=$?
   918     popd >/dev/null
   919  
   920     return $ret
   921  }
   922  
   923   function ui_version {
   924     # Arguments:
   925     #   $1 - path to index.html
   926     #
   927     # Returns:
   928     #   0 - success
   929     #   * -failure
   930     #
   931     # Notes: echoes the version to stdout upon success
   932     if ! test -f "$1"
   933     then
   934        err "ERROR: No such file: '$1'"
   935        return 1
   936     fi
   937  
   938     local ui_version=$(sed -n ${SED_EXT} -e 's/.*CONSUL_VERSION%22%3A%22([^%]*)%22%2C%22.*/\1/p' < "$1") || return 1
   939     echo "$ui_version"
   940     return 0
   941   }
   942   function ui_logo_type {
   943     # Arguments:
   944     #   $1 - path to index.html
   945     #
   946     # Returns:
   947     #   0 - success
   948     #   * -failure
   949     #
   950     # Notes: echoes the 'logo type' to stdout upon success
   951     # the 'logo' can be one of 'enterprise' or 'oss'
   952     # and doesn't necessarily correspond to the binary type of consul
   953     # the logo is 'enterprise' if the binary type is anything but 'oss'
   954     if ! test -f "$1"
   955     then
   956        err "ERROR: No such file: '$1'"
   957        return 1
   958     fi
   959     grep -q "data-enterprise-logo" < "$1"
   960  
   961     if test $? -eq 0
   962     then
   963       echo "enterprise"
   964     else
   965       echo "oss"
   966     fi
   967     return 0
   968   }