gerd 0.0.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 (43) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +3 -0
  3. data/.travis.yml +3 -0
  4. data/Gemfile +3 -0
  5. data/Gemfile.lock +115 -0
  6. data/Guardfile +43 -0
  7. data/README.md +83 -0
  8. data/Rakefile +11 -0
  9. data/bin/gerd +4 -0
  10. data/gerd.gemspec +33 -0
  11. data/lib/gerd.rb +6 -0
  12. data/lib/gerd/audit/audit.rb +79 -0
  13. data/lib/gerd/audit/builders.rb +0 -0
  14. data/lib/gerd/cli.rb +74 -0
  15. data/lib/gerd/exceptions.rb +16 -0
  16. data/lib/gerd/formatters.rb +39 -0
  17. data/lib/gerd/github_client.rb +35 -0
  18. data/lib/gerd/inspections/actions/change_repo_privacy.rb +16 -0
  19. data/lib/gerd/inspections/actions/create_repo.rb +26 -0
  20. data/lib/gerd/inspections/actions/create_team.rb +31 -0
  21. data/lib/gerd/inspections/actions/delete_repo.rb +29 -0
  22. data/lib/gerd/inspections/actions/delete_team.rb +19 -0
  23. data/lib/gerd/inspections/actions/update_name_action.rb +19 -0
  24. data/lib/gerd/inspections/diff.rb +17 -0
  25. data/lib/gerd/inspections/diffs/organisation.rb +89 -0
  26. data/lib/gerd/inspections/diffs/repositories.rb +94 -0
  27. data/lib/gerd/invoke.rb +18 -0
  28. data/lib/gerd/model/members.rb +0 -0
  29. data/lib/gerd/model/model.rb +95 -0
  30. data/lib/gerd/model/organisation.rb +0 -0
  31. data/lib/gerd/model/repositories.rb +0 -0
  32. data/lib/gerd/model/teams.rb +0 -0
  33. data/lib/gerd/validation/organisations/apply.rb +0 -0
  34. data/lib/gerd/validation/organisations/diff.rb +0 -0
  35. data/lib/gerd/validation/organisations/introspect.rb +0 -0
  36. data/lib/gerd/validators.rb +55 -0
  37. data/lib/gerd/version.rb +4 -0
  38. data/local.sh +10 -0
  39. data/spec/model_spec.rb +149 -0
  40. data/spec/organisation_spec.rb +76 -0
  41. data/spec/repositories_spec.rb +223 -0
  42. data/spec/spec_helper.rb +6 -0
  43. metadata +246 -0
