gerd 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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