bougyman-autumn 3.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. data/AUTHORS +11 -0
  2. data/CHANGELOG +511 -0
  3. data/MANIFEST +109 -0
  4. data/README +1141 -0
  5. data/README.textile +1175 -0
  6. data/Rakefile +75 -0
  7. data/autumn.gemspec +43 -0
  8. data/bin/autumn +11 -0
  9. data/lib/autumn/authentication.rb +238 -0
  10. data/lib/autumn/channel_leaf.rb +107 -0
  11. data/lib/autumn/coder.rb +166 -0
  12. data/lib/autumn/console_boot.rb +10 -0
  13. data/lib/autumn/ctcp.rb +250 -0
  14. data/lib/autumn/daemon.rb +207 -0
  15. data/lib/autumn/datamapper_hacks.rb +290 -0
  16. data/lib/autumn/foliater.rb +231 -0
  17. data/lib/autumn/formatting.rb +236 -0
  18. data/lib/autumn/generator.rb +231 -0
  19. data/lib/autumn/genesis.rb +190 -0
  20. data/lib/autumn/inheritable_attributes.rb +162 -0
  21. data/lib/autumn/leaf.rb +738 -0
  22. data/lib/autumn/log_facade.rb +49 -0
  23. data/lib/autumn/misc.rb +87 -0
  24. data/lib/autumn/resources/daemons/Anothernet.yml +3 -0
  25. data/lib/autumn/resources/daemons/AustHex.yml +29 -0
  26. data/lib/autumn/resources/daemons/Bahamut.yml +67 -0
  27. data/lib/autumn/resources/daemons/Dancer.yml +3 -0
  28. data/lib/autumn/resources/daemons/GameSurge.yml +3 -0
  29. data/lib/autumn/resources/daemons/IRCnet.yml +3 -0
  30. data/lib/autumn/resources/daemons/Ithildin.yml +7 -0
  31. data/lib/autumn/resources/daemons/KineIRCd.yml +56 -0
  32. data/lib/autumn/resources/daemons/PTlink.yml +6 -0
  33. data/lib/autumn/resources/daemons/QuakeNet.yml +20 -0
  34. data/lib/autumn/resources/daemons/RFC1459.yml +158 -0
  35. data/lib/autumn/resources/daemons/RFC2811.yml +16 -0
  36. data/lib/autumn/resources/daemons/RFC2812.yml +36 -0
  37. data/lib/autumn/resources/daemons/RatBox.yml +25 -0
  38. data/lib/autumn/resources/daemons/Ultimate.yml +24 -0
  39. data/lib/autumn/resources/daemons/Undernet.yml +6 -0
  40. data/lib/autumn/resources/daemons/Unreal.yml +110 -0
  41. data/lib/autumn/resources/daemons/_Other.yml +7 -0
  42. data/lib/autumn/resources/daemons/aircd.yml +33 -0
  43. data/lib/autumn/resources/daemons/bdq-ircd.yml +3 -0
  44. data/lib/autumn/resources/daemons/hybrid.yml +38 -0
  45. data/lib/autumn/resources/daemons/ircu.yml +67 -0
  46. data/lib/autumn/resources/daemons/tr-ircd.yml +8 -0
  47. data/lib/autumn/script.rb +74 -0
  48. data/lib/autumn/speciator.rb +165 -0
  49. data/lib/autumn/stem.rb +919 -0
  50. data/lib/autumn/stem_facade.rb +176 -0
  51. data/lib/autumn/tool/bin.rb +302 -0
  52. data/lib/autumn/tool/create.rb +48 -0
  53. data/lib/autumn/tool/project_creator.rb +110 -0
  54. data/lib/autumn/version.rb +3 -0
  55. data/lib/autumn.rb +6 -0
  56. data/lib/skel/Rakefile +135 -0
  57. data/lib/skel/config/global.yml +2 -0
  58. data/lib/skel/config/seasons/testing/database.yml +4 -0
  59. data/lib/skel/config/seasons/testing/leaves.yml +9 -0
  60. data/lib/skel/config/seasons/testing/season.yml +2 -0
  61. data/lib/skel/config/seasons/testing/stems.yml +10 -0
  62. data/lib/skel/leaves/administrator/README +20 -0
  63. data/lib/skel/leaves/administrator/controller.rb +67 -0
  64. data/lib/skel/leaves/administrator/views/autumn.txt.erb +1 -0
  65. data/lib/skel/leaves/administrator/views/reload.txt.erb +11 -0
  66. data/lib/skel/leaves/insulter/README +17 -0
  67. data/lib/skel/leaves/insulter/controller.rb +65 -0
  68. data/lib/skel/leaves/insulter/views/about.txt.erb +1 -0
  69. data/lib/skel/leaves/insulter/views/help.txt.erb +1 -0
  70. data/lib/skel/leaves/insulter/views/insult.txt.erb +1 -0
  71. data/lib/skel/leaves/scorekeeper/README +34 -0
  72. data/lib/skel/leaves/scorekeeper/config.yml +2 -0
  73. data/lib/skel/leaves/scorekeeper/controller.rb +104 -0
  74. data/lib/skel/leaves/scorekeeper/helpers/general.rb +64 -0
  75. data/lib/skel/leaves/scorekeeper/models/channel.rb +12 -0
  76. data/lib/skel/leaves/scorekeeper/models/person.rb +14 -0
  77. data/lib/skel/leaves/scorekeeper/models/pseudonym.rb +11 -0
  78. data/lib/skel/leaves/scorekeeper/models/score.rb +14 -0
  79. data/lib/skel/leaves/scorekeeper/tasks/stats.rake +17 -0
  80. data/lib/skel/leaves/scorekeeper/views/about.txt.erb +1 -0
  81. data/lib/skel/leaves/scorekeeper/views/change.txt.erb +5 -0
  82. data/lib/skel/leaves/scorekeeper/views/history.txt.erb +11 -0
  83. data/lib/skel/leaves/scorekeeper/views/points.txt.erb +5 -0
  84. data/lib/skel/leaves/scorekeeper/views/usage.txt.erb +1 -0
  85. data/lib/skel/log/README +1 -0
  86. data/lib/skel/script/console +28 -0
  87. data/lib/skel/script/destroy +48 -0
  88. data/lib/skel/script/generate +48 -0
  89. data/lib/skel/shared/README +1 -0
  90. data/lib/skel/tmp/README +1 -0
  91. data/spec/authentication_spec.rb +328 -0
  92. data/spec/channel_leaf_spec.rb +141 -0
  93. data/spec/coder_spec.rb +146 -0
  94. data/spec/ctcp_spec.rb +222 -0
  95. data/spec/daemon_spec.rb +202 -0
  96. data/spec/datamapper_hacks_spec.rb +164 -0
  97. data/tasks/authors.rake +30 -0
  98. data/tasks/bacon.rake +66 -0
  99. data/tasks/changelog.rake +18 -0
  100. data/tasks/copyright.rake +21 -0
  101. data/tasks/gem.rake +23 -0
  102. data/tasks/gem_installer.rake +76 -0
  103. data/tasks/install_dependencies.rake +6 -0
  104. data/tasks/manifest.rake +4 -0
  105. data/tasks/rcov.rake +23 -0
  106. data/tasks/release.rake +52 -0
  107. data/tasks/reversion.rake +8 -0
  108. data/tasks/setup.rake +24 -0
  109. data/tasks/yard.rake +4 -0
  110. metadata +187 -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,302 @@
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 which take an optional PIDFILE (-p/--pid) default to PROJECT.pid.\n"
156
+ txt << "* All commands take PROJECT as the directory the autumn bot lives in.\n"
157
+ txt << start_options.to_s << "\n"
158
+ txt << create_options.to_s << "\n"
159
+ #if is_windows?
160
+ #txt << %x{ruby #{rackup_path} --help}.split("\n").reject { |line| line.match(/^Usage:/) }.join("\n\t")
161
+ #else
162
+ #txt << %x{#{rackup_path} --help}.split("\n").reject { |line| line.match(/^Usage:/) }.join("\n\t")
163
+ #end
164
+ end # }}}
165
+
166
+ def start_options
167
+ @start_opts ||= OptionParser.new do |o|
168
+ o.banner = "Start/Restart Options"
169
+ o.on("-D", "--daemonize", "Daemonize the process") { |daem| @daemonize = true }
170
+ end
171
+ end
172
+
173
+ def al_root
174
+ require "pathname"
175
+ dir = nil
176
+ if ARGV.size == 1
177
+ dir = Pathname.new(ARGV.shift)
178
+ elsif ARGV.size > 1
179
+ $stderr.puts "Unknown options given #{ARGV.join(" ")}"
180
+ puts usage
181
+ exit 1
182
+ end
183
+ if dir.nil? or not dir.directory?
184
+ dir = Pathname.new(ENV["PWD"]).expand_path
185
+ $stderr.puts "Path to autumn tree not given or invalid, using #{dir}"
186
+ end
187
+ Object.const_set("AL_ROOT", dir.expand_path.to_s)
188
+ Dir.chdir(AL_ROOT)
189
+ end
190
+
191
+ ### Methods for commands {{{
192
+ def start # {{{
193
+ start_options.parse!(ARGV)
194
+ al_root
195
+
196
+ # Find the name of this app
197
+ puts "starting autumn"
198
+ if @daemonize
199
+ require "daemons"
200
+ Daemons.run_proc(Pathname.new(AL_ROOT).basename, :ARGV => ["start"], :dir_mode => :normal, :dir => "tmp", :multiple => false) do
201
+ start_autumn
202
+ end
203
+ puts "Autumn started in the background"
204
+ else
205
+ start_autumn
206
+ end
207
+ end # }}}
208
+
209
+ def start_autumn
210
+ require "autumn/genesis"
211
+ puts "Loading Autumn #{Autumn::VERSION}"
212
+ Autumn::Genesis.new.boot!
213
+ end
214
+
215
+ def create_options(opts = {})
216
+ @create_opts ||= OptionParser.new do |o|
217
+ o.banner = "Create Options"
218
+ o.on("-f", "--force", "Force creation if dir already exists") { |yn| opts[:force] = true }
219
+ o.on("-a", "--amend", "Update a tree") { |yn| opts[:amend] = true }
220
+ end
221
+ end
222
+
223
+ def create(command) # {{{
224
+ create_options(opts = {}).parse!(ARGV)
225
+ unless ARGV.size == 1
226
+ $stderr.puts "Invalid options given: #{ARGV.join(" ")}"
227
+ exit 1
228
+ end
229
+ project_name = ARGV.shift
230
+ if project_name.nil?
231
+ $stderr.puts "Must supply a valid project name, you gave none."
232
+ puts usage
233
+ exit 1
234
+ end
235
+ include_autumn
236
+ require 'autumn/tool/create'
237
+ Autumn::Tool::Create.create(project_name, opts)
238
+ end # }}}
239
+
240
+ def stop(command) # {{{
241
+ al_root
242
+ require "daemons"
243
+ Daemons.run_proc(Pathname.new(AL_ROOT).basename, :ARGV => ["stop"], :dir_mode => :normal, :dir => "tmp", :multiple => false) do
244
+ start_autumn
245
+ end
246
+ end # }}}
247
+
248
+ def status(command) # {{{
249
+ al_root
250
+ pn = Pathname.new(AL_ROOT)
251
+ unless pid_file = find_pid(pn.join("tmp", pn.basename.to_s + ".pid"))
252
+ $stderr.puts "No pid_file found! Autumn may not be started."
253
+ exit 1
254
+ end
255
+ puts "Pid file #{pid_file} found, PID is #{pid = File.read(pid_file).chomp}"
256
+ unless is_running?(pid.to_i)
257
+ $stderr.puts "PID #{pid} is not running"
258
+ exit 1
259
+ end
260
+ if is_windows?
261
+ wmi = WIN32OLE.connect("winmgmts://")
262
+ processes, ours = wmi.ExecQuery("select * from win32_process where ProcessId = #{pid}"), []
263
+ processes.each { |p| ours << [p.Name, p.CommandLine, p.VirtualSize, p.CreationDate, p.ExecutablePath, p.Status ] }
264
+ 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
265
+ else
266
+ require "pathname"
267
+ # Check for /proc
268
+ if File.directory?(proc_dir = Pathname.new("/proc"))
269
+ proc_dir = proc_dir.join(pid)
270
+ # If we have a "stat" file, we'll assume linux and get as much info
271
+ # as we can
272
+ if stat_file = proc_dir.join("stat") and stat_file.file?
273
+ stats = File.read(stat_file).split
274
+ puts "Autumn is running!\n\tCommand Line: %s\n\tVirtual Size: %s\n\tStarted: %s\n\tExec Path: %s\n\tStatus: %s" % [
275
+ File.read(proc_dir.join("cmdline")).split("\000").join(" "),
276
+ "%s k" % (stats[22].to_f / 1024),
277
+ File.mtime(proc_dir),
278
+ File.readlink(proc_dir.join("exe")),
279
+ stats[2]
280
+ ]
281
+ exit
282
+ end
283
+ end
284
+ # Fallthrough status, just print a ps
285
+ puts "Autumn process #{pid} is running!"
286
+ begin
287
+ puts %x{ps l #{pid}}
288
+ rescue
289
+ puts "No further information available"
290
+ end
291
+ end
292
+ end # }}}
293
+
294
+ ### End of command methods }}}
295
+ end # }}}
296
+ end
297
+ end
298
+ end
299
+
300
+ if $0 == __FILE__
301
+ Autumn::Tool::Bin::Cmd.run(ARGV)
302
+ end
@@ -0,0 +1,48 @@
1
+ # Copyright (c) 2008 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
4
+ require 'autumn/tool/project_creator'
5
+
6
+ module Autumn
7
+ module Tool
8
+
9
+ # Create is a simple class used to create new projects based on the proto
10
+ # directory.
11
+ #
12
+ # It is primarly used for this command:
13
+ #
14
+ # ramaze --create project
15
+ #
16
+ # where project is the directory you want the content put into.
17
+
18
+ class Create
19
+
20
+ # Default options passed to Create::create
21
+ # :proto is the directory to duplicate
22
+ # :amend no files may be overwritten but missing files will be added
23
+ # :force will overwrite existing files
24
+ # :layout copy one subdirectory in +proto+
25
+
26
+ DEFAULT = {
27
+ :proto => File.join(ROOT, 'skel'),
28
+ :amend => false,
29
+ :force => false,
30
+ :layout => '/',
31
+ }
32
+
33
+ # Using ProjectCreator to copy all files and directories from lib/proto
34
+ # to another location.
35
+ # +options+ are described in the DEFAULT constant and should be:
36
+ # :force => (true|false|nil)
37
+ # :amend => (true|false|nil)
38
+ # :layout => (String|nil)
39
+ # :proto => String
40
+
41
+ def self.create(project, options = {})
42
+ options = DEFAULT.merge(options)
43
+ creator = ProjectCreator.new(project, options)
44
+ creator.create
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,110 @@
1
+ # Copyright (c) 2008 Michael Fellinger m.fellinger@gmail.com
2
+ # All files in this distribution are subject to the terms of the Ruby license.
3
+
4
+ require 'fileutils'
5
+ require 'find'
6
+
7
+ class ProjectCreator
8
+ PROTO = []
9
+ PROTO << '~/.autumn_skel/' if ENV["HOME"] # Guard against Windows
10
+ attr_accessor :name, :options
11
+
12
+ def initialize(name, options = {})
13
+ @name, @options = name, options
14
+ end
15
+
16
+ def target
17
+ File.expand_path(name)
18
+ end
19
+
20
+ def proto
21
+ PROTO.map!{|pr| File.expand_path(pr) }
22
+ proto = options[:proto] ||= PROTO.find{|f| File.directory?(f) }
23
+ layout = options[:layout] ||= '/'
24
+ File.expand_path(File.join(proto, layout))
25
+ end
26
+
27
+ def create_root?
28
+ return true unless File.directory?(target)
29
+ return true if amend? or force?
30
+ fatal "%p is a directory, choose different project name or use --amend/--force" % target
31
+ end
32
+
33
+ def got_proto?
34
+ return true if File.directory?(proto)
35
+ fatal "Cannot create, %p doesn't exist, use --proto or create the proto directory" % proto
36
+ end
37
+
38
+ def create
39
+ got_proto?
40
+
41
+ puts "Found proto at: %p, proceeding...\n\n" % proto
42
+ mkdir(relate('/')) if create_root?
43
+ proceed
44
+ end
45
+
46
+ def proceed
47
+ files, directories = partition{|path| File.file?(path) }
48
+ proceed_directories(directories)
49
+ proceed_files(files)
50
+ end
51
+
52
+ def proceed_files(files)
53
+ files.each{|file| copy(file, relate(file)) }
54
+ end
55
+
56
+ def proceed_directories(dirs)
57
+ dirs.each{|dir| mkdir(relate(dir)) }
58
+ end
59
+
60
+ def mkdir(dir)
61
+ exists = File.directory?(dir)
62
+ return if exists and amend?
63
+ return if exists and not force?
64
+ puts "mkdir(%p)" % dir
65
+ FileUtils.mkdir_p(dir)
66
+ end
67
+
68
+ def copy(from, to)
69
+ return unless copy_check(to)
70
+ puts "copy(%p, %p)" % [from, to]
71
+ FileUtils.cp(from, to)
72
+ post_process(to)
73
+ end
74
+
75
+ def copy_check(to)
76
+ exists = File.file?(to)
77
+ return if exists and amend?
78
+ return if exists and not force?
79
+ return true
80
+ end
81
+
82
+ # Think about a useful way to process the generated files it should be
83
+ # possible to substitute some things like the project name in the
84
+ # configuration
85
+
86
+ def post_process(file)
87
+ source = File.read(file)
88
+ File.open(file, 'w+') do |io|
89
+ io.puts source.gsub('$${project}', @name)
90
+ end
91
+ end
92
+
93
+ def relate(path)
94
+ File.join(target, path.to_s.sub(proto, ''))
95
+ end
96
+
97
+ def amend?; options[:amend] end
98
+ def force?; options[:force] end
99
+
100
+ def fatal(message)
101
+ warn message
102
+ exit 1
103
+ end
104
+
105
+ def each
106
+ Dir["#{proto}/**/*"].each{|path| yield(path) }
107
+ end
108
+
109
+ include Enumerable
110
+ end
@@ -0,0 +1,3 @@
1
+ module Autumn
2
+ VERSION = "3.1.1"
3
+ end
data/lib/autumn.rb ADDED
@@ -0,0 +1,6 @@
1
+ require "pathname"
2
+ module Autumn
3
+ ROOT = Pathname.new(__FILE__).dirname.expand_path
4
+ end
5
+ $LOAD_PATH.unshift Autumn::ROOT
6
+ require "autumn/version"