4
\$\begingroup\$

I'm relatively new to bash scripting, and I'm wondering how I've done on this. Basically it's a script where if I'm in a github or bitbucket repository in my terminal, I can type browse-repository to open it up in the browser. I can also type something like browse-repository issues to visit the issues page, or browse-repository issues 19 to see issue # 19 for the repository.

I alias the command as br to save on typing, and can type things like br i 19 to get to the page for issue # 19.

I'm mainly looking for tips on organization and scope, and of course if there's any other improvements as well. I couldn't figure out any sort of namespacing, so i prefixed commands with _browse_repository

The file as it currently stands is simple sourced from my .bash_profile, if that matters.

#!/bin/bash -e

function browse-repository() {
  local URL="https://$(git config remote.origin.url | sed 's/\.git//' | sed 's/https:\/\///' | sed 's/ssh:\/\///' | sed 's/git:\/\///' | sed 's/git@//' | tr ':' '/')"

  if _browse_repository_is_bitbucket_repo "$URL" || _browse_repository_is_github_repo "$URL"
  then
    case "$1" in
      "")
        URL="$URL"
        _browse_repository_go
        ;;
      i|issues|-i|--issues)
        if [[ -n $2 ]]
        then
          if _browse_repository_is_bitbucket_repo "$URL"
          then
            URL="$URL/issue/$2"
          else
            URL="$URL/issues/$2"
          fi
        else
          URL="$URL/issues"
        fi
        _browse_repository_go
        ;;
      p|pulls|-p|--pulls)
        if _is_bitbucket_repo "$URL"
        then
          URL="$URL/pull-requests"
        else
          URL="$URL/pulls"
        fi
        _browse_repository_go
        ;;
      w|wiki|-w|--wiki)
        URL="$URL/wiki"
        _browse_repository_go
        ;;
      h|help|-h|--help)
        _browse_repository_usage
        ;;
      *)
        _browse_repository_usage
        ;;
    esac
  else
    case "$1" in
      h|help|-h|--help)
        _browse_repository_usage
        ;;
      *)
        echo "Not a valid bitbucket or github repository"
        ;;
    esac
  fi
}

_browse_repository_is_bitbucket_repo() {
  [ "$URL" != "${URL#https:\/\/bitbucket.org\/}" ]
}

_browse_repository_is_github_repo() {
  [ "$URL" != "${URL#https:\/\/github.com\/}" ]
}

_browse_repository_usage() {
  cat <<EOF
usage: browse-repository [<command>] [<number>]

The following commands are performed on the current project.

Available commands:

  -i --issues [<number>] Open issues, optionally pass a number to open a specific issue
  -p --pulls             Open pull requests, optionally pass a number to open a specific pull request
  -w --wiki              Open wiki

When no argument is supplied the main project page will be opened.
EOF
}

_browse_repository_go() {
  open "$URL"
}
\$\endgroup\$
  • \$\begingroup\$ I saved your script and made it executable, and from a github Repository, i executed it but nothing happens.. \$\endgroup\$ – Ciasto piekarz Feb 11 '14 at 17:21
3
\$\begingroup\$

Some things:

  • You don't need the function keyword to define a function.
  • You can combine sed commands by separating them by ;: sed 's/\.git//;s/https:\/\///;s/ssh:\/\///;s/git:\/\///;s/git@//'
  • This can be shortened down to a single statement: sed 's/\(\.git\|https:\/\/\|ssh:\/\/\|git:\/\/\|git@\)//'
  • Fortunately you can get rid of picket fences in sed by using a different separator: sed 's#\(\.git\|https://\|ssh://\|git://\|git@\)##'
  • I'd use getopt or getopts for option handling. Which one to use is a bit of a religious issue, but getopt supports long options (--help and the like), while getopts is more portable.
  • It is recommended to use upper case only for variables exported in the shell, and lower case for other variables.
  • This is maybe more of a personal preference, but rather than creating a function called I'd create a script with the same name and move the contents of the browse-repository function to the end of the script. That way there's no pollution of the function name space, and no need to source the script. Just put it for example at /usr/local/bin/browse-repository and run. An added advantage of this is that you don't need the function name prefixes anymore.
  • I'm not sure how portable open is. On my system:

    $ open http://www.example.org
    Couldn't get a file descriptor referring to the console
    

    Alternatively you could use x-www-browser, but I fear that's even less portable (Debian & derivatives only IIRC). I don't know if there's something more portable available.

All in all a very nice script.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.