Merge pull request #47 from trobrock/unlink

Adding unlink function
This commit is contained in:
Yusuke Murata
2013-07-21 10:37:16 -07:00
4 changed files with 132 additions and 3 deletions

3
.gitignore vendored
View File

@@ -44,4 +44,5 @@ pkg
.idea/ .idea/
*.iml *.iml
Gemfile.lock Gemfile.lock
vendor/

View File

@@ -90,7 +90,23 @@ class Homesick < Thor
desc 'push CASTLE', 'Push the specified castle' desc 'push CASTLE', 'Push the specified castle'
def push(name = DEFAULT_CASTLE_NAME) def push(name = DEFAULT_CASTLE_NAME)
push_castle name push_castle name
end
desc 'unlink CASTLE', 'Unsymlinks all dotfiles from the specified castle'
def unlink(name = DEFAULT_CASTLE_NAME)
check_castle_existance(name, 'symlink')
inside castle_dir(name) do
subdirs = subdirs(name)
# unlink files
unsymlink_each(name, castle_dir(name), subdirs)
# unlink files in subdirs
subdirs.each do |subdir|
unsymlink_each(name, subdir, subdirs)
end
end
end end
desc 'symlink CASTLE', 'Symlinks all dotfiles from the specified castle' desc 'symlink CASTLE', 'Symlinks all dotfiles from the specified castle'
@@ -331,7 +347,7 @@ class Homesick < Thor
first_p.mtime > second_p.mtime && !first_p.symlink? first_p.mtime > second_p.mtime && !first_p.symlink?
end end
def symlink_each(castle, basedir, subdirs) def each_file(castle, basedir, subdirs)
absolute_basedir = Pathname.new(basedir).expand_path absolute_basedir = Pathname.new(basedir).expand_path
inside basedir do inside basedir do
files = Pathname.glob('{.*,*}').reject{ |a| ['.', '..'].include?(a.to_s) } files = Pathname.glob('{.*,*}').reject{ |a| ['.', '..'].include?(a.to_s) }
@@ -360,8 +376,21 @@ class Homesick < Thor
relative_dir = absolute_basedir.relative_path_from(castle_home) relative_dir = absolute_basedir.relative_path_from(castle_home)
home_path = home_dir.join(relative_dir).join(path) home_path = home_dir.join(relative_dir).join(path)
ln_s absolute_path, home_path
yield(absolute_path, home_path)
end end
end end
end end
def unsymlink_each(castle, basedir, subdirs)
each_file(castle, basedir, subdirs) do |absolute_path, home_path|
rm_link home_path
end
end
def symlink_each(castle, basedir, subdirs)
each_file(castle, basedir, subdirs) do |absolute_path, home_path|
ln_s absolute_path, home_path
end
end
end end

View File

@@ -97,6 +97,17 @@ class Homesick
end end
end end
def rm_link(target)
target = Pathname.new(target)
if target.symlink?
say_status :unlink, "#{target.expand_path}", :green unless options[:quiet]
FileUtils.rm_rf target
else
say_status :conflict, "#{target} is not a symlink", :red unless options[:quiet]
end
end
def ln_s(source, destination, config = {}) def ln_s(source, destination, config = {})
source = Pathname.new(source) source = Pathname.new(source)
destination = Pathname.new(destination) destination = Pathname.new(destination)

View File

@@ -188,6 +188,94 @@ describe 'homesick' do
end end
end end
describe 'unlink' do
let(:castle) { given_castle('glencairn') }
it 'unlinks dotfiles in the home folder' do
dotfile = castle.file('.some_dotfile')
homesick.symlink('glencairn')
homesick.unlink('glencairn')
home.join('.some_dotfile').should_not exist
end
it 'unlinks non-dotfiles from the home folder' do
dotfile = castle.file('bin')
homesick.symlink('glencairn')
homesick.unlink('glencairn')
home.join('bin').should_not exist
end
context "with '.config' in .homesick_subdir" do
let(:castle) { given_castle('glencairn', ['.config']) }
it 'can unlink sub directories' do
dotdir = castle.directory('.config')
dotfile = dotdir.file('.some_dotfile')
homesick.symlink('glencairn')
homesick.unlink('glencairn')
home_dotdir = home.join('.config')
home_dotdir.should exist
home_dotdir.join('.some_dotfile').should_not exist
end
end
context "with '.config/appA' in .homesick_subdir" do
let(:castle) { given_castle('glencairn', ['.config/appA']) }
it 'can unsymlink in nested sub directory' do
dotdir = castle.directory('.config').directory('appA')
dotfile = dotdir.file('.some_dotfile')
homesick.symlink('glencairn')
homesick.unlink('glencairn')
home_dotdir = home.join('.config').join('appA')
home_dotdir.should exist
home_dotdir.join('.some_dotfile').should_not exist
end
end
context "with '.config' and '.config/someapp' in .homesick_subdir" do
let(:castle) { given_castle('glencairn', ['.config', '.config/someapp']) }
it 'can unsymlink under both of .config and .config/someapp' do
config_dir = castle.directory('.config')
config_dotfile = config_dir.file('.some_dotfile')
someapp_dir = config_dir.directory('someapp')
someapp_dotfile = someapp_dir.file('.some_appfile')
homesick.symlink('glencairn')
homesick.unlink('glencairn')
home_config_dir = home.join('.config')
home_someapp_dir = home_config_dir.join('someapp')
home_config_dir.should exist
home_config_dir.join('.some_dotfile').should_not exist
home_someapp_dir.should exist
home_someapp_dir.join('.some_appfile').should_not exist
end
end
context "when call with no castle name" do
let(:castle) { given_castle('dotfiles') }
it 'using default castle name: "dotfiles"' do
dotfile = castle.file('.some_dotfile')
homesick.symlink
homesick.unlink
home.join('.some_dotfile').should_not exist
end
end
end
describe 'list' do describe 'list' do
it 'should say each castle in the castle directory' do it 'should say each castle in the castle directory' do
given_castle('zomg') given_castle('zomg')