ninny 0.1.6 → 0.1.12

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.
@@ -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,14 +27,17 @@ 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
36
- Ninny.git.check_out(branch_to_merge_into)
38
+ prompt.say "Checking out #{branch_to_merge_into}."
39
+ Ninny.git.check_out(branch_to_merge_into, false)
40
+ Ninny.git.track_current_branch
37
41
  rescue Ninny::Git::NoBranchOfType
38
42
  prompt.say "No #{branch_type} branch available. Creating one now."
39
43
  CreateDatedBranch.new(branch: branch_type).execute
@@ -41,6 +45,7 @@ module Ninny
41
45
 
42
46
  # Public: Merge the pull request's branch into the checked-out branch
43
47
  def merge_pull_request
48
+ prompt.say "Merging #{pull_request.branch} to #{branch_to_merge_into}."
44
49
  Ninny.git.merge(pull_request.branch)
45
50
  end
46
51
 
@@ -59,9 +64,11 @@ module Ninny
59
64
  # Public: Find the pull request
60
65
  #
61
66
  # Returns a Ninny::Repository::PullRequest
67
+ # rubocop:disable Lint/DuplicateMethods
62
68
  def pull_request
63
69
  @pull_request ||= Ninny.repo.pull_request(pull_request_id)
64
70
  end
71
+ # rubocop:enable Lint/DuplicateMethods
65
72
 
66
73
  # Public: Find the branch
67
74
  #
@@ -6,40 +6,58 @@ module Ninny
6
6
  module Commands
7
7
  class Setup < Ninny::Command
8
8
  attr_reader :config
9
+
9
10
  def initialize(options)
10
11
  @options = options
11
12
  @config = Ninny.user_config
12
13
  end
13
14
 
14
- def execute(input: $stdin, output: $stdout)
15
+ def execute(output: $stdout)
15
16
  try_reading_user_config
16
17
 
17
- prompt_for_gitlab_private_token
18
+ private_token = prompt_for_gitlab_private_token
19
+
20
+ begin
21
+ # TODO: This only works with thor gem < 1. So, we need to make this work when TTY
22
+ # releases versions compatible with thor versions >= 1 as well.
23
+ config.write(force: true)
24
+ rescue StandardError
25
+ puts ' Unable to write config file via TTY... continuing anyway...'
26
+ File.open("#{ENV['HOME']}/.ninny.yml", 'w') do |file|
27
+ file.puts "gitlab_private_token: #{private_token}"
28
+ end
29
+ end
18
30
 
19
- config.write(force: true)
20
- # Command logic goes here ...
21
- output.puts "User config #{@result}"
31
+ output.puts "User config #{@result}!"
22
32
  end
23
33
 
24
34
  def try_reading_user_config
25
- begin
26
- config.read
27
- @result = 'updated'
28
- rescue MissingUserConfig
29
- @result = 'created'
30
- end
35
+ config.read
36
+ @result = 'updated'
37
+ rescue MissingUserConfig
38
+ @result = 'created'
31
39
  end
32
40
 
33
41
  def prompt_for_gitlab_private_token
34
42
  begin
35
43
  new_token_text = config.gitlab_private_token ? ' new' : ''
36
44
  rescue MissingUserConfig
37
- new_token_text = 'new'
45
+ new_token_text = ''
38
46
  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)
47
+
48
+ return unless prompt.yes?("Do you have a#{new_token_text} GitLab private token?")
49
+
50
+ private_token = prompt.ask('Enter private token:', required: true)
51
+
52
+ begin
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.
41
55
  config.set(:gitlab_private_token, value: private_token)
56
+ rescue ArgumentError
57
+ puts ' Unable to set new token via TTY... continuing anyway...'
42
58
  end
59
+
60
+ private_token
43
61
  end
44
62
  end
45
63
  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,13 +64,19 @@ 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
69
  branch.checkout
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
72
+ end
73
+
74
+ # Public: Track remote branch matching current branch
75
+ #
76
+ # do_after_pull - Should a pull be done after tracking?
77
+ def track_current_branch(do_after_pull = true)
78
+ command('branch', ['-u', "origin/#{current_branch_name}"])
79
+ pull if do_after_pull
74
80
  end
