atlassian-stash 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+