38 Commits

Author SHA1 Message Date
Trae Robrock
8874994feb Regenerate gemspec for version 0.9.7 2013-11-02 16:03:57 -07:00
Trae Robrock
5a8b92f556 Bump version 2013-11-02 16:03:51 -07:00
Trae Robrock
a65c2e6a1f Merge pull request #57 from boyvanduuren/issue_54
Git clone now uses config push.default upstream
2013-11-02 16:02:20 -07:00
bcd
2d0304feb1 Git clone now uses config push.default upstream 2013-11-02 21:15:51 +01:00
Trae Robrock
34fec63234 Merge pull request #56 from cball/update-readme
Remove symlink shorthand note in README
2013-10-30 15:20:33 -07:00
Chris Ball
1d5f27f567 Remove symlink shorthand note in README
Seems that using `homesick symlink <username>/<reponame>` after a clone does not locate the directory properly. `homesick symlink <reponame>` works in both cases regardless if the shorthand or full git url was used to clone.
2013-10-30 14:01:40 -04:00
Trae Robrock
093db8bdac Regenerate gemspec for version 0.9.6 2013-10-18 07:18:15 -07:00
Trae Robrock
04602efd6e Bump version 2013-10-18 07:18:07 -07:00
Trae Robrock
3265de0c1d Regenerate gemspec for version 0.9.5 2013-10-18 07:17:39 -07:00
Trae Robrock
e4a428e0c5 Merge pull request #55 from mingkai0812/master
Change github-repo pattern to allow numbers for usernames/repos
2013-10-18 07:15:05 -07:00
mingkai
6cc28450a4 Change github-repo pattern to allow numbers for usernames/repos 2013-10-18 14:35:56 +02:00
Yusuke Murata
a0c7fbacb7 Merge pull request #53 from boyvanduuren/issue52
Change the destination for the github clone shortcut
2013-10-07 09:39:40 -07:00
bcd87
b750094934 Rake now passes on Ruby 1.8.7 on my machine 2013-09-24 08:15:56 +02:00
bcd87
d953a964cd Changed the spec, bundle exec rake works 2013-09-23 20:58:16 +02:00
bcd87
aa95ffac82 Using the homesick clone github shortcut now clones to ~/.homesick/repos/repo/, in stead of ~/.homesick/repos/username/repo/ 2013-09-23 20:30:10 +02:00
Trae Robrock
9c345828b0 Regenerate gemspec for version 0.9.5 2013-09-18 09:48:33 -07:00
Trae Robrock
59c137c653 Bump version the right way 2013-09-18 09:48:26 -07:00
Trae Robrock
3d405542af Regenerate gemspec for version 0.9.4 2013-09-18 09:47:46 -07:00
Trae Robrock
88ff4b85ce Bump version 2013-09-18 09:47:36 -07:00
Trae Robrock
461ac5f226 Merge pull request #51 from trobrock/fix-quoting
Files with parentheses in filename fail to symlink/track
2013-09-18 09:46:40 -07:00
Trae Robrock
a7d2d0a3f3 Add test for parens in filenames, and fixed 2013-09-18 09:25:09 -07:00
muratayusuke
191ce11d8e Regenerate gemspec for version 0.9.4 2013-07-31 23:41:49 +09:00
muratayusuke
0d28a3ef9b bump up version 2013-07-31 23:41:36 +09:00
muratayusuke
ac34249afe Regenerate gemspec for version 0.9.3 2013-07-31 23:40:22 +09:00
muratayusuke
d1f87be435 bump up version 2013-07-31 23:38:37 +09:00
muratayusuke
cbb6117d69 remove unused variables 2013-07-31 23:21:46 +09:00
muratayusuke
334a1db262 fix deprecated method: stub! -> stub 2013-07-31 23:14:51 +09:00
Yusuke Murata
e3bee69b27 Merge pull request #48 from trobrock/fix-homesickrc
Fix #19 homesickrc pathname needs a to_s to eval
2013-07-30 09:54:48 -07:00
Yusuke Murata
0ff5325e3e Merge pull request #43 from johnbellone/master
Default GitHub to use HTTPS protocol.
2013-07-21 10:47:31 -07:00
Yusuke Murata
40efb2f58a Merge pull request #47 from trobrock/unlink
Adding unlink function
2013-07-21 10:37:16 -07:00
Trae Robrock
4b20c7224e Add tests for the rc command 2013-07-17 08:04:34 -07:00
Trae Robrock
8e06beced6 Ignore vendor 2013-07-17 07:26:00 -07:00
Trae Robrock
b043f2a5ed Adding test for clone running homesickrc 2013-07-17 07:23:35 -07:00
John Bellone
3d59bc7a97 Update specs to for change to https vs. git protocol. 2013-07-17 07:28:39 -04:00
Trae Robrock
75dcad8ea4 Fix #19 homesickrc pathname needs a to_s to eval
Also, moved the file evaluation into a new function so the script can be
ran manually which should make testing these scripts easier.
2013-07-16 21:13:09 -07:00
Trae Robrock
4b38eb848f Add unlink functionality 2013-07-16 20:50:36 -07:00
Trae Robrock
bfce04e63c Ignore vendor dir 2013-07-16 20:49:40 -07:00
John Bellone
92dc611bb1 Update homesick.rb to make https default for GitHub clones.
If we use HTTPS it is a lot easier for corporate worlds to manage proxies since its usually already done for us. Also HTTPS cloning is just as fast as the git protocol as of more recent versions.
2013-06-21 09:45:26 -03:00
8 changed files with 233 additions and 25 deletions