75
81
 
76
82
  # Public: Create a new branch from the given source
@@ -99,7 +105,7 @@ module Ninny
99
105
  # Returns an Array of Strings containing the branch names
100
106
  def remote_branches
101
107
  git.fetch
102
- 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)
103
109
  end
104
110
 
105
111
  # Public: List of branches starting with the given string
@@ -122,7 +128,6 @@ module Ninny
122
128
  branches_for(prefix).last || raise(NoBranchOfType, "No #{prefix} branch")
123
129
  end
124
130
 
125
-
126
131
  # Public: Whether the Git index is clean (has no uncommited changes)
127
132
  #
128
133
  # Returns a Boolean
@@ -131,7 +136,7 @@ module Ninny
131
136
  end
132
137
 
133
138
  # Public: Perform the block if the Git index is clean
134
- def if_clean(message=DEFAULT_DIRTY_MESSAGE)
139
+ def if_clean(message = DEFAULT_DIRTY_MESSAGE)
135
140
  if clean? || prompt.yes?(DIRTY_CONFIRM_MESSAGE)
136
141
  yield
137
142
  else
@@ -142,9 +147,9 @@ module Ninny
142
147
 
143
148
  # Public: Display the message and show the git status
144
149
  def alert_dirty_index(message)
145
- prompt.say " "
150
+ prompt.say ' '
146
151
  prompt.say message
147
- prompt.say " "
152
+ prompt.say ' '
148
153
  prompt.say command('status')
149
154
  raise DirtyIndex
150
155
  end
@@ -154,11 +159,11 @@ module Ninny
154
159
  TTY::Prompt.new(options)
155
160
  end
156
161
 
157
-
158
162
  # Exceptions
159
163
  CheckoutFailed = Class.new(StandardError)
160
164
  NotOnBranch = Class.new(StandardError)
161
165
  NoBranchOfType = Class.new(StandardError)
162
166
  DirtyIndex = Class.new(StandardError)
163
167
  end
168
+ # rubocop:enable Metrics/ClassLength
164
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Ninny
2
4
  class UserConfig
3
5
  attr_reader :config
@@ -25,11 +27,9 @@ module Ninny
25
27
  end
26
28
 
27
29
  def read
28
- begin
29
30
  config.read unless @read
30
- rescue TTY::Config::ReadError
31
- raise MissingUserConfig.new("User config not found, run `ninny setup`")
32
- end
31
+ rescue TTY::Config::ReadError
32
+ raise MissingUserConfig, 'User config not found, run `ninny setup`'
33
33
  end
34
34
 
35
35
  def with_read
data/lib/ninny/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ninny
4
- VERSION = "0.1.6"
4
+ VERSION = '0.1.12'
5
5
  end
data/ninny.gemspec CHANGED
@@ -1,72 +1,48 @@
1
1
  # frozen_string_literal: true
2
2
 
3
-
4
- lib = File.expand_path("../lib", __FILE__)
3
+ lib = File.expand_path('lib', __dir__)
5
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
- require "ninny/version"
5
+ require 'ninny/version'
7
6
 
8
7
  Gem::Specification.new do |spec|
9
- spec.name = "ninny"
10
- spec.license = "MIT"
8
+ spec.name = 'ninny'
9
+ spec.license = 'MIT'
11
10
  spec.version = Ninny::VERSION
12
- spec.authors = ["Carl Allen"]
13
- spec.email = ["carl.allen@dispatchwithus.com"]
14
-
15
- spec.summary = "ninny (n): an foolish person, see: git"
16
- spec.description = "Ninny is a command line workflow for git"
17
- # spec.homepage = "TODO: Put your gem's website or public repo URL here."
11
+ spec.authors = ['Dispatch Engineers']
12
+ spec.email = ['engineers@dispatchit.com']
18
13
 