@@ -0,0 +1,16 @@
1
+ module Gerd
2
+ module Exceptions
3
+
4
+ class ValidationException < StandardError
5
+
6
+ attr_reader :object
7
+
8
+ def initialize(object)
9
+ @object = object
10
+ end
11
+
12
+ end
13
+
14
+ end
15
+
16
+ end
@@ -0,0 +1,39 @@
1
+ require 'json'
2
+
3
+ module Gerd
4
+ module Formatters
5
+
6
+ def self.find_formatter(file)
7
+ return Gerd::Formatters::Stdout.new unless file
8
+ return Gerd::Formatters::FileFormatter.new(file)
9
+ end
10
+
11
+ class Stdout
12
+
13
+ def print(hash, options = {})
14
+ puts JSON.pretty_generate(hash)
15
+ end
16
+
17
+ end
18
+
19
+ class FileFormatter
20
+
21
+ def initialize(file)
22
+ @file = file
23
+ end
24
+
25
+ def print(hash, options = {})
26
+
27
+ if(File.exists?(@file))
28
+ puts "The file #{@file} already exists. Use -o or --overwrite" unless options[:overwrite]
29
+ return unless options[:overwrite]
30
+ end
31
+ output_file = File.new(@file, "w")
32
+ content = JSON.pretty_generate(hash)
33
+ output_file.write(content)
34
+ end
35
+
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,35 @@
1
+ require 'octokit'
2
+ require 'octokit/repository'
3
+ require 'json'
4
+
5
+ module Gerd
6
+ class GHClient
7
+
8
+ def self.create(explicit_token)
9
+ Octokit.auto_paginate = true
10
+ token = explicit_token
11
+ token = ENV['GERD_TOKEN'] unless token
12
+ token = from_local unless token
13
+ token = from_global unless token
14
+ client = token ? Octokit::Client.new(:access_token => token) : client = Octokit::Client.new
15
+ client
16
+ end
17
+
18
+ def self.from_local()
19
+ file = File.join(Dir.pwd, ".gerd")
20
+ return unless File.exist?(file)
21
+ local_file = File.read(file)
22
+ grim_conf = JSON.parse(local_file)
23
+ grim_conf['token']
24
+ end
25
+
26
+ def self.from_global()
27
+ file = File.join(ENV['HOME'], ".gerd")
28
+ return unless File.exist?(file)
29
+ global_file = File.read(file)
30
+ grim_conf = JSON.parse(global_file)
31
+ grim_conf['token']
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,16 @@
1
+ module Gerd
2
+ module Inspections
3
+ module Actions
4
+
5
+ class ChangeRepoPrivacy
6
+
7
+ def initialize(repo_to_change, privacy_state)
8
+ @repo = repo_to_change
9
+ @privacy_state = privacy_state
10
+ end
11
+
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,26 @@
1
+ module Gerd
2
+ module Inspections
3
+ module Actions
4
+
5
+ class CreateRepo
6
+
7
+ def initialize(repo_to_create, org, privacy = false)
8
+ @org = org
9
+ @repo = repo_to_create
10
+ @privacy = privacy
11
+ end
12
+
13
+ def invoke(client, options = {})
14
+ puts "Creating #{@org}/#{@repo}"
15
+ opts = {
16
+ :organization => @org,
17
+ :private => @privacy
18
+ }
19
+ res = client.create_repo(@repo, { :organization => @org })
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,31 @@
1
+ module Gerd
2
+ module Inspections
3
+ module Actions
4
+
5
+ class CreateTeam
6
+
7
+ def initialize(team_name, organisation, team_opts)
8
+ @team_name = team_name
9
+ @org = organisation
10
+ @opts = team_opts
11
+ end
12
+
13
+ def invoke(client, options = {})
14
+ team_name = @team_name
15
+ description = @opts['description']
16
+ privacy = @opts['privacy']
17
+ repos = []
18
+ repos = @opts['repos'].collect { | repo | "#{@org}/#{repo}" } unless !@opts.has_key?('repos')
19
+ opts = {
20
+ :name => team_name,
21
+ :repo_names => repos,
22
+ :permission => 'admin'
23
+ }
24
+ client.create_team(@org, opts)
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,29 @@
1
+ module Gerd
2
+ module Inspections
3
+ module Actions
4
+
5
+ class DeleteRepo
6
+
7
+ def initialize(repo_to_delete, organisation)
8
+ @org = organisation
9
+ @repo = repo_to_delete
10
+ end
11
+
12
+ def invoke(client, options = {})
13
+ if !options[:delete]
14
+ puts "You must explicitly use the --delete option to delete repos"
15
+ return
16
+ end
17
+ opts = {
18
+ :organization => @org
19
+ }
20
+ repo_name = "#{@org}/#{@repo}"
21
+ puts "Deleting #{repo_name}"
22
+ client.delete_repository(repo_name, opts)
23
+ end
24
+
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,19 @@
1
+ module Gerd
2
+ module Inspections
3
+ module Actions
4
+
5
+ class DeleteTeam
6
+
7
+ def initialize(team)
8
+ @team_id = team[:id]
9
+ end
10
+
11
+ def invoke(client, options = {})
12
+ client.delete_team(@team_id)
13
+ end
14
+
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module Gerd
2
+ module Inspections
3
+ module Organisation
4
+ module Actions
5
+
6
+ class UpdateName
7
+
8
+ def initialize(expected, actual)
9
+ end
10
+
11
+ end
12
+
13
+ end
14
+
15
+ end
16
+
17
+ end
18
+
19
+ end
@@ -0,0 +1,17 @@
1
+ module Gerd
2
+ module Inspections
3
+
4
+ class Diff
5
+
6
+ attr_accessor :passed, :message, :actions
7
+
8
+ def initialize(state, message, actions = [])
9
+ @passed = state
10
+ @message = message
11
+ @actions = actions
12
+ end
13
+
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,89 @@
1
+ require 'gerd/inspections/actions/update_name_action'
2
+ require 'gerd/inspections/actions/create_team'
3
+ require 'gerd/inspections/actions/delete_team'
4
+
5
+ module Gerd
6
+ module Inspections
7
+
8
+ module Organisation
9
+
10
+ def self.inspect_organisations(expected, actual)
11
+ if expected.organisation == actual.organisation
12
+ return Gerd::Inspections::Organisation::Diff.new(true, "Organisations match")
13
+ else
14
+ action = Gerd::Inspections::Organisation::Actions::UpdateName.new(expected, actual)
15
+ return Gerd::Inspections::Organisation::Diff.new(
16
+ false, "Expected #{expected.organisation} but found #{actual.organisation}",
17
+ [action]
18
+ )
19
+ end
20
+ end
21
+
22
+ def self.inspect_teams(expected, actual)
23
+ diffs = []
24
+
25
+ diffs << inspect_expected_teams_exist(expected, actual)
26
+
27
+ diffs << inspect_no_extra_teams_exist(expected, actual)
28
+
29
+ diffs.flatten
30
+ end
31
+
32
+ def self.inspect_expected_teams_exist(expected, actual)
33
+
34
+ diffs = []
35
+
36
+ expected_teams = expected.teams
37
+ actual_teams = actual.teams
38
+
39
+ expected_teams.keys.each do | expected_team |
40
+ if !actual_teams.keys.include? expected_team
41
+ team_to_create = expected_teams[expected_team]
42
+ action = Gerd::Inspections::Actions::CreateTeam.new(expected_team, expected.organisation, team_to_create)
43
+ diffs << Gerd::Inspections::Diff.new(false, "I expected to see team #{expected_team} but did not", [action])
44
+ end
45
+
46
+ end
47
+
48
+ diffs.flatten
49
+
50
+ end
51
+
52
+ def self.inspect_no_extra_teams_exist(expected, actual)
53
+
54
+ diffs = []
55
+
56
+ expected_teams = expected.teams
57
+ actual_teams = actual.teams
58
+
59
+ actual_teams.keys.each do | team |
60
+
61
+ if !expected_teams.keys.include? team
62
+
63
+ action = Gerd::Inspections::Actions::DeleteTeam.new(actual_teams[team])
64
+ diffs << Gerd::Inspections::Diff.new(false, "I did not expect to see team #{team} but saw it anyway", [action])
65
+ end
66
+
67
+ end
68
+
69
+ diffs
70
+
71
+ end
72
+
73
+ class Diff
74
+
75
+ attr_accessor :passed, :message, :actions
76
+
77
+ def initialize(state, message, actions = [])
78
+ @passed = state
79
+ @message = message
80
+ @actions = actions
81
+ end
82
+
83
+ end
84
+
85
+ end
86
+
87
+ end
88
+
89
+ end
@@ -0,0 +1,94 @@
1
+ require 'gerd/inspections/diff'
2
+ require 'gerd/inspections/actions/create_repo'
3
+ require 'gerd/inspections/actions/delete_repo'
4
+ require 'gerd/inspections/actions/change_repo_privacy'
5
+
6
+ module Gerd
7
+ module Inspections
8
+
9
+ module Repositories
10
+
11
+ def self.inspect_repositories(expected, actual)
12
+
13
+ diffs = []
14
+
15
+ diffs << inspect_required_repos_exist(expected, actual)
16
+
17
+ diffs << inspect_no_extra_repos_exist(expected, actual)
18
+
19
+ diffs << inspect_repo_privacy(expected, actual)
20
+
21
+ diffs.flatten
22
+
23
+ end
24
+
25
+ def self.inspect_required_repos_exist(expected, actual)
26
+
27
+ diffs = []
28
+
29
+ expected_repos = expected.repositories
30
+ actual_repos= actual.repositories
31
+
32
+ expected_repos.keys.each do | expected_repo |
33
+ if !actual_repos.keys.include? expected_repo
34
+ repo_to_create = expected_repos[expected_repo]
35
+ privacy = repo_to_create['privacy']
36
+ action = Gerd::Inspections::Actions::CreateRepo.new(expected_repo, expected.organisation, privacy)
37
+ diffs << Gerd::Inspections::Diff.new(false, "I expected to see repository #{expected_repo} but did not", [action])
38
+ end
39
+
40
+ end
41
+
42
+ diffs
43
+
44
+ end
45
+
46
+ def self.inspect_no_extra_repos_exist(expected, actual)
47
+
48
+ diffs = []
49
+
50
+ expected_repos = expected.repositories
51
+ actual_repos= actual.repositories
52
+
53
+ actual_repos.keys.each do | repo |
54
+
55
+ if !expected_repos.keys.include? repo
56
+ action = Gerd::Inspections::Actions::DeleteRepo.new(repo, expected.organisation)
57
+ diffs << Gerd::Inspections::Diff.new(false, "I did not expect to see repository #{repo} but saw it anyway", [action])
58
+ end
59
+
60
+ end
61
+
62
+ diffs
63
+
64
+ end
65
+
66
+ def self.inspect_repo_privacy(expected, actual)
67
+
68
+ diffs = []
69
+
70
+ expected_repos = expected.repositories
71
+ actual_repos= actual.repositories
72
+
73
+ expected_repos.each do | repo_name, expected_repo |
74
+ actual_repo = actual_repos[repo_name]
75
+ next if !actual_repo
76
+ if expected_repo['private'] == true && actual_repo['private'] == false
77
+ action = Gerd::Inspections::Actions::ChangeRepoPrivacy.new(actual_repo, true)
78
+ diffs << Gerd::Inspections::Diff.new(false, "I expected repo #{repo_name} to be private, but it is not", [action])
79
+ end
80
+ if expected_repo['private'] == false && actual_repo['private'] == true
81
+ action = Gerd::Inspections::Actions::ChangeRepoPrivacy.new(actual_repo, false)
82
+ diffs << Gerd::Inspections::Diff.new(false, "I did not expect repo #{repo_name} to be private, but it is", [action])
83
+ end
84
+ end
85
+
86
+ diffs
87
+
88
+ end
89
+
90
+ end
91
+
92
+ end
93
+
94
+ end