rps 0.0.2 → 0.0.3

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/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2010 Jari Bakken
1
+ Copyright (c) 2010-2011 Jari Bakken
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -10,7 +10,7 @@ $ rps
10
10
 
11
11
  * BSD/OS X ?
12
12
  - FFI
13
- - kvm_getprocs() http://www.manpages.info/macosx/kvm_getprocs.3.html
13
+ - sysctl
14
14
  - http://www.opensource.apple.com/source/adv_cmds/adv_cmds-138.1/ps/
15
15
 
16
16
  == Note on Patches/Pull Requests
@@ -25,4 +25,4 @@ $ rps
25
25
 
26
26
  == Copyright
27
27
 
28
- Copyright (c) 2010 Jari Bakken. See LICENSE for details.
28
+ Copyright (c) 2010-2011 Jari Bakken. See LICENSE for details.
data/lib/rps.rb CHANGED
@@ -1,18 +1,51 @@
1
1
  require "rbconfig"
2
+ require "rps/cli"
3
+ require "rps/runner"
4
+ require "rps/ui"
2
5
 
3
6
  module RPS
4
- def self.os
5
- @os ||= RbConfig::CONFIG['host_os']
7
+ PLATFORMS = {
8
+ :linux => "LinuxProcess",
9
+ :macosx => "MacOSXProcess"
10
+ }
11
+
12
+ def self.platform
13
+ @platform ||= (
14
+ host_os = RbConfig::CONFIG['host_os']
15
+ case host_os
16
+ when /mswin|msys|mingw32/
17
+ :windows
18
+ when /darwin|mac os/
19
+ :macosx
20
+ when /linux/
21
+ :linux
22
+ when /bsd/
23
+ :bsd
24
+ when /solaris/
25
+ :solaris
26
+ else
27
+ raise "unknown os: #{host_os.inspect}"
28
+ end
29
+ )
6
30
  end
7
31
 
8
32
  def self.check_platform
9
- unless os =~ /linux/i
10
- abort "rps only works on linux at the moment"
33
+ unless PLATFORMS.has_key? platform
34
+ abort platform_message
11
35
  end
12
36
  end
13
- end
14
37
 
15
- require "rps/cli"
16
- require "rps/runner"
17
- require "rps/process_entry"
18
- require "rps/ui"
38
+ def self.all
39
+ clazz = PLATFORMS[platform] or raise platform_message
40
+ const_get(clazz).all
41
+ end
42
+
43
+ def self.platform_message
44
+ "rps only works on #{SUPPORTED_PLATFORMS.inspect} at the moment"
45
+ end
46
+
47
+ autoload :LinuxProcess, "rps/linux_process"
48
+ autoload :BsdProcess, "rps/bsd_process"
49
+ autoload :MacOSXProcess, "rps/macosx_process"
50
+
51
+ end
@@ -0,0 +1,28 @@
1
+ module RPS
2
+ class BsdProcess
3
+ def self.all
4
+ raise NotImplementedError
5
+ end
6
+
7
+ def readable?
8
+ raise NotImplementedError
9
+ end
10
+
11
+ def ruby?
12
+ raise NotImplementedError
13
+ end
14
+
15
+ def exe
16
+ raise NotImplementedError
17
+ end
18
+
19
+ def pid
20
+ raise NotImplementedError
21
+ end
22
+
23
+ def command_line
24
+ raise NotImplementedError
25
+ end
26
+
27
+ end # BsdProcess
28
+ end # RPS
@@ -1,12 +1,19 @@
1
1
  module RPS
2
2
  class CLI
3
3
 
4
- def initialize(args = nil)
5
- @runner = Runner.new
4
+ def initialize(args = [])
5
+ opts = {}
6
+
7
+ if args.include? "--cwd"
8
+ opts[:cwd] = true
9
+ end
10
+
11
+ ui = UI.new(STDOUT, opts)
12
+
13
+ @runner = Runner.new ui
6
14
  end
