cobra_commander 0.6.1 → 0.9.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.
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "tty-command"
4
+
5
+ module CobraCommander
6
+ module Executor
7
+ # Execute a command on a single component
8
+ class ComponentExec
9
+ def initialize(component)
10
+ @component = component
11
+ end
12
+
13
+ def run(command, output: $stdout, **cmd_options)
14
+ tty = TTY::Command.new(pty: true, printer: :quiet, output: output)
15
+ isolate_bundle do
16
+ @component.root_paths.all? do |path|
17
+ tty.run!(command, chdir: path, **cmd_options).success?
18
+ end
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def isolate_bundle(&block)
25
+ if Bundler.respond_to?(:with_unbundled_env)
26
+ Bundler.with_unbundled_env(&block)
27
+ else
28
+ Bundler.with_clean_env(&block)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "tty-spinner"
4
+
5
+ require_relative "component_exec"
6
+
7
+ module CobraCommander
8
+ module Executor
9
+ # Executes a command on multiple components simultaniously
10
+ class MultiExec
11
+ def initialize(components)
12
+ @components = components
13
+ end
14
+
15
+ def run(command, output: $stdout, spin_output: $stderr, only_output_on_error: true, **cmd_options)
16
+ cmmd_output = StringIO.new
17
+ multi = TTY::Spinner::Multi.new("Running #{command}", output: spin_output)
18
+ @components.each do |component|
19
+ component_exec(multi, component, command, only_output_on_error: only_output_on_error,
20
+ stderr: :stdout, output: cmmd_output,
21
+ **cmd_options)
22
+ end
23
+ multi.auto_spin
24
+ output << cmmd_output.string
25
+ true
26
+ end
27
+
28
+ private
29
+
30
+ def component_exec(multi, component, command, **options)
31
+ exec = ComponentExec.new(component)
32
+ multi.register(*spinner(component.name)) do |spin|
33
+ exec.run(command, **options) ? spin.success : spin.error
34
+ end
35
+ end
36
+
37
+ def spinner(title)
38
+ pastel = Pastel.new
39
+ [":spinner #{title}", { format: :bouncing,
40
+ success_mark: pastel.green("[DONE]"),
41
+ error_mark: pastel.red("[ERROR]"), },]
42
+ end
43
+ end
44
+ end
45
+ end
@@ -1,74 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module CobraCommander
4
- # Module for pretty printing dependency trees
5
- module Output
6
- def self.print(tree, format)
7
- output = format == "list" ? Output::FlatList.new(tree) : Output::Tree.new(tree)
8
- puts output.to_s
9
- end
10
-
11
- # Flattens a tree and prints unique items
12
- class FlatList
13
- def initialize(tree)
14
- @tree = tree
15
- end
16
-
17
- def to_s
18
- @tree.flatten.map(&:name)
19
- end
20
- end
21
-
22
- # Prints the tree in a nice tree form
23
- class Tree
24
- attr_accessor :tree
25
-
26
- SPACE = " "
27
- BAR = "│   "
28
- TEE = "├── "
29
- CORNER = "└── "
30
-
31
- def initialize(tree)
32
- @tree = tree
33
- end
34
-
35
- def to_s
36
- StringIO.new.tap do |io|
37
- io.puts @tree.name
38
- list_dependencies(io, @tree)
39
- end.string
40
- end
41
-
42
- private
43
-
44
- def list_dependencies(io, deps, outdents = [])
45
- deps.dependencies.each do |dep|
46
- decide_on_line(io, deps, dep, outdents)
47
- end
48
- nil
49
- end
50
-
51
- def decide_on_line(io, parent, dep, outdents)
52
- if parent.dependencies.last != dep
53
- add_tee(io, outdents, dep)
54
- else
55
- add_corner(io, outdents, dep)
56
- end
57
- end
58
-
59
- def add_tee(io, outdents, dep)
60
- io.puts line(outdents, TEE, dep.name)
61
- list_dependencies(io, dep, (outdents + [BAR]))
62
- end
63
-
64
- def add_corner(io, outdents, dep)
65
- io.puts line(outdents, CORNER, dep.name)
66
- list_dependencies(io, dep, (outdents + [SPACE]))
67
- end
68
-
69
- def line(outdents, sym, name)
70
- (outdents + [sym] + [name]).join
71
- end
72
- end
73
- end
74
- end
3
+ require_relative "output/flat_list"
4
+ require_relative "output/ascii_tree"
5
+ require_relative "output/graph_viz"
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CobraCommander
4
+ module Output
5
+ # Prints the tree in a nice tree form
6
+ class AsciiTree
7
+ SPACE = " "
8
+ BAR = "│   "
9
+ TEE = "├── "
10
+ CORNER = "└── "
11
+
12
+ def initialize(component)
13
+ @component = component
14
+ end
15
+
16
+ def to_s
17
+ StringIO.new.tap do |io|
18
+ io.puts @component.name
19
+ list_dependencies(io, @component)
20
+ end.string
21
+ end
22
+
23
+ private
24
+
25
+ def list_dependencies(io, component, outdents = [])
26
+ component.dependencies.each do |dep|
27
+ decide_on_line(io, component, dep, outdents)
28
+ end
29
+ nil
30
+ end
31
+
32
+ def decide_on_line(io, parent, dep, outdents)
33
+ if parent.dependencies.last != dep
34
+ add_tee(io, outdents, dep)
35
+ else
36
+ add_corner(io, outdents, dep)
37
+ end
38
+ end
39
+
40
+ def add_tee(io, outdents, dep)
41
+ io.puts line(outdents, TEE, dep.name)
42
+ list_dependencies(io, dep, (outdents + [BAR]))
43
+ end
44
+
45
+ def add_corner(io, outdents, dep)
46
+ io.puts line(outdents, CORNER, dep.name)
47
+ list_dependencies(io, dep, (outdents + [SPACE]))
48
+ end
49
+
50
+ def line(outdents, sym, name)
51
+ (outdents + [sym] + [name]).join
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CobraCommander
4
+ module Output
5
+ # Prints a list of components' names sorted alphabetically
6
+ class FlatList
7
+ def initialize(components)
8
+ @components = components
9
+ end
10
+
11
+ def to_s
12
+ @components.map(&:name).sort
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "graphviz"
4
+
5
+ module CobraCommander
6
+ module Output
7
+ # Generates graphs of components
8
+ module GraphViz
9
+ def self.generate(component, output)
10
+ g = ::GraphViz.new(:G, type: :digraph, concentrate: true)
11
+ ([component] + component.deep_dependencies).each do |comp|
12
+ g.add_nodes comp.name
13
+ g.add_edges comp.name, comp.dependencies.map(&:name)
14
+ end
15
+
16
+ g.output(extract_format(output) => output)
17
+ end
18
+
19
+ private_class_method def self.extract_format(output)
20
+ format = output[-3..-1]
21
+ return format if %w[png dot].include?(format)
22
+
23
+ raise ArgumentError, "output format must be 'png' or 'dot'"
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CobraCommander
4
+ # An umbrella application
5
+ class Umbrella
6
+ attr_reader :name, :path
7
+
8
+ def initialize(name, path)
9
+ @root_component = Component.new(self, name)
10
+ @path = path
11
+ @components = {}
12
+ end
13
+
14
+ def find(name)
15
+ @components[name]
16
+ end
17
+
18
+ def root
19
+ @root_component
20
+ end
21
+
22
+ def resolve(component_root_path)
23
+ return root if root.root_paths.include?(component_root_path)
24
+
25
+ components.find do |component|
26
+ component.root_paths.include?(component_root_path)
27
+ end
28
+ end
29
+
30
+ def add_source(key, source)
31
+ @root_component.add_source key, source.path, source.dependencies
32
+ source.components.each do |path:, name:, dependencies:|
33
+ @components[name] ||= Component.new(self, name)
34
+ @components[name].add_source key, path, dependencies
35
+ end
36
+ end
37
+
38
+ def components
39
+ @components.values
40
+ end
41
+
42
+ def dependents_of(component)
43
+ find(component)&.deep_dependents
44
+ &.sort_by(&:name)
45
+ end
46
+
47
+ def dependencies_of(name)
48
+ find(name)&.deep_dependencies
49
+ &.sort_by(&:name)
50
+ end
51
+ end
52
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CobraCommander
4
- VERSION = "0.6.1"
4
+ VERSION = "0.9.1"
5
5
  end
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": [
3
+ "config:base"
4
+ ],
5
+ "ignorePaths": [
6
+ "spec/fixtures"
7
+ ]
8
+ }
metadata CHANGED
@@ -1,92 +1,121 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cobra_commander
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Langfeld
8
8
  - Garett Arrowood
