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,18 @@
1
+ module Gerd
2
+ module Helpers
3
+
4
+ class Exec
5
+
6
+ def initialize(script)
7
+ @script = script
8
+ end
9
+
10
+ def exec(model)
11
+ eval @script
12
+ invoke_script(model)
13
+ end
14
+
15
+ end
16
+
17
+ end
18
+ end
File without changes
@@ -0,0 +1,95 @@
1
+ require 'json'
2
+ require 'gerd/exceptions'
3
+
4
+ module Gerd
5
+ module Model
6
+
7
+ class GithubState
8
+
9
+ attr_accessor :organisation, :teams, :members, :repositories, :failures
10
+
11
+ def self.from_json(json)
12
+ begin
13
+ return Gerd::Model::GithubState.new(JSON.parse(json))
14
+ rescue => e
15
+ puts json
16
+ raise Gerd::Exceptions::ValidationException.new("Couldn't parse JSON")
17
+ end
18
+
19
+ end
20
+
21
+ def initialize(state_content)
22
+
23
+ validators = []
24
+ validators << Gerd::Model::SchemaValidator.new( Proc.new { | data | data['organisation'] != nil }, "Should have an organisation present")
25
+ validators << Gerd::Model::SchemaValidator.new( Proc.new { | data | data['teams'].class == Hash }, "Should have a teams element present")
26
+ validators << Gerd::Model::SchemaValidator.new( Proc.new { | data | data['repositories'].class == Hash }, "Should have a repositories element present")
27
+ validators << Gerd::Model::SchemaValidator.new( Proc.new { | data | data['members'].class == Hash }, "Should have a members element present")
28
+ failures = []
29
+ validators.each do | validator |
30
+ result = validator.evaluate(state_content)
31
+ failures << result unless result.valid?
32
+ end
33
+
34
+ @failures = failures
35
+ if failures.length != 0
36
+ failures.each do | failure |
37
+ puts failure.message
38
+ end
39
+ puts state_content
40
+ raise Gerd::Exceptions::ValidationException.new("Failed to validate #{failures}")
41
+ end
42
+
43
+ @organisation = state_content['organisation']
44
+ @teams = state_content['teams']
45
+ @members = state_content['members']
46
+ @repositories = state_content['repositories']
47
+
48
+ end
49
+
50
+ def serialize
51
+ json = { 'organisation' => @organisation,
52
+ 'teams' => @teams,
53
+ 'members' => @members,
54
+ 'repositories' => @repositories
55
+ }
56
+ json
57
+ end
58
+
59
+ end
60
+
61
+ class SchemaValidator
62
+
63
+ def initialize(expression, message)
64
+ @expression = expression
65
+ @message = message
66
+ end
67
+
68
+ def evaluate(content)
69
+ res = @expression.call(content)
70
+ Gerd::Model::ValidationResult.new(res, @message)
71
+ end
72
+
73
+ end
74
+
75
+ class ValidationResult
76
+
77
+ attr_accessor :message
78
+
79
+ def initialize(result, message)
80
+ @result = result
81
+ @message = message
82
+ end
83
+
84
+ def valid?
85
+ @result
86
+ end
87
+
88
+ def to_s
89
+ puts @message
90
+ end
91
+
92
+ end
93
+
94
+ end
95
+ end
File without changes
File without changes
File without changes
@@ -0,0 +1,55 @@
1
+ require 'gerd/model/model'
2
+ require 'gerd/inspections/diffs/organisation'
3
+ require 'gerd/inspections/diffs/repositories'
4
+
5
+ module Gerd
6
+ module Validation
7
+
8
+ class Diff
9
+
10
+ def initialize(expression, name)
11
+ @expression = expression
12
+ @name = name
13
+ end
14
+
15
+ def validate(expected, actual)
16
+ puts expected
17
+ res = @expression.call(expected, actual)
18
+ res ? "#{@name} passed" : "#{@name} failed"
19
+ end
20
+
21
+ end
22
+
23
+ StandardDiffs =[
24
+ Gerd::Validation::Diff.new( Proc.new { | e, a | e.organisation == a.organisation}, "Organisations"),
25
+ ]
26
+
27
+
28
+ class Validator
29
+
30
+ def initialize(expected_state, actual_state)
31
+ @expected = expected_state
32
+ @actual = actual_state
33
+ end
34
+
35
+ def validate
36
+ validation_result = []
37
+ validation_result << Gerd::Inspections::Organisation.inspect_organisations(@expected, @actual)
38
+ validation_result << Gerd::Inspections::Repositories.inspect_repositories(@expected, @actual)
39
+ validation_result << Gerd::Inspections::Organisation.inspect_teams(@expected, @actual)
40
+ report = validation_result.flatten.collect { | res | res.message }
41
+ report
42
+ end
43
+
44
+ def collect_actions
45
+ actions = []
46
+ actions << Gerd::Inspections::Organisation.inspect_organisations(@expected, @actual)
47
+ actions << Gerd::Inspections::Repositories.inspect_repositories(@expected, @actual)
48
+ actions << Gerd::Inspections::Organisation.inspect_teams(@expected, @actual)
49
+ actions.flatten.collect { | res | res.actions }
50
+ end
51
+ end
52
+
53
+ end
54
+
55
+ end
@@ -0,0 +1,4 @@
1
+
2
+ module Gerd
3
+ VERSION = "0.0.1"
4
+ end
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env bash
2
+
3
+ ###########
4
+ ##
5
+ ## Source this to set up the ability to use the gem locally without installing during dev
6
+ ##
7
+ ##########
8
+
9
+ export RUBYLIB="${PWD}/lib:$RUBYLIB"
10
+ export PATH="$PATH:${PWD}/bin"
@@ -0,0 +1,149 @@
1
+ require 'spec_helper'
2
+ require 'gerd/model/model'
3
+ require 'gerd/exceptions'
4
+
5
+ describe Gerd::Model::GithubState do
6
+
7
+ context "validation" do
8
+
9
+ it "should validate good json" do
10
+
11
+ content = load_fixture('good_state.json')
12
+
13
+ state = Gerd::Model::GithubState.from_json(content)
14
+
15
+ end
16
+
17
+ it "Should pull out the organisation" do
18
+
19
+ content = load_fixture('good_state.json')
20
+
21
+ state = Gerd::Model::GithubState.from_json(content)
22
+
23
+ expect(state.organisation).to eq "Elevenware"
24
+
25
+ end
26
+
27
+ it "Should have two teams" do
28
+
29
+ content = load_fixture('good_state.json')
30
+
31
+ state = Gerd::Model::GithubState.from_json(content)
32
+
33
+ expect(state.teams.length).to eq 2
34
+
35
+ end
36
+
37
+ it "Should have three members" do
38
+
39
+ content = load_fixture('good_state.json')
40
+
41
+ state = Gerd::Model::GithubState.from_json(content)
42
+
43
+ expect(state.members.length).to eq 3
44
+
45
+ end
46
+
47
+ it "Should have seven repositories" do
48
+
49
+ content = load_fixture('good_state.json')
50
+
51
+ state = Gerd::Model::GithubState.from_json(content)
52
+
53
+ expect(state.repositories.length).to eq 7
54
+
55
+ end
56
+
57
+ it "should not validate malformed json" do
58
+
59
+ content = "{"
60
+
61
+ expect {Gerd::Model::GithubState.from_json(content) }.to raise_error Gerd::Exceptions::ValidationException
62
+
63
+ end
64
+
65
+ it "should not validate if no organisation is present" do
66
+ content = {
67
+ "teams" => {},
68
+ "repositories" => {},
69
+ "members" => {}
70
+ }
71
+
72
+
73
+ expect {Gerd::Model::GithubState.new(content) }.to raise_error Gerd::Exceptions::ValidationException
74
+
75
+
76
+ end
77
+
78
+ it "should not validate if no team element is present" do
79
+ content = {
80
+ "organisation" => "test",
81
+ "repositories" => {},
82
+ "members" => {}
83
+ }
84
+
85
+ expect {Gerd::Model::GithubState.new(content) }.to raise_error Gerd::Exceptions::ValidationException
86
+
87
+ end
88
+
89
+ it "should not validate if the team element is not an object" do
90
+ content = {
91
+ "organisation" => "test",
92
+ "teams" => "a string",
93
+ "repositories" => {},
94
+ "members" => {}
95
+ }
96
+
97
+ expect {Gerd::Model::GithubState.new(content) }.to raise_error Gerd::Exceptions::ValidationException
98
+
99
+ end
100
+
101
+ it "should not validate if no repositories element is present" do
102
+ content = {
103
+ "organisation" => "test",
104
+ "teams" => {},
105
+ "members" => {}
106
+ }
107
+
108
+ expect {Gerd::Model::GithubState.new(content) }.to raise_error Gerd::Exceptions::ValidationException
109
+
110
+ end
111
+
112
+ it "should not validate if the repositories element is not an object" do
113
+ content = {
114
+ "organisation" => "test",
115
+ "teams" => {},
116
+ "repositories" => "dve",
117
+ "members" => {}
118
+ }
119
+
120
+ expect {Gerd::Model::GithubState.new(content) }.to raise_error Gerd::Exceptions::ValidationException
121
+
122
+ end
123
+
124
+ it "should not validate if no members element is present" do
125
+ content = {
126
+ "organisation" => "test",
127
+ "teams" => {},
128
+ "repositories" => {}
129
+ }
130
+
131
+ expect {Gerd::Model::GithubState.new(content) }.to raise_error Gerd::Exceptions::ValidationException
132
+
133
+ end
134
+
135
+ it "should not validate if the members element is not an object" do
136
+ content = {
137
+ "organisation" => "test",
138
+ "teams" => {},
139
+ "repositories" => {},
140
+ "members" => ""
141
+ }
142
+
143
+ expect {Gerd::Model::GithubState.new(content) }.to raise_error Gerd::Exceptions::ValidationException
144
+
145
+ end
146
+
147
+ end
148
+
149
+ end
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+ require 'gerd/model/model'
3
+ require 'gerd/inspections/diffs/organisation'
4
+
5
+
6
+ describe "organisation diff" do
7
+
8
+ context "states match" do
9
+
10
+ expected = Gerd::Model::GithubState.new(
11
+ {
12
+ "organisation" => "Test organisation",
13
+ "teams" => {},
14
+ "members" => {},
15
+ "repositories" => {}
16
+ })
17
+
18
+ actual = Gerd::Model::GithubState.new(
19
+ {
20
+ "organisation" => "Test organisation",
21
+ "teams" => {},
22
+ "members" => {},
23
+ "repositories" => {}
24
+ })
25
+
26
+ diff = Gerd::Inspections::Organisation::inspect_organisations(expected, actual)
27
+
28
+ it "should spot same organisations" do
29
+
30
+ expect(diff.passed).to be true
31
+
32
+ end
33
+
34
+ it "should give us no actions" do
35
+
36
+ expect(diff.actions.length).to be 0
37
+
38
+ end
39
+
40
+ end
41
+
42
+ context "states do not match" do
43
+
44
+ expected = Gerd::Model::GithubState.new(
45
+ {
46
+ "organisation" => "Test organisation",
47
+ "teams" => {},
48
+ "members" => {},
49
+ "repositories" => {}
50
+ })
51
+
52
+ actual = Gerd::Model::GithubState.new(
53
+ {
54
+ "organisation" => "Other organisation",
55
+ "teams" => {},
56
+ "members" => {},
57
+ "repositories" => {}
58
+ })
59
+
60
+ diff = Gerd::Inspections::Organisation::inspect_organisations(expected, actual)
61
+
62
+ it "should spot different organisations" do
63
+
64
+ expect(diff.passed).to be false
65
+
66
+ end
67
+
68
+ it "should give us a name change action" do
69
+
70
+ expect(diff.actions.length).to be 1
71
+
72
+ end
73
+
74
+ end
75
+
76
+ end
@@ -0,0 +1,223 @@
1
+ require 'spec_helper'
2
+ require 'gerd/model/model'
3
+ require 'gerd/inspections/diffs/repositories'
4
+
5
+ describe 'repositories inspection' do
6
+
7
+ context 'repositories match' do
8
+
9
+ expected = Gerd::Model::GithubState.new(
10
+ {
11
+ "organisation" => "Test organisation",
12
+ "teams" => {},
13
+ "members" => {},
14
+ "repositories" => {
15
+ "foo" => {
16
+ "private" => false
17
+ },
18
+ "bar" => {
19
+ "private" => false
20
+ }
21
+ }
22
+ })
23
+
24
+ actual = Gerd::Model::GithubState.new(
25
+ {
26
+ "organisation" => "Test organisation",
27
+ "teams" => {},
28
+ "members" => {},
29
+ "repositories" => {
30
+ "foo" => {
31
+ "private" => false
32
+ },
33
+ "bar" => {
34
+ "private" => false
35
+ }
36
+ }
37
+ })
38
+
39
+ diffs = Gerd::Inspections::Repositories::inspect_repositories(expected, actual)
40
+
41
+ it "should give me 0 diffs" do
42
+
43
+ expect(diffs.length).to be 0
44
+
45
+ end
46
+
47
+ end
48
+
49
+ context 'missing repository' do
50
+
51
+ expected = Gerd::Model::GithubState.new(
52
+ {
53
+ "organisation" => "Test organisation",
54
+ "teams" => {},
55
+ "members" => {},
56
+ "repositories" => {
57
+ "foo" => {
58
+ "private" => false
59
+ },
60
+ "bar" => {
61
+ "private" => false
62
+ }
63
+ }
64
+ })
65
+
66
+ actual = Gerd::Model::GithubState.new(
67
+ {
68
+ "organisation" => "Test organisation",
69
+ "teams" => {},
70
+ "members" => {},
71
+ "repositories" => {
72
+ "foo" => {
73
+ "private" => false
74
+ }
75
+ }
76
+ })
77
+
78
+ diffs = Gerd::Inspections::Repositories::inspect_repositories(expected, actual)
79
+
80
+ it "should give me 1 diff" do
81
+
82
+ expect(diffs.length).to be 1
83
+
84
+ expect(diffs[0].message).to eq "I expected to see repository bar but did not"
85
+
86
+ expect(diffs[0].actions.length).to be 1
87
+
88
+ expect(diffs[0].actions[0].class).to be Gerd::Inspections::Actions::CreateRepo
89
+
90
+ end
91
+
92
+ end
93
+
94
+ context 'extra repository' do
95
+
96
+ expected = Gerd::Model::GithubState.new(
97
+ {
98
+ "organisation" => "Test organisation",
99
+ "teams" => {},
100
+ "members" => {},
101
+ "repositories" => {
102
+ "foo" => {
103
+ "private" => false
104
+ }
105
+ }
106
+ })
107
+
108
+ actual = Gerd::Model::GithubState.new(
109
+ {
110
+ "organisation" => "Test organisation",
111
+ "teams" => {},
112
+ "members" => {},
113
+ "repositories" => {
114
+ "foo" => {
115
+ "private" => false
116
+ },
117
+ "bar" => {
118
+ "private" => false
119
+ }
120
+ }
121
+ })
122
+
123
+ diffs = Gerd::Inspections::Repositories::inspect_repositories(expected, actual)
124
+
125
+ it "should give me 1 diff" do
126
+
127
+ expect(diffs.length).to be 1
128
+
129
+ expect(diffs[0].message).to eq "I did not expect to see repository bar but saw it anyway"
130
+
131
+ expect(diffs[0].actions.length).to be 1
132
+
133
+ expect(diffs[0].actions[0].class).to be Gerd::Inspections::Actions::DeleteRepo
134
+
135
+ end
136
+
137
+ end
138
+
139
+ context 'repository should be private' do
140
+
141
+ expected = Gerd::Model::GithubState.new(
142
+ {
143
+ "organisation" => "Test organisation",
144
+ "teams" => {},
145
+ "members" => {},
146
+ "repositories" => {
147
+ "foo" => {
148
+ "private" => true
149
+ }
150
+ }
151
+ })
152
+
153
+ actual = Gerd::Model::GithubState.new(
154
+ {
155
+ "organisation" => "Test organisation",
156
+ "teams" => {},
157
+ "members" => {},
158
+ "repositories" => {
159
+ "foo" => {
160
+ "private" => false
161
+ }
162
+ }
163
+ })
164
+
165
+ diffs = Gerd::Inspections::Repositories::inspect_repositories(expected, actual)
166
+
167
+ it "should give me 1 diff" do
168
+
169
+ expect(diffs.length).to be 1
170
+
171
+ expect(diffs[0].message).to eq "I expected repo foo to be private, but it is not"
172
+
173
+ expect(diffs[0].actions.length).to be 1
174
+
175
+ expect(diffs[0].actions[0].class).to be Gerd::Inspections::Actions::ChangeRepoPrivacy
176
+
177
+ end
178
+
179
+ end
180
+
181
+ context 'repository should be public' do
182
+
183
+ expected = Gerd::Model::GithubState.new(
184
+ {
185
+ "organisation" => "Test organisation",
186
+ "teams" => {},
187
+ "members" => {},
188
+ "repositories" => {
189
+ "foo" => {
190
+ "private" => false
191
+ }
192
+ }
193
+ })
194
+
195
+ actual = Gerd::Model::GithubState.new(
196
+ {
197
+ "organisation" => "Test organisation",
198
+ "teams" => {},
199
+ "members" => {},
200
+ "repositories" => {
201
+ "foo" => {
202
+ "private" => true
203
+ }
204
+ }
205
+ })
206
+
207
+ diffs = Gerd::Inspections::Repositories::inspect_repositories(expected, actual)
208
+
209
+ it "should give me 1 diff" do
210
+
211
+ expect(diffs.length).to be 1
212
+
213
+ expect(diffs[0].message).to eq "I did not expect repo foo to be private, but it is"
214
+
215
+ expect(diffs[0].actions.length).to be 1
216
+
217
+ expect(diffs[0].actions[0].class).to be Gerd::Inspections::Actions::ChangeRepoPrivacy
218
+
219
+ end
220
+
221
+ end
222
+
223
+ end