From 49e4d2844b7474af7e94c1998c649aecffcc909a Mon Sep 17 00:00:00 2001 From: Eric West Date: Mon, 20 May 2013 19:11:48 -0500 Subject: [PATCH 01/18] Track now properly traverses folder structure --- .gitignore | 4 ++++ lib/homesick.rb | 14 ++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 88cf2e9..e605e1e 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,7 @@ pkg # # For vim: *.swp +# +# For IDEA: +.idea/ +*.iml diff --git a/lib/homesick.rb b/lib/homesick.rb index 341e3f9..a61645e 100644 --- a/lib/homesick.rb +++ b/lib/homesick.rb @@ -112,16 +112,22 @@ class Homesick < Thor desc "track FILE CASTLE", "add a file to a castle" def track(file, castle) castle = Pathname.new(castle) - file = Pathname.new(file) + file = Pathname.new(file.chomp('/')) check_castle_existance(castle, 'track') absolute_path = file.expand_path - castle_path = castle_dir(castle) + relative_dir = absolute_path.relative_path_from(home_dir).dirname + castle_path = Pathname.new(castle_dir(castle)).join(relative_dir) + + unless castle_path.exist? + FileUtils.mkdir_p castle_path + end + mv absolute_path, castle_path inside home_dir do - absolute_path = castle_dir(castle) + file.basename - home_path = home_dir + file + absolute_path = castle_path + file.basename + home_path = home_dir + relative_dir + file.basename ln_s absolute_path, home_path end From 7332aa4acd1a4a64384f59d1012f8268d943b75e Mon Sep 17 00:00:00 2001 From: Eric West Date: Mon, 20 May 2013 21:06:31 -0500 Subject: [PATCH 02/18] Specs for track --- spec/homesick_spec.rb | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/spec/homesick_spec.rb b/spec/homesick_spec.rb index 81fafb7..9e34ed3 100644 --- a/spec/homesick_spec.rb +++ b/spec/homesick_spec.rb @@ -169,5 +169,27 @@ describe "homesick" do some_rc_file.readlink.should == tracked_file end + + it 'should track a file in nested folder structure' do + castle = given_castle('castle_repo') + + some_nested_file = home.file('some/nested/file.txt') + homesick.track(some_nested_file.to_s, 'castle_repo') + + tracked_file = castle.join('some/nested/file.txt') + tracked_file.should exist + some_nested_file.readlink.should == tracked_file + end + + it 'should track a nested directory' do + castle = given_castle('castle_repo') + + some_nested_dir = home.directory('some/nested/directory/') + homesick.track(some_nested_dir.to_s, 'castle_repo') + + tracked_file = castle.join('some/nested/directory/') + tracked_file.should exist + File.realdirpath(some_nested_dir).should == File.realdirpath(tracked_file) + end end end From b93eea0e24c6c40d4dca1e1b6943e218e4e55e63 Mon Sep 17 00:00:00 2001 From: Eric West Date: Fri, 24 May 2013 07:52:54 -0500 Subject: [PATCH 03/18] Track makes entries in .manifest When a user tracks a file or directory that is in a nested folder, Homesick creates a .manifest in the user's castle (if there isn't one already) and adds an entry listing the file or directory's parent directory (if it isn't already listed). --- lib/homesick.rb | 9 +++++++++ spec/homesick_spec.rb | 29 +++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/lib/homesick.rb b/lib/homesick.rb index a61645e..9f5a63f 100644 --- a/lib/homesick.rb +++ b/lib/homesick.rb @@ -134,6 +134,15 @@ class Homesick < Thor inside castle_path do git_add absolute_path end + + # are we tracking something nested? Add the parent dir to the manifest unless its already listed + unless relative_dir.eql?(Pathname.new('.')) + manifest_path = Pathname.new(repos_dir.join(castle, '.manifest')) + File.open(manifest_path, 'a+') do |manifest| + manifest.puts relative_dir unless manifest.readlines.inject(false) { |memo, line| line.eql?("#{relative_dir.to_s}\n") || memo } + end + end + end desc "list", "List cloned castles" diff --git a/spec/homesick_spec.rb b/spec/homesick_spec.rb index 9e34ed3..d769489 100644 --- a/spec/homesick_spec.rb +++ b/spec/homesick_spec.rb @@ -191,5 +191,34 @@ describe "homesick" do tracked_file.should exist File.realdirpath(some_nested_dir).should == File.realdirpath(tracked_file) end + + describe "manifest" do + + it 'should add the nested files parent to the manifest' do + castle = given_castle('castle_repo') + + some_nested_file = home.file('some/nested/file.txt') + homesick.track(some_nested_file.to_s, 'castle_repo') + + manifest = Pathname.new(castle.parent.join('.manifest')) + File.open(manifest, 'r') do |f| + f.readline.should == "some/nested\n" + end + end + + it 'should NOT add anything if the files parent is already listed' do + castle = given_castle('castle_repo') + + some_nested_file = home.file('some/nested/file.txt') + other_nested_file = home.file('some/nested/other.txt') + homesick.track(some_nested_file.to_s, 'castle_repo') + homesick.track(other_nested_file.to_s, 'castle_repo') + + manifest = Pathname.new(castle.parent.join('.manifest')) + File.open(manifest, 'r') do |f| + f.readlines.size.should == 1 + end + end + end end end From a76d09d3f6b0b67837623b493bd82c44fcc0d611 Mon Sep 17 00:00:00 2001 From: muratayusuke Date: Fri, 24 May 2013 17:40:35 +0000 Subject: [PATCH 04/18] symlink subdirs with .homesick_subdir --- lib/homesick.rb | 29 ++++++++++++++++++++++++++++- spec/homesick_spec.rb | 15 +++++++++++++++ spec/spec_helper.rb | 11 +++++++++-- 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/lib/homesick.rb b/lib/homesick.rb index 341e3f9..8f48c9b 100644 --- a/lib/homesick.rb +++ b/lib/homesick.rb @@ -10,6 +10,7 @@ class Homesick < Thor add_runtime_options! GITHUB_NAME_REPO_PATTERN = /\A([A-Za-z_-]+\/[A-Za-z_-]+)\Z/ + SUBDIR_FILENAME = ".homesick_subdir" def initialize(args=[], options={}, config={}) super @@ -96,7 +97,17 @@ class Homesick < Thor check_castle_existance(name, "symlink") inside castle_dir(name) do - files = Pathname.glob('{.*,*}').reject{|a| [".",".."].include?(a.to_s)} + # prepare subdir information + subdir_file = Pathname.new(".").join(SUBDIR_FILENAME) + subdirs = [] + if subdir_file.exist? then + subdir_file.readlines.each do |subdir| + subdirs.push(subdir.chomp) + end + end + + # link files + files = Pathname.glob('{.*,*}').reject{|a| [".", "..", SUBDIR_FILENAME, subdirs].flatten.include?(a.to_s)} files.each do |path| absolute_path = path.expand_path @@ -106,6 +117,22 @@ class Homesick < Thor ln_s absolute_path, adjusted_path end end + + # link files in subdirs + subdirs.each do |subdir| + inside subdir do + files = Pathname.glob('{.*,*}').reject{|a| [".", ".."].include?(a.to_s)} + files.each do |path| + absolute_path = path.expand_path + + inside home_dir.join(subdir) do + adjusted_path = (home_dir + path).basename + + ln_s absolute_path, adjusted_path + end + end + end + end end end diff --git a/spec/homesick_spec.rb b/spec/homesick_spec.rb index 81fafb7..9ad98c2 100644 --- a/spec/homesick_spec.rb +++ b/spec/homesick_spec.rb @@ -120,6 +120,21 @@ describe "homesick" do existing_dotdir_link.readlink.should == dotdir end end + + context "when .homesick_subdir exists" do + let(:castle) { given_castle("glencairn", "glencairn", [".config"]) } + + it "can symlink in sub directory" do + dotdir = castle.directory(".config") + dotfile = dotdir.file(".some_dotfile") + + homesick.symlink("glencairn") + + home_dotdir = home.join(".config") + home_dotdir.symlink?.should == false + home_dotdir.join(".some_dotfile").readlink.should == dotfile + end + end end describe "list" do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 498bbab..26225f4 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -16,12 +16,19 @@ RSpec.configure do |config| homesick.stub(:say_status) end - def given_castle(name, path=name) + def given_castle(name, path=name, subdirs=[]) castles.directory(path) do |castle| Dir.chdir(castle) do system "git init >/dev/null 2>&1" system "git remote add origin git://github.com/technicalpickles/#{name}.git >/dev/null 2>&1" - return castle.directory("home") + castle_home = castle.directory("home") + if subdirs then + subdir_file = castle_home.join(Homesick::SUBDIR_FILENAME) + subdirs.each do |subdir| + system "echo #{subdir} >> #{subdir_file}" + end + end + return castle_home end end end From 6867ef78dc91290022fbd70c5af266715e26d004 Mon Sep 17 00:00:00 2001 From: Eric West Date: Fri, 24 May 2013 16:24:42 -0500 Subject: [PATCH 05/18] Handling edge cases Covers only edge cases related to tracking, not yet handling linking or updating. Getting a bit hairy, must be refactored. --- lib/homesick.rb | 33 ++++++++++++++++++++++++++++++++- spec/homesick_spec.rb | 14 ++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/lib/homesick.rb b/lib/homesick.rb index 9f5a63f..e2cc155 100644 --- a/lib/homesick.rb +++ b/lib/homesick.rb @@ -123,7 +123,38 @@ class Homesick < Thor FileUtils.mkdir_p castle_path end - mv absolute_path, castle_path + # Are we already tracking this or anything inside it? + target = Pathname.new(castle_path.join(file.basename)) + + if target.exist? + + if absolute_path.directory? + child_files = absolute_path.children + child_files.each do |child| + + if target.join(child.basename).exist? + next + end + + mv child, target + end + absolute_path.rmtree + manifest = Pathname.new(repos_dir.join(castle, '.manifest')) + if manifest.exist? + lines = IO.readlines(manifest).delete_if { |line| line == "#{relative_dir + file.basename}\n" } + File.open(manifest, 'w') { |manfile| manfile.puts lines } + end + + elsif absolute_path.mtime > target.mtime && !absolute_path.symlink? + target.delete + mv absolute_path, castle_path + else + shell.say_status(:track, "#{target} already exists, and is more recent than #{file}. Run 'homesick SYMLINK CASTLE' to create symlinks.") + end + + else + mv absolute_path, castle_path + end inside home_dir do absolute_path = castle_path + file.basename diff --git a/spec/homesick_spec.rb b/spec/homesick_spec.rb index d769489..7880d1f 100644 --- a/spec/homesick_spec.rb +++ b/spec/homesick_spec.rb @@ -219,6 +219,20 @@ describe "homesick" do f.readlines.size.should == 1 end end + + it 'should remove the parent of a tracked file from the manifest if the parent itself is tracked' do + castle = given_castle('castle_repo') + + some_nested_file = home.file('some/nested/file.txt') + nested_parent = home.directory('some/nested/') + homesick.track(some_nested_file.to_s, 'castle_repo') + homesick.track(nested_parent.to_s, 'castle_repo') + + manifest = Pathname.new(castle.parent.join('.manifest')) + File.open(manifest, 'r') do |f| + f.each_line { |line| line.should_not == "some/nested\n" } + end + end end end end From e924cbefda7a0173f6f21aaf8fbbe040f4f5e1b1 Mon Sep 17 00:00:00 2001 From: Eric West Date: Fri, 24 May 2013 21:57:12 -0500 Subject: [PATCH 06/18] refactor, cleanup and tweak --- lib/homesick.rb | 81 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 56 insertions(+), 25 deletions(-) diff --git a/lib/homesick.rb b/lib/homesick.rb index e2cc155..0f1507c 100644 --- a/lib/homesick.rb +++ b/lib/homesick.rb @@ -125,33 +125,18 @@ class Homesick < Thor # Are we already tracking this or anything inside it? target = Pathname.new(castle_path.join(file.basename)) - if target.exist? - if absolute_path.directory? - child_files = absolute_path.children - child_files.each do |child| - - if target.join(child.basename).exist? - next - end - - mv child, target - end + move_dir_contents(target, absolute_path) absolute_path.rmtree - manifest = Pathname.new(repos_dir.join(castle, '.manifest')) - if manifest.exist? - lines = IO.readlines(manifest).delete_if { |line| line == "#{relative_dir + file.basename}\n" } - File.open(manifest, 'w') { |manfile| manfile.puts lines } - end + manifest_remove(castle, relative_dir + file.basename) - elsif absolute_path.mtime > target.mtime && !absolute_path.symlink? + elsif more_recent? absolute_path, target target.delete mv absolute_path, castle_path else - shell.say_status(:track, "#{target} already exists, and is more recent than #{file}. Run 'homesick SYMLINK CASTLE' to create symlinks.") + shell.say_status(:track, "#{target} already exists, and is more recent than #{file}. Run 'homesick SYMLINK CASTLE' to create symlinks.", :blue) unless options[:quiet] end - else mv absolute_path, castle_path end @@ -166,14 +151,10 @@ class Homesick < Thor git_add absolute_path end - # are we tracking something nested? Add the parent dir to the manifest unless its already listed + # are we tracking something nested? Add the parent dir to the manifest unless relative_dir.eql?(Pathname.new('.')) - manifest_path = Pathname.new(repos_dir.join(castle, '.manifest')) - File.open(manifest_path, 'a+') do |manifest| - manifest.puts relative_dir unless manifest.readlines.inject(false) { |memo, line| line.eql?("#{relative_dir.to_s}\n") || memo } - end + manifest_add(castle, relative_dir) end - end desc "list", "List cloned castles" @@ -265,4 +246,54 @@ class Homesick < Thor git_push end end + + def manifest(castle) + Pathname.new(repos_dir.join(castle, '.manifest')) + end + + def manifest_add(castle, path) + manifest_path = manifest(castle) + File.open(manifest_path, 'a+') do |manifest| + manifest.puts path unless manifest.readlines.inject(false) { |memo, line| line.eql?("#{path.to_s}\n") || memo } + end + + inside castle_dir(castle) do + git_add manifest_path + end + end + + def manifest_remove(castle, path) + manifest_file = manifest(castle) + if manifest_file.exist? + lines = IO.readlines(manifest_file).delete_if { |line| line == "#{path}\n" } + File.open(manifest_file, 'w') { |manfile| manfile.puts lines } + end + + inside castle_dir(castle) do + git_add manifest_file + end + end + + def move_dir_contents(target, dir_path) + child_files = dir_path.children + child_files.each do |child| + + target_path = target.join(child.basename) + if target_path.exist? + if more_recent?(child, target_path) && target.file? + target_path.delete + mv child, target + end + next + end + + mv child, target + end + end + + def more_recent?(first, second) + first_p = Pathname.new(first) + second_p = Pathname.new(second) + first_p.mtime > second_p.mtime && !first_p.symlink? + end end From c31c67a3eb8126c2493236984a4229176b83633b Mon Sep 17 00:00:00 2001 From: muratayusuke Date: Sun, 26 May 2013 17:12:28 +0000 Subject: [PATCH 07/18] support nested dir in .homesick_subdir --- lib/homesick.rb | 13 +++++++++++-- spec/homesick_spec.rb | 17 +++++++++++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/lib/homesick.rb b/lib/homesick.rb index 8f48c9b..17d67f7 100644 --- a/lib/homesick.rb +++ b/lib/homesick.rb @@ -105,9 +105,18 @@ class Homesick < Thor subdirs.push(subdir.chomp) end end + ignore_dirs = [] + subdirs.each do |subdir| + splited_subdir = Pathname.new(subdir).split + ignore_dir = splited_subdir[0].to_s + if ignore_dir == "." then + ignore_dir = splited_subdir[1].to_s + end + ignore_dirs.push(ignore_dir) + end # link files - files = Pathname.glob('{.*,*}').reject{|a| [".", "..", SUBDIR_FILENAME, subdirs].flatten.include?(a.to_s)} + files = Pathname.glob('{.*,*}').reject{|a| [".", "..", SUBDIR_FILENAME, ignore_dirs].flatten.include?(a.to_s)} files.each do |path| absolute_path = path.expand_path @@ -126,7 +135,7 @@ class Homesick < Thor absolute_path = path.expand_path inside home_dir.join(subdir) do - adjusted_path = (home_dir + path).basename + adjusted_path = (home_dir + subdir + path).basename ln_s absolute_path, adjusted_path end diff --git a/spec/homesick_spec.rb b/spec/homesick_spec.rb index 9ad98c2..90132ed 100644 --- a/spec/homesick_spec.rb +++ b/spec/homesick_spec.rb @@ -121,9 +121,8 @@ describe "homesick" do end end - context "when .homesick_subdir exists" do + context "with '.config' in .homesick_subdir" do let(:castle) { given_castle("glencairn", "glencairn", [".config"]) } - it "can symlink in sub directory" do dotdir = castle.directory(".config") dotfile = dotdir.file(".some_dotfile") @@ -135,6 +134,20 @@ describe "homesick" do home_dotdir.join(".some_dotfile").readlink.should == dotfile end end + + context "with '.config/appA' in .homesick_subdir" do + let(:castle) { given_castle("glencairn", "glencairn", [".config/appA"]) } + it "can symlink in nested sub directory" do + dotdir = castle.directory(".config").directory("appA") + dotfile = dotdir.file(".some_dotfile") + + homesick.symlink("glencairn") + + home_dotdir = home.join(".config").join("appA") + home_dotdir.symlink?.should == false + home_dotdir.join(".some_dotfile").readlink.should == dotfile + end + end end describe "list" do From 3559d825cacd48c36e1220d9c90a83ebfc7be244 Mon Sep 17 00:00:00 2001 From: muratayusuke Date: Mon, 27 May 2013 18:08:09 +0000 Subject: [PATCH 08/18] replace .manifest to .homesick_subdir --- lib/homesick.rb | 41 +++++++++++++++++++---------------------- spec/homesick_spec.rb | 18 +++++++++--------- 2 files changed, 28 insertions(+), 31 deletions(-) diff --git a/lib/homesick.rb b/lib/homesick.rb index cf7f5bf..a75d5f1 100644 --- a/lib/homesick.rb +++ b/lib/homesick.rb @@ -98,10 +98,10 @@ class Homesick < Thor inside castle_dir(name) do # prepare subdir information - subdir_file = Pathname.new(".").join(SUBDIR_FILENAME) + subdir_filepath = subdir_file(name) subdirs = [] - if subdir_file.exist? then - subdir_file.readlines.each do |subdir| + if subdir_filepath.exist? then + subdir_filepath.readlines.each do |subdir| subdirs.push(subdir.chomp) end end @@ -154,10 +154,7 @@ class Homesick < Thor absolute_path = file.expand_path relative_dir = absolute_path.relative_path_from(home_dir).dirname castle_path = Pathname.new(castle_dir(castle)).join(relative_dir) - - unless castle_path.exist? - FileUtils.mkdir_p castle_path - end + FileUtils.mkdir_p castle_path # Are we already tracking this or anything inside it? target = Pathname.new(castle_path.join(file.basename)) @@ -165,7 +162,7 @@ class Homesick < Thor if absolute_path.directory? move_dir_contents(target, absolute_path) absolute_path.rmtree - manifest_remove(castle, relative_dir + file.basename) + subdir_remove(castle, relative_dir + file.basename) elsif more_recent? absolute_path, target target.delete @@ -189,7 +186,7 @@ class Homesick < Thor # are we tracking something nested? Add the parent dir to the manifest unless relative_dir.eql?(Pathname.new('.')) - manifest_add(castle, relative_dir) + subdir_add(castle, relative_dir) end end @@ -283,30 +280,30 @@ class Homesick < Thor end end - def manifest(castle) - Pathname.new(repos_dir.join(castle, '.manifest')) + def subdir_file(castle) + castle_dir(castle).join(SUBDIR_FILENAME) end - def manifest_add(castle, path) - manifest_path = manifest(castle) - File.open(manifest_path, 'a+') do |manifest| - manifest.puts path unless manifest.readlines.inject(false) { |memo, line| line.eql?("#{path.to_s}\n") || memo } + def subdir_add(castle, path) + subdir_filepath = subdir_file(castle) + File.open(subdir_filepath, 'a+') do |subdir| + subdir.puts path unless subdir.readlines.inject(false) { |memo, line| line.eql?("#{path.to_s}\n") || memo } end inside castle_dir(castle) do - git_add manifest_path + git_add subdir_filepath end end - def manifest_remove(castle, path) - manifest_file = manifest(castle) - if manifest_file.exist? - lines = IO.readlines(manifest_file).delete_if { |line| line == "#{path}\n" } - File.open(manifest_file, 'w') { |manfile| manfile.puts lines } + def subdir_remove(castle, path) + subdir_filepath = subdir_file(castle) + if subdir_filepath.exist? + lines = IO.readlines(subdir_filepath).delete_if { |line| line == "#{path}\n" } + File.open(subdir_filepath, 'w') { |manfile| manfile.puts lines } end inside castle_dir(castle) do - git_add manifest_file + git_add subdir_filepath end end diff --git a/spec/homesick_spec.rb b/spec/homesick_spec.rb index acecdcb..3dbf3cd 100644 --- a/spec/homesick_spec.rb +++ b/spec/homesick_spec.rb @@ -220,16 +220,16 @@ describe "homesick" do File.realdirpath(some_nested_dir).should == File.realdirpath(tracked_file) end - describe "manifest" do + describe "subdir_file" do - it 'should add the nested files parent to the manifest' do + it 'should add the nested files parent to the subdir_file' do castle = given_castle('castle_repo') some_nested_file = home.file('some/nested/file.txt') homesick.track(some_nested_file.to_s, 'castle_repo') - manifest = Pathname.new(castle.parent.join('.manifest')) - File.open(manifest, 'r') do |f| + subdir_file = castle.join(Homesick::SUBDIR_FILENAME) + File.open(subdir_file, 'r') do |f| f.readline.should == "some/nested\n" end end @@ -242,13 +242,13 @@ describe "homesick" do homesick.track(some_nested_file.to_s, 'castle_repo') homesick.track(other_nested_file.to_s, 'castle_repo') - manifest = Pathname.new(castle.parent.join('.manifest')) - File.open(manifest, 'r') do |f| + subdir_file = castle.join(Homesick::SUBDIR_FILENAME) + File.open(subdir_file, 'r') do |f| f.readlines.size.should == 1 end end - it 'should remove the parent of a tracked file from the manifest if the parent itself is tracked' do + it 'should remove the parent of a tracked file from the subdir_file if the parent itself is tracked' do castle = given_castle('castle_repo') some_nested_file = home.file('some/nested/file.txt') @@ -256,8 +256,8 @@ describe "homesick" do homesick.track(some_nested_file.to_s, 'castle_repo') homesick.track(nested_parent.to_s, 'castle_repo') - manifest = Pathname.new(castle.parent.join('.manifest')) - File.open(manifest, 'r') do |f| + subdir_file = castle.join(Homesick::SUBDIR_FILENAME) + File.open(subdir_file, 'r') do |f| f.each_line { |line| line.should_not == "some/nested\n" } end end From bf1fc58e10dcdc9150f1433f65f6d0759347aeb0 Mon Sep 17 00:00:00 2001 From: muratayusuke Date: Thu, 30 May 2013 14:33:08 +0000 Subject: [PATCH 09/18] fix spec for ruby-1.8.7 --- spec/homesick_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/homesick_spec.rb b/spec/homesick_spec.rb index 3dbf3cd..b5ac78f 100644 --- a/spec/homesick_spec.rb +++ b/spec/homesick_spec.rb @@ -217,7 +217,7 @@ describe "homesick" do tracked_file = castle.join('some/nested/directory/') tracked_file.should exist - File.realdirpath(some_nested_dir).should == File.realdirpath(tracked_file) + some_nested_dir.realpath.should == tracked_file.realpath end describe "subdir_file" do From 76fcf5d0b7d35e32c4ee8b0857cf53998c8972ad Mon Sep 17 00:00:00 2001 From: muratayusuke Date: Thu, 30 May 2013 14:33:45 +0000 Subject: [PATCH 10/18] add ruby-2.0.0 to travis --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index e14e9bc..285725e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ language: ruby rvm: + - 2.0.0 - 1.9.3 - 1.8.7 From 97fe1686f5adcbdf21be327cbce95fb31c5dcce6 Mon Sep 17 00:00:00 2001 From: muratayusuke Date: Thu, 30 May 2013 17:38:06 +0000 Subject: [PATCH 11/18] refactor given_castle --- spec/homesick_spec.rb | 6 +++--- spec/spec_helper.rb | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/spec/homesick_spec.rb b/spec/homesick_spec.rb index b5ac78f..774741a 100644 --- a/spec/homesick_spec.rb +++ b/spec/homesick_spec.rb @@ -122,7 +122,7 @@ describe "homesick" do end context "with '.config' in .homesick_subdir" do - let(:castle) { given_castle("glencairn", "glencairn", [".config"]) } + let(:castle) { given_castle("glencairn", [".config"]) } it "can symlink in sub directory" do dotdir = castle.directory(".config") dotfile = dotdir.file(".some_dotfile") @@ -136,7 +136,7 @@ describe "homesick" do end context "with '.config/appA' in .homesick_subdir" do - let(:castle) { given_castle("glencairn", "glencairn", [".config/appA"]) } + let(:castle) { given_castle("glencairn", [".config/appA"]) } it "can symlink in nested sub directory" do dotdir = castle.directory(".config").directory("appA") dotfile = dotdir.file(".some_dotfile") @@ -153,7 +153,7 @@ describe "homesick" do describe "list" do it "should say each castle in the castle directory" do given_castle('zomg') - given_castle('zomg', 'wtf/zomg') + given_castle('wtf/zomg') homesick.should_receive(:say_status).with("zomg", "git://github.com/technicalpickles/zomg.git", :cyan) homesick.should_receive(:say_status).with("wtf/zomg", "git://github.com/technicalpickles/zomg.git", :cyan) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 26225f4..9dfb5cb 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -16,7 +16,8 @@ RSpec.configure do |config| homesick.stub(:say_status) end - def given_castle(name, path=name, subdirs=[]) + def given_castle(path, subdirs=[]) + name = Pathname.new(path).basename castles.directory(path) do |castle| Dir.chdir(castle) do system "git init >/dev/null 2>&1" From a95c4b244603f4580b12e9d274798e76c2a5691c Mon Sep 17 00:00:00 2001 From: muratayusuke Date: Mon, 3 Jun 2013 18:17:38 +0000 Subject: [PATCH 12/18] refactor symlink --- lib/homesick.rb | 92 ++++++++++++++++++++++++----------------- lib/homesick/actions.rb | 1 + 2 files changed, 54 insertions(+), 39 deletions(-) diff --git a/lib/homesick.rb b/lib/homesick.rb index a75d5f1..67b9ac3 100644 --- a/lib/homesick.rb +++ b/lib/homesick.rb @@ -97,50 +97,14 @@ class Homesick < Thor check_castle_existance(name, "symlink") inside castle_dir(name) do - # prepare subdir information - subdir_filepath = subdir_file(name) - subdirs = [] - if subdir_filepath.exist? then - subdir_filepath.readlines.each do |subdir| - subdirs.push(subdir.chomp) - end - end - ignore_dirs = [] - subdirs.each do |subdir| - splited_subdir = Pathname.new(subdir).split - ignore_dir = splited_subdir[0].to_s - if ignore_dir == "." then - ignore_dir = splited_subdir[1].to_s - end - ignore_dirs.push(ignore_dir) - end + subdirs = subdirs(name) # link files - files = Pathname.glob('{.*,*}').reject{|a| [".", "..", SUBDIR_FILENAME, ignore_dirs].flatten.include?(a.to_s)} - files.each do |path| - absolute_path = path.expand_path - - inside home_dir do - adjusted_path = (home_dir + path).basename - - ln_s absolute_path, adjusted_path - end - end + symlink_each(name, castle_dir(name), subdirs) # link files in subdirs subdirs.each do |subdir| - inside subdir do - files = Pathname.glob('{.*,*}').reject{|a| [".", ".."].include?(a.to_s)} - files.each do |path| - absolute_path = path.expand_path - - inside home_dir.join(subdir) do - adjusted_path = (home_dir + subdir + path).basename - - ln_s absolute_path, adjusted_path - end - end - end + symlink_each(name, subdir, subdirs) end end end @@ -284,6 +248,17 @@ class Homesick < Thor castle_dir(castle).join(SUBDIR_FILENAME) end + def subdirs(castle) + subdir_filepath = subdir_file(castle) + subdirs = [] + if subdir_filepath.exist? + subdir_filepath.readlines.each do |subdir| + subdirs.push(subdir.chomp) + end + end + subdirs + end + def subdir_add(castle, path) subdir_filepath = subdir_file(castle) File.open(subdir_filepath, 'a+') do |subdir| @@ -329,4 +304,43 @@ class Homesick < Thor second_p = Pathname.new(second) first_p.mtime > second_p.mtime && !first_p.symlink? end + + def symlink_each(castle, basedir, subdirs) + basedir = Pathname.new(basedir).expand_path + inside basedir do + files = Pathname.glob('{.*,*}').reject{|a| [".", ".."].include?(a.to_s)} + files.each do |path| + absolute_path = path.expand_path + castle_home = castle_dir(castle) + + # ignore subdir file + next if absolute_path == castle_home.join(SUBDIR_FILENAME) + + # make ignore dirs + ignore_dirs = [] + subdirs.each do |subdir| + splited_subdir = Pathname.new(subdir).split + ignore_dir = splited_subdir[0].to_s + if ignore_dir == "." then + ignore_dir = splited_subdir[1].to_s + end + ignore_dirs.push(ignore_dir) + end + + # ignore dirs written in subdir file + matched = false + ignore_dirs.each do |ignore_dir| + if absolute_path == castle_home.join(ignore_dir) + matched = true + next + end + end + next if matched + + relative_dir = basedir.relative_path_from(castle_home) + home_path = home_dir.join(relative_dir).join(path) + ln_s absolute_path, home_path + end + end + end end diff --git a/lib/homesick/actions.rb b/lib/homesick/actions.rb index 9e5d903..82c4036 100644 --- a/lib/homesick/actions.rb +++ b/lib/homesick/actions.rb @@ -93,6 +93,7 @@ class Homesick def ln_s(source, destination, config = {}) source = Pathname.new(source) destination = Pathname.new(destination) + FileUtils.mkdir_p destination.dirname if destination.symlink? if destination.readlink == source From 8e58a3f5e2545ed5c6603fe60153aeb44a3284df Mon Sep 17 00:00:00 2001 From: muratayusuke Date: Tue, 4 Jun 2013 17:36:47 +0000 Subject: [PATCH 13/18] deal with edge case: the parent and descendant are both listed in the manifest --- lib/homesick.rb | 16 +++++++--------- spec/homesick_spec.rb | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/lib/homesick.rb b/lib/homesick.rb index 67b9ac3..43fdd53 100644 --- a/lib/homesick.rb +++ b/lib/homesick.rb @@ -306,7 +306,7 @@ class Homesick < Thor end def symlink_each(castle, basedir, subdirs) - basedir = Pathname.new(basedir).expand_path + absolute_basedir = Pathname.new(basedir).expand_path inside basedir do files = Pathname.glob('{.*,*}').reject{|a| [".", ".."].include?(a.to_s)} files.each do |path| @@ -319,25 +319,23 @@ class Homesick < Thor # make ignore dirs ignore_dirs = [] subdirs.each do |subdir| - splited_subdir = Pathname.new(subdir).split - ignore_dir = splited_subdir[0].to_s - if ignore_dir == "." then - ignore_dir = splited_subdir[1].to_s + # ignore all parent of each line in subdir file + Pathname.new(subdir).ascend do |p| + ignore_dirs.push(p) end - ignore_dirs.push(ignore_dir) end # ignore dirs written in subdir file matched = false - ignore_dirs.each do |ignore_dir| + ignore_dirs.uniq.each do |ignore_dir| if absolute_path == castle_home.join(ignore_dir) matched = true - next + break end end next if matched - relative_dir = basedir.relative_path_from(castle_home) + relative_dir = absolute_basedir.relative_path_from(castle_home) home_path = home_dir.join(relative_dir).join(path) ln_s absolute_path, home_path end diff --git a/spec/homesick_spec.rb b/spec/homesick_spec.rb index 774741a..7493d94 100644 --- a/spec/homesick_spec.rb +++ b/spec/homesick_spec.rb @@ -148,6 +148,25 @@ describe "homesick" do home_dotdir.join(".some_dotfile").readlink.should == dotfile end end + + context "with '.config' and '.config/appA' in .homesick_subdir" do + let(:castle) { given_castle("glencairn", [".config", ".config/appA"]) } + it "can symlink under both of .config and .config/appA" do + config_dir = castle.directory(".config") + config_dotfile = config_dir.file(".some_dotfile") + appA_dir = config_dir.directory("appA") + appA_dotfile = appA_dir.file(".some_appfile") + + homesick.symlink("glencairn") + + home_config_dir = home.join(".config") + home_appA_dir = home_config_dir.join("appA") + home_config_dir.symlink?.should == false + home_config_dir.join(".some_dotfile").readlink.should == config_dotfile + home_appA_dir.symlink?.should == false + home_appA_dir.join(".some_appfile").readlink.should == appA_dotfile + end + end end describe "list" do From 3ddd3207b305a3571639fb1fc5e473d3e6d5f239 Mon Sep 17 00:00:00 2001 From: muratayusuke Date: Tue, 4 Jun 2013 18:14:20 +0000 Subject: [PATCH 14/18] add .homesick_subdir explanation to README --- README.markdown | 78 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/README.markdown b/README.markdown index a0d239d..87fd3b4 100644 --- a/README.markdown +++ b/README.markdown @@ -51,6 +51,84 @@ Not sure what else homesick has up its sleeve? There's always the built in help: homesick help +## .homesick_subdir + +`homesick symlink` basically makes symlink to only first depth in `castle/home`. If you want to link nested files/directories, please use .homesick_subdir. + +For example, when you have castle like this: + + castle/home + `-- .config + `-- fooapp + |-- config1 + |-- config2 + `-- config3 + +and have home like this: + + $ tree -a + ~ + |-- .config + | `-- barapp + | |-- config1 + | |-- config2 + | `-- config3 + `-- .emacs.d + |-- elisp + `-- inits + +You may want to symlink only to `castle/home/.config/fooapp` instead of `castle/home/.config` because you already have `~/.config/barapp`. In this case, you can use .homesick_subdir. Please write "directories you want to look up sub direcoties (instead of just first depth)" in this file. + +castle/home/.homesick_subdir + + .config + +and run `homesick symlink CASTLE`. The result is: + + ~ + |-- .config + | |-- barapp + | | |-- config1 + | | |-- config2 + | | `-- config3 + | `-- fooapp -> castle/home/.config/fooapp + `-- .emacs.d + |-- elisp + `-- inits + +Or `homesick track NESTED_FILE CASTLE` adds a line automatically. For example: + + homesick track .emacs/elisp castle + +castle/home/.homesick_subdir + + .config + .emacs.d + +home directory + + ~ + |-- .config + | |-- barapp + | | |-- config1 + | | |-- config2 + | | `-- config3 + | `-- fooapp -> castle/home/.config/fooapp + `-- .emacs.d + |-- elisp -> castle/home/.emacs/elisp + `-- inits + +and castle + + castle/home + |-- .config + | `-- fooapp + | |-- config1 + | |-- config2 + | `-- config3 + `-- .emacs.d + `-- elisp + ## Note on Patches/Pull Requests * Fork the project. From 6b281ef0016ad9ea5d70bd28b89ef26eee420016 Mon Sep 17 00:00:00 2001 From: Yusuke Murata Date: Wed, 5 Jun 2013 03:15:44 +0900 Subject: [PATCH 15/18] fix style of README --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 87fd3b4..ac4d3df 100644 --- a/README.markdown +++ b/README.markdown @@ -115,7 +115,7 @@ home directory | | `-- config3 | `-- fooapp -> castle/home/.config/fooapp `-- .emacs.d - |-- elisp -> castle/home/.emacs/elisp + |-- elisp -> castle/home/.emacs/elisp `-- inits and castle From 70f5d24e0a6c8f162d79f2d4413fce33408e4449 Mon Sep 17 00:00:00 2001 From: Yusuke Murata Date: Wed, 5 Jun 2013 03:18:40 +0900 Subject: [PATCH 16/18] fix style of README --- README.markdown | 64 ++++++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/README.markdown b/README.markdown index ac4d3df..1a9460a 100644 --- a/README.markdown +++ b/README.markdown @@ -62,20 +62,20 @@ For example, when you have castle like this: `-- fooapp |-- config1 |-- config2 - `-- config3 + `-- config3 and have home like this: $ tree -a - ~ - |-- .config - | `-- barapp - | |-- config1 - | |-- config2 - | `-- config3 - `-- .emacs.d - |-- elisp - `-- inits + ~ + |-- .config + | `-- barapp + | |-- config1 + | |-- config2 + | `-- config3 + `-- .emacs.d + |-- elisp + `-- inits You may want to symlink only to `castle/home/.config/fooapp` instead of `castle/home/.config` because you already have `~/.config/barapp`. In this case, you can use .homesick_subdir. Please write "directories you want to look up sub direcoties (instead of just first depth)" in this file. @@ -85,16 +85,16 @@ castle/home/.homesick_subdir and run `homesick symlink CASTLE`. The result is: - ~ - |-- .config - | |-- barapp - | | |-- config1 - | | |-- config2 - | | `-- config3 - | `-- fooapp -> castle/home/.config/fooapp - `-- .emacs.d - |-- elisp - `-- inits + ~ + |-- .config + | |-- barapp + | | |-- config1 + | | |-- config2 + | | `-- config3 + | `-- fooapp -> castle/home/.config/fooapp + `-- .emacs.d + |-- elisp + `-- inits Or `homesick track NESTED_FILE CASTLE` adds a line automatically. For example: @@ -107,16 +107,16 @@ castle/home/.homesick_subdir home directory - ~ - |-- .config - | |-- barapp - | | |-- config1 - | | |-- config2 - | | `-- config3 - | `-- fooapp -> castle/home/.config/fooapp - `-- .emacs.d - |-- elisp -> castle/home/.emacs/elisp - `-- inits + ~ + |-- .config + | |-- barapp + | | |-- config1 + | | |-- config2 + | | `-- config3 + | `-- fooapp -> castle/home/.config/fooapp + `-- .emacs.d + |-- elisp -> castle/home/.emacs/elisp + `-- inits and castle @@ -126,8 +126,8 @@ and castle | |-- config1 | |-- config2 | `-- config3 - `-- .emacs.d - `-- elisp + `-- .emacs.d + `-- elisp ## Note on Patches/Pull Requests From da0958d45582aa6cb96cee274d14d1e8922cff36 Mon Sep 17 00:00:00 2001 From: Yusuke Murata Date: Thu, 6 Jun 2013 21:19:21 +0900 Subject: [PATCH 17/18] fix typo --- README.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.markdown b/README.markdown index 1a9460a..2ba35c8 100644 --- a/README.markdown +++ b/README.markdown @@ -98,7 +98,7 @@ and run `homesick symlink CASTLE`. The result is: Or `homesick track NESTED_FILE CASTLE` adds a line automatically. For example: - homesick track .emacs/elisp castle + homesick track .emacs.d/elisp castle castle/home/.homesick_subdir @@ -115,7 +115,7 @@ home directory | | `-- config3 | `-- fooapp -> castle/home/.config/fooapp `-- .emacs.d - |-- elisp -> castle/home/.emacs/elisp + |-- elisp -> castle/home/.emacs.d/elisp `-- inits and castle From 360e8185f75244b87d1a4f9191057616987097f7 Mon Sep 17 00:00:00 2001 From: muratayusuke Date: Thu, 6 Jun 2013 12:39:41 +0000 Subject: [PATCH 18/18] move castle/home/.homesick_subdir to castle/.homesick_subdir --- lib/homesick.rb | 5 +---- spec/homesick_spec.rb | 6 +++--- spec/spec_helper.rb | 5 ++--- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/lib/homesick.rb b/lib/homesick.rb index 43fdd53..cc03e81 100644 --- a/lib/homesick.rb +++ b/lib/homesick.rb @@ -245,7 +245,7 @@ class Homesick < Thor end def subdir_file(castle) - castle_dir(castle).join(SUBDIR_FILENAME) + repos_dir.join(castle, SUBDIR_FILENAME) end def subdirs(castle) @@ -313,9 +313,6 @@ class Homesick < Thor absolute_path = path.expand_path castle_home = castle_dir(castle) - # ignore subdir file - next if absolute_path == castle_home.join(SUBDIR_FILENAME) - # make ignore dirs ignore_dirs = [] subdirs.each do |subdir| diff --git a/spec/homesick_spec.rb b/spec/homesick_spec.rb index 7493d94..0d5c83a 100644 --- a/spec/homesick_spec.rb +++ b/spec/homesick_spec.rb @@ -247,7 +247,7 @@ describe "homesick" do some_nested_file = home.file('some/nested/file.txt') homesick.track(some_nested_file.to_s, 'castle_repo') - subdir_file = castle.join(Homesick::SUBDIR_FILENAME) + subdir_file = castle.parent.join(Homesick::SUBDIR_FILENAME) File.open(subdir_file, 'r') do |f| f.readline.should == "some/nested\n" end @@ -261,7 +261,7 @@ describe "homesick" do homesick.track(some_nested_file.to_s, 'castle_repo') homesick.track(other_nested_file.to_s, 'castle_repo') - subdir_file = castle.join(Homesick::SUBDIR_FILENAME) + subdir_file = castle.parent.join(Homesick::SUBDIR_FILENAME) File.open(subdir_file, 'r') do |f| f.readlines.size.should == 1 end @@ -275,7 +275,7 @@ describe "homesick" do homesick.track(some_nested_file.to_s, 'castle_repo') homesick.track(nested_parent.to_s, 'castle_repo') - subdir_file = castle.join(Homesick::SUBDIR_FILENAME) + subdir_file = castle.parent.join(Homesick::SUBDIR_FILENAME) File.open(subdir_file, 'r') do |f| f.each_line { |line| line.should_not == "some/nested\n" } end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 9dfb5cb..1c78cf3 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -22,14 +22,13 @@ RSpec.configure do |config| Dir.chdir(castle) do system "git init >/dev/null 2>&1" system "git remote add origin git://github.com/technicalpickles/#{name}.git >/dev/null 2>&1" - castle_home = castle.directory("home") if subdirs then - subdir_file = castle_home.join(Homesick::SUBDIR_FILENAME) + subdir_file = castle.join(Homesick::SUBDIR_FILENAME) subdirs.each do |subdir| system "echo #{subdir} >> #{subdir_file}" end end - return castle_home + return castle.directory("home") end end end