matebundle 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (6) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +20 -0
  3. data/README.md +41 -0
  4. data/Rakefile +49 -0
  5. data/bin/matebundle +167 -0
  6. metadata +64 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1250be3cf0f4d4fe358d9ea8b40451cf85717ba5
4
+ data.tar.gz: 1992a6059b26cd5afac457bcc068a72e478a7d76
5
+ SHA512:
6
+ metadata.gz: 6f903bda202fd56bc055a2bbc8cf972194631861726e5f17c0f4392b57a722104a5af0ed954dd1a0be13e2e52bb7095081938fb1bf40ecc68e819f6e508d6b16
7
+ data.tar.gz: 6c133f3be5fcbf69ef733fb2be60909c81395cd7276cbceeab307169308043ae9a61f66d7aa1a2420eaee744c1d06aadb73f53f27bf02f7ffd84e34770f31ea1
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 Yixi Zhang
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,41 @@
1
+ matebundle
2
+ ==========
3
+ Command line bundle manager for TextMate 2.
4
+
5
+ Find, Install and Update text mate bundles hosted on Github.
6
+
7
+ ## Usage
8
+
9
+ ```bash
10
+ matebundle [COMMANDS] [*PARAMS]
11
+ ```
12
+
13
+ ### list bundles
14
+
15
+ ```bash
16
+ matebundle list [*NAME]
17
+ ```
18
+
19
+ ### search remote bundles
20
+
21
+ ```bash
22
+ matebundle search [NAME]
23
+ ```
24
+
25
+ ### install bundle
26
+
27
+ ```bash
28
+ matebundle install [NAME]
29
+ ```
30
+
31
+ ### update bundles
32
+
33
+ ```bash
34
+ matebundle update
35
+ ```
36
+
37
+ ### uninstall bundle
38
+
39
+ ```bash
40
+ matebundle uninstall [NAME]
41
+ ```
data/Rakefile ADDED
@@ -0,0 +1,49 @@
1
+ require "rubygems"
2
+ require "rubygems/package_task"
3
+
4
+
5
+ GEM = "matebundle"
6
+ GEM_VERSION = "0.1.0"
7
+ AUTHOR = "YIXI ZHANG"
8
+ EMAIL = "yixi.zhang.max@gmail.com"
9
+ HOMEPAGE = "https://github.com/yixizhang/matebundle"
10
+ SUMMARY = "Bundle Manager for TextMate 2"
11
+
12
+ spec = Gem::Specification.new do |s|
13
+ s.name = GEM
14
+ s.version = GEM_VERSION
15
+ s.platform = Gem::Platform::RUBY
16
+ s.has_rdoc = true
17
+ s.extra_rdoc_files = ["README.md", "LICENSE"]
18
+ s.summary = SUMMARY
19
+ s.description = s.summary
20
+ s.author = AUTHOR
21
+ s.email = EMAIL
22
+ s.homepage = HOMEPAGE
23
+ s.license = "MIT"
24
+
25
+ s.add_dependency "thor", ">= 0.18"
26
+
27
+ s.require_path = "bin"
28
+ s.autorequire = GEM
29
+ s.files = %w(LICENSE README.md Rakefile) + Dir.glob("{bin,specs}/**/*")
30
+ s.bindir = "bin"
31
+ s.executables << "matebundle"
32
+
33
+ s.required_ruby_version = '>= 1.9.2'
34
+ end
35
+
36
+ Gem::PackageTask.new(spec) do |pkg|
37
+ pkg.gem_spec = spec
38
+ end
39
+
40
+ desc "make a gemspec file"
41
+ task :make_spec do
42
+ File.open("#{GEM}.gemspec", "w") do |file|
43
+ file.puts spec.to_ruby
44
+ end
45
+ end
46
+
47
+ task :install => [:package] do
48
+ %x{gem install pkg/#{GEM}-#{GEM_VERSION}.gem --no-rdoc --no-ri}
49
+ end
data/bin/matebundle ADDED
@@ -0,0 +1,167 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require "fileutils"
5
+ require "thor"
6
+ require "open-uri"
7
+ require "json"
8
+ require "uri"
9
+ require "shellwords"
10
+
11
+
12
+ class MateBundle < Thor
13
+
14
+ desc "search [NAME]", "Lists all the matching remote bundles"
15
+ def search(name="")
16
+ puts "\n" << "Searching remote Bundles on Github...\n"
17
+
18
+ bundles = search_bundles(name).map do |result|
19
+ "%s (by %s)" %
20
+ [
21
+ normalize_github_repo_name(result['name']).split('.').first,
22
+ result['username'] || result['owner']['login']
23
+ ]
24
+ end
25
+
26
+ puts bundles
27
+ end
28
+
29
+ desc "list [NAME]", "Lists all the installed bundles"
30
+ def list(name="")
31
+ puts "\n" << "Local Bundles\n\n"
32
+
33
+ puts Dir["#{LOCAL_LOCATION}/*.tmbundle"].map { |x| x.split("/").last.split(".").first }.
34
+ select { |x| x.downcase.match(name.downcase) }.join("\n")
35
+ end
36
+
37
+ desc "install [NAME]", "Install a bundle from Github. \n" \
38
+ "If multiple gems with the same name exists, you will be prompted to \n" \
39
+ "choose from the available list."
40
+ def install(name="")
41
+ FileUtils.mkdir_p LOCAL_LOCATION
42
+ puts "Checking out #{name}...\n"
43
+
44
+ repos = search_bundles(denormalize_github_repo_name(name))
45
+
46
+ cmd = case repos.size
47
+ when 0
48
+ 'echo "Sorry, no such bundle found"'
49
+ when 1
50
+ git_clone(repos.first)
51
+ else
52
+ puts "Multiple bundles with that name found. Please choose which one you want to install:"
53
+ repos.each_with_index do |repo, idx|
54
+ puts "%d: %s by %s" %
55
+ [
56
+ idx + 1,
57
+ normalize_github_repo_name(repo["name"]),
58
+ repo["username"]
59
+ ]
60
+ end
61
+ print "Your choice: "
62
+
63
+ choice = Integer(STDIN.gets.chomp) rescue nil
64
+ until choice && (0..repos.size).include?(choice-1) do
65
+ print "Sorry, invalid choice. Please enter a valid number or Ctrl+C to stop: "
66
+ choice = Integer(STDIN.gets.chomp) rescue nil
67
+ end
68
+
69
+ git_clone(repos[choice-1])
70
+ end
71
+
72
+ %x{#{cmd}}
73
+ end
74
+
75
+ desc "update", "Update all installed bundles"
76
+ def update
77
+ Dir.new(LOCAL_LOCATION).each do |dir|
78
+ path = File.join(LOCAL_LOCATION, dir)
79
+
80
+ if !['.', '..'].include?(dir) and File.directory?(path)
81
+ git_path = File.join(path, '.git')
82
+ if File.exist?(git_path)
83
+ puts "Updating #{dir}..."
84
+ %x[git --git-dir=#{git_path.shellescape} --work-tree=#{path.shellescape} pull]
85
+ end
86
+ end
87
+ end
88
+ end
89
+
90
+ desc "uninstall [NAME]", "Uninstall a bundle"
91
+ def uninstall(name)
92
+ bundle_path = "#{LOCAL_LOCATION}/#{name}.tmbundle"
93
+
94
+ puts "Removing bundle..."
95
+
96
+ if File.exist? bundle_path
97
+ %x[rm -rf #{bundle_path.shellescape}]
98
+ else
99
+ say "There is no bundle by that name in the system", :red
100
+ exit
101
+ end
102
+ end
103
+
104
+ private
105
+
106
+ LOCAL_LOCATION = "#{ENV['HOME']}/Library/Application Support/TextMate/Managed/Bundles"
107
+
108
+ CAPITALIZATION_EXCEPTIONS = %w[tmbundle on]
109
+
110
+ def normalize_github_repo_name(name)
111
+ name = name.gsub(/[\-\.]/, " ").split.each{|part| part.capitalize! unless CAPITALIZATION_EXCEPTIONS.include? part}.join(" ")
112
+ name[-9] = ?. if name =~ / tmbundle$/
113
+ name
114
+ end
115
+
116
+ def denormalize_github_repo_name(name)
117
+ # name = name.split(' ').each{|part| part.downcase!}.join(' ').gsub(' ', '-')
118
+ name = name.split(' ').each{|part| part.downcase!}.join('-')
119
+ name += ".tmbundle" unless name =~ /.tmbundle$/
120
+ name
121
+ end
122
+
123
+ def github_api_search(search_term, page=1)
124
+ begin
125
+ JSON.parse(open("https://api.github.com/search/repositories?q=tmbundle+#{search_term}&page=#{page}").read)["items"]
126
+ rescue
127
+ abort "Hit Github search API rate limit, please wait for a short while..."
128
+ end
129
+ end
130
+
131
+ def search_bundles(search_term)
132
+ page = 1
133
+ repositories = github_api_search(search_term, page)
134
+ results = []
135
+ until repositories.empty?
136
+ results += repositories.find_all do |repo|
137
+ repo_name = repo["name"].downcase
138
+ repo_name.match(search_term.downcase) and repo_name =~ /tmbundle$/
139
+ end
140
+ page += 1
141
+ repositories = github_api_search(search_term, page)
142
+ end
143
+ results.sort_by { |result| result["name"] }
144
+ end
145
+
146
+ def bundle_path(repo)
147
+ bundle_name = normalize_github_repo_name(repo["name"])
148
+ "#{LOCAL_LOCATION}/#{bundle_name}"
149
+ end
150
+
151
+ def git_clone(repo)
152
+ path = bundle_path(repo)
153
+
154
+ if File.directory?(path)
155
+ say "Sorry, that bundle is already installed. Please uninstall it first.", :red
156
+ exit
157
+ end
158
+
159
+ puts "Installing #{repo['name']}..."
160
+
161
+ %[git clone git@github.com:#{URI.escape(repo['full_name'])}.git #{path.shellescape}]
162
+ end
163
+
164
+ end
165
+
166
+
167
+ MateBundle.start(ARGV)
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: matebundle
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - YIXI ZHANG
8
+ autorequire: matebundle
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-12-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0.18'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0.18'
27
+ description: Bundle Manager for TextMate 2
28
+ email: yixi.zhang.max@gmail.com
29
+ executables:
30
+ - matebundle
31
+ extensions: []
32
+ extra_rdoc_files:
33
+ - README.md
34
+ - LICENSE
35
+ files:
36
+ - LICENSE
37
+ - README.md
38
+ - Rakefile
39
+ - bin/matebundle
40
+ homepage: https://github.com/yixizhang/matebundle
41
+ licenses:
42
+ - MIT
43
+ metadata: {}
44
+ post_install_message:
45
+ rdoc_options: []
46
+ require_paths:
47
+ - bin
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 1.9.2
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ requirements: []
59
+ rubyforge_project:
60
+ rubygems_version: 2.1.8
61
+ signing_key:
62
+ specification_version: 4
63
+ summary: Bundle Manager for TextMate 2
64
+ test_files: []