simple-hd-graph 0.1.0

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
+ SHA256:
3
+ metadata.gz: 44b324c969e0eee61a4e445debbb87b34d55a12995f1c72a4dc52d2f86807d68
4
+ data.tar.gz: 3caefc54af9dadbcd83fc9dc5cd903f04a1acd9034043bf90424e83f888314ce
5
+ SHA512:
6
+ metadata.gz: 987f4cd19880122491628b747a516f38f4e1a3124cdd54ecbd200070b294a0227e7172ca6aa3c07cc21c455430ebe4c3b3ff7dad94e5566f7e784704ee501c5b
7
+ data.tar.gz: c28ac4b38fdb99fa83e05b14992e935007ce0d7dfa760a87703fba4ad83e44b7ea1c289db222fcfcd2aac0f3b9a1c7de0961188b79d3d095f5f26e2a76989d6b
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ *~
2
+ *.bak
3
+ .DS_Store
4
+ Gemfile.lock
5
+
6
+ /.bundle/
7
+ /.yardoc
8
+ /_yardoc/
9
+ /coverage/
10
+ /doc/
11
+ /pkg/
12
+ /spec/reports/
13
+ /tmp/
14
+ /vendor/
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.6.5
7
+ before_install: gem install bundler -v 2.0.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in graph.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,9 @@
1
+ Copyright 2021 wtnabe
2
+
3
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
4
+
5
+ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
6
+
7
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8
+
9
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,33 @@
1
+ # SimpleHdGraph
2
+
3
+ parse single-tier hierarchy, simplex direction graph from YAML DSL, render PlantUML.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'simple-hd-graph'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install simple-hd-graph
20
+
21
+ ## Usage
22
+
23
+ $ simple-hd-graph -f FILE
24
+
25
+ ## Development
26
+
27
+ 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.
28
+
29
+ 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).
30
+
31
+ ## Contributing
32
+
33
+ Bug reports and pull requests are welcome on GitHub at https://github.com/wtnabe/graph.
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+ require "yard"
4
+
5
+ Rake::TestTask.new(:spec) do |t|
6
+ t.libs << "spec"
7
+ t.libs << "lib"
8
+ t.test_files = FileList["spec/**/*_spec.rb"]
9
+ end
10
+
11
+ YARD::Rake::YardocTask.new do |t|
12
+ t.files = ["lib/**/*.rb"]
13
+ t.options = ["--any", "--extra", "--opts"]
14
+ end
15
+
16
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "graph"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
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,9 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.join(__dir__, '../lib')
4
+ require 'bundler/setup'
5
+ require 'simple-hd-graph'
6
+
7
+ Version = SimpleHdGraph::VERSION
8
+ cmd = SimpleHdGraph::Command.new(ARGV)
9
+ cmd.run
@@ -0,0 +1,8 @@
1
+ module SimpleHdGraph
2
+ class Error < StandardError; end
3
+ # Your code goes here...
4
+ end
5
+
6
+ Dir.glob(__dir__ + '/simple-hd-graph/**/*.rb').each { |f|
7
+ require_relative f.sub(/\.rb\z/, '')
8
+ }
@@ -0,0 +1,33 @@
1
+ require 'optparse'
2
+
3
+ module SimpleHdGraph
4
+ class Command
5
+ def initialize(argv)
6
+ @argv = argv.dup
7
+ end
8
+
9
+ def run
10
+ opts.parse(@argv)
11
+ if @file
12
+ nodes = Parser.new.parse(Reader.new.read_file(@file))
13
+ renderer = Renderer::PlantUML::Context.new
14
+
15
+ puts nodes.map { |node|
16
+ renderer.render(node)
17
+ }.join
18
+ end
19
+ end
20
+
21
+ #
22
+ # @return [OptionParser]
23
+ #
24
+ # :reek:NestedIterators
25
+ def opts
26
+ OptionParser.new do |opt|
27
+ opt.on('-f FILE', '--file', 'filename') { |value|
28
+ @file = value
29
+ }
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,44 @@
1
+ module SimpleHdGraph
2
+ class ContextNode < Node
3
+ required :id
4
+
5
+ attr_reader :resources, :relations
6
+
7
+ #
8
+ # @return [String]
9
+ #
10
+ def alias
11
+ @content[:id]
12
+ end
13
+
14
+ #
15
+ # @return [String]
16
+ #
17
+ def id
18
+ id = camelize(self.alias)
19
+ id[0] = id[0].downcase
20
+ id
21
+ end
22
+
23
+ def <<(resource)
24
+ @resources ||= []
25
+ @resource_dict ||= {}
26
+ @resources << resource
27
+ @resource_dict[resource.alias] = resource.id
28
+ end
29
+
30
+ #
31
+ # :reek:NestedIterators
32
+ def refill_relation
33
+ @relations ||= []
34
+ @resources.each { |resource|
35
+ dependencies = resource.has
36
+ if dependencies
37
+ dependencies.each { |dependency|
38
+ @relations << { resource.id => @resource_dict[dependency] }
39
+ }
40
+ end
41
+ }
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,56 @@
1
+ require 'dry/inflector'
2
+
3
+ module SimpleHdGraph
4
+ class Node
5
+ class RequiredFieldNotFilled < StandardError; end
6
+
7
+ class << self
8
+ #
9
+ # @param names [Array]
10
+ #
11
+ def required(*names)
12
+ @required_fields = names
13
+ end
14
+ end
15
+
16
+ def initialize
17
+ @inflector = Dry::Inflector.new
18
+ end
19
+
20
+ #
21
+ # @param struct [Hash]
22
+ #
23
+ # :reek:TooManyStatements
24
+ def load(struct)
25
+ klass = self.class
26
+
27
+ required_fields = if klass.instance_variables.grep(':@required_fields').size > 0
28
+ klass.instance_variable_get('@required_fields')
29
+ else
30
+ nil
31
+ end
32
+
33
+ if required_fields.is_a? Array
34
+ filled = required_fields.all? {|field|
35
+ if struct.has_key? field
36
+ true
37
+ else
38
+ raise RequiredFieldNotFilled, field
39
+ end
40
+ }
41
+ else
42
+ filled = true
43
+ end
44
+
45
+ @content = struct if filled
46
+ end
47
+
48
+ #
49
+ # @param str [String]
50
+ # @return [String]
51
+ #
52
+ def camelize(str)
53
+ @inflector.camelize(@inflector.underscore(str.gsub(/ /, '_')))
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,59 @@
1
+ require 'yaml'
2
+
3
+ module SimpleHdGraph
4
+ #
5
+ # parse for YAML string
6
+ #
7
+ # :reek:InstanceVaariableAssumption
8
+ class Parser
9
+ #
10
+ # @param document [String]
11
+ #
12
+ # :reek:TooManyStatements
13
+ def parse(document)
14
+ contexts = []
15
+
16
+ YAML.load_stream(document) do |node|
17
+ context = nil
18
+ resources = []
19
+
20
+ # :reek:NestedIterators
21
+ node.each_pair { |key, value|
22
+ if key == 'id'
23
+ context = ContextNode.new
24
+ context.load({ id: value })
25
+ elsif reserved_keywords.include?(key)
26
+ elsif key == 'resources'
27
+ resources = value
28
+ end
29
+ }
30
+
31
+ resources.each { |key, resource|
32
+ rn = ResourceNode.new
33
+ rn.load_with_context({ id: context.id }, { key => resource })
34
+ context << rn
35
+ }
36
+ contexts << context
37
+ end
38
+ refill_relation(contexts)
39
+
40
+ contexts
41
+ end
42
+
43
+ #
44
+ # @param contexts [Array]
45
+ #
46
+ def refill_relation(contexts)
47
+ contexts.each {|context|
48
+ context.refill_relation
49
+ }
50
+ end
51
+
52
+ #
53
+ # @return [Array]
54
+ #
55
+ def reserved_keywords
56
+ [:depends]
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,22 @@
1
+ module SimpleHdGraph
2
+ class Reader
3
+ #
4
+ # @param file [String]
5
+ # @return [String]
6
+ #
7
+ # :reek:UtilityFunction
8
+ def read_file(file)
9
+ File.read(file)
10
+ end
11
+
12
+ #
13
+ # @param dir [String]
14
+ # @return [String]
15
+ #
16
+ def read_dir(dir)
17
+ Dir.glob("#{dir}/**/*.{yml,yaml}").map {|file|
18
+ read_file(file)
19
+ }.join("---\n")
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,50 @@
1
+ module SimpleHdGraph
2
+ module Renderer
3
+ module PlantUML
4
+ class Context
5
+ def initialize
6
+ @resource_renderer = Resource.new
7
+ end
8
+
9
+ #
10
+ # @param node [ContextNode]
11
+ #
12
+ # :reek:FeatureEnvy
13
+ def render(node)
14
+ resources = node.resources.map { |resource|
15
+ indent_resource(resource)
16
+ }.join
17
+ relations = node.relations.map { |relation|
18
+ render_relation(relation)
19
+ }.join("\n")
20
+ <<EOD
21
+ rectangle \"#{node.alias}\" as #{node.id} {
22
+ #{resources}
23
+ #{relations if relations.size > 0}
24
+ }
25
+ EOD
26
+ end
27
+
28
+ #
29
+ # @param resource [String]
30
+ # @return [String]
31
+ #
32
+ def indent_resource(resource)
33
+ @resource_renderer.render(resource).lines.map { |line|
34
+ " #{line}"
35
+ }.join
36
+ end
37
+
38
+ #
39
+ # @param relation [Hash]
40
+ # @return [String]
41
+ #
42
+ # :reek:UtilityFunction
43
+ def render_relation(relation)
44
+ depender, dependee = relation.to_a.first
45
+ " #{depender} -d-|> #{dependee}"
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,22 @@
1
+ module SimpleHdGraph
2
+ module Renderer
3
+ module PlantUML
4
+ class Resource
5
+ #
6
+ # @param node [ResourceNode]
7
+ #
8
+ # :reek:UtilityFunction
9
+ def render(node)
10
+ content = node.content.map { |key, value|
11
+ " #{key}: #{value}"
12
+ }.join("\n")
13
+ <<EOD
14
+ object \"#{node.alias}\" as #{node.id} {
15
+ #{content}
16
+ }
17
+ EOD
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,51 @@
1
+ module SimpleHdGraph
2
+ class ResourceNode < Node
3
+ #
4
+ # @param context [Object]
5
+ # @param struct [Hash]
6
+ #
7
+ def load_with_context(context, struct)
8
+ @context = context
9
+ load(struct)
10
+ end
11
+
12
+ #
13
+ # @return [String]
14
+ #
15
+ def alias
16
+ @content.keys.first.to_s.freeze
17
+ end
18
+
19
+ #
20
+ # @return [String]
21
+ #
22
+ def id
23
+ id = camelize(context)
24
+ id[0] = id[0].downcase
25
+ [id, camelize(self.alias)].join('').freeze
26
+ end
27
+
28
+ #
29
+ # @return [String]
30
+ #
31
+ def context
32
+ @context[:id].freeze
33
+ end
34
+
35
+ #
36
+ # @return [Hash]
37
+ #
38
+ def content
39
+ @content.values.first.select { |key, value|
40
+ key != 'has'
41
+ }
42
+ end
43
+
44
+ #
45
+ # @return [Array]
46
+ #
47
+ def has
48
+ @content.values.first['has']
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,3 @@
1
+ module SimpleHdGraph
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,38 @@
1
+ lib = File.expand_path("lib", __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "simple-hd-graph/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "simple-hd-graph"
7
+ spec.version = SimpleHdGraph::VERSION
8
+ spec.authors = ["wtnabe"]
9
+ spec.email = ["wtnabe@gmail.com"]
10
+
11
+ spec.summary = %q{single-tier hierary and simplex direction graph DSL}
12
+ spec.description = %q{parse single-tier hierarchy and simplex direction graph from YAML, and generate PlantUML with rectangle and object}
13
+ spec.homepage = "https://github.com/wtnabe/simple-hd-graph"
14
+
15
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
16
+
17
+ spec.metadata["homepage_uri"] = spec.homepage
18
+ spec.metadata["source_code_uri"] = spec.homepage
19
+ spec.metadata["changelog_uri"] = spec.metadata["source_code_uri"] + "/blob/master/CHANGELOG.md"
20
+
21
+ # Specify which files should be added to the gem when it is released.
22
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
24
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
25
+ end
26
+ spec.bindir = "exe"
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ["lib"]
29
+
30
+ spec.add_runtime_dependency "dry-inflector", "~> 0"
31
+
32
+ spec.add_development_dependency "bundler", "~> 2.0"
33
+ spec.add_development_dependency "rake", "~> 13.0"
34
+ spec.add_development_dependency "minitest", "~> 5.0"
35
+ spec.add_development_dependency "minitest-reporters", "~> 1"
36
+ spec.add_development_dependency "minitest-power_assert"
37
+ spec.add_development_dependency "yard"
38
+ end
metadata ADDED
@@ -0,0 +1,166 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simple-hd-graph
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - wtnabe
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-04-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: dry-inflector
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '13.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '13.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '5.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '5.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest-reporters
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1'
83
+ - !ruby/object:Gem::Dependency
84
+ name: minitest-power_assert
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: yard
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: parse single-tier hierarchy and simplex direction graph from YAML, and
112
+ generate PlantUML with rectangle and object
113
+ email:
114
+ - wtnabe@gmail.com
115
+ executables:
116
+ - simple-hd-graph
117
+ extensions: []
118
+ extra_rdoc_files: []
119
+ files:
120
+ - ".gitignore"
121
+ - ".travis.yml"
122
+ - Gemfile
123
+ - LICENSE
124
+ - README.md
125
+ - Rakefile
126
+ - bin/console
127
+ - bin/setup
128
+ - exe/simple-hd-graph
129
+ - lib/simple-hd-graph.rb
130
+ - lib/simple-hd-graph/command.rb
131
+ - lib/simple-hd-graph/context.rb
132
+ - lib/simple-hd-graph/node.rb
133
+ - lib/simple-hd-graph/parser.rb
134
+ - lib/simple-hd-graph/reader.rb
135
+ - lib/simple-hd-graph/renderer/plantuml/context.rb
136
+ - lib/simple-hd-graph/renderer/plantuml/resource.rb
137
+ - lib/simple-hd-graph/resource.rb
138
+ - lib/simple-hd-graph/version.rb
139
+ - simple-hd-graph.gemspec
140
+ homepage: https://github.com/wtnabe/simple-hd-graph
141
+ licenses: []
142
+ metadata:
143
+ allowed_push_host: https://rubygems.org
144
+ homepage_uri: https://github.com/wtnabe/simple-hd-graph
145
+ source_code_uri: https://github.com/wtnabe/simple-hd-graph
146
+ changelog_uri: https://github.com/wtnabe/simple-hd-graph/blob/master/CHANGELOG.md
147
+ post_install_message:
148
+ rdoc_options: []
149
+ require_paths:
150
+ - lib
151
+ required_ruby_version: !ruby/object:Gem::Requirement
152
+ requirements:
153
+ - - ">="
154
+ - !ruby/object:Gem::Version
155
+ version: '0'
156
+ required_rubygems_version: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ requirements: []
162
+ rubygems_version: 3.0.3
163
+ signing_key:
164
+ specification_version: 4
165
+ summary: single-tier hierary and simplex direction graph DSL
166
+ test_files: []