ragweed 0.1.7.2
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +32 -0
- data/README.rdoc +35 -0
- data/README.txt +9 -0
- data/Rakefile +34 -0
- data/examples/hittracertux.rb +49 -0
- data/examples/hittracerx.rb +63 -0
- data/examples/hook_notepad.rb +9 -0
- data/examples/snicker.rb +183 -0
- data/examples/tux-example.rb +23 -0
- data/lib/ragweed/arena.rb +55 -0
- data/lib/ragweed/blocks.rb +128 -0
- data/lib/ragweed/debugger32.rb +338 -0
- data/lib/ragweed/debuggerosx.rb +427 -0
- data/lib/ragweed/debuggertux.rb +346 -0
- data/lib/ragweed/detour.rb +223 -0
- data/lib/ragweed/ptr.rb +48 -0
- data/lib/ragweed/rasm/bblock.rb +73 -0
- data/lib/ragweed/rasm/isa.rb +1115 -0
- data/lib/ragweed/rasm.rb +59 -0
- data/lib/ragweed/sbuf.rb +197 -0
- data/lib/ragweed/trampoline.rb +103 -0
- data/lib/ragweed/utils.rb +156 -0
- data/lib/ragweed/wrap32/debugging.rb +163 -0
- data/lib/ragweed/wrap32/device.rb +49 -0
- data/lib/ragweed/wrap32/event.rb +50 -0
- data/lib/ragweed/wrap32/hooks.rb +23 -0
- data/lib/ragweed/wrap32/overlapped.rb +46 -0
- data/lib/ragweed/wrap32/process.rb +506 -0
- data/lib/ragweed/wrap32/process_token.rb +59 -0
- data/lib/ragweed/wrap32/thread_context.rb +208 -0
- data/lib/ragweed/wrap32/winx.rb +16 -0
- data/lib/ragweed/wrap32/wrap32.rb +526 -0
- data/lib/ragweed/wrap32.rb +59 -0
- data/lib/ragweed/wraposx/constants.rb +122 -0
- data/lib/ragweed/wraposx/kernelerrorx.rb +147 -0
- data/lib/ragweed/wraposx/region_info.rb +254 -0
- data/lib/ragweed/wraposx/thread_context.rb +203 -0
- data/lib/ragweed/wraposx/thread_info.rb +227 -0
- data/lib/ragweed/wraposx/wraposx.rb +433 -0
- data/lib/ragweed/wraposx.rb +59 -0
- data/lib/ragweed/wraptux/constants.rb +68 -0
- data/lib/ragweed/wraptux/threads.rb +7 -0
- data/lib/ragweed/wraptux/wraptux.rb +76 -0
- data/lib/ragweed/wraptux.rb +59 -0
- data/lib/ragweed.rb +84 -0
- data/ragweed.gemspec +34 -0
- data/spec/ragweed_spec.rb +7 -0
- data/spec/spec_helper.rb +16 -0
- data/tasks/ann.rake +80 -0
- data/tasks/bones.rake +20 -0
- data/tasks/gem.rake +201 -0
- data/tasks/git.rake +40 -0
- data/tasks/notes.rake +27 -0
- data/tasks/post_load.rake +34 -0
- data/tasks/rdoc.rake +51 -0
- data/tasks/rubyforge.rake +55 -0
- data/tasks/setup.rb +292 -0
- data/tasks/spec.rake +54 -0
- data/tasks/svn.rake +47 -0
- data/tasks/test.rake +40 -0
- data/tasks/zentest.rake +36 -0
- data/test/test_ragweed.rb +0 -0
- metadata +132 -0
@@ -0,0 +1,59 @@
|
|
1
|
+
# Dir[File.expand_path("#{File.dirname(__FILE__)}/wraposx/*.rb")].each do |file|
|
2
|
+
# require file
|
3
|
+
# end
|
4
|
+
module Ragweed; end
|
5
|
+
module Ragweed::Wraposx
|
6
|
+
|
7
|
+
# :stopdoc:
|
8
|
+
VERSION = '0.1.7.2'
|
9
|
+
LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
|
10
|
+
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
|
11
|
+
# :startdoc:
|
12
|
+
|
13
|
+
# Returns the version string for the library.
|
14
|
+
#
|
15
|
+
def self.version
|
16
|
+
VERSION
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns the library path for the module. If any arguments are given,
|
20
|
+
# they will be joined to the end of the libray path using
|
21
|
+
# <tt>File.join</tt>.
|
22
|
+
#
|
23
|
+
def self.libpath( *args )
|
24
|
+
args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns the lpath for the module. If any arguments are given,
|
28
|
+
# they will be joined to the end of the path using
|
29
|
+
# <tt>File.join</tt>.
|
30
|
+
#
|
31
|
+
def self.path( *args )
|
32
|
+
args.empty? ? PATH : ::File.join(PATH, args.flatten)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Utility function to load utility classes and extensions
|
36
|
+
def self.require_utils
|
37
|
+
%w{utils}.each{|r| require self.libpath(r)+'.rb'}
|
38
|
+
end
|
39
|
+
|
40
|
+
# Utility method used to require all files ending in .rb that lie in the
|
41
|
+
# directory below this file that has the same name as the filename passed
|
42
|
+
# in. Optionally, a specific _directory_ name can be passed in such that
|
43
|
+
# the _filename_ does not have to be equivalent to the directory.
|
44
|
+
#
|
45
|
+
def self.require_all_libs_relative_to( fname, dir = nil )
|
46
|
+
self.require_utils
|
47
|
+
dir ||= ::File.basename(fname, '.*')
|
48
|
+
search_me = ::File.expand_path(
|
49
|
+
::File.join(::File.dirname(fname), dir, '**', '*.rb'))
|
50
|
+
|
51
|
+
Dir.glob(search_me).reject{|rb| rb =~ /#{__FILE__}/}.sort.each {|rb| require rb}
|
52
|
+
# require File.dirname(File.basename(__FILE__)) + "/#{x}"
|
53
|
+
|
54
|
+
end
|
55
|
+
end # module Ragweed::Wraposx
|
56
|
+
|
57
|
+
Ragweed::Wraposx.require_all_libs_relative_to(__FILE__)
|
58
|
+
|
59
|
+
# EOF
|
@@ -0,0 +1,68 @@
|
|
1
|
+
NULL = nil
|
2
|
+
module Ragweed; end
|
3
|
+
module Ragweed::Wraptux;end
|
4
|
+
|
5
|
+
module Ragweed::Wraptux::Ptrace
|
6
|
+
TRACE_ME = 0
|
7
|
+
PEEK_TEXT = 1
|
8
|
+
PEEK_DATA = 2
|
9
|
+
PEEK_USER = 3
|
10
|
+
POKE_TEXT = 4
|
11
|
+
POKE_DATA = 5
|
12
|
+
POKE_USER = 6
|
13
|
+
CONTINUE = 7
|
14
|
+
KILL = 8
|
15
|
+
STEP = 9
|
16
|
+
GETREGS = 12
|
17
|
+
SETREGS = 13
|
18
|
+
ATTACH = 16
|
19
|
+
DETACH = 17
|
20
|
+
SYSCALL = 24
|
21
|
+
end
|
22
|
+
|
23
|
+
module Ragweed::Wraptux::Signal
|
24
|
+
SIGHUP = 1
|
25
|
+
SIGINT = 2
|
26
|
+
SIGQUIT = 3
|
27
|
+
SIGILL = 4
|
28
|
+
SIGTRAP = 5
|
29
|
+
SIGABRT = 6
|
30
|
+
SIGIOT = 6
|
31
|
+
SIGBUS = 7
|
32
|
+
SIGFPE = 8
|
33
|
+
SIGKILL = 9
|
34
|
+
SIGUSR1 = 10
|
35
|
+
SIGSEGV = 11
|
36
|
+
SIGUSR2 = 12
|
37
|
+
SIGPIPE = 13
|
38
|
+
SIGALRM = 14
|
39
|
+
SIGTERM = 15
|
40
|
+
SIGSTKFLT = 16
|
41
|
+
SIGCHLD = 17
|
42
|
+
SIGCONT = 18
|
43
|
+
SIGSTOP = 19
|
44
|
+
SIGTSTP = 20
|
45
|
+
SIGTTIN = 21
|
46
|
+
SIGTTOU = 22
|
47
|
+
SIGURG = 23
|
48
|
+
SIGXCPU = 24
|
49
|
+
SIGXFSZ = 25
|
50
|
+
SIGVTALRM = 26
|
51
|
+
SIGPROF = 27
|
52
|
+
SIGWINCH = 28
|
53
|
+
SIGIO = 29
|
54
|
+
SIGPOLL = SIGIO
|
55
|
+
#SIGLOST = 29
|
56
|
+
SIGPWR = 30
|
57
|
+
SIGSYS = 31
|
58
|
+
SIGUNUSED = 31
|
59
|
+
end
|
60
|
+
|
61
|
+
module Ragweed::Wraptux::Wait
|
62
|
+
NOHANG = 1
|
63
|
+
UNTRACED = 2
|
64
|
+
EXITED = 4
|
65
|
+
STOPPED = 8
|
66
|
+
CONTINUED = 10
|
67
|
+
NOWWAIT = 20
|
68
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'dl'
|
2
|
+
|
3
|
+
module Ragweed; end
|
4
|
+
module Ragweed::Wraptux
|
5
|
+
LIBS = Hash.new do |h, str|
|
6
|
+
if not str =~ /^[\.\/].*/
|
7
|
+
str = "/lib/" + str
|
8
|
+
end
|
9
|
+
if not str =~ /.*\.so.6$/
|
10
|
+
str = str + ".so.6"
|
11
|
+
end
|
12
|
+
h[str] = DL.dlopen(str)
|
13
|
+
end
|
14
|
+
|
15
|
+
CALLS = Hash.new do |h, str|
|
16
|
+
lib = proc = args = ret = nil
|
17
|
+
lib, rest = str.split "!"
|
18
|
+
proc, rest = rest.split ":"
|
19
|
+
args, ret = rest.split("=") if rest
|
20
|
+
ret ||= "0"
|
21
|
+
raise "need proc" if not proc
|
22
|
+
h[str] = LIBS[lib][proc, ret + args]
|
23
|
+
end
|
24
|
+
|
25
|
+
NULL = DL::PtrData.new(0)
|
26
|
+
|
27
|
+
SIZEOFINT = DL.sizeof('I')
|
28
|
+
SIZEOFLONG = DL.sizeof('L')
|
29
|
+
|
30
|
+
class << self
|
31
|
+
#long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);
|
32
|
+
def ptrace(request, pid, addr, data)
|
33
|
+
DL.last_error = 0
|
34
|
+
r = CALLS["libc!ptrace:IIII=I"].call(request, pid, addr, data).first
|
35
|
+
raise SystemCallError.new("ptrace", DL.last_error) if r == -1 and DL.last_error != 0
|
36
|
+
|
37
|
+
case request
|
38
|
+
when Ptrace::PEEK_TEXT, Ptrace::PEEK_DATA
|
39
|
+
return r
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def malloc(sz)
|
44
|
+
r = CALLS["libc!malloc:L=L"].call(sz)
|
45
|
+
return r
|
46
|
+
end
|
47
|
+
|
48
|
+
#wait(int *status);
|
49
|
+
def wait
|
50
|
+
status = ("\x00"*SIZEOFINT).to_ptr.to_i
|
51
|
+
r = CALLS["libc!wait:I=I"].call(status).first
|
52
|
+
raise SystemCallError.new("wait", DL.last_error) if r == -1
|
53
|
+
self.continue # continue with the ptrace at this point
|
54
|
+
return status.to_s(SIZEOFINT).unpack('i_').first
|
55
|
+
end
|
56
|
+
|
57
|
+
#waitpid(pid_t pid, int *stat_loc, int options);
|
58
|
+
def waitpid(pid, opt=1)
|
59
|
+
pstatus = ("\x00"*SIZEOFINT).to_ptr
|
60
|
+
r = CALLS["libc!waitpid:IPI=I"].call(pid, pstatus, opt).first
|
61
|
+
raise SystemCallError.new("waitpid", DL.last_error) if r == -1
|
62
|
+
return [r, pstatus.to_s(SIZEOFINT).unpack('i_').first]
|
63
|
+
end
|
64
|
+
|
65
|
+
#kill(pid_t pid, int sig);
|
66
|
+
def kill(pid, sig)
|
67
|
+
DL.last_error = 0
|
68
|
+
r = CALLS["libc!kill:II=I"].call(pid,sig).first
|
69
|
+
raise SystemCallError.new("kill",DL.last_error) if r != 0
|
70
|
+
end
|
71
|
+
|
72
|
+
def getpid
|
73
|
+
CALLS["libc!getpid:=I"].call.first
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# Dir[File.expand_path("#{File.dirname(__FILE__)}/wraptux/*.rb")].each do |file|
|
2
|
+
# require file
|
3
|
+
# end
|
4
|
+
module Ragweed; end
|
5
|
+
module Ragweed::Wraptux
|
6
|
+
|
7
|
+
# :stopdoc:
|
8
|
+
VERSION = '0.1.7.2'
|
9
|
+
LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
|
10
|
+
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
|
11
|
+
# :startdoc:
|
12
|
+
|
13
|
+
# Returns the version string for the library.
|
14
|
+
#
|
15
|
+
def self.version
|
16
|
+
VERSION
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns the library path for the module. If any arguments are given,
|
20
|
+
# they will be joined to the end of the libray path using
|
21
|
+
# <tt>File.join</tt>.
|
22
|
+
#
|
23
|
+
def self.libpath( *args )
|
24
|
+
args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns the lpath for the module. If any arguments are given,
|
28
|
+
# they will be joined to the end of the path using
|
29
|
+
# <tt>File.join</tt>.
|
30
|
+
#
|
31
|
+
def self.path( *args )
|
32
|
+
args.empty? ? PATH : ::File.join(PATH, args.flatten)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Utility function to load utility classes and extensions
|
36
|
+
def self.require_utils
|
37
|
+
%w{utils}.each{|r| require self.libpath(r)+'.rb'}
|
38
|
+
end
|
39
|
+
|
40
|
+
# Utility method used to require all files ending in .rb that lie in the
|
41
|
+
# directory below this file that has the same name as the filename passed
|
42
|
+
# in. Optionally, a specific _directory_ name can be passed in such that
|
43
|
+
# the _filename_ does not have to be equivalent to the directory.
|
44
|
+
#
|
45
|
+
def self.require_all_libs_relative_to( fname, dir = nil )
|
46
|
+
self.require_utils
|
47
|
+
dir ||= ::File.basename(fname, '.*')
|
48
|
+
search_me = ::File.expand_path(
|
49
|
+
::File.join(::File.dirname(fname), dir, '**', '*.rb'))
|
50
|
+
|
51
|
+
Dir.glob(search_me).sort.each {|rb| require rb}
|
52
|
+
# require File.dirname(File.basename(__FILE__)) + "/#{x}"
|
53
|
+
|
54
|
+
end
|
55
|
+
end # module Ragweed::Wraptux
|
56
|
+
|
57
|
+
Ragweed::Wraptux.require_all_libs_relative_to(__FILE__)
|
58
|
+
|
59
|
+
# EOF
|
data/lib/ragweed.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
|
2
|
+
module Ragweed
|
3
|
+
|
4
|
+
# :stopdoc:
|
5
|
+
VERSION = '0.1.7.2'
|
6
|
+
LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
|
7
|
+
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
|
8
|
+
# :startdoc:
|
9
|
+
|
10
|
+
# Returns the version string for the library.
|
11
|
+
#
|
12
|
+
def self.version
|
13
|
+
VERSION
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns the library path for the module. If any arguments are given,
|
17
|
+
# they will be joined to the end of the libray path using
|
18
|
+
# <tt>File.join</tt>.
|
19
|
+
#
|
20
|
+
def self.libpath( *args )
|
21
|
+
args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns the lpath for the module. If any arguments are given,
|
25
|
+
# they will be joined to the end of the path using
|
26
|
+
# <tt>File.join</tt>.
|
27
|
+
#
|
28
|
+
def self.path( *args )
|
29
|
+
args.empty? ? PATH : ::File.join(PATH, args.flatten)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Utility method used to require all files ending in .rb that lie in the
|
33
|
+
# directory below this file that has the same name as the filename passed
|
34
|
+
# in. Optionally, a specific _directory_ name can be passed in such that
|
35
|
+
# the _filename_ does not have to be equivalent to the directory.
|
36
|
+
#
|
37
|
+
def self.require_all_libs_relative_to( fname, dir = nil )
|
38
|
+
dir ||= ::File.basename(fname, '.*')
|
39
|
+
search_me = ::File.expand_path(
|
40
|
+
::File.join(::File.dirname(fname), dir, '**', '*.rb'))
|
41
|
+
|
42
|
+
# Don't want to load wrapper or debugger here.
|
43
|
+
Dir.glob(search_me).sort.reject{|rb| rb =~ /(wrap|debugger|rasm[^\.])/}.each {|rb| require rb}
|
44
|
+
# require File.dirname(File.basename(__FILE__)) + "/#{x}"d
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.require_os_libs_relative_to( fname, dir= nil )
|
48
|
+
dir ||= ::File.basename(fname, '.*')
|
49
|
+
pkgs = ""
|
50
|
+
dbg = ""
|
51
|
+
case
|
52
|
+
when RUBY_PLATFORM =~ /win(dows|32)/i
|
53
|
+
pkgs = '32'
|
54
|
+
when RUBY_PLATFORM =~ /darwin/i
|
55
|
+
pkgs = 'osx'
|
56
|
+
when RUBY_PLATFORM =~ /linux/i
|
57
|
+
pkgs = 'tux'
|
58
|
+
# when RUBY_PLATFORM =~ /java/i
|
59
|
+
# TODO - Java port using jni?
|
60
|
+
else
|
61
|
+
warn "Platform not supported no wrapper libraries loaded."
|
62
|
+
end
|
63
|
+
|
64
|
+
if not pkgs.empty?
|
65
|
+
search_me = File.expand_path(File.join(File.dirname(fname), dir, "*#{pkgs}.rb"))
|
66
|
+
Dir.glob(search_me).sort.reverse.each {|rb| require rb}
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end # module Ragweed
|
70
|
+
|
71
|
+
|
72
|
+
# pkgs = %w[arena sbuf ptr process event rasm blocks detour trampoline device debugger hooks]
|
73
|
+
# pkgs << 'wrap32' if RUBY_PLATFORM =~ /win(dows|32)/i
|
74
|
+
# pkgs << 'wraposx' if RUBY_PLATFORM =~ /darwin/i
|
75
|
+
# pkgs << 'wraptux' if RUBY_PLATFORM =~ /linux/i
|
76
|
+
# pkgs.each do |x|
|
77
|
+
# require File.dirname(__FILE__) + "/#{x}"
|
78
|
+
# end
|
79
|
+
|
80
|
+
|
81
|
+
Ragweed.require_os_libs_relative_to(__FILE__)
|
82
|
+
Ragweed.require_all_libs_relative_to(__FILE__)
|
83
|
+
|
84
|
+
# EOF
|
data/ragweed.gemspec
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{ragweed}
|
5
|
+
s.version = "0.1.7.2"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["tduehr, tqbf, struct"]
|
9
|
+
s.date = %q{2009-09-21}
|
10
|
+
s.description = %q{General debugging tool written in Ruby for OSX/Win32/Linux}
|
11
|
+
s.email = %q{td@matasano.com}
|
12
|
+
s.extra_rdoc_files = ["History.txt", "README.rdoc", "README.txt"]
|
13
|
+
s.files = ["History.txt", "README.rdoc", "README.txt", "Rakefile", "examples/hittracertux.rb", "examples/hittracerx.rb", "examples/hook_notepad.rb", "examples/snicker.rb", "examples/tux-example.rb", "lib/ragweed.rb", "lib/ragweed/arena.rb", "lib/ragweed/blocks.rb", "lib/ragweed/debugger32.rb", "lib/ragweed/debuggerosx.rb", "lib/ragweed/debuggertux.rb", "lib/ragweed/detour.rb", "lib/ragweed/ptr.rb", "lib/ragweed/rasm.rb", "lib/ragweed/rasm/bblock.rb", "lib/ragweed/rasm/isa.rb", "lib/ragweed/sbuf.rb", "lib/ragweed/trampoline.rb", "lib/ragweed/utils.rb", "lib/ragweed/wrap32.rb", "lib/ragweed/wrap32/debugging.rb", "lib/ragweed/wrap32/device.rb", "lib/ragweed/wrap32/event.rb", "lib/ragweed/wrap32/hooks.rb", "lib/ragweed/wrap32/overlapped.rb", "lib/ragweed/wrap32/process.rb", "lib/ragweed/wrap32/process_token.rb", "lib/ragweed/wrap32/thread_context.rb", "lib/ragweed/wrap32/winx.rb", "lib/ragweed/wrap32/wrap32.rb", "lib/ragweed/wraposx.rb", "lib/ragweed/wraposx/constants.rb", "lib/ragweed/wraposx/kernelerrorx.rb", "lib/ragweed/wraposx/region_info.rb", "lib/ragweed/wraposx/thread_context.rb", "lib/ragweed/wraposx/thread_info.rb", "lib/ragweed/wraposx/wraposx.rb", "lib/ragweed/wraptux.rb", "lib/ragweed/wraptux/constants.rb", "lib/ragweed/wraptux/threads.rb", "lib/ragweed/wraptux/wraptux.rb", "ragweed.gemspec", "spec/ragweed_spec.rb", "spec/spec_helper.rb", "tasks/ann.rake", "tasks/bones.rake", "tasks/gem.rake", "tasks/git.rake", "tasks/notes.rake", "tasks/post_load.rake", "tasks/rdoc.rake", "tasks/rubyforge.rake", "tasks/setup.rb", "tasks/spec.rake", "tasks/svn.rake", "tasks/test.rake", "tasks/zentest.rake", "test/test_ragweed.rb"]
|
14
|
+
s.homepage = %q{http://github.com/tduehr/ragweed/tree/master}
|
15
|
+
s.rdoc_options = ["--inline-source", "--line-numbers", "--main", "README.txt"]
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
s.rubyforge_project = %q{}
|
18
|
+
s.rubygems_version = %q{1.3.5}
|
19
|
+
s.summary = %q{Scriptable debugger}
|
20
|
+
s.test_files = ["test/test_ragweed.rb"]
|
21
|
+
|
22
|
+
if s.respond_to? :specification_version then
|
23
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
24
|
+
s.specification_version = 3
|
25
|
+
|
26
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
27
|
+
s.add_development_dependency(%q<bones>, [">= 2.5.1"])
|
28
|
+
else
|
29
|
+
s.add_dependency(%q<bones>, [">= 2.5.1"])
|
30
|
+
end
|
31
|
+
else
|
32
|
+
s.add_dependency(%q<bones>, [">= 2.5.1"])
|
33
|
+
end
|
34
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
require File.expand_path(
|
3
|
+
File.join(File.dirname(__FILE__), %w[.. lib ragweed]))
|
4
|
+
|
5
|
+
Spec::Runner.configure do |config|
|
6
|
+
# == Mock Framework
|
7
|
+
#
|
8
|
+
# RSpec uses it's own mocking framework by default. If you prefer to
|
9
|
+
# use mocha, flexmock or RR, uncomment the appropriate line:
|
10
|
+
#
|
11
|
+
# config.mock_with :mocha
|
12
|
+
# config.mock_with :flexmock
|
13
|
+
# config.mock_with :rr
|
14
|
+
end
|
15
|
+
|
16
|
+
# EOF
|
data/tasks/ann.rake
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
|
2
|
+
begin
|
3
|
+
require 'bones/smtp_tls'
|
4
|
+
rescue LoadError
|
5
|
+
require 'net/smtp'
|
6
|
+
end
|
7
|
+
require 'time'
|
8
|
+
|
9
|
+
namespace :ann do
|
10
|
+
|
11
|
+
# A prerequisites task that all other tasks depend upon
|
12
|
+
task :prereqs
|
13
|
+
|
14
|
+
file PROJ.ann.file do
|
15
|
+
ann = PROJ.ann
|
16
|
+
puts "Generating #{ann.file}"
|
17
|
+
File.open(ann.file,'w') do |fd|
|
18
|
+
fd.puts("#{PROJ.name} version #{PROJ.version}")
|
19
|
+
fd.puts(" by #{Array(PROJ.authors).first}") if PROJ.authors
|
20
|
+
fd.puts(" #{PROJ.url}") if PROJ.url.valid?
|
21
|
+
fd.puts(" (the \"#{PROJ.release_name}\" release)") if PROJ.release_name
|
22
|
+
fd.puts
|
23
|
+
fd.puts("== DESCRIPTION")
|
24
|
+
fd.puts
|
25
|
+
fd.puts(PROJ.description)
|
26
|
+
fd.puts
|
27
|
+
fd.puts(PROJ.changes.sub(%r/^.*$/, '== CHANGES'))
|
28
|
+
fd.puts
|
29
|
+
ann.paragraphs.each do |p|
|
30
|
+
fd.puts "== #{p.upcase}"
|
31
|
+
fd.puts
|
32
|
+
fd.puts paragraphs_of(PROJ.readme_file, p).join("\n\n")
|
33
|
+
fd.puts
|
34
|
+
end
|
35
|
+
fd.puts ann.text if ann.text
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
desc "Create an announcement file"
|
40
|
+
task :announcement => ['ann:prereqs', PROJ.ann.file]
|
41
|
+
|
42
|
+
desc "Send an email announcement"
|
43
|
+
task :email => ['ann:prereqs', PROJ.ann.file] do
|
44
|
+
ann = PROJ.ann
|
45
|
+
from = ann.email[:from] || Array(PROJ.authors).first || PROJ.email
|
46
|
+
to = Array(ann.email[:to])
|
47
|
+
|
48
|
+
### build a mail header for RFC 822
|
49
|
+
rfc822msg = "From: #{from}\n"
|
50
|
+
rfc822msg << "To: #{to.join(',')}\n"
|
51
|
+
rfc822msg << "Subject: [ANN] #{PROJ.name} #{PROJ.version}"
|
52
|
+
rfc822msg << " (#{PROJ.release_name})" if PROJ.release_name
|
53
|
+
rfc822msg << "\n"
|
54
|
+
rfc822msg << "Date: #{Time.new.rfc822}\n"
|
55
|
+
rfc822msg << "Message-Id: "
|
56
|
+
rfc822msg << "<#{"%.8f" % Time.now.to_f}@#{ann.email[:domain]}>\n\n"
|
57
|
+
rfc822msg << File.read(ann.file)
|
58
|
+
|
59
|
+
params = [:server, :port, :domain, :acct, :passwd, :authtype].map do |key|
|
60
|
+
ann.email[key]
|
61
|
+
end
|
62
|
+
|
63
|
+
params[3] = PROJ.email if params[3].nil?
|
64
|
+
|
65
|
+
if params[4].nil?
|
66
|
+
STDOUT.write "Please enter your e-mail password (#{params[3]}): "
|
67
|
+
params[4] = STDIN.gets.chomp
|
68
|
+
end
|
69
|
+
|
70
|
+
### send email
|
71
|
+
Net::SMTP.start(*params) {|smtp| smtp.sendmail(rfc822msg, from, to)}
|
72
|
+
end
|
73
|
+
end # namespace :ann
|
74
|
+
|
75
|
+
desc 'Alias to ann:announcement'
|
76
|
+
task :ann => 'ann:announcement'
|
77
|
+
|
78
|
+
CLOBBER << PROJ.ann.file
|
79
|
+
|
80
|
+
# EOF
|
data/tasks/bones.rake
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
if HAVE_BONES
|
3
|
+
|
4
|
+
namespace :bones do
|
5
|
+
|
6
|
+
desc 'Show the PROJ open struct'
|
7
|
+
task :debug do |t|
|
8
|
+
atr = if t.application.top_level_tasks.length == 2
|
9
|
+
t.application.top_level_tasks.pop
|
10
|
+
end
|
11
|
+
|
12
|
+
if atr then Bones::Debug.show_attr(PROJ, atr)
|
13
|
+
else Bones::Debug.show PROJ end
|
14
|
+
end
|
15
|
+
|
16
|
+
end # namespace :bones
|
17
|
+
|
18
|
+
end # HAVE_BONES
|
19
|
+
|
20
|
+
# EOF
|