ninny 0.1.9 → 0.1.14

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,12 +4,13 @@ module Ninny
4
4
  module Commands
5
5
  class CreateDatedBranch < Ninny::Command
6
6
  attr_reader :branch_type, :should_delete_old_branches
7
+
7
8
  def initialize(options)
8
9
  @branch_type = options[:branch_type] || Git::STAGING_PREFIX
9
10
  @should_delete_old_branches = options[:delete_old_branches]
10
11
  end
11
12
 
12
- def execute(input: $stdin, output: $stdout)
13
+ def execute(output: $stdout)
13
14
  create_branch
14
15
  delete_old_branches
15
16
  output.puts "#{branch_name} created"
@@ -22,7 +23,7 @@ module Ninny
22
23
 
23
24
  # Public: The date suffix to append to the branch name
24
25
  def date_suffix
25
- Date.today.strftime("%Y.%m.%d")
26
+ Date.today.strftime('%Y.%m.%d')
26
27
  end
27
28
 
28
29
  # Public: The name of the branch to create
@@ -35,12 +36,15 @@ module Ninny
35
36
  # Public: If necessary, and if user opts to, delete old branches of its type
36
37
  def delete_old_branches
37
38
  return unless extra_branches.any?
38
- should_delete = should_delete_old_branches || prompt.yes?("Do you want to delete the old #{branch_type} branch(es)? (#{extra_branches.join(", ")})")
39
39
 
40
- if should_delete
41
- extra_branches.each do |extra|
42
- Ninny.git.delete_branch(extra)
43
- end
40
+ should_delete = should_delete_old_branches || prompt.yes?(
41
+ "Do you want to delete the old #{branch_type} branch(es)? (#{extra_branches.join(', ')})"
42
+ )
43
+
44
+ return unless should_delete
45
+
46
+ extra_branches.each do |extra|
47
+ Ninny.git.delete_branch(extra)
44
48
  end
45
49
  end
46
50
 
@@ -49,11 +53,11 @@ module Ninny
49
53
  # Returns an Array of Strings of the branch names
50
54
  def extra_branches
51
55
  with_branch_type do
52
- Ninny.git.branches_for(branch_type).select{ |branch| branch.name != branch_name }
56
+ Ninny.git.branches_for(branch_type).reject { |branch| branch.name == branch_name }
53
57
  end
54
58
  end
55
59
 
56
- def with_branch_type(&block)
60
+ def with_branch_type
57
61
  case branch_type
58
62
  when Git::DEPLOYABLE_PREFIX, Git::STAGING_PREFIX, Git::QAREADY_PREFIX
59
63
  yield
@@ -6,12 +6,13 @@ module Ninny
6
6
  module Commands
7
7
  class OutputDatedBranch < Ninny::Command
8
8
  attr_reader :branch_type
9
+
9
10
  def initialize(options)
10
11
  @branch_type = options[:branch_type] || Git::STAGING_PREFIX
11
12
  @options = options
12
13
  end
13
14
 
14
- def execute(input: $stdin, output: $stdout)
15
+ def execute(output: $stdout)
15
16
  output.puts Ninny.git.latest_branch_for(branch_type)
16
17
  end
17
18
  end
@@ -14,11 +14,12 @@ module Ninny
14
14
  self.options = options
15
15
  end
16
16
 
17
- def execute(input: $stdin, output: $stdout)
18
- if (!pull_request_id)
17
+ def execute(*)
18
+ unless pull_request_id
19
19
  current = Ninny.repo.current_pull_request
20
20
  self.pull_request_id = current.number if current
21
21
  end
22
+
22
23
  self.pull_request_id ||= select_pull_request
23
24
 
24
25
  check_out_branch
@@ -26,13 +27,15 @@ module Ninny
26
27
  comment_about_merge
27
28
  end
28
29
 
29
- private def select_pull_request
30
+ def select_pull_request
30
31
  choices = Ninny.repo.open_pull_requests.map { |pr| { name: pr.title, value: pr.number } }
31
32
  prompt.select("Which #{Ninny.repo.pull_request_label}?", choices)
32
33
  end
34
+ private :select_pull_request
33
35
 
34
- # Public: Check out the branch
36
+ # Public: Check out the branch
35
37
  def check_out_branch
38
+ prompt.say "Checking out #{branch_to_merge_into}."
36
39
  Ninny.git.check_out(branch_to_merge_into, false)
37
40
  Ninny.git.track_current_branch
38
41
  rescue Ninny::Git::NoBranchOfType
