blackwinter-pru 0.1.4

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.
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