lib/tmbundle.rb in tmbundle-manager-0.1.0.pre3 vs lib/tmbundle.rb in tmbundle-manager-0.1.0.pre4
- old
+ new
@@ -2,27 +2,14 @@
require 'thor'
class TMBundle < Thor
desc 'edit PARTIAL_NAME', 'Edit an installed bundle (name will be matched against PARTIAL_NAME)'
def edit partial_name
- matches = installed_bundles.select do |bundle|
- bundle.name =~ /^#{partial_name}/i
- end
-
- if matches.size > 1
- puts "please be more specific:"
- matches.each_with_index {|m,i| puts " #{i+1}) #{m.name}"}
- return false
- end
-
- if matches.empty?
- puts "nothing found"
- return false
- end
-
- bundle = matches.first
+ bundle = find_bundle(partial_name)
mate bundle.path
+ rescue NotFound
+ return false
end
desc 'update', 'Update installed bundles'
def update
require 'thread'
@@ -40,11 +27,11 @@
skipped << bundle
next
end
puts "------> Updating #{bundle.name}..."
- system *%w[git pull --ff-only]
+ system(*%w[git pull --ff-only])
success = $? == 0
updated << bundle if success
errored << bundle unless success
puts
(puts 'Exiting…'; exit) if signals.pop == :int until signals.empty?
@@ -58,51 +45,118 @@
puts "Skipped (#{skipped.size})\n- #{skipped.map(&:name).join("\n- ")}\n\n" if skipped.any?
puts "Updated (#{updated.size})\n- #{updated.map(&:name).join("\n- ")}\n\n" if updated.any?
puts "Errored (#{errored.size})\n- #{errored.map(&:name).join("\n- ")}\n\n" if errored.any?
end
- desc 'install', 'Install a bundle from GitHub'
+ desc 'install USER/BUNDLE', 'Install a bundle from GitHub (e.g. tmb install elia/bundler)'
def install name
name = BundleName.new(name)
install_path = bundles_dir.join(name.install_name).to_s
system('git', 'clone', name.git_url, install_path)
end
- class BundleName
- def initialize(name)
- @name = name
+ desc 'path NAME', 'print path to bundle dir'
+ def path name
+ puts find_bundle(name).path
+ rescue NotFound
+ return false
+ end
+
+ desc 'status [BUNDLE]', 'Check the status of your local copy of the bundle'
+ def status name = nil
+ justification = 50
+ bundles_list.all.each do |bundle|
+ within bundle do
+ print "- #{bundle.name}...".ljust(justification)
+ # puts "-> fetching updates from remote..."
+ `git fetch -aq 2> /dev/null`
+ fetch_successful = $?.success?
+ # puts "-> checking status..."
+ branch_info, *changes = `git status -zb`.split("\0")
+ branch, remote, branch_status, = branch_info.scan(/^## (\S+)\.\.\.(\S+)(?: \[(.+)\])?/).flatten
+ cd_hint = false
+
+ if changes.any?
+ cd_hint = true
+ print "✘ #{changes.size} changed/new file#{:s if changes.size != 0}.".ljust(justification)
+ else
+ case branch_status.to_s
+ when /^ahead (\d+)/
+ ahead_commits = $1
+ cd_hint = true
+ print "✘ #{ahead_commits} commits ahead of #{remote}. ".ljust(justification)
+ when /^behind (\d+)/
+ behind_commits = $1
+ cd_hint = true
+ print "❍ behind remote (#{remote}) by #{behind_commits}. ".ljust(justification)
+ else
+ print "✔︎ up-to-date"
+ end
+ end
+ print "$ cd \"#{bundle.path}\" # to enter the bundle directory" if cd_hint
+ puts
+ puts "#{' '*justification}✘✘✘ Something went wrong while fetching from remote #{remote}" unless fetch_successful
+ end
end
+ end
- attr_reader :name
- private :name
+ desc 'list', 'lists all installed bundles'
+ def list
+ bundles_list.all.each do |bundle|
+ puts "- #{bundle.name.ljust(30)} (#{bundle.path})"
+ end
+ end
- def install_name
- File.basename(name.gsub(/([\.\-_]tmbundle)?$/i, '.tmbundle'))
+
+
+ private
+
+ def find_bundle(partial_name)
+ matches = installed_bundles.select do |bundle|
+ bundle.name =~ /^#{partial_name}/i
end
- def repo_name
- name+'.tmbundle' unless name =~ /([\.\-_]tmbundle)$/i
+ if matches.size > 1
+ puts "please be more specific:"
+ matches.each_with_index {|m,i| puts " #{i+1}) #{m.name}"}
+ raise NotFound
end
- def git_url
- "https://github.com/#{repo_name}.git"
+ if matches.empty?
+ puts "nothing found"
+ raise NotFound
end
+
+ matches.first
end
- private
+ class NotFound < StandardError
+ end
def within bundle
Dir.chdir bundle.path do
yield
end
end
def installed_bundles
- @installed_bundles ||= Dir[bundles_dir.join('*').to_s].map {|path| Bundle.new(path)}
+ bundles_list.all
end
+ def bundles_list
+ @bundles_list ||= BundlesList.new(bundles_dir)
+ end
+
def bundles_dir
@bundles_dir ||= Pathname('~/Library/Application Support/Avian/Bundles').expand_path
+ end
+
+ class BundlesList < Struct.new(:dir)
+ def all
+ @all ||= Dir[dir.join('*/.git').to_s].map do |path|
+ Bundle.new(Pathname(path).join('..').to_s)
+ end
+ end
end
class Bundle < Struct.new(:path)
def name
@name ||= File.basename(path, '.tmbundle')