hu 1.0.5 → 1.1.0
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.
- checksums.yaml +4 -4
- data/lib/hu/collab.rb +77 -47
- data/lib/hu/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 003507bbb3db74b361b601858c57fcd190ab5ba9
|
4
|
+
data.tar.gz: dd11b4e74533f76d52deeb4149c1a3dce3a25b28
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5de31ef9ff0d7e535ea0ea2f129564c9c8fc43721468ef71149c06df1f8c12bdfec4d8580c111d398cff96e0cec46e40f3bd87928c9ca58bf41f8fd3d58ad88c
|
7
|
+
data.tar.gz: 73d37b7cd37e63e0d395657e6fb200db2987f4551fc8c72fb6c0accc275411373cc3163d36af617943f9baf411a6e4b2d36aae404a7a983d91b02b8732eed223
|
data/lib/hu/collab.rb
CHANGED
@@ -7,6 +7,15 @@ require 'platform-api'
|
|
7
7
|
module Hu
|
8
8
|
class Cli < Optix::Cli
|
9
9
|
class Collab < Optix::Cli
|
10
|
+
class InvalidOperation < StandardError; end
|
11
|
+
class InvalidPlan < StandardError
|
12
|
+
attr_accessor :invalid_plan
|
13
|
+
|
14
|
+
def initialize(message=nil, invalid_plan=nil)
|
15
|
+
super(message)
|
16
|
+
self.invalid_plan = invalid_plan
|
17
|
+
end
|
18
|
+
end
|
10
19
|
|
11
20
|
text "Manage application/collaborator mapping."
|
12
21
|
text ""
|
@@ -15,23 +24,11 @@ module Hu
|
|
15
24
|
text ""
|
16
25
|
text "WARNING: If you remove yourself from an application"
|
17
26
|
text " then hu won't be able to see it anymore."
|
18
|
-
text ""
|
19
|
-
text "Please note that hu can only operate on applications and"
|
20
|
-
text "collaborators that it sees. It will stubbornly refuse to"
|
21
|
-
text "create new applications or collaborators."
|
22
|
-
text ""
|
23
|
-
text "Follow this procedure to introduce a new collaborator:"
|
24
|
-
text ""
|
25
|
-
text "1. Create collaborator on heroku (via web or toolbelt)"
|
26
|
-
text "2. Add them to at least one application that you have access to"
|
27
|
-
text ""
|
28
|
-
text "Now the new collaborator will show up in 'export'"
|
29
|
-
text "and may be assigned to applications."
|
30
27
|
def collab; end
|
31
28
|
|
32
29
|
OP_COLORS = {
|
33
30
|
'+' => "\e[0;1;32m",
|
34
|
-
'-' => "\e[0;1;
|
31
|
+
'-' => "\e[0;1;34m",
|
35
32
|
'~' => "\e[0;32m",
|
36
33
|
}
|
37
34
|
desc "Read mapping from stdin and diff to heroku state"
|
@@ -39,14 +36,26 @@ module Hu
|
|
39
36
|
parent "collab"
|
40
37
|
def diff(cmd, opts, argv)
|
41
38
|
parsed_state = parse_as_json_or_yaml(STDIN.read)
|
42
|
-
plan(HashDiff.diff(heroku_state['apps'], parsed_state['apps']))
|
39
|
+
show_plan( plan(HashDiff.diff(heroku_state['apps'], parsed_state['apps']), opts) )
|
40
|
+
end
|
41
|
+
|
42
|
+
def show_plan(plan)
|
43
|
+
plan.each do |s|
|
43
44
|
color = OP_COLORS[s[:op]]
|
44
45
|
msg = ''
|
46
|
+
icon = ' '
|
45
47
|
if s[:method].nil?
|
46
|
-
color = "\e[
|
47
|
-
msg = "Can not resolve this
|
48
|
+
color = "\e[0m"
|
49
|
+
msg = "<-- Can not resolve this (NO-OP)"
|
50
|
+
icon = "⚠️"
|
51
|
+
elsif s[:invalid]
|
52
|
+
color = "\e[0m"
|
53
|
+
icon = "⚠️"
|
54
|
+
end
|
55
|
+
STDERR.printf "%1s %s%6s %-30s %-15s %-30s %s\e[0m\n", icon, color, s[:op_name], s[:app_name], s[:role], s[:value], msg
|
56
|
+
if s[:invalid]
|
57
|
+
STDERR.puts "\e[31;1m Error: #{s[:invalid]}\e[0m\n\n"
|
48
58
|
end
|
49
|
-
STDERR.printf "%s%6s %-30s %-15s %-30s %s\e[0m\n", color, s[:op_name], s[:app_name], s[:role], s[:value], msg
|
50
59
|
end
|
51
60
|
end
|
52
61
|
|
@@ -60,31 +69,46 @@ module Hu
|
|
60
69
|
|
61
70
|
desc "Read mapping from stdin and push to heroku"
|
62
71
|
text "Read mapping from stdin and push to heroku"
|
72
|
+
opt :allow_create, "Create new collaborators on heroku", :short => 'c'
|
73
|
+
opt :silent_create, "Suppress email invitation when creating collaborators"
|
63
74
|
parent "collab"
|
64
75
|
def import(cmd, opts, argv)
|
65
76
|
parsed_state = parse_as_json_or_yaml(STDIN.read)
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
77
|
+
validators = {
|
78
|
+
:op_add_collaborators => Proc.new { |op|
|
79
|
+
unless heroku_state['collaborators'].include? op[:value] or opts[:allow_create]
|
80
|
+
raise InvalidOperation, "Use -c to allow creation of new collaborator '#{op[:value]}'"
|
81
|
+
end
|
82
|
+
}
|
83
|
+
}
|
84
|
+
begin
|
85
|
+
plan(HashDiff.diff(heroku_state['apps'], parsed_state['apps']), opts, validators).each do |s|
|
86
|
+
color = OP_COLORS[s[:op]]
|
87
|
+
msg = ''
|
88
|
+
icon = ' '
|
89
|
+
eol = "\e[1G"
|
90
|
+
if s[:method].nil?
|
91
|
+
color = "\e[0;41;33;1m"
|
92
|
+
msg = "Skipped."
|
93
|
+
icon = "\e[0;31;1m\u2718\e[0m" # X
|
94
|
+
eol = "\n"
|
95
|
+
end
|
96
|
+
STDERR.printf "%s %s%6s %-30s %-15s %-30s %s\e[0m%s", icon, color, s[:op_name], s[:app_name], s[:role], s[:value], msg, eol
|
97
|
+
next if s[:method].nil?
|
98
|
+
begin
|
99
|
+
self.send(s[:method], s)
|
100
|
+
STDERR.puts "\e[0;32;1m\u2713\e[0m\n" # check
|
101
|
+
rescue => e
|
102
|
+
STDERR.puts "\e[0;31;1m\u2718\e[0m\n" # X
|
103
|
+
puts e.inspect
|
104
|
+
puts e.backtrace
|
105
|
+
exit 1
|
106
|
+
end
|
107
|
+
end # /plan()
|
108
|
+
rescue InvalidPlan => e
|
109
|
+
STDERR.puts "\e[0;31;1m#{e}:\e[0m\n\n"
|
110
|
+
show_plan(e.invalid_plan)
|
111
|
+
exit 1
|
88
112
|
end
|
89
113
|
end
|
90
114
|
|
@@ -93,8 +117,9 @@ module Hu
|
|
93
117
|
'-' => 'remove',
|
94
118
|
'~' => 'change',
|
95
119
|
}
|
96
|
-
def plan(diff)
|
120
|
+
def plan(diff, env={}, validators={})
|
97
121
|
plan = []
|
122
|
+
last_error = nil
|
98
123
|
diff.each do |op, target, lval, rval|
|
99
124
|
value = rval || lval
|
100
125
|
app_name, role = target.split('.')
|
@@ -102,20 +127,30 @@ module Hu
|
|
102
127
|
role = role.split('[')[0] unless role.nil?
|
103
128
|
op_name = OP_MAP[op]
|
104
129
|
method_name = "op_#{op_name}_#{role}".to_sym
|
105
|
-
|
130
|
+
operation = {
|
106
131
|
app_name: app_name,
|
107
132
|
op: op,
|
108
133
|
op_name: op_name,
|
109
134
|
method: self.respond_to?(method_name) ? method_name : nil,
|
110
135
|
value: value,
|
111
136
|
role: role,
|
137
|
+
env: env,
|
112
138
|
}
|
139
|
+
if validators.include? method_name
|
140
|
+
begin
|
141
|
+
validators[method_name].call(operation)
|
142
|
+
rescue InvalidOperation => e
|
143
|
+
last_error = operation[:invalid] = e
|
144
|
+
end
|
145
|
+
end
|
146
|
+
plan << operation
|
113
147
|
end
|
148
|
+
raise InvalidPlan.new("Plan did not pass validation", plan) unless last_error.nil?
|
114
149
|
plan
|
115
150
|
end
|
116
151
|
|
117
152
|
def op_add_collaborators(args)
|
118
|
-
h.collaborator.create(args[:app_name], :user => args[:value])
|
153
|
+
h.collaborator.create(args[:app_name], :user => args[:value], :silent => args[:env][:silent_create])
|
119
154
|
end
|
120
155
|
|
121
156
|
def op_remove_collaborators(args)
|
@@ -154,11 +189,6 @@ module Hu
|
|
154
189
|
next unless v['collaborators'].is_a? Array
|
155
190
|
v['collaborators'].flatten!
|
156
191
|
v['collaborators'].sort!
|
157
|
-
v['collaborators'].each do |collab|
|
158
|
-
unless heroku_state['collaborators'].include? collab
|
159
|
-
raise ArgumentError, "Unknown collaborator: #{collab}"
|
160
|
-
end
|
161
|
-
end
|
162
192
|
end
|
163
193
|
parsed
|
164
194
|
end
|
data/lib/hu/version.rb
CHANGED