neetob 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) 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 +31 -0
  7. data/CHANGELOG.md +5 -0
  8. data/CODE_OF_CONDUCT.md +84 -0
  9. data/Gemfile +26 -0
  10. data/Gemfile.lock +249 -0
  11. data/LICENSE.txt +21 -0
  12. data/README.md +381 -0
  13. data/Rakefile +16 -0
  14. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/github_access.rb +29 -0
  15. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/neeto_apps.rb +35 -0
  16. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/neeto_commons.rb +16 -0
  17. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/runner.rb +35 -0
  18. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/skippable.rb +19 -0
  19. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/sync_neeto_commons/sync_bin.rb +32 -0
  20. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/sync_neeto_commons/sync_formatters.rb +35 -0
  21. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/sync_neeto_commons/sync_husky.rb +33 -0
  22. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/sync_neeto_commons/sync_misc.rb +36 -0
  23. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/sync_neeto_commons/sync_test_support.rb +38 -0
  24. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/sync_neeto_commons.rb +36 -0
  25. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/auto_update_prs_with_latest_master_verifier.rb +25 -0
  26. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/base.rb +72 -0
  27. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/bundler_version_verifier.rb +53 -0
  28. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/circleci_config_verifier.rb +25 -0
  29. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/common_gemfile_verifier.rb +25 -0
  30. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/common_initializers_verifier.rb +25 -0
  31. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/cypress_config_verifier.rb +46 -0
  32. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/cypress_plugins_index_verifier.rb +25 -0
  33. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/docker_file_dev_verifier.rb +25 -0
  34. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/environment_config_verifier.rb +38 -0
  35. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/gem_version_verifier.rb +38 -0
  36. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/gems_verifier_base.rb +34 -0
  37. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/gitignore_file_verifier.rb +39 -0
  38. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/jsconfig_verifier.rb +100 -0
  39. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/neeto_auth_gems_verifier.rb +20 -0
  40. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/neeto_commons_sync_verifier.rb +42 -0
  41. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/neeto_gems_version_verifier.rb +24 -0
  42. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/newrelic_verifier.rb +25 -0
  43. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/node_version_verifier.rb +63 -0
  44. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/package_dependencies_version_verifier.rb +62 -0
  45. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/package_json_verifier.rb +39 -0
  46. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/roles_verifier.rb +22 -0
  47. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/ruby_version_verifier.rb +25 -0
  48. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/semaphoreci_config_verifier.rb +162 -0
  49. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/sidekiq_queues_verifier.rb +34 -0
  50. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/simplecov_config_verifier.rb +28 -0
  51. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/sitemap_config_verifier.rb +29 -0
  52. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/slugignore_file_verifier.rb +25 -0
  53. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/sync_neeto_commons_verifier/bin_files_verifier.rb +29 -0
  54. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/sync_neeto_commons_verifier/formatter_files_verifier.rb +29 -0
  55. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/sync_neeto_commons_verifier/husky_files_verifier.rb +29 -0
  56. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/sync_neeto_commons_verifier/misc_files_verifier.rb +29 -0
  57. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/sync_neeto_commons_verifier/test_support_files_verifier.rb +28 -0
  58. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/sync_neeto_commons_verifier.rb +31 -0
  59. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/webpack_configuration_verifier.rb +44 -0
  60. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers/webpacker_config_verifier.rb +29 -0
  61. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/verifiers_list.rb +61 -0
  62. data/Users/chiragshah/Workspace/bigbinary/neeto/neetob/neeto_compliance/lib/neeto_compliance/version.rb +5 -0
  63. data/data/branch-protection-rules.json +25 -0
  64. data/data/config-vars-audit.json +18 -0
  65. data/data/config-vars-list.json +1 -0
  66. data/data/config-vars-upsert.json +3 -0
  67. data/data/github-labels.json +192 -0
  68. data/env.sample +1 -0
  69. data/exe/neetob +25 -0
  70. data/install.sh +21 -0
  71. data/lib/neetob/cli/base.rb +85 -0
  72. data/lib/neetob/cli/fetchorupdate_repos/execute.rb +53 -0
  73. data/lib/neetob/cli/github/auth.rb +134 -0
  74. data/lib/neetob/cli/github/base.rb +35 -0
  75. data/lib/neetob/cli/github/commands.rb +50 -0
  76. data/lib/neetob/cli/github/issues/commands.rb +51 -0
  77. data/lib/neetob/cli/github/issues/create.rb +42 -0
  78. data/lib/neetob/cli/github/issues/list.rb +94 -0
  79. data/lib/neetob/cli/github/labels/commands.rb +62 -0
  80. data/lib/neetob/cli/github/labels/delete.rb +44 -0
  81. data/lib/neetob/cli/github/labels/delete_all.rb +48 -0
  82. data/lib/neetob/cli/github/labels/list.rb +36 -0
  83. data/lib/neetob/cli/github/labels/show.rb +37 -0
  84. data/lib/neetob/cli/github/labels/update.rb +40 -0
  85. data/lib/neetob/cli/github/labels/upsert.rb +62 -0
  86. data/lib/neetob/cli/github/login.rb +16 -0
  87. data/lib/neetob/cli/github/make_pr/base.rb +72 -0
  88. data/lib/neetob/cli/github/make_pr/commands.rb +37 -0
  89. data/lib/neetob/cli/github/make_pr/compliance_fix.rb +49 -0
  90. data/lib/neetob/cli/github/make_pr/script.rb +55 -0
  91. data/lib/neetob/cli/github/protect_branch.rb +46 -0
  92. data/lib/neetob/cli/github/search.rb +38 -0
  93. data/lib/neetob/cli/heroku/access/add.rb +38 -0
  94. data/lib/neetob/cli/heroku/access/commands.rb +41 -0
  95. data/lib/neetob/cli/heroku/access/list.rb +36 -0
  96. data/lib/neetob/cli/heroku/access/remove.rb +38 -0
  97. data/lib/neetob/cli/heroku/commands.rb +28 -0
  98. data/lib/neetob/cli/heroku/config_vars/audit.rb +64 -0
  99. data/lib/neetob/cli/heroku/config_vars/base.rb +19 -0
  100. data/lib/neetob/cli/heroku/config_vars/commands.rb +49 -0
  101. data/lib/neetob/cli/heroku/config_vars/list.rb +56 -0
  102. data/lib/neetob/cli/heroku/config_vars/remove.rb +39 -0
  103. data/lib/neetob/cli/heroku/config_vars/upsert.rb +80 -0
  104. data/lib/neetob/cli/heroku/execute.rb +37 -0
  105. data/lib/neetob/cli/local/commands.rb +19 -0
  106. data/lib/neetob/cli/local/ls.rb +29 -0
  107. data/lib/neetob/cli/sub_command_base.rb +17 -0
  108. data/lib/neetob/cli/ui.rb +41 -0
  109. data/lib/neetob/cli/users/audit.rb +121 -0
  110. data/lib/neetob/cli/users/commands.rb +28 -0
  111. data/lib/neetob/cli/users/commits.rb +125 -0
  112. data/lib/neetob/cli.rb +40 -0
  113. data/lib/neetob/exception_handler.rb +58 -0
  114. data/lib/neetob/utils.rb +16 -0
  115. data/lib/neetob/version.rb +5 -0
  116. data/lib/neetob.rb +10 -0
  117. data/overcommit.yml +43 -0
  118. data/scripts/delete_unused_assets.rb +67 -0
  119. metadata +235 -0
