assisted_workflow 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- assisted_workflow (0.1.4)
4
+ assisted_workflow (0.2.0)
5
5
  hashie (~> 2.0.5)
6
6
  octokit (~> 2.0)
7
7
  pivotal-tracker (~> 0.5.12)
@@ -2,8 +2,12 @@ require "assisted_workflow/version"
2
2
  require "assisted_workflow/exceptions"
3
3
 
4
4
  module AssistedWorkflow
5
- autoload :Pivotal, "assisted_workflow/pivotal"
6
- autoload :Git, "assisted_workflow/git"
7
- autoload :Github, "assisted_workflow/github"
8
5
  autoload :ConfigFile, "assisted_workflow/config_file"
6
+ autoload :Output, "assisted_workflow/output"
7
+
8
+ module Addons
9
+ autoload :Pivotal, "assisted_workflow/addons/pivotal"
10
+ autoload :Git, "assisted_workflow/addons/git"
11
+ autoload :Github, "assisted_workflow/addons/github"
12
+ end
9
13
  end
@@ -0,0 +1,46 @@
1
+ module AssistedWorkflow::Addons
2
+
3
+ class Base
4
+
5
+ def initialize(output, options = {})
6
+ @output = output
7
+ validate_options!(options)
8
+ end
9
+
10
+ def name
11
+ self.class.name.downcase.split("::").last
12
+ end
13
+
14
+ def valid?
15
+ false
16
+ end
17
+
18
+ class << self
19
+
20
+ def required_options(*args)
21
+ @required_options = Array(args).map(&:to_s)
22
+ end
23
+
24
+ def get_required_options
25
+ @required_options || []
26
+ end
27
+ end
28
+
29
+ protected #===============================================================
30
+
31
+ def log(message)
32
+ @output.say_status(name, message) if @output
33
+ end
34
+
35
+ def validate_options!(options)
36
+ if options.nil?
37
+ raise AssistedWorkflow::Error, "#{name} missing configuration"
38
+ end
39
+ missing_keys = self.class.get_required_options - options.keys
40
+ if missing_keys.size > 0
41
+ raise AssistedWorkflow::Error, "#{name} missing configuration: #{missing_keys.inspect}"
42
+ end
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,108 @@
1
+ require "assisted_workflow/exceptions"
2
+ require "assisted_workflow/addons/base"
3
+
4
+ module AssistedWorkflow::Addons
5
+
6
+ class GitError < AssistedWorkflow::Error; end
7
+
8
+ class Git < Base
9
+
10
+ DESCRIPTION_LIMIT = 30
11
+
12
+ def initialize(output, options = {})
13
+ super
14
+ @command_options = {:raise_error => true}.merge(options)
15
+ end
16
+
17
+ # creates a new git branch based on story attributes
18
+ # the branch name format is:
19
+ # => story_onwer_username.story_id.story_name
20
+ def create_story_branch(story)
21
+ log "creating the feature branch"
22
+ branch = branch_name(story)
23
+ git "checkout -b #{branch}"
24
+ # git "push --set-upstream origin #{branch}"
25
+ end
26
+
27
+ # run all the git steps required for a clean pull request
28
+ def rebase_and_push
29
+ check_everything_commited!
30
+ branch = current_branch
31
+ git "checkout master"
32
+ git "pull --rebase"
33
+ git "checkout #{branch}"
34
+ git "rebase master"
35
+ git "push -u -f origin #{branch}"
36
+ end
37
+
38
+ # returns the current story id based on branch name
39
+ def current_story_id
40
+ current_branch.split(".")[1]
41
+ end
42
+
43
+ # returns the current local branch name
44
+ def current_branch
45
+ git("rev-parse --abbrev-ref HEAD", :silent => true)
46
+ end
47
+
48
+ # returns the repository name assigned to origin following the format:
49
+ # owner/project
50
+ def repository
51
+ url = git("config --get remote.origin.url", :error => "cannot find 'origin' remote repository url")
52
+ url.gsub("git@github.com:", "").gsub("https://github.com/", "").gsub(/\.git$/, "").chomp
53
+ end
54
+
55
+ # check if current branch is merged into master
56
+ def is_merged?
57
+ check_everything_commited!
58
+ branch = current_branch
59
+ git "checkout master"
60
+ git "pull --rebase"
61
+ merged = git("branch --merged").include?(branch)
62
+ git "checkout #{branch}"
63
+ merged
64
+ end
65
+
66
+ # removes current branch and its remote version
67
+ def remove_branch
68
+ branch = current_branch
69
+ git "push origin :#{branch}", :raise_error => false
70
+ git "checkout master"
71
+ git "branch -D #{branch}"
72
+ end
73
+
74
+ private #=================================================================
75
+
76
+ def git(command, options = {})
77
+ options = @command_options.merge(options)
78
+ puts "git #{command}" unless options[:silent] == true
79
+ result = system("git #{command}")
80
+ if system_error? && options[:raise_error]
81
+ msg = ["git command error", options[:error]].compact.join(": ")
82
+ raise GitError, msg
83
+ end
84
+ result
85
+ end
86
+
87
+ def system(command)
88
+ %x{#{command}}.chomp
89
+ end
90
+
91
+ def system_error?
92
+ $? != 0
93
+ end
94
+
95
+ def branch_name(story)
96
+ description = story.name.to_s.downcase.gsub(/\W/, "_").slice(0, DESCRIPTION_LIMIT)
97
+ [story.other_id, story.id, description].join(".").downcase
98
+ end
99
+
100
+ def not_commited_changes
101
+ git("status --porcelain", :silent => true).split("\n")
102
+ end
103
+
104
+ def check_everything_commited!
105
+ raise AssistedWorkflow::Error, "git: there are not commited changes" unless not_commited_changes.empty?
106
+ end
107
+ end
108
+ end
@@ -1,11 +1,14 @@
1
1
  require "assisted_workflow/exceptions"
2
+ require "assisted_workflow/addons/base"
2
3
  require "octokit"
3
4
 
4
- module AssistedWorkflow
5
+ module AssistedWorkflow::Addons
5
6
 
6
- class Github
7
- def initialize(options)
8
- validate_options!(options)
7
+ class Github < Base
8
+ required_options :token
9
+
10
+ def initialize(output, options = {})
11
+ super
9
12
  @client = Octokit::Client.new(:access_token => options["token"])
10
13
  end
11
14
 
@@ -16,31 +19,21 @@ module AssistedWorkflow
16
19
  # @param story [Story] Pivotal story object
17
20
  # @return [Sawyer::Resource] The newly created pull request
18
21
  def create_pull_request(repo, branch, story)
22
+ log "submiting the new pull request"
19
23
  base = "master"
20
24
  title = "[##{story.id}] #{story.name}"
21
25
  pull_request = @client.create_pull_request(repo, base, branch, title, story.description)
22
26
  if pull_request.nil?
23
27
  raise AssistedWorkflow::Error, "error on submiting the pull request"
24
28
  else
25
- pull_request
29
+ url = pull_request._links.html.href
30
+ log "new pull request at #{url}"
31
+ url
26
32
  end
27
33
  end
28
34
 
29
35
  def valid?
30
36
  @client.user_authenticated?
31
37
  end
32
-
33
- private
34
-
35
- def validate_options!(options)
36
- if options.nil? || options.empty?
37
- raise AssistedWorkflow::Error, "github missing configuration"
38
- end
39
- required_keys = %w(token)
40
- missing_keys = required_keys - options.keys
41
- if missing_keys.size > 0
42
- raise AssistedWorkflow::Error, "github missing configuration: #{missing_keys.inspect}"
43
- end
44
- end
45
38
  end
46
39
  end
@@ -1,12 +1,14 @@
1
1
  require "assisted_workflow/exceptions"
2
+ require "assisted_workflow/addons/base"
2
3
  require 'pivotal_tracker'
3
4
 
4
5
  # wrapper class to pivotal api client
5
- module AssistedWorkflow
6
- class Pivotal
6
+ module AssistedWorkflow::Addons
7
+ class Pivotal < Base
8
+ required_options :fullname, :token, :project_id
7
9
 
8
- def initialize(options)
9
- validate_options!(options)
10
+ def initialize(output, options = {})
11
+ super
10
12
 
11
13
  PivotalTracker::Client.token = options["token"]
12
14
  begin
@@ -20,6 +22,7 @@ module AssistedWorkflow
20
22
 
21
23
  def find_story(story_id)
22
24
  if story_id.to_i > 0
25
+ log "loading story ##{story_id}"
23
26
  story = @project.stories.find(story_id)
24
27
  story.other_id = @username || @fullname
25
28
  story.other_id = story.other_id.to_s.downcase.split.join
@@ -28,16 +31,19 @@ module AssistedWorkflow
28
31
  end
29
32
 
30
33
  def start_story(story, options = {})
34
+ log "starting story ##{story.id}"
31
35
  update_story! story, options.merge(:current_state => "started")
32
36
  end
33
37
 
34
38
  def finish_story(story, options = {})
39
+ log "finishing story ##{story.id}"
35
40
  if update_story! story, :current_state => finished_state(story)
36
41
  story.notes.create(:text => options[:note]) if options[:note]
37
42
  end
38
43
  end
39
44
 
40
45
  def pending_stories(options = {})
46
+ log "loading pending stories"
41
47
  states = ["unstarted"]
42
48
  states << "started" if options[:include_started]
43
49
  @project.stories.all(:state => states, :owned_by => @fullname, :limit => 5)
@@ -49,17 +55,6 @@ module AssistedWorkflow
49
55
 
50
56
  private
51
57
 
52
- def validate_options!(options)
53
- if options.nil? || options.empty?
54
- raise AssistedWorkflow::Error, "pivotal missing configuration"
55
- end
56
- required_keys = %w(fullname token project_id)
57
- missing_keys = required_keys - options.keys
58
- if missing_keys.size > 0
59
- raise AssistedWorkflow::Error, "pivotal missing configuration: #{missing_keys.inspect}"
60
- end
61
- end
62
-
63
58
  def finished_state(story)
64
59
  if story.story_type == "chore"
65
60
  "accepted"
@@ -1,188 +1,158 @@
1
1
  require "assisted_workflow"
2
2
  require "thor"
3
3
 
4
- class AssistedWorkflow::CLI < Thor
5
- include Thor::Actions
6
- GLOBAL_CONFIG = File.expand_path(".awconfig", ENV["HOME"])
7
- LOCAL_CONFIG = ".awconfig"
8
- source_root(File.expand_path(File.join(__FILE__, "..", "templates")))
4
+ module AssistedWorkflow
5
+ class CLI < Thor
6
+ include Thor::Actions
7
+ GLOBAL_CONFIG = File.expand_path(".awconfig", ENV["HOME"])
8
+ LOCAL_CONFIG = ".awconfig"
9
+ source_root(File.expand_path(File.join(__FILE__, "..", "templates")))
9
10
 
10
- # tasks shortcuts
11
- map ["-v", "--version"] => :version
12
- map "s" => :start
13
- map "u" => :submit
14
- map "f" => :finish
11
+ # tasks shortcuts
12
+ map ["-v", "--version"] => :version
13
+ map "s" => :start
14
+ map "u" => :submit
15
+ map "f" => :finish
15
16
 
16
- desc "setup", "Setup initial configuration in current project directory"
17
- def setup
18
- copy_file "awconfig.global.tt", GLOBAL_CONFIG
19
- copy_file "awconfig.local.tt", LOCAL_CONFIG
20
- if File.exists?(".git")
21
- copy_file "commit-msg.tt", ".git/hooks/commit-msg"
22
- chmod ".git/hooks/commit-msg", "a+x"
23
- else
24
- raise AssistedWorkflow::Error, ".git folder not found"
17
+ desc "setup", "Setup initial configuration in current project directory"
18
+ def setup
19
+ copy_file "awconfig.global.tt", GLOBAL_CONFIG
20
+ copy_file "awconfig.local.tt", LOCAL_CONFIG
21
+ if File.exists?(".git")
22
+ copy_file "commit-msg.tt", ".git/hooks/commit-msg"
23
+ chmod ".git/hooks/commit-msg", "a+x"
24
+ else
25
+ raise AssistedWorkflow::Error, ".git folder not found"
26
+ end
27
+ out.next_command "set your own configuration running:", "" do |c|
28
+ c << "$ aw config pivotal.fullname='Your Pivotal User Name' --global"
29
+ c << "$ aw config pivotal.token=MYPIVOTALTOKEN --global"
30
+ c << "$ aw config github.token=MYGITHUBOAUTHTOKEN --global"
31
+ c << "$ aw config pivotal.project_id=00001"
32
+ end
25
33
  end
26
- say "set your own configuration editing the .awconfig files or running:", :green
27
- say_command "$ aw config pivotal.fullname='Flavio Granero' --global"
28
- say_command "$ aw config pivotal.token=MYPIVOTALTOKEN --global"
29
- say_command "$ aw config github.token=MYGITHUBOAUTHTOKEN --global"
30
- say_command "$ aw config pivotal.project_id=00001"
31
- end
32
34
 
33
- desc "start [STORY_ID]", "Start the pivotal story and create a new branch to receive the changes"
34
- method_option :all, :type => :boolean, :default => false, :aliases => "-a", :desc => "Show started and pending stories when no story_id is provided"
35
- method_option :estimate, :type => :numeric, :aliases => "-e", :desc => "Sets the story estimate when starting"
36
- def start(story_id=nil)
37
- check_awfile!
38
- story = pivotal.find_story(story_id)
39
- if story.nil?
40
- stories = pivotal.pending_stories(:include_started => options[:all])
41
- print_title "pending stories"
42
- print_stories(stories)
43
- say "start a story using:", :green
44
- say_command "$ aw start [STORY_ID]"
45
- else
46
- say_status "starting story", story.name
47
- pivotal.start_story(story, :estimate => options[:estimate])
48
- print_wrapped story.description, :indent => 2
49
- say "creating the feature branch"
50
- git.create_story_branch(story)
51
- say "after commiting your changes, submit a pull request using:", :green
52
- say_command "$ aw submit"
35
+ desc "start [STORY_ID]", "Start the pivotal story and create a new branch to receive the changes"
36
+ method_option :all, :type => :boolean, :default => false, :aliases => "-a", :desc => "Show started and pending stories when no story_id is provided"
37
+ method_option :estimate, :type => :numeric, :aliases => "-e", :desc => "Sets the story estimate when starting"
38
+ def start(story_id=nil)
39
+ check_awfile!
40
+ story = pivotal.find_story(story_id)
41
+ if story.nil?
42
+ stories = pivotal.pending_stories(:include_started => options[:all])
43
+ out.print_stories "pending stories", stories, options
44
+ out.next_command "start a story using:", "$ aw start [STORY_ID]"
45
+ else
46
+ pivotal.start_story(story, :estimate => options[:estimate])
47
+ out.print_story story
48
+ git.create_story_branch(story)
49
+ out.next_command "after commiting your changes, submit a pull request using:", "$ aw submit"
50
+ end
53
51
  end
54
- end
55
52
 
56
- desc "submit", "Submits the current story creating a new pull request"
57
- def submit
58
- check_awfile!
59
- story_id = git.current_story_id
60
- say "loading story info"
61
- story = pivotal.find_story(story_id)
62
- if story
63
- say "preparing local branch"
64
- git.rebase_and_push
65
- say "submiting the new pull request"
66
- pr = github.create_pull_request(git.repository, git.current_branch, story)
67
- say "finishing the story"
68
- pivotal.finish_story(story, :note => pr._links.html.href)
69
- say "new pull request: #{pr._links.html.href}", :yellow
70
- say "after pull request approval, remove the feature branch using:", :green
71
- say_command "$ aw finish"
72
- else
73
- raise AssistedWorkflow::Error, "story not found, make sure a feature branch in active"
53
+ desc "submit", "Submits the current story creating a new pull request"
54
+ def submit
55
+ check_awfile!
56
+ story_id = git.current_story_id
57
+ story = pivotal.find_story(story_id)
58
+ if story
59
+ git.rebase_and_push
60
+ pr_url = github.create_pull_request(
61
+ git.repository, git.current_branch, story
62
+ )
63
+ pivotal.finish_story(story, :note => pr_url)
64
+ out.next_command "after pull request approval, remove the feature branch using:", "$ aw finish"
65
+ else
66
+ raise AssistedWorkflow::Error, "story not found, make sure a feature branch in active"
67
+ end
74
68
  end
75
- end
76
69
 
77
- desc "finish", "Check if the changes are merged into master, removing the current feature branch"
78
- def finish
79
- check_awfile!
80
- story_id = git.current_story_id
81
- if story_id.to_i > 0
82
- if git.is_merged?
83
- say "removing local and remote feature branches"
70
+ desc "finish", "Check if the changes are merged into master, removing the current feature branch"
71
+ def finish
72
+ check_awfile!
73
+ story_id = git.current_story_id
74
+ if story_id.to_i > 0
75
+ git.check_merged!
84
76
  git.remove_branch
85
- say "well done! check your next stories using:", :green
86
- say_command "$ aw start"
77
+ out.next_command "well done! check your next stories using:", "$ aw start"
87
78
  else
88
- say "this branch is not merged into master yet", :yellow
79
+ raise AssistedWorkflow::Error, "story not found, make sure a feature branch in active"
89
80
  end
90
- else
91
- raise AssistedWorkflow::Error, "story not found, make sure a feature branch in active"
92
81
  end
93
- end
94
82
 
95
- desc "version", "Display assisted_workflow gem version"
96
- def version
97
- say AssistedWorkflow::VERSION
98
- end
83
+ desc "version", "Display assisted_workflow gem version"
84
+ def version
85
+ say AssistedWorkflow::VERSION
86
+ end
99
87
 
100
- desc "config group.key=value", "Set configuration keys in local config file"
101
- method_option :global, :type => :boolean, :aliases => "-g", :desc => "Set configuration key in global configuration file (for all projects)"
102
- def config(*args)
103
- if args.empty?
104
- print_table configuration.to_hash
105
- else
106
- config_file.parse(args).save!
88
+ desc "config group.key=value", "Set configuration keys in local config file"
89
+ method_option :global, :type => :boolean, :aliases => "-g", :desc => "Set configuration key in global configuration file (for all projects)"
90
+ def config(*args)
91
+ if args.empty?
92
+ print_table configuration.to_hash
93
+ else
94
+ config_file.parse(args).save!
95
+ end
107
96
  end
108
- end
109
97
 
110
- desc "thanks", "Aw, Thanks!", :hide => true
111
- def thanks
112
- say "you're welcome!", :on_magenta
113
- end
98
+ desc "thanks", "Aw, Thanks!", :hide => true
99
+ def thanks
100
+ out.say "you're welcome!", :on_magenta
101
+ end
114
102
 
115
103
 
116
- no_tasks do
117
- def pivotal
118
- @pivotal ||= AssistedWorkflow::Pivotal.new(configuration[:pivotal])
119
- end
104
+ no_tasks do
105
+ def out
106
+ @out ||= Output.new(self.shell)
107
+ end
108
+
109
+ def pivotal
110
+ @pivotal ||= Addons::Pivotal.new(out, configuration[:pivotal])
111
+ end
120
112
 
121
- def git
122
- @git ||= AssistedWorkflow::Git.new
123
- end
113
+ def git
114
+ @git ||= Addons::Git.new(out)
115
+ end
124
116
 
125
- def github
126
- @github ||= AssistedWorkflow::Github.new(configuration[:github])
127
- end
117
+ def github
118
+ @github ||= Addons::Github.new(out, configuration[:github])
119
+ end
128
120
 
129
- def config_file
130
- @config_file ||= AssistedWorkflow::ConfigFile.new(awfile)
131
- end
121
+ def config_file
122
+ @config_file ||= ConfigFile.new(awfile)
123
+ end
132
124
 
133
- # loads all configuration, merging global and local values
134
- def configuration
135
- @configuration ||= begin
136
- AssistedWorkflow::ConfigFile.new(GLOBAL_CONFIG).merge_file(LOCAL_CONFIG)
137
- rescue TypeError
138
- raise AssistedWorkflow::Error, "Error on loading .awconfig files. Please check the content format."
125
+ # loads all configuration, merging global and local values
126
+ def configuration
127
+ @configuration ||= begin
128
+ ConfigFile.new(GLOBAL_CONFIG).merge_file(LOCAL_CONFIG)
129
+ rescue TypeError
130
+ raise AssistedWorkflow::Error, "Error on loading .awconfig files. Please check the content format."
131
+ end
139
132
  end
140
133
  end
141
- end
142
134
 
143
- class << self
144
- def start(given_args=ARGV, config={})
145
- super
146
- rescue AssistedWorkflow::Error => e
147
- config[:shell].say e.message, :red
148
- exit(1)
135
+ class << self
136
+ def start(given_args=ARGV, config={})
137
+ super
138
+ rescue AssistedWorkflow::Error => e
139
+ config[:shell].say e.message, :red
140
+ exit(1)
141
+ end
149
142
  end
150
- end
151
143
 
152
- private ######################################################################
144
+ private ##################################################################
153
145
 
154
- def print_title(title)
155
- say "-" * title.length, :green
156
- say title.upcase, :green
157
- say "-" * title.length, :green
158
- end
159
-
160
- def print_stories(stories)
161
- rows = stories.map do |story|
162
- if options[:all]
163
- [story.id, story.current_state, story.name]
164
- else
165
- [story.id, story.estimate, story.name]
166
- end
146
+ def check_awfile!
147
+ raise AssistedWorkflow::Error, "#{awfile} does not exist.\nmake sure you run `$ aw setup` in your project folder." unless File.exist?(awfile)
167
148
  end
168
- print_table(rows)
169
- end
170
-
171
- def say_command(command)
172
- with_padding do
173
- say command
174
- end
175
- end
176
-
177
- def check_awfile!
178
- raise AssistedWorkflow::Error, "#{awfile} does not exist.\nmake sure you run `$ aw setup` in your project folder." unless File.exist?(awfile)
179
- end
180
149
 
181
- def awfile
182
- case
183
- when options[:awfile] then options[:awfile]
184
- when options[:global] then GLOBAL_CONFIG
185
- else LOCAL_CONFIG
150
+ def awfile
151
+ case
152
+ when options[:awfile] then options[:awfile]
153
+ when options[:global] then GLOBAL_CONFIG
154
+ else LOCAL_CONFIG
155
+ end
186
156
  end
187
- end
157
+ end
188
158
  end
@@ -8,7 +8,8 @@ module AssistedWorkflow
8
8
 
9
9
  DESCRIPTION_LIMIT = 30
10
10
 
11
- def initialize(options = {})
11
+ def initialize(output, options = {})
12
+ super
12
13
  @command_options = {:raise_error => true}.merge(options)
13
14
  end
14
15
 
@@ -16,6 +17,7 @@ module AssistedWorkflow
16
17
  # the branch name format is:
17
18
  # => story_onwer_username.story_id.story_name
18
19
  def create_story_branch(story)
20
+ log "creating the new branch"
19
21
  branch = branch_name(story)
20
22
  git "checkout -b #{branch}"
21
23
  # git "push --set-upstream origin #{branch}"
@@ -23,6 +25,7 @@ module AssistedWorkflow
23
25
 
24
26
  # run all the git steps required for a clean pull request
25
27
  def rebase_and_push
28
+ log "preparing local branch"
26
29
  check_everything_commited!
27
30
  branch = current_branch
28
31
  git "checkout master"
@@ -50,18 +53,21 @@ module AssistedWorkflow
50
53
  end
51
54
 
52
55
  # check if current branch is merged into master
53
- def is_merged?
56
+ def check_merged!
54
57
  check_everything_commited!
55
58
  branch = current_branch
56
59
  git "checkout master"
57
60
  git "pull --rebase"
58
61
  merged = git("branch --merged").include?(branch)
59
62
  git "checkout #{branch}"
60
- merged
63
+ unless merged
64
+ raise AssistedWorkflow::Error, "this branch is not merged into master"
65
+ end
61
66
  end
62
67
 
63
68
  # removes current branch and its remote version
64
69
  def remove_branch
70
+ log "removing local and remote feature branches"
65
71
  branch = current_branch
66
72
  git "push origin :#{branch}", :raise_error => false
67
73
  git "checkout master"
@@ -72,7 +78,7 @@ module AssistedWorkflow
72
78
 
73
79
  def git(command, options = {})
74
80
  options = @command_options.merge(options)
75
- puts "git #{command}" unless options[:silent] == true
81
+ # log("git #{command}", :step => true) unless options[:silent] == true
76
82
  result = system("git #{command}")
77
83
  if system_error? && options[:raise_error]
78
84
  msg = ["git command error", options[:error]].compact.join(": ")
@@ -0,0 +1,54 @@
1
+ module AssistedWorkflow
2
+
3
+ # a helper class to provide custom shell print methods
4
+ class Output < SimpleDelegator
5
+ def initialize(shell)
6
+ super
7
+ @shell = shell
8
+ end
9
+
10
+ # prints a wrapped gray line, showing as comments between log lines
11
+ def say_comment(comment)
12
+ @shell.padding = 4
13
+ say comment, [:black, :bold]
14
+ @shell.padding = 0
15
+ end
16
+
17
+ # prints a highlighted title section
18
+ def print_title(title)
19
+ say "-" * title.length, :green
20
+ say title.upcase, :green
21
+ say "-" * title.length, :green
22
+ end
23
+
24
+ # prints as table with stories data
25
+ def print_stories(title, stories, options = {})
26
+ print_title title
27
+ rows = stories.map do |story|
28
+ if options[:all]
29
+ [story.id, story.current_state, story.name]
30
+ else
31
+ [story.id, story.estimate, story.name]
32
+ end
33
+ end
34
+ print_table(rows)
35
+ end
36
+
37
+ def print_story(story)
38
+ say "-" * 40
39
+ print_wrapped story.name, :indent => 2
40
+ print_wrapped story.description, :indent => 2
41
+ say "-" * 40
42
+ end
43
+
44
+ def next_command(title, commands, &block)
45
+ say title, :green
46
+ _commands = Array(commands)
47
+ yield(_commands) if block_given?
48
+ _commands.each do |command|
49
+ print_wrapped command, :indent => 2
50
+ end
51
+ end
52
+
53
+ end
54
+ end
@@ -1,3 +1,3 @@
1
1
  module AssistedWorkflow
2
- VERSION = "0.1.4"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -1,9 +1,9 @@
1
1
  require 'spec_helper'
2
- require 'assisted_workflow/git'
2
+ require 'assisted_workflow/addons/git'
3
3
 
4
- describe AssistedWorkflow::Git do
4
+ describe AssistedWorkflow::Addons::Git do
5
5
  before do
6
- @git = AssistedWorkflow::Git.new(:silent => true)
6
+ @git = AssistedWorkflow::Addons::Git.new(nil, :silent => true)
7
7
  stub(@git).system_error?{ false }
8
8
  stub(@git).system("git rev-parse --abbrev-ref HEAD"){ "flavio.00001.new_feature"}
9
9
  end
@@ -16,7 +16,7 @@ describe AssistedWorkflow::Git do
16
16
  it "raises a git error when git command does not exit with success" do
17
17
  mock(@git).system_error?{ true }
18
18
  mock(@git).system("git checkout -b flavio.00001.new_feature")
19
- proc { @git.create_story_branch(story) }.must_raise AssistedWorkflow::GitError, "git command error"
19
+ proc { @git.create_story_branch(story) }.must_raise AssistedWorkflow::Addons::GitError, "git command error"
20
20
  end
21
21
 
22
22
 
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
- require 'assisted_workflow/github'
2
+ require 'assisted_workflow/addons/github'
3
3
 
4
- describe AssistedWorkflow::Github do
4
+ describe AssistedWorkflow::Addons::Github do
5
5
  before do
6
6
  @configuration = {
7
7
  "token" => "mygithubtoken",
@@ -11,7 +11,7 @@ describe AssistedWorkflow::Github do
11
11
  stub(@client).user_authenticated?{ true }
12
12
  stub(Octokit::Client).new{ @client }
13
13
 
14
- @github = AssistedWorkflow::Github.new(@configuration)
14
+ @github = AssistedWorkflow::Addons::Github.new(nil, @configuration)
15
15
  end
16
16
 
17
17
  it "initializes a valid github wrapper" do
@@ -20,15 +20,15 @@ describe AssistedWorkflow::Github do
20
20
 
21
21
  it "requires token" do
22
22
  proc {
23
- AssistedWorkflow::Github.new({})
23
+ AssistedWorkflow::Addons::Github.new(nil, {})
24
24
  }.must_raise AssistedWorkflow::Error, "github missing configuration:[token]"
25
25
  end
26
26
 
27
27
  it "creates a new valid pull request" do
28
- mock(@client).create_pull_request("flaviogranero/assisted_workflow", "master", "flavio.00001.new_feature", "[#00001] New Feature", "Feature description"){ true }
28
+ mock(@client).create_pull_request("flaviogranero/assisted_workflow", "master", "flavio.00001.new_feature", "[#00001] New Feature", "Feature description"){ pull_request }
29
29
  @github.create_pull_request(
30
30
  "flaviogranero/assisted_workflow", "flavio.00001.new_feature", story
31
- )
31
+ ).must_match /flaviogranero\/assisted_workflow\/pull\/1/
32
32
  end
33
33
 
34
34
  it "raises on creating an invalid pull request" do
@@ -45,4 +45,10 @@ describe AssistedWorkflow::Github do
45
45
  def story
46
46
  @story ||= PivotalTracker::Story.new(:id => "00001", :name => "New Feature", :description => "Feature description")
47
47
  end
48
+
49
+ def pull_request
50
+ agent = Sawyer::Agent.new("", {:links_parser => Sawyer::LinkParsers::Simple.new})
51
+ data = {_links: {html: {href: "https://github.com/flaviogranero/assisted_workflow/pull/1"}}}
52
+ Sawyer::Resource.new(agent, data)
53
+ end
48
54
  end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
- require 'assisted_workflow/pivotal'
2
+ require 'assisted_workflow/addons/pivotal'
3
3
 
4
- describe AssistedWorkflow::Pivotal do
4
+ describe AssistedWorkflow::Addons::Pivotal do
5
5
 
6
6
  before do
7
7
  @configuration = {
@@ -14,7 +14,7 @@ describe AssistedWorkflow::Pivotal do
14
14
  @project = PivotalTracker::Project.new(:id => "1")
15
15
  stub(PivotalTracker::Project).find(@configuration["project_id"]){ @project }
16
16
 
17
- @pivotal = AssistedWorkflow::Pivotal.new(@configuration)
17
+ @pivotal = AssistedWorkflow::Addons::Pivotal.new(nil, @configuration)
18
18
  end
19
19
 
20
20
  it "initializes a valid pivotal wrapper" do
@@ -23,7 +23,8 @@ describe AssistedWorkflow::Pivotal do
23
23
 
24
24
  it "requires fullname" do
25
25
  proc {
26
- AssistedWorkflow::Pivotal.new(
26
+ AssistedWorkflow::Addons::Pivotal.new(
27
+ nil,
27
28
  @configuration.reject{|k,v| k == "fullname"}
28
29
  )
29
30
  }.must_raise AssistedWorkflow::Error, "pivotal missing configuration:[fullname]"
@@ -31,7 +32,8 @@ describe AssistedWorkflow::Pivotal do
31
32
 
32
33
  it "requires token" do
33
34
  proc {
34
- AssistedWorkflow::Pivotal.new(
35
+ AssistedWorkflow::Addons::Pivotal.new(
36
+ nil,
35
37
  @configuration.reject{|k,v| k == "token"}
36
38
  )
37
39
  }.must_raise AssistedWorkflow::Error, "pivotal missing configuration:[token]"
@@ -39,7 +41,8 @@ describe AssistedWorkflow::Pivotal do
39
41
 
40
42
  it "requires project_id" do
41
43
  proc {
42
- AssistedWorkflow::Pivotal.new(
44
+ AssistedWorkflow::Addons::Pivotal.new(
45
+ nil,
43
46
  @configuration.reject{|k,v| k == "project_id"}
44
47
  )
45
48
  }.must_raise AssistedWorkflow::Error, "pivotal missing configuration:[project_id]"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: assisted_workflow
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-02-07 00:00:00.000000000 Z
12
+ date: 2014-02-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -144,20 +144,23 @@ files:
144
144
  - assisted_workflow.gemspec
145
145
  - bin/aw
146
146
  - lib/assisted_workflow.rb
147
+ - lib/assisted_workflow/addons/base.rb
148
+ - lib/assisted_workflow/addons/git.rb
149
+ - lib/assisted_workflow/addons/github.rb
150
+ - lib/assisted_workflow/addons/pivotal.rb
147
151
  - lib/assisted_workflow/cli.rb
148
152
  - lib/assisted_workflow/config_file.rb
149
153
  - lib/assisted_workflow/exceptions.rb
150
154
  - lib/assisted_workflow/git.rb
151
- - lib/assisted_workflow/github.rb
152
- - lib/assisted_workflow/pivotal.rb
155
+ - lib/assisted_workflow/output.rb
153
156
  - lib/assisted_workflow/templates/awconfig.global.tt
154
157
  - lib/assisted_workflow/templates/awconfig.local.tt
155
158
  - lib/assisted_workflow/templates/commit-msg.tt
156
159
  - lib/assisted_workflow/version.rb
160
+ - spec/assisted_workflow/addons/git_spec.rb
161
+ - spec/assisted_workflow/addons/github_spec.rb
162
+ - spec/assisted_workflow/addons/pivotal_spec.rb
157
163
  - spec/assisted_workflow/config_file_spec.rb
158
- - spec/assisted_workflow/git_spec.rb
159
- - spec/assisted_workflow/github_spec.rb
160
- - spec/assisted_workflow/pivotal_spec.rb
161
164
  - spec/spec_helper.rb
162
165
  homepage: https://github.com/flaviogranero/assisted_workflow
163
166
  licenses:
@@ -216,7 +219,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
216
219
  version: '0'
217
220
  segments:
218
221
  - 0
219
- hash: 2646088369177769038
222
+ hash: -50568132931744746
220
223
  required_rubygems_version: !ruby/object:Gem::Requirement
221
224
  none: false
222
225
  requirements:
@@ -225,7 +228,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
225
228
  version: '0'
226
229
  segments:
227
230
  - 0
228
- hash: 2646088369177769038
231
+ hash: -50568132931744746
229
232
  requirements: []
230
233
  rubyforge_project:
231
234
  rubygems_version: 1.8.24
@@ -234,8 +237,8 @@ specification_version: 3
234
237
  summary: AW is a CLI tool to automate software development workflows based on github
235
238
  pull requests
236
239
  test_files:
240
+ - spec/assisted_workflow/addons/git_spec.rb
241
+ - spec/assisted_workflow/addons/github_spec.rb
242
+ - spec/assisted_workflow/addons/pivotal_spec.rb
237
243
  - spec/assisted_workflow/config_file_spec.rb
238
- - spec/assisted_workflow/git_spec.rb
239
- - spec/assisted_workflow/github_spec.rb
240
- - spec/assisted_workflow/pivotal_spec.rb
241
244
  - spec/spec_helper.rb