#!/usr/bin/env ruby require 'rubygems' require File.dirname(__FILE__) + "/../lib/stash_cli" require 'commander/import' require 'yaml' require 'launchy' require 'pathname' program :name, "Atlassian Stash CLI" program :version, Atlassian::Stash::Version::STRING program :description, "Provides convenient functions for interacting with Atlassian Stash through the command line" include Atlassian::Stash include Atlassian::Stash::Git $configFileName = ".stashconfig.yml" $configFile = File.join(ENV['HOME'], $configFileName) def load_config raise "No Stash configuration found; please run configure" unless File.exists? $configFile config = YAML.load_file($configFile) raise "Stash configuration file is incomplete, please re-run configure" unless config['username'] and config['stash_url'] config.merge! repo_config if repo_config config end def repo_config return @repo_config if @repo_config repo_root = get_repo_root_directory.strip repo_directory = Pathname.new(repo_root) stash_config = repo_directory + $configFileName if (stash_config.exist? && stash_config.file?) @repo_config = YAML.load_file(stash_config) end Hash.new end command 'configure' do |c| c.syntax = 'configure' c.description = 'Setup configuration details to your Stash instance' c.example 'stash configure --username sebr --password s3cre7 --stash_url http://stash.mycompany.com', 'Setup Stash CLI with credentials to the Stash server' c.option '--username user', String, 'Writes your Stash username to the configuration file' c.option '--password password', String, 'Writes your Stash user password to the configuration file. If omitted, password will be prompted to be entered' c.option '--stashUrl', String, 'Writes the Stash server url to the configuration file' c.option '--remote', String, 'Pull requests will be created in the Stash repository specified by the given remote' c.action do |args, options| username = options.username ? options.username : ask("Stash Username: ") password = options.password ? options.password : ask("Stash Password (optional): ") { |q| q.echo = "*" } stashUrl = options.stashUrl ? options.stashUrl : ask("Stash URL: ") remote = options.remote ? options.remote : ask("Remote (optional): ") c = { 'stash_url' => stashUrl.to_s } c['username'] = username.to_s unless username.empty? c['password'] = password.to_s unless password.empty? c['remote'] = remote.to_s unless remote.empty? File.open($configFile, 'w') do |out| YAML.dump(c, out) end File.chmod 0600, $configFile create_git_alias if agree "Create a git alias 'git create-pull-request'? " end end command 'pull-request' do |c| def extract_reviewers(args = []) default_reviewers = repo_config.nil? ? Array.new : Array(repo_config[:reviewers]) default_reviewers.concat args.collect { |user| user[1..-1] if user.start_with?("@") }.compact end c.syntax = 'pull-request [sourceBranch] targetBranch [@reviewer1 @reviewer2] [options]' c.description = 'Create a pull request in Stash' c.option '-d DESCRIPTION', '--description DESCRIPTION', String, 'Use the following description when creating the pull request' c.option '-T TITLE', '--title TITLE', String, 'Use the following title when creating the pull request' c.option '-r remote', '--remote remote', String, 'Creates the pull request in the Stash repository specified by the given remote' c.option '-o', '--open', 'Open the created pull request page in a web browser' c.example 'stash pull-request topicBranch master @michael', "Create a pull request from branch 'topicBranch' into 'master' with 'michael' added as a reviewer" c.example 'stash pull-request master', "Create a pull request from the current git branch into 'master'" c.example 'stash pull-request master -T "JIRA-1234 new feature" -d "Adds new feature as described in JIRA-1234"', "Create a pull request from the current git branch into 'master' with the title 'JIRA-1234 new feature' and description 'Adds new feature as described in JIRA-1234'" c.example 'stash pull-request topicBranch upstream/master', "Create a pull request from branch 'topicBranch' into branch 'master' on the remote named 'upstream'" c.example 'stash pull-request remotes/upstream/master', "Create a pull request from the current branch into branch 'master' on the remote named 'upstream'" c.action do |args, options| if args.length == 0 command(:help).run('pull-request') Process.exit end source = args.shift if args.empty? or args.first.start_with?("@") target = source source = get_current_branch reviewers = extract_reviewers args else target = args.shift reviewers = extract_reviewers args end # Strip out any starting 'remotes/' from branch name for matching if source.index('remotes/') == 0 source = source['remotes/'.size..-1] end if target.index('remotes/') == 0 target = target['remotes/'.size..-1] end options.src_remote = options.remote if not is_branch?(source) if not is_branch?("remotes/" + source) raise "fatal: unrecogonized source branch" end # If a remote matches, split the remote out of the refspec options.src_remote = source.split('/')[0] source = source.split('/')[1..-1].join('/') end if not is_branch?(target) if not is_branch?("remotes/" + target) raise "fatal: unrecognized target branch" end # If a remote matches, split the remote out of the refspec options.target_remote = target.split('/')[0] target = target.split('/')[1..-1].join('/') end ensure_within_git! do cpr = CreatePullRequest.new(load_config) cpr.create_pull_request source, target, reviewers, options end end end command 'browse' do |c| c.syntax = 'browse [browse|commits|pull-requests]' c.description = 'Open the Stash web ui for this repository' c.option '-b branch', '--branch branch', String, 'Open the Stash web ui at the specified branch, tag or commit hash. Defaults to the current branch' c.option '-r remote', '--remote remote', String, 'Creates the pull request in the Stash repository specified by the given remote' c.example 'stash browse -b master', 'Open the files view for this repository at the current branch' c.example 'stash browse -r upstream', 'Open the files view for the "upstream" remote repository' c.action do |args, options| tab = args.shift unless args.empty? config = load_config repoInfo = RepoInfo.create(config, options.remote) branch = options.branch || get_current_branch Launchy.open repoInfo.repoUrl(tab, branch) end end default_command :help program :help_formatter, :compact program :help, 'Authors', 'Seb Ruiz ' program :help, 'Website', 'https://bitbucket.org/atlassian/stash-command-line-tools' # vim set ft=ruby