7
15
 
8
16
  def run
9
- @runner.ui ||= UI.new
10
17
  @runner.run
11
18
  end
12
19
 
@@ -1,5 +1,7 @@
1
1
  module RPS
2
- class ProcessEntry
2
+ class LinuxProcess
3
+ NULL = "\000"
4
+
3
5
  def self.all
4
6
  Dir['/proc/*'].map { |dir| new(dir) if File.basename(dir) =~ /^\d+$/ }.compact
5
7
  end
@@ -24,8 +26,21 @@ module RPS
24
26
  @pid ||= Integer(File.basename(@dir))
25
27
  end
26
28
 
29
+ def cwd
30
+ @cwd ||= File.readlink(cwd_path)
31
+ end
32
+
27
33
  def command_line
28
- @command_line ||= File.read(cmdline_path).split("\000")
34
+ @command_line ||= File.read(cmdline_path).split(NULL)
35
+ end
36
+
37
+ def environment
38
+ @environment ||= (
39
+ strings = File.read(environ_path).split(NULL)
40
+ data = strings.map { |e| e.split("=") }
41
+
42
+ Hash[data]
43
+ )
29
44
  end
30
45
 
31
46
  private
@@ -37,5 +52,13 @@ module RPS
37
52
  def cmdline_path
38
53
  File.join(@dir, "cmdline")
39
54
  end
40
- end # ProcessEntry
55
+
56
+ def environ_path
57
+ File.join(@dir, "environ")
58
+ end
59
+
60
+ def cwd_path
61
+ File.join(@dir, 'cwd')
62
+ end
63
+ end # LinuxProcess
41
64
  end # RPS
@@ -0,0 +1,46 @@
1
+ require 'ffi'
2
+
3
+ module RPS
4
+ class MacOSXProcess
5
+ module Lib
6
+ extend FFI::Library
7
+ ffi_lib FFI::CURRENT_PROCESS
8
+
9
+ CTL_KERN = 1
10
+ KERN_PROC = 14
11
+ KERN_PROC_ALL = 0
12
+
13
+ attach_function :sysctl, [:pointer, :uint, :pointer, :pointer, :pointer, :size_t], :int
14
+ end
15
+
16
+
17
+ def self.all
18
+ raise NotImplementedError
19
+
20
+ mib = [Lib::CTL_KERN, Lib::KERN_PROC, Lib::KERN_PROC_ALL, 0]
21
+ mip = FFI::MemoryPointer.new(:int, mib.size).write_array_of_int(mib)
22
+
23
+ # meh. struct too much for bsd.
24
+ end
25
+
26
+ def readable?
27
+ raise NotImplementedError
28
+ end
29
+
30
+ def ruby?
31
+ raise NotImplementedError
32
+ end
33
+
34
+ def exe
35
+ raise NotImplementedError
36
+ end
37
+
38
+ def pid
39
+ raise NotImplementedError
40
+ end
41
+
42
+ def command_line
43
+ raise NotImplementedError
44
+ end
45
+ end # MacOSXProcess
46
+ end # RPS
@@ -4,6 +4,7 @@ module RPS
4
4
 
5
5
  def initialize(ui = nil)
6
6
  @ui = ui
7
+ @opts = {}
7
8
  end
8
9
 
9
10
  def run
@@ -14,7 +15,7 @@ module RPS
14
15
  private
15
16
 
16
17
  def procs
17
- @procs ||= ProcessEntry.all
18
+ @procs ||= RPS.all
18
19
  end
19
20
  end # Runner
20
21
  end # RPS
@@ -1,20 +1,21 @@
1
1
  module RPS
2
2
  class UI
3
3
 
4
- def initialize(io = $stdout)
4
+ def initialize(io = $stdout, opts = {})
5
5
  @io = io
6
+ @opts = opts
6
7
  end
7
8
 
8
9
  def render(process)
