fixer_upper 0.4.0 → 0.5.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cd048ff747c17e9b203c63f89ba9c39ac1d7894b
4
- data.tar.gz: ad1cf61e1c489d37519618782692f3c42db748d6
3
+ metadata.gz: 0bcbce16e5c4f9fb5a1b5d78322f9b2241c465b5
4
+ data.tar.gz: 51eb5aa25ae838861ab386c763d69568a94e391a
5
5
  SHA512:
6
- metadata.gz: fccbaf7810c6ef7f114f7021afa0b0e7f5075d1bcfbf3206411b37baa1b62272612320deec52dcdc14477b3b4dd2985044be915dffc2b47f2f9e8d83439d6d23
7
- data.tar.gz: 92b70790d2bda9592d21a4bb7a8fdd256a3e741be62e13802140238b566dab186afb0cdf3ccc16aea84ce1ce48893f634d043a2bbbf787f0aa3c083085bed7e4
6
+ metadata.gz: 677fa1150394d40b81d7c158d248d61766dda95ba18099434e7f4ef578a9f0d0f3c780c2b742a91f1a38fed7a5c73a261a48b27dfd8a4ef9ea486b34448d5886
7
+ data.tar.gz: 2169743b4cd1dd240adaea91eec433a0ac3594a661ab4fcad5ca7b9a1c87642f2ffcd7430e4ca05d8a37633c9de32427163d52895b440af7b085c44882ce10ce
data/.rubocop.yml CHANGED
@@ -1,55 +1,5 @@
1
- AllCops:
2
- DisplayCopNames: true
1
+ inherit_gem:
2
+ the_bath_of_zahn: rubocop.yml
3
3
 
4
- Bundler/OrderedGems:
4
+ Metrics/ParameterLists:
5
5
  Enabled: false
6
-
7
- Metrics/LineLength:
8
- IgnoredPatterns:
9
- - !ruby/regexp /^\s*#/
10
-
11
- Metrics/MethodLength:
12
- Exclude:
13
- - test/**/*.rb
14
-
15
- Style/AlignParameters:
16
- EnforcedStyle: with_fixed_indentation
17
-
18
- Style/AsciiComments:
19
- Enabled: false
20
-
21
- Style/Documentation:
22
- Enabled: false
23
-
24
- Style/EmptyMethod:
25
- Enabled: false
26
-
27
- Style/ExtraSpacing:
28
- AllowForAlignment: false
29
-
30
- Style/FrozenStringLiteralComment:
31
- Enabled: false
32
-
33
- Style/GuardClause:
34
- Enabled: false
35
-
36
- Style/IfUnlessModifier:
37
- Enabled: false
38
-
39
- Style/MultilineMethodCallIndentation:
40
- EnforcedStyle: indented_relative_to_receiver
41
-
42
- Style/NegatedIf:
43
- Enabled: false
44
-
45
- Style/SpaceInLambdaLiteral:
46
- EnforcedStyle: require_space
47
-
48
- Style/StringLiterals:
49
- EnforcedStyle: double_quotes
50
-
51
- Style/StringLiteralsInInterpolation:
52
- Enabled: false
53
-
54
- Style/TrailingCommaInLiteral:
55
- EnforcedStyleForMultiline: comma
data/README.md CHANGED
@@ -8,39 +8,84 @@ Gut job or not, FixerUpper makes that file into the result of your dreams,
8
8
  backsplash, shiplap, and all.
9
9
 
10
10
 
11
- ## Installation
11
+ ## Usage
12
12
 
13
- Add this line to your application's Gemfile:
13
+ FixerUpper is a wrapper around Tilt template engines.
14
+
15
+ It requires explicit registration of template engines:
14
16
 
15
17
  ```ruby
16
- gem "fixer_upper"
18
+ fixer_upper = FixerUpper.new
19
+ fixer_upper.register_tilt("erb", engine: Tilt::ERBTemplate)
20
+
21
+ renderer =
22
+ fixer_upper.renderer(
23
+ filename: "file.erb",
24
+ content: %(<%= 1 + 1 %>),
25
+ engines: %i[erb]
26
+ )
27
+ renderer.call # => "2"
17
28
  ```
