blackwinter-pru 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source :rubygems
2
+
3
+ group :dev do # not development <-> would add unneeded development dependencies in gemspec
4
+ gem 'rake'
5
+ gem 'rspec', '~>2'
6
+ gem 'jeweler'
7
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,26 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ diff-lcs (1.1.2)
5
+ git (1.2.5)
6
+ jeweler (1.5.2)
7
+ bundler (~> 1.0.0)
8
+ git (>= 1.2.5)
9
+ rake
10
+ rake (0.8.7)
11
+ rspec (2.4.0)
12
+ rspec-core (~> 2.4.0)
13
+ rspec-expectations (~> 2.4.0)
14
+ rspec-mocks (~> 2.4.0)
15
+ rspec-core (2.4.0)
16
+ rspec-expectations (2.4.0)
17
+ diff-lcs (~> 1.1.2)
18
+ rspec-mocks (2.4.0)
19
+
20
+ PLATFORMS
21
+ ruby
22
+
23
+ DEPENDENCIES
24
+ jeweler
25
+ rake
26
+ rspec (~> 2)
data/Rakefile ADDED
@@ -0,0 +1,22 @@
1
+ begin
2
+ require 'jeweler'
3
+
4
+ Jeweler::Tasks.new { |gem|
5
+ gem.name = 'blackwinter-pru'
6
+ gem.summary = 'Pipeable Ruby - forget about grep/sed/awk/wc... use pure, readable Ruby!'
7
+ gem.email = 'michael@grosser.it'
8
+ gem.homepage = "http://github.com/grosser/#{gem.name}"
9
+ gem.authors = ['Michael Grosser']
10
+ }
11
+
12
+ Jeweler::GemcutterTasks.new
13
+ rescue LoadError
14
+ puts 'Jeweler, or one of its dependencies, is not available. Install it with: gem install jeweler'
15
+ end
16
+
17
+ desc 'Run specs'
18
+ task :spec do
19
+ sh 'rspec spec/'
20
+ end
21
+
22
+ task :default => :spec
data/Readme.md ADDED
@@ -0,0 +1,71 @@
1
+ Pipeable Ruby - forget about grep / sed / awk / wc ... use pure, readable Ruby!
2
+
3
+ Install
4
+ =======
5
+ sudo gem install pru
6
+
7
+ Working with rvm / many gemsets -> only install once (1.9 recommended)
8
+
9
+ rvm 1.9.2 exec gem install pru
10
+ echo 'alias pru="rvm 1.9.2 exec pru"' >> ~/.bash_profile
11
+
12
+ Usage
13
+ =====
14
+ pru supports mapping and reducing.<br/><br/>
15
+ Map works on each line as String<br/>
16
+ Reduce works on all lines as Array<br/>
17
+
18
+ something | pru 'map' ['reduce']
19
+ something | pru -r 'reduce'
20
+
21
+ ### Examples
22
+
23
+ # grep --- all lines including foo
24
+ ls -al | grep foo
25
+ ls -al | pru /foo/
26
+
27
+ # grep --- all lines including current date
28
+ ls -al | grep $(date +"%Y-%m-%d")
29
+ ls -al | pru 'include?(Time.now.strftime("%Y-%m-%d"))'
30
+
31
+ # grep --- all lines including foo but not self
32
+ ps -ef | grep foo | grep -v grep
33
+ ps -ef | pru 'include?("foo") and not include?("pru")'
34
+
35
+ # awk --- return second item
36
+ ls -al | awk '{print $2}'
37
+ ls -al | pru 'split(" ")[1]'
38
+
39
+ # awk --- count and average of all integers on second position
40
+ ls -al | awk '{ s += $2; } END {print "average" ,int(s/NR);print "count ",int(NR)}'
41
+ ls -al | pru 'split(" ")[1]' '"average #{mean(&:to_i)}\ncount #{size}"'
42
+
43
+ # wc --- count lines
44
+ ls -al | wc -l
45
+ ls -al | pru -r 'size'
46
+
47
+ # sed -- replace a 5 with five
48
+ ls -al | sed 's/5/five/'
49
+ ls -al | pru 'gsub(/5/,"five")'
50
+
51
+ # every second line
52
+ ls -al | pru 'i % 2 == 0'
53
+
54
+ # paste-friendly mime-types
55
+ curl https://github.com/mattetti/mimetype-fu/raw/master/lib/mime_types.yml | grep image | pru 'gsub(/(.*): (.*)/, %{"\\1" => "\\2",})'
56
+
57
+ # number of files by date:
58
+ ls -al | pru 'split(" ")[5]' 'grouped.map{|d, f| "#{d} : #{f.size}" }'
59
+
60
+ # quotes inside a string
61
+ something | pru 'include?(%{"string"})'
62
+
63
+ Authors
64
+ =======
65
+ ### [Contributors](http://github.com/grosser/pru/contributors)
66
+ - [John Hobbs](http://github.com/jmhobbs)
67
+ - [Vasiliy Ermolovich](http://github.com/nashby)
68
+
69
+ [Michael Grosser](http://grosser.it)<br/>
70
+ michael@grosser.it<br/>
71
+ Hereby placed under public domain, do what you want, just do not hold me accountable...
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.4
data/bin/pru ADDED
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ autoload :Pru, 'pru'
4
+ require 'optparse'
5
+
6
+ usage = <<-EOS
7
+ Pipeable Ruby
8
+
9
+ Use ruby in your pipes, forget about grep/sed/awk/wc...
10
+
11
+ Map works on each line as String.
12
+ Reduce works on all lines as Array (optional or via -e/-f).
13
+
14
+ Usage:
15
+ something | pru 'map' ['reduce']
16
+ something | pru -e 'reduce'
17
+ EOS
18
+
19
+ options = {}
20
+
21
+ OptionParser.new { |opts|
22
+ opts.banner = usage
23
+
24
+ opts.separator ''
25
+ opts.separator 'Options:'
26
+
27
+ opts.on('-m', '--map-file FILE', 'Map via FILE') { |file|
28
+ options[:map] = Pru::Helper.load_file(file, :map)
29
+ }
30
+
31
+ opts.separator ''
32
+
33
+ opts.on('-e', '--execute CODE', 'Reduce via CODE') { |code|
34
+ options[:reduce] = code
35
+ }
36
+
37
+ opts.on('-f', '--reduce-file FILE', 'Reduce via FILE') { |file|
38
+ options[:reduce] = Pru::Helper.load_file(file, :reduce)
39
+ }
40
+
41
+ opts.separator ''
42
+ opts.separator 'Load options:'
43
+
44
+ opts.on('-I', '--libdir LIBDIR', 'Include LIBDIR in the search path for required modules') { |dir|
45
+ $LOAD_PATH << dir
46
+ }
47
+
48
+ opts.on('-r', '--require MODULE', 'Require MODULE before executing any code') { |mod|
49
+ require mod
50
+ }
51
+
52
+ opts.separator ''
53
+ opts.separator 'Generic options:'
54
+
55
+ opts.on('-h', '--help', 'Print this help message and exit') {
56
+ puts opts
57
+ exit
58
+ }
59
+
60
+ opts.on('--version', 'Print program version and exit') {
61
+ puts "#{File.basename($0)} v#{Pru::VERSION}"
62
+ exit
63
+ }
64
+ }.parse!
65
+
66
+ abort usage if ARGV.size > 2
67
+ map, reduce = ARGV
68
+
69
+ map ||= options[:map]
70
+ reduce ||= options[:reduce]
71
+
72
+ map = 'true' if map.nil? || map.strip.empty?
73
+
74
+ if reduce
75
+ results = []
76
+ Pru.map($stdin, map) { |x| results << x }
77
+ puts Pru.reduce(results, reduce)
78
+ else
79
+ Pru.map($stdin, map) { |x| puts x }
80
+ end
data/lib/pru.rb ADDED
@@ -0,0 +1,26 @@
1
+ require 'pru/helper'
2
+ require 'pru/core_ext'
3
+
4
+ module Pru
5
+
6
+ extend self
7
+
8
+ VERSION = File.read(File.join(File.dirname(__FILE__), '..', 'VERSION')).strip
9
+
10
+ def map(io, code)
11
+ io.each_line { |line|
12
+ line.chomp!
13
+
14
+ case result = line.instance_eval(code) or next
15
+ when true then yield line
16
+ when Regexp then yield line if line =~ result
17
+ else yield result
18
+ end
19
+ }
20
+ end
21
+
22
+ def reduce(array, code)
23
+ array.instance_eval(code)
24
+ end
25
+
26
+ end
@@ -0,0 +1,2 @@
1
+ require 'pru/core_ext/array'
2
+ require 'pru/core_ext/symbol'
@@ -0,0 +1,29 @@
1
+ class Array
2
+
3
+ # http://madeofcode.com/posts/74-ruby-core-extension-array-sum
4
+ def sum(method = nil)
5
+ if block_given?
6
+ raise ArgumentError, 'You cannot pass both a block and a method' if method
7
+ inject(0) { |s, x| s + yield(x) }
8
+ elsif method
9
+ inject(0) { |s, x| s + x.send(method) }
10
+ else
11
+ inject(0) { |s, x| s + x }
12
+ end
13
+ end unless method_defined?(:sum)
14
+
15
+ def mean(method = nil, &block)
16
+ sum(method, &block) / size.to_f
17
+ end unless method_defined?(:mean)
18
+
19
+ def grouped
20
+ group_by { |x| x }
21
+ end unless method_defined?(:grouped)
22
+
23
+ def group_by
24
+ hash = {}
25
+ each { |x| hash[yield(x)] = x }
26
+ hash
27
+ end unless method_defined?(:group_by)
28
+
29
+ end
@@ -0,0 +1,7 @@
1
+ class Symbol
2
+
3
+ def to_proc
4
+ proc { |obj, *args| obj.send(self, *args) }
5
+ end unless method_defined?(:to_proc)
6
+
7
+ end
data/lib/pru/helper.rb ADDED
@@ -0,0 +1,41 @@
1
+ module Pru
2
+
3
+ module Helper
4
+
5
+ extend self
6
+
7
+ EXTENSIONS = ['', '.pru', '.rb']
8
+
9
+ def load_file(file, type)
10
+ if _file = find_file(file)
11
+ file = _file
12
+ else
13
+ home = begin
14
+ require 'nuggets/env/user_home'
15
+ ENV.user_home
16
+ rescue LoadError
17
+ File.expand_path('~')
18
+ end
19
+
20
+ if _file = find_file(File.join(home, '.pru', type.to_s, file))
21
+ file = _file
22
+ end
23
+ end
24
+
25
+ begin
26
+ File.read(file)
27
+ rescue => err
28
+ abort "#{$0}: #{err}"
29
+ end
30
+ end
31
+
32
+ def find_file(file, extensions = EXTENSIONS)
33
+ extensions.find { |extension|
34
+ _file = file + extension
35
+ return _file if File.exist?(_file)
36
+ }
37
+ end
38
+
39
+ end
40
+
41
+ end
data/pru.gemspec ADDED
@@ -0,0 +1,48 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{pru}
8
+ s.version = "0.1.4"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Michael Grosser"]
12
+ s.date = %q{2011-04-21}
13
+ s.default_executable = %q{pru}
14
+ s.email = %q{michael@grosser.it}
15
+ s.executables = ["pru"]
16
+ s.files = [
17
+ "Gemfile",
18
+ "Gemfile.lock",
19
+ "Rakefile",
20
+ "Readme.md",
21
+ "VERSION",
22
+ "bin/pru",
23
+ "lib/pru.rb",
24
+ "lib/pru/core_ext.rb",
25
+ "pru.gemspec",
26
+ "spec/pru_spec.rb",
27
+ "spec/spec_helper.rb",
28
+ "spec/test.txt"
29
+ ]
30
+ s.homepage = %q{http://github.com/grosser/pru}
31
+ s.require_paths = ["lib"]
32
+ s.rubygems_version = %q{1.4.2}
33
+ s.summary = %q{Pipeable Ruby - forget about grep / sed / awk / wc ... use pure, readable Ruby!}
34
+ s.test_files = [
35
+ "spec/pru_spec.rb",
36
+ "spec/spec_helper.rb"
37
+ ]
38
+
39
+ if s.respond_to? :specification_version then
40
+ s.specification_version = 3
41
+
42
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
43
+ else
44
+ end
45
+ else
46
+ end
47
+ end
48
+
data/spec/pru_spec.rb ADDED
@@ -0,0 +1,79 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ describe Pru do
4
+
5
+ it 'has a VERSION' do
6
+ Pru::VERSION.should =~ /\A\d+\.\d+\.\d+\z/
7
+ end
8
+
9
+ describe 'map' do
10
+
11
+ it 'selects' do
12
+ %x{ls -l | #{PRU_CMD} 'include?("G")'}.split($/).size.should == 2
13
+ end
14
+
15
+ it 'selects via regex' do
16
+ %x{ls -l | #{PRU_CMD} /G/}.split($/).size.should == 2
17
+ end
18
+
19
+ it 'selects via $.' do
20
+ %x{cat spec/test.txt | #{PRU_CMD} '$.'}.split($/)[0...3].should == %w[1 2 3]
21
+ end
22
+
23
+ it 'maps' do
24
+ %x{echo abc | #{PRU_CMD} 'gsub(/a/, "b")'}.should == "bbc\n"
25
+ end
26
+
27
+ it 'selects and reduces' do
28
+ %x{cat spec/test.txt | #{PRU_CMD} 'include?("abc")' 'size'}.should == "3\n"
29
+ end
30
+
31
+ it 'opens files' do
32
+ %x{echo spec/test.txt | #{PRU_CMD} 'File.read(self)'}.should == File.read('spec/test.txt')
33
+ end
34
+
35
+ it 'open preserves whitespaces' do
36
+ %x{echo ' ab\tcd ' | #{PRU_CMD} 'self'}.should == " ab\tcd \n"
37
+ end
38
+
39
+ it 'works with continuous input' do
40
+ results = %x{ruby -e 'STDOUT.sync = true; puts 1; sleep 2; puts 1' | #{PRU_CMD} 'Time.now.to_i'}.split($/)
41
+ results.size.should == 2
42
+ results.uniq.size.should == 2 # called at a different time -> parses as you go
43
+ end
44
+
45
+ end
46
+
47
+ describe 'reduce' do
48
+
49
+ it 'reduces' do
50
+ %x{cat spec/test.txt | #{PRU_CMD} -e 'size'}.should == "5\n"
51
+ end
52
+
53
+ it 'prints arrays as newlines' do
54
+ %x{cat spec/test.txt | #{PRU_CMD} -e 'self'}.should == File.read('spec/test.txt')
55
+ end
56
+
57
+ it 'can sum' do
58
+ %x{cat spec/test.txt | #{PRU_CMD} -e 'sum(&:to_i)'}.should == "1212\n"
59
+ end
60
+
61
+ it 'can mean' do
62
+ %x{cat spec/test.txt | #{PRU_CMD} -e 'mean(&:to_i)'}.should == "242.4\n"
63
+ end
64
+
65
+ it 'can grouped' do
66
+ %x{cat spec/test.txt | #{PRU_CMD} -e 'grouped.map { |a, b| b.size }'}.should include("2\n")
67
+ end
68
+
69
+ end
70
+
71
+ describe 'map and reduce' do
72
+
73
+ it 'selects with empty string and reduces' do
74
+ %x{cat spec/test.txt | #{PRU_CMD} '' 'size'}.should == "5\n"
75
+ end
76
+
77
+ end
78
+
79
+ end
@@ -0,0 +1,5 @@
1
+ LIB_DIR = File.expand_path('../../lib', __FILE__)
2
+ PRU_CMD = "#{File.join(File.dirname(LIB_DIR), 'bin', 'pru')} -I#{LIB_DIR}"
3
+
4
+ $LOAD_PATH.unshift LIB_DIR
5
+ require 'pru'
data/spec/test.txt ADDED
@@ -0,0 +1,5 @@
1
+ abc
2
+ abc
3
+ abcdef
4
+ 12
5
+ 1200
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: blackwinter-pru
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.4
6
+ platform: ruby
7
+ authors:
8
+ - Michael Grosser
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-04-21 00:00:00 +02:00
14
+ default_executable: pru
15
+ dependencies: []
16
+
17
+ description:
18
+ email: michael@grosser.it
19
+ executables:
20
+ - pru
21
+ extensions: []
22
+
23
+ extra_rdoc_files: []
24
+
25
+ files:
26
+ - Gemfile
27
+ - Gemfile.lock
28
+ - Rakefile
29
+ - Readme.md
30
+ - VERSION
31
+ - bin/pru
32
+ - lib/pru.rb
33
+ - lib/pru/core_ext.rb
34
+ - lib/pru/core_ext/array.rb
35
+ - lib/pru/core_ext/symbol.rb
36
+ - lib/pru/helper.rb
37
+ - pru.gemspec
38
+ - spec/pru_spec.rb
39
+ - spec/spec_helper.rb
40
+ - spec/test.txt
41
+ has_rdoc: true
42
+ homepage: http://github.com/grosser/blackwinter-pru
43
+ licenses: []
44
+
45
+ post_install_message:
46
+ rdoc_options: []
47
+
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ requirements: []
63
+
64
+ rubyforge_project:
65
+ rubygems_version: 1.4.2
66
+ signing_key:
67
+ specification_version: 3
68
+ summary: Pipeable Ruby - forget about grep/sed/awk/wc... use pure, readable Ruby!
69
+ test_files:
70
+ - spec/pru_spec.rb
71
+ - spec/spec_helper.rb