9
- string = format_string % [ process.pid,
10
- process.exe,
11
- process.command_line.join(' ') ]
10
+ string = []
12
11
 
13
- @io << string
14
- end
12
+ string << process.pid.to_s
13
+ string << "[#{process.exe}]"
14
+ string << process.command_line.join(' ')
15
+ string << "cwd=#{process.cwd}" if @opts[:cwd]
15
16
 
16
- def format_string
17
- "%d [%s] %s\n"
17
+ @io << string.join(' ') << "\n"
18
18
  end
19
+
19
20
  end # RPS
20
21
  end # UI
@@ -1,3 +1,3 @@
1
1
  module RPS
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -7,13 +7,15 @@ Gem::Specification.new do |s|
7
7
  s.platform = Gem::Platform::RUBY
8
8
  s.authors = ["Jari Bakken"]
9
9
  s.email = ["jari.bakken@gmail.com"]
10
- s.homepage = "http://rubygems.org/gems/rps"
10
+ s.homepage = "http://github.com/jarib/rps"
11
11
  s.summary = "Ruby Process Status"
12
12
  s.description = "ps for Ruby processes"
13
13
 
14
14
  s.required_rubygems_version = ">= 1.3.6"
15
15
  s.rubyforge_project = "rps"
16
16
 
17
+ s.add_dependency "ffi", "~> 1.0.9"
18
+
17
19
  s.add_development_dependency "bundler", ">= 1.0.0"
18
20
  s.add_development_dependency "rspec", ">= 2.0.0"
19
21
  s.add_development_dependency "autotest", ">= 4.4.5"
@@ -5,9 +5,8 @@ module RPS
5
5
  it "creates a default runner" do
6
6
  runner = mock(Runner, :ui => nil)
7
7
 
8
- Runner.should_receive(:new).and_return(runner)
8
+ Runner.should_receive(:new).with(instance_of(UI)).and_return(runner)
9
9
  runner.should_receive(:run)
10
- runner.should_receive(:ui=).with(instance_of(UI))
11
10
 
12
11
  CLI.new.run
13
12
  end
@@ -0,0 +1,7 @@
1
+ require "spec_helper"
2
+
3
+ describe "RPS" do
4
+ it "should include the current process" do
5
+ RPS.all.find { |e| e.pid == Process.pid }.should be_ruby
6
+ end
7
+ end
@@ -1,40 +1,40 @@
1
1
  require "spec_helper"
2
2
 
3
3
  module RPS
4
- describe ProcessEntry do
4
+ describe LinuxProcess do
5
5
  it "creates a process for each process in /proc" do
6
6
  Dir.stub!(:[]).with("/proc/*").and_return(["/proc/1", "/proc/2", "/proc/3", "/proc/uptime"])
7
7
 
8
- procs = ProcessEntry.all
8
+ procs = LinuxProcess.all
9
9
 
10
10
  procs.should be_instance_of(Array)
11
11
  procs.size.should == 3
12
- procs.each { |proc| proc.should be_instance_of(ProcessEntry) }
12
+ procs.each { |proc| proc.should be_instance_of(LinuxProcess) }
13
13
  end
14
14
 
15
15
  it "returns the pid" do
16
- ProcessEntry.new("/proc/123").pid.should == 123
16
+ LinuxProcess.new("/proc/123").pid.should == 123
17
17
  end
18
18
 
19
19
  it "returns the executable path" do
20
20
  File.stub!(:readlink).with("/proc/1/exe").and_return("/some/executable")
21
- ProcessEntry.new("/proc/1").exe.should == "/some/executable"
21
+ LinuxProcess.new("/proc/1").exe.should == "/some/executable"
22
22
  end
23
23
 
24
24
  it "returns the command line" do
25
25
  File.stub!(:read).with("/proc/1/cmdline").and_return("ruby\000-e\000sleep\000")
