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,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+
5
+ require_relative "list"
6
+ require_relative "audit"
7
+ require_relative "upsert"
8
+ require_relative "remove"
9
+ require_relative "../../sub_command_base"
10
+
11
+ module Neetob
12
+ class CLI
13
+ module Heroku
14
+ module ConfigVars
15
+ class Commands < SubCommandBase
16
+ desc "list", "List all the config variables in the Heroku apps"
17
+ option :apps, type: :array, aliases: :a, required: true, desc: "Heroku app names. Can be matched using the '*' wildcard. Example: \"neeto*\" \"neeto-cal-web-staging\""
18
+ option :keys, type: :array, desc: "Array of config vars that needs to be listed."
19
+ option :path, type: :string, desc: "The JSON file path which has config vars that needs to be listed"
20
+ def list
21
+ List.new(options[:apps], options[:keys], options[:path], options[:sandbox]).run
22
+ end
23
+
24
+ desc "audit", "Verify whether config vars set in Heroku apps matches against the conditions specified in JSON file."
25
+ option :apps, type: :array, aliases: :a, required: true, desc: "Heroku app names. Can be matched using the '*' wildcard. Example: \"neeto*\" \"neeto-cal-web-staging\""
26
+ option :path, type: :string, desc: "The JSON file path from which config vars will be compared"
27
+ def audit
28
+ Audit.new(options[:apps], options[:path], options[:sandbox]).run
29
+ end
30
+
31
+ desc "upsert", "Update and insert the config vars in Heroku apps"
32
+ option :apps, type: :array, aliases: :a, desc: "Heroku app names. Can be matched using the '*' wildcard. Example: \"neeto*\" \"neeto-cal-web-staging\""
33
+ option :path, type: :string, aliases: :p, desc: "The JSON file path from which config vars will be upserted"
34
+ option :path_with_project_keys, type: :string, desc: "The JSON file path with the project names as the key containing required config vars for each project."
35
+ def upsert
36
+ Upsert.new(options[:apps], options[:path], options[:path_with_project_keys], options[:sandbox]).run
37
+ end
38
+
39
+ desc "remove", "Remove the config vars from Heroku apps"
40
+ option :apps, type: :array, aliases: :a, required: true, desc: "Heroku app names. Can be matched using the '*' wildcard. Example: \"neeto*\" \"neeto-cal-web-staging\""
41
+ option :keys, type: :array, required: true, desc: "Array of config vars to be removed."
42
+ def remove
43
+ Remove.new(options[:apps], options[:keys], options[:sandbox]).run
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,56 @@
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 List < Base
10
+ attr_accessor :apps, :sandbox, :keys, :required_config_vars_file_path
11
+
12
+ def initialize(apps, keys = [], required_config_vars_file_path = "", sandbox = false)
13
+ super()
14
+ @apps = apps
15
+ @sandbox = sandbox
16
+ @keys = keys
17
+ @required_config_vars_file_path = required_config_vars_file_path
18
+ end
19
+
20
+ def run
21
+ matching_apps = find_all_matching_apps(apps, :heroku, sandbox)
22
+ matching_apps.each do |app|
23
+ ui.info("\n Config of #{app}\n")
24
+ config = `heroku config -a #{app} --json`
25
+ unless $?.success?
26
+ ui.error("There is a problem in accessing the app with name \"#{app}\" in your account.")
27
+ ui.error("Please check the specified app name and ensure you're authorized to view that app.")
28
+ next
29
+ end
30
+ table = Terminal::Table.new headings: table_columns, rows: filter_config(config)
31
+ ui.success(table)
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def table_columns
38
+ ["Key", "Value"]
39
+ end
40
+
41
+ def filter_config(config)
42
+ parsed_config = JSON.parse(config)
43
+ if keys.nil? && required_config_vars_file_path.nil?
44
+ return parsed_config
45
+ end
46
+
47
+ required_config = keys || read_json_file(required_config_vars_file_path)
48
+ required_config.map do |key|
49
+ [key, parsed_config[key]]
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,39 @@
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 Remove < Base
10
+ attr_accessor :apps, :keys, :sandbox
11
+
12
+ def initialize(apps, keys = [], sandbox = false)
13
+ super()
14
+ @apps = apps
15
+ @keys = keys
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
+
24
+ unless $?.success?
25
+ ui.error("There is a problem in accessing the app with name \"#{app}\" in your account.")
26
+ ui.error("Please check the specified app name and ensure you're authorized to view that app.")
27
+ next
28
+ end
29
+
30
+ keys.each do |key|
31
+ `heroku config:unset #{key} -a #{app}`
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,80 @@
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 Upsert < Base
10
+ attr_accessor :apps, :required_config_vars_json_file_path,
11
+ :required_config_vars_with_project_keys_json_file_path, :sandbox
12
+
13
+ def initialize(apps, required_config_vars_json_file_path,
14
+ required_config_vars_with_project_keys_json_file_path, sandbox = false)
15
+ super()
16
+ @apps = apps
17
+ @required_config_vars_json_file_path = required_config_vars_json_file_path
18
+ @required_config_vars_with_project_keys_json_file_path =
19
+ required_config_vars_with_project_keys_json_file_path
20
+ @sandbox = sandbox
21
+ end
22
+
23
+ def run
24
+ check_the_given_arguments
25
+ inform_about_current_working_mode(sandbox) if apps.nil?
26
+ apps_to_be_updated = apps.nil? ?
27
+ read_json_file(required_config_vars_with_project_keys_json_file_path) :
28
+ find_all_matching_apps(apps, :heroku, sandbox)
29
+ inform_about_default_config_vars_file
30
+
31
+ apps_to_be_updated.each do |app|
32
+ required_config = apps.nil? ? app[1] : read_json_file(required_config_vars_json_file_path || default_config_vars_upsert_file_path)
33
+ app = app[0] if apps.nil?
34
+
35
+ if apps.nil? && sandbox && app != "neeto-dummy"
36
+ ui.error("The \"#{app}\" app is not available in sandbox mode.")
37
+ next
38
+ end
39
+
40
+ upsert_config_variables(app, required_config)
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def upsert_config_variables(app, vars)
47
+ `heroku access -a #{app}`
48
+ unless $?.success?
49
+ ui.error("There is a problem in accessing the app with name \"#{app}\" in your account.")
50
+ ui.error("Please check the specified app name and ensure you're authorized to view that app.")
51
+ return
52
+ end
53
+
54
+ vars.each do |key, val|
55
+ `heroku config:set #{key}='#{val}' -a #{app}`
56
+ end
57
+ end
58
+
59
+ def check_the_given_arguments
60
+ if (!apps.nil? && !required_config_vars_with_project_keys_json_file_path.nil?) ||
61
+ (apps.nil? && required_config_vars_with_project_keys_json_file_path.nil?)
62
+ ui.error("Please provide either apps or path to the config file with project keys")
63
+ exit
64
+ end
65
+ end
66
+
67
+ def default_config_vars_upsert_file_path
68
+ File.expand_path("../../../../../data/config-vars-upsert.json", __dir__)
69
+ end
70
+
71
+ def inform_about_default_config_vars_file
72
+ if !apps.nil? && required_config_vars_with_project_keys_json_file_path.nil? && required_config_vars_json_file_path.nil?
73
+ ui.info("Upserting config vars from the \"neetob/data/config-vars-upsert.json\" file")
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../base"
4
+
5
+ module Neetob
6
+ class CLI
7
+ module Heroku
8
+ class Execute < Base
9
+ attr_accessor :apps, :command_to_execute, :should_run_in_rails_console, :sandbox
10
+
11
+ def initialize(apps, command_to_execute, should_run_in_rails_console = false, sandbox = false)
12
+ super()
13
+ @apps = apps
14
+ @command_to_execute = command_to_execute
15
+ @should_run_in_rails_console = should_run_in_rails_console
16
+ @sandbox = sandbox
17
+ end
18
+
19
+ def run
20
+ matching_apps = find_all_matching_apps(apps, :heroku, sandbox)
21
+ rails_runner_command = "heroku run rails runner '#{command_to_execute}'"
22
+ heroku_command = should_run_in_rails_console ? rails_runner_command : command_to_execute
23
+ matching_apps.each do |app|
24
+ ui.info("\n Working on #{app}\n")
25
+ output = `#{heroku_command} -a #{app}`
26
+ unless $?.success?
27
+ ui.error("There is a problem in accessing the app with name \"#{app}\" in your account.")
28
+ ui.error("Please check the specified app name and ensure you're authorized to view that app.")
29
+ next
30
+ end
31
+ ui.success(output)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+ require_relative "ls"
5
+
6
+ module Neetob
7
+ class CLI
8
+ module Local
9
+ class Commands < Thor
10
+ desc "ls", "List the files in local neeto repos"
11
+ option :apps, type: :array, aliases: "-a", required: true, desc: "Neeto app names. Can be matched using the '*' wildcard. Example: \"neeto*\" \"neeto-cal-web\""
12
+ option :dir, type: :string, aliases: "-d", desc: "Mention the directory you want to list"
13
+ def ls
14
+ Ls.new(options[:apps], options[:dir], options[:sandbox]).run
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../base"
4
+
5
+ module Neetob
6
+ class CLI
7
+ module Local
8
+ class Ls < Base
9
+ attr_accessor :sandbox, :apps, :dir
10
+
11
+ def initialize(apps, dir, sandbox = false)
12
+ super()
13
+ @apps = apps
14
+ @dir = dir
15
+ @sandbox = sandbox
16
+ end
17
+
18
+ def run
19
+ matching_apps = find_all_matching_apps(apps, :github, sandbox, true)
20
+ matching_apps.each do |app|
21
+ app_name = app.split("/")[1]
22
+ ui.info("\nListing files from #{app_name}/#{dir}\n")
23
+ ui.info(`cd ./#{app_name} && ls #{dir}`)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+
5
+ class SubCommandBase < Thor
6
+ def self.banner(command, namespace = nil, subcommand = false)
7
+ "#{basename} #{subcommand_prefix} #{command.usage}"
8
+ end
9
+
10
+ def self.subcommand_prefix
11
+ self.name
12
+ .split("::")[2..-2]
13
+ .map { |name| name.gsub(%r{^[A-Z]}) { |match| match[0].downcase } }
14
+ .map { |name| name.gsub(%r{[A-Z]}) { |match| "-#{match[0].downcase}" } }
15
+ .join(" ")
16
+ end
17
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ 4# frozen_string_literal: true
4
+
5
+ require "thor"
6
+
7
+ module Neetob
8
+ class CLI
9
+ class UI
10
+ attr_accessor :shell
11
+
12
+ def initialize
13
+ @shell = Thor::Base.shell.new
14
+ end
15
+
16
+ def say(statement, color = Thor::Shell::Color::YELLOW)
17
+ shell.say(statement, color)
18
+ end
19
+
20
+ def ask(question, echo = true)
21
+ shell.ask(question, echo: echo)
22
+ end
23
+
24
+ def yes?(question)
25
+ shell.yes?(question)
26
+ end
27
+
28
+ def error(statement)
29
+ shell.say(statement, Thor::Shell::Color::RED)
30
+ end
31
+
32
+ def success(statement)
33
+ shell.say(statement, Thor::Shell::Color::GREEN)
34
+ end
35
+
36
+ def info(statement)
37
+ shell.say(statement)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../base"
4
+
5
+ module Neetob
6
+ class CLI
7
+ module Users
8
+ class Audit < Base
9
+ attr_accessor :sandbox
10
+
11
+ def initialize(sandbox = false)
12
+ super()
13
+ @sandbox = sandbox
14
+ end
15
+
16
+ def run
17
+ users_data = users_for_all_available_apps
18
+ users = extract_values_from_user_data(users_data)
19
+ email_repos_map = create_email_repos_map(users)
20
+ unique_users = users.uniq { |user| [user[0], user[1]] }.sort
21
+ ui.info("\nUsers with multiple emails:")
22
+ find_users_with_multiple_emails(unique_users.transpose, email_repos_map)
23
+ ui.info("Users with emails having 3rd party domains:")
24
+ find_users_with_invalid_emails(unique_users.transpose, email_repos_map)
25
+ end
26
+
27
+ private
28
+
29
+ def users_for_all_available_apps
30
+ find_all_matching_apps(["*"], :github, sandbox, true).map do |app|
31
+ clone_repo_and_get_users(app).split("\n").map { |user| "#{user} #{app}" }
32
+ end
33
+ end
34
+
35
+ def extract_values_from_user_data(users)
36
+ users.flatten.map do |user|
37
+ values = user.strip.split(" ")[1..-1]
38
+ [values[0..-3].join(" "), clean_email(values[-2]), clean_repo_name(values[-1])]
39
+ end
40
+ end
41
+
42
+ def clone_repo_and_get_users(app)
43
+ app_name_without_org_suffix = app.split("/")[1]
44
+ `git -C ./#{app_name_without_org_suffix} shortlog -sne`
45
+ end
46
+
47
+ def create_email_repos_map(users)
48
+ map = {}
49
+ users.each do |user|
50
+ email = user[1]
51
+ repo = user[2]
52
+ map[email] = [] unless map.key?(email)
53
+ map[email].push(repo)
54
+ end
55
+ map
56
+ end
57
+
58
+ def find_users_with_multiple_emails(users, email_repos_map)
59
+ user_emails = {}
60
+ users[0].each_with_index do |name, index|
61
+ email = users[1][index]
62
+ user_emails[name] = [] unless user_emails.key?(name)
63
+ user_emails[name].push(email)
64
+ end
65
+ user_with_multiple_emails = user_emails.filter { |_, val| val.length > 1 }
66
+ table_rows = create_rows_and_add_repos(user_with_multiple_emails, email_repos_map)
67
+ create_and_show_table(table_rows, table_columns)
68
+ end
69
+
70
+ def find_users_with_invalid_emails(users, email_repos_map)
71
+ user_with_invalid_emails = {}
72
+ users[1].each_with_index do |email, index|
73
+ name = users[0][index]
74
+ if invalid_email?(email)
75
+ user_with_invalid_emails[name] = [] unless user_with_invalid_emails.key?(name)
76
+ user_with_invalid_emails[name].push(email)
77
+ end
78
+ end
79
+ table_rows = create_rows_and_add_repos(user_with_invalid_emails, email_repos_map)
80
+ create_and_show_table(table_rows, table_columns)
81
+ end
82
+
83
+ def table_columns
84
+ [:Name, :Email, :Repo]
85
+ end
86
+
87
+ def create_rows_and_add_repos(users, email_repos_map)
88
+ users.map do |name, emails|
89
+ repos = emails.map { |email| email_repos_map[email] }
90
+ [name, emails.join(", "), join_and_truncate_repos(repos)]
91
+ end
92
+ end
93
+
94
+ def create_and_show_table(data, column_names)
95
+ table = Terminal::Table.new headings: column_names, rows: data
96
+ ui.error(table)
97
+ end
98
+
99
+ def join_and_truncate_repos(repos)
100
+ repos.flatten.uniq.join(",").truncate(35)
101
+ end
102
+
103
+ def clean_email(email)
104
+ email.gsub(/<|>/, "")
105
+ end
106
+
107
+ def clean_repo_name(repo)
108
+ repo.gsub("bigbinary/", "")
109
+ end
110
+
111
+ def invalid_email?(email)
112
+ !allowed_email_domains.any? { |domain| email.downcase.include?(domain) }
113
+ end
114
+
115
+ def allowed_email_domains
116
+ ["github", "gmail", "bigbinary"]
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+ require_relative "audit"
5
+ require_relative "commits"
6
+
7
+ module Neetob
8
+ class CLI
9
+ module Users
10
+ class Commands < Thor
11
+ desc "audit", "Audit the users of all the neeto apps"
12
+ def audit
13
+ Audit.new(options[:sandbox]).run
14
+ end
15
+
16
+ desc "commits", "List the commits of a user across the neeto apps"
17
+ option :apps, type: :array, aliases: "-a", default: ["*"], desc: "Github app names. Can be matched using the '*' wildcard. Example: \"neeto*\" \"neeto-cal-web\""
18
+ option :author, type: :string, required: true, desc: "Github username of the person whose commits you want to list"
19
+ option :duration, type: :string, required: true, desc: "Duration for which you want to list the commits. Example: \"6.months\" \"10.days\""
20
+ def commits
21
+ Commits.new(
22
+ options[:author], options[:duration], options[:apps],
23
+ options[:sandbox]).run
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,125 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../base"
4
+
5
+ module Neetob
6
+ class CLI
7
+ module Users
8
+ class Commits < Base
9
+ attr_accessor :sandbox, :apps, :author, :duration
10
+
11
+ def initialize(author, duration, apps = ["*"], sandbox = false)
12
+ super()
13
+ @sandbox = sandbox
14
+ @apps = apps
15
+ @author = author
16
+ @duration = duration
17
+ end
18
+
19
+ def run
20
+ table_rows = build_commit_rows
21
+ html_content = build_html_content(table_rows)
22
+ create_html_file(html_content)
23
+ open_html_file_in_default_system_application
24
+ end
25
+
26
+ private
27
+
28
+ def build_commit_rows
29
+ find_all_matching_apps(apps, :github, sandbox, true).map do |app|
30
+ commits = commits_within_range(app)
31
+ if commits.empty?
32
+ ui.error("No commits found in \"#{app}\" for the given author and duration.")
33
+ next
34
+ end
35
+
36
+ build_table_rows(app, commits)
37
+ end
38
+ end
39
+
40
+ def commits_within_range(app)
41
+ `git -C ./#{app_name_without_org_suffix(app)} log --pretty=format:"%H:::%ae:::%ar:::%s" --author=#{author} --since=#{duration} --no-merges`
42
+ end
43
+
44
+ def build_table_rows(app, commits)
45
+ commits.split("\n").map { |commit| html_table_row(app, *commit.split(":::")) }
46
+ end
47
+
48
+ def app_name_without_org_suffix(app)
49
+ app.split("/")[1]
50
+ end
51
+
52
+ def html_table_row(app, commit, email, time, title)
53
+ starting_7_characters_of_commit = commit[0..6]
54
+ "<tr>
55
+ <td class='commit'><a href='https://github.com/#{app}/commit/#{commit}'
56
+ target='_blank'>#{starting_7_characters_of_commit}</a></td>
57
+ <td class='project'>#{app_name_without_org_suffix(app)}</td>
58
+ <td class='email'>#{email}</td>
59
+ <td class='time'>#{time}</td>
60
+ <td class='title'>#{title}</td>
61
+ </tr>"
62
+ end
63
+
64
+ def build_html_content(table_rows)
65
+ "<!DOCTYPE html>
66
+ <html>
67
+ <body>
68
+ <style>
69
+ table {
70
+ font-family: arial, sans-serif;
71
+ border-collapse: collapse;
72
+ width: 100%;
73
+ }
74
+ td, th {
75
+ border: 1px solid #dddddd;
76
+ text-align: left;
77
+ padding: 8px;
78
+ }
79
+ tr:nth-child(even) {
80
+ background-color: #dddddd;
81
+ }
82
+ .project {
83
+ color: blue;
84
+ }
85
+ .commit {
86
+ color: blueviolet;
87
+ }
88
+ .email {
89
+ color: green;
90
+ width: 50px;
91
+ }
92
+ .time {
93
+ color: darkorange;
94
+ }
95
+ .title {
96
+ color: lightcoral
97
+ }
98
+ </style>
99
+ <table>
100
+ <tr>
101
+ <th>Commit</th>
102
+ <th>Product</th>
103
+ <th>Email</th>
104
+ <th>Created at</th>
105
+ <th>Title</th>
106
+ </tr>
107
+ #{table_rows.empty? ? "<tr><td>No commits found in the given duration</td></tr>" : table_rows.join}
108
+ </table>
109
+ </body>
110
+ </html>"
111
+ end
112
+
113
+ def create_html_file(html_content)
114
+ commits_file = File.new("commits.html", "w")
115
+ commits_file.puts(html_content)
116
+ commits_file.close
117
+ end
118
+
119
+ def open_html_file_in_default_system_application
120
+ `open ./commits.html`
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
data/lib/neetob/cli.rb ADDED
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+
5
+ module Neetob
6
+ class CLI < Thor
7
+ require_relative "cli/heroku/commands"
8
+ require_relative "cli/github/commands"
9
+ require_relative "cli/users/commands"
10
+ require_relative "cli/fetchorupdate_repos/execute"
11
+ require_relative "cli/local/commands"
12
+
13
+ class_option :sandbox,
14
+ {
15
+ type: :boolean, default: false,
16
+ desc: "All the commands in sandbox mode will run only on the \"neeto-dummy\" app."
17
+ }
18
+
19
+ def self.start(*)
20
+ super
21
+ end
22
+
23
+ desc "heroku", "Interact with any resource in Heroku"
24
+ subcommand "heroku", Heroku::Commands
25
+
26
+ desc "github", "Interact with any resource in Github"
27
+ subcommand "github", Github::Commands
28
+
29
+ desc "users", "Interact with the contributors of neeto apps"
30
+ subcommand "users", Users::Commands
31
+
32
+ desc "local", "Interact with the local neeto repos"
33
+ subcommand "local", Local::Commands
34
+
35
+ desc "make_repos_uptodate", "Uptodate all neeto repos"
36
+ def make_repos_uptodate
37
+ FetchorupdateRepos::Execute.new(options[:sandbox]).run
38
+ end
39
+ end
40
+ end