pageme 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in pageme.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 David R. MacIver
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,92 @@
1
+ # PageMe
2
+
3
+ PageMe is a trivial rubygem for invoking a pager on application data.
4
+
5
+ It even works under JRuby. The implementation for the JRuby support is an awful hack (it relies on netcat + unix domain sockets) and I've only tested it under linux, but it appears to be fully functional.
6
+
7
+ ## Usage
8
+
9
+ Include PageMe for use:
10
+
11
+ include PageMe
12
+
13
+ Paging a string:
14
+
15
+ page "some long string\nwhich spans many lines"
16
+
17
+ Paging an enumerable will page each element to its own line:
18
+
19
+ page (1..10000)
20
+
21
+ You can page multiple things at once
22
+
23
+ page "these", "strings", "will", "each", "go", "on", "their", "own", "line"
24
+
25
+ You can also page to a block
26
+
27
+ page do |o|
28
+ 10000.times do |i|
29
+ o.puts i
30
+ end
31
+ end
32
+
33
+ You can combine the different formats, which will page the arguments then the block
34
+
35
+ page "this is the first string" do |o|
36
+ 10000.times do |i|
37
+ o.puts i
38
+ end
39
+ end
40
+
41
+ It's ok for the blocks to throw exceptions
42
+
43
+ page{ raise "Denied!" }
44
+
45
+ Their results will be printed to the pager.
46
+
47
+ If you're passing multiple arguments and one of them raises an error then no further data will be paged
48
+
49
+ page lambda{raise "Denied!"}, "this line will never be printed"
50
+
51
+ If you want to page the results of the block first you can pass it as an argument
52
+
53
+ page "This line is printed first", lambda{ |o| 10.times{|i| o.puts i } }, "I just printed a bunch of lines"
54
+
55
+ You can page to a file either by passing its file name to page\_file
56
+
57
+ page_file "path/to/some/file"
58
+
59
+ or by passing an IO object
60
+
61
+ page File.open("path/to/some/file")
62
+
63
+ but the above example is bad because it won't close the file handle.
64
+
65
+ You can configure the pager being invoked:
66
+
67
+ self.pager = "more"
68
+ page %w{I hate fun}
69
+
70
+ You can also just disable paging if you want to print to STDOUT:
71
+
72
+ self.disable_paging
73
+ page %w{this will go to STDOUT as if it were the pager}
74
+
75
+ This is the default if STDOUT is not a tty.
76
+
77
+ You can of course enable it again:
78
+
79
+ self.enable_paging
80
+ page %w{this will go to a pager as normal}
81
+
82
+ ## Known bugs
83
+
84
+ Closing the pager does not work correctly in some versions of JRuby due to a bug in the Unix domain socket implementation. I've yet to pin down exactly where it's fixed (it might not be fixed in any released versions. It works in head and doesn't work in 1.6.2), but you may see that page continues to block after the pager closes. This is due to JRuby not raising an error when writing to a broken socket and there's not much I can do about it. Sorry.
85
+
86
+ ## Contributing
87
+
88
+ 1. Fork it
89
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
90
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
91
+ 4. Push to the branch (`git push origin my-new-feature`)
92
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,3 @@
1
+ module Pageme
2
+ VERSION = "0.0.1"
3
+ end
data/lib/pageme.rb ADDED
@@ -0,0 +1,133 @@
1
+ require "#{File.dirname __FILE__}/pageme/version"
2
+ require "rubygems"
3
+
4
+ module PageMe
5
+ if RUBY_VERSION < "1.9" || defined?(JRUBY_VERSION)
6
+ require "posix/spawn"
7
+ include POSIX::Spawn
8
+ end
9
+
10
+ def self.use_domain_socket_for_paging=(f)
11
+ if f
12
+ require "tempfile"
13
+ require "socket"
14
+ end
15
+ @use_domain_socket_for_paging = f
16
+ end
17
+
18
+ def self.use_domain_socket_for_paging?
19
+ @use_domain_socket_for_paging
20
+ end
21
+
22
+ self.use_domain_socket_for_paging = (defined? JRUBY_VERSION)
23
+
24
+ attr_writer :pager, :paging_disabled
25
+
26
+ def paging_disabled?
27
+ return @paging_disabled if defined? paging_disabled
28
+
29
+ !(STDOUT.tty?)
30
+ end
31
+
32
+ def disable_paging
33
+ self.paging_disabled = true
34
+ end
35
+
36
+ def enable_paging
37
+ self.paging_disabled = false
38
+ end
39
+
40
+ def pager
41
+ @pager || ENV["PAGER"] || "less"
42
+ end
43
+
44
+ def page *args, &p
45
+ args << p
46
+ args.compact!
47
+
48
+ if paging_disabled?
49
+ page_to STDOUT, args
50
+ return
51
+ end
52
+
53
+ t, w, server = nil
54
+
55
+ if defined? JRUBY_VERSION
56
+ loop do
57
+ begin
58
+ t = File.join(Dir::tmpdir, "socket-for-jruby-pager-#{rand(2**16)}")
59
+ server = UNIXServer.new(t)
60
+ break
61
+ rescue Errno::EADDRINUSE
62
+ end
63
+ end
64
+
65
+
66
+ child_pid = spawn "netcat -U #{t} | #{pager}"
67
+
68
+ w = server.accept
69
+ else
70
+ r, w = IO.pipe
71
+ child_pid = spawn pager, :in => r, w => :close
72
+ r.close
73
+ end
74
+
75
+ Kernel.trap("SIGINT"){ Process.kill "INT", child_pid }
76
+
77
+ begin
78
+ page_to w, args
79
+ rescue Errno::EPIPE
80
+ rescue Exception => e
81
+ unless w.closed?
82
+ w.puts "#{e.class}: #{e.message}"
83
+ e.backtrace.each{|l| w.puts "\t#{l}" }
84
+ end
85
+ raise
86
+ ensure
87
+ w.close
88
+ Process.wait child_pid
89
+ Kernel.trap("SIGINT", "DEFAULT")
90
+ File.delete(t) if t
91
+ server.close if server
92
+ end
93
+ nil
94
+ end
95
+
96
+ def page_file file
97
+ raise Errno::ENOENT, file unless File.exist? file
98
+
99
+ system pager, file
100
+ nil
101
+ end
102
+
103
+ def with_paged_output
104
+ page do |o|
105
+ original_stdout = STDOUT.dup
106
+ original_stderr = STDERR.dup
107
+ begin
108
+ STDERR.reopen(o)
109
+ STDOUT.reopen(o)
110
+ yield
111
+ ensure
112
+ STDERR.reopen(original_stderr)
113
+ STDOUT.reopen(original_stdout)
114
+ end
115
+ end
116
+ end
117
+
118
+ private
119
+
120
+ def page_to w, a
121
+ if a.kind_of? IO
122
+ a.each{|d| w.write d }
123
+ elsif a.kind_of? Proc
124
+ a.call(w)
125
+ elsif a.kind_of? String
126
+ w.write a
127
+ elsif a.kind_of? Enumerable
128
+ a.each{|e| page_to w, e; w.puts }
129
+ else
130
+ w.write a.to_s
131
+ end
132
+ end
133
+ end
data/pageme.gemspec ADDED
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/pageme/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["David R. MacIver"]
6
+ gem.email = ["david@drmaciver.com"]
7
+ gem.description = %q{Methods for invoking a pager}
8
+ gem.summary = %q{Trivial gem for invoking a pager for your program data}
9
+ gem.homepage = "https://github.com/DRMacIver/pageme"
10
+
11
+ gem.add_dependency 'posix-spawn', '>= 0.3.6'
12
+
13
+ gem.files = `git ls-files`.split($\)
14
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
15
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
16
+ gem.name = "pageme"
17
+ gem.require_paths = ["lib"]
18
+ gem.version = Pageme::VERSION
19
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pageme
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - David R. MacIver
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-29 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: posix-spawn
16
+ version_requirements: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ! '>='
19
+ - !ruby/object:Gem::Version
20
+ version: 0.3.6
21
+ none: false
22
+ requirement: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.3.6
27
+ none: false
28
+ prerelease: false
29
+ type: :runtime
30
+ description: Methods for invoking a pager
31
+ email:
32
+ - david@drmaciver.com
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - !binary |-
38
+ LmdpdGlnbm9yZQ==
39
+ - !binary |-
40
+ R2VtZmlsZQ==
41
+ - !binary |-
42
+ TElDRU5TRQ==
43
+ - !binary |-
44
+ UkVBRE1FLm1k
45
+ - !binary |-
46
+ UmFrZWZpbGU=
47
+ - !binary |-
48
+ bGliL3BhZ2VtZS5yYg==
49
+ - !binary |-
50
+ bGliL3BhZ2VtZS92ZXJzaW9uLnJi
51
+ - !binary |-
52
+ cGFnZW1lLmdlbXNwZWM=
53
+ homepage: https://github.com/DRMacIver/pageme
54
+ licenses: []
55
+ post_install_message:
56
+ rdoc_options: []
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ! '>='
62
+ - !ruby/object:Gem::Version
63
+ version: !binary |-
64
+ MA==
65
+ none: false
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: !binary |-
71
+ MA==
72
+ none: false
73
+ requirements: []
74
+ rubyforge_project:
75
+ rubygems_version: 1.8.24
76
+ signing_key:
77
+ specification_version: 3
78
+ summary: Trivial gem for invoking a pager for your program data
79
+ test_files: []
80
+ ...