class Homesick::CLI
Homesick's command line interface
Public Class Methods
new(args = [], options = {}, config = {})
click to toggle source
Calls superclass method
# File lib/homesick/cli.rb, line 20 def initialize(args = [], options = {}, config = {}) super # Check if git is installed unless git_version_correct? say_status :error, "Git version >= #{Homesick::Actions::GitActions::STRING} must be installed to use Homesick", :red exit(1) end # Hack in support for diffing symlinks # Also adds support for checking if destination or content is a directory shell_metaclass = class << shell; self; end shell_metaclass.send(:define_method, :show_diff) do |destination, source| destination = Pathname.new(destination) source = Pathname.new(source) return 'Unable to create diff: destination or content is a directory' if destination.directory? || source.directory? return super(destination, File.binread(source)) unless destination.symlink? say "- #{destination.readlink}", :red, true say "+ #{source.expand_path}", :green, true end end
Public Instance Methods
cd(castle = DEFAULT_CASTLE_NAME)
click to toggle source
# File lib/homesick/cli.rb, line 257 def cd(castle = DEFAULT_CASTLE_NAME) check_castle_existance castle, 'cd' castle_dir = repos_dir.join(castle) say_status "cd #{castle_dir.realpath}", "Opening a new shell in castle '#{castle}'. To return to the original one exit from the new shell.", :green inside castle_dir do system(ENV['SHELL']) end end
clone(uri, destination=nil)
click to toggle source
# File lib/homesick/cli.rb, line 41 def clone(uri, destination=nil) destination = Pathname.new(destination) unless destination.nil? inside repos_dir do if File.exist?(uri) uri = Pathname.new(uri).expand_path fail "Castle already cloned to #{uri}" if uri.to_s.start_with?(repos_dir.to_s) destination = uri.basename if destination.nil? ln_s uri, destination elsif uri =~ GITHUB_NAME_REPO_PATTERN destination = Pathname.new(uri).basename if destination.nil? git_clone "https://github.com/#{Regexp.last_match[1]}.git", destination: destination elsif uri =~ /%r([^%r]*?)(\.git)?\Z/ || uri =~ /[^:]+:([^:]+)(\.git)?\Z/ destination = Pathname.new(Regexp.last_match[1].gsub(/\.git$/, '')).basename if destination.nil? git_clone uri, destination: destination else fail "Unknown URI format: #{uri}" end setup_castle(destination) end end
commit(name = DEFAULT_CASTLE_NAME, message = nil)
click to toggle source
# File lib/homesick/cli.rb, line 104 def commit(name = DEFAULT_CASTLE_NAME, message = nil) commit_castle name, message end
destroy(name)
click to toggle source
# File lib/homesick/cli.rb, line 248 def destroy(name) check_castle_existance name, 'destroy' return unless shell.yes?('This will destroy your castle irreversible! Are you sure?') unlink(name) rm_rf repos_dir.join(name) end
diff(castle = DEFAULT_CASTLE_NAME)
click to toggle source
# File lib/homesick/cli.rb, line 214 def diff(castle = DEFAULT_CASTLE_NAME) check_castle_existance(castle, 'diff') inside repos_dir.join(castle) do git_diff end end
exec(castle, *args)
click to toggle source
# File lib/homesick/cli.rb, line 290 def exec(castle, *args) check_castle_existance castle, 'exec' unless args.count > 0 say_status :error, 'You must pass a shell command to execute', :red exit(1) end full_command = args.join(' ') say_status "exec '#{full_command}'", "#{options[:pretend] ? 'Would execute' : 'Executing command'} '#{full_command}' in castle '#{castle}'", :green inside repos_dir.join(castle) do system(full_command) end end
exec_all(*args)
click to toggle source
# File lib/homesick/cli.rb, line 309 def exec_all(*args) unless args.count > 0 say_status :error, 'You must pass a shell command to execute', :red exit(1) end full_command = args.join(' ') inside_each_castle do |castle| say_status "exec '#{full_command}'", "#{options[:pretend] ? 'Would execute' : 'Executing command'} '#{full_command}' in castle '#{castle}'", :green system(full_command) end end
generate(castle)
click to toggle source
# File lib/homesick/cli.rb, line 228 def generate(castle) castle = Pathname.new(castle).expand_path github_user = `git config github.user`.chomp github_user = nil if github_user == '' github_repo = castle.basename empty_directory castle inside castle do git_init if github_user url = "git@github.com:#{github_user}/#{github_repo}.git" git_remote_add 'origin', url end empty_directory 'home' end end
link(name = DEFAULT_CASTLE_NAME)
click to toggle source
# File lib/homesick/cli.rb, line 135 def link(name = DEFAULT_CASTLE_NAME) check_castle_existance(name, 'symlink') inside castle_dir(name) do subdirs = subdirs(name) # link files symlink_each(name, castle_dir(name), subdirs) # link files in subdirs subdirs.each do |subdir| symlink_each(name, subdir, subdirs) end end end
list()
click to toggle source
# File lib/homesick/cli.rb, line 197 def list inside_each_castle do |castle| say_status castle.relative_path_from(repos_dir).to_s, `git config remote.origin.url`.chomp, :cyan end end
open(castle = DEFAULT_CASTLE_NAME)
click to toggle source
# File lib/homesick/cli.rb, line 270 def open(castle = DEFAULT_CASTLE_NAME) unless ENV['EDITOR'] say_status :error, 'The $EDITOR environment variable must be set to use this command', :red exit(1) end check_castle_existance castle, 'open' castle_dir = repos_dir.join(castle) say_status "#{castle_dir.realpath}: #{ENV['EDITOR']} .", "Opening the root directory of castle '#{castle}' in editor '#{ENV['EDITOR']}'.", :green inside castle_dir do system("#{ENV['EDITOR']} .") end end
pull(name = DEFAULT_CASTLE_NAME)
click to toggle source
# File lib/homesick/cli.rb, line 92 def pull(name = DEFAULT_CASTLE_NAME) if options[:all] inside_each_castle do |castle| say castle.to_s.gsub(repos_dir.to_s + '/', '') + ':' update_castle castle end else update_castle name end end
push(name = DEFAULT_CASTLE_NAME)
click to toggle source
# File lib/homesick/cli.rb, line 109 def push(name = DEFAULT_CASTLE_NAME) push_castle name end
rc(name = DEFAULT_CASTLE_NAME)
click to toggle source
# File lib/homesick/cli.rb, line 72 def rc(name = DEFAULT_CASTLE_NAME) inside repos_dir do destination = Pathname.new(name) homesickrc = destination.join('.homesickrc').expand_path return unless homesickrc.exist? proceed = options[:force] || shell.yes?("#{name} has a .homesickrc. Proceed with evaling it? (This could be destructive)") return say_status 'eval skip', "not evaling #{homesickrc}, #{destination} may need manual configuration", :blue unless proceed say_status 'eval', homesickrc inside destination do eval homesickrc.read, binding, homesickrc.expand_path.to_s end end end
show_path(castle = DEFAULT_CASTLE_NAME)
click to toggle source
# File lib/homesick/cli.rb, line 222 def show_path(castle = DEFAULT_CASTLE_NAME) check_castle_existance(castle, 'show_path') say repos_dir.join(castle) end
status(castle = DEFAULT_CASTLE_NAME)
click to toggle source
# File lib/homesick/cli.rb, line 206 def status(castle = DEFAULT_CASTLE_NAME) check_castle_existance(castle, 'status') inside repos_dir.join(castle) do git_status end end
track(file, castle = DEFAULT_CASTLE_NAME)
click to toggle source
# File lib/homesick/cli.rb, line 152 def track(file, castle = DEFAULT_CASTLE_NAME) castle = Pathname.new(castle) file = Pathname.new(file.chomp('/')) check_castle_existance(castle, 'track') 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) FileUtils.mkdir_p 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? move_dir_contents(target, absolute_path) absolute_path.rmtree subdir_remove(castle, relative_dir + file.basename) elsif more_recent? absolute_path, target target.delete mv absolute_path, castle_path else say_status(:track, "#{target} already exists, and is more recent than #{file}. Run 'homesick SYMLINK CASTLE' to create symlinks.", :blue) end else mv absolute_path, castle_path end inside home_dir do absolute_path = castle_path + file.basename home_path = home_dir + relative_dir + file.basename ln_s absolute_path, home_path end inside castle_path do git_add absolute_path end # are we tracking something nested? Add the parent dir to the manifest subdir_add(castle, relative_dir) unless relative_dir.eql?(Pathname.new('.')) end
unlink(name = DEFAULT_CASTLE_NAME)
click to toggle source
# File lib/homesick/cli.rb, line 114 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
version()
click to toggle source
# File lib/homesick/cli.rb, line 326 def version say Homesick::Version::STRING end