Extract Pathname
refinement from Formulary
This commit is contained in:
parent
82fabab8aa
commit
763531e821
@ -17,6 +17,7 @@ require "utils/socket"
|
|||||||
require "cmd/install"
|
require "cmd/install"
|
||||||
require "json/add/exception"
|
require "json/add/exception"
|
||||||
require "utils/output"
|
require "utils/output"
|
||||||
|
require "extend/pathname/write_mkpath_extension"
|
||||||
|
|
||||||
# A formula build.
|
# A formula build.
|
||||||
class Build
|
class Build
|
||||||
@ -245,6 +246,9 @@ begin
|
|||||||
formula = args.named.to_formulae.first
|
formula = args.named.to_formulae.first
|
||||||
options = Options.create(args.flags_only)
|
options = Options.create(args.flags_only)
|
||||||
build = Build.new(formula, options, args:)
|
build = Build.new(formula, options, args:)
|
||||||
|
|
||||||
|
Pathname.prepend WriteMkpathExtension
|
||||||
|
|
||||||
build.install
|
build.install
|
||||||
# Any exception means the build did not complete.
|
# Any exception means the build did not complete.
|
||||||
# The `case` for what to do per-exception class is further down.
|
# The `case` for what to do per-exception class is further down.
|
||||||
|
34
Library/Homebrew/extend/pathname/write_mkpath_extension.rb
Normal file
34
Library/Homebrew/extend/pathname/write_mkpath_extension.rb
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# typed: strict
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module WriteMkpathExtension
|
||||||
|
extend T::Helpers
|
||||||
|
|
||||||
|
requires_ancestor { Pathname }
|
||||||
|
|
||||||
|
# Source for `sig`: https://github.com/sorbet/sorbet/blob/b4092efe0a4489c28aff7e1ead6ee8a0179dc8b3/rbi/stdlib/pathname.rbi#L1392-L1411
|
||||||
|
sig {
|
||||||
|
params(
|
||||||
|
content: Object,
|
||||||
|
offset: Integer,
|
||||||
|
external_encoding: T.any(String, Encoding),
|
||||||
|
internal_encoding: T.any(String, Encoding),
|
||||||
|
encoding: T.any(String, Encoding),
|
||||||
|
textmode: BasicObject,
|
||||||
|
binmode: BasicObject,
|
||||||
|
autoclose: BasicObject,
|
||||||
|
mode: String,
|
||||||
|
perm: Integer,
|
||||||
|
).returns(Integer)
|
||||||
|
}
|
||||||
|
def write(content, offset = T.unsafe(nil), external_encoding: T.unsafe(nil), internal_encoding: T.unsafe(nil),
|
||||||
|
encoding: T.unsafe(nil), textmode: T.unsafe(nil), binmode: T.unsafe(nil), autoclose: T.unsafe(nil),
|
||||||
|
mode: T.unsafe(nil), perm: T.unsafe(nil))
|
||||||
|
T.bind(self, Pathname)
|
||||||
|
raise "Will not overwrite #{self}" if exist? && !offset && !mode&.match?(/^a\+?$/)
|
||||||
|
|
||||||
|
dirname.mkpath
|
||||||
|
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
@ -1,4 +1,4 @@
|
|||||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
# typed: strict
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "digest/sha2"
|
require "digest/sha2"
|
||||||
@ -112,24 +112,6 @@ module Formulary
|
|||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
module PathnameWriteMkpath
|
|
||||||
# TODO: migrate away from refinements here, they don't play nicely with Sorbet
|
|
||||||
# rubocop:todo Sorbet/BlockMethodDefinition
|
|
||||||
refine Pathname do
|
|
||||||
def write(content, offset = nil, **open_args)
|
|
||||||
T.bind(self, Pathname)
|
|
||||||
raise "Will not overwrite #{self}" if exist? && !offset && !open_args[:mode]&.match?(/^a\+?$/)
|
|
||||||
|
|
||||||
dirname.mkpath
|
|
||||||
|
|
||||||
super
|
|
||||||
end
|
|
||||||
end
|
|
||||||
# rubocop:enable Sorbet/BlockMethodDefinition
|
|
||||||
end
|
|
||||||
|
|
||||||
using PathnameWriteMkpath
|
|
||||||
|
|
||||||
sig {
|
sig {
|
||||||
params(
|
params(
|
||||||
name: String,
|
name: String,
|
||||||
|
@ -0,0 +1,62 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "extend/pathname/write_mkpath_extension"
|
||||||
|
|
||||||
|
RSpec.describe WriteMkpathExtension do
|
||||||
|
let(:file_content) { "sample contents" }
|
||||||
|
|
||||||
|
before do
|
||||||
|
Pathname.prepend described_class
|
||||||
|
end
|
||||||
|
|
||||||
|
it "creates parent directories if they do not exist" do
|
||||||
|
mktmpdir do |tmpdir|
|
||||||
|
file = tmpdir/"foo/bar/baz.txt"
|
||||||
|
expect(file.dirname).not_to exist
|
||||||
|
file.write(file_content)
|
||||||
|
expect(file).to exist
|
||||||
|
expect(file.read).to eq(file_content)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "raises if file exists and not in append mode or with offset" do
|
||||||
|
mktmpdir do |tmpdir|
|
||||||
|
file = tmpdir/"file.txt"
|
||||||
|
file.write(file_content)
|
||||||
|
expect { file.write("new content") }.to raise_error(RuntimeError, /Will not overwrite/)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "allows overwrite if offset is provided" do
|
||||||
|
mktmpdir do |tmpdir|
|
||||||
|
file = tmpdir/"file.txt"
|
||||||
|
file.write(file_content)
|
||||||
|
expect do
|
||||||
|
file.write("change", 0)
|
||||||
|
end.not_to raise_error
|
||||||
|
expect(file.read).to eq("change contents")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "allows append mode ('a')" do
|
||||||
|
mktmpdir do |tmpdir|
|
||||||
|
file = tmpdir/"file.txt"
|
||||||
|
file.write(file_content)
|
||||||
|
expect do
|
||||||
|
file.write(" appended", mode: "a")
|
||||||
|
end.not_to raise_error
|
||||||
|
expect(file.read).to eq("#{file_content} appended")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "allows append mode ('a+')" do
|
||||||
|
mktmpdir do |tmpdir|
|
||||||
|
file = tmpdir/"file.txt"
|
||||||
|
file.write(file_content)
|
||||||
|
expect do
|
||||||
|
file.write(" again", mode: "a+")
|
||||||
|
end.not_to raise_error
|
||||||
|
expect(file.read).to include("again")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
x
Reference in New Issue
Block a user