9
+ - Carlos Palhares
9
10
  autorequire:
10
11
  bindir: exe
11
12
  cert_chain: []
12
- date: 2019-07-05 00:00:00.000000000 Z
13
+ date: 2020-09-08 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
- name: thor
16
+ name: bundler
16
17
  requirement: !ruby/object:Gem::Requirement
17
18
  requirements:
18
- - - ">="
19
+ - - "~>"
19
20
  - !ruby/object:Gem::Version
20
- version: 0.18.1
21
- - - "<"
21
+ version: '1.17'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - "~>"
22
27
  - !ruby/object:Gem::Version
23
- version: '2.0'
28
+ version: '1.17'
29
+ - !ruby/object:Gem::Dependency
30
+ name: ruby-graphviz
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - "~>"
34
+ - !ruby/object:Gem::Version
35
+ version: 1.2.3
24
36
  type: :runtime
25
37
  prerelease: false
26
38
  version_requirements: !ruby/object:Gem::Requirement
27
39
  requirements:
40
+ - - "~>"
41
+ - !ruby/object:Gem::Version
42
+ version: 1.2.3
43
+ - !ruby/object:Gem::Dependency
44
+ name: thor
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "<"
48
+ - !ruby/object:Gem::Version
49
+ version: '2.0'
28
50
  - - ">="
