article_fixture_gen 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rubocop.yml +6 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +220 -0
- data/Rakefile +48 -0
- data/article_fixture_gen.gemspec +55 -0
- data/bin/console +14 -0
- data/bin/setup +16 -0
- data/config.reek +8 -0
- data/data/all_specs.yml +127 -0
- data/data/validations.yml +35 -0
- data/exe/article_fixture_gen +16 -0
- data/lib/article_fixture_gen/cli/config.rb +57 -0
- data/lib/article_fixture_gen/cli/dump_config.rb +43 -0
- data/lib/article_fixture_gen/cli.rb +5 -0
- data/lib/article_fixture_gen/config/builder.rb +99 -0
- data/lib/article_fixture_gen/config/constants.rb +25 -0
- data/lib/article_fixture_gen/config/data.rb +26 -0
- data/lib/article_fixture_gen/config/option_validator.rb +74 -0
- data/lib/article_fixture_gen/config.rb +45 -0
- data/lib/article_fixture_gen/data/article.rb +55 -0
- data/lib/article_fixture_gen/data/article_content.rb +64 -0
- data/lib/article_fixture_gen/data/build_fragment_list.rb +68 -0
- data/lib/article_fixture_gen/data/build_target_entry_list.rb +68 -0
- data/lib/article_fixture_gen/data/build_word_list.rb +140 -0
- data/lib/article_fixture_gen/data/marker_array.rb +29 -0
- data/lib/article_fixture_gen/data/marker_tag_pair.rb +25 -0
- data/lib/article_fixture_gen/data/mtp_decorated_markup.rb +67 -0
- data/lib/article_fixture_gen/data/node_markup.rb +25 -0
- data/lib/article_fixture_gen/data/parent_element_for.rb +18 -0
- data/lib/article_fixture_gen/data/pmtp_attributes.rb +44 -0
- data/lib/article_fixture_gen/data/pmtp_decorated_markup.rb +27 -0
- data/lib/article_fixture_gen/data/pmtp_decorator_params.rb +16 -0
- data/lib/article_fixture_gen/data/replace_child_nodes_using_new_child.rb +67 -0
- data/lib/article_fixture_gen/data/single_marker_tag_pair.rb +31 -0
- data/lib/article_fixture_gen/data/smtp_attributes.rb +30 -0
- data/lib/article_fixture_gen/data/smtp_decorated_markup.rb +27 -0
- data/lib/article_fixture_gen/data/smtp_decorator_params.rb +16 -0
- data/lib/article_fixture_gen/data/split_text_at_target_word.rb +59 -0
- data/lib/article_fixture_gen/exe/config.rb +42 -0
- data/lib/article_fixture_gen/exe/generate_config.rb +51 -0
- data/lib/article_fixture_gen/exe/option_parser/trollop/option_spec.rb +30 -0
- data/lib/article_fixture_gen/exe/option_parser/trollop/option_spec_item.rb +16 -0
- data/lib/article_fixture_gen/exe/option_parser/trollop/options_and_mods.rb +57 -0
- data/lib/article_fixture_gen/exe/option_parser/trollop/options_with_defaults.rb +45 -0
- data/lib/article_fixture_gen/exe/option_parser/trollop/validator.rb +63 -0
- data/lib/article_fixture_gen/exe/option_parser/trollop.rb +49 -0
- data/lib/article_fixture_gen/exe/option_parser.rb +13 -0
- data/lib/article_fixture_gen/support/logging.rb +25 -0
- data/lib/article_fixture_gen/version.rb +6 -0
- data/lib/article_fixture_gen.rb +10 -0
- data/lib/tasks/prolog_flog_task.rb +12 -0
- data/vendor/ruby/2.3.0/bin/article_fixture_gen +22 -0
- 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,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)
|