sem 0.1.1
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.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.rspec +2 -0
- data/.rubocop.yml +103 -0
- data/Gemfile +6 -0
- data/README.md +27 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/sem +5 -0
- data/guides.md +168 -0
- data/ids.md +74 -0
- data/lib/sem.rb +53 -0
- data/lib/sem/api.rb +14 -0
- data/lib/sem/api/base.rb +17 -0
- data/lib/sem/api/env_vars.rb +20 -0
- data/lib/sem/api/files.rb +19 -0
- data/lib/sem/api/orgs.rb +54 -0
- data/lib/sem/api/projects.rb +33 -0
- data/lib/sem/api/shared_configs.rb +75 -0
- data/lib/sem/api/teams.rb +54 -0
- data/lib/sem/api/traits.rb +9 -0
- data/lib/sem/api/traits/associated_with_org.rb +13 -0
- data/lib/sem/api/traits/associated_with_shared_config.rb +29 -0
- data/lib/sem/api/traits/associated_with_team.rb +29 -0
- data/lib/sem/api/users.rb +26 -0
- data/lib/sem/api/users_with_permissions.rb +53 -0
- data/lib/sem/cli.rb +20 -0
- data/lib/sem/cli/orgs.rb +45 -0
- data/lib/sem/cli/projects.rb +17 -0
- data/lib/sem/cli/shared_configs.rb +97 -0
- data/lib/sem/cli/teams.rb +126 -0
- data/lib/sem/errors.rb +8 -0
- data/lib/sem/version.rb +3 -0
- data/lib/sem/views.rb +7 -0
- data/lib/sem/views/base.rb +7 -0
- data/lib/sem/views/env_vars.rb +13 -0
- data/lib/sem/views/files.rb +13 -0
- data/lib/sem/views/orgs.rb +22 -0
- data/lib/sem/views/projects.rb +22 -0
- data/lib/sem/views/shared_configs.rb +24 -0
- data/lib/sem/views/teams.rb +24 -0
- data/lib/sem/views/users.rb +13 -0
- data/lib/sem/views/users_with_permissions.rb +13 -0
- data/sem.gemspec +33 -0
- metadata +201 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8036852bc88fc42ae39872cd6db29f0e780928e7
|
4
|
+
data.tar.gz: 598ef13e790734d57ace6f06851ec270137eb9f0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b1c549f209533cdb62adf4c00bb4726819731f1f172ceb78b4c3c7fa5b4483f7bb42683aae4291c6094e167e7a7baf3501d4e75aca01b4e2678efd88fb139ddd
|
7
|
+
data.tar.gz: 3734c15ca55161ca222ff16270790a95920d0a82f9b0fffc51b0496a48f56d4188fab458c7cc85f030674cf3b5e1a4325a5d909b8cbab6c026d065d06dc78ce4
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
require: rubocop-rspec
|
2
|
+
|
3
|
+
AllCops:
|
4
|
+
DisplayCopNames: true
|
5
|
+
|
6
|
+
Exclude:
|
7
|
+
- "*.gemspec"
|
8
|
+
- "vendor/**/*"
|
9
|
+
|
10
|
+
Style/StringLiterals:
|
11
|
+
EnforcedStyle: double_quotes
|
12
|
+
|
13
|
+
Style/ClassAndModuleChildren:
|
14
|
+
Enabled: false
|
15
|
+
|
16
|
+
Style/StringLiteralsInInterpolation:
|
17
|
+
EnforcedStyle: double_quotes
|
18
|
+
|
19
|
+
Style/NumericLiterals:
|
20
|
+
Enabled: false
|
21
|
+
|
22
|
+
Style/Documentation:
|
23
|
+
Enabled: false
|
24
|
+
|
25
|
+
Style/HashSyntax:
|
26
|
+
EnforcedStyle: hash_rockets
|
27
|
+
|
28
|
+
Style/CollectionMethods:
|
29
|
+
StyleGuide: "https://github.com/bbatsov/ruby-style-guide#map-find-select-reduce-size"
|
30
|
+
Enabled: true
|
31
|
+
|
32
|
+
Metrics/LineLength:
|
33
|
+
Max: 120
|
34
|
+
|
35
|
+
Style/EmptyLinesAroundClassBody:
|
36
|
+
Enabled: false
|
37
|
+
|
38
|
+
Style/EmptyLinesAroundModuleBody:
|
39
|
+
Enabled: false
|
40
|
+
|
41
|
+
Style/MultilineMethodCallIndentation:
|
42
|
+
EnforcedStyle: indented
|
43
|
+
IndentationWidth: 2
|
44
|
+
|
45
|
+
Style/SpecialGlobalVars:
|
46
|
+
Enabled: false
|
47
|
+
|
48
|
+
Style/PercentLiteralDelimiters:
|
49
|
+
Enabled: false
|
50
|
+
|
51
|
+
RSpec/InstanceVariable:
|
52
|
+
Enabled: false
|
53
|
+
|
54
|
+
RSpec/MultipleExpectations:
|
55
|
+
Max: 5
|
56
|
+
|
57
|
+
Metrics/BlockLength:
|
58
|
+
Exclude:
|
59
|
+
- "Rakefile"
|
60
|
+
- "**/*.rake"
|
61
|
+
- "spec/**/*.rb"
|
62
|
+
|
63
|
+
Style/EmptyLinesAroundBlockBody:
|
64
|
+
Enabled: false
|
65
|
+
|
66
|
+
RSpec/BeforeAfterAll:
|
67
|
+
Enabled: false
|
68
|
+
|
69
|
+
RSpec/ExampleLength:
|
70
|
+
Enabled: false
|
71
|
+
|
72
|
+
RSpec/DescribedClass:
|
73
|
+
Enabled: false
|
74
|
+
|
75
|
+
Style/IndentArray:
|
76
|
+
EnforcedStyle: consistent
|
77
|
+
|
78
|
+
Style/MultilineMethodCallBraceLayout:
|
79
|
+
Enabled: false
|
80
|
+
|
81
|
+
RSpec/MessageSpies:
|
82
|
+
Enabled: false
|
83
|
+
|
84
|
+
Style/MultilineBlockLayout:
|
85
|
+
Enabled: false
|
86
|
+
|
87
|
+
RSpec/SubjectStub:
|
88
|
+
Enabled: false
|
89
|
+
|
90
|
+
RSpec/DescribeClass:
|
91
|
+
Enabled: false
|
92
|
+
|
93
|
+
RSpec/LeadingSubject:
|
94
|
+
Enabled: false
|
95
|
+
|
96
|
+
Style/WordArray:
|
97
|
+
Enabled: false
|
98
|
+
|
99
|
+
RSpec/NotToNot:
|
100
|
+
Enabled: false
|
101
|
+
|
102
|
+
Metrics/MethodLength:
|
103
|
+
Enabled: false
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# Semaphore CLI
|
2
|
+
|
3
|
+
[](https://semaphoreci.com/renderedtext/cli)
|
4
|
+
|
5
|
+

|
6
|
+
|
7
|
+
__Note: This tool is still in the early phase of development.__
|
8
|
+
|
9
|
+
The Semaphore CLI is used to manage Semaphore projects from the command line.
|
10
|
+
|
11
|
+
For more info about Semaphore see <https://www.semaphoreci.com>
|
12
|
+
|
13
|
+
## Issues
|
14
|
+
|
15
|
+
For problems directly related to the CLI, [add an issue on GitHub](https://github.com/renderedtext/cli/issues/new).
|
16
|
+
|
17
|
+
For other issues, [submit a support ticket](https://semaphoreci.com/support).
|
18
|
+
|
19
|
+
[Contributors](https://github.com/renderedtext/cli/contributors).
|
20
|
+
|
21
|
+
## Developing
|
22
|
+
|
23
|
+
Developing the CLI locally requires Ruby.
|
24
|
+
|
25
|
+
While developing please follow the [CLI development guide](guide.md).
|
26
|
+
|
27
|
+
To run the CLI locally, use the `bundle exec sem`.
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "sem"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/exe/sem
ADDED
data/guides.md
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
# Guides & Constraints
|
2
|
+
|
3
|
+
This document serves as a guide that highlights the important details while
|
4
|
+
developing the CLI. Please consult this guide before merging any Pull Request.
|
5
|
+
|
6
|
+
Content:
|
7
|
+
|
8
|
+
- [Development language](#development-language)
|
9
|
+
- [Simple setup](#simple-setup)
|
10
|
+
- [Authentication](#authentication)
|
11
|
+
- [Excellent help screens](#excellent-help-screens)
|
12
|
+
- [Command line Tab Completion](#command-line-tab-completion)
|
13
|
+
- [Errors and warnings](#errors-and-warnings)
|
14
|
+
- [Configuration](#configuration)
|
15
|
+
- [Format of the Output](#format-of-the-output)
|
16
|
+
|
17
|
+
## Development language
|
18
|
+
|
19
|
+
We decided to write the CLI in Ruby. Our assumption is
|
20
|
+
that most of our customers have Ruby preinstalled, or that they have the
|
21
|
+
knowledge to set it up. Ruby is language that offers excellent tools for
|
22
|
+
developing command line interfaces (e.g thor), and we have deep understanding of
|
23
|
+
the language and the ecosystem.
|
24
|
+
|
25
|
+
We want to support Ruby versions >= 2.0, and set up continuous integration for
|
26
|
+
every significant Ruby version (2.0, 2.1., 2.2, 2.3, 2.4).
|
27
|
+
|
28
|
+
The choice of the language dictates the preferable installation method of `gem
|
29
|
+
install semaphore-cli`.
|
30
|
+
|
31
|
+
## Simple setup
|
32
|
+
|
33
|
+
Developers like to set up and test tools fast. In this area, docker serves as
|
34
|
+
a good example as it can be installed with one command:
|
35
|
+
|
36
|
+
```
|
37
|
+
wget -qO- https://get.docker.com/ | sh
|
38
|
+
```
|
39
|
+
|
40
|
+
As our client will be written in Ruby, we will have to rely on the user to
|
41
|
+
install it before installing our CLI. However, this doesn't mean that we can't
|
42
|
+
make the installation step simple and intuitive.
|
43
|
+
|
44
|
+
Installation methods for SemaphoreCli:
|
45
|
+
|
46
|
+
- `gem install semaphore-cli`
|
47
|
+
- (optional) `wget -qO- https://cli.semaphoreci.com | sh`
|
48
|
+
- (optional) `sudo apt-get install semaphore-cli`
|
49
|
+
|
50
|
+
The shell script installation method should warn if Ruby is not installed, or if
|
51
|
+
the installed version is not supported. For clarity and proper versioning, we
|
52
|
+
should support installation of specific versions of the client. For example,
|
53
|
+
`wget -qO- https://cli.semaphoreci.com/v1.0.3 | sh` will install the `v1.0.3`
|
54
|
+
version on the user's system.
|
55
|
+
|
56
|
+
## Authentication
|
57
|
+
|
58
|
+
For start, we don’t want to store raw credentials, like a
|
59
|
+
username and password. Yes, the developer is responsible for their own machine’s
|
60
|
+
security, but there are better methods that ensure your CLI and user info will
|
61
|
+
stay secure.
|
62
|
+
|
63
|
+
Storing the access token in a resource file `~/.semaphoreci` is a better choice.
|
64
|
+
If the key falls into the wrong hands, it can be revoked without affecting the
|
65
|
+
user’s primary login.
|
66
|
+
|
67
|
+
HTTPS is a must.
|
68
|
+
|
69
|
+
Users would authenticate with the `semaphore login` command. This is an
|
70
|
+
interactive command that asks for the username, password and 2fa code and stores
|
71
|
+
the auth token in the `~/.semaphoreci` file.
|
72
|
+
|
73
|
+
Non-interactive usage of the `login` command will not be supported as it would
|
74
|
+
encourage unsafe practices for the CLI. In a non-interactive environments (e.g
|
75
|
+
CI builds) users should inject the `~/.semaphoreci` file in the environment.
|
76
|
+
|
77
|
+
## Excellent help screens
|
78
|
+
|
79
|
+
Getting started with a CLI is unlike using other software for the first time.
|
80
|
+
There is not always a welcome screen, no confirmation email with a link to
|
81
|
+
documentation. Only through the command itself can developers explore what’s
|
82
|
+
possible.
|
83
|
+
|
84
|
+
This experience begins with the help screen. Ideally, we should include multiple
|
85
|
+
ways to come across the help screen. For example, git provides `git --help` and
|
86
|
+
`git help` both of which shows the same screen. Even better, the help screen
|
87
|
+
should be accessible with short flags, such as `-h` or `-?`.
|
88
|
+
|
89
|
+
The CLI help screen is essentially a getting started documentation for the
|
90
|
+
command line. We should list out the possible commands in logical groups, with
|
91
|
+
each group in alphabetical order. Along with each command, give a quick and
|
92
|
+
thorough explanation. It’s a balancing act of saying enough without saying too
|
93
|
+
much.
|
94
|
+
|
95
|
+
As an addition to the main help screen, the users should be able to explore
|
96
|
+
further and get help for specific actions. For example, `semaphore help
|
97
|
+
team:create` should go in details about the `team:create` command, explaining
|
98
|
+
the required and optional parameters, the preconditions for successful
|
99
|
+
execution, and the expected results.
|
100
|
+
|
101
|
+
## Command line Tab Completion
|
102
|
+
|
103
|
+
Using the command line is all about controlling a computer at the speed of
|
104
|
+
thought. CLIs aren’t typically seen on the same level as other interfaces. Yet,
|
105
|
+
they share the commonality that a good interface helps users get things done.
|
106
|
+
|
107
|
+
Tab completion significantly improves the usability of a command line tool. Bash
|
108
|
+
and Zsh completion should be implemented and installed out of the box.
|
109
|
+
|
110
|
+
## Errors and warnings
|
111
|
+
|
112
|
+
A command line tool should not fail silently, neither should it fail with a `0`
|
113
|
+
exit status. We should provide meaningful exit statuses accompanied with
|
114
|
+
descriptive descriptions that provide context and possible corrections for the
|
115
|
+
failure.
|
116
|
+
|
117
|
+
Example of descriptive failure:
|
118
|
+
|
119
|
+
```
|
120
|
+
$ semaphore teams:list
|
121
|
+
[ERROR] Can't connect to the remote server semaphoreci.com.
|
122
|
+
|
123
|
+
$ echo $?
|
124
|
+
19
|
125
|
+
```
|
126
|
+
|
127
|
+
No Ruby error should be allowed to propagate to the user directly. In case of
|
128
|
+
unexpected failures, the command should describe that an unexpected error has
|
129
|
+
occurred, a link where the failure can be reported, and a tracelog of the
|
130
|
+
command with followed by the context in which it was invoked.
|
131
|
+
|
132
|
+
Example of descriptive unexpected failure:
|
133
|
+
|
134
|
+
```
|
135
|
+
$ semaphore teams:list
|
136
|
+
[ERROR] Unexpected error. Please report this issue to semaphoreci.com/support.
|
137
|
+
|
138
|
+
Context:
|
139
|
+
Called with: sempahore teams:list
|
140
|
+
Resource file `~/.semaphoreci` not-empty
|
141
|
+
Timestamp: 1500000312321
|
142
|
+
Version: v1.0.4
|
143
|
+
|
144
|
+
Trace:
|
145
|
+
ZeroDivisionError: divided by 0
|
146
|
+
from (irb):2:in `/'
|
147
|
+
from (irb):2
|
148
|
+
from /usr/local/rbenv/versions/2.3.4/bin/irb:11:in
|
149
|
+
`<main>'
|
150
|
+
|
151
|
+
$ echo $?
|
152
|
+
1
|
153
|
+
```
|
154
|
+
|
155
|
+
## Configuration
|
156
|
+
|
157
|
+
A command line tool should be configurable. Setting alternative domains for
|
158
|
+
staging, changing the default output format come to my mind.
|
159
|
+
|
160
|
+
## Format of the Output
|
161
|
+
|
162
|
+
Every command should have a `--json` and `--yaml` flag to indicate that we want
|
163
|
+
to display the response as JSON or Yaml.
|
164
|
+
|
165
|
+
The default output should be human readable, and should use colors to indicate
|
166
|
+
important fields and values.
|
167
|
+
|
168
|
+
If the command is piped into another command, no colors should be used.
|
data/ids.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# IDs in the CLI
|
2
|
+
|
3
|
+
Computers like to work with long IDs, but humans are much more comfortable with
|
4
|
+
hierarchical identifiers. A good example is git. While you could in theory do
|
5
|
+
everything with SHAs, the git interface allows you to work with labels such as
|
6
|
+
`master`, `HEAD`, `HEAD^2`, etc...
|
7
|
+
|
8
|
+
Semaphore exposes resources and uses UUIDs to uniquely identify resources. This
|
9
|
+
is very clean when it comes to the API interface, but it is a struggle to work
|
10
|
+
with from the CLI. For each step you must list the resources, find out their
|
11
|
+
ids, and then gather any useful information from them.
|
12
|
+
|
13
|
+
As an example, let's consider looking up the state of the last build on the
|
14
|
+
master branch for the test-boosters project. To achieve this, a user would need
|
15
|
+
to look up several IDS:
|
16
|
+
|
17
|
+
``` txt
|
18
|
+
$ sem orgs
|
19
|
+
|
20
|
+
931b14f7-0631-47a7-bb30-58b1c794e62c renderedtext
|
21
|
+
68ce72af-5725-4c04-af74-5f6ecc9f5e9a renderedtext-playground
|
22
|
+
|
23
|
+
|
24
|
+
$ sem projects --org-id 931b14f7-0631-47a7-bb30-58b1c794e62c
|
25
|
+
|
26
|
+
331b14f7-0631-47a7-bb30-58b1c794e62c test-boosters
|
27
|
+
68ce72af-5725-4c04-af74-5f6ecc9f5e9a semaphore-blog
|
28
|
+
|
29
|
+
|
30
|
+
$ sem branches --project-id 331b14f7-0631-47a7-bb30-58b1c794e62c
|
31
|
+
|
32
|
+
531b14f7-0631-47a7-bb30-58b1c794e62c master
|
33
|
+
98ce72af-5725-4c04-af74-5f6ecc9f5e9a rspec-test
|
34
|
+
78ce99af-5725-4c04-abas-5f6ecc9f5e9a development
|
35
|
+
|
36
|
+
|
37
|
+
$ sem builds --branch-id 531b14f7-0631-47a7-bb30-58b1c794e62c
|
38
|
+
|
39
|
+
531b14f7-0631-47a7-bb30-58b1c794e62c #9901
|
40
|
+
98ce72af-5725-4c04-af74-5f6ecc9f5e9a #9090
|
41
|
+
78ce99af-5725-4c04-abas-5f6ecc9f5e9a #9089
|
42
|
+
|
43
|
+
|
44
|
+
$ sem builds:info 531b14f7-0631-47a7-bb30-58b1c794e62c
|
45
|
+
|
46
|
+
531b14f7-0631-47a7-bb30-58b1c794e62c #9901 PASSED
|
47
|
+
```
|
48
|
+
|
49
|
+
This is clearly inefficient, and requires many hops from the user. The user
|
50
|
+
already knows the following information `renderedtext/test-boosters/master` but
|
51
|
+
he doesn't have a good way to tell this information to the semaphore CLI
|
52
|
+
efficiently.
|
53
|
+
|
54
|
+
A better interface would be:
|
55
|
+
|
56
|
+
```
|
57
|
+
$ sem builds renderedtext/test-boosters/master
|
58
|
+
|
59
|
+
531b14f7-0631-47a7-bb30-58b1c794e62c #9901 PASSED
|
60
|
+
98ce72af-5725-4c04-af74-5f6ecc9f5e9a #9090 FAILED
|
61
|
+
```
|
62
|
+
|
63
|
+
But for this, we need to have a good way to identify and transmit hierarchical
|
64
|
+
information to the CLI. The CLI itself can make multiple calls to the API to
|
65
|
+
collect this information.
|
66
|
+
|
67
|
+
This is not a finished proposal, only an intro for further thinking.
|
68
|
+
|
69
|
+
My current best ideas are to use `/` to pass the hierarchical information, but
|
70
|
+
this has its downsides.
|
71
|
+
|
72
|
+
Other ideas is to look into ARN(amazon resource names) and maybe collect some
|
73
|
+
good ideas. That way, we could formalize this format and introduce SRN(semaphore
|
74
|
+
resource names) or SRI(semaphore resource identifiers).
|