29
51
  - !ruby/object:Gem::Version
30
52
  version: 0.18.1
53
+ type: :runtime
54
+ prerelease: false
55
+ version_requirements: !ruby/object:Gem::Requirement
56
+ requirements:
31
57
  - - "<"
32
58
  - !ruby/object:Gem::Version
33
59
  version: '2.0'
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 0.18.1
34
63
  - !ruby/object:Gem::Dependency
35
- name: ruby-graphviz
64
+ name: tty-command
36
65
  requirement: !ruby/object:Gem::Requirement
37
66
  requirements:
38
67
  - - "~>"
39
68
  - !ruby/object:Gem::Version
40
- version: 1.2.3
69
+ version: 0.9.0
41
70
  type: :runtime
42
71
  prerelease: false
43
72
  version_requirements: !ruby/object:Gem::Requirement
44
73
  requirements:
45
74
  - - "~>"
46
75
  - !ruby/object:Gem::Version
47
- version: 1.2.3
76
+ version: 0.9.0
48
77
  - !ruby/object:Gem::Dependency
49
- name: bundler
78
+ name: tty-spinner
50
79
  requirement: !ruby/object:Gem::Requirement
51
80
  requirements:
52
81
  - - "~>"
53
82
  - !ruby/object:Gem::Version
54
- version: '1.13'
55
- type: :development
83
+ version: 0.9.3
84
+ type: :runtime
56
85
  prerelease: false
57
86
  version_requirements: !ruby/object:Gem::Requirement
58
87
  requirements:
59
88
  - - "~>"
60
89
  - !ruby/object:Gem::Version
61
- version: '1.13'
90
+ version: 0.9.3
62
91
  - !ruby/object:Gem::Dependency
63
- name: rake
92
+ name: aruba
64
93
  requirement: !ruby/object:Gem::Requirement
65
94
  requirements:
66
95
  - - "~>"
67
96
  - !ruby/object:Gem::Version
68
- version: '10.0'
97
+ version: 0.14.2
69
98
  type: :development
70
99
  prerelease: false
71
100
  version_requirements: !ruby/object:Gem::Requirement
72
101
  requirements:
73
102
  - - "~>"
74
103
  - !ruby/object:Gem::Version
75
- version: '10.0'
104
+ version: 0.14.2
76
105
  - !ruby/object:Gem::Dependency
77
- name: rspec
106
+ name: bundler
78
107
  requirement: !ruby/object:Gem::Requirement
79
108
  requirements:
80
109
  - - "~>"
81
110
  - !ruby/object:Gem::Version
82
- version: '3.5'
111
+ version: '1.17'
83
112
  type: :development
84
113
  prerelease: false
85
114
  version_requirements: !ruby/object:Gem::Requirement
86
115
  requirements:
87
116
  - - "~>"
88
117
  - !ruby/object:Gem::Version
89
- version: '3.5'
118
+ version: '1.17'
90
119
  - !ruby/object:Gem::Dependency
91
120
  name: guard-rspec
92
121
  requirement: !ruby/object:Gem::Requirement
@@ -102,47 +131,61 @@ dependencies:
102
131
  - !ruby/object:Gem::Version
103
132
  version: '0'
104
133
  - !ruby/object:Gem::Dependency
105
- name: aruba
134
+ name: pry
135
+ requirement: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ type: :development
141
+ prerelease: false
142
+ version_requirements: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ - !ruby/object:Gem::Dependency
148
+ name: rake
106
149
  requirement: !ruby/object:Gem::Requirement
