flow-yml-parser 0.1.3

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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 10230f71d919b423a6ca1d74254eaa53fcd1571f
4
+ data.tar.gz: 383f0b181b0b8e2183119f0eeda5e0b9f8724c32
5
+ SHA512:
6
+ metadata.gz: a8c01ee2284bb9b05f524f7eda526f674a5ad6a66c143d2213c7b4f9ee7749b16a6040ecb1397157be01f4a536c6b5b148e2aa6bb6e505a2fa041b3a2f406918
7
+ data.tar.gz: fa87085ebfd27523b7edf2408f079ebb6af1554e10eb76c7abe8bd517467799e76a91295714de9892a3c7bf585e0edf287c111e04b04cdb384837a84be732f04
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ .idea/
11
+ *.gem
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in flow-yml-parser.gemspec
4
+ gemspec
@@ -0,0 +1,35 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ flow-yml-parser (0.1.2)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.2.5)
10
+ rake (10.5.0)
11
+ rspec (3.5.0)
12
+ rspec-core (~> 3.5.0)
13
+ rspec-expectations (~> 3.5.0)
14
+ rspec-mocks (~> 3.5.0)
15
+ rspec-core (3.5.4)
16
+ rspec-support (~> 3.5.0)
17
+ rspec-expectations (3.5.0)
18
+ diff-lcs (>= 1.2.0, < 2.0)
19
+ rspec-support (~> 3.5.0)
20
+ rspec-mocks (3.5.0)
21
+ diff-lcs (>= 1.2.0, < 2.0)
22
+ rspec-support (~> 3.5.0)
23
+ rspec-support (3.5.0)
24
+
25
+ PLATFORMS
26
+ ruby
27
+
28
+ DEPENDENCIES
29
+ bundler (~> 1.13)
30
+ flow-yml-parser!
31
+ rake (~> 10.0)
32
+ rspec (~> 3.0)
33
+
34
+ BUNDLED WITH
35
+ 1.13.6
@@ -0,0 +1,36 @@
1
+ # Flow::Yml::Parser
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/flow/yml/parser`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'flow-yml-parser'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install flow-yml-parser
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ 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).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/flow-yml-parser.
36
+
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "flow/yml/parser"
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
@@ -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,38 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'flow-yml/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "flow-yml-parser"
8
+ spec.version = FlowYml::Parser::VERSION
9
+ spec.authors = ["yang.guo"]
10
+ spec.email = ["gy@fir.im"]
11
+
12
+ spec.summary = %q{flow.ci config parser}
13
+ spec.description = %q{flow.ci config parser}
14
+ spec.homepage = "http://www.flow.ci"
15
+
16
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
17
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
18
+ if spec.respond_to?(:metadata)
19
+ # spec.metadata['allowed_push_host'] = "'http://mygemserver.com'"
20
+ else
21
+ raise "RubyGems 2.0 or newer is required to protect against " \
22
+ "public gem pushes."
23
+ end
24
+
25
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
26
+ f.match(%r{^(test|spec|features)/})
27
+ end
28
+
29
+ # This gem will work with 1.8.6 or greater...
30
+ spec.required_ruby_version = '>= 2.2.0'
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_development_dependency "bundler", "~> 1.13"
36
+ spec.add_development_dependency "rake", "~> 10.0"
37
+ spec.add_development_dependency "rspec", "~> 3.0"
38
+ end
@@ -0,0 +1 @@
1
+ require 'flow-yml/parser'
@@ -0,0 +1,168 @@
1
+ # encoding: utf-8
2
+ require 'flow-yml/exceptions'
3
+ require 'flow-yml/domain/config_base'
4
+ require 'flow-yml/domain/fields'
5
+ require 'flow-yml/domain/project'
6
+ require 'flow-yml/domain/step'
7
+ require 'flow-yml/domain/flow_pipeline'
8
+
9
+ module FlowYml
10
+
11
+ class ConverterBase
12
+ attr_reader :yml_obj
13
+
14
+ def initialize(yml_obj)
15
+ raise YmlObjectMissingException.new if yml_obj.nil?
16
+ @yml_obj = yml_obj
17
+ end
18
+
19
+ def convert
20
+ raise NotImplementedError.new('ConverterBase..')
21
+ end
22
+
23
+ protected
24
+
25
+ def converter(meta_obj, yml_obj)
26
+ meta_obj.class.meta.each do |name, meta|
27
+ next if meta.skip
28
+
29
+ value = yml_obj[name]
30
+ value = yml_obj[name.to_s] if value.nil?
31
+
32
+ raise RequiredFieldMissingException.new(name) if value_missing?(meta, value)
33
+ next if value.nil?
34
+
35
+ raise YmlTypeException.new(meta.type, name) if type_miss_match?(meta, value)
36
+ case meta.type
37
+ when FlowYml::Domain::Fields::TYPE_ARRAY
38
+ meta_obj.send("#{name}=", convert_list(meta, value))
39
+
40
+ when FlowYml::Domain::Fields::TYPE_HASH
41
+ meta_obj.send("#{name}=", convert_hash(meta, value))
42
+
43
+ else
44
+ meta_obj.send("#{name}=", value)
45
+ end
46
+ end
47
+ end
48
+
49
+ def convert_list(meta, value)
50
+ obj_list = []
51
+ value.each do |item|
52
+ # add object to list if converter defined
53
+ if converter_defined?(meta)
54
+ converter = Object.const_get(converter_name(meta)).new(item)
55
+ obj_list.push(converter.convert)
56
+ next
57
+ end
58
+
59
+ # add item to list directly
60
+ obj_list.push(item)
61
+ end
62
+ obj_list
63
+ end
64
+
65
+ def convert_hash(meta, value)
66
+ # TODO convert value to object
67
+ end
68
+
69
+ # get target converter name
70
+ def converter_name(meta)
71
+ "FlowYml::#{meta.target}Converter"
72
+ end
73
+
74
+ # check target converter is defined
75
+ def converter_defined?(meta)
76
+ Object.const_defined?(converter_name(meta))
77
+ end
78
+
79
+ # check yml value whether nil and required
80
+ # return:
81
+ # true = if value is missing
82
+ # false = if value not required
83
+ def value_missing?(meta, value)
84
+ return false unless meta.required
85
+
86
+ ## check array type
87
+ return value.count == 0 if !value.nil? && value.class.to_s == FlowYml::Domain::Fields::TYPE_ARRAY
88
+
89
+ value.nil?
90
+ end
91
+
92
+ # check yml value is match the required type
93
+ # return:
94
+ # true = if type missing match
95
+ # false = if type is match
96
+ def type_miss_match?(meta, value)
97
+ meta.type.split('|').each do |type_str|
98
+ return false if value.class.to_s == type_str
99
+ end
100
+ true
101
+ end
102
+
103
+ end
104
+
105
+ # Project yml converter
106
+ class ProjectConverter < ConverterBase
107
+
108
+ def initialize(yml_obj)
109
+ super(yml_obj)
110
+ end
111
+
112
+ def convert
113
+ project = FlowYml::Domain::Project.new
114
+ converter(project, @yml_obj)
115
+ project
116
+ end
117
+
118
+ end
119
+
120
+ # Flow yml converter
121
+ class FlowConverter < ConverterBase
122
+
123
+ def initialize(yml_obj)
124
+ super(yml_obj)
125
+ end
126
+
127
+ def convert
128
+ flow = FlowYml::Domain::FlowPipeline.new
129
+ converter(flow, @yml_obj)
130
+ flow
131
+ end
132
+ end
133
+
134
+ # Step yml converter
135
+ class StepConverter < ConverterBase
136
+
137
+ def initialize(yml_obj)
138
+ super(yml_obj)
139
+ end
140
+
141
+ def convert
142
+ step = FlowYml::Domain::Step.new
143
+ converter(step, yml_adapter)
144
+ step
145
+ end
146
+
147
+ # convert to standard yml format
148
+ # from: - {step name}
149
+ # - command
150
+ # - command
151
+ # to: -
152
+ # name: {step name}
153
+ # scripts:
154
+ # - command
155
+ # - command
156
+ def yml_adapter
157
+ raise YmlTypeException.new('Hash', 'Step') if @yml_obj.class.to_s != FlowYml::Domain::Fields::TYPE_HASH
158
+
159
+ step_name = @yml_obj.keys[0]
160
+ step_script = @yml_obj.values[0]
161
+ raise RequiredFieldMissingException.new('name') if step_name.nil?
162
+ raise RequiredFieldMissingException.new('scripts') if step_script.nil? || step_script.empty?
163
+
164
+ {:name => step_name, :scripts => step_script}
165
+ end
166
+ end
167
+
168
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+ require 'flow-yml/domain/fields'
3
+
4
+ module FlowYml
5
+ module Domain
6
+
7
+ # Base Config to define attributes which can be overwrite by sub config
8
+ # Config level
9
+ # - project
10
+ # - flow
11
+ class ConfigBase
12
+ include FlowYml::Domain::Fields
13
+
14
+ # optional fields
15
+ field :docker, type: TYPE_STRING, required: false
16
+ field :sudo, type: "#{TYPE_TRUE}|#{TYPE_FALSE}", required: false, default: false
17
+ field :install, type: TYPE_ARRAY, required: false, default: nil, target: TYPE_STRING
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,90 @@
1
+ # encoding: utf-8
2
+
3
+ module FlowYml
4
+ module Domain
5
+ module Fields
6
+
7
+ TYPE_STRING = 'String'
8
+ TYPE_ARRAY = 'Array'
9
+ TYPE_HASH = 'Hash'
10
+ TYPE_TRUE = 'TrueClass'
11
+ TYPE_FALSE = 'FalseClass'
12
+
13
+ TYPE_FLOW = 'Flow'
14
+ TYPE_STEP = 'Step'
15
+
16
+ def self.included(base)
17
+ base.extend ClassMethods
18
+ end
19
+
20
+ # Field meta definition of yml
21
+ # name:Symbol = object name
22
+ # type:String = related yml type, ex: {String, Hash, Array, TrueClass|FalseClass}
23
+ # required:Boolean = is required in yml
24
+ # value:Object = default value of field
25
+ # target:String = Class of Hash value or Array Item
26
+ # skip:Boolean = skip this field
27
+ class YmlFieldMeta
28
+ attr_accessor :name,
29
+ :type,
30
+ :required,
31
+ :value,
32
+ :target,
33
+ :skip
34
+
35
+ def initialize(name, type, required, value, target, skip)
36
+ @name = name
37
+ @type = type
38
+ @required = required
39
+ @value = value
40
+ @target = target
41
+ @skip = skip
42
+ end
43
+ end
44
+
45
+ module ClassMethods
46
+ def field(name, options = {})
47
+ add_meta(name, options)
48
+ add_attribute(name)
49
+ end
50
+
51
+ def add_meta(name, options)
52
+ meta = Fields::YmlFieldMeta.new(name,
53
+ options[:type],
54
+ options[:required],
55
+ options[:default],
56
+ options[:target],
57
+ options[:skip])
58
+
59
+ self.instance_eval do
60
+
61
+ # init meta data
62
+ @meta = {} if @meta.nil?
63
+ @meta[name] = meta
64
+
65
+ # merge superclass meta data
66
+ @meta = @meta.merge(self.superclass.meta) if self.superclass.methods.include? :meta
67
+
68
+ def meta
69
+ @meta
70
+ end
71
+ end
72
+ end
73
+
74
+ def add_attribute(symbol)
75
+ raw = %Q{
76
+ def #{symbol}
77
+ return @#{symbol} unless @#{symbol}.nil?
78
+ self.class.meta[:#{symbol}].value
79
+ end
80
+
81
+ def #{symbol}=(value)
82
+ @#{symbol} = value
83
+ end
84
+ }
85
+ self.class_eval(raw)
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+ require 'flow-yml/domain/fields'
3
+
4
+ module FlowYml
5
+ module Domain
6
+
7
+ class FlowPipeline < ConfigBase
8
+ include FlowYml::Domain::Fields
9
+
10
+ field :branch, type: TYPE_STRING, required: true
11
+ field :steps, type: TYPE_ARRAY, required: true, target: TYPE_STEP
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+
3
+ module FlowYml
4
+ module Domain
5
+
6
+ # Project level configuration
7
+ class Project < ConfigBase
8
+ include FlowYml::Domain::Fields
9
+
10
+ # required fields
11
+ field :project, type: TYPE_STRING, required: true
12
+ field :language, type: TYPE_STRING, required: true
13
+ field :install, type: TYPE_ARRAY, required: false, target: TYPE_STRING
14
+ field :flows, type: TYPE_ARRAY, required: true, target: TYPE_FLOW
15
+ end
16
+ end
17
+ end
18
+
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+ require 'flow-yml/domain/fields'
3
+
4
+ module FlowYml
5
+ module Domain
6
+
7
+ class Step
8
+ include FlowYml::Domain::Fields
9
+
10
+ field :name, type: TYPE_STRING, required: true
11
+ field :scripts, type: TYPE_ARRAY, required: true, target: TYPE_STRING
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ module FlowYml
4
+
5
+ # Required yml field is missing
6
+ class RequiredFieldMissingException < Exception
7
+ def initialize(field)
8
+ super("Required yml field '#{field}' is missing")
9
+ end
10
+ end
11
+
12
+ # Yml field type is wrong
13
+ class YmlTypeException < Exception
14
+ def initialize(type, field)
15
+ super("Required '#{type}' for yml field '#{field}'")
16
+ end
17
+ end
18
+
19
+ # Yml object is missing
20
+ class YmlObjectMissingException < Exception
21
+ def initialize
22
+ super('Yml object cannot be nil')
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,23 @@
1
+ require 'flow-yml/version'
2
+ require 'flow-yml/converter'
3
+ require 'yaml'
4
+
5
+ module FlowYml
6
+
7
+ # main entry of flow yml parser to analysis and convert
8
+ # yml config to project object
9
+ class Parser
10
+ attr_reader :content
11
+
12
+ def initialize(content)
13
+ @content = content
14
+ end
15
+
16
+ # build yml file and return project object
17
+ def build
18
+ yml_obj = YAML::load(@content)
19
+ converter = FlowYml::ProjectConverter.new(yml_obj)
20
+ converter.convert
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,5 @@
1
+ module FlowYml
2
+ class Parser
3
+ VERSION = '0.1.3'
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: flow-yml-parser
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.3
5
+ platform: ruby
6
+ authors:
7
+ - yang.guo
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-12-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.13'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.13'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description: flow.ci config parser
56
+ email:
57
+ - gy@fir.im
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".rspec"
64
+ - Gemfile
65
+ - Gemfile.lock
66
+ - README.md
67
+ - Rakefile
68
+ - bin/console
69
+ - bin/setup
70
+ - flow-yml-parser.gemspec
71
+ - lib/flow-yml-parser.rb
72
+ - lib/flow-yml/converter.rb
73
+ - lib/flow-yml/domain/config_base.rb
74
+ - lib/flow-yml/domain/fields.rb
75
+ - lib/flow-yml/domain/flow_pipeline.rb
76
+ - lib/flow-yml/domain/project.rb
77
+ - lib/flow-yml/domain/step.rb
78
+ - lib/flow-yml/exceptions.rb
79
+ - lib/flow-yml/parser.rb
80
+ - lib/flow-yml/version.rb
81
+ homepage: http://www.flow.ci
82
+ licenses: []
83
+ metadata: {}
84
+ post_install_message:
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: 2.2.0
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ requirements: []
99
+ rubyforge_project:
100
+ rubygems_version: 2.6.8
101
+ signing_key:
102
+ specification_version: 4
103
+ summary: flow.ci config parser
104
+ test_files: []