Skip hidden files and absolutize feed asset URLs

This commit is contained in:
Sami Samhuri 2026-02-07 18:16:01 -08:00
parent 8b1e5e4349
commit 03bbd783a1
No known key found for this signature in database
4 changed files with 63 additions and 2 deletions

View file

@ -47,7 +47,7 @@ module Pressa
Dir.glob(File.join(public_dir, "**", "*"), File::FNM_DOTMATCH).each do |source_file|
next if File.directory?(source_file)
next if File.basename(source_file) == "." || File.basename(source_file) == ".."
next if skip_file?(source_file)
filename = File.basename(source_file)
ext = File.extname(source_file)[1..]
@ -75,6 +75,7 @@ module Pressa
site.renderers.each do |renderer|
Dir.glob(File.join(public_dir, "**", "*"), File::FNM_DOTMATCH).each do |source_file|
next if File.directory?(source_file)
next if skip_file?(source_file)
filename = File.basename(source_file)
ext = File.extname(source_file)[1..]
@ -93,5 +94,10 @@ module Pressa
end
end
end
def skip_file?(source_file)
basename = File.basename(source_file)
basename.start_with?(".")
end
end
end

View file

@ -11,7 +11,7 @@ module Pressa
def view_template
div do
p(class: "time") { @post.formatted_date }
raw(safe(@post.body))
raw(safe(normalized_body))
p do
a(class: "permalink", href: @site.url_for(@post.path)) { "" }
end
@ -19,6 +19,15 @@ module Pressa
end
private
def normalized_body
@post.body.gsub(/(href|src)=(['"])(\/(?!\/)[^'"]*)\2/) do
attr = Regexp.last_match(1)
quote = Regexp.last_match(2)
path = Regexp.last_match(3)
%(#{attr}=#{quote}#{@site.url_for(path)}#{quote})
end
end
end
end
end

View file

@ -69,5 +69,32 @@ RSpec.describe Pressa::Posts::JSONFeedWriter do
expect(item).not_to have_key("external_url")
end
end
it "expands root-relative links in content_html to absolute URLs" do
post_with_assets = Pressa::Posts::Post.new(
slug: "swift-optional-or",
title: "Swift Optional OR",
author: "Sami Samhuri",
date: DateTime.parse("2017-10-01T10:00:00-07:00"),
formatted_date: "1st October, 2017",
body: '<p><a href="/posts/2010/01/basics-of-the-mach-o-file-format">read</a></p>' \
'<p><img src="/images/me.jpg" alt="me"></p>' \
'<p><a href="//cdn.example.net/app.js">cdn</a></p>',
excerpt: "hello...",
path: "/posts/2017/10/swift-optional-or"
)
allow(posts_by_year).to receive(:recent_posts).and_return([post_with_assets])
Dir.mktmpdir do |dir|
writer.write_feed(target_path: dir, limit: 30)
feed = JSON.parse(File.read(File.join(dir, "feed.json")))
item = feed.fetch("items").first
content_html = item.fetch("content_html")
expect(content_html).to include('href="https://samhuri.net/posts/2010/01/basics-of-the-mach-o-file-format"')
expect(content_html).to include('src="https://samhuri.net/images/me.jpg"')
expect(content_html).to include('href="//cdn.example.net/app.js"')
end
end
end
end

View file

@ -30,4 +30,23 @@ RSpec.describe Pressa::SiteGenerator do
expect(File.read(source_file)).to eq("safe")
end
end
it "does not copy ignored dotfiles from public" do
Dir.mktmpdir do |dir|
source_path = File.join(dir, "source")
target_path = File.join(dir, "target")
public_path = File.join(source_path, "public")
FileUtils.mkdir_p(public_path)
File.write(File.join(public_path, ".DS_Store"), "finder cache")
File.write(File.join(public_path, ".gitkeep"), "")
File.write(File.join(public_path, "visible.txt"), "ok")
described_class.new(site:).generate(source_path:, target_path:)
expect(File.exist?(File.join(target_path, "visible.txt"))).to be(true)
expect(File.exist?(File.join(target_path, ".DS_Store"))).to be(false)
expect(File.exist?(File.join(target_path, ".gitkeep"))).to be(false)
end
end
end