Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
seamusabshere committed Feb 11, 2012
0 parents commit 5fb9ccf
Show file tree
Hide file tree
Showing 20 changed files with 516 additions and 0 deletions.
17 changes: 17 additions & 0 deletions .gitignore
@@ -0,0 +1,17 @@
*.gem
*.rbc
.bundle
.config
.yardoc
Gemfile.lock
InstalledFiles
_yardoc
coverage
doc/
lib/bundler/man
pkg
rdoc
spec/reports
test/tmp
test/version_tmp
tmp
7 changes: 7 additions & 0 deletions Gemfile
@@ -0,0 +1,7 @@
source :rubygems

gemspec

# development dependencies
gem 'minitest'
gem 'minitest-reporters'
22 changes: 22 additions & 0 deletions README.markdown
@@ -0,0 +1,22 @@
# unix_utils

Dead simple access to bzip2, bunzip2, tar, untar, du, sha256, etc.

TODO: md5, wc, etc.

## Philosophy

* Give a path, get a path (bzip2, bunzip2, etc.)
* Only return the good part (sha256, du, etc.)

## Spawning

Uses `open3` because it's the most consistent interface across MRI 1.8, 1.9 and JRuby.

## Authors

* Seamus Abshere <seamus@abshere.net>

## Copyright

Copyright (c) 2012 Brighter Planet. See LICENSE for details.
12 changes: 12 additions & 0 deletions Rakefile
@@ -0,0 +1,12 @@
#!/usr/bin/env rake
require "bundler/gem_tasks"

require 'rake'
require 'rake/testtask'
Rake::TestTask.new(:test) do |test|
test.libs << 'lib' << 'test'
test.pattern = 'test/**/test_*.rb'
test.verbose = true
end

task :default => :test
209 changes: 209 additions & 0 deletions lib/unix_utils.rb
@@ -0,0 +1,209 @@
require 'fileutils'
require 'tmpdir'
require 'uri'
require 'open3'

require "unix_utils/version"

module UnixUtils

def self.curl(url, form_data = nil)
out_path = tmp_path url
if url.start_with?('/') or url.start_with?('file://')
# deal with local files
::FileUtils.cp url.sub('file://', ''), path
return out_path
end
uri = ::URI.parse url
argv = [ 'curl', '--location', '--show-error', '--silent', '--compressed', '--header', 'Expect: ' ]
if form_data
argv += [ '--data', form_data ]
end
argv += [ uri.to_s, '--output', out_path ]
spawn *argv
out_path
end

def self.sha256(in_path)
stdout = spawn 'shasum', '-a', '256', :stdin => in_path
stdout.chomp.split(/\s+/).first
end

def self.du(in_dir)
stdout = spawn 'du', in_dir
stdout.chomp.split(/\s+/).first.to_i
end

# --

def self.unzip(in_path)
out_dir = tmp_path in_path
::FileUtils.mkdir out_dir
spawn 'unzip', '-qq', '-n', in_path, '-d', out_dir
out_dir
end

def self.untar(in_path)
out_dir = tmp_path in_path
::FileUtils.mkdir out_dir
spawn 'tar', '-xf', in_path, '-C', out_dir
out_dir
end

def self.gunzip(in_path)
out_path = tmp_path in_path
spawn 'gunzip', '--stdout', in_path, :stdout => out_path
out_path
end

def self.bunzip2(in_path)
out_path = tmp_path in_path
spawn 'bunzip2', '--stdout', in_path, :stdout => out_path
out_path
end

# --

def self.bzip2(in_path)
out_path = tmp_path in_path
spawn 'bzip2', '--keep', '--stdout', in_path, :stdout => out_path
out_path
end

def self.tar(in_dir)
out_path = tmp_path in_dir
spawn 'tar', '-cf', out_path, '-C', in_dir, '.'
out_path
end

def self.zip(in_dir)
out_path = tmp_path in_dir, 'zip'
spawn 'zip', '-rq', out_path, '.', :chdir => in_dir
out_path
end

def self.gzip(in_path)
out_path = tmp_path in_path
spawn 'gzip', '--stdout', in_path, :stdout => out_path
out_path
end
#
# # use awk to convert [CR]LF to CRLF
# def self.unix2dos(path)
# out_path = tmp_path
# ::File.open(out_path, 'wb') do |out|
# see also the simpler version
# pid = ::POSIX::Spawn.spawn 'awk', '{ sub(/\r?$/,"\r"); print }', path, :out => out
# ::Process.waitpid pid
# end
# ::FileUtils.mv out_path, path
# path
# end


#
#
#
#
# 'wc', '-l', in_path).split(/\s+/)[0].try :to_i
#
# sha1sum
# bang('sha1sum', in_path)[0..39]
#
#
# def self.in_place(*args)
# options = args.extract_options!
# in_path = args.shift
# argv = args
# out_path = tmp_path in_path
# ::File.open(in_path, 'r') do |f0|
# ::File.open(out_path, 'wb') do |f1|
# spawn *argv, :in => f0, :out => f1
# end
# end
# ::FileUtils.mv out_path, in_path
# nil
# rescue SpawnError => e
# if options[:ignore_error]
# $stderr.puts "#{e.inspect} (ignoring error...)"
# ::FileUtils.mv out_path, in_path
# else
# raise e
# end
# end
# #
# #
# gsed "s/#{quoted_clone_name.gsub('`', %{\\\\`})}/#{resource_model.quoted_table_name.gsub('`', %{\\\\`})}/g" --in-place="" #{p}}
#
# # use awk to convert [CR]LF to CRLF
# def self.unix2dos(in_path)
# in_place 'awk', '{ sub(/\r?$/,"\r"); print }', in_path
# end