@@ -0,0 +1,62 @@
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
13
+
14
+ def initialize(apps, required_labels_json_file_path = "", sandbox = false)
15
+ super()
16
+ @apps = apps
17
+ @required_labels_json_file_path = required_labels_json_file_path
18
+ @sandbox = sandbox
19
+ end
20
+
21
+ def run
22
+ matching_apps = find_all_matching_apps(apps, :github, sandbox)
23
+ inform_about_default_labels_file
24
+ matching_apps.each do |app|
25
+ ui.info("\n Working on #{app} repo \n")
26
+ begin
27
+ required_labels = read_json_file(required_labels_json_file_path || default_labels_file_path)
28
+ required_labels.each do |label|
29
+ create_or_update_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 create_or_update_label(app, label_details)
40
+ begin
41
+ client.update_label(app, label_details["name"], label_details)
42
+ ui.success("Label \"#{label_details["name"]}\" updated successfully")
43
+ rescue Octokit::NotFound
44
+ client.add_label(app, label_details["name"], label_details["color"], label_details)
45
+ ui.success("Label \"#{label_details["name"]}\" created successfully")
46
+ end
47
+ end
48
+
49
+ def default_labels_file_path
50
+ File.expand_path("../../../../../data/github-labels.json", __dir__)
51
+ end
52
+
53
+ def inform_about_default_labels_file
54
+ if required_labels_json_file_path.nil?
55
+ ui.info("Upserting labels from the \"neetob/data/github-labels.json\" file")
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ 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,46 @@
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
10
+
11
+ def initialize(branch_name, apps, required_rules_json_file_path = "", sandbox = 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
+ end
18
+
19
+ def run
20
+ matching_apps = find_all_matching_apps(apps, :github, sandbox)
21
+ inform_about_default_rules_file
22
+ matching_apps.each do |app|
23
+ ui.info("\n Working on \"#{app}\" repo")
24
+ ui.info(" Updating \"#{branch_name}\" branch protection rules")
25
+ rules = read_json_file(required_rules_json_file_path || default_rules_file_path)
26
+ rules_with_symbol_keys = rules.transform_keys(&:to_sym)
27
+ client.protect_branch(app, branch_name, rules_with_symbol_keys)
28
+ ui.success("Branch protection rules updated successfully")
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def default_rules_file_path
35
+ File.expand_path("../../../../data/branch-protection-rules.json", __dir__)
36
+ end
37
+
38
+ def inform_about_default_rules_file
39
+ if required_rules_json_file_path.nil?
40
+ ui.info("Updating protection rules from the \"neetob/data/branch-protection-rules.json\" file")
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ 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
@@ -0,0 +1,36 @@
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 List < Base
10
+ attr_accessor :apps, :sandbox
11
+
12
+ def initialize(apps, sandbox = false)
13
+ super()
14
+ @apps = apps
15
+ @sandbox = sandbox
16
+ end
17
+
18
+ def run
19
+ matching_apps = find_all_matching_apps(apps, :heroku, sandbox)
20
+ matching_apps.each do |app|
21
+ ui.info("\n Users for \"#{app}\" app\n")
22
+ users = `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
+ ui.success(users)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ 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 Remove < Base
10
+ attr_accessor :apps, :users_to_be_removed, :sandbox
11
+
12
+ def initialize(apps, users_to_be_removed = [], sandbox = false)
13
+ super()
14
+ @apps = apps
15
+ @users_to_be_removed = users_to_be_removed
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
+ users_to_be_removed.each do |user|
30
+ ui.info(`heroku access:remove #{user} -a #{app}`)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+ require_relative "config_vars/commands"
5
+ require_relative "access/commands"
6
+ require_relative "execute"
7
+
8
+ module Neetob
9
+ class CLI
10
+ module Heroku
11
+ class Commands < Thor
12
+ desc "execute", "Run the given Heroku CLI command or Rails console command on Heroku apps"
13
+ option :command, type: :string, aliases: "-c", required: true, desc: "Command to run on Heroku apps"
14
+ option :rails, type: :boolean, aliases: "-r", default: false, desc: "Use this flag to run the given command in the Rails console"
15
+ option :apps, type: :array, aliases: "-a", required: true, desc: "Heroku app names. Can be matched using the '*' wildcard. Example: \"neeto*\" \"neeto-cal-web-staging\""
16
+ def execute
17
+ Execute.new(options[:apps], options[:command], options[:rails], options[:sandbox]).run
18
+ end
19
+
20
+ desc "config_vars", "Interact with the config(env) variables on Heroku apps"
21
+ subcommand "config_vars", ConfigVars::Commands
22
+
23
+ desc "access", "Interact with the users of the Heroku apps"
24
+ subcommand "access", Access::Commands
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "terminal-table"
5
+
6
+ require_relative "base"
7
+
8
+ module Neetob
9
+ class CLI
10
+ module Heroku
11
+ module ConfigVars
12
+ class Audit < Base
13
+ attr_accessor :apps, :expected_config_vars_json_file_path, :sandbox
14
+
15
+ def initialize(apps, expected_config_vars_json_file_path = "", sandbox = false)
16
+ super()
17
+ @apps = apps
18
+ @expected_config_vars_json_file_path = expected_config_vars_json_file_path
19
+ @sandbox = sandbox
20
+ end
21
+
22
+ def run
23
+ matching_apps = find_all_matching_apps(apps, :heroku, sandbox)
24
+ table_rows = []
25
+ expected_config = read_json_file(expected_config_vars_json_file_path || default_config_vars_json_file_path)
26
+ return unless expected_config
27
+
28
+ matching_apps.each do |app|
29
+ actual_config = `heroku config -a #{app} --json`
30
+ unless $?.success?
31
+ ui.error("There is a problem in accessing the app with name \"#{app}\" in your account.")
32
+ ui.error("Please check the specified app name and ensure you're authorized to view that app.")
33
+ next
34
+ end
35
+
36
+ actual_config_json = JSON.parse(actual_config)
37
+ table_rows.concat(compare_config_and_build_rows(app, expected_config, actual_config_json))
38
+ end
39
+ table = Terminal::Table.new headings: ["App", "Config var", "Expected", "Result"], rows: table_rows
40
+ ui.success(table)
41
+ end
42
+
43
+ private
44
+
45
+ def compare_config_and_build_rows(app, expected_config, actual_config)
46
+ expected_config.map do |key, val|
47
+ row = [app, key.to_s]
48
+ row << (value_set_dynamically_by_heroku?(val) ? "Heroku has dynamically set the value" : val.to_s)
49
+ row << (actual_config[key] == val ? "✅" : (actual_config[key] || "No such key"))
50
+ end
51
+ end
52
+
53
+ def value_set_dynamically_by_heroku?(value)
54
+ value == { "isDynamic" => true }
55
+ end
56
+
57
+ def default_config_vars_json_file_path
58
+ File.expand_path("../../../../../data/config-vars-audit.json", __dir__)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../base"
4
+
5
+ module Neetob
6
+ class CLI
7
+ module Heroku
8
+ module ConfigVars
9
+ class Base < CLI::Base
10
+ attr_accessor :client
11
+
12
+ def initialize
13
+ super()
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end