3
.gitignore vendored
View File

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

View File

@@ -1,3 +1,9 @@
# 0.9.4
* Use https protocol instead of git protocol
* Introduce new commands
* `homesick unlink`
* `homesick rc`
# 0.9.3 # 0.9.3
* Add recursive option to `homesick clone` * Add recursive option to `homesick clone`

View File

@@ -27,9 +27,10 @@ With the castle cloned, you can now link its contents into your home dir:
homesick symlink pickled-vim homesick symlink pickled-vim
If you use the shorthand syntax for GitHub repositories in your clone, please note you will instead need to run:
homesick symlink technicalpickles/pickled-vim You can remove symlinks anytime when you don't need them anymore
homesick unlink pickled-vim
If you're not sure what castles you have around, you can easily list them: If you're not sure what castles you have around, you can easily list them:

View File

@@ -22,7 +22,7 @@ Jeweler::Tasks.new do |gem|
gem.email = ["josh@technicalpickles.com", "info@muratayusuke.com"] gem.email = ["josh@technicalpickles.com", "info@muratayusuke.com"]
gem.homepage = "http://github.com/technicalpickles/homesick" gem.homepage = "http://github.com/technicalpickles/homesick"
gem.authors = ["Joshua Nichols", "Yusuke Murata"] gem.authors = ["Joshua Nichols", "Yusuke Murata"]
gem.version = "0.9.3" gem.version = "0.9.7"
gem.license = "MIT" gem.license = "MIT"
# Have dependencies? Add them to Gemfile # Have dependencies? Add them to Gemfile

View File

@@ -5,11 +5,11 @@
Gem::Specification.new do |s| Gem::Specification.new do |s|
s.name = "homesick" s.name = "homesick"
s.version = "0.9.3" s.version = "0.9.7"
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["Joshua Nichols", "Yusuke Murata"] s.authors = ["Joshua Nichols", "Yusuke Murata"]
s.date = "2013-07-06" s.date = "2013-11-02"
s.description = "\n A man's home (directory) is his castle, so don't leave home with out it.\n\n Homesick is sorta like rip, but for dotfiles. It uses git to clone a repository containing dotfiles, and saves them in ~/.homesick. It then allows you to symlink all the dotfiles into place with a single command. \n\n " s.description = "\n A man's home (directory) is his castle, so don't leave home with out it.\n\n Homesick is sorta like rip, but for dotfiles. It uses git to clone a repository containing dotfiles, and saves them in ~/.homesick. It then allows you to symlink all the dotfiles into place with a single command. \n\n "
s.email = ["josh@technicalpickles.com", "info@muratayusuke.com"] s.email = ["josh@technicalpickles.com", "info@muratayusuke.com"]
s.executables = ["homesick"] s.executables = ["homesick"]
@@ -39,11 +39,11 @@ Gem::Specification.new do |s|
s.homepage = "http://github.com/technicalpickles/homesick" s.homepage = "http://github.com/technicalpickles/homesick"
s.licenses = ["MIT"] s.licenses = ["MIT"]
s.require_paths = ["lib"] s.require_paths = ["lib"]
s.rubygems_version = "2.0.3" s.rubygems_version = "1.8.23"
s.summary = "A man's home is his castle. Never leave your dotfiles behind." s.summary = "A man's home is his castle. Never leave your dotfiles behind."
if s.respond_to? :specification_version then if s.respond_to? :specification_version then
s.specification_version = 4 s.specification_version = 3
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
s.add_runtime_dependency(%q<thor>, [">= 0.14.0"]) s.add_runtime_dependency(%q<thor>, [">= 0.14.0"])

View File