26
- ProcessEntry.new("/proc/1").command_line.should == ["ruby", "-e", "sleep"]
26
+ LinuxProcess.new("/proc/1").command_line.should == ["ruby", "-e", "sleep"]
27
27
  end
28
28
 
29
29
  it "knows if the process is a ruby process" do
30
- pe = ProcessEntry.new("/proc/1")
30
+ pe = LinuxProcess.new("/proc/1")
31
31
  pe.stub!(:exe).and_return "/path/to/ruby"
32
32
 
33
33
  pe.should be_ruby
34
34
  end
35
35
 
36
36
  it "knows if the process is not a ruby process" do
37
- pe = ProcessEntry.new("/proc/1")
37
+ pe = LinuxProcess.new("/proc/1")
38
38
  pe.stub!(:exe).and_return "/path/to/something else"
39
39
 
40
40
  pe.should_not be_ruby
@@ -45,7 +45,7 @@ module RPS
45
45
  with("/proc/1/exe").
46
46
  and_return(true)
47
47
 
48
- pe = ProcessEntry.new("/proc/1")
48
+ pe = LinuxProcess.new("/proc/1")
49
49
  pe.should be_readable
50
50
  end
51
51
 
@@ -54,7 +54,7 @@ module RPS
54
54
  with("/proc/1/exe").
55
55
  and_return(false)
56
56
 
57
- pe = ProcessEntry.new("/proc/1")
57
+ pe = LinuxProcess.new("/proc/1")
58
58
  pe.should_not be_readable
59
59
  end
60
60
 
@@ -6,18 +6,19 @@ module RPS
6
6
  let(:runner) { Runner.new(ui) }
7
7
 
8
8
  it "fetches the process list" do
9
- ProcessEntry.should_receive(:all).and_return([])
9
+ RPS.should_receive(:all).and_return([])
10
10
  runner.run
11
11
  end
12
12
 
13
13
  it "shows each readable ruby process on the UI" do
14
14
  procs = [
15
- mock(ProcessEntry, :ruby? => true, :readable? => true),
16
- mock(ProcessEntry, :ruby? => false, :readable? => true),
17
- mock(ProcessEntry, :ruby? => true, :readable? => false),
18
- mock(ProcessEntry, :ruby? => true, :readable? => true)
15
+ mock(:ruby? => true, :readable? => true),
16
+ mock(:ruby? => false, :readable? => true),
17
+ mock(:ruby? => true, :readable? => false),
18
+ mock(:ruby? => true, :readable? => true)
19
19
  ]
20
- ProcessEntry.should_receive(:all).and_return(procs)
20
+
21
+ RPS.should_receive(:all).and_return(procs)
21
22
 
22
23
  ui.should_receive(:render).once.with(procs.first)
23
24
  ui.should_receive(:render).once.with(procs.last)
@@ -6,7 +6,7 @@ module RPS
6
6
  let(:ui) { UI.new(io) }
7
7
 
8
8
  it "renders the given proc" do
