Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle relative source path in create_link #identical? #701

Merged
merged 2 commits into from
Dec 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion lib/thor/actions/create_link.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ class CreateLink < CreateFile #:nodoc:
# Boolean:: true if it is identical, false otherwise.
#
def identical?
exists? && File.identical?(render, destination)
source = File.expand_path(render, File.dirname(destination))
exists? && File.identical?(source, destination)
end

def invoke!
Expand Down
105 changes: 64 additions & 41 deletions spec/actions/create_link_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,93 +4,116 @@

describe Thor::Actions::CreateLink, :unless => windows? do
before do
@silence = false
@hardlink_to = File.join(Dir.tmpdir, "linkdest.rb")
::FileUtils.rm_rf(destination_root)
::FileUtils.rm_rf(@hardlink_to)
end

def create_link(destination = nil, config = {}, options = {})
@base = MyCounter.new([1, 2], options, :destination_root => destination_root)
allow(@base).to receive(:file_name).and_return("rdoc")
let(:config) { {} }
let(:options) { {} }

@tempfile = Tempfile.new("config.rb")
let(:base) do
base = MyCounter.new([1, 2], options, :destination_root => destination_root)
allow(base).to receive(:file_name).and_return("rdoc")
base
end

let(:tempfile) { Tempfile.new("config.rb") }

let(:source) { tempfile.path }

@action = Thor::Actions::CreateLink.new(@base, destination, @tempfile.path,
{:verbose => !@silence}.merge(config))
let(:destination) { "doc/config.rb" }

let(:action) do
Thor::Actions::CreateLink.new(base, destination, source, config)
end

def invoke!
capture(:stdout) { @action.invoke! }
capture(:stdout) { action.invoke! }
end

def revoke!
capture(:stdout) { @action.revoke! }
end

def silence!
@silence = true
capture(:stdout) { action.revoke! }
end

describe "#invoke!" do
it "creates a symbolic link for :symbolic => true" do
create_link("doc/config.rb", :symbolic => true)
invoke!
destination_path = File.join(destination_root, "doc/config.rb")
expect(File.exist?(destination_path)).to be true
expect(File.symlink?(destination_path)).to be true
context "specifying :symbolic => true" do
let(:config) { {:symbolic => true} }

it "creates a symbolic link" do
invoke!
destination_path = File.join(destination_root, "doc/config.rb")
expect(File.exist?(destination_path)).to be true
expect(File.symlink?(destination_path)).to be true
end
end

it "creates a hard link for :symbolic => false" do
create_link(@hardlink_to, :symbolic => false)
invoke!
destination_path = @hardlink_to
expect(File.exist?(destination_path)).to be true
expect(File.symlink?(destination_path)).to be false
context "specifying :symbolic => false" do
let(:config) { {:symbolic => false} }
let(:destination) { @hardlink_to }

it "creates a hard link" do
invoke!
destination_path = @hardlink_to
expect(File.exist?(destination_path)).to be true
expect(File.symlink?(destination_path)).to be false
end
end

it "creates a symbolic link by default" do
create_link("doc/config.rb")
invoke!
destination_path = File.join(destination_root, "doc/config.rb")
expect(File.exist?(destination_path)).to be true
expect(File.symlink?(destination_path)).to be true
end

it "does not create a link if pretending" do
create_link("doc/config.rb", {}, :pretend => true)
invoke!
expect(File.exist?(File.join(destination_root, "doc/config.rb"))).to be false
context "specifying :pretend => true" do
let(:options) { {:pretend => true} }
it "does not create a link" do
invoke!
expect(File.exist?(File.join(destination_root, "doc/config.rb"))).to be false
end
end

it "shows created status to the user" do
create_link("doc/config.rb")
expect(invoke!).to eq(" create doc/config.rb\n")
end

it "does not show any information if log status is false" do
silence!
create_link("doc/config.rb")
expect(invoke!).to be_empty
context "specifying :verbose => false" do
let(:config) { {:verbose => false} }
it "does not show any information" do
expect(invoke!).to be_empty
end
end
end

describe "#identical?" do
it "returns true if the destination link exists and is identical" do
create_link("doc/config.rb")
expect(@action.identical?).to be false
expect(action.identical?).to be false
invoke!
expect(@action.identical?).to be true
expect(action.identical?).to be true
end

context "with source path relative to destination" do
let(:source) do
destination_path = File.dirname(File.join(destination_root, destination))
Pathname.new(super()).relative_path_from(Pathname.new(destination_path)).to_s
end

it "returns true if the destination link exists and is identical" do
expect(action.identical?).to be false
invoke!
expect(action.identical?).to be true
end
end
end

describe "#revoke!" do
it "removes the symbolic link of non-existent destination" do
create_link("doc/config.rb")
invoke!
File.delete(@tempfile.path)
File.delete(tempfile.path)
revoke!
expect(File.symlink?(@action.destination)).to be false
expect(File.symlink?(action.destination)).to be false
end
end
end