grabass 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|