18
29
 
19
- And then execute:
20
-
21
- $ bundle
30
+ It allows for setting "global" options.
22
31
 
32
+ ```ruby
33
+ fixer_upper = FixerUpper.new
34
+ fixer_upper.register_tilt(
35
+ "csv",
36
+ engine: Tilt::CSVTemplate,
37
+ options: { col_sep: "|" }
38
+ )
39
+
40
+ template = %(csv << ["hello", "world"])
41
+
42
+ renderer =
43
+ fixer_upper.renderer(
44
+ filename: "file.csv",
45
+ content: template,
46
+ engines: %i[csv]
47
+ )
48
+ renderer.call # => "hello|world\n"
49
+ ```
23
50
 
24
- ## Usage
51
+ It works with non-tilt templates as well
25
52
 
26
53
  ```ruby
27
- require "commonmarker"
54
+ class Upcase
55
+ def initialize(_filename, memo)
56
+ @memo = memo
57
+ end
28
58
 
29
- class FixerUpperCmark
30
- def call(text, parse_option: :DEFAULT)
31
- CommonMarker.render_html(text, parse_option)
59
+ def render(_view_scope, &block)
60
+ @memo.upcase
32
61
  end
33
62
  end
34
63
 
35
64
  fixer_upper = FixerUpper.new
36
- fixer_upper.register("md", "markdown", to: FixerUpperCmark.new, \
37
- parse_option: :HARDBREAKS)
65
+ fixer_upper.register("upcase", engine: Upcase)
66
+
67
+ renderer =
68
+ fixer_upper.renderer(
69
+ filename: "file.upcase",
70
+ content: "hi",
71
+ engines: %i[upcase]
72
+ )
73
+ renderer.call # => "HI"
74
+ ```
75
+
76
+
77
+ ## Installation
78
+
79
+ Add this line to your application's Gemfile:
38
80
 
39
- fixer_upper.renovate("file.md")
40
- # OR
41
- fixer_upper.diy("**text**", "md")
81
+ ```ruby
82
+ gem "fixer_upper"
42
83
  ```
43
84
 
85
+ And then execute:
86
+
87
+ $ bundle
88
+
44
89
 
45
90
  ## Development
46
91
 
data/fixer_upper.gemspec CHANGED
@@ -23,10 +23,13 @@ Gem::Specification.new do |spec|
23
23
 
24
24
  spec.required_ruby_version = ">= 2.1.0"
25
25
 
26
+ spec.add_runtime_dependency "tilt", "~> 2.0"
27
+
26
28
  spec.add_development_dependency "bundler", "~> 1.14"
27
29
  spec.add_development_dependency "rake", "~> 10.0"
28
30
  spec.add_development_dependency "minitest", "~> 5.0"
29
31
  spec.add_development_dependency "pry"
30
32
  spec.add_development_dependency "rubocop"
31
33
  spec.add_development_dependency "sass"
34
+ spec.add_development_dependency "the_bath_of_zahn"
32
35
  end
data/lib/fixer_upper.rb CHANGED
@@ -1,63 +1,24 @@
1
- require "fixer_upper/contractor"
1
+ require "forwardable"
2
+
3
+ require "tilt"
4
+
2
5
  require "fixer_upper/error"
3
- require "fixer_upper/renovation"
6
+ require "fixer_upper/engine_registry"
7
+ require "fixer_upper/renderer"
8
+ require "fixer_upper/tilt_template_bridge"
4
9
  require "fixer_upper/version"
5
10
 
6
11
  class FixerUpper
