sem 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://semaphoreci.com/api/v1/renderedtext/cli/branches/master/badge.svg)](https://semaphoreci.com/renderedtext/cli)
|
4
|
+
|
5
|
+
![Semaphore logo](https://d1dkupr86d302v.cloudfront.net/assets/application_bootstrap/layout/semaphore-logo-a6d954e176b6975b511f314a0cc808dc94a8030210077e3a6e904fbe69dc5354.svg)
|
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).
|