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.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +103 -0
  5. data/Gemfile +6 -0
  6. data/README.md +27 -0
  7. data/Rakefile +10 -0
  8. data/bin/console +14 -0
  9. data/bin/setup +8 -0
  10. data/exe/sem +5 -0
  11. data/guides.md +168 -0
  12. data/ids.md +74 -0
  13. data/lib/sem.rb +53 -0
  14. data/lib/sem/api.rb +14 -0
  15. data/lib/sem/api/base.rb +17 -0
  16. data/lib/sem/api/env_vars.rb +20 -0
  17. data/lib/sem/api/files.rb +19 -0
  18. data/lib/sem/api/orgs.rb +54 -0
  19. data/lib/sem/api/projects.rb +33 -0
  20. data/lib/sem/api/shared_configs.rb +75 -0
  21. data/lib/sem/api/teams.rb +54 -0
  22. data/lib/sem/api/traits.rb +9 -0
  23. data/lib/sem/api/traits/associated_with_org.rb +13 -0
  24. data/lib/sem/api/traits/associated_with_shared_config.rb +29 -0
  25. data/lib/sem/api/traits/associated_with_team.rb +29 -0
  26. data/lib/sem/api/users.rb +26 -0
  27. data/lib/sem/api/users_with_permissions.rb +53 -0
  28. data/lib/sem/cli.rb +20 -0
  29. data/lib/sem/cli/orgs.rb +45 -0
  30. data/lib/sem/cli/projects.rb +17 -0
  31. data/lib/sem/cli/shared_configs.rb +97 -0
  32. data/lib/sem/cli/teams.rb +126 -0
  33. data/lib/sem/errors.rb +8 -0
  34. data/lib/sem/version.rb +3 -0
  35. data/lib/sem/views.rb +7 -0
  36. data/lib/sem/views/base.rb +7 -0
  37. data/lib/sem/views/env_vars.rb +13 -0
  38. data/lib/sem/views/files.rb +13 -0
  39. data/lib/sem/views/orgs.rb +22 -0
  40. data/lib/sem/views/projects.rb +22 -0
  41. data/lib/sem/views/shared_configs.rb +24 -0
  42. data/lib/sem/views/teams.rb +24 -0
  43. data/lib/sem/views/users.rb +13 -0
  44. data/lib/sem/views/users_with_permissions.rb +13 -0
  45. data/sem.gemspec +33 -0
  46. metadata +201 -0