7
- def initialize
8
- @engine_registry = {}
9
- @options_registry = {}
10
- @renovation = Renovation.new(@engine_registry, @options_registry)
11
- end
12
-
13
- def register(*keys, to:, **options)
14
- keys.each do |key|
15
- @engine_registry[key] = to
16
- @options_registry[key] = options
17
- end
18
- end
12
+ extend Forwardable
19
13
 
20
- def for(key)
21
- @engine_registry[key]
22
- end
23
-
24
- def renovate(filepath, contents = nil, **options, &block)
25
- @renovation.renovate(
26
- filepath: filepath,
27
- text: contents,
28
- options: options,
29
- block: block,
30
- bang: false
31
- )
32
- end
14
+ def_delegator :@engine_registry, :register
15
+ def_delegator :@engine_registry, :register_tilt
33
16
 
34
- def renovate!(filepath, contents = nil, **options, &block)
35
- @renovation.renovate(
36
- filepath: filepath,
37
- text: contents,
38
- options: options,
39
- block: block,
40
- bang: true
41
- )
42
- end
43
-
44
- def diy(text, *engines, **options, &block)
45
- @renovation.diy(
46
- text: text,
47
- engines: engines,
48
- options: options,
49
- block: block,
50
- bang: false
51
- )
17
+ def initialize
18
+ @engine_registry = EngineRegistry.new
52
19
  end
53
20
 
54
- def diy!(text, *engines, **options, &block)
55
- @renovation.diy(
56
- text: text,
57
- engines: engines,
58
- options: options,
59
- block: block,
60
- bang: true
61
- )
21
+ def renderer(**args)
22
+ Renderer.new(engine_registry: @engine_registry, **args)
62
23
  end
63
24
  end
@@ -0,0 +1,70 @@
1
+ class FixerUpper
2
+ class EngineRegistry
3
+ def initialize
4
+ @engines = {}
5
+ end
6
+
7
+ def register(*names, engine:, options: {})
8
+ if definitely_like_tilt_template?(engine)
9
+ register_tilt(*names, engine: engine, options: options)
10
+ else
11
+ register_fixer_upper(names, engine, options)
12
+ end
13
+ end
14
+
15
+ def register_tilt(*names, engine:, options: {})
16
+ engine_bridge =
17
+ TiltTemplateClassBridge.new(engine, options)
18
+
19
+ names.each do |name|
20
+ register_single(name, engine_bridge)
21
+ end
22
+ end
23
+
24
+ def engine?(engine)
25
+ @engines.key?(engine.to_s)
26
+ end
27
+
28
+ def [](engine_name)
29
+ @engines[engine_name.to_s]
30
+ end
31
+
32
+ private
33
+
34
+ def definitely_like_tilt_template?(engine)
35
+ engine < Tilt::Template
36
+ end
37
+
38
+ def engine_class_name(engine)
39
+ if engine.is_a?(TiltTemplateClassBridge)
40
+ engine.tilt_engine_class.name
41
+ else
42
+ engine.name
43
+ end
44
+ end
45
+
46
+ def register_fixer_upper(names, engine, options)
47
+ if options.any?
48
+ raise Error::EngineDoesntAcceptOptions, \
49
+ "Only Tilt templates can accept options"
50
+ end
51
+
52
+ names.each do |name|
53
+ register_single(name, engine)
54
+ end
55
+ end
56
+
57
+ def register_single(name, engine)
58
+ if engine?(name)
59
+ existing_engine = self[name]
60
+
61
+ raise Error::MultipleEnginesForOneName, \
62
+ "Trying to register `#{engine_class_name(engine)}` " \
63
+ "to the name `#{name}`, " \
64
+ "but `#{engine_class_name(existing_engine)}` is already registered."
65
+ end
66
+
67
+ @engines[name.to_s] = engine
68
+ end
69
+ end
70
+ end
@@ -1,6 +1,9 @@
1
1
  class FixerUpper
2
2
  class Error < StandardError
3
- class EngineNotFound < FixerUpper::Error
3
+ class MultipleEnginesForOneName < Error
4
+ end
5
+
6
+ class EngineDoesntAcceptOptions < Error
4
7
  end
