bpescatore-stash 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZDBlOTcxYzM3YzkzYjY3ZTQ5NWRlYmQ5N2Y0NWVhODQ5MzQ4MzE2Ng==
5
+ data.tar.gz: !binary |-
6
+ M2EyZTlhNDk2ODY0OGQxN2I2MmE3OGQ2YmZmMmQ2OWMzZTdhMzhjYw==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ ZTllZDZmNjY2NjQ3OGViMGY4YjJlMDg4MTc4YWJmZGE0MmU5ZDMxZjE0MmFm
10
+ MDZiMjljOGFmYzhiMjU0NzgxMzM1ODNhZDM2NzI4MWVmZTQwNTU3M2RhMGI3
11
+ ZTkxNjEwNzJjZjA5ODFiNGExYWI5ODU3YjUwYmJlNTU2MmQyNjY=
12
+ data.tar.gz: !binary |-
13
+ ZTZjZGI0NGVmOTQ2YzVjMGYxYWI4MTJhNDIxNmQ1NTU4ZjhmYjM0ZjY5OTAx
14
+ ODhkMzEwYjczZjJhZDY2YmE2MTJiMDg0NjYxNmRmMmYwNDMzYjNhYmI5MTQ2
15
+ OTEzNjQ1ZjM3ZDY2YzA2YTliYTVmZTY1N2VmNWJjYmEwNDM0MDI=
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,22 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ gem "git", ">= 1.2.5"
7
+ gem "json", ">= 1.7.5"
8
+ gem "commander", "~> 4.1.2"
9
+ gem "launchy", "~> 2.4.2"
10
+
11
+ # Add dependencies to develop your gem here.
12
+ # Include everything needed to run rake, tests, features, etc.
13
+ group :development do
14
+ gem "shoulda", ">= 0"
15
+ gem "rdoc", "~> 3.12"
16
+ gem "bundler", ">= 1.2.0"
17
+ gem "jeweler", "~> 2.0.0"
18
+ gem "rcov", ">= 0", :platforms => :ruby_18
19
+ gem "simplecov", ">= 0", :platforms => :ruby_19, :require => "false"
20
+ gem "minitest", ">= 0", :platforms => :ruby_19
21
+ gem "mocha", ">= 0"
22
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Seb Ruiz
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,114 @@
1
+ # Atlassian Stash Command Line Tools
2
+
3
+ ## Installing this tool
4
+ This command line helper for Stash is written in Ruby and is deployed as a [Ruby Gem](https://rubygems.org/gems/atlassian-stash/). Installation is easy, simply run the following command
5
+
6
+ ```
7
+ #!text
8
+ $> gem install atlassian-stash
9
+ ```
10
+
11
+ (Protip: you might need to `sudo`)
12
+
13
+ Once the gem is installed, the command `stash` will be in your `$PATH`
14
+
15
+ ## Configuration and usage
16
+ Run `stash configure`. This will prompt for details about your Stash instance. If no password is provided, then you will be prompted for a password when executing commands to Stash. Currently, the password is stored in plain text in a configuration file, `~/.stashconfig.yml` which is protected with a permission bit of `0600`.
17
+
18
+ ### Creating a pull request
19
+ Use the `pull-request` command to create a pull request in Stash. For example:
20
+
21
+ ```
22
+ #!text
23
+ $> stash pull-request topicBranch master @michael
24
+ Create a pull request from branch 'topicBranch' into 'master' with 'michael' added as a reviewer
25
+ ```
26
+
27
+ See the usage for command details
28
+
29
+ ```
30
+ #!text
31
+ $> stash help pull-request
32
+ ```
33
+
34
+ ### Opening the Stash web UI
35
+ Use the `browse` command to open the Stash UI for your repository in the browser.
36
+
37
+ ```
38
+ #!text
39
+ $> stash browse -b develop
40
+ Open the browser at the Stash repository page for the branch 'develop'
41
+ ```
42
+
43
+ For more options, see the help
44
+
45
+ ```
46
+ #!text
47
+ stash help browse
48
+ ```
49
+
50
+ ## Configuration options
51
+
52
+ Running `stash configure` will prepopulate `~/.stashconfig.yml` with a variety of options. Complete options are:
53
+
54
+ ```
55
+ #!yaml
56
+ username: seb # username to connect to stash server.
57
+ password: s3cr3t # password for user. If ommitted, you will be prompted at the terminal when making a request to Stash
58
+ stash_url: https://stash.server.com # fully qualified stash url
59
+ open: true # opens newly created pull requests in the browser
60
+ ssl_no_verify: true # do not check ssl certificates for the configured stash server
61
+ ```
62
+
63
+ ## Troubleshooting
64
+ Q: I installed the gem, but the `stash` command doesn't work.
65
+ A: Do you have another command called `stash` or do you have an alias? Have a look where the command maps to
66
+
67
+ ```
68
+ #!text
69
+ $> which -a stash
70
+ ```
71
+
72
+ Then check the value of your $PATH
73
+
74
+ ## I want to contribute
75
+ Thanks! Please [fork this project](https://bitbucket.org/atlassian/stash-command-line-tools/fork) and create a pull request to submit changes back to the original project.
76
+
77
+ ### Build instructions
78
+ Building this gem is easy. To get started, run the following commands:
79
+
80
+ ```
81
+ #!text
82
+ $> gem install bundler
83
+ $> bundle install
84
+ ```
85
+
86
+ Now start hacking, and run the stash command by invoking `./bin/stash command`
87
+
88
+ ### Testing
89
+
90
+ Easy:
91
+
92
+ ```
93
+ $> rake test
94
+ ```
95
+
96
+ ### Releasing
97
+
98
+ #### Bumping versions
99
+
100
+ Use `rake version`:
101
+
102
+ ```
103
+ version -- displays the current version
104
+ version:bump:major -- bump the major version by 1
105
+ version:bump:minor -- bump the a minor version by 1
106
+ version:bump:patch -- bump the patch version by 1
107
+ version:write -- writes out an explicit version
108
+ ```
109
+
110
+ #### Releasing
111
+
112
+ ```
113
+ $> rake release
114
+ ```
data/Rakefile ADDED
@@ -0,0 +1,69 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "bpescatore-stash"
18
+ gem.homepage = "https://bitbucket.org/atlassian/stash-command-line-tools"
19
+ gem.license = "MIT"
20
+ gem.summary = "Command line tools for Atlassian Stash"
21
+ gem.description = "Provides convenient functions for interacting with Atlassian Stash through the command line"
22
+ gem.email = "bpescatore@mocana.com"
23
+ gem.authors = ["Seb Ruiz"]
24
+ # dependencies defined in Gemfile
25
+ gem.executables = ["stash"]
26
+ end
27
+ Jeweler::RubygemsDotOrgTasks.new
28
+
29
+ require 'rake/testtask'
30
+ Rake::TestTask.new(:test) do |test|
31
+ test.libs << 'lib' << 'test'
32
+ test.pattern = 'test/**/test_*.rb'
33
+ test.verbose = true
34
+ end
35
+
36
+ task :default => :test
37
+
38
+ begin
39
+ require 'rcov/rcovtask'
40
+
41
+ Rcov::RcovTask.new do |test|
42
+ test.libs << 'test'
43
+ test.pattern = 'test/**/test_*.rb'
44
+ test.verbose = true
45
+ test.rcov_opts << '--exclude "gems/*"'
46
+ end
47
+ rescue LoadError => e
48
+ end
49
+
50
+ begin
51
+ require "simplecov"
52
+
53
+ desc "Execute tests with coverage report"
54
+ task :simplecov do
55
+ ENV["COVERAGE"]="true"
56
+ Rake::Task["test"].execute
57
+ end
58
+ rescue LoadError
59
+ end
60
+
61
+ require 'rdoc/task'
62
+ Rake::RDocTask.new do |rdoc|
63
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
64
+
65
+ rdoc.rdoc_dir = 'rdoc'
66
+ rdoc.title = "atlassian-stash #{version}"
67
+ rdoc.rdoc_files.include('README*')
68
+ rdoc.rdoc_files.include('lib/**/*.rb')
69
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.3.2
data/bin/stash ADDED
@@ -0,0 +1,170 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require File.dirname(__FILE__) + "/../lib/stash_cli"
5
+ require 'commander/import'
6
+ require 'yaml'
7
+ require 'launchy'
8
+ require 'pathname'
9
+
10
+ program :name, "Atlassian Stash CLI"
11
+ program :version, Atlassian::Stash::Version::STRING
12
+ program :description, "Provides convenient functions for interacting with Atlassian Stash through the command line"
13
+
14
+ include Atlassian::Stash
15
+ include Atlassian::Stash::Git
16
+
17
+ $configFileName = ".stashconfig.yml"
18
+ $configFile = File.join(ENV['HOME'], $configFileName)
19
+
20
+ def load_config
21
+ raise "No Stash configuration found; please run configure" unless File.exists? $configFile
22
+ config = YAML.load_file($configFile)
23
+ raise "Stash configuration file is incomplete, please re-run configure" unless config['username'] and config['stash_url']
24
+ config.merge! repo_config if repo_config
25
+ config
26
+ end
27
+
28
+ def repo_config
29
+ return @repo_config if @repo_config
30
+
31
+ repo_root = get_repo_root_directory.strip
32
+ repo_directory = Pathname.new(repo_root)
33
+ stash_config = repo_directory + $configFileName
34
+ if (stash_config.exist? && stash_config.file?)
35
+ @repo_config = YAML.load_file(stash_config)
36
+ end
37
+ Hash.new
38
+ end
39
+
40
+ command 'configure' do |c|
41
+ c.syntax = 'configure'
42
+ c.description = 'Setup configuration details to your Stash instance'
43
+ c.example 'stash configure --username sebr --password s3cre7 --stash_url http://stash.mycompany.com', 'Setup Stash CLI with credentials to the Stash server'
44
+ c.option '--username user', String, 'Writes your Stash username to the configuration file'
45
+ c.option '--password password', String, 'Writes your Stash user password to the configuration file. If omitted, password will be prompted to be entered'
46
+ c.option '--stashUrl', String, 'Writes the Stash server url to the configuration file'
47
+ c.option '--remote', String, 'Pull requests will be created in the Stash repository specified by the given remote'
48
+ c.action do |args, options|
49
+ username = options.username ? options.username : ask("Stash Username: ")
50
+ password = options.password ? options.password : ask("Stash Password (optional): ") { |q| q.echo = "*" }
51
+ stashUrl = options.stashUrl ? options.stashUrl : ask("Stash URL: ")
52
+ remote = options.remote ? options.remote : ask("Remote (optional): ")
53
+
54
+ c = {
55
+ 'stash_url' => stashUrl.to_s
56
+ }
57
+
58
+ c['username'] = username.to_s unless username.empty?
59
+ c['password'] = password.to_s unless password.empty?
60
+ c['remote'] = remote.to_s unless remote.empty?
61
+
62
+ File.open($configFile, 'w') do |out|
63
+ YAML.dump(c, out)
64
+ end
65
+
66
+ File.chmod 0600, $configFile
67
+
68
+ create_git_alias if agree "Create a git alias 'git create-pull-request'? "
69
+ end
70
+ end
71
+
72
+ command 'pull-request' do |c|
73
+ def extract_reviewers(args = [])
74
+ default_reviewers = repo_config.nil? ? Array.new : Array(repo_config[:reviewers])
75
+ default_reviewers.concat args.collect { |user|
76
+ user[1..-1] if user.start_with?("@")
77
+ }.compact
78
+ end
79
+
80
+ c.syntax = 'pull-request [sourceBranch] targetBranch [@reviewer1 @reviewer2] [options]'
81
+ c.description = 'Create a pull request in Stash'
82
+ c.option '-d DESCRIPTION', '--description DESCRIPTION', String, 'Use the following description when creating the pull request'
83
+ c.option '-T TITLE', '--title TITLE', String, 'Use the following title when creating the pull request'
84
+ c.option '-r remote', '--remote remote', String, 'Creates the pull request in the Stash repository specified by the given remote'
85
+ c.option '-o', '--open', 'Open the created pull request page in a web browser'
86
+ c.example 'stash pull-request topicBranch master @michael', "Create a pull request from branch 'topicBranch' into 'master' with 'michael' added as a reviewer"
87
+ c.example 'stash pull-request master', "Create a pull request from the current git branch into 'master'"
88
+ 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'"
89
+ c.example 'stash pull-request topicBranch upstream/master', "Create a pull request from branch 'topicBranch' into branch 'master' on the remote named 'upstream'"
90
+ c.example 'stash pull-request remotes/upstream/master', "Create a pull request from the current branch into branch 'master' on the remote named 'upstream'"
91
+ c.action do |args, options|
92
+ if args.length == 0
93
+ command(:help).run('pull-request')
94
+ Process.exit
95
+ end
96
+
97
+ source = args.shift
98
+ if args.empty? or args.first.start_with?("@")
99
+ target = source
100
+ source = get_current_branch
101
+ reviewers = extract_reviewers args
102
+ else
103
+ target = args.shift
104
+ reviewers = extract_reviewers args
105
+ end
106
+
107
+ # Strip out any starting 'remotes/' from branch name for matching
108
+ if source.index('remotes/') == 0
109
+ source = source['remotes/'.size..-1]
110
+ end
111
+ if target.index('remotes/') == 0
112
+ target = target['remotes/'.size..-1]
113
+ end
114
+
115
+ options.src_remote = options.remote
116
+ if not is_branch?(source)
117
+ if not is_branch?("remotes/" + source)
118
+ raise "fatal: unrecogonized source branch"
119
+ end
120
+ # If a remote matches, split the remote out of the refspec
121
+ options.src_remote = source.split('/')[0]
122
+ source = source.split('/')[1..-1].join('/')
123
+ end
124
+
125
+ if not is_branch?(target)
126
+ if not is_branch?("remotes/" + target)
127
+ raise "fatal: unrecognized target branch"
128
+ end
129
+ # If a remote matches, split the remote out of the refspec
130
+ options.target_remote = target.split('/')[0]
131
+ target = target.split('/')[1..-1].join('/')
132
+ end
133
+
134
+ ensure_within_git! do
135
+ cpr = CreatePullRequest.new(load_config)
136
+ cpr.create_pull_request source, target, reviewers, options
137
+ end
138
+ end
139
+ end
140
+
141
+ command 'browse' do |c|
142
+ c.syntax = 'browse [browse|commits|pull-requests]'
143
+ c.description = 'Open the Stash web ui for this repository'
144
+ 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'
145
+ c.option '-r remote', '--remote remote', String, 'Creates the pull request in the Stash repository specified by the given remote'
146
+ c.example 'stash browse -b master', 'Open the files view for this repository at the current branch'
147
+ c.example 'stash browse -r upstream', 'Open the files view for the "upstream" remote repository'
148
+
149
+ c.action do |args, options|
150
+
151
+ tab = args.shift unless args.empty?
152
+
153
+ config = load_config
154
+
155
+ repoInfo = RepoInfo.create(config, options.remote)
156
+
157
+ branch = options.branch || get_current_branch
158
+
159
+ Launchy.open repoInfo.repoUrl(tab, branch)
160
+ end
161
+ end
162
+
163
+
164
+ default_command :help
165
+ program :help_formatter, :compact
166
+ program :help, 'Authors', 'Seb Ruiz <sruiz@atlassian.com>'
167
+ program :help, 'Website', 'https://bitbucket.org/atlassian/stash-command-line-tools'
168
+
169
+
170
+ # vim set ft=ruby
@@ -0,0 +1,57 @@
1
+
2
+
3
+ module Atlassian
4
+ module Stash
5
+ module Git
6
+
7
+ DEFAULT_REMOTE="origin"
8
+
9
+ def get_current_branch
10
+ %x(git symbolic-ref HEAD)[/refs\/heads\/(.*)/, 1]
11
+ end
12
+
13
+ def get_branches()
14
+ %x{git branch -a}
15
+ end
16
+
17
+ def is_branch?(match)
18
+ not get_branches.split().select{|x| x == match}.empty?
19
+ end
20
+
21
+ def is_in_git_repository?
22
+ system('git rev-parse')
23
+ end
24
+
25
+ def get_remotes
26
+ %x(git remote -v)
27
+ end
28
+
29
+ def get_remote_url(remote=nil)
30
+ remotes = get_remotes
31
+ return nil if remotes.empty?
32
+
33
+ remote = DEFAULT_REMOTE if remote.nil? || remote.empty?
34
+
35
+ origin = remotes.split("\n").collect { |r| r.strip }.grep(/^#{remote}.*\(push\)$/).first
36
+ return nil if origin.nil?
37
+ URI.extract(origin).first
38
+ end
39
+
40
+ def ensure_within_git!
41
+ if is_in_git_repository?
42
+ yield
43
+ else
44
+ raise "fatal: Not a git repository"
45
+ end
46
+ end
47
+
48
+ def create_git_alias
49
+ %x(git config --global alias.create-pull-request "\!sh -c 'stash pull-request \\$0'")
50
+ end
51
+
52
+ def get_repo_root_directory
53
+ %x(git rev-parse --show-toplevel)
54
+ end
55
+ end
56
+ end
57
+ end