@@ -42,6 +45,7 @@ module Ninny
42
45
 
43
46
  # Public: Merge the pull request's branch into the checked-out branch
44
47
  def merge_pull_request
48
+ prompt.say "Merging #{pull_request.branch} to #{branch_to_merge_into}."
45
49
  Ninny.git.merge(pull_request.branch)
46
50
  end
47
51
 
@@ -60,9 +64,11 @@ module Ninny
60
64
  # Public: Find the pull request
61
65
  #
62
66
  # Returns a Ninny::Repository::PullRequest
67
+ # rubocop:disable Lint/DuplicateMethods
63
68
  def pull_request
64
69
  @pull_request ||= Ninny.repo.pull_request(pull_request_id)
65
70
  end
71
+ # rubocop:enable Lint/DuplicateMethods
66
72
 
67
73
  # Public: Find the branch
68
74
  #
@@ -5,41 +5,69 @@ require_relative '../command'
5
5
  module Ninny
6
6
  module Commands
7
7
  class Setup < Ninny::Command
8
- attr_reader :config
8
+ attr_reader :config, :private_token
9
+
9
10
  def initialize(options)
10
11
  @options = options
12
+ @private_token = options[:token]
11
13
  @config = Ninny.user_config
12
14
  end
13
15
 
14
- def execute(input: $stdin, output: $stdout)
16
+ def execute(output: $stdout)
15
17
  try_reading_user_config
16
18
 
17
- prompt_for_gitlab_private_token
19
+ unless @private_token
20
+ @private_token = prompt_for_gitlab_private_token
18
21
 
19
- config.write(force: true)
20
- # Command logic goes here ...
21
- output.puts "User config #{@result}"
22
+ unless @private_token
23
+ output.puts "Please create a private token on GitLab and then rerun 'ninny setup'."
24
+ return
25
+ end
26
+ end
27
+
28
+ set_response = config_set_gitlab_private_token(@private_token)
29
+ write_gitlab_private_token(@private_token, set_response)
30
+ output.puts "User config #{@result}!"
22
31
  end
23
32
 
24
33
  def try_reading_user_config
25
- begin
26
- config.read
27
- @result = 'updated'
28
- rescue MissingUserConfig
29
- @result = 'created'
30
- end
34
+ config.read
35
+ @result = 'updated'
36
+ rescue MissingUserConfig
37
+ @result = 'created'
38
+ end
39
+
40
+ def config_set_gitlab_private_token(private_token)
41
+ # TODO: This only works with thor gem < 1. So, we need to make this work when TTY
42
+ # releases versions compatible with thor versions >= 1 as well.
43
+ config.set(:gitlab_private_token, value: private_token)
44
+ :success
45
+ rescue ArgumentError
46
+ puts ' Unable to set new token via TTY... continuing anyway...'
47
+ :failed
48
+ end
49
+
50
+ def write_gitlab_private_token(private_token, set_response)
51
+ raise StandardError unless set_response == :success
52
+
53
+ # TODO: This only works with thor gem < 1. So, we need to make this work when TTY
54
+ # releases versions compatible with thor versions >= 1 as well.
55
+ config.write(force: true)
56
+ rescue StandardError
57
+ puts ' Unable to write config file via TTY... continuing anyway...'
58
+ File.open("#{ENV['HOME']}/.ninny.yml", 'w') { |file| file.puts "gitlab_private_token: #{private_token}" }
31
59
  end
32
60
 
33
61
  def prompt_for_gitlab_private_token
34
62
  begin
35
63
  new_token_text = config.gitlab_private_token ? ' new' : ''
36
64
  rescue MissingUserConfig
37
- new_token_text = 'new'
38
- end
39
- if prompt.yes?("Do you have a#{new_token_text} gitlab private token?")
40
- private_token = prompt.ask("Enter private token", required: true)
41
- config.set(:gitlab_private_token, value: private_token)
65
+ new_token_text = ''
42
66
  end
67
+
68
+ return unless prompt.yes?("Do you have a#{new_token_text} GitLab private token?")
69
+
70
+ prompt.ask('Enter private token:', required: true)
43
71
  end
44
72
  end
45
73
  end
data/lib/ninny/git.rb CHANGED
@@ -1,16 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ninny
4
+ # rubocop:disable Metrics/ClassLength
4
5
  class Git
5
6
  extend Forwardable
