Blob Blame Raw
#!/bin/bash

usage() {
cat >&2 << EOF_USAGE
Usage: $0 -g <go import path> [-p <prefix>] [-G <go path>] [-v <version string>] [-a <attributes>]
<go import path>   the Go import path of the target package
<prefix>:          an eventual prefix path such as %{buildroot}
<go path>:         the root of the Go source tree
<version string>:  tag the provides with the <version string>
<attributes>:      attributes to add to the provides, for example
                   (commit=XXXX)(branch=YYYY) or
                   (vermod=alpha1)

Example:
echo filename | $0 -g golang.org/x/net -G /usr/share/gocode -v 2.5-0.1
echo filename | $0 -g golang.org/x/net -a '(commit=XXXX)(branch=YYYY)'
echo filename | $0 -g golang.org/x/net -a '(vermod=alpha1)'
EOF_USAGE
exit 1
}

if ! options=$(getopt -n $0 -o hg:p:G:v:a: -l help,goipath:,prefix:,gopath:,version:,attr:,attribute:,attributes: -- "$@")
then
    # something went wrong, getopt will put out an error message for us
    exit 2
fi

eval set -- "$options"

provides() {
  package="${1#${root}/src/}"
  for index in "${!deco[@]}" ; do
    echo "golang(${package})${deco[index]}${version}"
  done
}

version=''
prefix=''
gopath=/usr/share/gocode
declare -A attributes

while [ $# -gt 0 ] ; do
  case $1 in
    -h|--help)    usage ;;
    -g|--goipath) goipath="$2" ; shift;;
    -p|--prefix)  prefix=$(realpath -sm "$2") ; shift;;
    -G|--gopath)  gopath="$2" ; shift;;
    -v|--version) version=" = $2" ; shift;;
    -a|--attr|--attribute|--attributes)
                  IFS=')' read -r -a newattrs <<< "$2"
                  for index in "${!newattrs[@]}" ; do
                    newattrs[index]=${newattrs[index]#\(}
                    attributes[${newattrs[index]%%=*}]=${newattrs[index]#*=}
                  done ; shift;;
    (--)          shift; break;;
    (-*)          echo "$0: error - unrecognized option $1" >&2; exit 3;;
    (*)           break;;
  esac
  shift
done

[[ -z ${goipath} ]] && exit 0

root="${prefix}${gopath}"

deco=( "" )
# Some filtering may be needed in the future
for key in "${!attributes[@]}"; do
  [ -n "${attributes[$key]}" ] && deco+=( "($key=${attributes[$key]})" )
done

while read dir ; do
  if [[ -L $dir ]] ; then
    targetdir=$(realpath -m "$dir")
    [[ $targetdir != ${prefix}* ]] && targetdir="${prefix}${targetdir}"
    if [[ ${targetdir}/ == ${root}/src/${goipath}/* ]] ; then
      for subdir in $(find "$targetdir" -type d) ; do
        subdir="${dir}${subdir#${targetdir}}"
        provides "$subdir"
      done
    fi
  else
    if [[ -d $dir ]] ; then
      dir=$(realpath -sm "$dir")
      [[ ${dir}/ == ${root}/src/${goipath}/* ]] && provides "$dir"
    fi
  fi
done | sort | uniq | grep -v '/\([._]\)\?\(internal\|vendor\)\([/)]\)'