@@ -9,7 +9,7 @@ class Homesick < Thor
add_runtime_options! add_runtime_options!
GITHUB_NAME_REPO_PATTERN = /\A([A-Za-z_-]+\/[A-Za-z_-]+)\Z/ GITHUB_NAME_REPO_PATTERN = /\A([A-Za-z0-9_-]+\/[A-Za-z0-9_-]+)\Z/
SUBDIR_FILENAME = '.homesick_subdir' SUBDIR_FILENAME = '.homesick_subdir'
DEFAULT_CASTLE_NAME = 'dotfiles' DEFAULT_CASTLE_NAME = 'dotfiles'
@@ -33,8 +33,8 @@ class Homesick < Thor
ln_s uri, destination ln_s uri, destination
elsif uri =~ GITHUB_NAME_REPO_PATTERN elsif uri =~ GITHUB_NAME_REPO_PATTERN
destination = Pathname.new($1) destination = Pathname.new(uri).basename
git_clone "git://github.com/#{$1}.git", :destination => destination git_clone "https://github.com/#{$1}.git", :destination => destination
elsif uri =~ /%r([^%r]*?)(\.git)?\Z/ elsif uri =~ /%r([^%r]*?)(\.git)?\Z/
destination = Pathname.new($1) destination = Pathname.new($1)
git_clone uri git_clone uri
@@ -52,13 +52,21 @@ class Homesick < Thor
end end
end end
rc(destination)
end
end
desc 'rc CASTLE', 'Run the .homesickrc for the specified castle'
def rc(name = DEFAULT_CASTLE_NAME)
inside repos_dir do
destination = Pathname.new(name)
homesickrc = destination.join('.homesickrc').expand_path homesickrc = destination.join('.homesickrc').expand_path
if homesickrc.exist? if homesickrc.exist?
proceed = shell.yes?("#{uri} has a .homesickrc. Proceed with evaling it? (This could be destructive)") proceed = shell.yes?("#{name} has a .homesickrc. Proceed with evaling it? (This could be destructive)")
if proceed if proceed
shell.say_status 'eval', homesickrc shell.say_status 'eval', homesickrc
inside destination do inside destination do
eval homesickrc.read, binding, homesickrc.expand_path eval homesickrc.read, binding, homesickrc.expand_path.to_s
end end
else else
shell.say_status 'eval skip', "not evaling #{homesickrc}, #{destination} may need manual configuration", :blue shell.say_status 'eval skip', "not evaling #{homesickrc}, #{destination} may need manual configuration", :blue
@@ -90,7 +98,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 +355,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 +384,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

@@ -10,7 +10,7 @@ class Homesick
if ! destination.directory? if ! destination.directory?
say_status 'git clone', "#{repo} to #{destination.expand_path}", :green unless options[:quiet] say_status 'git clone', "#{repo} to #{destination.expand_path}", :green unless options[:quiet]
system "git clone -q --recursive #{repo} #{destination}" unless options[:pretend] system "git clone -q --config push.default=upstream --recursive #{repo} #{destination}" unless options[:pretend]
else else
say_status :exist, destination.expand_path, :blue unless options[:quiet] say_status :exist, destination.expand_path, :blue unless options[:quiet]
end end
@@ -68,7 +68,7 @@ class Homesick
def git_add(file, config = {}) def git_add(file, config = {})
say_status 'git add file', '', :green unless options[:quiet] say_status 'git add file', '', :green unless options[:quiet]
system "git add #{file}" unless options[:pretend] system "git add '#{file}'" unless options[:pretend]
end end
def git_status(config = {}) def git_status(config = {})
@@ -89,11 +89,22 @@ class Homesick
say_status :conflict, "#{destination} exists", :red unless options[:quiet] say_status :conflict, "#{destination} exists", :red unless options[:quiet]
if options[:force] || shell.file_collision(destination) { source } if options[:force] || shell.file_collision(destination) { source }
system "mv #{source} #{destination}" unless options[:pretend] system "mv '#{source}' '#{destination}'" unless options[:pretend]
end end
else else
# this needs some sort of message here. # this needs some sort of message here.
system "mv #{source} #{destination}" unless options[:pretend] system "mv '#{source}' '#{destination}'" unless options[:pretend]
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
end end
@@ -109,19 +120,19 @@ class Homesick
say_status :conflict, "#{destination} exists and points to #{destination.readlink}", :red unless options[:quiet] say_status :conflict, "#{destination} exists and points to #{destination.readlink}", :red unless options[:quiet]
if options[:force] || shell.file_collision(destination) { source } if options[:force] || shell.file_collision(destination) { source }
system "ln -nsf #{source} #{destination}" unless options[:pretend] system "ln -nsf '#{source}' '#{destination}'" unless options[:pretend]
end end
end end
elsif destination.exist? elsif destination.exist?
say_status :conflict, "#{destination} exists", :red unless options[:quiet] say_status :conflict, "#{destination} exists", :red unless options[:quiet]
if options[:force] || shell.file_collision(destination) { source } if options[:force] || shell.file_collision(destination) { source }
system "rm -rf #{destination}" unless options[:pretend] system "rm -rf '#{destination}'" unless options[:pretend]
system "ln -sf #{source} #{destination}" unless options[:pretend] system "ln -sf '#{source}' '#{destination}'" unless options[:pretend]
end end
else else
say_status :symlink, "#{source.expand_path} to #{destination.expand_path}", :green unless options[:quiet] say_status :symlink, "#{source.expand_path} to #{destination.expand_path}", :green unless options[:quiet]
system "ln -s #{source} #{destination}" unless options[:pretend] system "ln -s '#{source}' '#{destination}'" unless options[:pretend]
end end
end end
end end