data/lib/sem.rb ADDED
@@ -0,0 +1,53 @@
1
+ require "sem/version"
2
+ require "dracula"
3
+ require "semaphore_client"
4
+
5
+ module Sem
6
+ require "sem/errors"
7
+ require "sem/cli"
8
+ require "sem/api"
9
+ require "sem/views"
10
+
11
+ # Returns exit status as a number.
12
+ def self.start(args)
13
+ Sem::CLI.start(args)
14
+
15
+ 0
16
+ rescue Sem::Errors::Auth::NoCredentials
17
+ on_no_credentials
18
+
19
+ 1
20
+ rescue Sem::Errors::Auth::InvalidCredentials
21
+ on_invalid_credentials
22
+
23
+ 1
24
+ rescue StandardError => e
25
+ on_unhandled_error(e)
26
+
27
+ 1
28
+ end
29
+
30
+ private_class_method def self.on_no_credentials
31
+ puts "[ERROR] You are not logged in."
32
+ puts ""
33
+ puts "Log in with '#{Sem::CLI.program_name} login --auth-token <token>'"
34
+ end
35
+
36
+ private_class_method def self.on_invalid_credentials
37
+ puts "[ERROR] Your credentials are invalid."
38
+ puts ""
39
+ puts "Log in with '#{Sem::CLI.program_name} login --auth-token <token>'"
40
+ end
41
+
42
+ private_class_method def self.on_unhandled_error(exception)
43
+ puts "[PANIC] Unhandled error."
44
+ puts ""
45
+ puts "Well, this is emberassing. An unknown error was detected."
46
+ puts ""
47
+ puts "Backtrace: "
48
+ puts exception.backtrace
49
+ puts ""
50
+ puts "Please report this issue to https://semaphoreci.com/support."
51
+ end
52
+
53
+ end
data/lib/sem/api.rb ADDED
@@ -0,0 +1,14 @@
1
+ module Sem
2
+ module API
3
+ require_relative "api/traits"
4
+ require_relative "api/base"
5
+ require_relative "api/users_with_permissions"
6
+ require_relative "api/orgs"
7
+ require_relative "api/users"
8
+ require_relative "api/projects"
9
+ require_relative "api/env_vars"
10
+ require_relative "api/files"
11
+ require_relative "api/shared_configs"
12
+ require_relative "api/teams"
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ module Sem
2
+ module API
3
+ class Base
4
+ CREDENTIALS_PATH = "~/.sem/credentials".freeze
5
+
6
+ def self.client
7
+ @client ||= begin
8
+ path = File.expand_path(CREDENTIALS_PATH)
9
+
10
+ auth_token = File.read(path).delete("\n")
11
+
12
+ SemaphoreClient.new(auth_token)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ module Sem
2
+ module API
3
+ class EnvVars < Base
4
+ extend Traits::AssociatedWithSharedConfig
5
+
6
+ def self.api
7
+ client.env_vars
8
+ end
9
+
10
+ def self.to_hash(env_var)
11
+ {
12
+ :id => env_var.id,
13
+ :name => env_var.name,
14
+ :encrypted? => env_var.encrypted,
15
+ :content => env_var.content
16
+ }
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ module Sem
2
+ module API
3
+ class Files < Base
4
+ extend Traits::AssociatedWithSharedConfig
5
+
6
+ def self.api
7
+ client.config_files
8
+ end
9
+
10
+ def self.to_hash(files)
11
+ {
12
+ :id => files.id,
13
+ :name => files.path,
14
+ :encrypted? => files.encrypted
15
+ }
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,54 @@
1
+ module Sem
2
+ module API
3
+ class Orgs < Base
4
+ def self.list
5
+ orgs = api.list
6
+
7
+ orgs.map { |org| to_hash(org) }
8
+ end
9
+
10
+ def self.info(name)
11
+ org = api.get(name)
12
+
13
+ to_hash(org)
14
+ end
15
+
16
+ def self.list_teams(org_name)
17
+ Sem::API::Teams.list_for_org(org_name)
18
+ end
19
+
20
+ def self.list_users(org_name)
21
+ Sem::API::Users.list_for_org(org_name)
22
+ end
23
+
24
+ def self.list_admins(org_name)
25
+ admin_teams = list_teams(org_name).select { |team| team[:permission] == "admin" }
26
+
27
+ admins = admin_teams.map { |team| client.users.list_for_team(team[:id]) }.flatten
28
+
29
+ admins.map { |admin| Sem::API::Users.to_hash(admin) }
30
+ end
31
+
32
+ def self.list_owners(org_name)
33
+ owners_team = list_teams(org_name).find { |team| team[:name] == "Owners" }
34
+
35
+ owners = client.users.list_for_team(owners_team[:id])
36
+
37
+ owners.map { |owner| Sem::API::Users.to_hash(owner) }
38
+ end
39
+
40
+ def self.api
41
+ client.orgs
42
+ end
43
+
44
+ def self.to_hash(org)
45
+ {
46
+ :id => org.id,
47
+ :username => org.username,
48
+ :created_at => org.created_at,
49
+ :updated_at => org.updated_at
50
+ }
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,33 @@
1
+ module Sem
2
+ module API
3
+ class Projects < Base
4
+ extend Traits::AssociatedWithOrg
5
+ extend Traits::AssociatedWithTeam
6
+
7
+ def self.list
8
+ org_names = Orgs.list.map { |org| org[:username] }
9
+
10
+ org_names.map { |name| list_for_org(name) }.flatten
11
+ end
12
+
13
+ def self.info(path)
14
+ org_name, project_name = path.split("/")
15
+
16
+ list_for_org(org_name).find { |project| project[:name] == project_name }
17
+ end
18
+
19
+ def self.api
20
+ client.projects
21
+ end
22
+
23
+ def self.to_hash(project)
24
+ {
25
+ :id => project.id,
26
+ :name => project.name,
27
+ :created_at => project.created_at,
28
+ :updated_at => project.updated_at
29
+ }
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,75 @@
1
+ module Sem
2
+ module API
3
+ class SharedConfigs < Base
4
+ extend Traits::AssociatedWithTeam
5
+ extend Traits::AssociatedWithOrg
6
+
7
+ def self.list
8
+ org_names = Orgs.list.map { |org| org[:username] }
9
+
10
+ org_names.map { |name| list_for_org(name) }.flatten
11
+ end
12
+
13
+ def self.info(path)
14
+ org_name, config_name = path.split("/")
15
+
16
+ list_for_org(org_name).find { |config| config[:name] == config_name }
17
+ end
18
+
19
+ def self.create(org_name, args)
20
+ config = api.create_for_org(org_name, args)
21
+
22
+ to_hash(config)
23
+ end
24
+
25
+ def self.update(path, args)
26
+ shared_config = info(path)
27
+
28
+ shared_config = api.update(shared_config[:id], args)
29
+
30
+ to_hash(shared_config)
31
+ end
32
+
33
+ def self.delete(path)
34
+ id = info(path)[:id]
35
+
36
+ api.delete(id)
37
+ end
38
+
39
+ def self.list_env_vars(path)
40
+ Sem::API::EnvVars.list_for_shared_config(path)
41
+ end
42
+
43
+ def self.list_files(path)
44
+ Sem::API::Files.list_for_shared_config(path)
45
+ end
46
+
47
+ def self.api
48
+ client.shared_configs
49
+ end
50
+
51
+ def self.to_hash(config)
52
+ {
53
+ :id => config.id,
54
+ :name => config.name,
55
+ :config_files => config_files_count(config.id),
56
+ :env_vars => env_vars_count(config.id),
57
+ :created_at => config.created_at,
58
+ :updated_at => config.updated_at
59
+ }
60
+ end
61
+
62
+ class << self
63
+ private
64
+
65
+ def config_files_count(config_id)
66
+ client.config_files.list_for_shared_config(config_id).to_a.size
67
+ end
68
+
69
+ def env_vars_count(config_id)
70
+ client.env_vars.list_for_shared_config(config_id).to_a.size
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,54 @@
1
+ module Sem
2
+ module API
3
+ class Teams < Base
4
+ extend Traits::AssociatedWithOrg
5
+
6
+ def self.list
7
+ org_names = Sem::API::Orgs.list.map { |org| org[:username] }
8
+
9
+ org_names.map { |name| list_for_org(name) }.flatten
10
+ end
11
+
12
+ def self.info(path)
13
+ org_name, team_name = path.split("/")
14
+
15
+ list_for_org(org_name).find { |team| team[:name] == team_name }
16
+ end
17
+
18
+ def self.create(org_name, args)
19
+ team = api.create_for_org(org_name, args)
20
+
21
+ to_hash(team)
22
+ end
23
+
24
+ def self.update(path, args)
25
+ team = info(path)
26
+
27
+ team = api.update(team[:id], args)
28
+
29
+ to_hash(team)
30
+ end
31
+
32
+ def self.delete(path)
33
+ id = info(path)[:id]
34
+
35
+ api.delete(id)
36
+ end
37
+
38
+ def self.api
39
+ client.teams
40
+ end
41
+
42
+ def self.to_hash(team)
43
+ {
44
+ :id => team.id,
45
+ :name => team.name,
46
+ :permission => team.permission,
47
+ :members => client.users.list_for_team(team.id).count.to_s,
48
+ :created_at => team.created_at,
49
+ :updated_at => team.updated_at
50
+ }
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,9 @@
1
+ module Sem
2
+ module API
3
+ module Traits
4
+ require_relative "traits/associated_with_org"
5
+ require_relative "traits/associated_with_team"
6
+ require_relative "traits/associated_with_shared_config"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ module Sem
2
+ module API
3
+ module Traits
4
+ module AssociatedWithOrg
5
+ def list_for_org(org_name)
6
+ instances = api.list_for_org(org_name)
7
+
8
+ instances.map { |instance| to_hash(instance) }
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,29 @@
1
+ module Sem
2
+ module API
3
+ module Traits
4
+ module AssociatedWithSharedConfig
5
+ def list_for_shared_config(shared_config_path)
6
+ shared_config = SharedConfigs.info(shared_config_path)
7
+
8
+ instances = api.list_for_shared_config(shared_config[:id])
9
+
10
+ instances.map { |instance| to_hash(instance) }
11
+ end
12
+
13
+ def add_to_shared_config(shared_config_path, params)
14
+ shared_config = SharedConfigs.info(shared_config_path)
15
+
16
+ api.create_for_shared_config(shared_config[:id], params)
17
+ end
18
+
19
+ def remove_from_shared_config(shared_config_path, instance_name)
20
+ instances = list_for_shared_config(shared_config_path)
21
+
22
+ selected_instance = instances.find { |instance| instance[:name] == instance_name }
23
+
24
+ api.delete(selected_instance[:id])
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ module Sem
2
+ module API
3
+ module Traits
4
+ module AssociatedWithTeam
5
+ def list_for_team(team_path)
6
+ team = Teams.info(team_path)
7
+
8
+ instances = api.list_for_team(team[:id])
9
+
10
+ instances.map { |instance| to_hash(instance) }
11
+ end
12
+
13
+ def add_to_team(team_path, instance_path)
14
+ instance = info(instance_path)
15
+ team = Teams.info(team_path)
16
+
17
+ api.attach_to_team(instance[:id], team[:id])
18
+ end
19
+
20
+ def remove_from_team(team_path, instance_path)
21
+ instance = info(instance_path)
22
+ team = Teams.info(team_path)
23
+
24
+ api.detach_from_team(instance[:id], team[:id])
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,26 @@
1
+ module Sem
2
+ module API
3
+ class Users < Base
4
+ extend Traits::AssociatedWithOrg
5
+ extend Traits::AssociatedWithTeam
6
+
7
+ def self.list
8
+ org_names = Orgs.list.map { |org| org[:username] }
9
+
10
+ org_names.map { |name| list_for_org(name) }.flatten
11
+ end
12
+
13
+ def self.info(name)
14
+ list.find { |user| user[:id] == name }
15
+ end
16
+
17
+ def self.api
18
+ client.users
19
+ end
20
+
21
+ def self.to_hash(user)
22
+ { :id => user.username }
23
+ end
24
+ end
25
+ end
26
+ end