autumn 3.1.8
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/AUTHORS +11 -0
- data/CHANGELOG +567 -0
- data/MANIFEST +110 -0
- data/README +1114 -0
- data/README.textile +1153 -0
- data/Rakefile +75 -0
- data/autumn.gemspec +44 -0
- data/bin/autumn +11 -0
- data/lib/autumn.rb +8 -0
- data/lib/autumn/authentication.rb +238 -0
- data/lib/autumn/channel_leaf.rb +107 -0
- data/lib/autumn/coder.rb +166 -0
- data/lib/autumn/console_boot.rb +10 -0
- data/lib/autumn/ctcp.rb +250 -0
- data/lib/autumn/daemon.rb +207 -0
- data/lib/autumn/datamapper_hacks.rb +290 -0
- data/lib/autumn/foliater.rb +231 -0
- data/lib/autumn/formatting.rb +236 -0
- data/lib/autumn/generator.rb +231 -0
- data/lib/autumn/genesis.rb +190 -0
- data/lib/autumn/inheritable_attributes.rb +162 -0
- data/lib/autumn/leaf.rb +738 -0
- data/lib/autumn/log_facade.rb +49 -0
- data/lib/autumn/misc.rb +87 -0
- data/lib/autumn/resources/daemons/Anothernet.yml +3 -0
- data/lib/autumn/resources/daemons/AustHex.yml +29 -0
- data/lib/autumn/resources/daemons/Bahamut.yml +67 -0
- data/lib/autumn/resources/daemons/Dancer.yml +3 -0
- data/lib/autumn/resources/daemons/GameSurge.yml +3 -0
- data/lib/autumn/resources/daemons/IRCnet.yml +3 -0
- data/lib/autumn/resources/daemons/Ithildin.yml +7 -0
- data/lib/autumn/resources/daemons/KineIRCd.yml +56 -0
- data/lib/autumn/resources/daemons/PTlink.yml +6 -0
- data/lib/autumn/resources/daemons/QuakeNet.yml +20 -0
- data/lib/autumn/resources/daemons/RFC1459.yml +158 -0
- data/lib/autumn/resources/daemons/RFC2811.yml +16 -0
- data/lib/autumn/resources/daemons/RFC2812.yml +36 -0
- data/lib/autumn/resources/daemons/RatBox.yml +25 -0
- data/lib/autumn/resources/daemons/Ultimate.yml +24 -0
- data/lib/autumn/resources/daemons/Undernet.yml +6 -0
- data/lib/autumn/resources/daemons/Unreal.yml +110 -0
- data/lib/autumn/resources/daemons/_Other.yml +7 -0
- data/lib/autumn/resources/daemons/aircd.yml +33 -0
- data/lib/autumn/resources/daemons/bdq-ircd.yml +3 -0
- data/lib/autumn/resources/daemons/hybrid.yml +38 -0
- data/lib/autumn/resources/daemons/ircu.yml +67 -0
- data/lib/autumn/resources/daemons/tr-ircd.yml +8 -0
- data/lib/autumn/script.rb +74 -0
- data/lib/autumn/speciator.rb +165 -0
- data/lib/autumn/stem.rb +919 -0
- data/lib/autumn/stem_facade.rb +176 -0
- data/lib/autumn/tool/bin.rb +301 -0
- data/lib/autumn/tool/create.rb +48 -0
- data/lib/autumn/tool/project_creator.rb +110 -0
- data/lib/autumn/version.rb +3 -0
- data/lib/skel/Rakefile +163 -0
- data/lib/skel/config/global.yml +2 -0
- data/lib/skel/config/seasons/testing/database.yml +4 -0
- data/lib/skel/config/seasons/testing/leaves.yml +9 -0
- data/lib/skel/config/seasons/testing/season.yml +2 -0
- data/lib/skel/config/seasons/testing/stems.yml +10 -0
- data/lib/skel/leaves/administrator/README +20 -0
- data/lib/skel/leaves/administrator/controller.rb +67 -0
- data/lib/skel/leaves/administrator/views/autumn.txt.erb +1 -0
- data/lib/skel/leaves/administrator/views/reload.txt.erb +11 -0
- data/lib/skel/leaves/insulter/README +17 -0
- data/lib/skel/leaves/insulter/controller.rb +65 -0
- data/lib/skel/leaves/insulter/views/about.txt.erb +1 -0
- data/lib/skel/leaves/insulter/views/help.txt.erb +1 -0
- data/lib/skel/leaves/insulter/views/insult.txt.erb +1 -0
- data/lib/skel/leaves/scorekeeper/README +34 -0
- data/lib/skel/leaves/scorekeeper/config.yml +2 -0
- data/lib/skel/leaves/scorekeeper/controller.rb +104 -0
- data/lib/skel/leaves/scorekeeper/helpers/general.rb +64 -0
- data/lib/skel/leaves/scorekeeper/models/channel.rb +12 -0
- data/lib/skel/leaves/scorekeeper/models/person.rb +14 -0
- data/lib/skel/leaves/scorekeeper/models/pseudonym.rb +11 -0
- data/lib/skel/leaves/scorekeeper/models/score.rb +14 -0
- data/lib/skel/leaves/scorekeeper/tasks/stats.rake +17 -0
- data/lib/skel/leaves/scorekeeper/views/about.txt.erb +1 -0
- data/lib/skel/leaves/scorekeeper/views/change.txt.erb +5 -0
- data/lib/skel/leaves/scorekeeper/views/history.txt.erb +11 -0
- data/lib/skel/leaves/scorekeeper/views/points.txt.erb +5 -0
- data/lib/skel/leaves/scorekeeper/views/usage.txt.erb +1 -0
- data/lib/skel/log/README +1 -0
- data/lib/skel/script/console +28 -0
- data/lib/skel/script/destroy +48 -0
- data/lib/skel/script/generate +48 -0
- data/lib/skel/shared/README +1 -0
- data/lib/skel/tmp/README +1 -0
- data/spec/authentication_spec.rb +328 -0
- data/spec/channel_leaf_spec.rb +142 -0
- data/spec/coder_spec.rb +146 -0
- data/spec/ctcp_spec.rb +222 -0
- data/spec/daemon_spec.rb +202 -0
- data/spec/datamapper_hacks_spec.rb +164 -0
- data/tasks/authors.rake +30 -0
- data/tasks/changelog.rake +18 -0
- data/tasks/copyright.rake +21 -0
- data/tasks/doc.rake +7 -0
- data/tasks/gem.rake +23 -0
- data/tasks/gem_installer.rake +76 -0
- data/tasks/install_dependencies.rake +6 -0
- data/tasks/manifest.rake +4 -0
- data/tasks/rcov.rake +23 -0
- data/tasks/release.rake +52 -0
- data/tasks/reversion.rake +8 -0
- data/tasks/setup.rake +24 -0
- data/tasks/spec.rake +7 -0
- data/tasks/yard.rake +4 -0
- metadata +188 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# Defines the Autumn::StemFacade class, which provides additional convenience
|
|
2
|
+
# methods to Autumn::Stem.
|
|
3
|
+
|
|
4
|
+
module Autumn
|
|
5
|
+
|
|
6
|
+
# A collection of convenience methods that are added to the Stem class. These
|
|
7
|
+
# methods serve two purposes; one, to allow easier backwards compatibility
|
|
8
|
+
# with Autumn Leaves 1.0 (which had a simpler one-stem-per-leaf approach), and
|
|
9
|
+
# two, to make it easier or more Ruby-like to perform certain IRC actions.
|
|
10
|
+
|
|
11
|
+
module StemFacade
|
|
12
|
+
|
|
13
|
+
# Sends a message to one or more channels or nicks. If no channels or nicks
|
|
14
|
+
# are specified, broadcasts the message to every channel the stem is in. If
|
|
15
|
+
# you are sending a message to a channel you must prefix it correctly; the
|
|
16
|
+
# "#" will not be added before the channel name for you.
|
|
17
|
+
#
|
|
18
|
+
# message "Look at me!" # Broadcasts to all channels
|
|
19
|
+
# message "I love kitties", '#kitties' # Sends a message to one channel or person
|
|
20
|
+
# message "Learn to RTFM", '#help', 'NoobGuy' # Sends a message to two channels or people
|
|
21
|
+
|
|
22
|
+
def message(msg, *chans)
|
|
23
|
+
return if msg.nil? or msg.empty?
|
|
24
|
+
chans = channels if chans.empty?
|
|
25
|
+
if @throttle then
|
|
26
|
+
Thread.exclusive { msg.each_line { |line| privmsgt chans.to_a, line.strip unless line.strip.empty? } }
|
|
27
|
+
else
|
|
28
|
+
msg.each_line { |line| privmsg chans.to_a, line.strip unless line.strip.empty? }
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Sets the topic for one or more channels. If no channels are specified,
|
|
33
|
+
# sets the topic of every channel the stem is in.
|
|
34
|
+
#
|
|
35
|
+
# set_topic "Bots sure are fun!", 'bots', 'morebots'
|
|
36
|
+
|
|
37
|
+
def set_topic(motd, *chans)
|
|
38
|
+
return if motd.nil?
|
|
39
|
+
chans = chans.empty? ? channels : chans.map { |chan| normalized_channel_name chan }
|
|
40
|
+
chans.each { |chan| topic chan, motd }
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Joins a channel by name. If the channel is password-protected, specify the
|
|
44
|
+
# +password+ parameter. Of course, you could always just call the +join+
|
|
45
|
+
# method (since each IRC command has a method named after it), but the
|
|
46
|
+
# advantage to using this method is that it will also update the
|
|
47
|
+
# <tt>@channel_passwords</tt> instance variable. Internal consistency is a
|
|
48
|
+
# good thing, so please use this method.
|
|
49
|
+
|
|
50
|
+
def join_channel(channel, password=nil)
|
|
51
|
+
channel = normalized_channel_name(channel)
|
|
52
|
+
return if channels.include? channel
|
|
53
|
+
join channel, password
|
|
54
|
+
@channel_passwords[channel] = password if password
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Leaves a channel, specified by name.
|
|
58
|
+
|
|
59
|
+
def leave_channel(channel)
|
|
60
|
+
channel = normalized_channel_name(channel)
|
|
61
|
+
return unless channels.include? channel
|
|
62
|
+
part channel
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Changes this stem's IRC nick. Note that the stem's original nick will
|
|
66
|
+
# still be used by the logger.
|
|
67
|
+
|
|
68
|
+
def change_nick(new_nick)
|
|
69
|
+
nick new_nick
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Grants a privilege to a channel member, such as voicing a member. The stem
|
|
73
|
+
# must have the required privilege level to perform this command.
|
|
74
|
+
# +privilege+ can either be a symbol from the Daemon instance or a string
|
|
75
|
+
# with the letter code for the privilege.
|
|
76
|
+
#
|
|
77
|
+
# grant_user_privilege 'mychannel', 'Somedude', :operator
|
|
78
|
+
# grant_user_privilege '#mychannel', 'Somedude', 'oa'
|
|
79
|
+
|
|
80
|
+
def grant_user_privilege(channel, nick, privilege)
|
|
81
|
+
channel = normalized_channel_name(channel)
|
|
82
|
+
privcode = server_type.privilege.index(privilege).chr if server_type.privilege.value? privilege
|
|
83
|
+
privcode ||= privilege
|
|
84
|
+
mode channel, "+#{privcode}", nick
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Removes a privilege to a channel member, such as voicing a member. The
|
|
88
|
+
# stem must have the required privilege level to perform this command.
|
|
89
|
+
# +privilege+ can either be a symbol from the Daemon instance or a string
|
|
90
|
+
# with the letter code for the privilege.
|
|
91
|
+
|
|
92
|
+
def remove_user_privilege(channel, nick, privilege)
|
|
93
|
+
channel = normalized_channel_name(channel)
|
|
94
|
+
privcode = server_type.privilege.index(privilege).chr if server_type.privilege.value? privilege
|
|
95
|
+
privcode ||= privilege
|
|
96
|
+
mode channel, "-#{privcode}", nick
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Grants a usermode to an IRC nick, such as making a nick invisible.
|
|
100
|
+
# The stem must have the required privilege level to perform this command.
|
|
101
|
+
# (Generally, one can only change his own usermode unless he is a server
|
|
102
|
+
# op.) +mode+ can either be a symbol from the Daemon instance or a string
|
|
103
|
+
# with the letter code for the usermode.
|
|
104
|
+
#
|
|
105
|
+
# grant_usermode 'Spycloak', :invisible
|
|
106
|
+
# grant_usermode 'UpMobility', 'os'
|
|
107
|
+
|
|
108
|
+
def grant_usermode(nick, property)
|
|
109
|
+
propcode = server_type.usermode.index(property).chr if server_type.usermode.value? property
|
|
110
|
+
propcode ||= property
|
|
111
|
+
mode nick, "+#{property}"
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Revokes a usermode from an IRC nick, such as removing invisibility. The
|
|
115
|
+
# stem must have the required privilege level to perform this command.
|
|
116
|
+
# (Generally, one can only change his own usermode unless he is a server
|
|
117
|
+
# op.) +mode+ can either be a symbol from the Daemon instance or a string
|
|
118
|
+
# with the letter code for the usermode.
|
|
119
|
+
|
|
120
|
+
def remove_usermode(nick, property)
|
|
121
|
+
propcode = server_type.usermode.index(property).chr if server_type.usermode.value? property
|
|
122
|
+
propcode ||= property
|
|
123
|
+
mode nick, "-#{property}"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Sets a property of a channel, such as moderated. The stem must have the
|
|
127
|
+
# required privilege level to perform this command. +property+ can either be
|
|
128
|
+
# a symbol from the Daemon instance or a string with the letter code for the
|
|
129
|
+
# property. If the property takes an argument (such as when setting a
|
|
130
|
+
# channel password), pass it as the +argument+ paramter.
|
|
131
|
+
#
|
|
132
|
+
# set_channel_property '#mychannel', :secret
|
|
133
|
+
# set_channel_property 'mychannel', :keylock, 'mypassword'
|
|
134
|
+
# set_channel_property '#mychannel', 'ntr'
|
|
135
|
+
|
|
136
|
+
def set_channel_property(channel, property, argument=nil)
|
|
137
|
+
channel = normalized_channel_name(channel)
|
|
138
|
+
propcode = server_type.channel_property.index(property).chr if server_type.channel_property.value? property
|
|
139
|
+
propcode ||= property
|
|
140
|
+
mode channel, "+#{propcode}", argument
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Removes a property of a channel, such as moderated. The stem must have the
|
|
144
|
+
# required privilege level to perform this command. +property+ can either be
|
|
145
|
+
# a symbol from the Daemon instance or a string with the letter code for the
|
|
146
|
+
# property. If the property takes an argument (such as when removing a
|
|
147
|
+
# channel password), pass it as the +argument+ paramter.
|
|
148
|
+
|
|
149
|
+
def unset_channel_property(channel, property, argument=nil)
|
|
150
|
+
channel = normalized_channel_name(channel)
|
|
151
|
+
propcode = server_type.channel_property.index(property).chr if server_type.channel_property.value? property
|
|
152
|
+
propcode ||= property
|
|
153
|
+
mode channel, "-#{propcode}", argument
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Returns an array of nicks for users that are in a channel.
|
|
157
|
+
|
|
158
|
+
def users(channel)
|
|
159
|
+
channel = normalized_channel_name(channel)
|
|
160
|
+
@chan_mutex.synchronize { @channel_members[channel] && @channel_members[channel].keys }
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Returns the privilege level of a channel member. The privilege level will
|
|
164
|
+
# be a symbol from the Daemon instance. Returns nil if the channel member
|
|
165
|
+
# doesn't exist or if the bot is not on the given channel. Returns an array
|
|
166
|
+
# of privileges if the server supports multiple privileges per user, and the
|
|
167
|
+
# user has more than one privilege.
|
|
168
|
+
#
|
|
169
|
+
# +user+ can be a nick or a sender hash.
|
|
170
|
+
|
|
171
|
+
def privilege(channel, user)
|
|
172
|
+
user = user[:nick] if user.kind_of? Hash
|
|
173
|
+
@chan_mutex.synchronize { @channel_members[channel] && @channel_members[channel][user] }
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require 'optparse'
|
|
3
|
+
### This module offers the functionality to start, stop, restart, create,
|
|
4
|
+
### Check status, or run a console of an autumn application
|
|
5
|
+
### see autumn -h for usage
|
|
6
|
+
module Autumn
|
|
7
|
+
module Tool
|
|
8
|
+
module Bin
|
|
9
|
+
module Helpers # Helper methods {{{
|
|
10
|
+
|
|
11
|
+
def default_pidfile # {{{
|
|
12
|
+
return @default_pidfile if @default_pidfile
|
|
13
|
+
al_root
|
|
14
|
+
pn = Pathname.new(AL_ROOT)
|
|
15
|
+
@default_pidfile = (pn.expand_path.join("tmp", pn.basename.to_s + ".pid")).strip
|
|
16
|
+
end # }}}
|
|
17
|
+
|
|
18
|
+
# We're really only concerned about win32ole, so we focus our check on its
|
|
19
|
+
# ability to load that
|
|
20
|
+
def is_windows? # {{{
|
|
21
|
+
return @is_win if @is_win
|
|
22
|
+
begin
|
|
23
|
+
require "win32ole"
|
|
24
|
+
rescue LoadError
|
|
25
|
+
end
|
|
26
|
+
@is_win ||= Object.const_defined?("WIN32OLE")
|
|
27
|
+
end # }}}
|
|
28
|
+
|
|
29
|
+
def is_running?(pid) # {{{
|
|
30
|
+
if is_windows?
|
|
31
|
+
wmi = WIN32OLE.connect("winmgmts://")
|
|
32
|
+
processes, ours = wmi.ExecQuery("select * from win32_process where ProcessId = #{pid}"), []
|
|
33
|
+
processes.each { |process| ours << process.Name }
|
|
34
|
+
ours.first.nil?
|
|
35
|
+
else
|
|
36
|
+
begin
|
|
37
|
+
prio = Process.getpriority(Process::PRIO_PROCESS, pid)
|
|
38
|
+
true
|
|
39
|
+
rescue Errno::ESRCH
|
|
40
|
+
false
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end # }}}
|
|
44
|
+
|
|
45
|
+
def check_running?(pid_file) # {{{
|
|
46
|
+
return false unless File.file?(pid_file)
|
|
47
|
+
is_running?(File.read(pid_file).to_i)
|
|
48
|
+
end # }}}
|
|
49
|
+
|
|
50
|
+
def find_pid(pid_file) # {{{
|
|
51
|
+
if pid_file.nil? or not File.file?(pid_file)
|
|
52
|
+
pid_file = default_pidfile
|
|
53
|
+
end
|
|
54
|
+
unless File.file?(pid_file)
|
|
55
|
+
$stderr.puts "Could not find running process id."
|
|
56
|
+
return false
|
|
57
|
+
end
|
|
58
|
+
pid_file
|
|
59
|
+
end # }}}
|
|
60
|
+
end # End helper methods }}}
|
|
61
|
+
|
|
62
|
+
class Cmd # This class contains the command methods {{{
|
|
63
|
+
include Helpers
|
|
64
|
+
attr_accessor :command
|
|
65
|
+
|
|
66
|
+
def initialize(args = nil)
|
|
67
|
+
args ||= ARGV
|
|
68
|
+
raise "arguments must be an array!" unless args.respond_to?(:detect)
|
|
69
|
+
@ourargs = args.dup
|
|
70
|
+
@command = args.detect { |arg| arg.match(/^(?:--?)?(?:start|stop|restart|create|h(?:elp)?|v(?:ersion)?|console|status)/) }
|
|
71
|
+
if command.nil?
|
|
72
|
+
@command = ""
|
|
73
|
+
else
|
|
74
|
+
args.delete(@command)
|
|
75
|
+
end
|
|
76
|
+
ARGV.replace(args)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# {{{ #run is called when we're interactive ($0 == __FILE__)
|
|
80
|
+
def self.run(args = nil)
|
|
81
|
+
cmd = new(args)
|
|
82
|
+
case cmd.command
|
|
83
|
+
when /^(?:--?)?status$/
|
|
84
|
+
cmd.status(cmd.command)
|
|
85
|
+
when /^(?:--?)?restart$/
|
|
86
|
+
cmd.stop(cmd.command)
|
|
87
|
+
cmd.start
|
|
88
|
+
when /^(?:--?)?start$/
|
|
89
|
+
cmd.start
|
|
90
|
+
when /^(?:--?)?create$/
|
|
91
|
+
cmd.create(cmd.command)
|
|
92
|
+
when /^(?:--?)?stop$/
|
|
93
|
+
if cmd.stop(cmd.command)
|
|
94
|
+
puts "Autumn session has ended."
|
|
95
|
+
$stdout.flush
|
|
96
|
+
else
|
|
97
|
+
puts "Autumn failed to stop (or was not running)"
|
|
98
|
+
end
|
|
99
|
+
when /^(?:--?)?console$/
|
|
100
|
+
require "irb"
|
|
101
|
+
require "irb/completion"
|
|
102
|
+
cmd.include_autumn
|
|
103
|
+
require "lib/genesis"
|
|
104
|
+
IRB.start
|
|
105
|
+
puts "Autumn session has ended."
|
|
106
|
+
when /^(?:--?)?h(elp)?$/
|
|
107
|
+
puts cmd.usage
|
|
108
|
+
when /^(?:--?)?v(ersion)?$/
|
|
109
|
+
cmd.include_autumn
|
|
110
|
+
puts Autumn::VERSION
|
|
111
|
+
exit
|
|
112
|
+
when /^$/
|
|
113
|
+
puts "Must supply a valid command"
|
|
114
|
+
puts cmd.usage
|
|
115
|
+
exit 1
|
|
116
|
+
else
|
|
117
|
+
puts "#{command} not implemented"
|
|
118
|
+
puts cmd.usage
|
|
119
|
+
exit 1
|
|
120
|
+
end
|
|
121
|
+
end # }}}
|
|
122
|
+
|
|
123
|
+
def include_autumn # {{{
|
|
124
|
+
begin
|
|
125
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '/../lib')
|
|
126
|
+
require 'autumn'
|
|
127
|
+
rescue LoadError
|
|
128
|
+
$LOAD_PATH.shift
|
|
129
|
+
|
|
130
|
+
begin
|
|
131
|
+
require 'rubygems'
|
|
132
|
+
rescue LoadError
|
|
133
|
+
end
|
|
134
|
+
require 'autumn'
|
|
135
|
+
end
|
|
136
|
+
end # }}}
|
|
137
|
+
|
|
138
|
+
def usage # {{{
|
|
139
|
+
txt = [
|
|
140
|
+
"\n Usage:",
|
|
141
|
+
"autumn <start|stop|restart|status|create|console> PROJECT [options]\n",
|
|
142
|
+
"Commands:\n",
|
|
143
|
+
" start - Starts an instance of this application.\n",
|
|
144
|
+
" stop - Stops a running instance of this application.\n",
|
|
145
|
+
" restart - Stops running instance of this application, then starts it back up. Pidfile",
|
|
146
|
+
" (if supplied) is used for both stop and start.\n",
|
|
147
|
+
" status - Gives status of a running autumn instance\n",
|
|
148
|
+
" create - Creates a new prototype Autumn application in a directory named PROJECT in",
|
|
149
|
+
" the current directory. autumn create foo would make ./foo containing an",
|
|
150
|
+
" application prototype.\n",
|
|
151
|
+
" console - Starts an irb console with autumn (and irb completion) loaded.",
|
|
152
|
+
" ARGV is passed on to IRB.\n\n"
|
|
153
|
+
].join("\n\t")
|
|
154
|
+
|
|
155
|
+
txt << "* All commands take PROJECT as the directory the autumn bot lives in.\n\n"
|
|
156
|
+
txt << start_options.to_s << "\n"
|
|
157
|
+
txt << create_options.to_s << "\n"
|
|
158
|
+
#if is_windows?
|
|
159
|
+
#txt << %x{ruby #{rackup_path} --help}.split("\n").reject { |line| line.match(/^Usage:/) }.join("\n\t")
|
|
160
|
+
#else
|
|
161
|
+
#txt << %x{#{rackup_path} --help}.split("\n").reject { |line| line.match(/^Usage:/) }.join("\n\t")
|
|
162
|
+
#end
|
|
163
|
+
end # }}}
|
|
164
|
+
|
|
165
|
+
def start_options
|
|
166
|
+
@start_opts ||= OptionParser.new do |o|
|
|
167
|
+
o.banner = "Start/Restart Options"
|
|
168
|
+
o.on("-D", "--daemonize", "Daemonize the process") { |daem| @daemonize = true }
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def al_root
|
|
173
|
+
require "pathname"
|
|
174
|
+
dir = nil
|
|
175
|
+
if ARGV.size == 1
|
|
176
|
+
dir = Pathname.new(ARGV.shift)
|
|
177
|
+
elsif ARGV.size > 1
|
|
178
|
+
$stderr.puts "Unknown options given #{ARGV.join(" ")}"
|
|
179
|
+
puts usage
|
|
180
|
+
exit 1
|
|
181
|
+
end
|
|
182
|
+
if dir.nil? or not dir.directory?
|
|
183
|
+
dir = Pathname.new(ENV["PWD"]).expand_path
|
|
184
|
+
$stderr.puts "Path to autumn tree not given or invalid, using #{dir}"
|
|
185
|
+
end
|
|
186
|
+
Object.const_set("AL_ROOT", dir.expand_path.to_s)
|
|
187
|
+
Dir.chdir(AL_ROOT)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
### Methods for commands {{{
|
|
191
|
+
def start # {{{
|
|
192
|
+
start_options.parse!(ARGV)
|
|
193
|
+
al_root
|
|
194
|
+
|
|
195
|
+
# Find the name of this app
|
|
196
|
+
puts "starting autumn"
|
|
197
|
+
if @daemonize
|
|
198
|
+
require "daemons"
|
|
199
|
+
Daemons.run_proc(Pathname.new(AL_ROOT).basename, :ARGV => ["start"], :dir_mode => :normal, :dir => "tmp", :multiple => false) do
|
|
200
|
+
start_autumn
|
|
201
|
+
end
|
|
202
|
+
puts "Autumn started in the background"
|
|
203
|
+
else
|
|
204
|
+
start_autumn
|
|
205
|
+
end
|
|
206
|
+
end # }}}
|
|
207
|
+
|
|
208
|
+
def start_autumn
|
|
209
|
+
require "autumn/genesis"
|
|
210
|
+
puts "Loading Autumn #{Autumn::VERSION}"
|
|
211
|
+
Autumn::Genesis.new.boot!
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def create_options(opts = {})
|
|
215
|
+
@create_opts ||= OptionParser.new do |o|
|
|
216
|
+
o.banner = "Create Options"
|
|
217
|
+
o.on("-f", "--force", "Force creation if dir already exists") { |yn| opts[:force] = true }
|
|
218
|
+
o.on("-a", "--amend", "Update a tree") { |yn| opts[:amend] = true }
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def create(command) # {{{
|
|
223
|
+
create_options(opts = {}).parse!(ARGV)
|
|
224
|
+
unless ARGV.size == 1
|
|
225
|
+
$stderr.puts "Invalid options given: #{ARGV.join(" ")}"
|
|
226
|
+
exit 1
|
|
227
|
+
end
|
|
228
|
+
project_name = ARGV.shift
|
|
229
|
+
if project_name.nil?
|
|
230
|
+
$stderr.puts "Must supply a valid project name, you gave none."
|
|
231
|
+
puts usage
|
|
232
|
+
exit 1
|
|
233
|
+
end
|
|
234
|
+
include_autumn
|
|
235
|
+
require 'autumn/tool/create'
|
|
236
|
+
Autumn::Tool::Create.create(project_name, opts)
|
|
237
|
+
end # }}}
|
|
238
|
+
|
|
239
|
+
def stop(command) # {{{
|
|
240
|
+
al_root
|
|
241
|
+
require "daemons"
|
|
242
|
+
Daemons.run_proc(Pathname.new(AL_ROOT).basename, :ARGV => ["stop"], :dir_mode => :normal, :dir => "tmp", :multiple => false) do
|
|
243
|
+
start_autumn
|
|
244
|
+
end
|
|
245
|
+
end # }}}
|
|
246
|
+
|
|
247
|
+
def status(command) # {{{
|
|
248
|
+
al_root
|
|
249
|
+
pn = Pathname.new(AL_ROOT)
|
|
250
|
+
unless pid_file = find_pid(pn.join("tmp", pn.basename.to_s + ".pid"))
|
|
251
|
+
$stderr.puts "No pid_file found! Autumn may not be started."
|
|
252
|
+
exit 1
|
|
253
|
+
end
|
|
254
|
+
puts "Pid file #{pid_file} found, PID is #{pid = File.read(pid_file).chomp}"
|
|
255
|
+
unless is_running?(pid.to_i)
|
|
256
|
+
$stderr.puts "PID #{pid} is not running"
|
|
257
|
+
exit 1
|
|
258
|
+
end
|
|
259
|
+
if is_windows?
|
|
260
|
+
wmi = WIN32OLE.connect("winmgmts://")
|
|
261
|
+
processes, ours = wmi.ExecQuery("select * from win32_process where ProcessId = #{pid}"), []
|
|
262
|
+
processes.each { |p| ours << [p.Name, p.CommandLine, p.VirtualSize, p.CreationDate, p.ExecutablePath, p.Status ] }
|
|
263
|
+
puts "Autumn is running!\n\tName: %s\n\tCommand Line: %s\n\tVirtual Size: %s\n\tStarted: %s\n\tExec Path: %s\n\tStatus: %s" % ours.first
|
|
264
|
+
else
|
|
265
|
+
require "pathname"
|
|
266
|
+
# Check for /proc
|
|
267
|
+
if File.directory?(proc_dir = Pathname.new("/proc"))
|
|
268
|
+
proc_dir = proc_dir.join(pid)
|
|
269
|
+
# If we have a "stat" file, we'll assume linux and get as much info
|
|
270
|
+
# as we can
|
|
271
|
+
if stat_file = proc_dir.join("stat") and stat_file.file?
|
|
272
|
+
stats = File.read(stat_file).split
|
|
273
|
+
puts "Autumn is running!\n\tCommand Line: %s\n\tVirtual Size: %s\n\tStarted: %s\n\tExec Path: %s\n\tStatus: %s" % [
|
|
274
|
+
File.read(proc_dir.join("cmdline")).split("\000").join(" "),
|
|
275
|
+
"%s k" % (stats[22].to_f / 1024),
|
|
276
|
+
File.mtime(proc_dir),
|
|
277
|
+
File.readlink(proc_dir.join("exe")),
|
|
278
|
+
stats[2]
|
|
279
|
+
]
|
|
280
|
+
exit
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
# Fallthrough status, just print a ps
|
|
284
|
+
puts "Autumn process #{pid} is running!"
|
|
285
|
+
begin
|
|
286
|
+
puts %x{ps l #{pid}}
|
|
287
|
+
rescue
|
|
288
|
+
puts "No further information available"
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
end # }}}
|
|
292
|
+
|
|
293
|
+
### End of command methods }}}
|
|
294
|
+
end # }}}
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
if $0 == __FILE__
|
|
300
|
+
Autumn::Tool::Bin::Cmd.run(ARGV)
|
|
301
|
+
end
|