neetob-ud 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +10 -0
  3. data/.env +1 -0
  4. data/.rubocop.yml +596 -0
  5. data/.ruby-version +1 -0
  6. data/.semaphore/semaphore.yml +30 -0
  7. data/CHANGELOG.md +40 -0
  8. data/CODE_OF_CONDUCT.md +84 -0
  9. data/Gemfile +28 -0
  10. data/Gemfile.lock +250 -0
  11. data/LICENSE.txt +21 -0
  12. data/README.md +396 -0
  13. data/Rakefile +16 -0
  14. data/config/secrets.yml +0 -0
  15. data/data/branch-protection-rules.json +25 -0
  16. data/data/config-vars-audit.json +18 -0
  17. data/data/config-vars-list.json +1 -0
  18. data/data/github-labels.json +197 -0
  19. data/env.sample +1 -0
  20. data/exe/neetob +25 -0
  21. data/install.sh +21 -0
  22. data/lib/neetob/cli/base.rb +96 -0
  23. data/lib/neetob/cli/fetchorupdate_repos/execute.rb +55 -0
  24. data/lib/neetob/cli/github/auth.rb +134 -0
  25. data/lib/neetob/cli/github/base.rb +42 -0
  26. data/lib/neetob/cli/github/commands.rb +54 -0
  27. data/lib/neetob/cli/github/issues/commands.rb +51 -0
  28. data/lib/neetob/cli/github/issues/create.rb +42 -0
  29. data/lib/neetob/cli/github/issues/list.rb +94 -0
  30. data/lib/neetob/cli/github/labels/commands.rb +65 -0
  31. data/lib/neetob/cli/github/labels/delete.rb +46 -0
  32. data/lib/neetob/cli/github/labels/delete_all.rb +50 -0
  33. data/lib/neetob/cli/github/labels/list.rb +38 -0
  34. data/lib/neetob/cli/github/labels/show.rb +39 -0
  35. data/lib/neetob/cli/github/labels/update.rb +42 -0
  36. data/lib/neetob/cli/github/labels/upsert.rb +64 -0
  37. data/lib/neetob/cli/github/login.rb +16 -0
  38. data/lib/neetob/cli/github/make_pr/base.rb +72 -0
  39. data/lib/neetob/cli/github/make_pr/commands.rb +37 -0
  40. data/lib/neetob/cli/github/make_pr/compliance_fix.rb +49 -0
  41. data/lib/neetob/cli/github/make_pr/script.rb +55 -0
  42. data/lib/neetob/cli/github/protect_branch.rb +48 -0
  43. data/lib/neetob/cli/github/search.rb +38 -0
  44. data/lib/neetob/cli/heroku/access/add.rb +38 -0
  45. data/lib/neetob/cli/heroku/access/commands.rb +41 -0
  46. data/lib/neetob/cli/heroku/access/list.rb +36 -0
  47. data/lib/neetob/cli/heroku/access/remove.rb +38 -0
  48. data/lib/neetob/cli/heroku/commands.rb +28 -0
  49. data/lib/neetob/cli/heroku/config_vars/audit.rb +64 -0
  50. data/lib/neetob/cli/heroku/config_vars/base.rb +19 -0
  51. data/lib/neetob/cli/heroku/config_vars/commands.rb +49 -0
  52. data/lib/neetob/cli/heroku/config_vars/list.rb +56 -0
  53. data/lib/neetob/cli/heroku/config_vars/remove.rb +39 -0
  54. data/lib/neetob/cli/heroku/config_vars/upsert.rb +80 -0
  55. data/lib/neetob/cli/heroku/execute.rb +37 -0
  56. data/lib/neetob/cli/local/commands.rb +19 -0
  57. data/lib/neetob/cli/local/ls.rb +29 -0
  58. data/lib/neetob/cli/sub_command_base.rb +17 -0
  59. data/lib/neetob/cli/ui.rb +41 -0
  60. data/lib/neetob/cli/users/audit.rb +121 -0
  61. data/lib/neetob/cli/users/commands.rb +30 -0
  62. data/lib/neetob/cli/users/commits.rb +171 -0
  63. data/lib/neetob/cli.rb +42 -0
  64. data/lib/neetob/exception_handler.rb +58 -0
  65. data/lib/neetob/utils.rb +16 -0
  66. data/lib/neetob/version.rb +5 -0
  67. data/lib/neetob.rb +10 -0
  68. data/overcommit.yml +43 -0
  69. data/scripts/delete_unused_assets.rb +67 -0
  70. metadata +186 -0
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+
5
+ require_relative "../base"
6
+
7
+ module Neetob
8
+ class CLI
9
+ module Github
10
+ module Labels
11
+ class Delete < Base
12
+ attr_accessor :apps, :sandbox, :labels, :all_neeto_repos
13
+
14
+ def initialize(apps, labels, sandbox = false, all_neeto_repos = false)
15
+ super()
16
+ @labels = labels
17
+ @apps = apps
18
+ @sandbox = sandbox
19
+ @all_neeto_repos = all_neeto_repos
20
+ end
21
+
22
+ def run
23
+ check_for_apps_and_all_neeto_repos_option(apps, all_neeto_repos)
24
+ matching_apps = find_all_matching_apps(apps, :github, sandbox, false, all_neeto_repos)
25
+ matching_apps.each do |app|
26
+ ui.info("\n Deleting labels from #{app} repo \n")
27
+ labels.each do |label|
28
+ delete_label(app, label)
29
+ end
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def delete_label(app, label)
36
+ if client.delete_label!(app, label)
37
+ ui.success("The \"#{label}\" label deleted successfully")
38
+ else
39
+ ui.error("The \"#{label}\" label can't be deleted. Please check and try again")
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+
5
+ require_relative "../base"
6
+
7
+ module Neetob
8
+ class CLI
9
+ module Github
10
+ module Labels
11
+ class DeleteAll < Base
12
+ attr_accessor :apps, :sandbox, :all_neeto_repos
13
+
14
+ def initialize(apps, sandbox = false, all_neeto_repos = false)
15
+ super()
16
+ @apps = apps
17
+ @sandbox = sandbox
18
+ @all_neeto_repos = all_neeto_repos
19
+ end
20
+
21
+ def run
22
+ check_for_apps_and_all_neeto_repos_option(apps, all_neeto_repos)
23
+ matching_apps = find_all_matching_apps(apps, :github, sandbox, false, all_neeto_repos)
24
+ matching_apps.each do |app|
25
+ ui.info("\n Working on #{app} repo \n")
26
+ begin
27
+ labels = client.labels(app)
28
+ labels.each do |label|
29
+ delete_label(app, label)
30
+ end
31
+ rescue StandardError => e
32
+ ExceptionHandler.new(e).process
33
+ end
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def delete_label(app, label_details)
40
+ if client.delete_label!(app, label_details[:name])
41
+ ui.success("The \"#{label_details[:name]}\" label deleted successfully")
42
+ else
43
+ ui.error("The \"#{label_details[:name]}\" label can't be deleted. Please try again")
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+
5
+ require_relative "../base"
6
+
7
+ module Neetob
8
+ class CLI
9
+ module Github
10
+ module Labels
11
+ class List < Base
12
+ attr_accessor :apps, :sandbox, :all_neeto_repos
13
+
14
+ def initialize(apps, sandbox = false, all_neeto_repos = false)
15
+ super()
16
+ @apps = apps
17
+ @sandbox = sandbox
18
+ @all_neeto_repos = all_neeto_repos
19
+ end
20
+
21
+ def run
22
+ check_for_apps_and_all_neeto_repos_option(apps, all_neeto_repos)
23
+ matching_apps = find_all_matching_apps(apps, :github, sandbox, false, all_neeto_repos)
24
+ matching_apps.each do |app|
25
+ ui.info("\n Labels of #{app} \n")
26
+ begin
27
+ labels = client.labels(app)
28
+ ui.success(labels)
29
+ rescue StandardError => e
30
+ ExceptionHandler.new(e).process
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+
5
+ require_relative "../base"
6
+
7
+ module Neetob
8
+ class CLI
9
+ module Github
10
+ module Labels
11
+ class Show < Base
12
+ attr_accessor :apps, :label_name, :sandbox, :all_neeto_repos
13
+
14
+ def initialize(apps, label_name, sandbox = false, all_neeto_repos = false)
15
+ super()
16
+ @apps = apps
17
+ @label_name = label_name
18
+ @sandbox = sandbox
19
+ @all_neeto_repos = all_neeto_repos
20
+ end
21
+
22
+ def run
23
+ check_for_apps_and_all_neeto_repos_option(apps, all_neeto_repos)
24
+ matching_apps = find_all_matching_apps(apps, :github, sandbox, false, all_neeto_repos)
25
+ matching_apps.each do |app|
26
+ ui.info("\n \"#{label_name}\" label details from #{app} \n")
27
+ begin
28
+ label_details = client.label(app, label_name)
29
+ ui.success(label_details.inspect)
30
+ rescue StandardError => e
31
+ ExceptionHandler.new(e).process
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+
5
+ require_relative "../base"
6
+
7
+ module Neetob
8
+ class CLI
9
+ module Github
10
+ module Labels
11
+ class Update < Base
12
+ attr_accessor :apps, :sandbox, :old_name, :new_name, :all_neeto_repos
13
+
14
+ def initialize(apps, old_name, new_name, sandbox = false, all_neeto_repos = false)
15
+ super()
16
+ @apps = apps
17
+ @sandbox = sandbox
18
+ @old_name = old_name
19
+ @new_name = new_name
20
+ @all_neeto_repos = all_neeto_repos
21
+ end
22
+
23
+ def run
24
+ check_for_apps_and_all_neeto_repos_option(apps, all_neeto_repos)
25
+ matching_apps = find_all_matching_apps(apps, :github, sandbox, false, all_neeto_repos)
26
+ matching_apps.each do |app|
27
+ ui.info("\n Updating label for #{app} repo \n")
28
+ update_label!(app, old_name, new_name)
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def update_label!(app, old_name, new_name)
35
+ client.update_label(app, old_name, { name: new_name })
36
+ ui.success("Label \"#{old_name}\" updated to \"#{new_name}\" successfully")
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+
5
+ require_relative "../base"
6
+
7
+ module Neetob
8
+ class CLI
9
+ module Github
10
+ module Labels
11
+ class Upsert < Base
12
+ attr_accessor :apps, :required_labels_json_file_path, :sandbox, :all_neeto_repos
13
+
14
+ def initialize(apps, required_labels_json_file_path = "", sandbox = false, all_neeto_repos = false)
15
+ super()
16
+ @apps = apps
17
+ @required_labels_json_file_path = required_labels_json_file_path
18
+ @sandbox = sandbox
19
+ @all_neeto_repos = all_neeto_repos
20
+ end
21
+
22
+ def run
23
+ check_for_apps_and_all_neeto_repos_option(apps, all_neeto_repos)
24
+ matching_apps = find_all_matching_apps(apps, :github, sandbox, false, all_neeto_repos)
25
+ inform_about_default_labels_file
26
+ matching_apps.each do |app|
27
+ ui.info("\n Working on #{app} repo \n")
28
+ begin
29
+ required_labels = read_json_file(required_labels_json_file_path || default_labels_file_path)
30
+ required_labels.each do |label|
31
+ create_or_update_label(app, label)
32
+ end
33
+ rescue StandardError => e
34
+ ExceptionHandler.new(e).process
35
+ end
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def create_or_update_label(app, label_details)
42
+ begin
43
+ client.update_label(app, label_details["name"], label_details)
44
+ ui.success("Label \"#{label_details["name"]}\" updated successfully")
45
+ rescue Octokit::NotFound
46
+ client.add_label(app, label_details["name"], label_details["color"], label_details)
47
+ ui.success("Label \"#{label_details["name"]}\" created successfully")
48
+ end
49
+ end
50
+
51
+ def default_labels_file_path
52
+ File.expand_path("../../../../../data/github-labels.json", __dir__)
53
+ end
54
+
55
+ def inform_about_default_labels_file
56
+ if required_labels_json_file_path.nil?
57
+ ui.info("Upserting labels from the \"neetob/data/github-labels.json\" file")
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Neetob
6
+ class CLI
7
+ module Github
8
+ class Login < Base
9
+ def initialize
10
+ super()
11
+ Auth.new(**read_and_parse_auth_params_from_env).start_oauth2_device_flow
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../base"
4
+
5
+ module Neetob
6
+ class CLI
7
+ module Github
8
+ module MakePr
9
+ class Base < Github::Base
10
+ BRANCH_NAME = "neeto_compliance"
11
+ PR_TITLE = "Neeto Compliance"
12
+ attr_accessor :branch_name, :pr_title
13
+
14
+ def initialize(pr_title = PR_TITLE, branch_name = BRANCH_NAME)
15
+ super()
16
+ @branch_name = branch_name || BRANCH_NAME
17
+ @pr_title = pr_title || PR_TITLE
18
+ end
19
+
20
+ private
21
+
22
+ def delete_and_create_temp_neetob_dir
23
+ `rm -rf /tmp/neetob`
24
+ `mkdir /tmp/neetob`
25
+ end
26
+
27
+ def app_name_without_org_suffix(app)
28
+ app.split("/").last
29
+ end
30
+
31
+ def clone_app_in_tmp_dir(app)
32
+ `git clone --quiet git@github.com:#{app}.git /tmp/neetob/#{app_name_without_org_suffix(app)}`
33
+ end
34
+
35
+ def add_commmit_and_push_changes(app)
36
+ `#{cd_to_app_in_tmp_dir(app)} && git add . && git commit -m "#{pr_title}" && git push -u origin #{branch_name} --force`
37
+ end
38
+
39
+ def delete_local_feature_branch(app)
40
+ `#{cd_to_app_in_tmp_dir(app)} && git checkout main && git branch -D #{branch_name}`
41
+ end
42
+
43
+ def checkout_to_new_branch(app)
44
+ `#{cd_to_app_in_tmp_dir(app)} && git checkout -b #{branch_name}`
45
+ end
46
+
47
+ def checkout_to_feature_branch(app)
48
+ `#{cd_to_app_in_tmp_dir(app)} && git checkout #{branch_name}`
49
+ end
50
+
51
+ def delete_remote_feature_branch(app)
52
+ `#{cd_to_app_in_tmp_dir(app)} && git push origin --delete #{branch_name}`
53
+ end
54
+
55
+ def check_and_delete_remote_branch(app)
56
+ checkout_to_feature_branch(app)
57
+ if $?.success?
58
+ ui.info("Remote branch found with the name \"#{branch_name}\"")
59
+ delete_remote_feature_branch(app)
60
+ delete_local_feature_branch(app)
61
+ end
62
+ checkout_to_new_branch(app)
63
+ end
64
+
65
+ def cd_to_app_in_tmp_dir(app)
66
+ "cd /tmp/neetob/#{app_name_without_org_suffix(app)}"
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+
5
+ require_relative "compliance_fix"
6
+ require_relative "script"
7
+ require_relative "../../sub_command_base"
8
+
9
+ module Neetob
10
+ class CLI
11
+ module Github
12
+ module MakePr
13
+ class Commands < SubCommandBase
14
+ class_option :apps,
15
+ {
16
+ type: :array, aliases: "-a", default: ["*"],
17
+ desc: "Github app names. Can be matched using the '*' wildcard. Example: \"neeto*\" \"neeto-cal-web\""
18
+ }
19
+
20
+ desc "compliance-fix", "Create PRs for fixing neeto compliance in all products"
21
+ def compliance_fix
22
+ ComplianceFix.new(options[:apps], options[:sandbox]).run
23
+ end
24
+
25
+ desc "script", "Create PRs after running the given script for each product."
26
+ option :path, type: :string, aliases: "-p",
27
+ desc: "Path to UNIX executable script which will be run for each product", required: true
28
+ option :title, type: :string, aliases: "-t", desc: "Title for the PR"
29
+ option :branch, type: :string, aliases: "-b", desc: "Feature branch name for the PR"
30
+ def script
31
+ Script.new(options[:apps], options[:path], options[:title], options[:branch], options[:sandbox]).run
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+
5
+ require_relative "base"
6
+
7
+ module Neetob
8
+ class CLI
9
+ module Github
10
+ module MakePr
11
+ class ComplianceFix < Base
12
+ attr_accessor :apps, :sandbox
13
+
14
+ def initialize(apps, sandbox = false)
15
+ super()
16
+ @apps = apps
17
+ @sandbox = sandbox
18
+ end
19
+
20
+ def run
21
+ matching_apps = find_all_matching_apps(apps, :github, sandbox)
22
+ delete_and_create_temp_neetob_dir
23
+ matching_apps.each do |app|
24
+ ui.info("\n Working on #{app} \n")
25
+ begin
26
+ clone_app_in_tmp_dir(app)
27
+ check_and_delete_remote_branch(app)
28
+ bundle_install(app)
29
+ ui.info(add_commmit_and_push_changes(app))
30
+ delete_local_feature_branch(app)
31
+ res = client.create_pull_request(app, "main", BRANCH_NAME, PR_TITLE)
32
+ ui.success("PR created in \"#{app}\" project successfully.")
33
+ rescue StandardError => e
34
+ ExceptionHandler.new(e).process
35
+ end
36
+ end
37
+ `rm -rf /tmp/neetob`
38
+ end
39
+
40
+ private
41
+
42
+ def bundle_install(app)
43
+ `#{cd_to_app_in_tmp_dir(app)} && bundle`
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+
5
+ require_relative "base"
6
+
7
+ module Neetob
8
+ class CLI
9
+ module Github
10
+ module MakePr
11
+ class Script < Base
12
+ attr_accessor :apps, :sandbox, :path_to_the_script_file
13
+
14
+ def initialize(apps, path_to_the_script_file, pr_title, branch_name, sandbox = false)
15
+ super(pr_title, branch_name)
16
+ @apps = apps
17
+ @sandbox = sandbox
18
+ @path_to_the_script_file = path_to_the_script_file
19
+ end
20
+
21
+ def run
22
+ matching_apps = find_all_matching_apps(apps, :github, sandbox)
23
+ delete_and_create_temp_neetob_dir
24
+ matching_apps.each do |app|
25
+ ui.info("\n Working on #{app} \n")
26
+ begin
27
+ clone_app_in_tmp_dir(app)
28
+ check_and_delete_remote_branch(app)
29
+ update_script_file_permissions
30
+ execute_script(app)
31
+ ui.info(add_commmit_and_push_changes(app))
32
+ delete_local_feature_branch(app)
33
+ res = client.create_pull_request(app, "main", branch_name, pr_title)
34
+ ui.success("PR created in \"#{app}\" project successfully.")
35
+ rescue StandardError => e
36
+ ExceptionHandler.new(e).process
37
+ end
38
+ end
39
+ `rm -rf /tmp/neetob`
40
+ end
41
+
42
+ private
43
+
44
+ def update_script_file_permissions
45
+ `chmod +x #{path_to_the_script_file}`
46
+ end
47
+
48
+ def execute_script(app)
49
+ `#{cd_to_app_in_tmp_dir(app)} && #{path_to_the_script_file}`
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Neetob
6
+ class CLI
7
+ module Github
8
+ class ProtectBranch < Base
9
+ attr_accessor :branch_name, :required_rules_json_file_path, :apps, :sandbox, :all_neeto_repos
10
+
11
+ def initialize(branch_name, apps, required_rules_json_file_path = "", sandbox = false, all_neeto_repos = false)
12
+ super()
13
+ @branch_name = branch_name
14
+ @required_rules_json_file_path = required_rules_json_file_path
15
+ @apps = apps
16
+ @sandbox = sandbox
17
+ @all_neeto_repos = all_neeto_repos
18
+ end
19
+
20
+ def run
21
+ check_for_apps_and_all_neeto_repos_option(apps, all_neeto_repos)
22
+ matching_apps = find_all_matching_apps(apps, :github, sandbox, false, all_neeto_repos)
23
+ inform_about_default_rules_file
24
+ matching_apps.each do |app|
25
+ ui.info("\n Working on \"#{app}\" repo")
26
+ ui.info(" Updating \"#{branch_name}\" branch protection rules")
27
+ rules = read_json_file(required_rules_json_file_path || default_rules_file_path)
28
+ rules_with_symbol_keys = rules.transform_keys(&:to_sym)
29
+ client.protect_branch(app, branch_name, rules_with_symbol_keys)
30
+ ui.success("Branch protection rules updated successfully")
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def default_rules_file_path
37
+ File.expand_path("../../../../data/branch-protection-rules.json", __dir__)
38
+ end
39
+
40
+ def inform_about_default_rules_file
41
+ if required_rules_json_file_path.nil?
42
+ ui.info("Updating protection rules from the \"neetob/data/branch-protection-rules.json\" file")
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ module Neetob
6
+ class CLI
7
+ module Github
8
+ class Search < Base
9
+ attr_accessor :apps, :key_to_search, :search_file_path, :sandbox
10
+
11
+ def initialize(apps, key_to_search, search_file_path, sandbox = false)
12
+ super()
13
+ @apps = apps
14
+ @key_to_search = key_to_search
15
+ @search_file_path = search_file_path
16
+ @sandbox = sandbox
17
+ end
18
+
19
+ def run
20
+ matching_apps = find_all_matching_apps(apps, :github, sandbox)
21
+ matching_apps.each do |app|
22
+ begin
23
+ ui.info("\n Searching in \"#{app}/#{search_file_path}\" for \"#{key_to_search}\"\n")
24
+ content = Base64.decode64(client.contents(app, path: search_file_path).content)
25
+ ui.error("Keyword not found") and next unless content.include? key_to_search
26
+
27
+ content.each_line do |line|
28
+ ui.success(line) if line.include?(key_to_search)
29
+ end
30
+ rescue StandardError => e
31
+ ExceptionHandler.new(e).process
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../base"
4
+
5
+ module Neetob
6
+ class CLI
7
+ module Heroku
8
+ module Access
9
+ class Add < Base
10
+ attr_accessor :apps, :new_users, :sandbox
11
+
12
+ def initialize(apps, new_users = [], sandbox = false)
13
+ super()
14
+ @apps = apps
15
+ @new_users = new_users
16
+ @sandbox = sandbox
17
+ end
18
+
19
+ def run
20
+ matching_apps = find_all_matching_apps(apps, :heroku, sandbox)
21
+ matching_apps.each do |app|
22
+ `heroku access -a #{app}`
23
+ unless $?.success?
24
+ ui.error("There is a problem in accessing the app with name \"#{app}\" in your account.")
25
+ ui.error("Please check the specified app name and ensure you're authorized to view that app.")
26
+ next
27
+ end
28
+
29
+ new_users.each do |user|
30
+ ui.info(`heroku access:add #{user} -a #{app}`)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+
5
+ require_relative "list"
6
+ require_relative "add"
7
+ require_relative "remove"
8
+ require_relative "../../sub_command_base"
9
+
10
+ module Neetob
11
+ class CLI
12
+ module Heroku
13
+ module Access
14
+ class Commands < SubCommandBase
15
+ class_option :apps,
16
+ {
17
+ type: :array, aliases: "-a", required: true,
18
+ desc: "Heroku app names. Can be matched using the '*' wildcard. Example: \"neeto*\" \"neeto-cal-web-staging\""
19
+ }
20
+
21
+ desc "list", "List all the users of the Heroku apps"
22
+ def list
23
+ List.new(options[:apps], options[:sandbox]).run
24
+ end
25
+
26
+ desc "add", "Add new users to the Heroku apps"
27
+ option :users, type: :array, required: true, desc: "Users' emails that need to be added to Heroku apps"
28
+ def add
29
+ Add.new(options[:apps], options[:users], options[:sandbox]).run
30
+ end
31
+
32
+ desc "remove", "Remove the users from the Heroku apps"
33
+ option :users, type: :array, required: true, desc: "Users' emails that need to be removed from the Heroku apps"
34
+ def remove
35
+ Remove.new(options[:apps], options[:users], options[:sandbox]).run
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end