Move StringInreplaceExtension
into separate file.
This commit is contained in:
parent
24ae318a3d
commit
318091cccc
@ -1,54 +1,4 @@
|
||||
# typed: false
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "active_support/core_ext/object/blank"
|
||||
|
||||
# Used by the inreplace function (in `utils.rb`).
|
||||
class StringInreplaceExtension
|
||||
attr_accessor :errors, :inreplace_string
|
||||
|
||||
def initialize(str)
|
||||
@inreplace_string = str
|
||||
@errors = []
|
||||
end
|
||||
|
||||
def self.extended(str)
|
||||
str.errors = []
|
||||
end
|
||||
|
||||
def sub!(before, after)
|
||||
result = inreplace_string.sub!(before, after)
|
||||
errors << "expected replacement of #{before.inspect} with #{after.inspect}" unless result
|
||||
result
|
||||
end
|
||||
|
||||
# Warn if nothing was replaced
|
||||
def gsub!(before, after, audit_result = true) # rubocop:disable Style/OptionalBooleanParameter
|
||||
result = inreplace_string.gsub!(before, after)
|
||||
errors << "expected replacement of #{before.inspect} with #{after.inspect}" if audit_result && result.nil?
|
||||
result
|
||||
end
|
||||
|
||||
# Looks for Makefile style variable definitions and replaces the
|
||||
# value with "new_value", or removes the definition entirely.
|
||||
def change_make_var!(flag, new_value)
|
||||
return if gsub!(/^#{Regexp.escape(flag)}[ \t]*[\\?+:!]?=[ \t]*((?:.*\\\n)*.*)$/, "#{flag}=#{new_value}", false)
|
||||
|
||||
errors << "expected to change #{flag.inspect} to #{new_value.inspect}"
|
||||
end
|
||||
|
||||
# Removes variable assignments completely.
|
||||
def remove_make_var!(flags)
|
||||
Array(flags).each do |flag|
|
||||
# Also remove trailing \n, if present.
|
||||
unless gsub!(/^#{Regexp.escape(flag)}[ \t]*[\\?+:!]?=(?:.*\\\n)*.*$\n?/, "", false)
|
||||
errors << "expected to remove #{flag.inspect}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Finds the specified variable
|
||||
def get_make_var(flag)
|
||||
inreplace_string[/^#{Regexp.escape(flag)}[ \t]*[\\?+:!]?=[ \t]*((?:.*\\\n)*.*)$/, 1]
|
||||
end
|
||||
end
|
||||
|
@ -1,29 +0,0 @@
|
||||
# typed: strict
|
||||
|
||||
module Utils::Inreplace
|
||||
include Kernel
|
||||
|
||||
sig { params(paths: T::Array[T.untyped], before: T.nilable(String), after: T.nilable(T.any(String, Symbol)), audit_result: T::Boolean).void }
|
||||
def inreplace(paths, before = nil, after = nil, audit_result = true); end
|
||||
end
|
||||
|
||||
class StringInreplaceExtension
|
||||
sig { params(before: String, after: String).returns(T.nilable(String)) }
|
||||
def sub!(before, after)
|
||||
end
|
||||
|
||||
sig { params(before: T.nilable(String), after: T.nilable(String), audit_result: T::Boolean).returns(T.nilable(String)) }
|
||||
def gsub!(before, after, audit_result = true); end
|
||||
|
||||
sig {params(flag: String, new_value: String).void}
|
||||
def change_make_var!(flag, new_value)
|
||||
end
|
||||
|
||||
sig {params(flags: T::Array[String]).void}
|
||||
def remove_make_var!(flags)
|
||||
end
|
||||
|
||||
sig {params(flag: String).returns(String)}
|
||||
def get_make_var(flag)
|
||||
end
|
||||
end
|
@ -1,17 +0,0 @@
|
||||
# typed: false
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "extend/string"
|
||||
|
||||
describe StringInreplaceExtension do
|
||||
subject { described_class.new(string) }
|
||||
|
||||
let(:string) { +"foobar" }
|
||||
|
||||
describe "#sub!" do
|
||||
it "adds an error to #errors when no replacement was made" do
|
||||
subject.sub! "not here", "test"
|
||||
expect(subject.errors).to eq(['expected replacement of "not here" with "test"'])
|
||||
end
|
||||
end
|
||||
end
|
56
Library/Homebrew/test/utils/inreplace_spec.rb
Normal file
56
Library/Homebrew/test/utils/inreplace_spec.rb
Normal file
@ -0,0 +1,56 @@
|
||||
# typed: false
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "tempfile"
|
||||
require "utils/inreplace"
|
||||
|
||||
describe Utils::Inreplace do
|
||||
let(:file) { Tempfile.new("test") }
|
||||
|
||||
before do
|
||||
file.write <<~EOS
|
||||
a
|
||||
b
|
||||
c
|
||||
EOS
|
||||
end
|
||||
|
||||
after { file.unlink }
|
||||
|
||||
it "raises error if there are no files given to replace" do
|
||||
expect {
|
||||
described_class.inreplace [], "d", "f"
|
||||
}.to raise_error(Utils::Inreplace::Error)
|
||||
end
|
||||
|
||||
it "raises error if there is nothing to replace" do
|
||||
expect {
|
||||
described_class.inreplace file.path, "d", "f"
|
||||
}.to raise_error(Utils::Inreplace::Error)
|
||||
end
|
||||
|
||||
it "raises error if there is nothing to replace in block form" do
|
||||
expect {
|
||||
described_class.inreplace(file.path) do |s|
|
||||
s.gsub!("d", "f") # rubocop:disable Performance/StringReplacement
|
||||
end
|
||||
}.to raise_error(Utils::Inreplace::Error)
|
||||
end
|
||||
|
||||
it "raises error if there is no make variables to replace" do
|
||||
expect {
|
||||
described_class.inreplace(file.path) do |s|
|
||||
s.change_make_var! "VAR", "value"
|
||||
s.remove_make_var! "VAR2"
|
||||
end
|
||||
}.to raise_error(Utils::Inreplace::Error)
|
||||
end
|
||||
|
||||
describe "#inreplace_pairs" do
|
||||
it "raises error if there is no old value" do
|
||||
expect {
|
||||
described_class.inreplace_pairs(file.path, [[nil, "f"]])
|
||||
}.to raise_error(Utils::Inreplace::Error)
|
||||
end
|
||||
end
|
||||
end
|
@ -1,12 +1,10 @@
|
||||
# typed: false
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "extend/string"
|
||||
require "tempfile"
|
||||
require "utils/inreplace"
|
||||
require "utils/string_inreplace_extension"
|
||||
|
||||
describe StringInreplaceExtension do
|
||||
subject { described_class.new(string.dup) }
|
||||
subject(:string_extension) { described_class.new(string.dup) }
|
||||
|
||||
describe "#change_make_var!" do
|
||||
context "flag" do
|
||||
@ -20,8 +18,8 @@ describe StringInreplaceExtension do
|
||||
end
|
||||
|
||||
it "is successfully replaced" do
|
||||
subject.change_make_var! "FLAG", "def"
|
||||
expect(subject.inreplace_string).to eq <<~EOS
|
||||
string_extension.change_make_var! "FLAG", "def"
|
||||
expect(string_extension.inreplace_string).to eq <<~EOS
|
||||
OTHER=def
|
||||
FLAG=def
|
||||
FLAG2=abc
|
||||
@ -29,8 +27,8 @@ describe StringInreplaceExtension do
|
||||
end
|
||||
|
||||
it "is successfully appended" do
|
||||
subject.change_make_var! "FLAG", "\\1 def"
|
||||
expect(subject.inreplace_string).to eq <<~EOS
|
||||
string_extension.change_make_var! "FLAG", "\\1 def"
|
||||
expect(string_extension.inreplace_string).to eq <<~EOS
|
||||
OTHER=def
|
||||
FLAG=abc def
|
||||
FLAG2=abc
|
||||
@ -47,8 +45,8 @@ describe StringInreplaceExtension do
|
||||
end
|
||||
|
||||
it "is successfully replaced" do
|
||||
subject.change_make_var! "CFLAGS", "-O3"
|
||||
expect(subject.inreplace_string).to eq <<~EOS
|
||||
string_extension.change_make_var! "CFLAGS", "-O3"
|
||||
expect(string_extension.inreplace_string).to eq <<~EOS
|
||||
CFLAGS=-O3
|
||||
LDFLAGS\t=\t-lcrypto -lssl
|
||||
EOS
|
||||
@ -65,8 +63,8 @@ describe StringInreplaceExtension do
|
||||
end
|
||||
|
||||
it "is successfully replaced" do
|
||||
subject.change_make_var! "CFLAGS", "-O3"
|
||||
expect(subject.inreplace_string).to eq <<~EOS
|
||||
string_extension.change_make_var! "CFLAGS", "-O3"
|
||||
expect(string_extension.inreplace_string).to eq <<~EOS
|
||||
CFLAGS=-O3
|
||||
LDFLAGS = -lcrypto -lssl
|
||||
EOS
|
||||
@ -84,8 +82,8 @@ describe StringInreplaceExtension do
|
||||
end
|
||||
|
||||
it "is successfully replaced" do
|
||||
subject.change_make_var! "FLAG", "def"
|
||||
expect(subject.inreplace_string).to eq <<~EOS
|
||||
string_extension.change_make_var! "FLAG", "def"
|
||||
expect(string_extension.inreplace_string).to eq <<~EOS
|
||||
OTHER=def
|
||||
FLAG=def
|
||||
FLAG2=abc
|
||||
@ -102,8 +100,8 @@ describe StringInreplaceExtension do
|
||||
end
|
||||
|
||||
it "is successfully replaced" do
|
||||
subject.change_make_var! "FLAG", "def"
|
||||
expect(subject.inreplace_string).to eq <<~EOS
|
||||
string_extension.change_make_var! "FLAG", "def"
|
||||
expect(string_extension.inreplace_string).to eq <<~EOS
|
||||
FLAG=def
|
||||
mv file_a file_b
|
||||
EOS
|
||||
@ -120,8 +118,8 @@ describe StringInreplaceExtension do
|
||||
end
|
||||
|
||||
it "is successfully replaced" do
|
||||
subject.change_make_var! "FLAG", "def"
|
||||
expect(subject.inreplace_string).to eq <<~EOS
|
||||
string_extension.change_make_var! "FLAG", "def"
|
||||
expect(string_extension.inreplace_string).to eq <<~EOS
|
||||
OTHER=def
|
||||
FLAG=def
|
||||
FLAG2=abc
|
||||
@ -142,8 +140,8 @@ describe StringInreplaceExtension do
|
||||
end
|
||||
|
||||
it "is successfully removed" do
|
||||
subject.remove_make_var! "FLAG"
|
||||
expect(subject.inreplace_string).to eq <<~EOS
|
||||
string_extension.remove_make_var! "FLAG"
|
||||
expect(string_extension.inreplace_string).to eq <<~EOS
|
||||
OTHER=def
|
||||
FLAG2 = def
|
||||
EOS
|
||||
@ -159,8 +157,8 @@ describe StringInreplaceExtension do
|
||||
end
|
||||
|
||||
it "is successfully removed" do
|
||||
subject.remove_make_var! "LDFLAGS"
|
||||
expect(subject.inreplace_string).to eq <<~EOS
|
||||
string_extension.remove_make_var! "LDFLAGS"
|
||||
expect(string_extension.inreplace_string).to eq <<~EOS
|
||||
CFLAGS\t=\t-Wall -O2
|
||||
EOS
|
||||
end
|
||||
@ -176,8 +174,8 @@ describe StringInreplaceExtension do
|
||||
end
|
||||
|
||||
it "is successfully removed" do
|
||||
subject.remove_make_var! "CFLAGS"
|
||||
expect(subject.inreplace_string).to eq <<~EOS
|
||||
string_extension.remove_make_var! "CFLAGS"
|
||||
expect(string_extension.inreplace_string).to eq <<~EOS
|
||||
LDFLAGS = -lcrypto -lssl
|
||||
EOS
|
||||
end
|
||||
@ -195,8 +193,8 @@ describe StringInreplaceExtension do
|
||||
end
|
||||
|
||||
specify "are be successfully removed" do
|
||||
subject.remove_make_var! ["FLAG", "FLAG2"]
|
||||
expect(subject.inreplace_string).to eq <<~EOS
|
||||
string_extension.remove_make_var! ["FLAG", "FLAG2"]
|
||||
expect(string_extension.inreplace_string).to eq <<~EOS
|
||||
OTHER=def
|
||||
OTHER2=def
|
||||
EOS
|
||||
@ -214,7 +212,7 @@ describe StringInreplaceExtension do
|
||||
end
|
||||
|
||||
it "extracts the value for a given variable" do
|
||||
expect(subject.get_make_var("CFLAGS")).to eq("-Wall -O2")
|
||||
expect(string_extension.get_make_var("CFLAGS")).to eq("-Wall -O2")
|
||||
end
|
||||
end
|
||||
|
||||
@ -227,7 +225,7 @@ describe StringInreplaceExtension do
|
||||
end
|
||||
|
||||
it "extracts the value for a given variable" do
|
||||
expect(subject.get_make_var("CFLAGS")).to eq("-Wall -O2")
|
||||
expect(string_extension.get_make_var("CFLAGS")).to eq("-Wall -O2")
|
||||
end
|
||||
end
|
||||
|
||||
@ -241,7 +239,7 @@ describe StringInreplaceExtension do
|
||||
end
|
||||
|
||||
it "extracts the value for a given variable" do
|
||||
expect(subject.get_make_var("CFLAGS")).to match(/^-Wall -O2 \\\n +-DSOME_VAR=1$/)
|
||||
expect(string_extension.get_make_var("CFLAGS")).to match(/^-Wall -O2 \\\n +-DSOME_VAR=1$/)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -250,8 +248,13 @@ describe StringInreplaceExtension do
|
||||
let(:string) { "foo" }
|
||||
|
||||
it "replaces the first occurrence" do
|
||||
subject.sub!("o", "e")
|
||||
expect(subject.inreplace_string).to eq("feo")
|
||||
string_extension.sub!("o", "e")
|
||||
expect(string_extension.inreplace_string).to eq("feo")
|
||||
end
|
||||
|
||||
it "adds an error to #errors when no replacement was made" do
|
||||
string_extension.sub! "not here", "test"
|
||||
expect(string_extension.errors).to eq(['expected replacement of "not here" with "test"'])
|
||||
end
|
||||
end
|
||||
|
||||
@ -259,59 +262,8 @@ describe StringInreplaceExtension do
|
||||
let(:string) { "foo" }
|
||||
|
||||
it "replaces all occurrences" do
|
||||
subject.gsub!("o", "e") # rubocop:disable Performance/StringReplacement
|
||||
expect(subject.inreplace_string).to eq("fee")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe Utils::Inreplace do
|
||||
let(:file) { Tempfile.new("test") }
|
||||
|
||||
before do
|
||||
file.write <<~EOS
|
||||
a
|
||||
b
|
||||
c
|
||||
EOS
|
||||
end
|
||||
|
||||
after { file.unlink }
|
||||
|
||||
it "raises error if there are no files given to replace" do
|
||||
expect {
|
||||
described_class.inreplace [], "d", "f"
|
||||
}.to raise_error(Utils::Inreplace::Error)
|
||||
end
|
||||
|
||||
it "raises error if there is nothing to replace" do
|
||||
expect {
|
||||
described_class.inreplace file.path, "d", "f"
|
||||
}.to raise_error(Utils::Inreplace::Error)
|
||||
end
|
||||
|
||||
it "raises error if there is nothing to replace in block form" do
|
||||
expect {
|
||||
described_class.inreplace(file.path) do |s|
|
||||
s.gsub!("d", "f") # rubocop:disable Performance/StringReplacement
|
||||
end
|
||||
}.to raise_error(Utils::Inreplace::Error)
|
||||
end
|
||||
|
||||
it "raises error if there is no make variables to replace" do
|
||||
expect {
|
||||
described_class.inreplace(file.path) do |s|
|
||||
s.change_make_var! "VAR", "value"
|
||||
s.remove_make_var! "VAR2"
|
||||
end
|
||||
}.to raise_error(Utils::Inreplace::Error)
|
||||
end
|
||||
|
||||
describe "#inreplace_pairs" do
|
||||
it "raises error if there is no old value" do
|
||||
expect {
|
||||
described_class.inreplace_pairs(file.path, [[nil, "f"]])
|
||||
}.to raise_error(Utils::Inreplace::Error)
|
||||
string_extension.gsub!("o", "e") # rubocop:disable Performance/StringReplacement
|
||||
expect(string_extension.inreplace_string).to eq("fee")
|
||||
end
|
||||
end
|
||||
end
|
@ -1,11 +1,16 @@
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/string_inreplace_extension"
|
||||
|
||||
module Utils
|
||||
# Helper functions for replacing text in files in-place.
|
||||
#
|
||||
# @api private
|
||||
module Inreplace
|
||||
include Kernel
|
||||
extend T::Sig
|
||||
|
||||
# Error during replacement.
|
||||
class Error < RuntimeError
|
||||
def initialize(errors)
|
||||
@ -28,6 +33,14 @@ module Utils
|
||||
# <pre>inreplace "somefile.cfg", /look[for]what?/, "replace by #{bin}/tool"</pre>
|
||||
#
|
||||
# @api public
|
||||
sig do
|
||||
params(
|
||||
paths: T::Array[T.untyped],
|
||||
before: T.nilable(T.any(Regexp, String)),
|
||||
after: T.nilable(T.any(String, Symbol)),
|
||||
audit_result: T::Boolean,
|
||||
).void
|
||||
end
|
||||
def inreplace(paths, before = nil, after = nil, audit_result = true) # rubocop:disable Style/OptionalBooleanParameter
|
||||
after = after.to_s if after.is_a? Symbol
|
||||
|
||||
@ -42,7 +55,7 @@ module Utils
|
||||
if before.nil? && after.nil?
|
||||
yield s
|
||||
else
|
||||
s.gsub!(before, after, audit_result)
|
||||
s.gsub!(T.must(before), after, audit_result)
|
||||
end
|
||||
|
||||
errors[path] = s.errors unless s.errors.empty?
|
||||
@ -54,7 +67,7 @@ module Utils
|
||||
end
|
||||
|
||||
def inreplace_pairs(path, replacement_pairs, read_only_run: false, silent: false)
|
||||
str = File.open(path, "rb", &:read)
|
||||
str = File.open(path, "rb", &:read) || ""
|
||||
contents = StringInreplaceExtension.new(str)
|
||||
replacement_pairs.each do |old, new|
|
||||
ohai "replace #{old.inspect} with #{new.inspect}" unless silent
|
||||
|
72
Library/Homebrew/utils/string_inreplace_extension.rb
Normal file
72
Library/Homebrew/utils/string_inreplace_extension.rb
Normal file
@ -0,0 +1,72 @@
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Used by the `inreplace` function (in `utils.rb`).
|
||||
#
|
||||
# @api private
|
||||
class StringInreplaceExtension
|
||||
extend T::Sig
|
||||
|
||||
attr_accessor :errors, :inreplace_string
|
||||
|
||||
sig { params(string: String).void }
|
||||
def initialize(string)
|
||||
@inreplace_string = string
|
||||
@errors = []
|
||||
end
|
||||
|
||||
# Same as `String#sub!`, but warns if nothing was replaced.
|
||||
#
|
||||
# @api public
|
||||
sig { params(before: String, after: String).returns(T.nilable(String)) }
|
||||
def sub!(before, after)
|
||||
result = inreplace_string.sub!(before, after)
|
||||
errors << "expected replacement of #{before.inspect} with #{after.inspect}" unless result
|
||||
result
|
||||
end
|
||||
|
||||
# Same as `String#gsub!`, but warns if nothing was replaced.
|
||||
#
|
||||
# @api public
|
||||
sig do
|
||||
params(before: T.any(Regexp, String), after: T.nilable(String), audit_result: T::Boolean)
|
||||
.returns(T.nilable(String))
|
||||
end
|
||||
def gsub!(before, after, audit_result = true) # rubocop:disable Style/OptionalBooleanParameter
|
||||
result = inreplace_string.gsub!(before, after)
|
||||
errors << "expected replacement of #{before.inspect} with #{after.inspect}" if audit_result && result.nil?
|
||||
result
|
||||
end
|
||||
|
||||
# Looks for Makefile style variable definitions and replaces the
|
||||
# value with "new_value", or removes the definition entirely.
|
||||
#
|
||||
# @api public
|
||||
sig { params(flag: String, new_value: String).void }
|
||||
def change_make_var!(flag, new_value)
|
||||
return if gsub!(/^#{Regexp.escape(flag)}[ \t]*[\\?+:!]?=[ \t]*((?:.*\\\n)*.*)$/, "#{flag}=#{new_value}", false)
|
||||
|
||||
errors << "expected to change #{flag.inspect} to #{new_value.inspect}"
|
||||
end
|
||||
|
||||
# Removes variable assignments completely.
|
||||
#
|
||||
# @api public
|
||||
sig { params(flags: T.any(String, T::Array[String])).void }
|
||||
def remove_make_var!(flags)
|
||||
Array(flags).each do |flag|
|
||||
# Also remove trailing \n, if present.
|
||||
unless gsub!(/^#{Regexp.escape(flag)}[ \t]*[\\?+:!]?=(?:.*\\\n)*.*$\n?/, "", false)
|
||||
errors << "expected to remove #{flag.inspect}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Finds the specified variable.
|
||||
#
|
||||
# @api public
|
||||
sig { params(flag: String).returns(String) }
|
||||
def get_make_var(flag)
|
||||
inreplace_string[/^#{Regexp.escape(flag)}[ \t]*[\\?+:!]?=[ \t]*((?:.*\\\n)*.*)$/, 1]
|
||||
end
|
||||
end
|
Loading…
x
Reference in New Issue
Block a user