# mostly for internal use...

def self.tmp_path(ancestor, extname = nil)
basename = ::File.basename ancestor.gsub(/\W+/, '_')
basename.sub!(/^unix_utils-[0-9]+-/, '')
if extname
basename.concat ".#{extname}"
end
::Kernel.srand
::File.join ::Dir.tmpdir, "unix_utils-#{::Kernel.rand(1e11)}-#{basename}"
end

def self.spawn(*argv)
argv = argv.dup
options = argv.last.is_a?(::Hash) ? argv.pop : {}

if options[:chdir]
old_pwd = ::Dir.pwd
::Dir.chdir options[:chdir]
end

whole_stdout = nil
whole_stderr = nil

if options[:stdin]
::File.open(options[:stdin], 'r') do |in_f|
::Open3.popen3(*argv) do |stdin, stdout, stderr|
while chunk = in_f.read(4_194_304)
stdin.write chunk
end
stdin.close
whole_stdout = stdout.read
whole_stderr = stderr.read
end
end
elsif options[:stdout]
::File.open(options[:stdout], 'wb') do |out_f|
::Open3.popen3(*argv) do |stdin, stdout, stderr|
stdin.close
while chunk = stdout.read(4_194_304)
out_f.write chunk
end
whole_stdout = "Redirected to #{options[:stdout]}"
whole_stderr = stderr.read
end
end
else
::Open3.popen3(*argv) do |stdin, stdout, stderr|
stdin.close
whole_stdout = stdout.read
whole_stderr = stderr.read
end
end

unless whole_stderr.empty?
$stderr.puts "[unix_utils] `#{argv.join(' ')}` STDERR:"
$stderr.puts whole_stderr
end

whole_stdout

ensure
if options[:chdir]
::Dir.chdir old_pwd
end
end
end
3 changes: 3 additions & 0 deletions lib/unix_utils/version.rb
@@ -0,0 +1,3 @@
module UnixUtils
VERSION = "0.0.1"
end
Binary file added test/.DS_Store
Binary file not shown.
75 changes: 75 additions & 0 deletions test/helper.rb
@@ -0,0 +1,75 @@
require 'bundler/setup'

require 'minitest/spec'
require 'minitest/autorun'
require 'minitest/reporters'
MiniTest::Unit.runner = MiniTest::SuiteRunner.new
MiniTest::Unit.runner.reporters << MiniTest::Reporters::SpecReporter.new

$LOAD_PATH.unshift(File.dirname(__FILE__))
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
require 'unix_utils'

READY_MADE_DIR = ::File.expand_path('../ready_made', __FILE__)
TO_BE_PROCESSED_DIR = ::File.expand_path('../to_be_processed', __FILE__)
ZIP_SHA256 = '661af2b7b0993088263228b071b649a88d82a6a655562162c32307d1e127f27a'
DIR_SIZE = 16
ARCHIVE_ENTRIES = %w{ . .. hello_world.txt hello_world.xml }

require 'fileutils'
require 'tmpdir'

module TestHelper
extend self

def ready_made(method_id_or_extname)
::File.join READY_MADE_DIR, "#{what_do_i_hold(method_id_or_extname)}.#{extname(method_id_or_extname)}"
end

def anonymous_ready_made(method_id_or_extname)
::File.join READY_MADE_DIR, "#{what_do_i_hold(method_id_or_extname)}-really-a-#{extname(method_id_or_extname).to_s.chars.to_a.join('_')}-shh"
end

def to_be_processed(method_id_or_extname)
return TO_BE_PROCESSED_DIR if method_id_or_extname == :dir

case what_do_i_hold(method_id_or_extname)
when :file
::File.join TO_BE_PROCESSED_DIR, 'hello_world.txt'
when :directory
TO_BE_PROCESSED_DIR
end
end

def extname(method_id_or_extname)
case method_id_or_extname.to_s.downcase
when /b.*z/
:bz2
when /g.*z/
:gz
when /tar/
:tar
when /zip/
:zip
end
end

def what_do_i_hold(method_id_or_extname)
case method_id_or_extname.to_s.downcase
when /b.*z/, /g.*z/
:file
when /zip/, /tar/
:directory
end
end

def rm_rf(path)
path = File.expand_path path
raise "Refusing to rm_rf #{path} because it's not in #{Dir.tmpdir}" unless File.dirname(path).start_with?(Dir.tmpdir)
FileUtils.rm_rf path
end
end

class MiniTest::Spec
include TestHelper
end
Binary file added test/ready_made/directory-really-a-t_a_r-shh
Binary file not shown.
Binary file added test/ready_made/directory-really-a-z_i_p-shh
Binary file not shown.
Binary file added test/ready_made/directory.tar
Binary file not shown.
Binary file added test/ready_made/directory.zip
Binary file not shown.
Binary file added test/ready_made/file-really-a-b_z_2-shh
Binary file not shown.
Binary file added test/ready_made/file-really-a-g_z-shh
Binary file not shown.
Binary file added test/ready_made/file.bz2
Binary file not shown.
Binary file added test/ready_made/file.gz
Binary file not shown.

0 comments on commit 5fb9ccf

Please sign in to comment.