rps 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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" }