article_fixture_gen 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.rubocop.yml +6 -0
  4. data/.travis.yml +5 -0
  5. data/CODE_OF_CONDUCT.md +49 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +220 -0
  9. data/Rakefile +48 -0
  10. data/article_fixture_gen.gemspec +55 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +16 -0
  13. data/config.reek +8 -0
  14. data/data/all_specs.yml +127 -0
  15. data/data/validations.yml +35 -0
  16. data/exe/article_fixture_gen +16 -0
  17. data/lib/article_fixture_gen/cli/config.rb +57 -0
  18. data/lib/article_fixture_gen/cli/dump_config.rb +43 -0
  19. data/lib/article_fixture_gen/cli.rb +5 -0
  20. data/lib/article_fixture_gen/config/builder.rb +99 -0
  21. data/lib/article_fixture_gen/config/constants.rb +25 -0
  22. data/lib/article_fixture_gen/config/data.rb +26 -0
  23. data/lib/article_fixture_gen/config/option_validator.rb +74 -0
  24. data/lib/article_fixture_gen/config.rb +45 -0
  25. data/lib/article_fixture_gen/data/article.rb +55 -0
  26. data/lib/article_fixture_gen/data/article_content.rb +64 -0
  27. data/lib/article_fixture_gen/data/build_fragment_list.rb +68 -0
  28. data/lib/article_fixture_gen/data/build_target_entry_list.rb +68 -0
  29. data/lib/article_fixture_gen/data/build_word_list.rb +140 -0
  30. data/lib/article_fixture_gen/data/marker_array.rb +29 -0
  31. data/lib/article_fixture_gen/data/marker_tag_pair.rb +25 -0
  32. data/lib/article_fixture_gen/data/mtp_decorated_markup.rb +67 -0
  33. data/lib/article_fixture_gen/data/node_markup.rb +25 -0
  34. data/lib/article_fixture_gen/data/parent_element_for.rb +18 -0
  35. data/lib/article_fixture_gen/data/pmtp_attributes.rb +44 -0
  36. data/lib/article_fixture_gen/data/pmtp_decorated_markup.rb +27 -0
  37. data/lib/article_fixture_gen/data/pmtp_decorator_params.rb +16 -0
  38. data/lib/article_fixture_gen/data/replace_child_nodes_using_new_child.rb +67 -0
  39. data/lib/article_fixture_gen/data/single_marker_tag_pair.rb +31 -0
  40. data/lib/article_fixture_gen/data/smtp_attributes.rb +30 -0
  41. data/lib/article_fixture_gen/data/smtp_decorated_markup.rb +27 -0
  42. data/lib/article_fixture_gen/data/smtp_decorator_params.rb +16 -0
  43. data/lib/article_fixture_gen/data/split_text_at_target_word.rb +59 -0
  44. data/lib/article_fixture_gen/exe/config.rb +42 -0
  45. data/lib/article_fixture_gen/exe/generate_config.rb +51 -0
  46. data/lib/article_fixture_gen/exe/option_parser/trollop/option_spec.rb +30 -0
  47. data/lib/article_fixture_gen/exe/option_parser/trollop/option_spec_item.rb +16 -0
  48. data/lib/article_fixture_gen/exe/option_parser/trollop/options_and_mods.rb +57 -0
  49. data/lib/article_fixture_gen/exe/option_parser/trollop/options_with_defaults.rb +45 -0
  50. data/lib/article_fixture_gen/exe/option_parser/trollop/validator.rb +63 -0
  51. data/lib/article_fixture_gen/exe/option_parser/trollop.rb +49 -0
  52. data/lib/article_fixture_gen/exe/option_parser.rb +13 -0
  53. data/lib/article_fixture_gen/support/logging.rb +25 -0
  54. data/lib/article_fixture_gen/version.rb +6 -0
  55. data/lib/article_fixture_gen.rb +10 -0
  56. data/lib/tasks/prolog_flog_task.rb +12 -0
  57. data/vendor/ruby/2.3.0/bin/article_fixture_gen +22 -0
  58. metadata +515 -0
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+
5
+ module ArticleFixtureGen
6
+ module Exe
7
+ # Save configuration as YAML to file specified *in* configuration.
8
+ class GenerateConfig
9
+ def self.call(config)
10
+ new(config).call
11
+ end
12
+
13
+ def call
14
+ return unless filename
15
+ write_output
16
+ data.freeze
17
+ end
18
+
19
+ protected
20
+
21
+ def initialize(config)
22
+ @data = Internals.filter_data(config)
23
+ @filename = config.generate_config.to_s
24
+ self
25
+ end
26
+
27
+ private
28
+
29
+ attr_reader :data, :filename
30
+
31
+ OMITTED_KEYS = [:config, :config_given, :generate_config,
32
+ :generate_config_given].freeze
33
+ private_constant :OMITTED_KEYS
34
+
35
+ def write_output
36
+ # Using a File.open block raises an IOError within Psych (YAML internal)
37
+ outf = File.open(filename, 'w')
38
+ YAML.dump data, outf
39
+ outf.close
40
+ end
41
+
42
+ # Stateless methods
43
+ module Internals
44
+ def self.filter_data(config)
45
+ config.to_hash.reject { |attrib, _| OMITTED_KEYS.include? attrib }
46
+ end
47
+ end
48
+ private_constant :Internals
49
+ end # class ArticleFixtureGen::Exe::GenerateConfig
50
+ end
51
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+
5
+ require_relative './option_spec_item'
6
+
7
+ module ArticleFixtureGen
8
+ module Exe
9
+ module Trollop
10
+ # Encapsulate configuration of a Trollop command-line option
11
+ class OptionSpec
12
+ extend Forwardable
13
+
14
+ def initialize(*key_and_desc, **options)
15
+ @item = OptionSpecItem.new key: key_and_desc[0],
16
+ desc: key_and_desc[1], options: options
17
+ # freeze # Cannot freeze data passed to `Trollop.opt`.
18
+ # WTFometer at 11.
19
+ self
20
+ end
21
+
22
+ def add_option(context)
23
+ context.opt key, desc, options
24
+ end
25
+
26
+ def_delegators :@item, :desc, :key, :options
27
+ end # class ArticleFixtureGen::Exe::Trollop::OptionSpec
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'prolog/dry_types'
4
+
5
+ module ArticleFixtureGen
6
+ module Exe
7
+ module Trollop
8
+ # Individual item hash for Trollop data. This can't be frozen per Trollop.
9
+ class OptionSpecItem < Dry::Struct
10
+ attribute :key, Types::Strict::Symbol
11
+ attribute :desc, Types::Strict::String
12
+ attribute :options, Types::Strict::Hash
13
+ end # class ArticleFixtureGen::Exe::Trollop::OptionSpecItem
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './options_with_defaults'
4
+
5
+ module ArticleFixtureGen
6
+ module Exe
7
+ module Trollop
8
+ # Adds modified attributes to lists produced by `OptionsWithDefaults`.
9
+ class OptionsAndMods
10
+ def self.call(all_specs)
11
+ new(all_specs).call
12
+ end
13
+
14
+ def call
15
+ container = OptionsWithDefaults.call(all_specs).to_hash
16
+ container[:modified] = Internals.modified_from(container)
17
+ Result.new container
18
+ end
19
+
20
+ protected
21
+
22
+ def initialize(all_specs)
23
+ @all_specs = all_specs
24
+ self
25
+ end
26
+
27
+ private
28
+
29
+ attr_reader :all_specs
30
+
31
+ # Stateless methods
32
+ module Internals
33
+ def self.modified_from(container)
34
+ _modified_attributes(container).reject do |attrib, _|
35
+ [:help, :version].include? attrib
36
+ end
37
+ end
38
+
39
+ def self._modified_attributes(container)
40
+ container[:options].reject do |attrib, value|
41
+ container[:defaults][attrib] == value
42
+ end
43
+ end
44
+ end
45
+ private_constant :Internals
46
+
47
+ # Encapsulates configured options, default values, and modified options.
48
+ class Result < Dry::Struct
49
+ attribute :defaults, Types::Strict::Hash
50
+ attribute :modified, Types::Strict::Hash
51
+ attribute :options, Types::Strict::Hash
52
+ end
53
+ private_constant :Result
54
+ end # class ArticleFixtureGen::Exe::Trollop::OptionsAndMods
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'trollop'
4
+
5
+ module ArticleFixtureGen
6
+ module Exe
7
+ module Trollop
8
+ # Builds an encapsulation of Trollop option menu and default values.
9
+ class OptionsWithDefaults
10
+ USAGE_BANNER = \
11
+ "Generates article/blog post fixture data based on settings.\n" \
12
+ "Usage:\n\n" \
13
+ " #{File.basename($PROGRAM_NAME)} [options]\n\n" \
14
+ 'where [options] are any of:'
15
+ private_constant :USAGE_BANNER
16
+
17
+ VERSION_BANNER = "#{$PROGRAM_NAME} Version " \
18
+ "#{ArticleFixtureGen::VERSION}\n" \
19
+ 'Copyright (c)2016, Jeff Dickey and Prolog Systems (S) Pte Ltd'
20
+ private_constant :VERSION_BANNER
21
+
22
+ # Reek says this method has :reek:TooManyStatements. Such is a DSL.
23
+ def self.call(all_specs)
24
+ defaults = {}
25
+ options = ::Trollop.options do
26
+ version VERSION_BANNER
27
+ banner USAGE_BANNER
28
+ all_specs.map { |spec| spec.add_option self }
29
+ # Reminder: `all_specs` is our data. `Trollop.specs` is valid only
30
+ # inside the `.options` block
31
+ specs.each { |attrib, spec| defaults[attrib] = spec[:default] }
32
+ end
33
+ Result.new defaults: defaults, options: options
34
+ end
35
+
36
+ # Encapsulates Trollop option menu and default values.
37
+ class Result < Dry::Struct
38
+ attribute :defaults, Types::Strict::Hash
39
+ attribute :options, Types::Strict::Hash
40
+ end
41
+ private_constant :Result
42
+ end # class ArticleFixtureGen::Exe::Trollop::OptionsWithDefaults
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'trollop'
4
+
5
+ module ArticleFixtureGen
6
+ module Exe
7
+ module Trollop
8
+ # Validates attribute values using evaled code from YAML file.
9
+ class Validator
10
+ def self.call(option_data)
11
+ new(option_data).call
12
+ end
13
+
14
+ def call
15
+ Internals.validations.map do |validation|
16
+ validate(validation)
17
+ end
18
+ option_data
19
+ end
20
+
21
+ protected
22
+
23
+ def initialize(option_data)
24
+ @option_data = option_data
25
+ self
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :option_data
31
+
32
+ def options
33
+ option_data.options
34
+ end
35
+
36
+ # Reek calls out :reek:FeatureEnvy on `validation`. Pffft.
37
+ def validate(validation)
38
+ die_params = [validation[:key], validation[:str]]
39
+ ::Trollop.die(*die_params) if validation_failed?(validation)
40
+ true
41
+ end
42
+
43
+ def validation_failed?(validation)
44
+ validation_proc_for(validation).call options
45
+ end
46
+
47
+ def validation_proc_for(validation)
48
+ # rubocop:disable Lint/Eval
49
+ eval(validation[:fails_with])
50
+ # rubocop:enable Lint/Eval
51
+ end
52
+
53
+ # Stateless methods
54
+ module Internals
55
+ def self.validations
56
+ YAML.load_file 'data/validations.yml'
57
+ end
58
+ end
59
+ private_constant :Internals
60
+ end # class ArticleFixtureGen::Exe::Trollop::Validator
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'trollop'
4
+
5
+ require 'prolog/dry_types'
6
+
7
+ require_relative './trollop/option_spec'
8
+ require_relative './trollop/options_and_mods'
9
+ require_relative './trollop/validator'
10
+
11
+ module ArticleFixtureGen
12
+ module Exe
13
+ module Trollop
14
+ # Parse command-line options using Trollop. Note that Trollop is one-shot
15
+ # stateful; it is apparently not possible to reset/rewind status once a
16
+ # command line has been parsed without writing directly to ARGV.
17
+ class OptionParser
18
+ def self.call
19
+ option_data = OptionsAndMods.call Internals.all_specs
20
+ Internals.result_from option_data
21
+ end
22
+
23
+ # Stateless methods
24
+ module Internals
25
+ # NOTE: This is only "direct" user of `OptionSpec`, which is only
26
+ # direct user of `OptionSpecItem`.
27
+ def self.all_specs
28
+ YAML.load_file 'data/all_specs.yml'
29
+ end
30
+
31
+ def self.result_from(option_data)
32
+ # validate(option_data)
33
+ Validator.call option_data
34
+ Result.new modified: option_data.modified,
35
+ options: option_data.options
36
+ end
37
+ end
38
+ private_constant :Internals
39
+
40
+ # Encapsulates active and modified command-line option data.
41
+ class Result < Dry::Struct
42
+ attribute :modified, Types::Hash
43
+ attribute :options, Types::Hash
44
+ end
45
+ private_constant :Result
46
+ end # class ArticleFixtureGen::Exe::Trollop::OptionParser
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'option_parser/trollop'
4
+
5
+ module ArticleFixtureGen
6
+ module Exe
7
+ # Individual item hash based on parser, such as Trollop. To change to a
8
+ # different parser, implement an equivalent of `Trollop::OptionParser` with
9
+ # the new parser and change the parent class of this class. Voila.
10
+ class OptionParser < Trollop::OptionParser
11
+ end # class ArticleFixtureGen::Exe::OptionParser
12
+ end
13
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'semantic_logger'
4
+
5
+ log_env_str = ENV['RACK_ENV'] || 'dev'
6
+ log_fname = "log/#{log_env_str}.log"
7
+ log_level_default = %w(dev test).include?(log_env_str) ? 'trace' : 'info'
8
+ log_level_str = ENV['LOG_LEVEL'] || log_level_default
9
+
10
+ # Variations:
11
+ #
12
+ # 1. `bundle exec ruby test/path/to/your_test.rb` will log to `log/test.log` at
13
+ # log level `info` unless your environment variables are set to override;
14
+ # 2. `RACK_ENV=dev bundle exec ruby test/path/to/your_test.rb` will log to
15
+ # `log/dev.log` at log level `trace` unless the `LOG_LEVEL` environment
16
+ # variable overrides the level setting;
17
+ # 3. `LOG_LEVEL=trace bundle exec ruby test/path/to/your_test.rb` will log to
18
+ # `log/test.log` unless the `RACK_ENV` setting overrides the filename, at log
19
+ # level `trace`.
20
+ #
21
+ # The file `test/test_helper.rb` sets the default `RACK_ENV` to `test` unless
22
+ # already set.
23
+
24
+ SemanticLogger.default_level = log_level_str.downcase.to_sym
25
+ SemanticLogger.add_appender file_name: log_fname, formatter: :color
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Generate blog post/article fixture data, with embedded marker tag pairs.
4
+ module ArticleFixtureGen
5
+ VERSION = '0.1.1'
6
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'article_fixture_gen/data/article'
4
+ require 'article_fixture_gen/config'
5
+ require 'article_fixture_gen/version'
6
+
7
+ # Generate blog post/article fixture data, with embedded marker tag pairs.
8
+ module ArticleFixtureGen
9
+ # Your code goes here...
10
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rake/tasklib'
4
+ require 'flog'
5
+ require 'flog_task'
6
+
7
+ # Redefinition of standard task's Rake invocation. Because we don't like
8
+ # inconsistency in option settings.
9
+ class FlogTask < Rake::TaskLib
10
+ # Reek bitches that this is a :reek:Attribute (writable). That's the *point*.
11
+ attr_accessor :methods_only
12
+ end
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by RubyGems.
4
+ #
5
+ # The application 'article_fixture_gen' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'rubygems'
10
+
11
+ version = ">= 0.a"
12
+
13
+ if ARGV.first
14
+ str = ARGV.first
15
+ str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
16
+ if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
17
+ version = $1
18
+ ARGV.shift
19
+ end
20
+ end
21
+
22
+ load Gem.activate_bin_path('article_fixture_gen', 'article_fixture_gen', version)