grabass 0.0.1 → 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 (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