5
8
  end
6
9
  end
@@ -0,0 +1,45 @@
1
+ class FixerUpper
2
+ class Renderer
3
+ attr_reader :engines
4
+
5
+ def initialize(engine_registry:,
6
+ filename:,
7
+ content:,
8
+ engines:,
9
+ view_scope: nil,
10
+ block: nil)
11
+ @engine_registry = engine_registry
12
+
13
+ @filename = filename
14
+ @content = content
15
+ @engines = engines || []
16
+ @view_scope = view_scope
17
+ @block = block
18
+ end
19
+
20
+ def call
21
+ @engines.reduce(@content) do |memo, engine|
22
+ if @engine_registry.engine?(engine)
23
+ render_engine(engine, memo)
24
+ else
25
+ memo
26
+ end
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def render_engine(engine, memo)
33
+ fixer_upper_engine_class = @engine_registry[engine]
34
+
35
+ fixer_upper_engine = fixer_upper_engine_class.new(@filename, memo)
36
+
37
+ fixer_upper_engine.render(@view_scope, &@block)
38
+ end
39
+
40
+ def compute_extensions
41
+ basename = File.basename(@filename)
42
+ basename.split(".")[1..-1]
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,26 @@
1
+ class FixerUpper
2
+ class TiltTemplateClassBridge
3
+ attr_reader :tilt_engine_class
4
+
5
+ def initialize(engine, options)
6
+ @tilt_engine_class = engine
7
+ @options = options
8
+ end
9
+
10
+ def new(filename, content)
11
+ tilt_engine = @tilt_engine_class.new(filename, 1, @options) { content }
12
+
13
+ TiltTemplateInstanceBridge.new(tilt_engine)
14
+ end
15
+ end
16
+
17
+ class TiltTemplateInstanceBridge
18
+ def initialize(tilt_engine)
19
+ @tilt_engine = tilt_engine
20
+ end
21
+
22
+ def render(view_scope, &block)
23
+ @tilt_engine.render(view_scope, {}, &block)
24
+ end
25
+ end
26
+ end
@@ -1,3 +1,3 @@
1
1
  class FixerUpper
2
- VERSION = "0.4.0".freeze
2
+ VERSION = "0.5.0".freeze
3
3
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fixer_upper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zach Ahn
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-05-27 00:00:00.000000000 Z
11
+ date: 2017-06-30 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: tilt
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +108,20 @@ dependencies:
94
108
  - - ">="
95
109
  - !ruby/object:Gem::Version
96
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: the_bath_of_zahn
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
97
125
  description: Simple interface for template engines
98
126
  email:
99
127
  - engineering@zachahn.com
@@ -114,12 +142,10 @@ files:
114
142
  - bin/setup
115
143
  - fixer_upper.gemspec
116
144
  - lib/fixer_upper.rb
117
- - lib/fixer_upper/contractor.rb
118
- - lib/fixer_upper/engine/erb.rb
119
- - lib/fixer_upper/engine/noop.rb
120
- - lib/fixer_upper/engine/scss.rb
145
+ - lib/fixer_upper/engine_registry.rb
121
146
  - lib/fixer_upper/error.rb
122
- - lib/fixer_upper/renovation.rb
147
+ - lib/fixer_upper/renderer.rb
148
+ - lib/fixer_upper/tilt_template_bridge.rb
123
149
  - lib/fixer_upper/version.rb
124
150
  homepage:
125
151
  licenses:
