atlassian-stash 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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,17 @@
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 "json"
7
+ gem "commander"
8
+
9
+ # Add dependencies to develop your gem here.
10
+ # Include everything needed to run rake, tests, features, etc.
11
+ group :development do
12
+ gem "shoulda", ">= 0"
13
+ gem "rdoc", "~> 3.12"
14
+ gem "bundler", ">= 1.2.0"
15
+ gem "jeweler", "~> 1.8.4"
16
+ gem "rcov", ">= 0"
17
+ 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,16 @@
1
+ Atlassian Stash CLI
2
+ ===================
3
+
4
+
5
+ Build instructions
6
+ ------------------
7
+ 1. gem install bundler
8
+ 2. bundle install
9
+
10
+ Configuration
11
+ -------------
12
+ Create a file, `.stashconfig.yml` in your `$HOME` directory, with the following contents
13
+
14
+ username: YOUR_USERNAME
15
+ password: YOUR_PASSWORD
16
+ stash_url: http://localhost:7990/stash
data/Rakefile ADDED
@@ -0,0 +1,54 @@
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 = "atlassian-stash"
18
+ gem.homepage = "https://bitbucket.org/sebr/git-stash-scripts"
19
+ gem.license = "MIT"
20
+ gem.summary = "CLI for Atlassian Stash"
21
+ gem.description = "Provides convenient functions for interacting with Atlassian Stash through the command line"
22
+ gem.email = "sruiz@atlassian.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
+ require 'rcov/rcovtask'
37
+ Rcov::RcovTask.new do |test|
38
+ test.libs << 'test'
39
+ test.pattern = 'test/**/test_*.rb'
40
+ test.verbose = true
41
+ test.rcov_opts << '--exclude "gems/*"'
42
+ end
43
+
44
+ task :default => :test
45
+
46
+ require 'rdoc/task'
47
+ Rake::RDocTask.new do |rdoc|
48
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
49
+
50
+ rdoc.rdoc_dir = 'rdoc'
51
+ rdoc.title = "atlassian-stash #{version}"
52
+ rdoc.rdoc_files.include('README*')
53
+ rdoc.rdoc_files.include('lib/**/*.rb')
54
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/bin/stash ADDED
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require File.dirname(__FILE__) + "/../lib/stash_cli"
5
+ #require 'stash_cli'
6
+ require 'commander/import'
7
+ require 'yaml'
8
+
9
+ program :name, "Atlassian Stash CLI"
10
+ program :version, Atlassian::Stash::Version::STRING
11
+ program :description, "Provides convenient functions for interacting with Atlassian Stash through the command line"
12
+
13
+ include Atlassian::Stash
14
+ include Atlassian::Stash::Git
15
+
16
+ $configFile = File.join(Etc.getpwuid.dir, ".stashconfig.yml")
17
+
18
+ def load_config
19
+ raise "No Stash configuration found; please run setup" unless File.exists? $configFile
20
+ config = YAML.load_file($configFile)
21
+ raise "Stash configuration file is incomplete, please re-run setup" unless config['username'] and config['password'] and config['stash_url']
22
+ config
23
+ end
24
+
25
+ program :help_formatter, :compact
26
+
27
+ command 'setup' do |c|
28
+ c.syntax = 'setup'
29
+ c.description = 'Setup configuration details to your Stash instance'
30
+ c.example 'stash setup --username sebr --password s3cre7 --stash_url http://stash.mycompany.com', 'Setup Stash CLI with credentials to the Stash server'
31
+ c.option '--username user', String, 'Writes your Stash username to the configuration file'
32
+ c.option '--password password', String, 'Writes your Stash user password to the configuration file. If omitted, password will be prompted to be entered'
33
+ c.option '--stashUrl', String, 'Writes the Stash server url to the configuration file'
34
+ c.action do |args, options|
35
+ username = options.username ? options.username : ask("Stash Username: ")
36
+ password = options.password ? options.password : ask("Stash Password: ") { |q| q.echo = "*" }
37
+ stashUrl = options.stashUrl ? options.stashUrl : ask("Stash URL: ")
38
+
39
+ c = {
40
+ 'username' => username.to_s,
41
+ 'password' => password.to_s,
42
+ 'stash_url' => stashUrl.to_s
43
+ }
44
+
45
+ File.open($configFile, 'w') do |out|
46
+ YAML.dump(c, out)
47
+ end
48
+
49
+ File.chmod 0600, $configFile
50
+ end
51
+ end
52
+
53
+ command 'pull-request' do |c|
54
+ def extract_reviewers(args = [])
55
+ args.collect { |user|
56
+ user[1..-1] if user.start_with?("@")
57
+ }.compact
58
+ end
59
+
60
+ c.syntax = 'pull-request source target'
61
+ c.description = 'Create a pull request in Stash'
62
+ c.example 'stash pull-request topicBranch master', "Creates a pull request from branch 'topicBranch' into 'master'"
63
+ c.action do |args, options|
64
+ if args.length == 0
65
+ command(:help).run(*args)
66
+ Process.exit
67
+ end
68
+
69
+ source = args.shift
70
+ if args.empty? or args.first.start_with?("@")
71
+ target = source
72
+ source = get_current_branch()
73
+ reviewers = extract_reviewers args
74
+ else
75
+ target = args.shift
76
+ reviewers = extract_reviewers args
77
+ end
78
+
79
+ ensure_within_git! do
80
+ cpr = CreatePullRequest.new(load_config)
81
+ cpr.create_pull_request source, target, reviewers
82
+ end
83
+ end
84
+ end
85
+
86
+ default_command :help
87
+
88
+ # vim set ft=ruby
@@ -0,0 +1,27 @@
1
+
2
+
3
+ module Atlassian
4
+ module Stash
5
+ module Git
6
+ def get_current_branch
7
+ %x(git symbolic-ref HEAD)[/refs\/heads\/(.*)/, 1]
8
+ end
9
+
10
+ def is_in_git_repository?
11
+ system('git rev-parse')
12
+ end
13
+
14
+ def get_remote_url
15
+ URI.extract(%x(git remote -v)).first
16
+ end
17
+
18
+ def ensure_within_git!
19
+ if is_in_git_repository?
20
+ yield
21
+ else
22
+ raise "fatal: Not a git repository"
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,114 @@
1
+ require 'json'
2
+ require 'net/http'
3
+ require 'net/https'
4
+ require 'uri'
5
+ require 'git'
6
+
7
+ module Atlassian
8
+ module Stash
9
+ class CreatePullRequestResource
10
+ attr_accessor :resource
11
+
12
+ def initialize(projectKey, slug, title, description, reviewers, source, target)
13
+ repository = {
14
+ 'slug' => slug,
15
+ 'project' => {
16
+ 'key' => projectKey
17
+ }
18
+ }
19
+ fromRef = {
20
+ 'id' => source,
21
+ 'repository' => repository
22
+ }
23
+ toRef = {
24
+ 'id' => target,
25
+ 'repository' => repository
26
+ }
27
+ @resource = {
28
+ 'title' => title,
29
+ 'fromRef' => fromRef,
30
+ 'toRef' => toRef
31
+ }
32
+
33
+ @resource["reviewers"] = reviewers.collect { |r|
34
+ {
35
+ 'user' => {
36
+ 'name' => r
37
+ }
38
+ }
39
+ } unless reviewers.empty?
40
+ end
41
+ end
42
+
43
+ class CreatePullRequest
44
+
45
+ RepoInfo = Struct.new(:projectKey, :slug)
46
+
47
+ def initialize(config)
48
+ @config = config
49
+ end
50
+
51
+ def extract_repository_info
52
+ if m = get_remote_url.match(/\/(\w+)\/(\w+).git$/)
53
+ return RepoInfo.new(m[1], m[2])
54
+ end
55
+ raise "Repository does not seem to be hosted in Stash"
56
+ end
57
+
58
+ def generate_pull_request_title(source, target)
59
+ output = %x(git log --reverse --format=%s #{target}..#{source}).split(/\n/).first
60
+ output || 'Merge \'%s\' into \'%s\'' % [source, target]
61
+ end
62
+
63
+
64
+ def create_pull_request(source, target, reviewers)
65
+ Process.exit if not target or not source
66
+
67
+ repoInfo = extract_repository_info
68
+ title = generate_pull_request_title source, target
69
+ description = ''
70
+
71
+ resource = CreatePullRequestResource.new(repoInfo.projectKey, repoInfo.slug, title, description, reviewers, source, target).resource
72
+
73
+ uri = URI.parse(@config["stash_url"])
74
+ prPath = uri.path + '/projects/' + repoInfo.projectKey + '/repos/' + repoInfo.slug + '/pull-requests'
75
+
76
+ req = Net::HTTP::Post.new(prPath, initheader = {'Content-Type' => 'application/json', 'Accept' => 'application/json'})
77
+ req.basic_auth @config["username"], @config["password"]
78
+ req.body = resource.to_json
79
+ http = Net::HTTP.new(uri.host, uri.port)
80
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
81
+ http.use_ssl = true
82
+
83
+ response = http.start {|http| http.request(req) }
84
+
85
+ if not response.is_a? Net::HTTPCreated
86
+ responseBody = JSON.parse(response.body)
87
+ if responseBody['errors']
88
+ responseBody['errors'].collect { |error|
89
+ puts error['message']
90
+ if error['reviewerErrors']
91
+ error['reviewerErrors'].collect { |revError|
92
+ puts revError['message']
93
+ }
94
+ end
95
+ }
96
+ elsif responseBody['message']
97
+ puts responseBody['message']
98
+ else
99
+ puts 'An unknown error occurred.'
100
+ puts response.code
101
+ puts response.body
102
+ end
103
+ else
104
+ responseBody = JSON.parse(response.body)
105
+ prUri = uri.clone
106
+ prUri.path = prPath + '/' + responseBody['id'].to_s
107
+ puts prUri.to_s
108
+ end
109
+
110
+ end
111
+ end
112
+ end
113
+ end
114
+
@@ -0,0 +1,9 @@
1
+
2
+ module Atlassian
3
+ module Stash
4
+ module Version
5
+ STRING = IO.readlines(File.dirname(__FILE__) + "/../../../VERSION").first.strip
6
+ end
7
+ end
8
+ end
9
+
data/lib/stash_cli.rb ADDED
@@ -0,0 +1,2 @@
1
+
2
+ Dir[File.join(File.dirname(__FILE__), "atlassian", "stash", "*.rb")].sort.each {|f| require f}
data/test/helper.rb ADDED
@@ -0,0 +1,20 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+ require 'shoulda'
12
+
13
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ # require 'atlassian-stash'
16
+ require File.dirname(__FILE__) + "/../lib/stash_cli"
17
+
18
+
19
+ class Test::Unit::TestCase
20
+ end
@@ -0,0 +1,21 @@
1
+ require 'helper'
2
+
3
+ include Atlassian::Stash
4
+ include Atlassian::Stash::Git
5
+
6
+ class TestStashCreatePullRequest < Test::Unit::TestCase
7
+
8
+ should "extract project key and repo slug from Stash remote" do
9
+ get_remote_url = "https://sruiz@stash-dev.atlassian.com/scm/STASH/stash.git"
10
+ cpr = CreatePullRequest.new nil
11
+ ri = cpr.extract_repository_info
12
+ assert_equal 'STASH', ri.projectKey
13
+ assert_equal 'stash', ri.slug
14
+ end
15
+
16
+ # should "extracting project key and repo slug from non stash url raises exception" do
17
+ # get_remote_url = "git@bitbucket.org:sebr/atlassian-stash-rubygem.git"
18
+ # cpr = CreatePullRequest.new nil
19
+ # assert_raise(RuntimeError) { cpr.extract_repository_info }
20
+ # end
21
+ end
metadata ADDED
@@ -0,0 +1,163 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: atlassian-stash
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Seb Ruiz
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2012-10-26 00:00:00 +11:00
18
+ default_executable: stash
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ prerelease: false
22
+ type: :runtime
23
+ name: json
24
+ version_requirements: &id001 !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ requirement: *id001
32
+ - !ruby/object:Gem::Dependency
33
+ prerelease: false
34
+ type: :runtime
35
+ name: commander
36
+ version_requirements: &id002 !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ segments:
41
+ - 0
42
+ version: "0"
43
+ requirement: *id002
44
+ - !ruby/object:Gem::Dependency
45
+ prerelease: false
46
+ type: :development
47
+ name: shoulda
48
+ version_requirements: &id003 !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ segments:
53
+ - 0
54
+ version: "0"
55
+ requirement: *id003
56
+ - !ruby/object:Gem::Dependency
57
+ prerelease: false
58
+ type: :development
59
+ name: rdoc
60
+ version_requirements: &id004 !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ~>
63
+ - !ruby/object:Gem::Version
64
+ segments:
65
+ - 3
66
+ - 12
67
+ version: "3.12"
68
+ requirement: *id004
69
+ - !ruby/object:Gem::Dependency
70
+ prerelease: false
71
+ type: :development
72
+ name: bundler
73
+ version_requirements: &id005 !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ segments:
78
+ - 1
79
+ - 2
80
+ - 0
81
+ version: 1.2.0
82
+ requirement: *id005
83
+ - !ruby/object:Gem::Dependency
84
+ prerelease: false
85
+ type: :development
86
+ name: jeweler
87
+ version_requirements: &id006 !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ~>
90
+ - !ruby/object:Gem::Version
91
+ segments:
92
+ - 1
93
+ - 8
94
+ - 4
95
+ version: 1.8.4
96
+ requirement: *id006
97
+ - !ruby/object:Gem::Dependency
98
+ prerelease: false
99
+ type: :development
100
+ name: rcov
101
+ version_requirements: &id007 !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ segments:
106
+ - 0
107
+ version: "0"
108
+ requirement: *id007
109
+ description: Provides convenient functions for interacting with Atlassian Stash through the command line
110
+ email: sruiz@atlassian.com
111
+ executables:
112
+ - stash
113
+ extensions: []
114
+
115
+ extra_rdoc_files:
116
+ - LICENSE.txt
117
+ - README.md
118
+ files:
119
+ - .document
120
+ - Gemfile
121
+ - LICENSE.txt
122
+ - README.md
123
+ - Rakefile
124
+ - VERSION
125
+ - bin/stash
126
+ - lib/atlassian/stash/git.rb
127
+ - lib/atlassian/stash/pullrequest.rb
128
+ - lib/atlassian/stash/version.rb
129
+ - lib/stash_cli.rb
130
+ - test/helper.rb
131
+ - test/test_stash-create-pull-request.rb
132
+ has_rdoc: true
133
+ homepage: https://bitbucket.org/sebr/git-stash-scripts
134
+ licenses:
135
+ - MIT
136
+ post_install_message:
137
+ rdoc_options: []
138
+
139
+ require_paths:
140
+ - lib
141
+ required_ruby_version: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ segments:
146
+ - 0
147
+ version: "0"
148
+ required_rubygems_version: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ segments:
153
+ - 0
154
+ version: "0"
155
+ requirements: []
156
+
157
+ rubyforge_project:
158
+ rubygems_version: 1.3.6
159
+ signing_key:
160
+ specification_version: 3
161
+ summary: CLI for Atlassian Stash
162
+ test_files: []
163
+