bin/textmate in ddollar-textmate-0.9.8 vs bin/textmate in ddollar-textmate-1.0.0
- old
+ new
@@ -1,236 +1,94 @@
#!/usr/bin/env ruby
-require "fileutils"
-require "rubygems"
-require "thor"
-require "open-uri"
-require "yaml"
+require 'thor'
+$:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
+require 'textmate'
+
class TextmateInstaller < Thor
-
- # CHANGED: renamed list to remote. Could there be a better name?
+
desc "search [SEARCH]", "Lists all the matching remote bundles"
- def search(search_term = "")
- search_term = Regexp.new(".*#{search_term}.*", "i")
-
- remote_bundle_locations.keys.map { |key| key.to_s }.sort.each do |name|
- location = remote_bundle_locations[name.to_sym]
- puts "\n" << name.to_s << " Remote Bundles\n" << name.to_s.gsub(/./,'-') << '---------------'
-
- results = case location[:scm]
- when :svn
- %x[svn list #{e_sh location[:url]}].select {|x| x =~ search_term}.map do |result|
- "%s - %s" % [
- result.split('.').first,
- "#{location[:url]}/#{result.chomp}"
- ]
- end.join("\n")
- when :git
- 'git remotes not implemented yet'
- when :github
- find_github_bundles(search_term).map {|result|
- "%s - %s" %
- [
- normalize_github_repo_name(result['name']).split('.').first,
- git_url_from_github_result(result)
- ]
- }
- end
-
- puts results
- end
+ def search(search = "")
+ display_hash remote.bundles(search)
end
-
+
desc "list [SEARCH]", "lists all the bundles installed locally"
- def list(search_term = "")
- search_term = Regexp.new(".*#{search_term}.*", "i")
-
- local_bundle_paths.each do |name,bundles_path|
- puts "\n" << name.to_s << " Bundles\n" << name.to_s.gsub(/./,'-') << '--------'
- puts Dir["#{e_sh bundles_path}/*.tmbundle"].map {|x| x.split("/").last.split(".").first}.
- select {|x| x =~ search_term}.join("\n")
- end
+ def list(search = "")
+ display_hash local.bundles(search)
end
-
+
desc "install NAME [SOURCE]", "install a bundle"
- def install(bundle_name, remote_bundle_location_name=nil)
- FileUtils.mkdir_p install_bundles_path
- puts "Checking out #{bundle_name}..."
-
- # CHANGED: It's faster to just try and fail for each repo than to search them all first
- installed=false
- remote_bundle_locations.each do |remote_name,location|
- next unless remote_name.to_s.downcase.include? remote_bundle_location_name.to_s.downcase if remote_bundle_location_name
-
- cmd = case location[:scm]
- when :git
- 'echo "git remotes not implemented yet"'
- when :svn
- %[svn co #{e_sh location[:url]}/#{e_sh bundle_name}.tmbundle #{e_sh install_bundles_path}/#{e_sh bundle_name}.tmbundle 2>&1]
- when :github
- repos = find_github_bundles(denormalize_github_repo_name(bundle_name))
-
- # Handle possible multiple Repos with the same name
- case repos.size
- when 0
- 'echo "Sorry, no such bundle found"'
- when 1
- %[git clone git://github.com/#{repos.first['username']}/#{repos.first['name']}.git #{e_sh install_bundles_path}/#{e_sh bundle_name}.tmbundle 2>&1]
- else
- puts "Multiple bundles with that name found. Please choose which one you want to install:"
- repos.each_with_index {|repo, idx|
- puts "%d: %s by %s" %
- [
- idx + 1,
- normalize_github_repo_name(repo['name']),
- repo['username']
- ]
- }
- print "Your choice: "
-
- # Since to_i defaults to 0, we have to use Integer
- choice = Integer(STDIN.gets.chomp) rescue nil
- until choice && (0...repos.size).include?( choice - 1 ) do
- print "Sorry, invalid choice. Please enter a valid number or Ctrl+C to stop: "
- choice = Integer(STDIN.gets.chomp) rescue nil
- end
-
- %[git clone git://github.com/#{repos[choice - 1]['username']}/#{repos.first['name']}.git #{e_sh install_bundles_path}/#{e_sh bundle_name}.tmbundle 2>&1]
- end
- end
-
- res = %x{#{cmd}}
-
- puts cmd, res.gsub(/^/,' ')
-
- installed=true and break if res =~ /Checked out revision|Initialized empty Git repository/
+ def install(bundle)
+ remotes = remote.bundles(bundle)
+
+ case remotes.values.flatten.length
+ when 0 then abort("Unknown bundle: #{bundle}")
+ when 1 then local.install(bundle, remotes.keys.detect { |k| remotes[k].length == 1 })
+ else local.install(*select_remote(remotes))
end
- abort 'Not Installed' unless installed
-
- reload :verbose => true
+
+ reload
end
desc "uninstall NAME", "uninstall a bundle"
- def uninstall(bundle_name)
+ def uninstall(bundle)
puts "Removing bundle..."
- # When moving to the trash, maybe move the bundle into a trash/disabled_bundles subfolder
- # named as the bundles_path key. Just in case there are multiple versions of
- # the same bundle in multiple bundle paths
- local_bundle_paths.each do |name,bundles_path|
- bundle_path = "#{bundles_path}/#{bundle_name}.tmbundle"
- if File.exist? bundle_path
- %x[osascript -e 'tell application "Finder" to move the POSIX file "#{bundle_path}" to trash']
- end
- end
-
- reload :verbose => true
+ local.uninstall(bundle)
+ reload
end
-
+
desc "reload", "Reloads TextMate Bundles"
- method_options :verbose => :boolean
- def reload(opts = {})
- puts "Reloading bundles..." if opts[:verbose]
- %x[osascript -e 'tell app "TextMate" to reload bundles']
- puts "Done." if opts[:verbose]
+ def reload
+ puts "Reloading bundles..."
+ %x{ osascript -e 'tell app "TextMate" to reload bundles' }
end
-
- private
- def remote_bundle_locations
- { :'Macromates Trunk' => {:scm => :svn, :url => 'http://svn.textmate.org/trunk/Bundles'},
- :'Macromates Review' => {:scm => :svn, :url => 'http://svn.textmate.org/trunk/Review/Bundles'},
-
- # :'Bunch of Git Bundles' => {:scm => :git, :url => 'git://NotImplemented'},
-
- :'GitHub' => {:scm => :github, :url => 'http://github.com/search?q=tmbundle'},
- }
+
+end
+
+def local
+ @local ||= Textmate::Local.new
+end
+
+def remote
+ @remote ||= Textmate::Remote.new
+end
+
+def display_hash(hash)
+ puts
+ hash.keys.sort.each do |key|
+ value = hash[key]
+ key = key.name if key.respond_to?(:name)
+ puts key
+ puts '-' * key.length
+ case value
+ when Array then puts value.join("\n") unless value.empty?
+ else puts value
+ end
+ puts
end
-
- def local_bundle_paths
- { :Application => '/Applications/TextMate.app/Contents/SharedSupport/Bundles',
- :User => "#{ENV["HOME"]}/Library/Application Support/TextMate/Bundles",
- :System => '/Library/Application Support/TextMate/Bundles',
- :'User Pristine' => "#{ENV["HOME"]}/Library/Application Support/TextMate/Pristine Copy/Bundles",
- :'System Pristine' => '/Library/Application Support/TextMate/Pristine Copy/Bundles',
- }
- end
-
- def install_bundles_path
- local_bundle_paths[:'User Pristine']
- end
-
- # Copied from http://macromates.com/svn/Bundles/trunk/Support/lib/escape.rb
- # escape text to make it useable in a shell script as one “word” (string)
- def e_sh(str)
- str.to_s.gsub(/(?=[^a-zA-Z0-9_.\/\-\x7F-\xFF\n])/, '\\').gsub(/\n/, "'\n'").sub(/^$/, "''")
- end
-
- CAPITALIZATION_EXCEPTIONS = %w[tmbundle on]
- # Convert a GitHub repo name into a "normal" TM bundle name
- # e.g. ruby-on-rails-tmbundle => Ruby on Rails.tmbundle
- def normalize_github_repo_name(name)
- name = name.gsub("-", " ").split.each{|part| part.capitalize! unless CAPITALIZATION_EXCEPTIONS.include? part}.join(" ")
- name[-9] = ?. if name =~ / tmbundle$/
- name
- end
-
- # Does the opposite of normalize_github_repo_name
- def denormalize_github_repo_name(name)
- name += " tmbundle" unless name =~ / tmbundle$/
- name.split(' ').each{|part| part.downcase!}.join(' ').gsub(' ', '-')
- end
-
- def find_github_bundles(search_term)
- # Until GitHub fixes http://support.github.com/discussions/feature-requests/11-api-search-results,
- # we need to account for multiple pages of results:
- page = 1
- repositories = YAML.load(open("http://github.com/api/v1/yaml/search/tmbundle?start_value=#{page}"))['repositories']
- results = []
- until repositories.empty?
- results += repositories.find_all{|result| result['name'].match(search_term)}
- page += 1
- repositories = YAML.load(open("http://github.com/api/v1/yaml/search/tmbundle?start_value=#{page}"))['repositories']
+end
+
+def select_remote(remotes)
+ puts "Please select a bundle from the following list:"
+ puts
+ bundle_index = {}
+ remotes.keys.sort.inject(0) do |index, remote|
+ bundles = remotes[remote]
+ puts remote.name
+ puts '-' * remote.name.length
+ bundles.each do |bundle|
+ bundle_index[index += 1] = [bundle, remote]
+ puts "#{index}. #{bundle}"
end
- results.sort{|a,b| a['name'] <=> b['name']}
+ puts
+ index
end
-
- def git_url_from_github_result(result)
- "git://github.com/#{result['username']}/#{result['name']}.git"
- end
-end
+ index = ask('Which bundle would you like to install?').to_i
+ puts
+ abort("Unknown option: #{index}") unless bundle_index[index]
-# TODO: create a "monument to personal cleverness" by class-izing everything?
-# class TextMateBundle
-# def self.find_local(bundle_name)
-#
-# end
-#
-# def self.find_remote(bundle_name)
-#
-# end
-# attr_reader :name
-# attr_reader :location
-# attr_reader :scm
-# def initialize(name, location, scm)
-# @name = name
-# @location = location
-# @scm = scm
-# end
-#
-# def install!
-#
-# end
-#
-# def uninstall!
-#
-# end
-#
-#
-# def installed?
-# # List all the installed versions, and where they're at
-# end
-#
-# # TODO: dirty? method to show if there are any deltas
-# end
+ bundle_index[index]
+end
TextmateInstaller.start