cobra_commander 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 91660f448535600d40a46445e412e45ff4eeeb10
4
+ data.tar.gz: 2ccb7102130a937e86cd387cd65d6053b1933558
5
+ SHA512:
6
+ metadata.gz: '008ca06433fad82bcfade84a3af06b6785f6ce28015bf004c152c2c325aff4a67a7d964b960dc27d28fdd2a6cf70eb375322f73e8d12603f5dadc5293a3da569'
7
+ data.tar.gz: 0e8a1c7f20f78554a71492a6fd05dddf38f22000e5c6fd67e76f23d4f23a9763b3fa4da41126030cba5fcba0a8c1350bb52e39d17ceb36f376d9ce484ee5d51a
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.DS_store
3
+ /.yardoc
4
+ /Gemfile.lock
5
+ /_yardoc/
6
+ /coverage/
7
+ /doc/
8
+ /graph.*
9
+ /pkg/
10
+ /spec/examples.txt
11
+ /spec/reports/
12
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,50 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.3
3
+
4
+ Metrics/LineLength:
5
+ Max: 120
6
+
7
+ Metrics/BlockLength:
8
+ Exclude:
9
+ - spec/**/*.rb
10
+ - cobra_commander.gemspec
11
+
12
+ Metrics/ClassLength:
13
+ Exclude:
14
+ - spec/**/*.rb
15
+ - cobra_commander.gemspec
16
+
17
+ Style/AccessModifierIndentation:
18
+ EnforcedStyle: outdent
19
+
20
+ Style/Documentation:
21
+ Enabled: true
22
+
23
+ Style/ExtraSpacing:
24
+ Exclude:
25
+ - cobra_commander.gemspec
26
+
27
+ Style/SpaceAroundOperators:
28
+ Exclude:
29
+ - cobra_commander.gemspec
30
+
31
+ Style/Lambda:
32
+ EnforcedStyle: literal
33
+
34
+ Style/PercentLiteralDelimiters:
35
+ PreferredDelimiters:
36
+ default: ()
37
+ '%i': '[]'
38
+ '%I': '[]'
39
+ '%r': '{}'
40
+ '%w': '[]'
41
+ '%W': '[]'
42
+
43
+ # Single quotes being faster is hardly measurable and only affects parse time.
44
+ # Enforcing double quotes reduces the times where you need to change them when introducing an interpolation.
45
+ # Use single quotes only if their semantics are needed.
46
+ Style/StringLiterals:
47
+ EnforcedStyle: double_quotes
48
+
49
+ Style/TrailingCommaInLiteral:
50
+ EnforcedStyleForMultiline: comma
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ sudo: true
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ before_install:
6
+ - gem install bundler -v 1.13.6
7
+ - sudo apt-get -qq install graphviz
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at blangfeld@powerhrg.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in cbra.gemspec
6
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ guard :rspec, cmd: "bundle exec rspec" do
4
+ require "guard/rspec/dsl"
5
+ dsl = Guard::RSpec::Dsl.new(self)
6
+
7
+ rspec = dsl.rspec
8
+ watch(rspec.spec_helper) { rspec.spec_dir }
9
+ watch(rspec.spec_support) { rspec.spec_dir }
10
+ watch(rspec.spec_files)
11
+
12
+ ruby = dsl.ruby
13
+ dsl.watch_spec_files_for(ruby.lib_files)
14
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Power Home Remodelling Group LLC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,50 @@
1
+ # cobra_commander
2
+
3
+ [![Gem](https://img.shields.io/gem/dv/cobra_commander/stable.svg)](https://rubygems.org/gems/cobra_commander)
4
+ [![Gem](https://img.shields.io/gem/v/cobra_commander.svg)](https://rubygems.org/gems/cobra_commander)
5
+ [![Travis](https://img.shields.io/travis/powerhome/cobra_commander.svg)](https://travis-ci.org/powerhome/cobra_commander)
6
+ [![Code Climate](https://img.shields.io/codeclimate/github/powerhome/cobra_commander.svg)](https://codeclimate.com/github/powerhome/cobra_commander)
7
+ [![Gemnasium](https://img.shields.io/gemnasium/powerhome/cobra_commander.svg)](https://gemnasium.com/github.com/powerhome/cobra_commander)
8
+
9
+ Tools for working with Component Based Rails Apps (see http://shageman.github.io/cbra.info/). Includes tools for graphing the components of an app and their relationships, as well as selectively testing components based on changes made.
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ ```ruby
16
+ gem 'cobra'
17
+ ```
18
+
19
+ And then execute:
20
+
21
+ $ bundle
22
+
23
+ Or install it yourself as:
24
+
25
+ $ gem install cobra
26
+
27
+ ## Usage
28
+
29
+ ```bash
30
+ Commands:
31
+ cobra changes APP_PATH [--results=RESULTS] [--branch=BRANCH] # Prints list of changed files
32
+ cobra graph APP_PATH [--format=FORMAT] # Outputs graph
33
+ cobra help [COMMAND] # Describe available commands or one specific command
34
+ cobra ls APP_PATH # Prints tree of components for an app
35
+ cobra version # Prints version
36
+ ```
37
+
38
+ ## Development
39
+
40
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
41
+
42
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
43
+
44
+ ## Contributing
45
+
46
+ Bug reports and pull requests are welcome on GitHub at https://github.com/powerhome/cobra_commander. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
47
+
48
+ ## License
49
+
50
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+
5
+ require "rspec/core/rake_task"
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "rubocop/rake_task"
9
+ RuboCop::RakeTask.new
10
+
11
+ task default: %i[spec rubocop]
data/_config.yml ADDED
@@ -0,0 +1 @@
1
+ theme: jekyll-theme-architect
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "cobra_commander"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,45 @@
1
+ # coding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ lib = File.expand_path("../lib", __FILE__)
5
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
+ require "cobra_commander/version"
7
+
8
+ Gem::Specification.new do |spec|
9
+ spec.name = "cobra_commander"
10
+ spec.version = CobraCommander::VERSION
11
+ spec.authors = [
12
+ "Ben Langfeld",
13
+ "Garett Arrowood",
14
+ ]
15
+ spec.email = [
16
+ "blangfeld@powerhrg.com",
17
+ "garett.arrowood@powerhrg.com",
18
+ ]
19
+ spec.summary = "Tools for working with Component Based Rails Apps"
20
+ spec.description = <<~DESCRIPTION
21
+ Tools for working with Component Based Rails Apps (see http://shageman.github.io/cbra.info/).
22
+ Includes tools for graphing the components of an app and their relationships, as well as selectively
23
+ testing components based on changes made.
24
+ DESCRIPTION
25
+ spec.homepage = "http://tech.powerhrg.com/cobra_commander/"
26
+ spec.license = "MIT"
27
+
28
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
29
+ f.match(%r{^(test|spec|features)/})
30
+ end
31
+ spec.bindir = "exe"
32
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
33
+ spec.require_paths = ["lib"]
34
+
35
+ spec.add_dependency "thor", "~> 0.19.4"
36
+ spec.add_dependency "ruby-graphviz", "~> 1.2.3"
37
+
38
+ spec.add_development_dependency "bundler", "~> 1.13"
39
+ spec.add_development_dependency "rake", "~> 10.0"
40
+ spec.add_development_dependency "rspec", "~> 3.5"
41
+ spec.add_development_dependency "guard-rspec"
42
+ spec.add_development_dependency "aruba", "~> 0.14.2"
43
+ spec.add_development_dependency "rubocop", "0.48.1"
44
+ spec.add_development_dependency "pry"
45
+ end
data/exe/cobra ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "cobra_commander"
5
+
6
+ CobraCommander::CLI.start
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cobra_commander/cli"
4
+ require "cobra_commander/component_tree"
5
+ require "cobra_commander/version"
6
+ require "cobra_commander/formatted_output"
7
+ require "cobra_commander/graph"
8
+ require "cobra_commander/change"
9
+ require "cobra_commander/affected"
10
+
11
+ # Tools for working with Component Based Rails Apps (see http://shageman.github.io/cbra.info/).
12
+ # Includes tools for graphing the components of an app and their relationships, as well as selectively
13
+ # testing components based on changes made.
14
+ module CobraCommander
15
+ UMBRELLA_APP_NAME = "App"
16
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CobraCommander
4
+ # Calculates directly & transitively affected components
5
+ class Affected
6
+ attr_reader :directly, :transitively
7
+
8
+ def initialize(tree, changes, path)
9
+ @changes = changes
10
+ @path = path
11
+ @transitively = Set.new
12
+ @directly = Set.new
13
+ find_dependencies(tree)
14
+ @transitively.delete(name: UMBRELLA_APP_NAME, path: @path)
15
+ end
16
+
17
+ def needs_testing
18
+ @needs_testing ||= (@directly + @transitively).map! do |component|
19
+ File.join(component[:path], "test.sh")
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def find_dependencies(parent_component)
26
+ parent_component[:dependencies].each do |component|
27
+ add_if_changed(component)
28
+ find_dependencies(component)
29
+ end
30
+ end
31
+
32
+ def add_if_changed(component)
33
+ @changes.each do |change|
34
+ if change.start_with?(component[:path])
35
+ @directly << component.reject { |k| k == :dependencies || k == :ancestry }
36
+ @transitively.merge component[:ancestry]
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cobra_commander/component_tree"
4
+ require "cobra_commander/affected"
5
+ require "open3"
6
+
7
+ module CobraCommander
8
+ # Calculates and prints affected components & files
9
+ class Change
10
+ InvalidSelectionError = Class.new(StandardError)
11
+
12
+ def initialize(path, results, branch)
13
+ @root_dir = Dir.chdir(path) { `git rev-parse --show-toplevel`.chomp }
14
+ @results = results
15
+ @branch = branch
16
+ @tree = ComponentTree.new(path).to_h
17
+ @affected = Affected.new(@tree, changes, path)
18
+ end
19
+
20
+ def run!
21
+ assert_valid_result_choice
22
+ show_full if selected_full_results?
23
+ tests_to_run
24
+ rescue InvalidSelectionError => e
25
+ puts e.message
26
+ end
27
+
28
+ private
29
+
30
+ def show_full
31
+ changes_since_last_commit
32
+ directly_affected_components
33
+ transitively_affected_components
34
+ end
35
+
36
+ def changes
37
+ @changes ||= begin
38
+ diff, _, result = Dir.chdir(@root_dir) do
39
+ Open3.capture3("git", "diff", "--name-only", @branch)
40
+ end
41
+
42
+ if result.exitstatus == 128
43
+ raise InvalidSelectionError, "Specified --branch could not be found"
44
+ end
45
+
46
+ diff.split("\n").map { |f| File.join(@root_dir, f) }
47
+ end
48
+ end
49
+
50
+ def assert_valid_result_choice
51
+ raise InvalidSelectionError, "--results must be 'test' or 'full'" unless %w[test full].include?(@results)
52
+ end
53
+
54
+ def selected_full_results?
55
+ @results == "full"
56
+ end
57
+
58
+ def changes_since_last_commit
59
+ puts "<<< Changes since last commit on #{@branch} >>>"
60
+ changes.each { |path| puts path }
61
+ puts blank_line
62
+ end
63
+
64
+ def directly_affected_components
65
+ puts "<<< Directly affected components >>>"
66
+ @affected.directly.each { |component| puts component[:name] }
67
+ puts blank_line
68
+ end
69
+
70
+ def transitively_affected_components
71
+ puts "<<< Transitively affected components >>>"
72
+ @affected.transitively.each { |component| puts component[:name] }
73
+ puts blank_line
74
+ end
75
+
76
+ def tests_to_run
77
+ puts "<<< Test scripts to run >>>" if selected_full_results?
78
+ @affected.needs_testing.each { |script| puts script }
79
+ end
80
+
81
+ def blank_line
82
+ ""
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+
5
+ module CobraCommander
6
+ # Implements the tool's CLI
7
+ class CLI < Thor
8
+ desc "ls APP_PATH", "Prints tree of components for an app"
9
+ def ls(app_path)
10
+ puts FormattedOutput.new(app_path).run!
11
+ end
12
+
13
+ desc "version", "Prints version"
14
+ def version
15
+ puts CobraCommander::VERSION
16
+ end
17
+
18
+ desc "graph APP_PATH [--format=FORMAT]", "Outputs graph"
19
+ method_option :format, default: "png", aliases: "-f", desc: "Accepts png or dot"
20
+ def graph(app_path)
21
+ Graph.new(app_path, @options[:format]).generate!
22
+ end
23
+
24
+ desc "changes APP_PATH [--results=RESULTS] [--branch=BRANCH]", "Prints list of changed files"
25
+ method_option :results, default: "test", aliases: "-r", desc: "Accepts test or full"
26
+ method_option :branch, default: "master", aliases: "-b", desc: "Specified target to calculate against"
27
+ def changes(app_path)
28
+ Change.new(app_path, @options[:results], @options[:branch]).run!
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CobraCommander
4
+ # Representation of the tree of components and their dependencies
5
+ class ComponentTree
6
+ def initialize(path)
7
+ @root_path = path
8
+ end
9
+
10
+ def to_h
11
+ GemComponentTree.new(UMBRELLA_APP_NAME, @root_path).to_h
12
+ end
13
+
14
+ # Represents a tree of gem components with dependencies extracted via Bundler
15
+ class GemComponentTree
16
+ def initialize(name, path, ancestry = Set.new)
17
+ @name = name
18
+ @root_path = path
19
+ @ancestry = ancestry
20
+ end
21
+
22
+ def to_h
23
+ {
24
+ name: @name,
25
+ path: @root_path,
26
+ ancestry: @ancestry,
27
+ dependencies: component_dependencies.map(&method(:dep_representation)),
28
+ }
29
+ end
30
+
31
+ private
32
+
33
+ def gemfile_path
34
+ File.join(@root_path, "Gemfile")
35
+ end
36
+
37
+ def gemfile_lock_path
38
+ File.join(@root_path, "Gemfile.lock")
39
+ end
40
+
41
+ def bundler_definition
42
+ ::Bundler::Definition.build(gemfile_path, gemfile_lock_path, nil)
43
+ end
44
+
45
+ def component_dependencies
46
+ bundler_definition.dependencies.select do |dep|
47
+ dep.source&.is_a_path?
48
+ end
49
+ end
50
+
51
+ def dep_representation(dep)
52
+ path = File.expand_path(File.join(@root_path, dep.source.path, dep.name))
53
+ ancestry = @ancestry + [{ name: @name, path: @root_path }]
54
+ self.class.new(dep.name, path, ancestry).to_h
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cobra_commander/component_tree"
4
+
5
+ module CobraCommander
6
+ # Formats CLI ls output
7
+ class FormattedOutput
8
+ attr_accessor :tree
9
+
10
+ SPACE = " "
11
+ BAR = "│   "
12
+ TEE = "├── "
13
+ CORNER = "└── "
14
+
15
+ def initialize(app_path)
16
+ @tree = ComponentTree.new(app_path).to_h
17
+ end
18
+
19
+ def run!
20
+ puts @tree[:name]
21
+ list_dependencies(@tree)
22
+ nil
23
+ end
24
+
25
+ private
26
+
27
+ def list_dependencies(deps, outdents = [])
28
+ deps[:dependencies].each do |dep|
29
+ decide_on_line(deps, dep, outdents)
30
+ end
31
+ end
32
+
33
+ def decide_on_line(parent, dep, outdents)
34
+ if parent[:dependencies].last != dep
35
+ add_tee(outdents, dep)
36
+ else
37
+ add_corner(outdents, dep)
38
+ end
39
+ end
40
+
41
+ def add_tee(outdents, dep)
42
+ puts line(outdents, TEE, dep[:name])
43
+ list_dependencies(dep, ([BAR] + outdents))
44
+ end
45
+
46
+ def add_corner(outdents, dep)
47
+ puts line(outdents, CORNER, dep[:name])
48
+ list_dependencies(dep, (outdents + [SPACE]))
49
+ end
50
+
51
+ def line(outdents, sym, name)
52
+ (outdents + [sym] + [name]).join
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "graphviz"
4
+ require "cobra_commander/component_tree"
5
+
6
+ module CobraCommander
7
+ # Generates graphs of components
8
+ class Graph
9
+ def initialize(app_path, format)
10
+ @format = format
11
+ @tree = ComponentTree.new(app_path).to_h
12
+ end
13
+
14
+ def generate!
15
+ return unless valid_format?
16
+
17
+ g = GraphViz.new(:G, type: :digraph, concentrate: true)
18
+
19
+ app_node = g.add_nodes(@tree[:name])
20
+ map_nodes(g, app_node, @tree)
21
+ output(g)
22
+ end
23
+
24
+ private
25
+
26
+ def map_nodes(g, parent_node, tree)
27
+ tree[:dependencies].each do |dep|
28
+ node = g.find_node(dep[:name]) || g.add_nodes(dep[:name])
29
+ g.add_edges(parent_node, node)
30
+ map_nodes(g, node, dep)
31
+ end
32
+ end
33
+
34
+ def output(g)
35
+ graph = "graph.#{@format}"
36
+ g.output(@format => graph)
37
+ puts "Graph generated at #{`pwd`.chomp}/#{graph}"
38
+ end
39
+
40
+ def valid_format?
41
+ return true if @format == "png" || @format == "dot"
42
+ puts "FORMAT must be 'png' or 'dot'"
43
+ false
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CobraCommander
4
+ VERSION = "0.1.1"
5
+ end
metadata ADDED
@@ -0,0 +1,199 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cobra_commander
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Ben Langfeld
8
+ - Garett Arrowood
9
+ autorequire:
10
+ bindir: exe
11
+ cert_chain: []
12
+ date: 2017-05-05 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: thor
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: 0.19.4
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: 0.19.4
28
+ - !ruby/object:Gem::Dependency
29
+ name: ruby-graphviz
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: 1.2.3
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: 1.2.3
42
+ - !ruby/object:Gem::Dependency
43
+ name: bundler
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '1.13'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '1.13'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rake
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '10.0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '10.0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: rspec
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '3.5'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '3.5'
84
+ - !ruby/object:Gem::Dependency
85
+ name: guard-rspec
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: aruba
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: 0.14.2
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: 0.14.2
112
+ - !ruby/object:Gem::Dependency
113
+ name: rubocop
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - '='
117
+ - !ruby/object:Gem::Version
118
+ version: 0.48.1
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - '='
124
+ - !ruby/object:Gem::Version
125
+ version: 0.48.1
126
+ - !ruby/object:Gem::Dependency
127
+ name: pry
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ description: |
141
+ Tools for working with Component Based Rails Apps (see http://shageman.github.io/cbra.info/).
142
+ Includes tools for graphing the components of an app and their relationships, as well as selectively
143
+ testing components based on changes made.
144
+ email:
145
+ - blangfeld@powerhrg.com
146
+ - garett.arrowood@powerhrg.com
147
+ executables:
148
+ - cobra
149
+ extensions: []
150
+ extra_rdoc_files: []
151
+ files:
152
+ - ".gitignore"
153
+ - ".rspec"
154
+ - ".rubocop.yml"
155
+ - ".travis.yml"
156
+ - CODE_OF_CONDUCT.md
157
+ - Gemfile
158
+ - Guardfile
159
+ - LICENSE.txt
160
+ - README.md
161
+ - Rakefile
162
+ - _config.yml
163
+ - bin/console
164
+ - bin/setup
165
+ - cobra_commander.gemspec
166
+ - exe/cobra
167
+ - lib/cobra_commander.rb
168
+ - lib/cobra_commander/affected.rb
169
+ - lib/cobra_commander/change.rb
170
+ - lib/cobra_commander/cli.rb
171
+ - lib/cobra_commander/component_tree.rb
172
+ - lib/cobra_commander/formatted_output.rb
173
+ - lib/cobra_commander/graph.rb
174
+ - lib/cobra_commander/version.rb
175
+ homepage: http://tech.powerhrg.com/cobra_commander/
176
+ licenses:
177
+ - MIT
178
+ metadata: {}
179
+ post_install_message:
180
+ rdoc_options: []
181
+ require_paths:
182
+ - lib
183
+ required_ruby_version: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ required_rubygems_version: !ruby/object:Gem::Requirement
189
+ requirements:
190
+ - - ">="
191
+ - !ruby/object:Gem::Version
192
+ version: '0'
193
+ requirements: []
194
+ rubyforge_project:
195
+ rubygems_version: 2.5.2
196
+ signing_key:
197
+ specification_version: 4
198
+ summary: Tools for working with Component Based Rails Apps
199
+ test_files: []