View File

@@ -8,9 +8,25 @@ describe 'homesick' do
let(:homesick) { Homesick.new } let(:homesick) { Homesick.new }
before { homesick.stub!(:repos_dir).and_return(castles) } before { homesick.stub(:repos_dir).and_return(castles) }
describe 'clone' do describe 'clone' do
context 'has a .homesickrc' do
it 'should run the .homesickrc' do
somewhere = create_construct
local_repo = somewhere.directory('some_repo')
local_repo.file('.homesickrc') do |file|
file << "File.open(Dir.pwd + '/testing', 'w') { |f| f.print 'testing' }"
end
expect($stdout).to receive(:print)
expect($stdin).to receive(:gets).and_return('y')
homesick.clone local_repo
castles.join('some_repo').join('testing').should exist
end
end
context 'of a file' do context 'of a file' do
it 'should symlink existing directories' do it 'should symlink existing directories' do
somewhere = create_construct somewhere = create_construct
@@ -78,12 +94,50 @@ describe 'homesick' do
end end
it 'should clone a github repo' do it 'should clone a github repo' do
homesick.should_receive(:git_clone).with('git://github.com/wfarr/dotfiles.git', :destination => Pathname.new('wfarr/dotfiles')) homesick.should_receive(:git_clone).with('https://github.com/wfarr/dotfiles.git', :destination => Pathname.new('dotfiles'))
homesick.clone 'wfarr/dotfiles' homesick.clone 'wfarr/dotfiles'
end end
end end
describe 'rc' do
let(:castle) { given_castle('glencairn') }
context 'when told to do so' do
before do
expect($stdout).to receive(:print)
expect($stdin).to receive(:gets).and_return('y')
end
it 'executes the .homesickrc' do
castle.file('.homesickrc') do |file|
file << "File.open(Dir.pwd + '/testing', 'w') { |f| f.print 'testing' }"
end
homesick.rc castle
castle.join('testing').should exist
end
end
context 'when told not to do so' do
before do
expect($stdout).to receive(:print)
expect($stdin).to receive(:gets).and_return('n')
end
it 'does not execute the .homesickrc' do
castle.file('.homesickrc') do |file|
file << "File.open(Dir.pwd + '/testing', 'w') { |f| f.print 'testing' }"
end
homesick.rc castle
castle.join('testing').should_not exist
end
end
end
describe 'symlink' do describe 'symlink' do
let(:castle) { given_castle('glencairn') } let(:castle) { given_castle('glencairn') }
@@ -188,6 +242,91 @@ describe 'homesick' do
end end
end end
describe 'unlink' do
let(:castle) { given_castle('glencairn') }
it 'unlinks dotfiles in the home folder' do
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
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
castle.directory('.config').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
castle.directory('.config').directory('appA').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_dir.file('.some_dotfile')
config_dir.directory('someapp').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
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')
@@ -258,6 +397,19 @@ describe 'homesick' do
some_rc_file.readlink.should == tracked_file some_rc_file.readlink.should == tracked_file
end end
it 'should handle files with parens' do
castle = given_castle('castle_repo')
some_rc_file = home.file 'Default (Linux).sublime-keymap'
homesick.track(some_rc_file.to_s, 'castle_repo')
tracked_file = castle.join('Default (Linux).sublime-keymap')
tracked_file.should exist
some_rc_file.readlink.should == tracked_file
end
it 'should track a file in nested folder structure' do it 'should track a file in nested folder structure' do
castle = given_castle('castle_repo') castle = given_castle('castle_repo')