49 Commits

Author SHA1 Message Date
Jeremy Cook
7a2df591c0 Regenerate gemspec for version 1.1.5 2017-03-23 08:37:44 -04:00
Jeremy Cook
4923265dea Updated homesick version and changelog due to problem with version
number in release.
2017-03-23 08:34:47 -04:00
Jeremy Cook
79421580e9 Merge branch 'master' of github.com:technicalpickles/homesick 2017-03-22 17:24:28 -04:00
Jeremy Cook
cabde9e5f1 Updated change log for new version. 2017-03-22 17:23:49 -04:00
Jeremy Cook
0d60ae9d1a Regenerate gemspec for version 1.1.4 2017-03-22 17:14:09 -04:00
Jeremy Cook
d5317b8e17 Bumped version in preparation for release. 2017-03-22 17:10:23 -04:00
Jeremy Cook
3b8a5b4be4 Merge pull request #159 from mruwek/refactor-conflict-actions
Wrap symlink and regular conflicts into one case
2017-03-20 16:07:19 -04:00
Jacek Sowiński
6590a1eeff Wrap symlink and regular conflicts into one case
This way we're not duplicating collision-related code.
2017-03-20 20:26:14 +01:00
Jeremy Cook
693ae5f05e Merge pull request #157 from mruwek/verbose-symlink-conflicts
Don't overwrite silently on symlink conflicts
2017-03-19 22:02:41 -04:00
Jeremy Cook
da3002f199 Merge pull request #154 from singular0/symlink_realpath
Use real paths of symlinks when linking castle into home
2017-03-19 22:02:01 -04:00
Jeremy Cook
feaaab2fa4 Merge pull request #158 from JCook21/master
Minor updates
2017-03-19 22:00:34 -04:00
Jeremy Cook
59f75711a4 Changed strings to use symbols. 2017-03-19 15:57:44 -04:00
Jeremy Cook
f24030b51f Updates to Gemfile to clean it up. 2017-03-19 15:57:22 -04:00
Jeremy Cook
71bb120a12 Update to dependency. 2017-03-19 14:44:44 -04:00
Jacek Sowiński
85f46e01b1 Don't overwrite silently on symlink conflicts
Symlink conflicts are now handled in similar fashion as normal
file-conflicts.
2017-03-17 19:31:23 +01:00
Jeremy Cook
c5b24b9b38 Merge pull request #155 from danielbayerlein/ruby-2.4.0
Add support for Ruby 2.4.0
2016-12-26 07:08:38 -05:00
Daniel Bayerlein
68460af45e Add support for Ruby 2.4.0 2016-12-26 10:31:34 +01:00
Denis Yantarev
5614b6b8b3 Use real paths of symlinks when linking castle into home 2016-12-25 18:34:33 +03:00
Jeremy Cook
570b063632 Merge pull request #152 from singular0/master
Thanks for taking care of this.
2016-12-24 12:13:55 -05:00
Jeremy Cook
1d398587d0 Remove config for removed ruby versions.
Deleted config for unused ruby versions.
2016-12-24 12:11:01 -05:00
Jeremy Cook
085853faaa Merge branch 'master' into master 2016-12-24 12:05:54 -05:00
Jeremy Cook
21b4e344a9 Merge pull request #153 from danielbayerlein/ruby-version
Looks good to me, thanks!
2016-12-24 12:03:51 -05:00
Daniel Bayerlein
a6194dfe8b Update RSpec 2016-12-23 11:59:44 +01:00
Daniel Bayerlein
5692194fa2 Add support for Ruby 2.2.6 and 2.3.3 2016-12-23 11:37:47 +01:00
Daniel Bayerlein
11745098c2 Support Ruby 2.1.0, 2.2.0, 2.3.0 2016-12-23 11:23:11 +01:00
Denis Yantarev
b1bb0c996c Add Ruby 2.2 & 2.3 to Travis config and fix GEM dependencies 2016-12-05 03:34:57 +03:00
Denis Yantarev
a62039da50 Ignore rbenv configuration files 2016-12-05 03:34:14 +03:00
Denis Yantarev
4bfd1c60c2 Fix default option value type warning 2016-12-03 15:56:22 +03:00
Jeremy Cook
f0e11abb5b Merge pull request #149 from mail6543210/master
Use source content instead of source path (fixes: #148). Thanks for fixing this!
2016-01-21 20:05:33 -05:00
mail6543210
ed397bdaf8 Use source content instead of source path (fixes: #148) 2016-01-21 18:36:52 +08:00
Jeremy Cook
2f5e20d963 Fixed formatting in Changelog file. 2015-10-31 09:54:41 -04:00
Jeremy Cook
cc83a4e1fa Preparing for 1.1.3 release. 2015-10-31 09:48:10 -04:00
Jeremy Cook
dcc5cb0bc1 Merge pull request #146 from JCook21/issue134
Fix for issue134
2015-10-25 15:21:26 -04:00
Jeremy Cook
978416d1e4 Fixing diff problems by providing source block and checking for
directories in diff
2015-10-20 21:47:43 -04:00
Jeremy Cook
1c12c73e4b Merge branch 'rweng-named_castles' 2015-10-14 22:31:20 -04:00
Jeremy Cook
1016002638 Merge branch 'named_castles' of https://github.com/rweng/homesick into rweng-named_castles 2015-10-14 22:30:46 -04:00
Jeremy Cook
6431a864ad Merge pull request #145 from JCook21/master
Maintenance fixes
2015-10-13 22:43:07 -04:00
Jeremy Cook
42f661cfbf Update to use new travis container infrastructure (see
http://docs.travis-ci.com/user/migrating-from-legacy/?utm_source=legacy-notice&utm_medium=banner&utm_campaign=legacy-upgrade)
2015-10-12 19:30:29 -04:00
Jeremy Cook
7632591681 Coding standards fixes based off of Rubocop and minor edits to make
logic flow easier to understand.
2015-10-12 19:30:29 -04:00
Jeremy Cook
a9a5b81dc5 Adding system notifications to development gems. 2015-10-12 19:30:29 -04:00
Jeremy Cook
721c10cffd Merge pull request #143 from rweng/fix-open
Fix homesick open
2015-10-12 11:06:10 -04:00
Robin Wenglewski
332aad8ad0 change 'homesick open' to run '$EDITOR .' instead of '$EDITOR' in castle_dir #142 2015-10-12 16:39:52 +02:00
Robin Wenglewski
171b4c1fb8 add option to pass in destination to homesick clone 2015-10-11 18:21:22 +02:00
Jeremy Cook
60d4458bbc Merge pull request #124 from shioyama/clone_destination
Pass destination when cloning url.
2015-03-22 14:12:41 -04:00
Chris Salzberg
9ad171ab78 Pass destination when cloning url. 2015-03-05 22:26:41 +09:00
Jeremy Cook
5918746059 Merge pull request #137 from gerasiov/master
Thanks!
2015-02-23 23:00:22 -05:00
Alexander GQ Gerasiov
4641843ffd Add "requite 'pathname'" to lib/homesick/utils.rb
Since Pathname is used in lib/homesick/utils.rb, it should require this module
itself.

Signed-off-by: Alexander GQ Gerasiov <gq@cs.msu.su>
2015-02-22 23:09:18 +03:00
Jeremy Cook
1a181b907c Merge pull request #136 from williamboman/patch-1
Thanks for fixing this!
2015-02-20 09:19:15 -05:00
William Boman
fb7595d254 Escape message correctly on git_commit_all. 2015-02-19 16:51:53 +01:00
13 changed files with 233 additions and 225 deletions

5
.gitignore vendored
View File

@@ -46,3 +46,8 @@ pkg
Gemfile.lock Gemfile.lock
vendor/ vendor/
homesick*.gem
# rbenv configuration
.ruby-version

View File

@@ -1,5 +1,6 @@
language: ruby language: ruby
rvm: rvm:
- 2.1.0 - 2.4.0
- 2.0.0 - 2.3.3
- 1.9.3 - 2.2.6
sudo: false

View File

@@ -1,3 +1,19 @@
#1.1.5
* Fixed problem with version number being incorrect.
#1.1.4
* Make sure symlink conflicts are explicitly communicated to a user and symlinks are not silently overwritten
* Use real paths of symlinks when linking a castle into home
* Fix a problem when in a diff when asking a user to resolve a conflict
* Some code refactoring and fixes
#1.1.3
* Allow a destination to be passed when cloning a castle
* Make sure `homesick edit` opens default editor in the root of the given castle
* Fixed bug when diffing edited files
* Fixed crashing bug when attempting to diff directories
* Ensure that messages are escaped correctly on `git commit all`
#1.1.2 #1.1.2
* Added '--force' option to the rc command to bypass confirmation checks when running a .homesickrc file * Added '--force' option to the rc command to bypass confirmation checks when running a .homesickrc file
* Added a check to make sure that a minimum of Git 1.8.0 is installed. This stops Homesick failing silently if Git is not installed. * Added a check to make sure that a minimum of Git 1.8.0 is installed. This stops Homesick failing silently if Git is not installed.
@@ -39,11 +55,11 @@
* Introduce .homesick_subdir #39 * Introduce .homesick_subdir #39
# 0.8.1 # 0.8.1
*Fixed `homesick list` bug on ruby 2.0 #37 * Fixed `homesick list` bug on ruby 2.0 #37
# 0.8.0 # 0.8.0
* Introduce commit & push command * Introduce commit & push command
* commit changes in castle and push to remote * commit changes in castle and push to remote
* Enable recursive submodule update * Enable recursive submodule update
* Git add when track * Git add when track

37
Gemfile
View File

@@ -1,25 +1,36 @@
require 'rbconfig'
source 'https://rubygems.org' source 'https://rubygems.org'
this_ruby = Gem::Version.new(RUBY_VERSION)
ruby_230 = Gem::Version.new('2.3.0')
# Add dependencies required to use your gem here. # Add dependencies required to use your gem here.
gem "thor", ">= 0.14.0" gem 'thor', '>= 0.14.0'
# Add dependencies to develop your gem here. # Add dependencies to develop your gem here.
# Include everything needed to run rake, tests, features, etc. # Include everything needed to run rake, tests, features, etc.
group :development do group :development do
gem "rake", ">= 0.8.7" gem 'capture-output', '~> 1.0.0'
gem "rspec", "~> 3.1.0"
gem "guard"
gem "guard-rspec"
gem "rb-readline", "~> 0.5.0"
gem "jeweler", ">= 1.6.2"
gem 'coveralls', require: false gem 'coveralls', require: false
gem "test_construct" gem 'guard'
gem "capture-output", "~> 1.0.0" gem 'guard-rspec'
if RbConfig::CONFIG['host_os'] =~ /linux|freebsd|openbsd|sunos|solaris/ gem 'jeweler', '>= 1.6.2', '< 2.2' if this_ruby < ruby_230
gem 'jeweler', '>= 1.6.2' if this_ruby >= ruby_230
gem 'rake', '>= 0.8.7'
gem 'rb-readline', '~> 0.5.0'
gem 'rspec', '~> 3.5.0'
gem 'rubocop'
gem 'test_construct'
install_if -> { RUBY_PLATFORM =~ /linux|freebsd|openbsd|sunos|solaris/ } do
gem 'libnotify' gem 'libnotify'
end end
if RUBY_VERSION >= '1.9.2'
gem "rubocop" install_if -> { RUBY_PLATFORM =~ /darwin/ } do
gem 'terminal-notifier-guard', '~> 1.7.0'
end
install_if -> { this_ruby < ruby_230 } do
gem 'listen', '< 3'
gem 'rack', '< 2'
end end
end end

View File

@@ -164,9 +164,9 @@ and castle
Homesick is tested on the following Ruby versions: Homesick is tested on the following Ruby versions:
* 1.9.3 * 2.2.6
* 2.0.0 * 2.3.3
* 2.1.0 * 2.4.0
## Note on Patches/Pull Requests ## Note on Patches/Pull Requests

View File

@@ -2,19 +2,19 @@
# DO NOT EDIT THIS FILE DIRECTLY # DO NOT EDIT THIS FILE DIRECTLY
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec' # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
# -*- encoding: utf-8 -*- # -*- encoding: utf-8 -*-
# stub: homesick 1.1.2 ruby lib # stub: homesick 1.1.5 ruby lib
Gem::Specification.new do |s| Gem::Specification.new do |s|
s.name = "homesick" s.name = "homesick".freeze
s.version = "1.1.2" s.version = "1.1.5"
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
s.require_paths = ["lib"] s.require_paths = ["lib".freeze]
s.authors = ["Joshua Nichols", "Yusuke Murata"] s.authors = ["Joshua Nichols".freeze, "Yusuke Murata".freeze]
s.date = "2015-01-02" s.date = "2017-03-23"
s.description = "\n Your home directory is your castle. Don't leave your dotfiles behind.\n \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 Your home directory is your castle. Don't leave your dotfiles behind.\n \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 ".freeze
s.email = ["josh@technicalpickles.com", "info@muratayusuke.com"] s.email = ["josh@technicalpickles.com".freeze, "info@muratayusuke.com".freeze]
s.executables = ["homesick"] s.executables = ["homesick".freeze]
s.extra_rdoc_files = [ s.extra_rdoc_files = [
"ChangeLog.markdown", "ChangeLog.markdown",
"LICENSE", "LICENSE",
@@ -43,51 +43,63 @@ Gem::Specification.new do |s|
"spec/spec.opts", "spec/spec.opts",
"spec/spec_helper.rb" "spec/spec_helper.rb"
] ]
s.homepage = "http://github.com/technicalpickles/homesick" s.homepage = "http://github.com/technicalpickles/homesick".freeze
s.licenses = ["MIT"] s.licenses = ["MIT".freeze]
s.rubygems_version = "2.2.2" s.rubygems_version = "2.6.11".freeze
s.summary = "Your home directory is your castle. Don't leave your dotfiles behind." s.summary = "Your home directory is your castle. Don't leave your dotfiles behind.".freeze
if s.respond_to? :specification_version then if s.respond_to? :specification_version then
s.specification_version = 4 s.specification_version = 4
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>.freeze, [">= 0.14.0"])
s.add_development_dependency(%q<rake>, [">= 0.8.7"]) s.add_development_dependency(%q<capture-output>.freeze, ["~> 1.0.0"])
s.add_development_dependency(%q<rspec>, ["~> 3.1.0"]) s.add_development_dependency(%q<coveralls>.freeze, [">= 0"])
s.add_development_dependency(%q<guard>, [">= 0"]) s.add_development_dependency(%q<guard>.freeze, [">= 0"])
s.add_development_dependency(%q<guard-rspec>, [">= 0"]) s.add_development_dependency(%q<guard-rspec>.freeze, [">= 0"])
s.add_development_dependency(%q<rb-readline>, ["~> 0.5.0"]) s.add_development_dependency(%q<jeweler>.freeze, [">= 1.6.2"])
s.add_development_dependency(%q<jeweler>, [">= 1.6.2"]) s.add_development_dependency(%q<rake>.freeze, [">= 0.8.7"])
s.add_development_dependency(%q<coveralls>, [">= 0"]) s.add_development_dependency(%q<rb-readline>.freeze, ["~> 0.5.0"])
s.add_development_dependency(%q<test_construct>, [">= 0"]) s.add_development_dependency(%q<rspec>.freeze, ["~> 3.5.0"])
s.add_development_dependency(%q<capture-output>, ["~> 1.0.0"]) s.add_development_dependency(%q<rubocop>.freeze, [">= 0"])
s.add_development_dependency(%q<rubocop>, [">= 0"]) s.add_development_dependency(%q<test_construct>.freeze, [">= 0"])
s.add_development_dependency(%q<libnotify>.freeze, [">= 0"])
s.add_development_dependency(%q<terminal-notifier-guard>.freeze, ["~> 1.7.0"])
s.add_development_dependency(%q<listen>.freeze, ["< 3"])
s.add_development_dependency(%q<rack>.freeze, ["< 2"])
else else
s.add_dependency(%q<thor>, [">= 0.14.0"]) s.add_dependency(%q<thor>.freeze, [">= 0.14.0"])
s.add_dependency(%q<rake>, [">= 0.8.7"]) s.add_dependency(%q<capture-output>.freeze, ["~> 1.0.0"])
s.add_dependency(%q<rspec>, ["~> 3.1.0"]) s.add_dependency(%q<coveralls>.freeze, [">= 0"])
s.add_dependency(%q<guard>, [">= 0"]) s.add_dependency(%q<guard>.freeze, [">= 0"])
s.add_dependency(%q<guard-rspec>, [">= 0"]) s.add_dependency(%q<guard-rspec>.freeze, [">= 0"])
s.add_dependency(%q<rb-readline>, ["~> 0.5.0"]) s.add_dependency(%q<jeweler>.freeze, [">= 1.6.2"])
s.add_dependency(%q<jeweler>, [">= 1.6.2"]) s.add_dependency(%q<rake>.freeze, [">= 0.8.7"])
s.add_dependency(%q<coveralls>, [">= 0"]) s.add_dependency(%q<rb-readline>.freeze, ["~> 0.5.0"])
s.add_dependency(%q<test_construct>, [">= 0"]) s.add_dependency(%q<rspec>.freeze, ["~> 3.5.0"])
s.add_dependency(%q<capture-output>, ["~> 1.0.0"]) s.add_dependency(%q<rubocop>.freeze, [">= 0"])
s.add_dependency(%q<rubocop>, [">= 0"]) s.add_dependency(%q<test_construct>.freeze, [">= 0"])
s.add_dependency(%q<libnotify>.freeze, [">= 0"])
s.add_dependency(%q<terminal-notifier-guard>.freeze, ["~> 1.7.0"])
s.add_dependency(%q<listen>.freeze, ["< 3"])
s.add_dependency(%q<rack>.freeze, ["< 2"])
end end
else else
s.add_dependency(%q<thor>, [">= 0.14.0"]) s.add_dependency(%q<thor>.freeze, [">= 0.14.0"])
s.add_dependency(%q<rake>, [">= 0.8.7"]) s.add_dependency(%q<capture-output>.freeze, ["~> 1.0.0"])
s.add_dependency(%q<rspec>, ["~> 3.1.0"]) s.add_dependency(%q<coveralls>.freeze, [">= 0"])
s.add_dependency(%q<guard>, [">= 0"]) s.add_dependency(%q<guard>.freeze, [">= 0"])
s.add_dependency(%q<guard-rspec>, [">= 0"]) s.add_dependency(%q<guard-rspec>.freeze, [">= 0"])
s.add_dependency(%q<rb-readline>, ["~> 0.5.0"]) s.add_dependency(%q<jeweler>.freeze, [">= 1.6.2"])
s.add_dependency(%q<jeweler>, [">= 1.6.2"]) s.add_dependency(%q<rake>.freeze, [">= 0.8.7"])
s.add_dependency(%q<coveralls>, [">= 0"]) s.add_dependency(%q<rb-readline>.freeze, ["~> 0.5.0"])
s.add_dependency(%q<test_construct>, [">= 0"]) s.add_dependency(%q<rspec>.freeze, ["~> 3.5.0"])
s.add_dependency(%q<capture-output>, ["~> 1.0.0"]) s.add_dependency(%q<rubocop>.freeze, [">= 0"])
s.add_dependency(%q<rubocop>, [">= 0"]) s.add_dependency(%q<test_construct>.freeze, [">= 0"])
s.add_dependency(%q<libnotify>.freeze, [">= 0"])
s.add_dependency(%q<terminal-notifier-guard>.freeze, ["~> 1.7.0"])
s.add_dependency(%q<listen>.freeze, ["< 3"])
s.add_dependency(%q<rack>.freeze, ["< 2"])
end end
end end

View File

@@ -7,7 +7,7 @@ require 'homesick/cli'
# Homesick's top-level module # Homesick's top-level module
module Homesick module Homesick
GITHUB_NAME_REPO_PATTERN = /\A([A-Za-z0-9_-]+\/[A-Za-z0-9_-]+)\Z/ GITHUB_NAME_REPO_PATTERN = %r{\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'

View File

@@ -3,16 +3,14 @@ module Homesick
module Actions module Actions
# File-related helper methods for Homesick # File-related helper methods for Homesick
module FileActions module FileActions
def mv(source, destination, config = {}) def mv(source, destination)
source = Pathname.new(source) source = Pathname.new(source)
destination = Pathname.new(destination + source.basename) destination = Pathname.new(destination + source.basename)
case
if destination.exist? when destination.exist? && (options[:force] || shell.file_collision(destination) { source })
say_status :conflict, "#{destination} exists", :red say_status :conflict, "#{destination} exists", :red
FileUtils.mv source, destination unless options[:pretend]
FileUtils.mv source, destination if (options[:force] || shell.file_collision(destination) { source }) && !options[:pretend]
else else
# this needs some sort of message here.
FileUtils.mv source, destination unless options[:pretend] FileUtils.mv source, destination unless options[:pretend]
end end
end end
@@ -43,8 +41,8 @@ module Homesick
FileUtils.rm_r dir FileUtils.rm_r dir
end end
def ln_s(source, destination, config = {}) def ln_s(source, destination)
source = Pathname.new(source) source = Pathname.new(source).realpath
destination = Pathname.new(destination) destination = Pathname.new(destination)
FileUtils.mkdir_p destination.dirname FileUtils.mkdir_p destination.dirname
@@ -65,17 +63,15 @@ module Homesick
case action case action
when :identical when :identical
say_status :identical, destination.expand_path, :blue say_status :identical, destination.expand_path, :blue
when :symlink_conflict when :symlink_conflict, :conflict
say_status :conflict, if action == :conflict
"#{destination} exists and points to #{destination.readlink}", say_status :conflict, "#{destination} exists", :red
:red else
say_status :conflict,
FileUtils.rm destination "#{destination} exists and points to #{destination.readlink}",
FileUtils.ln_s source, destination, force: true unless options[:pretend] :red
when :conflict end
say_status :conflict, "#{destination} exists", :red if collision_accepted?(destination, source)
if collision_accepted?(destination)
FileUtils.rm_r destination, force: true unless options[:pretend] FileUtils.rm_r destination, force: true unless options[:pretend]
FileUtils.ln_s source, destination, force: true unless options[:pretend] FileUtils.ln_s source, destination, force: true unless options[:pretend]
end end

View File

@@ -14,7 +14,7 @@ module Homesick
def git_version_correct? def git_version_correct?
info = `git --version`.scan(/(\d+)\.(\d+)\.(\d+)/).flatten.map(&:to_i) info = `git --version`.scan(/(\d+)\.(\d+)\.(\d+)/).flatten.map(&:to_i)
return false unless info.count == 3 return false unless info.count == 3
current_version = Hash[ [:major, :minor, :patch].zip(info) ] current_version = Hash[[:major, :minor, :patch].zip(info)]
return true if current_version.eql?(MIN_VERSION) return true if current_version.eql?(MIN_VERSION)
return true if current_version[:major] > MIN_VERSION[:major] return true if current_version[:major] > MIN_VERSION[:major]
return true if current_version[:major] == MIN_VERSION[:major] && current_version[:minor] > MIN_VERSION[:minor] return true if current_version[:major] == MIN_VERSION[:major] && current_version[:minor] > MIN_VERSION[:minor]
@@ -27,7 +27,7 @@ module Homesick
config ||= {} config ||= {}
destination = config[:destination] || File.basename(repo, '.git') destination = config[:destination] || File.basename(repo, '.git')
destination = Pathname.new(destination) unless destination.kind_of?(Pathname) destination = Pathname.new(destination) unless destination.is_a?(Pathname)
FileUtils.mkdir_p destination.dirname FileUtils.mkdir_p destination.dirname
if destination.directory? if destination.directory?
@@ -65,22 +65,22 @@ module Homesick
end end
end end
def git_submodule_init(config = {}) def git_submodule_init
say_status 'git submodule', 'init', :green say_status 'git submodule', 'init', :green
system 'git submodule --quiet init' system 'git submodule --quiet init'
end end
def git_submodule_update(config = {}) def git_submodule_update
say_status 'git submodule', 'update', :green say_status 'git submodule', 'update', :green
system 'git submodule --quiet update --init --recursive >/dev/null 2>&1' system 'git submodule --quiet update --init --recursive >/dev/null 2>&1'
end end
def git_pull(config = {}) def git_pull
say_status 'git pull', '', :green say_status 'git pull', '', :green
system 'git pull --quiet' system 'git pull --quiet'
end end
def git_push(config = {}) def git_push
say_status 'git push', '', :green say_status 'git push', '', :green
system 'git push' system 'git push'
end end
@@ -88,23 +88,23 @@ module Homesick
def git_commit_all(config = {}) def git_commit_all(config = {})
say_status 'git commit all', '', :green say_status 'git commit all', '', :green
if config[:message] if config[:message]
system "git commit -a -m '#{config[:message]}'" system %(git commit -a -m "#{config[:message]}")
else else
system 'git commit -v -a' system 'git commit -v -a'
end end
end end
def git_add(file, config = {}) def git_add(file)
say_status 'git add file', '', :green say_status 'git add file', '', :green
system "git add '#{file}'" system "git add '#{file}'"
end end
def git_status(config = {}) def git_status
say_status 'git status', '', :green say_status 'git status', '', :green
system 'git status' system 'git status'
end end
def git_diff(config = {}) def git_diff
say_status 'git diff', '', :green say_status 'git diff', '', :green
system 'git diff' system 'git diff'
end end

View File

@@ -25,38 +25,37 @@ module Homesick
exit(1) exit(1)
end end
# Hack in support for diffing symlinks # Hack in support for diffing symlinks
self.shell = Thor::Shell::Color.new # Also adds support for checking if destination or content is a directory
class << shell shell_metaclass = class << shell; self; end
def show_diff(destination, content) shell_metaclass.send(:define_method, :show_diff) do |destination, content|
destination = Pathname.new(destination) destination = Pathname.new(destination)
if destination.symlink? content = Pathname.new(content)
say "- #{destination.readlink}", :red, true return 'Unable to create diff: destination or content is a directory' if destination.directory? || content.directory?
say "+ #{content.expand_path}", :green, true return super(destination, content) unless destination.symlink?
else say "- #{destination.readlink}", :red, true
super say "+ #{content.expand_path}", :green, true
end
end
end end
end end
desc 'clone URI', 'Clone +uri+ as a castle for homesick' desc 'clone URI CASTLE_NAME', 'Clone +uri+ as a castle with name CASTLE_NAME for homesick'
def clone(uri) def clone(uri, destination=nil)
destination = Pathname.new(destination) unless destination.nil?
inside repos_dir do inside repos_dir do
destination = nil
if File.exist?(uri) if File.exist?(uri)
uri = Pathname.new(uri).expand_path uri = Pathname.new(uri).expand_path
fail "Castle already cloned to #{uri}" if uri.to_s.start_with?(repos_dir.to_s) fail "Castle already cloned to #{uri}" if uri.to_s.start_with?(repos_dir.to_s)
destination = uri.basename destination = uri.basename if destination.nil?
ln_s uri, destination ln_s uri, destination
elsif uri =~ GITHUB_NAME_REPO_PATTERN elsif uri =~ GITHUB_NAME_REPO_PATTERN
destination = Pathname.new(uri).basename destination = Pathname.new(uri).basename if destination.nil?
git_clone "https://github.com/#{Regexp.last_match[1]}.git", git_clone "https://github.com/#{Regexp.last_match[1]}.git",
destination: destination destination: destination
elsif uri =~ /%r([^%r]*?)(\.git)?\Z/ || uri =~ /[^:]+:([^:]+)(\.git)?\Z/ elsif uri =~ /%r([^%r]*?)(\.git)?\Z/ || uri =~ /[^:]+:([^:]+)(\.git)?\Z/
destination = Pathname.new(Regexp.last_match[1]) destination = Pathname.new(Regexp.last_match[1].gsub(/\.git$/, '')).basename if destination.nil?
git_clone uri git_clone uri, destination: destination
else else
fail "Unknown URI format: #{uri}" fail "Unknown URI format: #{uri}"
end end
@@ -67,24 +66,19 @@ module Homesick
desc 'rc CASTLE', 'Run the .homesickrc for the specified castle' desc 'rc CASTLE', 'Run the .homesickrc for the specified castle'
method_option :force, method_option :force,
type: :boolean,
default: false, default: false,
desc: 'Evaluate .homesickrc without prompting.' desc: 'Evaluate .homesickrc without prompting.'
def rc(name = DEFAULT_CASTLE_NAME) def rc(name = DEFAULT_CASTLE_NAME)
inside repos_dir do inside repos_dir do
destination = Pathname.new(name) destination = Pathname.new(name)
homesickrc = destination.join('.homesickrc').expand_path homesickrc = destination.join('.homesickrc').expand_path
if homesickrc.exist? return unless homesickrc.exist?
proceed = options[:force] || shell.yes?("#{name} has a .homesickrc. Proceed with evaling it? (This could be destructive)") proceed = options[:force] || shell.yes?("#{name} has a .homesickrc. Proceed with evaling it? (This could be destructive)")
if proceed return say_status 'eval skip', "not evaling #{homesickrc}, #{destination} may need manual configuration", :blue unless proceed
say_status 'eval', homesickrc say_status 'eval', homesickrc
inside destination do inside destination do
eval homesickrc.read, binding, homesickrc.expand_path.to_s eval homesickrc.read, binding, homesickrc.expand_path.to_s
end
else
say_status 'eval skip',
"not evaling #{homesickrc}, #{destination} may need manual configuration",
:blue
end
end end
end end
end end
@@ -135,6 +129,7 @@ module Homesick
desc 'link CASTLE', 'Symlinks all dotfiles from the specified castle' desc 'link CASTLE', 'Symlinks all dotfiles from the specified castle'
method_option :force, method_option :force,
type: :boolean,
default: false, default: false,
desc: 'Overwrite existing conflicting symlinks without prompting.' desc: 'Overwrite existing conflicting symlinks without prompting.'
def link(name = DEFAULT_CASTLE_NAME) def link(name = DEFAULT_CASTLE_NAME)
@@ -252,11 +247,10 @@ module Homesick
desc 'destroy CASTLE', 'Delete all symlinks and remove the cloned repository' desc 'destroy CASTLE', 'Delete all symlinks and remove the cloned repository'
def destroy(name) def destroy(name)
check_castle_existance name, 'destroy' check_castle_existance name, 'destroy'
return unless shell.yes?('This will destroy your castle irreversible! Are you sure?')
if shell.yes?('This will destroy your castle irreversible! Are you sure?') unlink(name)
unlink(name) rm_rf repos_dir.join(name)
rm_rf repos_dir.join(name)
end
end end
desc 'cd CASTLE', 'Open a new shell in the root of the given castle' desc 'cd CASTLE', 'Open a new shell in the root of the given castle'
@@ -283,11 +277,11 @@ module Homesick
end end
check_castle_existance castle, 'open' check_castle_existance castle, 'open'
castle_dir = repos_dir.join(castle) castle_dir = repos_dir.join(castle)
say_status "#{ENV['EDITOR']} #{castle_dir.realpath}", say_status "#{castle_dir.realpath}: #{ENV['EDITOR']} .",
"Opening the root directory of castle '#{castle}' in editor '#{ENV['EDITOR']}'.", "Opening the root directory of castle '#{castle}' in editor '#{ENV['EDITOR']}'.",
:green :green
inside castle_dir do inside castle_dir do
system(ENV['EDITOR']) system("#{ENV['EDITOR']} .")
end end
end end

View File

@@ -1,10 +1,12 @@
# -*- encoding : utf-8 -*- # -*- encoding : utf-8 -*-
require 'pathname'
module Homesick module Homesick
# Various utility methods that are used by Homesick # Various utility methods that are used by Homesick
module Utils module Utils
QUIETABLE = ['say_status'] QUIETABLE = [:say_status]
PRETENDABLE = ['system'] PRETENDABLE = [:system]
QUIETABLE.each do |method_name| QUIETABLE.each do |method_name|
define_method(method_name) do |*args| define_method(method_name) do |*args|
@@ -33,12 +35,11 @@ module Homesick
end end
def check_castle_existance(name, action) def check_castle_existance(name, action)
unless castle_dir(name).exist? return if castle_dir(name).exist?
say_status :error, say_status :error,
"Could not #{action} #{name}, expected #{castle_dir(name)} exist and contain dotfiles", "Could not #{action} #{name}, expected #{castle_dir(name)} exist and contain dotfiles",
:red :red
exit(1) exit(1)
end
end end
def all_castles def all_castles
@@ -51,7 +52,7 @@ module Homesick
end end
end end
def inside_each_castle(&block) def inside_each_castle
all_castles.each do |git_dir| all_castles.each do |git_dir|
castle = git_dir.dirname castle = git_dir.dirname
Dir.chdir castle do # so we can call git config from the right contxt Dir.chdir castle do # so we can call git config from the right contxt
@@ -128,7 +129,6 @@ module Homesick
def move_dir_contents(target, dir_path) def move_dir_contents(target, dir_path)
child_files = dir_path.children child_files = dir_path.children
child_files.each do |child| child_files.each do |child|
target_path = target.join(child.basename) target_path = target.join(child.basename)
if target_path.exist? if target_path.exist?
if more_recent?(child, target_path) && target.file? if more_recent?(child, target_path) && target.file?
@@ -148,9 +148,9 @@ module Homesick
first_p.mtime > second_p.mtime && !first_p.symlink? first_p.mtime > second_p.mtime && !first_p.symlink?
end end
def collision_accepted?(destination) def collision_accepted?(destination, source)
fail "Argument must be an instance of Pathname, #{destination.class.name} given" unless destination.instance_of?(Pathname) fail "Arguments must be instances of Pathname, #{destination.class.name} and #{source.class.name} given" unless destination.instance_of?(Pathname) && source.instance_of?(Pathname)
options[:force] || shell.file_collision(destination) { source } options[:force] || shell.file_collision(destination) { File.binread(source) }
end end
def each_file(castle, basedir, subdirs) def each_file(castle, basedir, subdirs)
@@ -191,7 +191,7 @@ module Homesick
end end
def unsymlink_each(castle, basedir, subdirs) def unsymlink_each(castle, basedir, subdirs)
each_file(castle, basedir, subdirs) do |absolute_path, home_path| each_file(castle, basedir, subdirs) do |_absolute_path, home_path|
rm_link home_path rm_link home_path
end end
end end

View File

@@ -5,7 +5,7 @@ module Homesick
module Version module Version
MAJOR = 1 MAJOR = 1
MINOR = 1 MINOR = 1
PATCH = 2 PATCH = 5
STRING = [MAJOR, MINOR, PATCH].compact.join('.') STRING = [MAJOR, MINOR, PATCH].compact.join('.')
end end

View File

@@ -26,10 +26,10 @@ describe Homesick::CLI do
context 'when a git version that doesn\'t meet the minimum required is installed' do context 'when a git version that doesn\'t meet the minimum required is installed' do
before do before do
expect_any_instance_of(Homesick::Actions::GitActions).to receive(:`).and_return("git version 1.7.6") expect_any_instance_of(Homesick::Actions::GitActions).to receive(:`).and_return('git version 1.7.6')
end end
it 'should raise an exception' do it 'should raise an exception' do
output = Capture.stdout{ expect{Homesick::CLI.new}.to raise_error SystemExit } output = Capture.stdout { expect { Homesick::CLI.new }.to raise_error SystemExit }
expect(output.chomp).to include(Homesick::Actions::GitActions::STRING) expect(output.chomp).to include(Homesick::Actions::GitActions::STRING)
end end
end end
@@ -39,20 +39,19 @@ describe Homesick::CLI do
expect_any_instance_of(Homesick::Actions::GitActions).to receive(:`).at_least(:once).and_return("git version #{Homesick::Actions::GitActions::STRING}") expect_any_instance_of(Homesick::Actions::GitActions).to receive(:`).at_least(:once).and_return("git version #{Homesick::Actions::GitActions::STRING}")
end end
it 'should not raise an exception' do it 'should not raise an exception' do
output = Capture.stdout{ expect{Homesick::CLI.new}.not_to raise_error } output = Capture.stdout { expect { Homesick::CLI.new }.not_to raise_error }
expect(output.chomp).not_to include(Homesick::Actions::GitActions::STRING) expect(output.chomp).not_to include(Homesick::Actions::GitActions::STRING)
end end
end end
context 'when a git version that is greater than the minimum required is installed' do context 'when a git version that is greater than the minimum required is installed' do
before do before do
expect_any_instance_of(Homesick::Actions::GitActions).to receive(:`).at_least(:once).and_return("git version 3.9.8") expect_any_instance_of(Homesick::Actions::GitActions).to receive(:`).at_least(:once).and_return('git version 3.9.8')
end end
it 'should not raise an exception' do it 'should not raise an exception' do
output = Capture.stdout{ expect{Homesick::CLI.new}.not_to raise_error } output = Capture.stdout { expect { Homesick::CLI.new }.not_to raise_error }
expect(output.chomp).not_to include(Homesick::Actions::GitActions::STRING) expect(output.chomp).not_to include(Homesick::Actions::GitActions::STRING)
end end
end end
end end
@@ -112,50 +111,58 @@ describe Homesick::CLI do
it 'clones git repo like git://host/path/to.git' do it 'clones git repo like git://host/path/to.git' do
expect(homesick).to receive(:git_clone) expect(homesick).to receive(:git_clone)
.with('git://github.com/technicalpickles/pickled-vim.git') .with('git://github.com/technicalpickles/pickled-vim.git', destination: Pathname.new('pickled-vim'))
homesick.clone 'git://github.com/technicalpickles/pickled-vim.git' homesick.clone 'git://github.com/technicalpickles/pickled-vim.git'
end end
it 'clones git repo like git@host:path/to.git' do it 'clones git repo like git@host:path/to.git' do
expect(homesick).to receive(:git_clone) expect(homesick).to receive(:git_clone)
.with('git@github.com:technicalpickles/pickled-vim.git') .with('git@github.com:technicalpickles/pickled-vim.git', destination: Pathname.new('pickled-vim'))
homesick.clone 'git@github.com:technicalpickles/pickled-vim.git' homesick.clone 'git@github.com:technicalpickles/pickled-vim.git'
end end
it 'clones git repo like http://host/path/to.git' do it 'clones git repo like http://host/path/to.git' do
expect(homesick).to receive(:git_clone) expect(homesick).to receive(:git_clone)
.with('http://github.com/technicalpickles/pickled-vim.git') .with('http://github.com/technicalpickles/pickled-vim.git', destination: Pathname.new('pickled-vim'))
homesick.clone 'http://github.com/technicalpickles/pickled-vim.git' homesick.clone 'http://github.com/technicalpickles/pickled-vim.git'
end end
it 'clones git repo like http://host/path/to' do it 'clones git repo like http://host/path/to' do
expect(homesick).to receive(:git_clone) expect(homesick).to receive(:git_clone)
.with('http://github.com/technicalpickles/pickled-vim') .with('http://github.com/technicalpickles/pickled-vim', destination: Pathname.new('pickled-vim'))
homesick.clone 'http://github.com/technicalpickles/pickled-vim' homesick.clone 'http://github.com/technicalpickles/pickled-vim'
end end
it 'clones git repo like host-alias:repos.git' do it 'clones git repo like host-alias:repos.git' do
expect(homesick).to receive(:git_clone).with('gitolite:pickled-vim.git') expect(homesick).to receive(:git_clone).with('gitolite:pickled-vim.git',
destination: Pathname.new('pickled-vim'))
homesick.clone 'gitolite:pickled-vim.git' homesick.clone 'gitolite:pickled-vim.git'
end end
it 'throws an exception when trying to clone a malformed uri like malformed' do it 'throws an exception when trying to clone a malformed uri like malformed' do
expect(homesick).not_to receive(:git_clone) expect(homesick).not_to receive(:git_clone)
expect { homesick.clone 'malformed' }.to raise_error expect { homesick.clone 'malformed' }.to raise_error(RuntimeError)
end end
it 'clones a github repo' do it 'clones a github repo' do
expect(homesick).to receive(:git_clone) expect(homesick).to receive(:git_clone)
.with('https://github.com/wfarr/dotfiles.git', .with('https://github.com/wfarr/dotfiles.git', destination: Pathname.new('dotfiles'))
destination: Pathname.new('dotfiles'))
homesick.clone 'wfarr/dotfiles' homesick.clone 'wfarr/dotfiles'
end end
it 'accepts a destination', :focus do
expect(homesick).to receive(:git_clone)
.with('https://github.com/wfarr/dotfiles.git',
destination: Pathname.new('other-name'))
homesick.clone 'wfarr/dotfiles', 'other-name'
end
end end
describe 'rc' do describe 'rc' do
@@ -220,7 +227,7 @@ describe Homesick::CLI do
end end
end end
describe 'link' do describe 'link_castle' do
let(:castle) { given_castle('glencairn') } let(:castle) { given_castle('glencairn') }
it 'links dotfiles from a castle to the home folder' do it 'links dotfiles from a castle to the home folder' do
@@ -308,11 +315,9 @@ describe Homesick::CLI do
home_config_dir = home.join('.config') home_config_dir = home.join('.config')
home_someapp_dir = home_config_dir.join('someapp') home_someapp_dir = home_config_dir.join('someapp')
expect(home_config_dir.symlink?).to eq(false) expect(home_config_dir.symlink?).to eq(false)
expect(home_config_dir.join('.some_dotfile').readlink) expect(home_config_dir.join('.some_dotfile').readlink).to eq(config_dotfile)
.to eq(config_dotfile)
expect(home_someapp_dir.symlink?).to eq(false) expect(home_someapp_dir.symlink?).to eq(false)
expect(home_someapp_dir.join('.some_appfile').readlink) expect(home_someapp_dir.join('.some_appfile').readlink).to eq(someapp_dotfile)
.to eq(someapp_dotfile)
end end
end end
@@ -421,13 +426,9 @@ describe Homesick::CLI do
given_castle('wtf/zomg') given_castle('wtf/zomg')
expect(homesick).to receive(:say_status) expect(homesick).to receive(:say_status)
.with('zomg', .with('zomg', 'git://github.com/technicalpickles/zomg.git', :cyan)
'git://github.com/technicalpickles/zomg.git',
:cyan)
expect(homesick).to receive(:say_status) expect(homesick).to receive(:say_status)
.with('wtf/zomg', .with('wtf/zomg', 'git://github.com/technicalpickles/zomg.git', :cyan)
'git://github.com/technicalpickles/zomg.git',
:cyan)
homesick.list homesick.list
end end
@@ -437,7 +438,7 @@ describe Homesick::CLI do
it 'says "nothing to commit" when there are no changes' do it 'says "nothing to commit" when there are no changes' do
given_castle('castle_repo') given_castle('castle_repo')
text = Capture.stdout { homesick.status('castle_repo') } text = Capture.stdout { homesick.status('castle_repo') }
expect(text).to match(/nothing to commit \(create\/copy files and use "git add" to track\)$/) expect(text).to match(%r{nothing to commit \(create/copy files and use "git add" to track\)$})
end end
it 'says "Changes to be committed" when there are changes' do it 'says "Changes to be committed" when there are changes' do
@@ -445,9 +446,7 @@ describe Homesick::CLI do
some_rc_file = home.file '.some_rc_file' some_rc_file = home.file '.some_rc_file'
homesick.track(some_rc_file.to_s, 'castle_repo') homesick.track(some_rc_file.to_s, 'castle_repo')
text = Capture.stdout { homesick.status('castle_repo') } text = Capture.stdout { homesick.status('castle_repo') }
expect(text).to match( expect(text).to match(%r{Changes to be committed:.*new file:\s*home\/.some_rc_file}m)
/Changes to be committed:.*new file:\s*home\/.some_rc_file/m
)
end end
end end
@@ -519,7 +518,6 @@ describe Homesick::CLI do
end end
end end
end end
end end
describe 'push' do describe 'push' do
@@ -531,9 +529,7 @@ describe Homesick::CLI do
it 'prints an error message when trying to push a non-existant castle' do it 'prints an error message when trying to push a non-existant castle' do
expect(homesick).to receive('say_status').once expect(homesick).to receive('say_status').once
.with(:error, .with(:error, /Could not push castle_repo, expected .* exist and contain dotfiles/, :red)
/Could not push castle_repo, expected .* exist and contain dotfiles/,
:red)
expect { homesick.push 'castle_repo' }.to raise_error(SystemExit) expect { homesick.push 'castle_repo' }.to raise_error(SystemExit)
end end
end end
@@ -617,7 +613,6 @@ describe Homesick::CLI do
# Note that this is a test for the subdir_file related feature of track, # Note that this is a test for the subdir_file related feature of track,
# not for the subdir_file method itself. # not for the subdir_file method itself.
describe 'subdir_file' do describe 'subdir_file' do
it 'adds the nested files parent to the subdir_file' do it 'adds the nested files parent to the subdir_file' do
castle = given_castle('castle_repo') castle = given_castle('castle_repo')
@@ -692,9 +687,7 @@ describe Homesick::CLI do
it 'returns an error message when the given castle does not exist' do it 'returns an error message when the given castle does not exist' do
expect(homesick).to receive('say_status').once expect(homesick).to receive('say_status').once
.with(:error, .with(:error, /Could not cd castle_repo, expected .* exist and contain dotfiles/, :red)
/Could not cd castle_repo, expected .* exist and contain dotfiles/,
:red)
expect { homesick.cd 'castle_repo' }.to raise_error(SystemExit) expect { homesick.cd 'castle_repo' }.to raise_error(SystemExit)
end end
end end
@@ -707,7 +700,7 @@ describe Homesick::CLI do
allow(ENV).to receive(:[]).with('EDITOR').and_return('vim') allow(ENV).to receive(:[]).with('EDITOR').and_return('vim')
given_castle 'castle_repo' given_castle 'castle_repo'
expect(homesick).to receive('inside').once.with(kind_of(Pathname)).and_yield expect(homesick).to receive('inside').once.with(kind_of(Pathname)).and_yield
expect(homesick).to receive('system').once.with('vim') expect(homesick).to receive('system').once.with('vim .')
Capture.stdout { homesick.open 'castle_repo' } Capture.stdout { homesick.open 'castle_repo' }
end end
@@ -715,9 +708,7 @@ describe Homesick::CLI do
# Set the default editor to make sure it fails. # Set the default editor to make sure it fails.
allow(ENV).to receive(:[]).with('EDITOR').and_return(nil) allow(ENV).to receive(:[]).with('EDITOR').and_return(nil)
expect(homesick).to receive('say_status').once expect(homesick).to receive('say_status').once
.with(:error, .with(:error, 'The $EDITOR environment variable must be set to use this command', :red)
'The $EDITOR environment variable must be set to use this command',
:red)
expect { homesick.open 'castle_repo' }.to raise_error(SystemExit) expect { homesick.open 'castle_repo' }.to raise_error(SystemExit)
end end
@@ -725,9 +716,7 @@ describe Homesick::CLI do
# Set a default just in case none is set # Set a default just in case none is set
allow(ENV).to receive(:[]).with('EDITOR').and_return('vim') allow(ENV).to receive(:[]).with('EDITOR').and_return('vim')
allow(homesick).to receive('say_status').once allow(homesick).to receive('say_status').once
.with(:error, .with(:error, /Could not open castle_repo, expected .* exist and contain dotfiles/, :red)
/Could not open castle_repo, expected .* exist and contain dotfiles/,
:red)
expect { homesick.open 'castle_repo' }.to raise_error(SystemExit) expect { homesick.open 'castle_repo' }.to raise_error(SystemExit)
end end
end end
@@ -746,9 +735,7 @@ describe Homesick::CLI do
it 'executes a single command with no arguments inside a given castle' do it 'executes a single command with no arguments inside a given castle' do
allow(homesick).to receive('inside').once.with(kind_of(Pathname)).and_yield allow(homesick).to receive('inside').once.with(kind_of(Pathname)).and_yield
allow(homesick).to receive('say_status').once allow(homesick).to receive('say_status').once
.with(be_a(String), .with(be_a(String), be_a(String), :green)
be_a(String),
:green)
allow(homesick).to receive('system').once.with('ls') allow(homesick).to receive('system').once.with('ls')
Capture.stdout { homesick.exec 'castle_repo', 'ls' } Capture.stdout { homesick.exec 'castle_repo', 'ls' }
end end
@@ -756,18 +743,14 @@ describe Homesick::CLI do
it 'executes a single command with arguments inside a given castle' do it 'executes a single command with arguments inside a given castle' do
allow(homesick).to receive('inside').once.with(kind_of(Pathname)).and_yield allow(homesick).to receive('inside').once.with(kind_of(Pathname)).and_yield
allow(homesick).to receive('say_status').once allow(homesick).to receive('say_status').once
.with(be_a(String), .with(be_a(String), be_a(String), :green)
be_a(String),
:green)
allow(homesick).to receive('system').once.with('ls -la') allow(homesick).to receive('system').once.with('ls -la')
Capture.stdout { homesick.exec 'castle_repo', 'ls', '-la' } Capture.stdout { homesick.exec 'castle_repo', 'ls', '-la' }
end end
it 'raises an error when the method is called without a command' do it 'raises an error when the method is called without a command' do
allow(homesick).to receive('say_status').once allow(homesick).to receive('say_status').once
.with(:error, .with(:error, be_a(String), :red)
be_a(String),
:red)
allow(homesick).to receive('exit').once.with(1) allow(homesick).to receive('exit').once.with(1)
Capture.stdout { homesick.exec 'castle_repo' } Capture.stdout { homesick.exec 'castle_repo' }
end end
@@ -775,9 +758,7 @@ describe Homesick::CLI do
context 'pretend' do context 'pretend' do
it 'does not execute a command when the pretend option is passed' do it 'does not execute a command when the pretend option is passed' do
allow(homesick).to receive('say_status').once allow(homesick).to receive('say_status').once
.with(be_a(String), .with(be_a(String), match(/.*Would execute.*/), :green)
match(/.*Would execute.*/),
:green)
expect(homesick).to receive('system').never expect(homesick).to receive('system').never
Capture.stdout { homesick.invoke 'exec', %w(castle_repo ls -la), pretend: true } Capture.stdout { homesick.invoke 'exec', %w(castle_repo ls -la), pretend: true }
end end
@@ -787,7 +768,7 @@ describe Homesick::CLI do
it 'does not print status information when quiet is passed' do it 'does not print status information when quiet is passed' do
expect(homesick).to receive('say_status').never expect(homesick).to receive('say_status').never
allow(homesick).to receive('system').once allow(homesick).to receive('system').once
.with('ls -la') .with('ls -la')
Capture.stdout { homesick.invoke 'exec', %w(castle_repo ls -la), quiet: true } Capture.stdout { homesick.invoke 'exec', %w(castle_repo ls -la), quiet: true }
end end
end end
@@ -802,9 +783,7 @@ describe Homesick::CLI do
it 'executes a command without arguments inside the root of each cloned castle' do it 'executes a command without arguments inside the root of each cloned castle' do
allow(homesick).to receive('inside_each_castle').exactly(:twice).and_yield('castle_repo').and_yield('another_castle_repo') allow(homesick).to receive('inside_each_castle').exactly(:twice).and_yield('castle_repo').and_yield('another_castle_repo')
allow(homesick).to receive('say_status').at_least(:once) allow(homesick).to receive('say_status').at_least(:once)
.with(be_a(String), .with(be_a(String), be_a(String), :green)
be_a(String),
:green)
allow(homesick).to receive('system').at_least(:once).with('ls') allow(homesick).to receive('system').at_least(:once).with('ls')
Capture.stdout { homesick.exec_all 'ls' } Capture.stdout { homesick.exec_all 'ls' }
end end
@@ -812,18 +791,14 @@ describe Homesick::CLI do
it 'executes a command with arguments inside the root of each cloned castle' do it 'executes a command with arguments inside the root of each cloned castle' do
allow(homesick).to receive('inside_each_castle').exactly(:twice).and_yield('castle_repo').and_yield('another_castle_repo') allow(homesick).to receive('inside_each_castle').exactly(:twice).and_yield('castle_repo').and_yield('another_castle_repo')
allow(homesick).to receive('say_status').at_least(:once) allow(homesick).to receive('say_status').at_least(:once)
.with(be_a(String), .with(be_a(String), be_a(String), :green)
be_a(String),
:green)
allow(homesick).to receive('system').at_least(:once).with('ls -la') allow(homesick).to receive('system').at_least(:once).with('ls -la')
Capture.stdout { homesick.exec_all 'ls', '-la' } Capture.stdout { homesick.exec_all 'ls', '-la' }
end end
it 'raises an error when the method is called without a command' do it 'raises an error when the method is called without a command' do
allow(homesick).to receive('say_status').once allow(homesick).to receive('say_status').once
.with(:error, .with(:error, be_a(String), :red)
be_a(String),
:red)
allow(homesick).to receive('exit').once.with(1) allow(homesick).to receive('exit').once.with(1)
Capture.stdout { homesick.exec_all } Capture.stdout { homesick.exec_all }
end end
@@ -831,9 +806,7 @@ describe Homesick::CLI do
context 'pretend' do context 'pretend' do
it 'does not execute a command when the pretend option is passed' do it 'does not execute a command when the pretend option is passed' do
allow(homesick).to receive('say_status').at_least(:once) allow(homesick).to receive('say_status').at_least(:once)
.with(be_a(String), .with(be_a(String), match(/.*Would execute.*/), :green)
match(/.*Would execute.*/),
:green)
expect(homesick).to receive('system').never expect(homesick).to receive('system').never
Capture.stdout { homesick.invoke 'exec_all', %w(ls -la), pretend: true } Capture.stdout { homesick.invoke 'exec_all', %w(ls -la), pretend: true }
end end
@@ -843,7 +816,7 @@ describe Homesick::CLI do
it 'does not print status information when quiet is passed' do it 'does not print status information when quiet is passed' do
expect(homesick).to receive('say_status').never expect(homesick).to receive('say_status').never
allow(homesick).to receive('system').at_least(:once) allow(homesick).to receive('system').at_least(:once)
.with('ls -la') .with('ls -la')
Capture.stdout { homesick.invoke 'exec_all', %w(ls -la), quiet: true } Capture.stdout { homesick.invoke 'exec_all', %w(ls -la), quiet: true }
end end
end end