indexmap 0.8.0 → 0.8.2

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
  SHA256:
3
- metadata.gz: 7e1e66f1d2afc109e4475d63d4c24c4e66d4da6a50e729b1f67f325bf729b792
4
- data.tar.gz: ce2d2d9f892c510b337e7c2155cc304044a9182722588172456c82b737e196d3
3
+ metadata.gz: d3d31112daf5ee0b501338d564a4e7e9ef30487c88e65439a67543faac070d64
4
+ data.tar.gz: 550713d5205e26bc9c42a4a37660d0c72e493898b47f7bf5dbb4ef92e2488e6b
5
5
  SHA512:
6
- metadata.gz: 0ad6376f15ef8e5f734c952ae209b472cdefeeb195c641c05e84413f58a3f699f33a8dd6145d661df14c3603fa26268829fae0028da66496bc222f85a3a3c21b
7
- data.tar.gz: 2a1c8520caabe2cd2650dda8fd62e77fb9a3a55f85d508b38eb2529d1a658701c15fb65a168e65d278587b55ecbeae15d6bba929b17a1d1855dace51e6d205cd
6
+ metadata.gz: 10da855e190aab04ccd1e3dcc4fe5e49125bd431eb9831c9ea0e983169f11c08d0ce1beb093bd16d8576d637b850fa3d8da74c013b65cd5982bab0452097d272
7
+ data.tar.gz: 6e4c5cdd0a014d1e897ba94d79f22f1acb69f0eb6ff1ff4f23ef756fb1884b1ef27df96f5181b665bdefd9e80f4925b7fe985a1ddc51bdd91e1f9d9e47af98af
data/CHANGELOG.md CHANGED
@@ -5,6 +5,24 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.8.2] - 2026-07-22
9
+
10
+
11
+ ### Fixed
12
+
13
+ - use authoritative sitemap entrypoint ([#18](https://github.com/ethos-link/indexmap/pull/18))
14
+
15
+
16
+
17
+ ## [0.8.1] - 2026-07-21
18
+
19
+
20
+ ### Added
21
+
22
+ - add lazy install generator ([#17](https://github.com/ethos-link/indexmap/pull/17))
23
+
24
+
25
+
8
26
  ## [0.8.0] - 2026-07-21
9
27
 
10
28
 
data/README.md CHANGED
@@ -72,20 +72,18 @@ Indexmap::Writer.new(
72
72
 
73
73
  ## Rails Usage
74
74
 
75
- For an app that uses Indexmap through rake tasks, load the task entrypoint only
76
- when an Indexmap task is requested. In the application's `Rakefile`, before
77
- `require_relative "config/application"`:
75
+ Run the install generator after adding the gem:
78
76
 
79
- ```ruby
80
- list_tasks = Rake.application.options.show_tasks || ARGV.any? { |argument| ["-T", "--tasks"].include?(argument) }
81
- require "indexmap/tasks" if list_tasks || ARGV.any? { |argument| argument.start_with?("indexmap:") }
77
+ ```bash
78
+ bin/rails generate indexmap:install
82
79
  ```
83
80
 
84
- This preserves `bin/rails --tasks` and the `indexmap:*` tasks without loading
85
- Indexmap during normal Rails boot. Runtime callers and jobs should explicitly
86
- `require "indexmap"` immediately before configuring or using the gem.
81
+ The generator creates `config/initializers/indexmap.rb` with an idempotent
82
+ `IndexmapConfiguration.apply` loader and adds conditional `indexmap/tasks`
83
+ loading to the application's `Rakefile`. This preserves `bin/rails --tasks` and
84
+ the `indexmap:*` tasks without loading Indexmap during normal Rails boot.
87
85
 
88
- In an initializer:
86
+ Customize the `Indexmap.configure` block inside the generated initializer:
89
87
 
90
88
  ```ruby
91
89
  Indexmap.configure do |config|
@@ -109,6 +107,17 @@ Indexmap.configure do |config|
109
107
  end
110
108
  ```
111
109
 
110
+ Runtime callers and jobs must apply the generated configuration before using
111
+ Indexmap:
112
+
113
+ ```ruby
114
+ IndexmapConfiguration.apply
115
+ Indexmap.create
116
+ ```
117
+
118
+ Rake tasks apply it automatically because `indexmap/tasks` loads the gem before
119
+ Rails evaluates the initializer.
120
+
112
121
  Then run:
113
122
 
114
123
  ```bash
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators"
4
+
5
+ module Indexmap
6
+ module Generators
7
+ class InstallGenerator < Rails::Generators::Base
8
+ source_root File.expand_path("templates", __dir__)
9
+
10
+ desc "Create a lazy-safe Indexmap initializer and task loader"
11
+
12
+ def create_initializer
13
+ template "initializer.rb.tt", "config/initializers/indexmap.rb"
14
+ end
15
+
16
+ def configure_rakefile
17
+ rakefile = File.join(destination_root, "Rakefile")
18
+ return unless File.exist?(rakefile)
19
+ return if File.read(rakefile).include?('require "indexmap/tasks"')
20
+
21
+ inject_into_file "Rakefile", rakefile_setup, before: /^require_relative ["']config\/application["']/
22
+ end
23
+
24
+ private
25
+
26
+ def rakefile_setup
27
+ <<~RUBY
28
+ indexmap_tasks_requested = Rake.application.options.show_tasks ||
29
+ ARGV.any? { |argument| ["-T", "--tasks"].include?(argument) }
30
+ require "indexmap/tasks" if indexmap_tasks_requested ||
31
+ ARGV.any? { |argument| argument.start_with?("indexmap:") }
32
+
33
+ RUBY
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IndexmapConfiguration
4
+ MUTEX = Mutex.new
5
+
6
+ def self.apply
7
+ return if @applied
8
+
9
+ MUTEX.synchronize do
10
+ return if @applied
11
+
12
+ require "indexmap"
13
+
14
+ Indexmap.configure do |config|
15
+ config.base_url = -> { ENV.fetch("INDEXMAP_BASE_URL", "http://localhost:3000") }
16
+ config.storage = lambda {
17
+ Indexmap::Storage::Filesystem.new(
18
+ path: Rails.public_path,
19
+ public_url: config.base_url
20
+ )
21
+ }
22
+
23
+ # Search-engine pings start from config.index_filename (default: "sitemap.xml").
24
+ # Configure the sitemap data owned by your application:
25
+ # config.sections = -> { Sitemap.sections }
26
+ end
27
+
28
+ @applied = true
29
+ end
30
+ end
31
+ end
32
+
33
+ IndexmapConfiguration.apply if defined?(Indexmap)
@@ -51,7 +51,10 @@ module Indexmap
51
51
  end
52
52
 
53
53
  def sitemap_files
54
- storage.list(prefix: "sitemap", suffix: ".xml")
54
+ index_filename = configuration.index_filename.to_s
55
+ return [] if index_filename.empty? || !storage.exist?(index_filename)
56
+
57
+ [index_filename]
55
58
  end
56
59
 
57
60
  def ping_sitemap(_sitemap_file)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Indexmap
4
- VERSION = "0.8.0"
4
+ VERSION = "0.8.2"
5
5
  end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+ require "generators/indexmap/install_generator"
5
+ require "open3"
6
+ require "rbconfig"
7
+
8
+ class IndexmapInstallGeneratorTest < Minitest::Test
9
+ def test_generates_lazy_initializer_and_task_loader
10
+ Dir.mktmpdir do |destination|
11
+ File.write(File.join(destination, "Rakefile"), <<~RUBY)
12
+ require_relative "config/application"
13
+ Rails.application.load_tasks
14
+ RUBY
15
+
16
+ Indexmap::Generators::InstallGenerator.start([], destination_root: destination)
17
+
18
+ initializer = File.join(destination, "config/initializers/indexmap.rb")
19
+ rakefile = File.read(File.join(destination, "Rakefile"))
20
+
21
+ assert File.exist?(initializer)
22
+ assert_includes File.read(initializer), "module IndexmapConfiguration"
23
+ assert_includes File.read(initializer), "IndexmapConfiguration.apply if defined?(Indexmap)"
24
+ assert_includes File.read(initializer), "Search-engine pings start from config.index_filename"
25
+ assert_includes rakefile, 'require "indexmap/tasks"'
26
+ assert_operator rakefile.index('require "indexmap/tasks"'), :<, rakefile.index('require_relative "config/application"')
27
+
28
+ _stdout, stderr, status = Open3.capture3(RbConfig.ruby, initializer)
29
+ assert status.success?, stderr
30
+
31
+ script = <<~RUBY
32
+ require "pathname"
33
+
34
+ module Rails
35
+ def self.public_path
36
+ Pathname.new("public")
37
+ end
38
+ end
39
+
40
+ require "indexmap"
41
+ load ARGV.fetch(0)
42
+
43
+ configuration = Indexmap.configuration
44
+ IndexmapConfiguration.apply
45
+ abort "configuration replaced" unless Indexmap.configuration.equal?(configuration)
46
+ abort "base URL missing" unless configuration.base_url == "http://localhost:3000"
47
+ abort "index filename missing" unless configuration.index_filename == "sitemap.xml"
48
+ RUBY
49
+ _stdout, stderr, status = Open3.capture3(
50
+ RbConfig.ruby,
51
+ "-I#{File.expand_path("../../lib", __dir__)}",
52
+ "-e",
53
+ script,
54
+ initializer
55
+ )
56
+ assert status.success?, stderr
57
+ end
58
+ end
59
+ end
@@ -69,13 +69,19 @@ class IndexmapPingerGoogleTest < Minitest::Test
69
69
  <url><loc>https://www.example.com/about</loc></url>
70
70
  </urlset>
71
71
  XML
72
- "sitemap-posts.xml" => <<~XML
72
+ "sitemap-posts.xml" => <<~XML,
73
73
  <?xml version="1.0" encoding="UTF-8"?>
74
74
  <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
75
75
  <url><loc>https://www.example.com/about</loc></url>
76
76
  <url><loc>https://www.example.com/blog</loc></url>
77
77
  </urlset>
78
78
  XML
79
+ "sitemap-stale.xml" => <<~XML
80
+ <?xml version="1.0" encoding="UTF-8"?>
81
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
82
+ <url><loc>https://www.example.com/retired</loc></url>
83
+ </urlset>
84
+ XML
79
85
  )
80
86
  configuration = configuration_with(storage: storage)
81
87
  configuration.google.credentials = "{\"type\":\"service_account\"}"
@@ -88,11 +94,9 @@ class IndexmapPingerGoogleTest < Minitest::Test
88
94
  ).ping
89
95
 
90
96
  assert_equal :submitted, result[:status]
91
- assert_equal 3, result[:sitemap_count]
97
+ assert_equal 1, result[:sitemap_count]
92
98
  assert_equal 3, result[:url_count]
93
99
  assert_equal [
94
- ["sc-domain:example.com", "https://www.example.com/sitemap-pages.xml"],
95
- ["sc-domain:example.com", "https://www.example.com/sitemap-posts.xml"],
96
100
  ["sc-domain:example.com", "https://www.example.com/sitemap.xml"]
97
101
  ], service.submissions
98
102
  end
@@ -71,7 +71,14 @@ class IndexmapPingerIndexNowTest < Minitest::Test
71
71
  end
72
72
 
73
73
  def test_pings_all_sitemap_urls_when_no_cutoff_is_provided
74
- configuration = configuration_with(storage: sitemap_storage)
74
+ storage = sitemap_storage
75
+ storage.write("sitemap-stale.xml", <<~XML)
76
+ <?xml version="1.0" encoding="UTF-8"?>
77
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
78
+ <url><loc>https://www.example.com/retired</loc></url>
79
+ </urlset>
80
+ XML
81
+ configuration = configuration_with(storage: storage)
75
82
  configuration.index_now.key = VALID_KEY
76
83
 
77
84
  indexnow_url = "https://api.indexnow.org/indexnow"
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.8.0
4
+ version: 0.8.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paulo Fidalgo
@@ -175,6 +175,8 @@ files:
175
175
  - CHANGELOG.md
176
176
  - LICENSE.txt
177
177
  - README.md
178
+ - lib/generators/indexmap/install_generator.rb
179
+ - lib/generators/indexmap/templates/initializer.rb.tt
178
180
  - lib/indexmap.rb
179
181
  - lib/indexmap/configuration.rb
180
182
  - lib/indexmap/creator.rb
@@ -199,6 +201,7 @@ files:
199
201
  - lib/indexmap/writer.rb
200
202
  - lib/tasks/indexmap_tasks.rake
201
203
  - test/indexmap/configuration_test.rb
204
+ - test/indexmap/install_generator_test.rb
202
205
  - test/indexmap/lazy_loading_test.rb
203
206
  - test/indexmap/parser_test.rb
204
207
  - test/indexmap/pinger/google_test.rb