beachio-hammer 0.1.0.pre1 → 0.1.0.pre3
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 +4 -4
- data/Gemfile.lock +1 -1
- data/PUBLISH.md +68 -2
- data/exe/hammer +3 -0
- data/lib/beachio-hammer.rb +4 -0
- data/lib/hammer/builder.rb +2 -2
- data/lib/hammer/content/config.rb +1 -1
- data/lib/hammer/content/document.rb +2 -2
- data/lib/hammer/content/expression_evaluator.rb +1 -1
- data/lib/hammer/content/helpers.rb +1 -1
- data/lib/hammer/content/page_generator.rb +3 -1
- data/lib/hammer/content/parser.rb +2 -2
- data/lib/hammer/css_parser.rb +1 -1
- data/lib/hammer/ignore.rb +1 -1
- data/lib/hammer/io.rb +9 -0
- data/lib/hammer/sitemap_generator.rb +1 -1
- data/lib/hammer/tag_parser.rb +72 -35
- data/lib/hammer/version.rb +1 -1
- data/spec/encoding_spec.rb +24 -0
- data/spec/path_resolution_spec.rb +26 -0
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9ff203a27e8f29525a3120a073279ab2e8578f9d60a49a7f1c62c7ebf1a59253
|
|
4
|
+
data.tar.gz: e706eaee172b73d6abf8c14f7d936adb48144b2c4b2fc8ebdbf44fcfb9952f81
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 47a316f9de1c74ec4c16881c2663ab8aa172256264fe6e7aa66aa84d95f7d26a8082bdf521bc998bcb26f5e8bc621b8b05c6301034ead326e2dbb8271e292185
|
|
7
|
+
data.tar.gz: 3c5cbc689cb680d0e3adf630adfc2add3f13285aebdd2f6dae258ea83deff4a7364dfe609ac816e638dab2b732ab2cf63404b9effe1d5424afb8ac182e7e35d0
|
data/Gemfile.lock
CHANGED
data/PUBLISH.md
CHANGED
|
@@ -10,8 +10,21 @@ bundle exec rspec
|
|
|
10
10
|
|
|
11
11
|
## Capture golden Build/ trees (macOS Swift CLI)
|
|
12
12
|
|
|
13
|
+
From repo root:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
./gem/scripts/capture-goldens.sh
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Or manually:
|
|
20
|
+
|
|
13
21
|
```bash
|
|
14
|
-
./
|
|
22
|
+
xcodebuild -project Hammer-Swift.xcodeproj -scheme hammer-cli -configuration Release -derivedDataPath ./build-derived build
|
|
23
|
+
./build-derived/Build/Products/Release/hammer build \
|
|
24
|
+
--project "Test Projects/classic-fixture" --mode export --clean --quiet
|
|
25
|
+
./build-derived/Build/Products/Release/hammer build \
|
|
26
|
+
--project "Test Projects/content-generation-test" --mode export --clean --quiet
|
|
27
|
+
git add -f "Test Projects/classic-fixture/Build" "Test Projects/content-generation-test/Build"
|
|
15
28
|
```
|
|
16
29
|
|
|
17
30
|
## Publish to RubyGems
|
|
@@ -25,10 +38,63 @@ gem build beachio-hammer.gemspec
|
|
|
25
38
|
gem push beachio-hammer-*.gem
|
|
26
39
|
```
|
|
27
40
|
|
|
41
|
+
Prerelease pin for executor team: **`beachio-hammer` `0.1.0.pre3`**
|
|
42
|
+
|
|
43
|
+
### 0.1.0.pre3 changes (nested @path resolution)
|
|
44
|
+
|
|
45
|
+
- Resolve `@path` using full path segments (not basename only)
|
|
46
|
+
- Resolve directory paths via `index.html` lookup
|
|
47
|
+
- Always emit context-aware relative URLs (Swift parity)
|
|
48
|
+
|
|
49
|
+
### 0.1.0.pre2 changes (Beachio / Linux fixes)
|
|
50
|
+
|
|
51
|
+
- Force UTF-8 text reads (`Hammer.read_text`) — fixes `invalid byte sequence in US-ASCII` on Render
|
|
52
|
+
- `require "date"` for content pipeline
|
|
53
|
+
- `find_file` skips directories (Swift parity)
|
|
54
|
+
- `resolve_output_path` returns empty when collection has no output pattern
|
|
55
|
+
|
|
28
56
|
## hammer-cloud integration
|
|
29
57
|
|
|
30
58
|
Pin the published gem version in the executor Dockerfile:
|
|
31
59
|
|
|
32
60
|
```dockerfile
|
|
33
|
-
RUN gem install beachio-hammer -v 0.1.0.
|
|
61
|
+
RUN gem install beachio-hammer -v 0.1.0.pre3
|
|
34
62
|
```
|
|
63
|
+
|
|
64
|
+
Build step in the agent:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
hammer build --project "$WORKSPACE" --mode export --format json --clean
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### CLI contract
|
|
71
|
+
|
|
72
|
+
| Flag | Default | Notes |
|
|
73
|
+
|------|---------|-------|
|
|
74
|
+
| `--project` | cwd (walk-up for markers) | Project root |
|
|
75
|
+
| `--output` | `<project>/Build` | Output directory |
|
|
76
|
+
| `--mode` | `export` | `normal`, `export`, `publish` |
|
|
77
|
+
| `--format` | `human` | `json` for agent parsing |
|
|
78
|
+
| `--clean` | off | Wipes Build/ before compile |
|
|
79
|
+
|
|
80
|
+
**Exit codes:** `0` success, `1` build errors, `2` config error, `3` internal.
|
|
81
|
+
|
|
82
|
+
**JSON stdout** (`--format json`):
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"status": "success",
|
|
87
|
+
"stats": { "filesProcessed", "errors", "warnings", "durationMs", "buildSize" },
|
|
88
|
+
"errors": [{ "file", "message" }],
|
|
89
|
+
"warnings": [{ "file", "message" }]
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Parity fixtures
|
|
94
|
+
|
|
95
|
+
| Fixture | Path | Files |
|
|
96
|
+
|---------|------|-------|
|
|
97
|
+
| Classic | `Test Projects/classic-fixture` | 9 |
|
|
98
|
+
| Content | `Test Projects/content-generation-test` | 13 |
|
|
99
|
+
|
|
100
|
+
CI: `.github/workflows/gem-parity.yml` — macOS re-exports goldens, Linux runs `bundle exec rspec`.
|
data/exe/hammer
CHANGED
data/lib/beachio-hammer.rb
CHANGED
data/lib/hammer/builder.rb
CHANGED
|
@@ -134,7 +134,7 @@ module Hammer
|
|
|
134
134
|
|
|
135
135
|
case ext
|
|
136
136
|
when ".html"
|
|
137
|
-
content =
|
|
137
|
+
content = Hammer.read_text(src)
|
|
138
138
|
if !@content_collections.empty? && content.include?("@loop") && content.include?("collections.")
|
|
139
139
|
content = Content::PageGenerator.pre_process_collection_loops(
|
|
140
140
|
content,
|
|
@@ -148,7 +148,7 @@ module Hammer
|
|
|
148
148
|
FileUtils.mkdir_p(File.dirname(dest))
|
|
149
149
|
File.write(dest, processed)
|
|
150
150
|
when ".css"
|
|
151
|
-
processed = css_parser.parse(
|
|
151
|
+
processed = css_parser.parse(Hammer.read_text(src), relative_path: rel)
|
|
152
152
|
FileUtils.mkdir_p(File.dirname(dest))
|
|
153
153
|
File.write(dest, processed)
|
|
154
154
|
else
|
|
@@ -45,7 +45,7 @@ module Hammer
|
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
def self.load(path)
|
|
48
|
-
data = JSON.parse(
|
|
48
|
+
data = JSON.parse(Hammer.read_text(path))
|
|
49
49
|
collections = data.fetch("collections", {}).transform_values { |c| CollectionConfig.from_hash(c) }
|
|
50
50
|
new(collections: collections, site_url: data["siteUrl"])
|
|
51
51
|
end
|
|
@@ -28,7 +28,7 @@ module Hammer
|
|
|
28
28
|
|
|
29
29
|
def date
|
|
30
30
|
val = metadata["date"]
|
|
31
|
-
return val if val.is_a?(Time) || val.is_a?(Date)
|
|
31
|
+
return val if val.is_a?(Time) || val.is_a?(::Date)
|
|
32
32
|
|
|
33
33
|
self.class.parse_date(val.to_s) if val
|
|
34
34
|
end
|
|
@@ -83,7 +83,7 @@ module Hammer
|
|
|
83
83
|
value.map { |v| serialize_value(v) }
|
|
84
84
|
when Hash
|
|
85
85
|
value.transform_values { |v| serialize_value(v) }
|
|
86
|
-
when Time, Date
|
|
86
|
+
when Time, ::Date
|
|
87
87
|
value.utc.iso8601(3)
|
|
88
88
|
else
|
|
89
89
|
value
|
|
@@ -59,6 +59,8 @@ module Hammer
|
|
|
59
59
|
|
|
60
60
|
def resolve_output_path(doc, collection_config)
|
|
61
61
|
pattern = collection_config.output_path_pattern
|
|
62
|
+
return "" if pattern.nil? || pattern.empty?
|
|
63
|
+
|
|
62
64
|
slug_field = collection_config.slug&.dig("field") || "slug"
|
|
63
65
|
slug = resolve_slug(doc, collection_config.slug)
|
|
64
66
|
interpolate_output_path(pattern, slug, slug_field)
|
|
@@ -88,7 +90,7 @@ module Hammer
|
|
|
88
90
|
end
|
|
89
91
|
|
|
90
92
|
def generate_page(template_path, doc, output_path)
|
|
91
|
-
template =
|
|
93
|
+
template = Hammer.read_text(template_path)
|
|
92
94
|
site = { "title" => "My Site" }
|
|
93
95
|
context = TemplateContext.new(
|
|
94
96
|
site: site,
|
|
@@ -8,7 +8,7 @@ module Hammer
|
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def parse_markdown_file(path)
|
|
11
|
-
content =
|
|
11
|
+
content = Hammer.read_text(path)
|
|
12
12
|
metadata, body = extract_front_matter(content)
|
|
13
13
|
html_body = parse_markdown_body(body)
|
|
14
14
|
collection = extract_collection(path)
|
|
@@ -22,7 +22,7 @@ module Hammer
|
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
def parse_yaml_file(path)
|
|
25
|
-
metadata = parse_simple_yaml(
|
|
25
|
+
metadata = parse_simple_yaml(Hammer.read_text(path))
|
|
26
26
|
Document.new(
|
|
27
27
|
file_path: path,
|
|
28
28
|
metadata: metadata,
|
data/lib/hammer/css_parser.rb
CHANGED
|
@@ -35,7 +35,7 @@ module Hammer
|
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
@processed_includes << include_path
|
|
38
|
-
included =
|
|
38
|
+
included = Hammer.read_text(File.join(@source_directory, include_path))
|
|
39
39
|
result.sub!(match[0], "\n#{process_includes(included)}\n")
|
|
40
40
|
end
|
|
41
41
|
|
data/lib/hammer/ignore.rb
CHANGED
|
@@ -13,7 +13,7 @@ module Hammer
|
|
|
13
13
|
path = File.join(source_dir, ".hammer-ignore")
|
|
14
14
|
return [] unless File.file?(path)
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
Hammer.read_text(path).each_line.map(&:strip).reject do |line|
|
|
17
17
|
line.empty? || line.start_with?("#")
|
|
18
18
|
end
|
|
19
19
|
end
|
data/lib/hammer/io.rb
ADDED
|
@@ -54,7 +54,7 @@ module Hammer
|
|
|
54
54
|
path = File.join(@build_directory, "sitemap.xml")
|
|
55
55
|
return [] unless File.file?(path)
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
Hammer.read_text(path).scan(%r{<loc>([^<]+)</loc>}).flatten
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
def generate_xml(pages)
|
data/lib/hammer/tag_parser.rb
CHANGED
|
@@ -25,7 +25,7 @@ module Hammer
|
|
|
25
25
|
|
|
26
26
|
def process_file(relative_path, output_path_for_styling: nil)
|
|
27
27
|
@current_file_path = output_path_for_styling || relative_path
|
|
28
|
-
content =
|
|
28
|
+
content = Hammer.read_text(File.join(@source_directory, relative_path))
|
|
29
29
|
process_file_content(content, relative_path, output_path_for_styling)
|
|
30
30
|
end
|
|
31
31
|
|
|
@@ -167,7 +167,7 @@ module Hammer
|
|
|
167
167
|
end
|
|
168
168
|
|
|
169
169
|
@processed_includes << path
|
|
170
|
-
included =
|
|
170
|
+
included = Hammer.read_text(File.join(@source_directory, path))
|
|
171
171
|
child = self.class.new(
|
|
172
172
|
source_directory: @source_directory,
|
|
173
173
|
parent_variables: @parent_variables.merge(@variables),
|
|
@@ -349,34 +349,58 @@ module Hammer
|
|
|
349
349
|
ref = get_variable(ref[1..]) || ref
|
|
350
350
|
end
|
|
351
351
|
|
|
352
|
-
|
|
353
|
-
generate_context_aware_path(".")
|
|
354
|
-
else
|
|
355
|
-
preserve_slash = ref.end_with?("/")
|
|
356
|
-
filename = preserve_slash ? ref.chomp("/") : ref
|
|
357
|
-
paths, error = find_file(File.basename(filename))
|
|
358
|
-
raise TagError, error if error
|
|
359
|
-
|
|
360
|
-
if paths.empty?
|
|
361
|
-
@delegate&.warning(@current_file_path, "File not found: #{ref}")
|
|
362
|
-
ref
|
|
363
|
-
else
|
|
364
|
-
path = paths.first
|
|
365
|
-
path = "#{path}/" if preserve_slash
|
|
366
|
-
generate_context_aware_path(path).gsub("%20", " ").gsub(" ", "%20")
|
|
367
|
-
end
|
|
368
|
-
end
|
|
352
|
+
resolve_path_reference(ref)
|
|
369
353
|
end
|
|
370
354
|
end
|
|
371
355
|
|
|
356
|
+
def resolve_path_reference(ref)
|
|
357
|
+
if ref == "/"
|
|
358
|
+
return root_relative_path
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
preserve_slash = ref.end_with?("/")
|
|
362
|
+
search_path = preserve_slash ? ref.chomp("/") : ref
|
|
363
|
+
paths, error = find_file(search_path)
|
|
364
|
+
raise TagError, error if error
|
|
365
|
+
|
|
366
|
+
if preserve_slash && paths.empty?
|
|
367
|
+
index_path = "#{search_path}/index.html"
|
|
368
|
+
index_paths, index_error = find_file(index_path)
|
|
369
|
+
raise TagError, index_error if index_error
|
|
370
|
+
|
|
371
|
+
paths = [search_path] unless index_paths.empty?
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
relative_path = (paths.first || search_path).tr(" ", "%20")
|
|
375
|
+
relative_path = "#{relative_path}/" if preserve_slash && !relative_path.end_with?("/")
|
|
376
|
+
|
|
377
|
+
@delegate&.warning(@current_file_path, "File not found: #{ref}") if paths.empty?
|
|
378
|
+
|
|
379
|
+
generate_context_aware_path(relative_path, preserve_trailing_slash: preserve_slash)
|
|
380
|
+
.tr("%20", " ")
|
|
381
|
+
.gsub(" ", "%20")
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
def root_relative_path
|
|
385
|
+
return "./" unless @current_file_path
|
|
386
|
+
|
|
387
|
+
current_dir = current_directory_components
|
|
388
|
+
return "./" if current_dir.empty?
|
|
389
|
+
|
|
390
|
+
"#{"../" * current_dir.length}"
|
|
391
|
+
end
|
|
392
|
+
|
|
372
393
|
def find_file(filename)
|
|
373
394
|
found = []
|
|
395
|
+
direct_path = File.join(@source_directory, filename)
|
|
396
|
+
found << filename if File.file?(direct_path)
|
|
397
|
+
|
|
374
398
|
dirs = %w[assets/img assets/images assets/media images img media]
|
|
375
399
|
dirs.each do |dir|
|
|
376
400
|
path = "#{dir}/#{filename}"
|
|
377
|
-
found << path if File.
|
|
401
|
+
found << path if File.file?(File.join(@source_directory, path))
|
|
378
402
|
end
|
|
379
|
-
found
|
|
403
|
+
found.uniq!
|
|
380
404
|
|
|
381
405
|
if found.empty? || found.length > 1
|
|
382
406
|
Dir.glob(File.join(@source_directory, "**", "*")).each do |f|
|
|
@@ -384,7 +408,9 @@ module Hammer
|
|
|
384
408
|
rel = f.delete_prefix("#{@source_directory}/")
|
|
385
409
|
next if skip_scan_path?(rel)
|
|
386
410
|
|
|
387
|
-
|
|
411
|
+
if rel == filename || File.basename(f) == filename
|
|
412
|
+
found << rel unless found.include?(rel)
|
|
413
|
+
end
|
|
388
414
|
end
|
|
389
415
|
end
|
|
390
416
|
|
|
@@ -394,26 +420,37 @@ module Hammer
|
|
|
394
420
|
[found, nil]
|
|
395
421
|
end
|
|
396
422
|
|
|
397
|
-
def
|
|
423
|
+
def current_directory_components
|
|
424
|
+
@current_file_path.split("/")[0...-1].reject { |part| part == "." || part.empty? }
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
def generate_context_aware_path(file_path, preserve_trailing_slash: file_path.end_with?("/"))
|
|
398
428
|
return "./#{file_path}" unless @current_file_path
|
|
399
429
|
|
|
400
|
-
path_for_processing =
|
|
401
|
-
current_dir =
|
|
430
|
+
path_for_processing = preserve_trailing_slash ? file_path.chomp("/") : file_path
|
|
431
|
+
current_dir = current_directory_components
|
|
402
432
|
target_parts = path_for_processing.split("/")
|
|
403
433
|
common = 0
|
|
404
434
|
common += 1 while common < current_dir.length && common < target_parts.length && current_dir[common] == target_parts[common]
|
|
405
435
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
parts = ([".."] * levels_up) + remaining
|
|
409
|
-
|
|
410
|
-
if parts.empty?
|
|
411
|
-
"./#{target_parts.last}"
|
|
412
|
-
elsif levels_up.zero? && remaining.length == 1
|
|
413
|
-
"./#{remaining[0]}"
|
|
436
|
+
if current_dir == target_parts
|
|
437
|
+
result = "./"
|
|
414
438
|
else
|
|
415
|
-
|
|
416
|
-
|
|
439
|
+
levels_up = current_dir.length - common
|
|
440
|
+
remaining = target_parts[common..]
|
|
441
|
+
parts = ([".."] * levels_up) + remaining
|
|
442
|
+
|
|
443
|
+
result = if parts.empty?
|
|
444
|
+
"./#{target_parts.last}"
|
|
445
|
+
elsif levels_up.zero? && remaining.length == 1
|
|
446
|
+
"./#{remaining[0]}"
|
|
447
|
+
else
|
|
448
|
+
parts.join("/")
|
|
449
|
+
end
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
result << "/" if preserve_trailing_slash && !result.end_with?("/")
|
|
453
|
+
result
|
|
417
454
|
end
|
|
418
455
|
|
|
419
456
|
def process_navigation_helpers(content)
|
data/lib/hammer/version.rb
CHANGED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
require "tmpdir"
|
|
5
|
+
|
|
6
|
+
RSpec.describe "UTF-8 file reads under US-ASCII locale" do
|
|
7
|
+
it "reads smart quotes without raising" do
|
|
8
|
+
Dir.mktmpdir do |dir|
|
|
9
|
+
path = File.join(dir, "sample.html")
|
|
10
|
+
File.binwrite(path, "<p>It\u2019s working \u2014 really.</p>".encode("UTF-8"))
|
|
11
|
+
|
|
12
|
+
previous_external = Encoding.default_external
|
|
13
|
+
previous_internal = Encoding.default_internal
|
|
14
|
+
Encoding.default_external = Encoding::US_ASCII
|
|
15
|
+
Encoding.default_internal = Encoding::US_ASCII
|
|
16
|
+
|
|
17
|
+
expect { Hammer.read_text(path) }.not_to raise_error
|
|
18
|
+
expect(Hammer.read_text(path)).to include("really")
|
|
19
|
+
|
|
20
|
+
Encoding.default_external = previous_external
|
|
21
|
+
Encoding.default_internal = previous_internal
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
RSpec.describe Hammer::TagParser do
|
|
6
|
+
let(:source_directory) { File.expand_path("../../Test Projects/classic-fixture", __dir__) }
|
|
7
|
+
let(:parser) { described_class.new(source_directory: source_directory) }
|
|
8
|
+
|
|
9
|
+
it "resolves nested @path references relative to the output page" do
|
|
10
|
+
parser.current_file_path = "work/mixfit/index.html"
|
|
11
|
+
content = '<a href="<!-- @path products/gleo/ -->">'
|
|
12
|
+
|
|
13
|
+
result = parser.send(:parse, content)
|
|
14
|
+
|
|
15
|
+
expect(result).to include('href="../../products/gleo/"')
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "resolves root @path references from nested pages" do
|
|
19
|
+
parser.current_file_path = "work/mixfit/index.html"
|
|
20
|
+
content = '<a href="<!-- @path / -->">'
|
|
21
|
+
|
|
22
|
+
result = parser.send(:parse, content)
|
|
23
|
+
|
|
24
|
+
expect(result).to include('href="../../"')
|
|
25
|
+
end
|
|
26
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: beachio-hammer
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.0.
|
|
4
|
+
version: 0.1.0.pre3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Beach.io
|
|
@@ -67,6 +67,7 @@ files:
|
|
|
67
67
|
- lib/hammer/css_parser.rb
|
|
68
68
|
- lib/hammer/errors.rb
|
|
69
69
|
- lib/hammer/ignore.rb
|
|
70
|
+
- lib/hammer/io.rb
|
|
70
71
|
- lib/hammer/output_formatter.rb
|
|
71
72
|
- lib/hammer/project_resolver.rb
|
|
72
73
|
- lib/hammer/sitemap_generator.rb
|
|
@@ -76,8 +77,10 @@ files:
|
|
|
76
77
|
- scripts/test-classic.rb
|
|
77
78
|
- scripts/test-content.rb
|
|
78
79
|
- scripts/tree-diff.rb
|
|
80
|
+
- spec/encoding_spec.rb
|
|
79
81
|
- spec/parity/classic_spec.rb
|
|
80
82
|
- spec/parity/content_spec.rb
|
|
83
|
+
- spec/path_resolution_spec.rb
|
|
81
84
|
- spec/spec_helper.rb
|
|
82
85
|
homepage: https://github.com/beachio/hammer-swift
|
|
83
86
|
licenses:
|