@@ -1,77 +0,0 @@
1
- class FixerUpper
2
- class Contractor
3
- def initialize(registry, options)
4
- @registry = registry
5
- @options = options
6
- end
7
-
8
- def call(text:, engines:, options:, filepath:, block:, bang:)
9
- engines.reduce(text) do |memo, engine_name|
10
- engine = find_engine(engine_name, bang)
11
-
12
- if engine.nil?
13
- next memo
14
- end
15
-
16
- parameters = parameters_for(engine)
17
- merged_options =
18
- options_for_engine(engine_name, options, parameters, filepath)
19
-
20
- engine_invoke(engine, memo, merged_options, parameters, block)
21
- end
22
- end
23
-
24
- private
25
-
26
- def find_engine(engine_name, bang)
27
- if bang
28
- engine_or_raise(engine_name)
29
- else
30
- engine_or_nil(engine_name)
31
- end
32
- end
33
-
34
- def engine_invoke(engine, text, options, parameters, block)
35
- if options.any? && parameters.count >= 2
36
- engine.call(text, **options, &block)
37
- else
38
- engine.call(text, &block)
39
- end
40
- end
41
-
42
- def parameters_for(engine)
43
- if engine.respond_to?(:parameters)
44
- engine.parameters
45
- else
46
- engine.method(:call).parameters
47
- end
48
- end
49
-
50
- def options_for_engine(engine_name, local_options, parameters, filepath)
51
- default_options = @options[engine_name] || {}
52
- specific_options = local_options[engine_name.to_sym] || {}
53
-
54
- merged_options = default_options.merge(specific_options)
55
-
56
- if parameters.include?([:keyreq, :filepath])
57
- merged_options[:filepath] = filepath
58
- end
59
-
60
- merged_options
61
- end
62
-
63
- def engine_or_nil(engine_name)
64
- @registry[engine_name]
65
- end
66
-
67
- def engine_or_raise(engine_name)
68
- found_engine = @registry[engine_name]
69
-
70
- if found_engine
71
- found_engine
72
- else
73
- raise Error::EngineNotFound, "unknown engine: `#{engine_name}`"
74
- end
75
- end
76
- end
77
- end
@@ -1,13 +0,0 @@
1
- class FixerUpper
2
- module Engine
3
- class Erb
4
- def call(text, scope:, filepath:, &block)
5
- scope_binding = scope.instance_eval { binding }
6
-
7
- erb = ::ERB.new(text)
8
- erb.filename = filepath
9
- erb.result(scope_binding)
10
- end
11
- end
12
- end
13
- end
@@ -1,9 +0,0 @@
1
- class FixerUpper
2
- module Engine
3
- class Noop
4
- def call(text)
5
- text
6
- end
7
- end
8
- end
9
- end
@@ -1,12 +0,0 @@
1
- class FixerUpper
2
- module Engine
3
- class Scss
4
- def call(text, filepath:, **options)
5
- options = options.merge(syntax: :scss, filename: filepath)
6
-
7
- engine = ::Sass::Engine.new(text, **options)
8
- engine.render
9
- end
10
- end
11
- end
12
- end
@@ -1,50 +0,0 @@
1
- class FixerUpper
2
- class Renovation
3
- def initialize(registry, options)
4
- @registry = registry
5
- @options = options
6
- end
7
-
8
- def renovate(filepath:, text: nil, options:, block: nil, bang:)
9
- contents = file_contents(filepath, text)
10
-
11
- diy(
12
- text: contents,
13
- engines: extensions(filepath).reverse,
14
- options: options,
15
- filepath: filepath,
16
- block: block,
17
- bang: bang
18
- )
19
- end
20
-
21
- def diy(text:, engines:, options:, filepath: nil, block: nil, bang:)
22
- contractor = Contractor.new(@registry, @options)
23
- contractor.call(
24
- text: text,
25
- engines: engines,
26
- options: options,
27
- filepath: filepath,
28
- block: block,
29
- bang: bang
30
- )
31
- end
32
-
33
- private
34
-
35
- def file_contents(filepath, contents)
36
- if contents
37
- contents
38
- else
39
- File.read(filepath)
40
- end
41
- end
42
-
43
- def extensions(filepath)
44
- filename = File.basename(filepath)
45
- divided_by_dots = filename.split(".")
46
-
47
- divided_by_dots[1..-1]
48
- end
49
- end
50
- end