grabass 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/bin/grabass +16 -10
  2. data/lib/grabass.rb +154 -75
  3. metadata +2 -2
@@ -1,8 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'optparse'
4
- require 'json'
5
- require 'fileutils'
6
4
  require 'grabass'
7
5
 
8
6
  ABOUT = '''
@@ -26,6 +24,10 @@ optparse = OptionParser.new do |args|
26
24
  args.on '-f', '--force', 'Replace existing files' do
27
25
  options[:force] = true
28
26
  end
27
+ options[:quiet] = false
28
+ args.on '-q', '--quiet', 'Don\'t log anything' do
29
+ options[:quiet] = true
30
+ end
29
31
  end
30
32
 
31
33
  optparse.parse!
@@ -37,19 +39,23 @@ if ARGV.length == 0
37
39
  elsif ARGV.length == 1
38
40
  if File.exists? ARGV[0]
39
41
  manifest = Grabass::AssetManifest.new ARGV[0]
40
- manifest.fetch(options)
41
- finished = Time.now
42
+ results = manifest.grab options
42
43
  else
43
44
  puts "Asset manifest \"#{ARGV[0]}\" not found."
45
+ exit
44
46
  end
45
47
  elsif ARGV.length == 2
46
- asset = Grabass::Asset.new ARGV[0], ARGV[1]
47
- asset.fetch(options)
48
- finished = Time.now
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
49
53
  end
50
54
 
51
- if finished
52
- puts '', "Grabass took in #{'%.2f' % (finished - started)} seconds."
53
- end
55
+ finished = Time.now
56
+ time = '%.2f' % (finished - started)
57
+ pass = results[:pass]
58
+ total = pass + results[:fail]
54
59
 
60
+ puts "Grabass took in #{time} seconds. #{pass}/#{total} successful."
55
61
  puts ''
@@ -1,120 +1,199 @@
1
- #!/usr/bin/env ruby
2
-
3
1
  require 'json'
4
2
  require 'fileutils'
5
3
 
6
- module Grabass
7
- def self.underline(string, char = '-')
8
- "#{string}\n#{char * (string.length / char.length)}"
4
+ class Grabass
5
+ def self.temp_dir
6
+ File.join ENV['TMPDIR'], 'grabass'
9
7
  end
10
8
 
11
- def self.indent(string, prefix = '', spaces = 2)
12
- prefix + (' ' * (spaces - prefix.length)) + string
9
+ def self.indent(text, prefix = '', spaces = 2)
10
+ prefix + (' ' * (spaces - prefix.length)) + text
13
11
  end
14
12
 
15
- SCRIPT_DIR = File.dirname __FILE__
16
- TEMP_DIR = "#{SCRIPT_DIR}/_grabass_temp"
13
+ def self.underline(text, char = '-')
14
+ "#{text}\n#{char * 72}"
15
+ end
17
16
 
18
- class AssetManifest
19
- def initialize(filename)
20
- @filename = filename
17
+ class Asset
18
+ attr_accessor :source, :selections, :type
21
19
 
22
- @assets = JSON.parse File.read filename
23
- @assets.map! do |definition|
24
- source = definition.keys[0]
25
- destination = definition[source]
20
+ def initialize(source, selections = [])
21
+ @source = source
22
+ @selections = selections # [{'pattern': 'destination'}]
26
23
 
27
- Asset.new source, destination
24
+ if source.end_with? '.git' or Dir.exists? File.join @source, '.git'
25
+ @type = :git
26
+ elsif @source.start_with? '/', '.', '~'
27
+ @type = :local
28
+ else
29
+ @type = :remote
28
30
  end
29
31
  end
30
32
 
31
- def fetch(options)
32
- puts ''
33
- puts Grabass::underline "Fetching assets from #{@filename}", '='
33
+ def grab(destination_root, options = {})
34
+ puts Grabass::underline @source unless options[:quite]
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
34
42
 
35
- @assets.each do |asset|
36
- asset.fetch options
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
37
66
  end
67
+
68
+ puts '' unless options[:quiet] # Blank line between assets
69
+ results
38
70
  end
39
- end
40
71
 
41
- class Asset
42
- def initialize(source, destination)
43
- @source, @destination = source, destination
44
- @temp_file = TEMP_DIR + '/' + source.gsub(/\W+/, '-')
72
+ def fetch(options = {})
73
+ `rm -rf #{temp_dir}`
74
+
75
+ if @type == :local
76
+ elsif @type == :remote
77
+ download_remote options
78
+ if is_zipped?
79
+ unzip
80
+ end
81
+ elsif @type == :git
82
+ clone_git_repo
83
+ end
84
+
85
+ Dir.chdir temp_dir
86
+ Dir['*']
45
87
  end
46
88
 
47
- def fetch(options)
48
- FileUtils.remove_dir TEMP_DIR if File.exists? TEMP_DIR
49
- FileUtils.mkpath TEMP_DIR
89
+ def copy_local
90
+ end
50
91
 
51
- puts ''
52
- puts Grabass::underline @source
92
+ def download_remote(options = {})
93
+ puts Grabass::indent "Downloading #{@source}" unless options[:quiet]
94
+ `curl --silent --location #{@source} --output #{temp_file}`
95
+ end
53
96
 
54
- if not options[:force] and File.exists? @destination
55
- puts Grabass::indent 'Destination file already exists!', '!'
56
- puts Grabass::indent 'Use the --force option to overwrite it.'
57
- else
58
- if download
59
- unzip if mime_type.include? 'zip'
60
- move_to_destination options[:force]
61
- else
62
- puts Grabass::indent 'Download failed!', '!'
97
+ def is_zipped?
98
+ `file --brief --mime-type #{temp_file}`.include? 'zip'
99
+ end
100
+
101
+ def unzip(options ={})
102
+ puts Grabass::indent "Unzipping..." unless options[:quiet]
103
+ `unzip #{temp_file} -d #{temp_dir}`
104
+ FileUtils.remove temp_file
105
+
106
+ # If the zip file expanded into a single directory (they usually do),
107
+ # bring its contents up into temp_dir
108
+ # since that's the root from which we'll make our selections
109
+
110
+ Dir.chdir temp_dir
111
+ if Dir['*'].length == 1
112
+ single_unzipped_thing = Dir['*'][0]
113
+ if File.directory? single_unzipped_thing
114
+ `mv #{File.join temp_dir, single_unzipped_thing, '*'} #{temp_dir}`
115
+ FileUtils.remove_dir single_unzipped_thing
63
116
  end
117
+ else
118
+ puts Grabass::indent "Zip archive contained loose contents", '>' unless options[:quiet]
64
119
  end
120
+ end
65
121
 
66
- FileUtils.remove_dir TEMP_DIR
122
+ def clone_git_repo
123
+ puts Grabass::indent "Temporarily cloning #{@source}" unless options[:quiet]
124
+ `git clone --quiet #{@source} #{temp_dir}`
67
125
  end
68
126
 
69
- def download
70
- puts Grabass::indent "Downloading #{@source}"
71
- `curl --silent --location #{@source} --output "#{@temp_file}"`
72
- File.exists? @temp_file
127
+ private
128
+
129
+ def short_name
130
+ @source.gsub(/\W/, '')
73
131
  end
74
132
 
75
- def mime_type
76
- `file --brief --mime-type #{@temp_file}`
133
+ def temp_dir
134
+ holding = File.join Grabass::temp_dir, short_name
135
+ FileUtils.makedirs holding
136
+ holding
77
137
  end
78
138
 
79
- def unzip
80
- puts Grabass::indent 'Unzipping...'
139
+ def temp_file
140
+ File.join temp_dir, short_name
141
+ end
142
+ end
81
143
 
82
- # Remember what files exist now so we can see exactly what gets unzipped.
83
- originals = Dir.entries TEMP_DIR
144
+ class Comment
145
+ def initialize(content)
146
+ @content = content
147
+ end
84
148
 
85
- `unzip #{@temp_file} -d #{TEMP_DIR}`
149
+ def display(options)
150
+ puts Grabass::underline @content unless options[:quiet]
151
+ end
152
+ end
86
153
 
87
- FileUtils.rm "#{@temp_file}"
154
+ class AssetManifest
155
+ def initialize(filename)
156
+ @filename = filename
157
+ @root = File.absolute_path File.dirname filename
88
158
 
89
- new_files = Dir.entries(TEMP_DIR) - originals
90
- new_files.map! do |filename|
91
- "#{TEMP_DIR}/#{filename}"
92
- end
159
+ records = JSON.parse File.read @filename
160
+ @records = records.map do |record|
161
+ if record.is_a? String
162
+ Comment.new record
163
+ else
164
+ source, selections = record.to_a[0]
93
165
 
94
- if new_files.length == 1
95
- # Rename to the original temp name if the zip only unzipped one thing.
96
- FileUtils.move new_files[0], @temp_file
97
- else
98
- # Pack more than one thing into a single directory with the temp name.
99
- FileUtils.mkpath @temp_file
100
- FileUtils.move new_files, @temp_file
166
+ if selections.is_a? String
167
+ selections = [{'*' => selections}]
168
+ elsif selections.is_a? Hash
169
+ selections = [selections]
170
+ end
171
+
172
+ Asset.new source, selections
173
+ end
101
174
  end
102
175
  end
103
176
 
104
- def move_to_destination(force)
105
- if File.exists? @destination and force
106
- puts Grabass::indent "Replacing existing #{@destination}"
177
+ def grab(options = {})
178
+ results = {:pass => 0, :fail => 0}
107
179
 
108
- if Dir.exists? @destination
109
- FileUtils.remove_dir @destination
110
- else
111
- FileUtils.remove @destination
180
+ unless options[:quiet]
181
+ puts ''
182
+ puts Grabass::underline "Fetching assets from #{@filename}", '='
183
+ puts ''
184
+ end
185
+
186
+ @records.each do |record|
187
+ if record.is_a? Comment
188
+ record.display options
189
+ elsif record.is_a? Asset
190
+ asset_results = record.grab @root, options
191
+ results[:pass] += asset_results[:pass]
192
+ results[:fail] += asset_results[:fail]
112
193
  end
113
194
  end
114
195
 
115
- puts Grabass::indent "Moving to #{@destination}..."
116
- FileUtils.mkpath(File.dirname(@destination))
117
- FileUtils.move @temp_file, @destination
196
+ results
118
197
  end
119
198
  end
120
199
  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.0.1
4
+ version: 0.1.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-02-25 00:00:00.000000000 Z
12
+ date: 2012-03-11 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