6
- NO_BRANCH = "(no branch)"
7
- DEFAULT_DIRTY_MESSAGE = "Your Git index is not clean. Commit, stash, or otherwise clean up the index before continuing."
8
- DIRTY_CONFIRM_MESSAGE = "Your Git index is not clean. Do you want to continue?"
7
+ NO_BRANCH = '(no branch)'
8
+ DEFAULT_DIRTY_MESSAGE = 'Your Git index is not clean. Commit, stash, or otherwise clean' \
9
+ ' up the index before continuing.'
10
+ DIRTY_CONFIRM_MESSAGE = 'Your Git index is not clean. Do you want to continue?'
9
11
 
10
12
  # branch prefixes
11
- DEPLOYABLE_PREFIX = "deployable"
12
- STAGING_PREFIX = "staging"
13
- QAREADY_PREFIX = "qaready"
13
+ DEPLOYABLE_PREFIX = 'deployable'
14
+ STAGING_PREFIX = 'staging'
15
+ QAREADY_PREFIX = 'qaready'
14
16
 
15
17
  def_delegators :git, :branch
16
18
 
@@ -29,12 +31,9 @@ module Ninny
29
31
  end
30
32
 
31
33
  def current_branch_name
32
- name = git.current_branch
33
- if name == NO_BRANCH
34
- raise NotOnBranch, "Not currently checked out to a particular branch"
35
- else
36
- name
37
- end
34
+ raise NotOnBranch, 'Not currently checked out to a particular branch' if git.current_branch == NO_BRANCH
35
+
36
+ git.current_branch
38
37
  end
39
38
 
40
39
  def merge(branch_name)
@@ -42,6 +41,7 @@ module Ninny
42
41
  git.fetch
43
42
  command 'merge', ['--no-ff', "origin/#{branch_name}"]
44
43
  raise MergeFailed unless clean?
44
+
45
45
  push
46
46
  end
47
47
  end
@@ -64,24 +64,21 @@ module Ninny
64
64
  #
65
65
  # branch_name - The name of the branch to check out
66
66
  # do_after_pull - Should a pull be done after checkout?
67
- def check_out(branch, do_after_pull=true)
67
+ def check_out(branch, do_after_pull = true)
68
68
  git.fetch
69
- branch.checkout
69
+ git.checkout(branch)
70
70
  pull if do_after_pull
71
- unless current_branch.name == branch.name
72
- raise CheckoutFailed, "Failed to check out '#{branch}'"
73
- end
71
+ raise CheckoutFailed, "Failed to check out '#{branch}'" unless current_branch.name == branch.name
74
72
  end
75
73
 
76
74
  # Public: Track remote branch matching current branch
77
75
  #
78
76
  # do_after_pull - Should a pull be done after tracking?
79
- def track_current_branch(do_after_pull=true)
77
+ def track_current_branch(do_after_pull = true)
80
78
  command('branch', ['-u', "origin/#{current_branch_name}"])
81
79
  pull if do_after_pull
82
80
  end
83
81
 
84
-
85
82
  # Public: Create a new branch from the given source
86
83
  #
87
84
  # new_branch_name - The name of the branch to create
@@ -108,7 +105,7 @@ module Ninny
108
105
  # Returns an Array of Strings containing the branch names
109
106
  def remote_branches
110
107
  git.fetch
111
- git.branches.remote.map{ |branch| git.branch(branch.name) }.sort_by(&:name)
108
+ git.branches.remote.map { |branch| git.branch(branch.name) }.sort_by(&:name)
112
109
  end
113
110
 
114
111
  # Public: List of branches starting with the given string
@@ -131,7 +128,6 @@ module Ninny
131
128
  branches_for(prefix).last || raise(NoBranchOfType, "No #{prefix} branch")
132
129
  end
133
130
 
134
-
135
131
  # Public: Whether the Git index is clean (has no uncommited changes)
136
132
  #
137
133
  # Returns a Boolean
@@ -140,7 +136,7 @@ module Ninny
140
136
  end
141
137
 
142
138
  # Public: Perform the block if the Git index is clean
143
- def if_clean(message=DEFAULT_DIRTY_MESSAGE)
139
+ def if_clean(message = DEFAULT_DIRTY_MESSAGE)
144
140
  if clean? || prompt.yes?(DIRTY_CONFIRM_MESSAGE)
145
141
  yield
146
142
  else
@@ -151,9 +147,9 @@ module Ninny
151
147
 
152
148
  # Public: Display the message and show the git status
153
149
  def alert_dirty_index(message)
154
- prompt.say " "
150
+ prompt.say ' '
155
151
  prompt.say message
156
- prompt.say " "
152
+ prompt.say ' '
157
153
  prompt.say command('status')
