indexmap 0.8.2 → 0.10.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 +4 -4
- data/CHANGELOG.md +85 -0
- data/README.md +281 -94
- data/UPGRADE.md +361 -0
- data/docs/architecture.md +55 -0
- data/docs/deployment.md +223 -0
- data/docs/domain-terms.md +27 -0
- data/docs/dynamic-sitemaps.md +302 -0
- data/docs/search-engine-ping.md +368 -0
- data/docs/storage.md +94 -0
- data/lib/generators/indexmap/install_generator.rb +1 -1
- data/lib/generators/indexmap/templates/initializer.rb.tt +18 -18
- data/lib/indexmap/artifact.rb +9 -0
- data/lib/indexmap/configuration.rb +12 -1
- data/lib/indexmap/creator.rb +45 -42
- data/lib/indexmap/index_now_configuration.rb +3 -1
- data/lib/indexmap/output.rb +19 -5
- data/lib/indexmap/parser.rb +112 -53
- data/lib/indexmap/pinger/base.rb +6 -5
- data/lib/indexmap/pinger/google.rb +12 -8
- data/lib/indexmap/pinger/index_now.rb +97 -52
- data/lib/indexmap/publication.rb +89 -0
- data/lib/indexmap/rails.rb +6 -0
- data/lib/indexmap/railtie.rb +7 -0
- data/lib/indexmap/robots.rb +67 -0
- data/lib/indexmap/robots_controller.rb +13 -0
- data/lib/indexmap/sitemaps_controller.rb +57 -0
- data/lib/indexmap/storage/active_storage.rb +132 -1
- data/lib/indexmap/storage/filesystem.rb +182 -11
- data/lib/indexmap/storage/memory.rb +1 -1
- data/lib/indexmap/task_runner.rb +21 -28
- data/lib/indexmap/validator/duplicates.rb +83 -0
- data/lib/indexmap/validator.rb +171 -59
- data/lib/indexmap/version.rb +1 -1
- data/lib/indexmap/writer.rb +89 -34
- data/lib/indexmap.rb +14 -1
- data/lib/tasks/indexmap_tasks.rake +21 -2
- data/test/indexmap/correctness_test.rb +153 -0
- data/test/indexmap/install_generator_test.rb +36 -4
- data/test/indexmap/parser_test.rb +77 -0
- data/test/indexmap/pinger/google_test.rb +22 -0
- data/test/indexmap/pinger/index_now_test.rb +168 -0
- data/test/indexmap/publication_test.rb +280 -0
- data/test/indexmap/rails_test.rb +22 -0
- data/test/indexmap/robots_test.rb +73 -0
- data/test/indexmap/sitemaps_controller_test.rb +50 -0
- data/test/indexmap/storage_test.rb +27 -0
- data/test/indexmap/task_runner_test.rb +24 -0
- data/test/indexmap/validator_test.rb +14 -0
- data/test/indexmap/writer_test.rb +42 -0
- data/test/integration/queue_checks.rb +244 -0
- metadata +33 -51
- data/lib/indexmap/storage/file.rb +0 -11
- data/test/release_task_test.rb +0 -86
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "minitest/autorun"
|
|
4
|
+
require "indexmap"
|
|
5
|
+
require "timeout"
|
|
6
|
+
require "rbconfig"
|
|
7
|
+
|
|
8
|
+
class QueueChecks < Minitest::Test
|
|
9
|
+
def setup
|
|
10
|
+
Indexmap::HostConfiguration.apply
|
|
11
|
+
PublicPage.delete_all
|
|
12
|
+
5.times { |id| PublicPage.create!(slug: "page-#{id}", published: true) }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def test_good_job_executes_database_projection_and_surfaces_validation_failure
|
|
16
|
+
IntegrationRefreshJob.queue_adapter = :good_job
|
|
17
|
+
job = IntegrationRefreshJob.perform_later
|
|
18
|
+
GoodJob.perform_inline
|
|
19
|
+
assert GoodJob::Job.find(job.provider_job_id).finished_at
|
|
20
|
+
assert_equal 5, Indexmap::Parser.new.entries.size
|
|
21
|
+
previous = Indexmap.configuration.storage.read("sitemap.xml")
|
|
22
|
+
PublicPage.create!(slug: "page-0", published: true)
|
|
23
|
+
IntegrationRefreshJob.perform_later
|
|
24
|
+
assert_raises(Indexmap::ValidationError) { GoodJob.perform_inline }
|
|
25
|
+
assert_equal previous, Indexmap.configuration.storage.read("sitemap.xml")
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def test_solid_queue_worker_executes_and_records_failed_generation
|
|
29
|
+
IntegrationRefreshJob.queue_adapter = :solid_queue
|
|
30
|
+
reader, writer = IO.pipe
|
|
31
|
+
pid = Process.spawn({"INDEXMAP_ADAPTER" => "solid_queue"}, RbConfig.ruby, "bin/jobs",
|
|
32
|
+
chdir: Rails.root, out: writer, err: writer, pgroup: true)
|
|
33
|
+
writer.close
|
|
34
|
+
job = IntegrationRefreshJob.perform_later
|
|
35
|
+
wait_for(reader) { SolidQueue::Job.find_by(active_job_id: job.job_id)&.finished_at }
|
|
36
|
+
assert_equal 5, Indexmap::Parser.new.entries.size
|
|
37
|
+
previous = Indexmap.configuration.storage.read("sitemap.xml")
|
|
38
|
+
PublicPage.create!(slug: "page-0", published: true)
|
|
39
|
+
failed = IntegrationRefreshJob.perform_later
|
|
40
|
+
wait_for(reader) { SolidQueue::FailedExecution.joins(:job).where(solid_queue_jobs: {active_job_id: failed.job_id}).exists? }
|
|
41
|
+
assert_equal previous, Indexmap.configuration.storage.read("sitemap.xml")
|
|
42
|
+
ensure
|
|
43
|
+
if pid
|
|
44
|
+
Process.kill("TERM", -pid)
|
|
45
|
+
Timeout.timeout(15) { Process.wait(pid) }
|
|
46
|
+
end
|
|
47
|
+
reader&.close
|
|
48
|
+
writer&.close unless writer&.closed?
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def test_active_storage_atomic_publication_and_retention
|
|
52
|
+
config = Indexmap.configuration
|
|
53
|
+
config.storage = Indexmap::Storage::ActiveStorage.new(model: SitemapArtifact, public_url: config.base_url)
|
|
54
|
+
first = Indexmap.create
|
|
55
|
+
previous = config.storage.read("sitemap.xml")
|
|
56
|
+
SitemapArtifact.find_by!(filename: "sitemap.xml").file.blob.update!(created_at: 4.days.ago)
|
|
57
|
+
revision = config.storage.revision("sitemap.xml")
|
|
58
|
+
config.storage.define_singleton_method(:open) do |filename, &block|
|
|
59
|
+
raise "Root body must not be downloaded during activation" if filename == "sitemap.xml"
|
|
60
|
+
|
|
61
|
+
super(filename, &block)
|
|
62
|
+
end
|
|
63
|
+
second = Indexmap.create
|
|
64
|
+
config.storage.singleton_class.remove_method(:open)
|
|
65
|
+
refute_equal first, second
|
|
66
|
+
assert_empty config.storage.prune(root: "sitemap.xml", before: 2.days.ago)
|
|
67
|
+
assert first.all? { |filename| config.storage.exist?(filename) }
|
|
68
|
+
assert_raises(Indexmap::SupersededPublication) do
|
|
69
|
+
Dir.mktmpdir do |directory|
|
|
70
|
+
staged = Indexmap::Storage::Filesystem.new(path: directory)
|
|
71
|
+
staged.write("sitemap.xml", previous)
|
|
72
|
+
config.storage.publish(staged, files: ["sitemap.xml"], root: "sitemap.xml", expected: revision)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
assert Indexmap::Validator.new(configuration: config).validate!
|
|
76
|
+
config.storage.prune(root: "sitemap.xml", before: Time.now.utc + 1)
|
|
77
|
+
assert (first - ["sitemap.xml"]).none? { |filename| config.storage.exist?(filename) }
|
|
78
|
+
assert second.all? { |filename| config.storage.exist?(filename) }
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def test_active_storage_rejects_stale_builds_without_uploading
|
|
82
|
+
config = active_storage_configuration("stale.xml")
|
|
83
|
+
Indexmap.create(configuration: config)
|
|
84
|
+
expected = config.storage.revision(config.index_filename)
|
|
85
|
+
Indexmap.create(configuration: config)
|
|
86
|
+
blobs = ActiveStorage::Blob.order(:id).pluck(:id)
|
|
87
|
+
assert_raises(Indexmap::SupersededPublication) do
|
|
88
|
+
config.storage.publish(nil, files: [], root: config.index_filename, expected: expected)
|
|
89
|
+
end
|
|
90
|
+
assert_equal blobs, ActiveStorage::Blob.order(:id).pluck(:id)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def test_active_storage_cleans_partial_uploads_synchronously
|
|
94
|
+
config = active_storage_configuration("failed-upload.xml")
|
|
95
|
+
Indexmap.create(configuration: config)
|
|
96
|
+
previous = config.storage.read(config.index_filename)
|
|
97
|
+
blobs = ActiveStorage::Blob.order(:id).pluck(:id)
|
|
98
|
+
records = SitemapArtifact.order(:id).pluck(:id)
|
|
99
|
+
service = ActiveStorage::Blob.service
|
|
100
|
+
uploaded = []
|
|
101
|
+
service.define_singleton_method(:upload) do |key, io, **options|
|
|
102
|
+
super(key, io, **options)
|
|
103
|
+
uploaded << key
|
|
104
|
+
raise IOError, "upload interrupted after object write" if uploaded.size == 2
|
|
105
|
+
end
|
|
106
|
+
assert_raises(IOError) { Indexmap.create(configuration: config) }
|
|
107
|
+
assert_equal previous, config.storage.read(config.index_filename)
|
|
108
|
+
assert_equal blobs, ActiveStorage::Blob.order(:id).pluck(:id)
|
|
109
|
+
assert_equal records, SitemapArtifact.order(:id).pluck(:id)
|
|
110
|
+
assert uploaded.none? { |key| service.exist?(key) }
|
|
111
|
+
assert Indexmap::Validator.new(configuration: config).validate!
|
|
112
|
+
ensure
|
|
113
|
+
service&.singleton_class&.remove_method(:upload)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def test_active_storage_cleans_a_losing_build_without_pruning
|
|
117
|
+
config = active_storage_configuration("race.xml")
|
|
118
|
+
storage = config.storage
|
|
119
|
+
baseline = ActiveStorage::Blob.pluck(:id)
|
|
120
|
+
lost_files = []
|
|
121
|
+
lost_keys = []
|
|
122
|
+
winner = nil
|
|
123
|
+
storage.define_singleton_method(:publish) do |source, **options|
|
|
124
|
+
lost_files.concat(options.fetch(:files).reject { |name| name == options.fetch(:root) })
|
|
125
|
+
source.define_singleton_method(:open) do |filename, &block|
|
|
126
|
+
if filename == options.fetch(:root)
|
|
127
|
+
lost_keys.concat(ActiveStorage::Blob.where.not(id: baseline).pluck(:key))
|
|
128
|
+
competing = Indexmap::Configuration.new
|
|
129
|
+
competing.base_url = config.base_url
|
|
130
|
+
competing.index_filename = config.index_filename
|
|
131
|
+
competing.atomic = true
|
|
132
|
+
competing.sections = config.sections
|
|
133
|
+
competing.storage = Indexmap::Storage::ActiveStorage.new(model: SitemapArtifact, public_url: config.base_url)
|
|
134
|
+
winner = Indexmap.create(configuration: competing)
|
|
135
|
+
end
|
|
136
|
+
super(filename, &block)
|
|
137
|
+
end
|
|
138
|
+
super(source, **options)
|
|
139
|
+
end
|
|
140
|
+
assert_raises(Indexmap::SupersededPublication) { Indexmap.create(configuration: config) }
|
|
141
|
+
assert_equal winner.size, ActiveStorage::Blob.where.not(id: baseline).count
|
|
142
|
+
assert lost_files.none? { |filename| storage.exist?(filename) }
|
|
143
|
+
assert lost_keys.none? { |key| ActiveStorage::Blob.service.exist?(key) }
|
|
144
|
+
assert winner.all? { |filename| storage.exist?(filename) }
|
|
145
|
+
assert Indexmap::Validator.new(configuration: config).validate!
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def test_active_storage_does_not_activate_children_deleted_by_pruning
|
|
149
|
+
config = active_storage_configuration("prune-race.xml")
|
|
150
|
+
Indexmap.create(configuration: config)
|
|
151
|
+
previous = config.storage.read(config.index_filename)
|
|
152
|
+
blobs = ActiveStorage::Blob.pluck(:id).sort
|
|
153
|
+
config.storage.define_singleton_method(:publish) do |source, **options|
|
|
154
|
+
storage = self
|
|
155
|
+
source.define_singleton_method(:open) do |filename, &block|
|
|
156
|
+
storage.prune(root: options.fetch(:root), before: Time.now.utc + 1) if filename == options.fetch(:root)
|
|
157
|
+
super(filename, &block)
|
|
158
|
+
end
|
|
159
|
+
super(source, **options)
|
|
160
|
+
end
|
|
161
|
+
assert_raises(Indexmap::SupersededPublication) { Indexmap.create(configuration: config) }
|
|
162
|
+
assert_equal previous, config.storage.read(config.index_filename)
|
|
163
|
+
assert_equal blobs, ActiveStorage::Blob.pluck(:id).sort
|
|
164
|
+
assert Indexmap::Validator.new(configuration: config).validate!
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def test_active_storage_preserves_a_commit_when_a_host_callback_raises
|
|
168
|
+
config = active_storage_configuration("callback.xml")
|
|
169
|
+
callback = proc do |record|
|
|
170
|
+
if record.filename == "callback.xml" && record.file.attached?
|
|
171
|
+
raise IOError, "host callback failed after commit"
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
SitemapArtifact.set_callback(:commit, :after, callback)
|
|
175
|
+
assert_raises(IOError) { Indexmap.create(configuration: config) }
|
|
176
|
+
assert config.storage.exist?(config.index_filename)
|
|
177
|
+
assert Indexmap::Validator.new(configuration: config).validate!
|
|
178
|
+
ensure
|
|
179
|
+
SitemapArtifact.skip_callback(:commit, :after, callback) if callback
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def test_active_storage_reports_cleanup_failures_and_attempts_remaining_objects
|
|
183
|
+
config = active_storage_configuration("cleanup-error.xml")
|
|
184
|
+
Indexmap.create(configuration: config)
|
|
185
|
+
previous = config.storage.read(config.index_filename)
|
|
186
|
+
service = ActiveStorage::Blob.service
|
|
187
|
+
uploaded = []
|
|
188
|
+
attempted = []
|
|
189
|
+
service.define_singleton_method(:upload) do |key, io, **options|
|
|
190
|
+
super(key, io, **options)
|
|
191
|
+
uploaded << key
|
|
192
|
+
raise IOError, "original upload failure" if uploaded.size == 2
|
|
193
|
+
end
|
|
194
|
+
service.define_singleton_method(:delete) do |key|
|
|
195
|
+
attempted << key
|
|
196
|
+
raise IOError, "cleanup unavailable" if key == uploaded.first
|
|
197
|
+
|
|
198
|
+
super(key)
|
|
199
|
+
end
|
|
200
|
+
error = assert_raises(Indexmap::PublicationCleanupError) { Indexmap.create(configuration: config) }
|
|
201
|
+
assert_equal "original upload failure", error.cause.message
|
|
202
|
+
assert_equal [uploaded.first], error.failures.map { |failure| failure.fetch(:artifact) }
|
|
203
|
+
assert_equal uploaded.sort, attempted.sort
|
|
204
|
+
assert_equal previous, config.storage.read(config.index_filename)
|
|
205
|
+
assert Indexmap::Validator.new(configuration: config).validate!
|
|
206
|
+
ensure
|
|
207
|
+
if service
|
|
208
|
+
service.singleton_class.remove_method(:upload)
|
|
209
|
+
service.singleton_class.remove_method(:delete)
|
|
210
|
+
uploaded&.each { |key| service.delete(key) }
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def test_active_storage_publishes_atomic_single_file_outputs
|
|
215
|
+
config = active_storage_configuration("single.xml")
|
|
216
|
+
config.format = :single_file
|
|
217
|
+
config.entries = [{loc: "https://example.com/page"}]
|
|
218
|
+
assert_equal ["single.xml"], Indexmap.create(configuration: config)
|
|
219
|
+
assert_equal ["single.xml"], Indexmap.create(configuration: config)
|
|
220
|
+
assert Indexmap::Validator.new(configuration: config).validate!
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
private
|
|
224
|
+
|
|
225
|
+
def active_storage_configuration(root)
|
|
226
|
+
Indexmap.configuration.tap do |config|
|
|
227
|
+
config.index_filename = root
|
|
228
|
+
config.storage = Indexmap::Storage::ActiveStorage.new(model: SitemapArtifact, public_url: config.base_url)
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def wait_for(reader)
|
|
233
|
+
deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + 30
|
|
234
|
+
log = +""
|
|
235
|
+
until yield
|
|
236
|
+
raise "Worker did not reach expected state: #{log[-2000, 2000]}" if Process.clock_gettime(Process::CLOCK_MONOTONIC) > deadline
|
|
237
|
+
|
|
238
|
+
if IO.select([reader], nil, nil, 0.1)
|
|
239
|
+
chunk = reader.read_nonblock(4096, exception: false)
|
|
240
|
+
log << chunk if chunk.is_a?(String)
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: indexmap
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.10.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Paulo Fidalgo
|
|
@@ -16,14 +16,20 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
19
|
+
version: '8.0'
|
|
20
|
+
- - "<"
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
22
|
+
version: '9'
|
|
20
23
|
type: :runtime
|
|
21
24
|
prerelease: false
|
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
26
|
requirements:
|
|
24
27
|
- - ">="
|
|
25
28
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
29
|
+
version: '8.0'
|
|
30
|
+
- - "<"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '9'
|
|
27
33
|
- !ruby/object:Gem::Dependency
|
|
28
34
|
name: faraday
|
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -80,20 +86,6 @@ dependencies:
|
|
|
80
86
|
- - ">="
|
|
81
87
|
- !ruby/object:Gem::Version
|
|
82
88
|
version: '1.16'
|
|
83
|
-
- !ruby/object:Gem::Dependency
|
|
84
|
-
name: railties
|
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
|
86
|
-
requirements:
|
|
87
|
-
- - ">="
|
|
88
|
-
- !ruby/object:Gem::Version
|
|
89
|
-
version: '7.1'
|
|
90
|
-
type: :runtime
|
|
91
|
-
prerelease: false
|
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
-
requirements:
|
|
94
|
-
- - ">="
|
|
95
|
-
- !ruby/object:Gem::Version
|
|
96
|
-
version: '7.1'
|
|
97
89
|
- !ruby/object:Gem::Dependency
|
|
98
90
|
name: minitest
|
|
99
91
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -108,20 +100,6 @@ dependencies:
|
|
|
108
100
|
- - "~>"
|
|
109
101
|
- !ruby/object:Gem::Version
|
|
110
102
|
version: '5.0'
|
|
111
|
-
- !ruby/object:Gem::Dependency
|
|
112
|
-
name: rake
|
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
|
114
|
-
requirements:
|
|
115
|
-
- - "~>"
|
|
116
|
-
- !ruby/object:Gem::Version
|
|
117
|
-
version: '13.0'
|
|
118
|
-
type: :development
|
|
119
|
-
prerelease: false
|
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
-
requirements:
|
|
122
|
-
- - "~>"
|
|
123
|
-
- !ruby/object:Gem::Version
|
|
124
|
-
version: '13.0'
|
|
125
103
|
- !ruby/object:Gem::Dependency
|
|
126
104
|
name: simplecov
|
|
127
105
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -136,20 +114,6 @@ dependencies:
|
|
|
136
114
|
- - "~>"
|
|
137
115
|
- !ruby/object:Gem::Version
|
|
138
116
|
version: '0.22'
|
|
139
|
-
- !ruby/object:Gem::Dependency
|
|
140
|
-
name: standard
|
|
141
|
-
requirement: !ruby/object:Gem::Requirement
|
|
142
|
-
requirements:
|
|
143
|
-
- - "~>"
|
|
144
|
-
- !ruby/object:Gem::Version
|
|
145
|
-
version: '1.0'
|
|
146
|
-
type: :development
|
|
147
|
-
prerelease: false
|
|
148
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
149
|
-
requirements:
|
|
150
|
-
- - "~>"
|
|
151
|
-
- !ruby/object:Gem::Version
|
|
152
|
-
version: '1.0'
|
|
153
117
|
- !ruby/object:Gem::Dependency
|
|
154
118
|
name: webmock
|
|
155
119
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -175,9 +139,17 @@ files:
|
|
|
175
139
|
- CHANGELOG.md
|
|
176
140
|
- LICENSE.txt
|
|
177
141
|
- README.md
|
|
142
|
+
- UPGRADE.md
|
|
143
|
+
- docs/architecture.md
|
|
144
|
+
- docs/deployment.md
|
|
145
|
+
- docs/domain-terms.md
|
|
146
|
+
- docs/dynamic-sitemaps.md
|
|
147
|
+
- docs/search-engine-ping.md
|
|
148
|
+
- docs/storage.md
|
|
178
149
|
- lib/generators/indexmap/install_generator.rb
|
|
179
150
|
- lib/generators/indexmap/templates/initializer.rb.tt
|
|
180
151
|
- lib/indexmap.rb
|
|
152
|
+
- lib/indexmap/artifact.rb
|
|
181
153
|
- lib/indexmap/configuration.rb
|
|
182
154
|
- lib/indexmap/creator.rb
|
|
183
155
|
- lib/indexmap/entry.rb
|
|
@@ -188,29 +160,39 @@ files:
|
|
|
188
160
|
- lib/indexmap/pinger/base.rb
|
|
189
161
|
- lib/indexmap/pinger/google.rb
|
|
190
162
|
- lib/indexmap/pinger/index_now.rb
|
|
163
|
+
- lib/indexmap/publication.rb
|
|
164
|
+
- lib/indexmap/rails.rb
|
|
191
165
|
- lib/indexmap/railtie.rb
|
|
166
|
+
- lib/indexmap/robots.rb
|
|
167
|
+
- lib/indexmap/robots_controller.rb
|
|
192
168
|
- lib/indexmap/section.rb
|
|
169
|
+
- lib/indexmap/sitemaps_controller.rb
|
|
193
170
|
- lib/indexmap/storage/active_storage.rb
|
|
194
|
-
- lib/indexmap/storage/file.rb
|
|
195
171
|
- lib/indexmap/storage/filesystem.rb
|
|
196
172
|
- lib/indexmap/storage/memory.rb
|
|
197
173
|
- lib/indexmap/task_runner.rb
|
|
198
174
|
- lib/indexmap/tasks.rb
|
|
199
175
|
- lib/indexmap/validator.rb
|
|
176
|
+
- lib/indexmap/validator/duplicates.rb
|
|
200
177
|
- lib/indexmap/version.rb
|
|
201
178
|
- lib/indexmap/writer.rb
|
|
202
179
|
- lib/tasks/indexmap_tasks.rake
|
|
203
180
|
- test/indexmap/configuration_test.rb
|
|
181
|
+
- test/indexmap/correctness_test.rb
|
|
204
182
|
- test/indexmap/install_generator_test.rb
|
|
205
183
|
- test/indexmap/lazy_loading_test.rb
|
|
206
184
|
- test/indexmap/parser_test.rb
|
|
207
185
|
- test/indexmap/pinger/google_test.rb
|
|
208
186
|
- test/indexmap/pinger/index_now_test.rb
|
|
187
|
+
- test/indexmap/publication_test.rb
|
|
188
|
+
- test/indexmap/rails_test.rb
|
|
189
|
+
- test/indexmap/robots_test.rb
|
|
190
|
+
- test/indexmap/sitemaps_controller_test.rb
|
|
209
191
|
- test/indexmap/storage_test.rb
|
|
210
192
|
- test/indexmap/task_runner_test.rb
|
|
211
193
|
- test/indexmap/validator_test.rb
|
|
212
194
|
- test/indexmap/writer_test.rb
|
|
213
|
-
- test/
|
|
195
|
+
- test/integration/queue_checks.rb
|
|
214
196
|
- test/test_helper.rb
|
|
215
197
|
homepage: https://www.ethos-link.com/opensource/indexmap
|
|
216
198
|
licenses:
|
|
@@ -219,8 +201,8 @@ metadata:
|
|
|
219
201
|
homepage_uri: https://www.ethos-link.com/opensource/indexmap
|
|
220
202
|
source_code_uri: https://github.com/ethos-link/indexmap
|
|
221
203
|
bug_tracker_uri: https://github.com/ethos-link/indexmap/issues
|
|
222
|
-
changelog_uri: https://github.com/ethos-link/indexmap/blob/
|
|
223
|
-
documentation_uri: https://github.com/ethos-link/indexmap/blob/
|
|
204
|
+
changelog_uri: https://github.com/ethos-link/indexmap/blob/v0.10.0/CHANGELOG.md
|
|
205
|
+
documentation_uri: https://github.com/ethos-link/indexmap/blob/v0.10.0/README.md
|
|
224
206
|
funding_uri: https://www.reviato.com/
|
|
225
207
|
github_repo: ssh://github.com/ethos-link/indexmap
|
|
226
208
|
allowed_push_host: https://rubygems.org
|
|
@@ -232,14 +214,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
232
214
|
requirements:
|
|
233
215
|
- - ">="
|
|
234
216
|
- !ruby/object:Gem::Version
|
|
235
|
-
version:
|
|
217
|
+
version: '4.0'
|
|
236
218
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
237
219
|
requirements:
|
|
238
220
|
- - ">="
|
|
239
221
|
- !ruby/object:Gem::Version
|
|
240
222
|
version: '0'
|
|
241
223
|
requirements: []
|
|
242
|
-
rubygems_version: 4.0.
|
|
224
|
+
rubygems_version: 4.0.20
|
|
243
225
|
specification_version: 4
|
|
244
226
|
summary: Generate sitemap indexes and child sitemaps with plain Ruby
|
|
245
227
|
test_files: []
|
data/test/release_task_test.rb
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "test_helper"
|
|
4
|
-
require "rake"
|
|
5
|
-
|
|
6
|
-
unless respond_to?(:release_version, true)
|
|
7
|
-
load File.expand_path("../Rakefile", __dir__)
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
class ReleaseTaskTest < Minitest::Test
|
|
11
|
-
def test_release_version_increments_patch_from_current_version
|
|
12
|
-
major, minor, patch = Indexmap::VERSION.split(".").map(&:to_i)
|
|
13
|
-
|
|
14
|
-
assert_equal "#{major}.#{minor}.#{patch + 1}", release_version("patch")
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def test_release_version_accepts_explicit_semantic_version
|
|
18
|
-
assert_equal "0.3.0", release_version("0.3.0")
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def test_validate_release_version_rejects_current_version
|
|
22
|
-
error = assert_raises(ArgumentError) do
|
|
23
|
-
validate_release_version!("0.2.7", "0.2.7")
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
assert_equal(
|
|
27
|
-
"Release version 0.2.7 must be newer than current version 0.2.7.",
|
|
28
|
-
error.message
|
|
29
|
-
)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def test_validate_release_version_rejects_existing_local_tag
|
|
33
|
-
@local_release_tag_exists = true
|
|
34
|
-
@remote_release_tag_exists = false
|
|
35
|
-
|
|
36
|
-
error = assert_raises(ArgumentError) do
|
|
37
|
-
validate_release_version!("0.2.8", "0.2.7")
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
assert_equal "Release tag v0.2.8 already exists locally.", error.message
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def test_validate_release_version_rejects_existing_remote_tag
|
|
44
|
-
@local_release_tag_exists = false
|
|
45
|
-
@remote_release_tag_exists = true
|
|
46
|
-
|
|
47
|
-
error = assert_raises(ArgumentError) do
|
|
48
|
-
validate_release_version!("0.2.8", "0.2.7")
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
assert_equal "Release tag v0.2.8 already exists on origin.", error.message
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def test_remote_release_tag_command_asks_git_to_fail_when_no_tag_matches
|
|
55
|
-
assert_equal(
|
|
56
|
-
"git ls-remote --exit-code --tags origin refs/tags/v0.2.8",
|
|
57
|
-
remote_release_tag_command("v0.2.8")
|
|
58
|
-
)
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def test_changelog_command_prepends_the_next_release
|
|
62
|
-
assert_equal(
|
|
63
|
-
[
|
|
64
|
-
"git-cliff",
|
|
65
|
-
"-c",
|
|
66
|
-
"cliff.toml",
|
|
67
|
-
"--unreleased",
|
|
68
|
-
"--tag",
|
|
69
|
-
"v0.2.8",
|
|
70
|
-
"--prepend",
|
|
71
|
-
"CHANGELOG.md"
|
|
72
|
-
],
|
|
73
|
-
changelog_command("0.2.8")
|
|
74
|
-
)
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
private
|
|
78
|
-
|
|
79
|
-
def local_release_tag_exists?(_tag)
|
|
80
|
-
@local_release_tag_exists || false
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def remote_release_tag_exists?(_tag)
|
|
84
|
-
@remote_release_tag_exists || false
|
|
85
|
-
end
|
|
86
|
-
end
|