19
- # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
20
- # to allow pushing to a single host or delete this section to allow pushing to any host.
21
- # if spec.respond_to?(:metadata)
22
- # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
23
-
24
- # spec.metadata["homepage_uri"] = spec.homepage
25
- # spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
26
- # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
27
- # else
28
- # raise "RubyGems 2.0 or newer is required to protect against " \
29
- # "public gem pushes."
30
- # end
14
+ spec.summary = 'ninny (n): an foolish person, see: git'
15
+ spec.description = 'Ninny is a command line workflow for git with GitLab'
16
+ spec.homepage = 'https://github.com/dispatchinc/ninny'
31
17
 
32
18
  # Specify which files should be added to the gem when it is released.
33
19
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
34
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
20
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
35
21
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
36
22
  end
37
- spec.bindir = "exe"
38
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
39
- spec.require_paths = ["lib"]
40
-
41
- spec.add_dependency "tty-box", "~> 0.3.0"
42
- spec.add_dependency "tty-color", "~> 0.4"
43
- spec.add_dependency "tty-command", "~> 0.8.0"
44
- spec.add_dependency "tty-config", "~> 0.3.0"
45
- spec.add_dependency "tty-prompt", "~> 0.18.0"
46
-
47
- # spec.add_dependency "tty-cursor", "~> 0.6"
48
- # spec.add_dependency "tty-editor", "~> 0.5.0"
49
- # spec.add_dependency "tty-file", "~> 0.7.0"
50
- # spec.add_dependency "tty-font", "~> 0.2.0"
51
- # spec.add_dependency "tty-markdown", "~> 0.5.0"
52
- # spec.add_dependency "tty-pager", "~> 0.12.0"
53
- # spec.add_dependency "tty-pie", "~> 0.1.0"
54
- # spec.add_dependency "tty-platform", "~> 0.2.0"
55
- # spec.add_dependency "tty-progressbar", "~> 0.16.0"
56
- # spec.add_dependency "tty-screen", "~> 0.6"
57
- # spec.add_dependency "tty-spinner", "~> 0.9.0"
58
- # spec.add_dependency "tty-table", "~> 0.10.0"
59
- # spec.add_dependency "tty-tree", "~> 0.2.0"
60
- # spec.add_dependency "tty-which", "~> 0.4"
61
-
62
- spec.add_dependency "pastel", "~> 0.7.2"
63
- spec.add_dependency "thor", "~> 0.20.0"
64
-
65
- spec.add_dependency "git", "~> 1.5.0"
66
- spec.add_dependency "gitlab", "~> 4.11"
67
23
 
68
- spec.add_development_dependency "bundler", "~> 1.17"
69
- spec.add_development_dependency "rake", "~> 10.0"
70
- spec.add_development_dependency "rspec", "~> 3.0"
71
- spec.add_development_dependency "byebug"
24
+ spec.bindir = 'exe'
25
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
+ spec.require_paths = ['lib']
27
+
28
+ spec.add_dependency 'git', '~> 1.5.0'
29
+ spec.add_dependency 'gitlab', '~> 4.11'
30
+ spec.add_dependency 'pastel', '~> 0.7.2'
31
+ spec.add_dependency 'thor', '< 2'
32
+ spec.add_dependency 'tty-box', '~> 0.3.0'
33
+ spec.add_dependency 'tty-color', '~> 0.4'
34
+ spec.add_dependency 'tty-command', '~> 0.8.0'
35
+ spec.add_dependency 'tty-config', '~> 0.3.0'
36
+ spec.add_dependency 'tty-prompt', '~> 0.18.0'
37
+
38
+ spec.add_development_dependency 'bundler', '~> 1.17'
39
+ spec.add_development_dependency 'byebug', '~> 11.1'
40
+ spec.add_development_dependency 'guard-rspec', '~> 4.3'
41
+ spec.add_development_dependency 'pronto', '~> 0.11'
42
+ spec.add_development_dependency 'pronto-rubocop', '~> 0.11'
43
+ spec.add_development_dependency 'rake', '~> 13.0'
44
+ spec.add_development_dependency 'rspec', '~> 3.0'
45
+ spec.add_development_dependency 'rubocop', '~> 1.11'
46
+ spec.add_development_dependency 'rubocop-rails', '~> 2.9'
47
+ spec.add_development_dependency 'rubocop-rspec', '~> 2.2'
72
48
  end