grabass 0.1.0 → 0.2.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.
- data/bin/grabass +31 -46
- data/lib/grabass.rb +150 -104
- metadata +2 -2
data/bin/grabass
CHANGED
@@ -1,61 +1,46 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
|
4
|
-
require 'grabass'
|
3
|
+
require_relative '../lib/grabass'
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
http://github.com/brian-c/grabass
|
10
|
-
|
11
|
-
Use it like this:
|
12
|
-
grabass assets.json
|
13
|
-
# That JSON looks like this:
|
14
|
-
[{"http://some.remote/file.js": "./lib/file.js"}]
|
15
|
-
|
16
|
-
grabass http://some.remote/file.js ./lib/file.js
|
17
|
-
grabass http://some.remote/archive.zip ./lib/archive/
|
18
|
-
'''
|
5
|
+
commands = ['install', 'help']
|
6
|
+
command = ARGV.shift if commands.include? ARGV[0]
|
7
|
+
command ||= commands[0]
|
19
8
|
|
20
9
|
options = {}
|
10
|
+
options[:force] = (ARGV.delete '--force') || (ARGV.delete '-f')
|
11
|
+
options[:quiet] = (ARGV.delete '--quiet') || (ARGV.delete '-q')
|
12
|
+
options[:help] = (ARGV.delete '--help') || (ARGV.delete '-h')
|
13
|
+
options[:version] = (ARGV.delete '--version') || (ARGV.delete '-v')
|
21
14
|
|
22
|
-
|
23
|
-
|
24
|
-
args.on '-f', '--force', 'Replace existing files' do
|
25
|
-
options[:force] = true
|
26
|
-
end
|
27
|
-
options[:quiet] = false
|
28
|
-
args.on '-q', '--quiet', 'Don\'t log anything' do
|
29
|
-
options[:quiet] = true
|
30
|
-
end
|
31
|
-
end
|
15
|
+
manifest = ARGV.shift if not ARGV[0].nil? and File.exists? ARGV[0]
|
16
|
+
manifest = Grabass::AssetManifest.new manifest || 'assets.json'
|
32
17
|
|
33
|
-
|
18
|
+
destinations = ARGV
|
34
19
|
|
35
|
-
|
20
|
+
unless options[:quiet]
|
21
|
+
started = Time.now
|
22
|
+
end
|
36
23
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
24
|
+
case command
|
25
|
+
when 'help'
|
26
|
+
puts 'Help!'
|
27
|
+
when 'install'
|
28
|
+
if destinations.length == 0
|
29
|
+
# Grab entire manifest
|
30
|
+
results = manifest.install options
|
43
31
|
else
|
44
|
-
|
32
|
+
# Grab the given destinations
|
33
|
+
puts 'TODO: Install specific destinations from the command line'
|
45
34
|
exit
|
46
35
|
end
|
47
|
-
elsif ARGV.length == 2
|
48
|
-
asset = Grabass::Asset.new ARGV[0], {'*' => ARGV[1]}
|
49
|
-
results = asset.fetch options
|
50
|
-
elsif ARGV.length == 3
|
51
|
-
asset = Grabass::Asset.new ARGV[0], {ARGV[1] => ARGV[2]}
|
52
|
-
results = asset.fetch options
|
53
36
|
end
|
54
37
|
|
55
|
-
|
56
|
-
time = '%.2f' % (
|
57
|
-
pass = results[:pass]
|
58
|
-
total = pass + results[:fail]
|
38
|
+
unless options[:quiet] or results.nil?
|
39
|
+
time = '%.2f' % (Time.now - started)
|
59
40
|
|
60
|
-
|
61
|
-
|
41
|
+
pass = results[:pass]
|
42
|
+
total = pass + results[:fail]
|
43
|
+
|
44
|
+
puts "Grabass took in #{time} seconds. #{pass}/#{total} successful."
|
45
|
+
puts ''
|
46
|
+
end
|
data/lib/grabass.rb
CHANGED
@@ -14,130 +14,178 @@ class Grabass
|
|
14
14
|
"#{text}\n#{char * 72}"
|
15
15
|
end
|
16
16
|
|
17
|
-
class
|
18
|
-
|
19
|
-
|
20
|
-
def initialize(source, selections = [])
|
21
|
-
@source = source
|
22
|
-
@selections = selections # [{'pattern': 'destination'}]
|
17
|
+
class Source
|
18
|
+
def initialize(location)
|
19
|
+
@location = location
|
23
20
|
|
24
|
-
if
|
21
|
+
if @location.end_with? '.git' or Dir.exists? File.join @location, '.git'
|
25
22
|
@type = :git
|
26
|
-
elsif @
|
23
|
+
elsif @location.start_with? '/', '.', '~'
|
27
24
|
@type = :local
|
28
25
|
else
|
29
26
|
@type = :remote
|
30
27
|
end
|
31
28
|
end
|
32
29
|
|
33
|
-
def
|
34
|
-
|
35
|
-
fetch options # Get the files into the temp_dir
|
36
|
-
|
37
|
-
results = {:pass => 0, :fail => 0}
|
38
|
-
|
39
|
-
@selections.each do |selection|
|
40
|
-
pattern, destination = selection.to_a[0]
|
41
|
-
absolute_destination = File.absolute_path destination, destination_root
|
42
|
-
|
43
|
-
# TODO: Do this check before fetching things.
|
44
|
-
if File.exists? absolute_destination and not options[:force]
|
45
|
-
puts Grabass::indent "#{destination} already exists. Use --force to replace.", '!'
|
46
|
-
results[:fail] += 1
|
47
|
-
else
|
48
|
-
if File.exists? absolute_destination
|
49
|
-
puts Grabass::indent "Replacing existing #{destination}", '!' unless options[:quiet]
|
50
|
-
FileUtils.remove_entry absolute_destination, true
|
51
|
-
end
|
52
|
-
|
53
|
-
Dir.chdir temp_dir
|
54
|
-
selected_files = Dir.glob(pattern)
|
55
|
-
|
56
|
-
if selected_files.length == 1
|
57
|
-
FileUtils.makedirs File.dirname absolute_destination
|
58
|
-
`mv #{selected_files[0]} #{absolute_destination}`
|
59
|
-
else
|
60
|
-
FileUtils.makedirs absolute_destination
|
61
|
-
FileUtils.move selected_files, absolute_destination
|
62
|
-
end
|
63
|
-
|
64
|
-
results[:pass] += 1
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
puts '' unless options[:quiet] # Blank line between assets
|
69
|
-
results
|
30
|
+
def clean_up
|
31
|
+
FileUtils.rm_rf temp_dir
|
70
32
|
end
|
71
33
|
|
72
34
|
def fetch(options = {})
|
73
|
-
|
35
|
+
clean_up
|
36
|
+
FileUtils.mkdir_p temp_dir
|
74
37
|
|
75
|
-
|
76
|
-
|
38
|
+
case @type
|
39
|
+
when :local
|
40
|
+
copy_local options
|
41
|
+
when :remote
|
77
42
|
download_remote options
|
78
|
-
if is_zipped?
|
79
|
-
|
80
|
-
|
81
|
-
elsif @type == :git
|
82
|
-
clone_git_repo
|
43
|
+
unzip options if is_zipped?
|
44
|
+
when :git
|
45
|
+
clone_git_repo options
|
83
46
|
end
|
84
47
|
|
85
|
-
|
86
|
-
Dir['*']
|
48
|
+
temp_dir
|
87
49
|
end
|
88
50
|
|
89
|
-
def copy_local
|
51
|
+
def copy_local(options = {})
|
52
|
+
# TODO
|
90
53
|
end
|
91
54
|
|
92
55
|
def download_remote(options = {})
|
93
|
-
puts
|
94
|
-
|
56
|
+
puts "Downloading #{@location}" unless options[:quiet]
|
57
|
+
wd = FileUtils.pwd
|
58
|
+
FileUtils.cd temp_dir
|
59
|
+
`curl --silent --location #{@location} --remote-name --remote-header-name`
|
60
|
+
FileUtils.cd wd
|
95
61
|
end
|
96
62
|
|
97
63
|
def is_zipped?
|
98
|
-
`file --
|
64
|
+
`file --mime-type --brief #{Dir[File.join temp_dir, '*']}`.include? 'zip'
|
99
65
|
end
|
100
66
|
|
101
|
-
def unzip(options ={})
|
102
|
-
puts
|
103
|
-
|
104
|
-
|
67
|
+
def unzip(options = {})
|
68
|
+
puts "Unzipping..." unless options[:quiet]
|
69
|
+
|
70
|
+
download = Dir[File.join temp_dir, '*'][0]
|
71
|
+
`unzip #{download} -d #{temp_dir}`
|
72
|
+
FileUtils.rm download
|
105
73
|
|
106
74
|
# If the zip file expanded into a single directory (they usually do),
|
107
75
|
# bring its contents up into temp_dir
|
108
76
|
# since that's the root from which we'll make our selections
|
109
77
|
|
110
|
-
Dir.
|
111
|
-
if
|
112
|
-
single_unzipped_thing =
|
78
|
+
temp_dir_contents = Dir[File.join temp_dir, '*']
|
79
|
+
if temp_dir_contents.length == 1
|
80
|
+
single_unzipped_thing = temp_dir_contents[0]
|
81
|
+
|
113
82
|
if File.directory? single_unzipped_thing
|
114
|
-
|
115
|
-
FileUtils.
|
83
|
+
FileUtils.mv Dir[File.join single_unzipped_thing, '*'], temp_dir
|
84
|
+
FileUtils.rm_r single_unzipped_thing
|
116
85
|
end
|
117
|
-
else
|
118
|
-
puts Grabass::indent "Zip archive contained loose contents", '>' unless options[:quiet]
|
119
86
|
end
|
120
87
|
end
|
121
88
|
|
122
|
-
def clone_git_repo
|
123
|
-
puts Grabass::indent "Temporarily cloning #{@
|
124
|
-
`git clone --quiet #{@
|
89
|
+
def clone_git_repo(options = {})
|
90
|
+
puts Grabass::indent "Temporarily cloning #{@location}" unless options[:quiet]
|
91
|
+
`git clone --quiet #{@location} #{temp_dir}`
|
125
92
|
end
|
126
93
|
|
127
|
-
private
|
128
|
-
|
129
94
|
def short_name
|
130
|
-
@
|
95
|
+
@location.gsub(/\W/, '')
|
131
96
|
end
|
132
97
|
|
133
98
|
def temp_dir
|
134
|
-
|
135
|
-
|
136
|
-
|
99
|
+
File.join Grabass::temp_dir, short_name
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
class Selection
|
104
|
+
def initialize(glob, destination)
|
105
|
+
@glob, @destination = glob, destination
|
106
|
+
end
|
107
|
+
|
108
|
+
def make_from(source_dir, options)
|
109
|
+
selection = Dir[File.join source_dir, @glob]
|
110
|
+
|
111
|
+
if selection.length == 0
|
112
|
+
puts "No files selected with glob \"#{@glob}\"" unless options[:quiet]
|
113
|
+
return false
|
114
|
+
elsif selection.length == 1
|
115
|
+
puts "Moving \"#{File.basename selection[0]}\" to #{@destination}" unless options[:quiet]
|
116
|
+
|
117
|
+
if File.exists? @destination
|
118
|
+
if options[:force]
|
119
|
+
if File.directory?(selection[0]) == File.directory?(@destination)
|
120
|
+
puts "Removing existing \"#{@destination}\"..." unless options[:quiet]
|
121
|
+
FileUtils.rm_rf @destination
|
122
|
+
end
|
123
|
+
else
|
124
|
+
puts "#{@destination} already exists. Use --force to replace." unless options[:quiet]
|
125
|
+
return false
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
FileUtils.mkdir_p File.dirname @destination
|
130
|
+
FileUtils.mv selection[0], @destination
|
131
|
+
else
|
132
|
+
puts "Moving #{selection.length} \"#{@glob}\" to #{@destination}" unless options[:quiet]
|
133
|
+
|
134
|
+
failures = 0
|
135
|
+
selection.each do |file|
|
136
|
+
destination_file = File.join @destination, file.sub(source_dir, '')
|
137
|
+
if File.exists? destination_file
|
138
|
+
if options[:force]
|
139
|
+
if File.directory?(file) == File.directory?(destination_file)
|
140
|
+
puts "Removing \"#{destination_file}\"..." unless options[:quiet]
|
141
|
+
FileUtils.rm_rf destination_file
|
142
|
+
end
|
143
|
+
else
|
144
|
+
puts "#{destination_file} already exists. Use --force to replace." unless options[:quiet]
|
145
|
+
failures += 1
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
return false if failures > 0
|
151
|
+
|
152
|
+
FileUtils.mkdir_p @destination
|
153
|
+
FileUtils.mv selection, @destination
|
154
|
+
end
|
155
|
+
|
156
|
+
true
|
137
157
|
end
|
158
|
+
end
|
159
|
+
|
160
|
+
class Asset
|
161
|
+
def initialize(source, selections)
|
162
|
+
@source = Source.new(source)
|
138
163
|
|
139
|
-
|
140
|
-
|
164
|
+
@selections = []
|
165
|
+
selections.each do |selection|
|
166
|
+
selection.each do |glob, destination|
|
167
|
+
@selections << Selection.new(glob, destination)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def install(options = {})
|
173
|
+
results = {:pass => 0, :fail => 0}
|
174
|
+
|
175
|
+
source_dir = @source.fetch
|
176
|
+
|
177
|
+
@selections.each do |selection|
|
178
|
+
success = selection.make_from source_dir, options
|
179
|
+
|
180
|
+
if success
|
181
|
+
results[:pass] += 1
|
182
|
+
else
|
183
|
+
results[:fail] += 1
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
puts '' unless options[:quiet] # Blank line between assets
|
188
|
+
results
|
141
189
|
end
|
142
190
|
end
|
143
191
|
|
@@ -147,26 +195,28 @@ class Grabass
|
|
147
195
|
end
|
148
196
|
|
149
197
|
def display(options)
|
150
|
-
puts
|
198
|
+
puts @content unless options[:quiet]
|
151
199
|
end
|
152
200
|
end
|
153
201
|
|
154
202
|
class AssetManifest
|
155
203
|
def initialize(filename)
|
156
204
|
@filename = filename
|
157
|
-
|
205
|
+
root = File.dirname File.absolute_path filename
|
158
206
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
Comment.new record
|
207
|
+
@assets = JSON.parse(File.read @filename).map do |item|
|
208
|
+
if item.is_a? String
|
209
|
+
Comment.new item
|
163
210
|
else
|
164
|
-
source, selections =
|
211
|
+
source, selections = item.to_a[0]
|
165
212
|
|
166
|
-
if selections.is_a? String
|
167
|
-
|
168
|
-
|
169
|
-
|
213
|
+
selections = {'*' => selections} if selections.is_a? String
|
214
|
+
selections = [selections] if selections.is_a? Hash
|
215
|
+
|
216
|
+
selections.map! do |selection|
|
217
|
+
selection.each do |glob, destination|
|
218
|
+
selection[glob] = File.absolute_path destination, root
|
219
|
+
end
|
170
220
|
end
|
171
221
|
|
172
222
|
Asset.new source, selections
|
@@ -174,20 +224,16 @@ class Grabass
|
|
174
224
|
end
|
175
225
|
end
|
176
226
|
|
177
|
-
def
|
178
|
-
|
227
|
+
def install(options = {})
|
228
|
+
puts "Installing assets from #{@filename}", '' unless options[:quiet]
|
179
229
|
|
180
|
-
|
181
|
-
puts ''
|
182
|
-
puts Grabass::underline "Fetching assets from #{@filename}", '='
|
183
|
-
puts ''
|
184
|
-
end
|
230
|
+
results = {:pass => 0, :fail => 0}
|
185
231
|
|
186
|
-
@
|
187
|
-
if
|
188
|
-
|
189
|
-
elsif
|
190
|
-
asset_results =
|
232
|
+
@assets.each do |asset|
|
233
|
+
if asset.is_a? Comment
|
234
|
+
asset.display options
|
235
|
+
elsif asset.is_a? Asset
|
236
|
+
asset_results = asset.install options
|
191
237
|
results[:pass] += asset_results[:pass]
|
192
238
|
results[:fail] += asset_results[:fail]
|
193
239
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: grabass
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-03-
|
12
|
+
date: 2012-03-26 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Grab static assets and put them somewhere
|
15
15
|
email: brian.carstensen@gmail.com
|