107
150
  requirements:
108
151
  - - "~>"
109
152
  - !ruby/object:Gem::Version
110
- version: 0.14.2
153
+ version: '10.0'
111
154
  type: :development
112
155
  prerelease: false
113
156
  version_requirements: !ruby/object:Gem::Requirement
114
157
  requirements:
115
158
  - - "~>"
116
159
  - !ruby/object:Gem::Version
117
- version: 0.14.2
160
+ version: '10.0'
118
161
  - !ruby/object:Gem::Dependency
119
- name: rubocop
162
+ name: rspec
120
163
  requirement: !ruby/object:Gem::Requirement
121
164
  requirements:
122
- - - '='
165
+ - - "~>"
123
166
  - !ruby/object:Gem::Version
124
- version: 0.48.1
167
+ version: '3.5'
125
168
  type: :development
126
169
  prerelease: false
127
170
  version_requirements: !ruby/object:Gem::Requirement
128
171
  requirements:
129
- - - '='
172
+ - - "~>"
130
173
  - !ruby/object:Gem::Version
131
- version: 0.48.1
174
+ version: '3.5'
132
175
  - !ruby/object:Gem::Dependency
133
- name: pry
176
+ name: rubocop
134
177
  requirement: !ruby/object:Gem::Requirement
135
178
  requirements:
136
- - - ">="
179
+ - - '='
137
180
  - !ruby/object:Gem::Version
138
- version: '0'
181
+ version: 0.88.0
139
182
  type: :development
140
183
  prerelease: false
141
184
  version_requirements: !ruby/object:Gem::Requirement
142
185
  requirements:
143
- - - ">="
186
+ - - '='
144
187
  - !ruby/object:Gem::Version
145
- version: '0'
188
+ version: 0.88.0
146
189
  description: |
147
190
  Tools for working with Component Based Rails Apps (see http://shageman.github.io/cbra.info/).
148
191
  Includes tools for graphing the components of an app and their relationships, as well as selectively
@@ -150,11 +193,14 @@ description: |
150
193
  email:
151
194
  - blangfeld@powerhrg.com
152
195
  - garett.arrowood@powerhrg.com
196
+ - carlos.palhares@powerhrg.com
153
197
  executables:
154
198
  - cobra
155
199
  extensions: []
156
200
  extra_rdoc_files: []
157
201
  files:
202
+ - ".editorconfig"
203
+ - ".github/workflows/ci.yml"
158
204
  - ".gitignore"
159
205
  - ".rspec"
160
206
  - ".rubocop.yml"
@@ -173,15 +219,24 @@ files:
173
219
  - exe/cobra
174
220
  - lib/cobra_commander.rb
175
221
  - lib/cobra_commander/affected.rb
176
- - lib/cobra_commander/cached_component_tree.rb
177
- - lib/cobra_commander/calculated_component_tree.rb
178
222
  - lib/cobra_commander/change.rb
179
223
  - lib/cobra_commander/cli.rb
180
- - lib/cobra_commander/component_tree.rb
224
+ - lib/cobra_commander/component.rb
225
+ - lib/cobra_commander/dependencies.rb
226
+ - lib/cobra_commander/dependencies/bundler.rb
227
+ - lib/cobra_commander/dependencies/yarn/package.rb
228
+ - lib/cobra_commander/dependencies/yarn/package_repo.rb
229
+ - lib/cobra_commander/dependencies/yarn_workspace.rb
181
230
  - lib/cobra_commander/executor.rb
182
- - lib/cobra_commander/graph.rb
231
+ - lib/cobra_commander/executor/component_exec.rb
232
+ - lib/cobra_commander/executor/multi_exec.rb
183
233
  - lib/cobra_commander/output.rb
234
+ - lib/cobra_commander/output/ascii_tree.rb
235
+ - lib/cobra_commander/output/flat_list.rb
236
+ - lib/cobra_commander/output/graph_viz.rb
237
+ - lib/cobra_commander/umbrella.rb
184
238
  - lib/cobra_commander/version.rb
239
+ - renovate.json
185
240
  homepage: http://tech.powerhrg.com/cobra_commander/
186
241
  licenses:
187
242
  - MIT
@@ -201,7 +256,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
201
256
  - !ruby/object:Gem::Version
202
257
  version: '0'
203
258
  requirements: []
204
- rubygems_version: 3.0.4
259
+ rubyforge_project:
260
+ rubygems_version: 2.7.3
205
261
  signing_key:
206
262
  specification_version: 4
207
263
  summary: Tools for working with Component Based Rails Apps