circleci-cli 1.0.0 → 3.0.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/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # circleci-cli
2
-
2
+ [![All Contributors](https://img.shields.io/badge/all_contributors-3-orange.svg?style=flat-square)](#contributors-)
3
3
  [![Gem Version](https://badge.fury.io/rb/circleci-cli.svg)](https://badge.fury.io/rb/circleci-cli)
4
4
  [![Circle CI](https://circleci.com/gh/unhappychoice/circleci-cli.svg?style=shield)](https://circleci.com/gh/unhappychoice/circleci-cli)
5
5
  [![Code Climate](https://codeclimate.com/github/unhappychoice/circleci-cli/badges/gpa.svg)](https://codeclimate.com/github/unhappychoice/circleci-cli)
@@ -12,8 +12,6 @@ circleci-cli is a CLI tool for [Circle CI](https://circleci.com).
12
12
 
13
13
  ![sample.gif](https://github.com/unhappychoice/circler/raw/master/movie/rec.gif)
14
14
 
15
- Notice: This gem is renamed from `circler` to `circleci-cli` on 2019/09/22
16
-
17
15
  ## Installation
18
16
 
19
17
  ```sh
@@ -29,19 +27,59 @@ export CIRCLE_CI_TOKEN=your-circle-ci-token
29
27
  ## Usage
30
28
  ```
31
29
  Commands:
32
- circleci-cli browse # open circle ci website
33
- circleci-cli build # show build description
34
- circleci-cli builds # list builds
35
- circleci-cli help [COMMAND] # describe available commands or one specific command
36
- circleci-cli projects # list projects
37
- circleci-cli retry # retry a build
38
- circleci-cli version # show gem version
39
- circleci-cli watch # watch a build in real time
30
+ circleci-cli browse # Open CircleCI website
31
+ circleci-cli build # Show the build result
32
+ circleci-cli builds # List builds
33
+ circleci-cli cancel # Cancel a build
34
+ circleci-cli help [COMMAND] # Describe available commands or one specific command
35
+ circleci-cli projects # List projects
36
+ circleci-cli retry # Retry a build
37
+ circleci-cli version # Show gem version
38
+ circleci-cli watch # Watch builds in real time
40
39
 
41
40
  Options:
42
- -p user_name/project # specify repository
43
- -b branch # specify branch name
44
- -n build_number # specify build number
41
+ -p user_name/project # Specify repository
42
+ # Default to the Git remote of current directory
43
+
44
+ -b branch # Specify branch name
45
+ # Default to the current Git branch
46
+
47
+ -a, --all, --no-all # Ignore the branch option and stop being filtered by the branch
48
+ # Default to false
49
+
50
+ -n build_number # Specify build number.
51
+ -l last # Get or retry last failed build.
52
+ -v verbose # Show all the logs if applied to watch command.
53
+
54
+ --pretty=true/false, --no-pretty # Make outputs pretty or not
55
+ # Default to true
56
+ ```
57
+
58
+ ### Examples
59
+
60
+ #### Watch your project
61
+ ```
62
+ $ circleci-cli watch
63
+ ```
64
+
65
+ #### Watch your project and show all of the build log
66
+ ```
67
+ $ circleci-cli watch -v
68
+ ```
69
+
70
+ #### Show last failed build
71
+ ```
72
+ $ circleci-cli build --last
73
+ ```
74
+
75
+ #### Retry last failed build
76
+ ```
77
+ $ circleci-cli retry --last
78
+ ```
79
+
80
+ #### Open CircleCI webpage for current project
81
+ ```
82
+ $ circleci-cli browse
45
83
  ```
46
84
 
47
85
  ## Contributing
@@ -51,3 +89,25 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/unhapp
51
89
  ## License
52
90
 
53
91
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
92
+
93
+ ## Contributors ✨
94
+
95
+ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
96
+
97
+ <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
98
+ <!-- prettier-ignore-start -->
99
+ <!-- markdownlint-disable -->
100
+ <table>
101
+ <tr>
102
+ <td align="center"><a href="http://blog.unhappychoice.com"><img src="https://avatars3.githubusercontent.com/u/5608948?v=4" width="100px;" alt=""/><br /><sub><b>Yuji Ueki</b></sub></a><br /><a href="https://github.com/unhappychoice/circleci-cli/commits?author=unhappychoice" title="Code">💻</a></td>
103
+ <td align="center"><a href="https://mattbrictson.com/"><img src="https://avatars0.githubusercontent.com/u/189693?v=4" width="100px;" alt=""/><br /><sub><b>Matt Brictson</b></sub></a><br /><a href="https://github.com/unhappychoice/circleci-cli/commits?author=mattbrictson" title="Code">💻</a> <a href="https://github.com/unhappychoice/circleci-cli/commits?author=mattbrictson" title="Tests">⚠️</a></td>
104
+ <td align="center"><a href="http://fzf.me"><img src="https://avatars0.githubusercontent.com/u/1462357?v=4" width="100px;" alt=""/><br /><sub><b>Fletcher Fowler</b></sub></a><br /><a href="https://github.com/unhappychoice/circleci-cli/issues?q=author%3Afzf" title="Bug reports">🐛</a> <a href="#ideas-fzf" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/unhappychoice/circleci-cli/commits?author=fzf" title="Code">💻</a></td>
105
+ <td align="center"><a href="https://datadoghq.com"><img src="https://avatars3.githubusercontent.com/u/583503?v=4" width="100px;" alt=""/><br /><sub><b>Marco Costa</b></sub></a><br /><a href="#ideas-marcotc" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/unhappychoice/circleci-cli/commits?author=marcotc" title="Code">💻</a></td>
106
+ </tr>
107
+ </table>
108
+
109
+ <!-- markdownlint-enable -->
110
+ <!-- prettier-ignore-end -->
111
+ <!-- ALL-CONTRIBUTORS-LIST:END -->
112
+
113
+ This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
data/Rakefile CHANGED
@@ -2,7 +2,15 @@
2
2
 
3
3
  require 'bundler/gem_tasks'
4
4
  require 'rspec/core/rake_task'
5
+ require 'github_changelog_generator/task'
5
6
 
6
7
  RSpec::Core::RakeTask.new(:spec)
7
8
 
8
9
  task default: :spec
10
+
11
+ GitHubChangelogGenerator::RakeTask.new :changelog do |config|
12
+ config.user = 'unhappychoice'
13
+ config.project = 'circleci-cli'
14
+ config.since_tag = '0.1.0'
15
+ # config.future_release = '2.2.0'
16
+ end
@@ -6,20 +6,20 @@ require 'circleci/cli/version'
6
6
 
7
7
  def production_dependency(spec)
8
8
  spec.add_dependency 'circleci', '~> 2.0.2'
9
- spec.add_dependency 'colorize', '~> 0.8.1'
10
- spec.add_dependency 'faraday', '>= 0.14', '< 0.16'
9
+ spec.add_dependency 'faraday', '>= 0.14', '< 1.1'
11
10
  spec.add_dependency 'highline', '>= 1.7.8', '< 2.1.0'
12
- spec.add_dependency 'launchy', '~> 2.4.3'
11
+ spec.add_dependency 'launchy', '>= 2.4.3', '< 2.6.0'
13
12
  spec.add_dependency 'pusher-client', '~> 0.6.2'
14
- spec.add_dependency 'rugged', '>= 0.26', '< 0.29'
13
+ spec.add_dependency 'rugged', '>= 0.26', '< 1.1'
15
14
  spec.add_dependency 'terminal-notifier', '~> 2.0.0'
16
15
  spec.add_dependency 'terminal-table', '~> 1.8.0'
17
- spec.add_dependency 'thor', '~> 0.20.0'
16
+ spec.add_dependency 'thor', '>= 0.20', '< 1.1'
18
17
  end
19
18
 
20
19
  def development_dependency(spec)
21
20
  spec.add_development_dependency 'bundler'
22
21
  spec.add_development_dependency 'codecov'
22
+ spec.add_development_dependency 'github_changelog_generator'
23
23
  spec.add_development_dependency 'guard'
24
24
  spec.add_development_dependency 'guard-rspec'
25
25
  spec.add_development_dependency 'guard-rubocop'
@@ -38,6 +38,7 @@ end
38
38
  Gem::Specification.new do |spec|
39
39
  spec.name = 'circleci-cli'
40
40
  spec.version = CircleCI::CLI::VERSION
41
+ spec.required_ruby_version = '>= 2.5'
41
42
  spec.authors = ['unhappychoice']
42
43
  spec.email = ['unhappychoice@gmail.com']
43
44
 
@@ -5,7 +5,6 @@ require 'faraday'
5
5
  require 'launchy'
6
6
  require 'terminal-table'
7
7
  require 'highline/import'
8
- require 'colorize'
9
8
  require 'rugged'
10
9
  require 'circleci'
11
10
  require 'terminal-notifier'
@@ -18,57 +17,149 @@ require 'circleci/cli/networking'
18
17
 
19
18
  module CircleCI
20
19
  module CLI
21
- class Runner < Thor
22
- desc 'projects', 'list projects'
23
- method_option :format, aliases: 'f', type: :string, banner: 'pretty/simple'
20
+ class Runner < Thor # rubocop:disable Metrics/ClassLength
21
+ package_name 'circleci-cli'
22
+
23
+ class << self
24
+ def project
25
+ repository = Rugged::Repository.new('.')
26
+ origin = repository.remotes.find { |r| r.name == 'origin' }
27
+ regexp = %r{(?:git@|https://)github.com(?::|/)([\w_-]+/[.\w_-]+?)(?:\.git)*$}
28
+ return Regexp.last_match(1) if origin.url =~ regexp
29
+
30
+ nil
31
+ end
32
+
33
+ def branch_name
34
+ repository = Rugged::Repository.new('.')
35
+ head = repository.head
36
+
37
+ return nil unless head.branch?
38
+
39
+ head.name.sub(%r{\Arefs/heads/}, '')
40
+ end
41
+ end
42
+
43
+ desc 'projects', 'List projects'
44
+ method_option :pretty, type: :boolean, default: true, desc: 'Make output pretty'
24
45
  def projects
25
46
  Command::ProjectsCommand.run(options)
26
47
  end
27
48
 
28
- desc 'builds', 'list builds'
29
- method_option :project, aliases: 'p', type: :string, banner: 'user/project'
30
- method_option :branch, aliases: 'b', type: :string, banner: 'some-branch'
31
- method_option :format, aliases: 'f', type: :string, banner: 'pretty/simple'
49
+ desc 'builds', 'List builds'
50
+ method_option :project,
51
+ aliases: 'p',
52
+ type: :string,
53
+ banner: 'user/project',
54
+ default: project,
55
+ desc: 'A project you want to get.'
56
+ method_option :branch,
57
+ aliases: 'b',
58
+ type: :string,
59
+ banner: 'some-branch',
60
+ default: branch_name,
61
+ desc: 'A branch name you want to filter with.'
62
+ method_option :all,
63
+ aliases: 'a',
64
+ type: :boolean,
65
+ default: false,
66
+ desc: 'Target all the branches. This option overwrites branch option.'
67
+ method_option :pretty, type: :boolean, banner: 'true/false', default: true, desc: 'Make output pretty.'
32
68
  def builds
33
69
  Command::BuildsCommand.run(options)
34
70
  end
35
71
 
36
- desc 'build', 'show build description'
37
- method_option :project, aliases: 'p', type: :string, banner: 'user/project'
38
- method_option :build, aliases: 'n', type: :numeric, banner: 'build-number'
72
+ desc 'build', 'Show the build result'
73
+ method_option :project,
74
+ aliases: 'p',
75
+ type: :string,
76
+ banner: 'user/project',
77
+ default: project,
78
+ desc: 'A project you want to get.'
79
+ method_option :build, aliases: 'n', type: :numeric, banner: 'build-number', desc: 'Build number you want to get.'
80
+ method_option :last, aliases: 'l', type: :boolean, default: false, desc: 'Get last failed build.'
81
+ method_option :pretty, type: :boolean, banner: 'true/false', default: true, desc: 'Make output pretty.'
39
82
  def build
40
83
  Command::BuildCommand.run(options)
41
84
  end
42
85
 
43
- desc 'browse', 'open circle ci website'
44
- method_option :project, aliases: 'p', type: :string, banner: 'user/project'
45
- method_option :build, aliases: 'n', type: :numeric, banner: 'build-number'
86
+ desc 'browse', 'Open CircleCI website'
87
+ method_option :project,
88
+ aliases: 'p',
89
+ type: :string,
90
+ banner: 'user/project',
91
+ default: project,
92
+ desc: 'A project you want to get.'
93
+ method_option :build,
94
+ aliases: 'n',
95
+ type: :numeric,
96
+ banner: 'build-number',
97
+ desc: 'Build number you want to browse.'
46
98
  def browse
47
99
  Command::BrowseCommand.run(options)
48
100
  end
49
101
 
50
- desc 'retry', 'retry a build'
51
- method_option :project, aliases: 'p', type: :string, banner: 'user/project'
52
- method_option :build, aliases: 'n', type: :numeric, banner: 'build-number'
102
+ desc 'retry', 'Retry a build'
103
+ method_option :project,
104
+ aliases: 'p',
105
+ type: :string,
106
+ banner: 'user/project',
107
+ default: project,
108
+ desc: 'A project you want to get.'
109
+ method_option :build,
110
+ aliases: 'n',
111
+ type: :numeric,
112
+ banner: 'build-number',
113
+ desc: 'Build number you want to retry.'
114
+ method_option :last, aliases: 'l', type: :boolean, desc: 'Retry last failed build.'
53
115
  def retry
54
116
  Command::RetryCommand.run(options)
55
117
  end
56
118
 
57
- desc 'cancel', 'cancel a build'
58
- method_option :project, aliases: 'p', type: :string, banner: 'user/project'
59
- method_option :build, aliases: 'n', type: :numeric, banner: 'build-number'
119
+ desc 'cancel', 'Cancel a build'
120
+ method_option :project,
121
+ aliases: 'p',
122
+ type: :string,
123
+ default: project,
124
+ desc: 'A project you want to get.'
125
+ method_option :build,
126
+ aliases: 'n',
127
+ type: :numeric,
128
+ banner: 'build-number',
129
+ desc: 'Build number you want to cancel.'
60
130
  def cancel
61
131
  Command::CancelCommand.run(options)
62
132
  end
63
133
 
64
- desc 'watch', 'watch a build in real time'
65
- method_option :project, aliases: 'p', type: :string, banner: 'user/project'
66
- method_option :build, aliases: 'n', type: :numeric, banner: 'build-number'
134
+ desc 'watch', 'Watch builds in real time'
135
+ method_option :project,
136
+ aliases: 'p',
137
+ type: :string,
138
+ banner: 'user/project',
139
+ default: project,
140
+ desc: 'A project you want to get.'
141
+ method_option :branch,
142
+ aliases: 'b',
143
+ type: :string,
144
+ banner: 'some-branch',
145
+ default: branch_name,
146
+ desc: 'A branch name you want to filter with.'
147
+ method_option :all,
148
+ aliases: 'a',
149
+ type: :boolean,
150
+ default: false,
151
+ desc: 'Target all the branches. This option overwrites branch option.'
152
+ method_option :user, aliases: 'u', type: :string, banner: 'user'
153
+ method_option :verbose,
154
+ aliases: 'v',
155
+ type: :boolean,
156
+ default: false,
157
+ desc: 'Show all the build logs including successful build steps.'
67
158
  def watch
68
159
  Command::WatchCommand.run(options)
69
160
  end
70
161
 
71
- desc 'version', 'show gem version'
162
+ desc 'version', 'Show gem version'
72
163
  def version
73
164
  say CircleCI::CLI::VERSION
74
165
  end
@@ -14,30 +14,23 @@ module CircleCI
14
14
  def project_name(options)
15
15
  if options.project
16
16
  options.project
17
- elsif reponame
18
- reponame
19
17
  else
20
18
  say Printer::ProjectPrinter.new(Response::Project.all).to_s
21
19
  ask('Input user-name/project-name :')
22
20
  end
23
21
  end
24
22
 
25
- def reponame
26
- repository = Rugged::Repository.new('.')
27
- origin = repository.remotes.find { |r| r.name == 'origin' }
28
- regexp = %r{git@github.com(?::|/)([\w_-]+/[\w_-]+)(?:\.git)*}
29
- return Regexp.last_match(1) if origin.url =~ regexp
30
-
31
- nil
23
+ def branch_name(options)
24
+ if options.all
25
+ nil
26
+ else
27
+ options.branch
28
+ end
32
29
  end
33
30
 
34
31
  def build_number(options)
35
32
  options.build || ask('Input build number')
36
33
  end
37
-
38
- def should_be_pretty(options)
39
- options['format'] != 'simple'
40
- end
41
34
  end
42
35
  end
43
36
  end
@@ -8,9 +8,25 @@ module CircleCI
8
8
  def run(options)
9
9
  setup_token
10
10
  username, reponame = project_name(options).split('/')
11
+ build =
12
+ if options.last
13
+ get_last_build(username, reponame)
14
+ else
15
+ get_build(username, reponame, options)
16
+ end
17
+ say Printer::StepPrinter.new(build.steps, pretty: options.pretty).to_s
18
+ end
19
+
20
+ private
21
+
22
+ def get_build(username, reponame, options)
11
23
  number = build_number(options)
12
- build = Response::Build.get(username, reponame, number)
13
- say Printer::StepPrinter.new(build.steps).to_s
24
+ Response::Build.get(username, reponame, number)
25
+ end
26
+
27
+ def get_last_build(username, reponame)
28
+ builds = Response::Build.failed(username, reponame)
29
+ Response::Build.get(username, reponame, builds.map(&:build_number).max)
14
30
  end
15
31
  end
16
32
  end
@@ -7,16 +7,16 @@ module CircleCI
7
7
  class << self
8
8
  def run(options)
9
9
  setup_token
10
- username, reponame = project_name(options).split('/')
10
+ project_name = project_name(options)
11
+ username, reponame = project_name.split('/')
12
+ branch = branch_name(options)
13
+ builds = if branch
14
+ Response::Build.branch(username, reponame, branch)
15
+ else
16
+ Response::Build.all(username, reponame)
17
+ end
11
18
 
12
- builds =
13
- if options.branch
14
- Response::Build.branch(username, reponame, options.branch)
15
- else
16
- Response::Build.all(username, reponame)
17
- end
18
-
19
- say Printer::BuildPrinter.new(builds, pretty: should_be_pretty(options)).to_s
19
+ say Printer::BuildPrinter.new(builds, project_name, pretty: options.pretty).to_s
20
20
  end
21
21
  end
22
22
  end
@@ -7,7 +7,7 @@ module CircleCI
7
7
  class << self
8
8
  def run(options)
9
9
  setup_token
10
- say Printer::ProjectPrinter.new(Response::Project.all, pretty: should_be_pretty(options)).to_s
10
+ say Printer::ProjectPrinter.new(Response::Project.all, pretty: options.pretty).to_s
11
11
  end
12
12
  end
13
13
  end
@@ -8,14 +8,30 @@ module CircleCI
8
8
  def run(options)
9
9
  setup_token
10
10
  username, reponame = project_name(options).split('/')
11
- number = build_number(options)
11
+ number = build_number_for(username, reponame, options)
12
+
12
13
  build = Response::Build.retry(username, reponame, number)
13
- if build.username
14
+
15
+ if build&.username
14
16
  say "build #{username}/#{reponame} #{build.build_number} is triggered"
15
17
  else
16
18
  say "failed to trigger #{username}/#{reponame} #{number}"
17
19
  end
18
20
  end
21
+
22
+ private
23
+
24
+ def build_number_for(username, reponame, options)
25
+ if options.last
26
+ get_last_build_number(username, reponame)
27
+ else
28
+ build_number(options)
29
+ end
30
+ end
31
+
32
+ def get_last_build_number(username, reponame)
33
+ Response::Build.failed(username, reponame).map(&:build_number).max
34
+ end
19
35
  end
20
36
  end
21
37
  end