sem 0.1.4 → 0.2.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.
- checksums.yaml +4 -4
- data/README.md +17 -0
- data/lib/sem/api/base.rb +7 -5
- data/lib/sem/api/env_vars.rb +12 -10
- data/lib/sem/api/files.rb +11 -9
- data/lib/sem/api/orgs.rb +27 -39
- data/lib/sem/api/projects.rb +27 -18
- data/lib/sem/api/shared_configs.rb +73 -45
- data/lib/sem/api/teams.rb +48 -33
- data/lib/sem/api/traits/associated_with_org.rb +6 -2
- data/lib/sem/api/traits/associated_with_project.rb +29 -0
- data/lib/sem/api/traits/associated_with_shared_config.rb +9 -7
- data/lib/sem/api/traits/associated_with_team.rb +12 -12
- data/lib/sem/api/traits.rb +1 -0
- data/lib/sem/api/users.rb +30 -12
- data/lib/sem/api.rb +0 -1
- data/lib/sem/cli/orgs.rb +11 -28
- data/lib/sem/cli/projects.rb +46 -3
- data/lib/sem/cli/shared_configs.rb +57 -30
- data/lib/sem/cli/teams.rb +101 -45
- data/lib/sem/cli.rb +21 -4
- data/lib/sem/configuration.rb +48 -0
- data/lib/sem/errors.rb +33 -0
- data/lib/sem/pagination.rb +29 -0
- data/lib/sem/srn.rb +42 -0
- data/lib/sem/version.rb +1 -1
- data/lib/sem/views/base.rb +8 -3
- data/lib/sem/views/orgs.rb +9 -0
- data/lib/sem/views/projects.rb +31 -14
- data/lib/sem/views/shared_configs.rb +11 -0
- data/lib/sem/views/teams.rb +68 -16
- data/lib/sem/views/users.rb +5 -7
- data/lib/sem.rb +35 -2
- data/sem.gemspec +4 -3
- metadata +28 -13
- data/lib/sem/api/users_with_permissions.rb +0 -57
- data/lib/sem/credentials.rb +0 -19
- data/lib/sem/views/users_with_permissions.rb +0 -13
data/lib/sem/api/users.rb
CHANGED
@@ -4,22 +4,40 @@ module Sem
|
|
4
4
|
extend Traits::AssociatedWithOrg
|
5
5
|
extend Traits::AssociatedWithTeam
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
class << self
|
8
|
+
def name_to_id(_, name)
|
9
|
+
name
|
10
|
+
end
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
+
def list
|
13
|
+
org_names = Orgs.list.map { |org| org[:username] }
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
-
end
|
15
|
+
org_names.pmap { |name| list_for_org(name) }.flatten
|
16
|
+
end
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
def info(*args)
|
19
|
+
if args.count == 2
|
20
|
+
org_name, user_name = args
|
21
|
+
users = list_for_org(org_name)
|
22
|
+
else
|
23
|
+
user_name = args.first
|
24
|
+
users = list
|
25
|
+
end
|
26
|
+
|
27
|
+
selected_user = users.find { |user| user[:id] == user_name }
|
28
|
+
|
29
|
+
raise Sem::Errors::ResourceNotFound.new("User", [user_name]) if selected_user.nil?
|
30
|
+
|
31
|
+
selected_user
|
32
|
+
end
|
33
|
+
|
34
|
+
def api
|
35
|
+
client.users
|
36
|
+
end
|
20
37
|
|
21
|
-
|
22
|
-
|
38
|
+
def to_hash(user, _ = nil)
|
39
|
+
{ :id => user.username }
|
40
|
+
end
|
23
41
|
end
|
24
42
|
end
|
25
43
|
end
|
data/lib/sem/api.rb
CHANGED
data/lib/sem/cli/orgs.rb
CHANGED
@@ -8,38 +8,21 @@ class Sem::CLI::Orgs < Dracula
|
|
8
8
|
end
|
9
9
|
|
10
10
|
desc "info", "shows detailed information about an organization"
|
11
|
-
def info(
|
12
|
-
|
11
|
+
def info(org)
|
12
|
+
org_name = Sem::SRN.parse_org(org).first
|
13
13
|
|
14
|
-
Sem::
|
14
|
+
org_instance = Sem::API::Orgs.info(org_name).to_h
|
15
|
+
|
16
|
+
Sem::Views::Orgs.info(org_instance)
|
15
17
|
end
|
16
18
|
|
17
19
|
desc "members", "list members of an organization"
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
:type => :boolean,
|
25
|
-
:desc => "list only admins in the organization"
|
26
|
-
option :owners,
|
27
|
-
:default => false,
|
28
|
-
:type => :boolean,
|
29
|
-
:desc => "list only owners in the organization"
|
30
|
-
def members(org_name)
|
31
|
-
raise "Not Implemented" if options[:with_2fa]
|
32
|
-
|
33
|
-
users =
|
34
|
-
if options[:owners]
|
35
|
-
Sem::API::UsersWithPermissions.list_owners_for_org(org_name)
|
36
|
-
elsif options[:admins]
|
37
|
-
Sem::API::UsersWithPermissions.list_admins_for_org(org_name)
|
38
|
-
else
|
39
|
-
Sem::API::UsersWithPermissions.list_for_org(org_name)
|
40
|
-
end
|
41
|
-
|
42
|
-
Sem::Views::UsersWithPermissions.list(users)
|
20
|
+
def members(org)
|
21
|
+
org_name = Sem::SRN.parse_org(org).first
|
22
|
+
|
23
|
+
users = Sem::API::Users.list_for_org(org_name)
|
24
|
+
|
25
|
+
Sem::Views::Users.list(users)
|
43
26
|
end
|
44
27
|
|
45
28
|
end
|
data/lib/sem/cli/projects.rb
CHANGED
@@ -8,10 +8,53 @@ class Sem::CLI::Projects < Dracula
|
|
8
8
|
end
|
9
9
|
|
10
10
|
desc "info", "shows detailed information about a project"
|
11
|
-
def info(
|
12
|
-
|
11
|
+
def info(project)
|
12
|
+
org_name, project_name = Sem::SRN.parse_project(project)
|
13
13
|
|
14
|
-
Sem::
|
14
|
+
project_instance = Sem::API::Projects.info(org_name, project_name).to_h
|
15
|
+
|
16
|
+
Sem::Views::Projects.info(project_instance)
|
17
|
+
end
|
18
|
+
|
19
|
+
class SharedConfigs < Dracula
|
20
|
+
desc "list", "list shared configurations on a project"
|
21
|
+
def list(project)
|
22
|
+
org_name, project_name = Sem::SRN.parse_project(project)
|
23
|
+
|
24
|
+
configs = Sem::API::SharedConfigs.list_for_project(org_name, project_name)
|
25
|
+
|
26
|
+
Sem::Views::SharedConfigs.list(configs)
|
27
|
+
end
|
28
|
+
|
29
|
+
desc "add", "attach a shared configuration to a project"
|
30
|
+
def add(project, shared_config)
|
31
|
+
project_org_name, project_name = Sem::SRN.parse_project(project)
|
32
|
+
shared_config_org_name, shared_config_name = Sem::SRN.parse_shared_config(shared_config)
|
33
|
+
|
34
|
+
if project_org_name != shared_config_org_name
|
35
|
+
abort Sem::Views::Projects.org_names_not_matching("project", "shared configuration", project, shared_config)
|
36
|
+
end
|
37
|
+
|
38
|
+
Sem::API::SharedConfigs.add_to_project(project_org_name, project_name, shared_config_name)
|
39
|
+
|
40
|
+
puts "Shared Configuration #{project_org_name}/#{shared_config_name} added to the project."
|
41
|
+
end
|
42
|
+
|
43
|
+
desc "remove", "removes a shared configuration from the project"
|
44
|
+
def remove(project, shared_config)
|
45
|
+
project_org_name, project_name = Sem::SRN.parse_project(project)
|
46
|
+
shared_config_org_name, shared_config_name = Sem::SRN.parse_shared_config(shared_config)
|
47
|
+
|
48
|
+
if project_org_name != shared_config_org_name
|
49
|
+
abort Sem::Views::Projects.org_names_not_matching("project", "shared configuration", project, shared_config)
|
50
|
+
end
|
51
|
+
|
52
|
+
Sem::API::SharedConfigs.remove_from_project(project_org_name, project_name, shared_config_name)
|
53
|
+
|
54
|
+
puts "Shared Configuration #{project_org_name}/#{shared_config_name} removed from the project."
|
55
|
+
end
|
15
56
|
end
|
16
57
|
|
58
|
+
register "shared-configs", "manage shared configurations", SharedConfigs
|
59
|
+
|
17
60
|
end
|
@@ -8,67 +8,89 @@ class Sem::CLI::SharedConfigs < Dracula
|
|
8
8
|
end
|
9
9
|
|
10
10
|
desc "info", "show information about a shared configuration"
|
11
|
-
def info(
|
12
|
-
|
11
|
+
def info(shared_config)
|
12
|
+
org_name, shared_config_name = Sem::SRN.parse_shared_config(shared_config)
|
13
13
|
|
14
|
-
Sem::
|
14
|
+
shared_config_instance = Sem::API::SharedConfigs.info(org_name, shared_config_name).to_h
|
15
|
+
|
16
|
+
Sem::Views::SharedConfigs.info(shared_config_instance)
|
15
17
|
end
|
16
18
|
|
17
19
|
desc "create", "create a new shared configuration"
|
18
|
-
def create(
|
19
|
-
org_name, shared_config_name =
|
20
|
+
def create(shared_config)
|
21
|
+
org_name, shared_config_name = Sem::SRN.parse_shared_config(shared_config)
|
20
22
|
|
21
|
-
|
23
|
+
shared_config_instance = Sem::API::SharedConfigs.create(org_name, :name => shared_config_name)
|
22
24
|
|
23
|
-
Sem::Views::SharedConfigs.info(
|
25
|
+
Sem::Views::SharedConfigs.info(shared_config_instance)
|
24
26
|
end
|
25
27
|
|
26
28
|
desc "rename", "rename a shared configuration"
|
27
|
-
def rename(
|
28
|
-
|
29
|
+
def rename(old_shared_config, new_shared_config)
|
30
|
+
old_org_name, old_shared_config_name = Sem::SRN.parse_shared_config(old_shared_config)
|
31
|
+
new_org_name, new_shared_config_name = Sem::SRN.parse_shared_config(new_shared_config)
|
32
|
+
|
33
|
+
if old_org_name != new_org_name
|
34
|
+
abort Sem::Views::SharedConfigs.org_names_not_matching("old shared configuration name",
|
35
|
+
"new shared configuration name",
|
36
|
+
old_shared_config,
|
37
|
+
new_shared_config)
|
38
|
+
end
|
29
39
|
|
30
|
-
|
40
|
+
shared_config_instance = Sem::API::SharedConfigs.update(old_org_name,
|
41
|
+
old_shared_config_name,
|
42
|
+
:name => new_shared_config_name)
|
31
43
|
|
32
|
-
Sem::Views::SharedConfigs.info(
|
44
|
+
Sem::Views::SharedConfigs.info(shared_config_instance)
|
33
45
|
end
|
34
46
|
|
35
47
|
desc "delete", "removes a shared configuration from your organization"
|
36
|
-
def delete(
|
37
|
-
Sem::
|
48
|
+
def delete(shared_config)
|
49
|
+
org_name, shared_config_name = Sem::SRN.parse_shared_config(shared_config)
|
50
|
+
|
51
|
+
Sem::API::SharedConfigs.delete(org_name, shared_config_name)
|
38
52
|
|
39
|
-
puts "Deleted shared configuration #{
|
53
|
+
puts "Deleted shared configuration #{org_name}/#{shared_config_name}"
|
40
54
|
end
|
41
55
|
|
42
56
|
class Files < Dracula
|
43
57
|
desc "list", "list files in the shared configuration"
|
44
|
-
def list(
|
45
|
-
|
58
|
+
def list(shared_config)
|
59
|
+
org_name, shared_config_name = Sem::SRN.parse_shared_config(shared_config)
|
60
|
+
|
61
|
+
files = Sem::API::SharedConfigs.list_files(org_name, shared_config_name)
|
46
62
|
|
47
63
|
Sem::Views::Files.list(files)
|
48
64
|
end
|
49
65
|
|
50
66
|
desc "add", "add a file to the shared configuration"
|
51
67
|
option :file, :aliases => "f", :desc => "File to upload", :required => true
|
52
|
-
def add(
|
68
|
+
def add(shared_config, file)
|
69
|
+
org_name, shared_config_name = Sem::SRN.parse_shared_config(shared_config)
|
70
|
+
|
53
71
|
content = File.read(options[:file])
|
54
72
|
|
55
|
-
Sem::API::Files.add_to_shared_config(
|
73
|
+
Sem::API::Files.add_to_shared_config(org_name, shared_config_name, :path => file, :content => content)
|
56
74
|
|
57
|
-
puts "Added #{
|
75
|
+
puts "Added #{file} to #{org_name}/#{shared_config_name}"
|
58
76
|
end
|
59
77
|
|
60
78
|
desc "remove", "remove a file from the shared configuration"
|
61
|
-
def remove(
|
62
|
-
Sem::
|
79
|
+
def remove(shared_config, file)
|
80
|
+
org_name, shared_config_name = Sem::SRN.parse_shared_config(shared_config)
|
63
81
|
|
64
|
-
|
82
|
+
Sem::API::Files.remove_from_shared_config(org_name, shared_config_name, file)
|
83
|
+
|
84
|
+
puts "Removed #{file} from #{org_name}/#{shared_config_name}"
|
65
85
|
end
|
66
86
|
end
|
67
87
|
|
68
88
|
class EnvVars < Dracula
|
69
89
|
desc "list", "list environment variables in the shared configuration"
|
70
|
-
def list(
|
71
|
-
|
90
|
+
def list(shared_config)
|
91
|
+
org_name, shared_config_name = Sem::SRN.parse_shared_config(shared_config)
|
92
|
+
|
93
|
+
env_vars = Sem::API::SharedConfigs.list_env_vars(org_name, shared_config_name)
|
72
94
|
|
73
95
|
Sem::Views::EnvVars.list(env_vars)
|
74
96
|
end
|
@@ -76,19 +98,24 @@ class Sem::CLI::SharedConfigs < Dracula
|
|
76
98
|
desc "add", "add an environment variable to the shared configuration"
|
77
99
|
option :name, :aliases => "-n", :desc => "Name of the variable", :required => true
|
78
100
|
option :content, :aliases => "-c", :desc => "Content of the variable", :required => true
|
79
|
-
def add(
|
80
|
-
Sem::
|
101
|
+
def add(shared_config)
|
102
|
+
org_name, shared_config_name = Sem::SRN.parse_shared_config(shared_config)
|
103
|
+
|
104
|
+
Sem::API::EnvVars.add_to_shared_config(org_name,
|
105
|
+
shared_config_name,
|
81
106
|
:name => options[:name],
|
82
107
|
:content => options[:content])
|
83
108
|
|
84
|
-
puts "Added #{options[:name]} to #{
|
109
|
+
puts "Added #{options[:name]} to #{org_name}/#{shared_config_name}"
|
85
110
|
end
|
86
111
|
|
87
112
|
desc "remove", "remove an environment variable from the shared configuration"
|
88
|
-
def remove(
|
89
|
-
Sem::
|
113
|
+
def remove(shared_config, env_var)
|
114
|
+
org_name, shared_config_name = Sem::SRN.parse_shared_config(shared_config)
|
115
|
+
|
116
|
+
Sem::API::EnvVars.remove_from_shared_config(org_name, shared_config_name, env_var)
|
90
117
|
|
91
|
-
puts "Removed #{
|
118
|
+
puts "Removed #{env_var} from #{org_name}/#{shared_config_name}"
|
92
119
|
end
|
93
120
|
end
|
94
121
|
|
data/lib/sem/cli/teams.rb
CHANGED
@@ -8,115 +8,171 @@ class Sem::CLI::Teams < Dracula
|
|
8
8
|
end
|
9
9
|
|
10
10
|
desc "info", "show information about a team"
|
11
|
-
def info(
|
12
|
-
|
11
|
+
def info(team)
|
12
|
+
org_name, team_name = Sem::SRN.parse_team(team)
|
13
13
|
|
14
|
-
Sem::
|
14
|
+
team_instance = Sem::API::Teams.info(org_name, team_name).to_h
|
15
|
+
|
16
|
+
Sem::Views::Teams.info(team_instance)
|
15
17
|
end
|
16
18
|
|
17
19
|
desc "create", "create a new team"
|
18
20
|
option :permission, :default => "read",
|
19
21
|
:aliases => "-p",
|
20
22
|
:desc => "Permission level of the team in the organization"
|
21
|
-
def create(
|
22
|
-
org_name, team_name =
|
23
|
+
def create(team)
|
24
|
+
org_name, team_name = Sem::SRN.parse_team(team)
|
23
25
|
|
24
|
-
|
25
|
-
|
26
|
-
|
26
|
+
team_instance = Sem::API::Teams.create(org_name,
|
27
|
+
:name => team_name,
|
28
|
+
:permission => options[:permission])
|
27
29
|
|
28
|
-
Sem::Views::Teams.info(
|
30
|
+
Sem::Views::Teams.info(team_instance)
|
29
31
|
end
|
30
32
|
|
31
33
|
desc "rename", "change the name of the team"
|
32
|
-
def rename(
|
33
|
-
|
34
|
+
def rename(old_team, new_team)
|
35
|
+
old_org_name, old_team_name = Sem::SRN.parse_team(old_team)
|
36
|
+
new_org_name, new_team_name = Sem::SRN.parse_team(new_team)
|
37
|
+
|
38
|
+
if old_org_name != new_org_name
|
39
|
+
abort Sem::Views::Teams.org_names_not_matching("old team name", "new team name", old_team, new_team)
|
40
|
+
end
|
34
41
|
|
35
|
-
|
42
|
+
team_instance = Sem::API::Teams.update(old_org_name, old_team_name, :name => new_team_name)
|
36
43
|
|
37
|
-
Sem::Views::Teams.info(
|
44
|
+
Sem::Views::Teams.info(team_instance)
|
38
45
|
end
|
39
46
|
|
40
47
|
desc "set-permission", "set the permission level of the team"
|
41
|
-
def set_permission(
|
42
|
-
|
48
|
+
def set_permission(team, permission)
|
49
|
+
unless ["read", "write", "admin"].include?(permission)
|
50
|
+
abort "Permission \"#{permission}\" doesn't exist.\n" \
|
51
|
+
"Choose one of the following: read, write, admin."
|
52
|
+
end
|
53
|
+
|
54
|
+
org_name, team_name = Sem::SRN.parse_team(team)
|
55
|
+
|
56
|
+
team_instance = Sem::API::Teams.update(org_name, team_name, :permission => permission)
|
43
57
|
|
44
|
-
Sem::Views::Teams.info(
|
58
|
+
Sem::Views::Teams.info(team_instance)
|
45
59
|
end
|
46
60
|
|
47
61
|
desc "delete", "removes a team from your organization"
|
48
|
-
def delete(
|
49
|
-
Sem::
|
62
|
+
def delete(team)
|
63
|
+
org_name, team_name = Sem::SRN.parse_team(team)
|
50
64
|
|
51
|
-
|
65
|
+
Sem::API::Teams.delete(org_name, team_name)
|
66
|
+
|
67
|
+
puts "Deleted team #{org_name}/#{team_name}"
|
52
68
|
end
|
53
69
|
|
54
70
|
class Members < Dracula
|
55
71
|
desc "list", "lists members of the team"
|
56
|
-
def list(
|
57
|
-
|
72
|
+
def list(team)
|
73
|
+
org_name, team_name = Sem::SRN.parse_team(team)
|
74
|
+
|
75
|
+
members = Sem::API::Users.list_for_team(org_name, team_name)
|
58
76
|
|
59
|
-
Sem::Views::
|
77
|
+
Sem::Views::Teams.list_members(team, members)
|
60
78
|
end
|
61
79
|
|
62
80
|
desc "add", "add a user to the team"
|
63
|
-
def add(
|
64
|
-
Sem::
|
81
|
+
def add(team, user)
|
82
|
+
org_name, team_name = Sem::SRN.parse_team(team)
|
83
|
+
user_name = Sem::SRN.parse_user(user).first
|
84
|
+
|
85
|
+
Sem::API::Users.add_to_team(org_name, team_name, user_name)
|
65
86
|
|
66
|
-
puts "User #{
|
87
|
+
puts "User #{user_name} added to the team."
|
67
88
|
end
|
68
89
|
|
69
90
|
desc "remove", "removes a user from the team"
|
70
|
-
def remove(
|
71
|
-
Sem::
|
91
|
+
def remove(team, user)
|
92
|
+
org_name, team_name = Sem::SRN.parse_team(team)
|
93
|
+
user_name = Sem::SRN.parse_user(user).first
|
72
94
|
|
73
|
-
|
95
|
+
Sem::API::Users.remove_from_team(org_name, team_name, user_name)
|
96
|
+
|
97
|
+
puts "User #{user_name} removed from the team."
|
74
98
|
end
|
75
99
|
end
|
76
100
|
|
77
101
|
class Projects < Dracula
|
78
102
|
desc "list", "lists projects in a team"
|
79
|
-
def list(
|
80
|
-
|
103
|
+
def list(team)
|
104
|
+
org_name, team_name = Sem::SRN.parse_team(team)
|
105
|
+
|
106
|
+
projects = Sem::API::Projects.list_for_team(org_name, team_name)
|
81
107
|
|
82
108
|
Sem::Views::Projects.list(projects)
|
83
109
|
end
|
84
110
|
|
85
111
|
desc "add", "add a project to a team"
|
86
|
-
def add(
|
87
|
-
Sem::
|
112
|
+
def add(team, project)
|
113
|
+
team_org_name, team_name = Sem::SRN.parse_team(team)
|
114
|
+
project_org_name, project_name = Sem::SRN.parse_project(project)
|
88
115
|
|
89
|
-
|
116
|
+
if team_org_name != project_org_name
|
117
|
+
abort Sem::Views::Teams.org_names_not_matching("team", "project", team, project)
|
118
|
+
end
|
119
|
+
|
120
|
+
Sem::API::Projects.add_to_team(team_org_name, team_name, project_name)
|
121
|
+
|
122
|
+
puts "Project #{team_org_name}/#{project_name} added to the team."
|
90
123
|
end
|
91
124
|
|
92
125
|
desc "remove", "removes a project from the team"
|
93
|
-
def remove(
|
94
|
-
Sem::
|
126
|
+
def remove(team, project)
|
127
|
+
team_org_name, team_name = Sem::SRN.parse_team(team)
|
128
|
+
project_org_name, project_name = Sem::SRN.parse_project(project)
|
129
|
+
|
130
|
+
if team_org_name != project_org_name
|
131
|
+
abort Sem::Views::Teams.org_names_not_matching("team", "project", team, project)
|
132
|
+
end
|
95
133
|
|
96
|
-
|
134
|
+
Sem::API::Projects.remove_from_team(team_org_name, team_name, project_name)
|
135
|
+
|
136
|
+
puts "Project #{team_org_name}/#{project_name} removed from the team."
|
97
137
|
end
|
98
138
|
end
|
99
139
|
|
100
140
|
class SharedConfigs < Dracula
|
101
141
|
desc "list", "list shared configurations in a team"
|
102
|
-
def list(
|
103
|
-
|
142
|
+
def list(team)
|
143
|
+
org_name, team_name = Sem::SRN.parse_team(team)
|
144
|
+
|
145
|
+
configs = Sem::API::SharedConfigs.list_for_team(org_name, team_name)
|
104
146
|
|
105
147
|
Sem::Views::SharedConfigs.list(configs)
|
106
148
|
end
|
107
149
|
|
108
150
|
desc "add", "add a shared configuration to a team"
|
109
|
-
def add(
|
110
|
-
Sem::
|
151
|
+
def add(team, shared_config)
|
152
|
+
team_org_name, team_name = Sem::SRN.parse_team(team)
|
153
|
+
shared_config_org_name, shared_config_name = Sem::SRN.parse_shared_config(shared_config)
|
111
154
|
|
112
|
-
|
155
|
+
if team_org_name != shared_config_org_name
|
156
|
+
abort Sem::Views::Teams.org_names_not_matching("team", "shared configuration", team, shared_config)
|
157
|
+
end
|
158
|
+
|
159
|
+
Sem::API::SharedConfigs.add_to_team(team_org_name, team_name, shared_config_name)
|
160
|
+
|
161
|
+
puts "Shared Configuration #{team_org_name}/#{shared_config_name} added to the team."
|
113
162
|
end
|
114
163
|
|
115
|
-
desc "remove", "removes a
|
116
|
-
def remove(
|
117
|
-
Sem::
|
164
|
+
desc "remove", "removes a shared Configuration from the team"
|
165
|
+
def remove(team, shared_config)
|
166
|
+
team_org_name, team_name = Sem::SRN.parse_team(team)
|
167
|
+
shared_config_org_name, shared_config_name = Sem::SRN.parse_shared_config(shared_config)
|
168
|
+
|
169
|
+
if team_org_name != shared_config_org_name
|
170
|
+
abort Sem::Views::Teams.org_names_not_matching("team", "shared configuration", team, shared_config)
|
171
|
+
end
|
172
|
+
|
173
|
+
Sem::API::SharedConfigs.remove_from_team(team_org_name, team_name, shared_config_name)
|
118
174
|
|
119
|
-
puts "Shared Configuration #{shared_config_name} removed from the team."
|
175
|
+
puts "Shared Configuration #{team_org_name}/#{shared_config_name} removed from the team."
|
120
176
|
end
|
121
177
|
end
|
122
178
|
|
data/lib/sem/cli.rb
CHANGED
@@ -7,11 +7,28 @@ module Sem
|
|
7
7
|
require_relative "cli/teams"
|
8
8
|
require_relative "cli/shared_configs"
|
9
9
|
|
10
|
-
desc "login", "
|
11
|
-
|
12
|
-
|
10
|
+
desc "login", "Log in to semaphore from the command line"
|
11
|
+
option :auth_token, :required => true
|
12
|
+
long_desc <<-DESC
|
13
|
+
You can find your auth_token on the bottom of the users settings page https://semaphoreci.com/users/edit.
|
14
|
+
DESC
|
15
|
+
def login
|
16
|
+
auth_token = options[:auth_token]
|
13
17
|
|
14
|
-
|
18
|
+
if Sem::Configuration.valid_auth_token?(auth_token)
|
19
|
+
Sem::Configuration.export_auth_token(auth_token)
|
20
|
+
|
21
|
+
puts "Your credentials have been saved to #{Sem::Configuration::CREDENTIALS_PATH}."
|
22
|
+
else
|
23
|
+
abort "[ERROR] Token is invalid!"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
desc "logout", "Log out from semaphore"
|
28
|
+
def logout
|
29
|
+
Sem::Configuration.delete_auth_token
|
30
|
+
|
31
|
+
puts "Loged out."
|
15
32
|
end
|
16
33
|
|
17
34
|
register "orgs", "manage organizations", Sem::CLI::Orgs
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Sem
|
2
|
+
class Configuration
|
3
|
+
CREDENTIALS_PATH = File.expand_path("~/.sem/credentials").freeze
|
4
|
+
API_URL_PATH = File.expand_path("~/.sem/api_url").freeze
|
5
|
+
|
6
|
+
DEFAULT_API_URL = "https://api.semaphoreci.com".freeze
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def valid_auth_token?(auth_token)
|
10
|
+
client = SemaphoreClient.new(
|
11
|
+
auth_token,
|
12
|
+
:api_url => api_url,
|
13
|
+
:verbose => (Sem.log_level == Sem::LOG_LEVEL_TRACE)
|
14
|
+
)
|
15
|
+
|
16
|
+
client.orgs.list!
|
17
|
+
|
18
|
+
true
|
19
|
+
rescue SemaphoreClient::Exceptions::RequestFailed
|
20
|
+
false
|
21
|
+
end
|
22
|
+
|
23
|
+
def export_auth_token(auth_token)
|
24
|
+
dirname = File.dirname(CREDENTIALS_PATH)
|
25
|
+
FileUtils.mkdir_p(dirname)
|
26
|
+
|
27
|
+
File.write(CREDENTIALS_PATH, auth_token)
|
28
|
+
File.chmod(0o0600, CREDENTIALS_PATH)
|
29
|
+
end
|
30
|
+
|
31
|
+
def delete_auth_token
|
32
|
+
FileUtils.rm_f(CREDENTIALS_PATH)
|
33
|
+
end
|
34
|
+
|
35
|
+
def auth_token
|
36
|
+
raise Sem::Errors::Auth::NoCredentials unless File.file?(CREDENTIALS_PATH)
|
37
|
+
|
38
|
+
File.read(CREDENTIALS_PATH).strip
|
39
|
+
end
|
40
|
+
|
41
|
+
def api_url
|
42
|
+
return DEFAULT_API_URL unless File.file?(API_URL_PATH)
|
43
|
+
|
44
|
+
File.read(API_URL_PATH).strip
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/sem/errors.rb
CHANGED
@@ -1,6 +1,39 @@
|
|
1
1
|
module Sem::Errors
|
2
2
|
Base = Class.new(StandardError)
|
3
3
|
|
4
|
+
InvalidSRN = Class.new(StandardError)
|
5
|
+
|
6
|
+
class ResourceException < Base
|
7
|
+
def initialize(resource, path)
|
8
|
+
@resource = resource
|
9
|
+
@path = path
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class ResourceNotFound < ResourceException
|
14
|
+
def message
|
15
|
+
"[ERROR] #{@resource} lookup failed\n\n#{@resource} #{@path.join("/")} not found."
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class ResourceNotCreated < ResourceException
|
20
|
+
def message
|
21
|
+
"[ERROR] #{@resource} creation failed\n\n#{@resource} #{@path.join("/")} not created."
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class ResourceNotUpdated < ResourceException
|
26
|
+
def message
|
27
|
+
"[ERROR] #{@resource} update failed\n\n#{@resource} #{@path.join("/")} not updated."
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class ResourceNotDeleted < ResourceException
|
32
|
+
def message
|
33
|
+
"[ERROR] #{@resource} deletion failed\n\n#{@resource} #{@path.join("/")} not deleted."
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
4
37
|
module Auth
|
5
38
|
NoCredentials = Class.new(Sem::Errors::Base)
|
6
39
|
InvalidCredentials = Class.new(Sem::Errors::Base)
|