9
- pe = mock(ProcessEntry,
9
+ pe = mock(
10
10
  :exe => "/usr/bin/ruby1.8",
11
11
  :pid => 123,
12
12
  :command_line => %w[ruby -e sleep]
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rps
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
4
+ hash: 25
5
+ prerelease:
5
6
  segments:
6
7
  - 0
7
8
  - 0
8
- - 2
9
- version: 0.0.2
9
+ - 3
10
+ version: 0.0.3
10
11
  platform: ruby
11
12
  authors:
12
13
  - Jari Bakken
@@ -14,54 +15,72 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-11-25 00:00:00 +01:00
18
- default_executable:
18
+ date: 2011-11-30 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
- name: bundler
21
+ name: ffi
22
22
  prerelease: false
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ hash: 5
29
+ segments:
30
+ - 1
31
+ - 0
32
+ - 9
33
+ version: 1.0.9
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: bundler
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
24
40
  none: false
25
41
  requirements:
26
42
  - - ">="
27
43
  - !ruby/object:Gem::Version
44
+ hash: 23
28
45
  segments:
29
46
  - 1
30
47
  - 0
31
48
  - 0
32
49
  version: 1.0.0
33
50
  type: :development
34
- version_requirements: *id001
51
+ version_requirements: *id002
35
52
  - !ruby/object:Gem::Dependency
36
53
  name: rspec
37
54
  prerelease: false
38
- requirement: &id002 !ruby/object:Gem::Requirement
55
+ requirement: &id003 !ruby/object:Gem::Requirement
39
56
  none: false
40
57
  requirements:
41
58
  - - ">="
42
59
  - !ruby/object:Gem::Version
60
+ hash: 15
43
61
  segments:
44
62
  - 2
45
63
  - 0
46
64
  - 0
47
65
  version: 2.0.0
48
66
  type: :development
49
- version_requirements: *id002
67
+ version_requirements: *id003
50
68
  - !ruby/object:Gem::Dependency
51
69
  name: autotest
52
70
  prerelease: false
53
- requirement: &id003 !ruby/object:Gem::Requirement
71
+ requirement: &id004 !ruby/object:Gem::Requirement
54
72
  none: false
55
73
  requirements:
56
74
  - - ">="
57
75
  - !ruby/object:Gem::Version
76
+ hash: 37
58
77
  segments:
59
78
  - 4
60
79
  - 4
61
80
  - 5
62
81
  version: 4.4.5
63
82
  type: :development
64
- version_requirements: *id003
83
+ version_requirements: *id004
65
84
  description: ps for Ruby processes
66
85
  email:
67
86
  - jari.bakken@gmail.com
@@ -73,26 +92,28 @@ extra_rdoc_files: []
73
92
 
74
93
  files:
75
94
  - .gitignore
95
+ - .rspec
76
96
  - Gemfile
77
97
  - LICENSE
78
98
  - README.rdoc
79
99
  - Rakefile
80
- - autotest/discover.rb
81
100
  - bin/rps
82
101
  - lib/rps.rb
102
+ - lib/rps/bsd_process.rb
83
103
  - lib/rps/cli.rb
84
- - lib/rps/process_entry.rb
104
+ - lib/rps/linux_process.rb
105
+ - lib/rps/macosx_process.rb
85
106
  - lib/rps/runner.rb
86
107
  - lib/rps/ui.rb
87
108
  - lib/rps/version.rb
88
109
  - rps.gemspec
89
110
  - spec/rps/cli_spec.rb
90
- - spec/rps/process_entry_spec.rb
111
+ - spec/rps/integration_spec.rb
112
+ - spec/rps/linux_process_spec.rb
91
113
  - spec/rps/runner_spec.rb
92
114
  - spec/rps/ui_spec.rb
93
115
  - spec/spec_helper.rb
94
- has_rdoc: true
95
- homepage: http://rubygems.org/gems/rps
116
+ homepage: http://github.com/jarib/rps
96
117
  licenses: []
97
118
 
98
119
  post_install_message:
@@ -105,6 +126,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
105
126
  requirements:
106
127
  - - ">="
107
128
  - !ruby/object:Gem::Version
129
+ hash: 3
108
130
  segments:
109
131
  - 0
110
132
  version: "0"
@@ -113,6 +135,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
113
135
  requirements:
114
136
  - - ">="
115
137
  - !ruby/object:Gem::Version
138
+ hash: 23
116
139
  segments:
117
140
  - 1
118
141
  - 3
@@ -121,9 +144,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
121
144
  requirements: []
122
145
 
123
146
  rubyforge_project: rps
124
- rubygems_version: 1.3.7
147
+ rubygems_version: 1.8.10
125
148
  signing_key:
126
149
  specification_version: 3
127
150
  summary: Ruby Process Status
128
151
  test_files: []
129
152
 
153
+ has_rdoc:
@@ -1 +0,0 @@
1
- Autotest.add_discovery { "rspec2" }