158
154
  raise DirtyIndex
159
155
  end
@@ -163,11 +159,11 @@ module Ninny
163
159
  TTY::Prompt.new(options)
164
160
  end
165
161
 
166
-
167
162
  # Exceptions
168
163
  CheckoutFailed = Class.new(StandardError)
169
164
  NotOnBranch = Class.new(StandardError)
170
165
  NoBranchOfType = Class.new(StandardError)
171
166
  DirtyIndex = Class.new(StandardError)
172
167
  end
168
+ # rubocop:enable Metrics/ClassLength
173
169
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ninny
2
4
  class ProjectConfig
3
5
  attr_reader :config
@@ -31,14 +33,14 @@ module Ninny
31
33
  end
32
34
 
33
35
  def gitlab_endpoint
34
- config.fetch(:gitlab_endpoint, default: "https://gitlab.com/api/v4")
36
+ config.fetch(:gitlab_endpoint, default: 'https://gitlab.com/api/v4')
35
37
  end
36
38
 
37
39
  def repo
38
40
  return unless repo_type
39
41
 
40
42
  repo_class = { gitlab: Repository::Gitlab }[repo_type.to_sym]
41
- repo_class && repo_class.new
43
+ repo_class&.new
42
44
  end
43
45
 
44
46
  def self.config
@@ -1,18 +1,25 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ninny
2
4
  module Repository
3
5
  class Gitlab
4
- attr_reader :gitlab
5
- attr_reader :project_id
6
+ attr_reader :gitlab, :project_id
7
+
6
8
  def initialize
7
- @gitlab = ::Gitlab.client(endpoint: Ninny.project_config.gitlab_endpoint,
8
- private_token: Ninny.user_config.gitlab_private_token)
9
+ @gitlab = ::Gitlab.client(
10
+ endpoint: Ninny.project_config.gitlab_endpoint,
11
+ private_token: Ninny.user_config.gitlab_private_token
12
+ )
9
13
  @project_id = Ninny.project_config.gitlab_project_id
10
14
  end
11
15
 
12
16
  def current_pull_request
13
- to_pr(gitlab.merge_requests(project_id, { source_branch: Ninny.git.current_branch.name,
14
- target_branch: Ninny.project_config.deploy_branch })
15
- .last)
17
+ to_pr(
18
+ gitlab.merge_requests(
19
+ project_id,
20
+ { source_branch: Ninny.git.current_branch.name, target_branch: Ninny.project_config.deploy_branch }
21
+ ).last
22
+ )
16
23
  end
17
24
 
18
25
  def pull_request_label
@@ -20,7 +27,7 @@ module Ninny
20
27
  end
21
28
 
22
29
  def open_pull_requests
23
- gitlab.merge_requests(project_id, { state: 'opened' }).map{ |mr| to_pr(mr) }
30
+ gitlab.merge_requests(project_id, { state: 'opened' }).map { |mr| to_pr(mr) }
24
31
  end
25
32
 
26
33
  def pull_request(id)
@@ -31,13 +38,16 @@ module Ninny
31
38
  gitlab.create_merge_request_note(project_id, id, body)
32
39
  end
33
40
 
34
- private def to_pr(request)
35
- request && PullRequest.new(number: request.iid,
36
- title: request.title,
37
- branch: request.source_branch,
38
- description: request.description,
39
- comment_lambda: ->(body) { Ninny.repo.create_merge_request_note(request.iid, body) })
41
+ def to_pr(request)
42
+ request && PullRequest.new(
43
+ number: request.iid,
44
+ title: request.title,
45
+ branch: request.source_branch,
46
+ description: request.description,
47
+ comment_lambda: ->(body) { Ninny.repo.create_merge_request_note(request.iid, body) }
48
+ )
40
49
  end
50
+ private :to_pr
41
51
  end
42
52
  end
43
53
  end
@@ -1,8 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ninny
2
4
  module Repository
3
5
  class PullRequest
4
6
  attr_accessor :number, :title, :description, :branch, :comment_lambda
5
- def initialize(opts={})
7
+
8
+ def initialize(opts = {})
6
9
  self.number = opts[:number]
7
10
  self.title = opts[:title]
8
11
  self.description = opts[:description]
@@ -11,7 +14,7 @@ module Ninny
11
14
  end
12
15
 
13
16
  def write_comment(body)
14
- self.comment_lambda.call(body)
17
+ comment_lambda.call(body)
15
18
  end
16
19
  end
17
20
  end