carps 0.2.1

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.
Files changed (157) hide show
  1. data/COPYING +674 -0
  2. data/GEM_DESCRIPTION +10 -0
  3. data/History.txt +4 -0
  4. data/Manifest.txt +156 -0
  5. data/PostInstall.txt +20 -0
  6. data/README.rdoc +141 -0
  7. data/Rakefile +28 -0
  8. data/bin/carps +123 -0
  9. data/bin/carps_init +29 -0
  10. data/bin/carps_ipc_test +44 -0
  11. data/bin/carps_mod_saver_test +71 -0
  12. data/bin/carps_mod_test +62 -0
  13. data/config/website.yml +2 -0
  14. data/features/character_sheet.feature +40 -0
  15. data/features/crash.feature +15 -0
  16. data/features/crypt.feature +22 -0
  17. data/features/dice.feature +173 -0
  18. data/features/dm.feature +36 -0
  19. data/features/dmll.feature +51 -0
  20. data/features/edit.feature +10 -0
  21. data/features/email.feature +29 -0
  22. data/features/interface.feature +17 -0
  23. data/features/ipc.feature +10 -0
  24. data/features/mailbox.feature +33 -0
  25. data/features/mod.feature +31 -0
  26. data/features/parser.feature +9 -0
  27. data/features/persistent_protocol.feature +14 -0
  28. data/features/player.feature +22 -0
  29. data/features/player_turn.feature +29 -0
  30. data/features/random.feature +15 -0
  31. data/features/rule.feature +19 -0
  32. data/features/safety.feature +13 -0
  33. data/features/sessions.feature +16 -0
  34. data/features/start_dm.feature +18 -0
  35. data/features/start_player.feature +8 -0
  36. data/features/step_definitions/common_steps.rb +170 -0
  37. data/features/steps/character_sheet.rb +89 -0
  38. data/features/steps/crash.rb +27 -0
  39. data/features/steps/crypt.rb +166 -0
  40. data/features/steps/dice.rb +91 -0
  41. data/features/steps/dm.rb +147 -0
  42. data/features/steps/dmll.rb +47 -0
  43. data/features/steps/edit.rb +7 -0
  44. data/features/steps/email.rb +108 -0
  45. data/features/steps/general.rb +5 -0
  46. data/features/steps/interface.rb +64 -0
  47. data/features/steps/ipc.rb +22 -0
  48. data/features/steps/mailbox.rb +126 -0
  49. data/features/steps/mod.rb +25 -0
  50. data/features/steps/parser.rb +23 -0
  51. data/features/steps/persistent_protocol.rb +29 -0
  52. data/features/steps/player.rb +82 -0
  53. data/features/steps/player_turn.rb +56 -0
  54. data/features/steps/random.rb +47 -0
  55. data/features/steps/rule.rb +53 -0
  56. data/features/steps/safety.rb +17 -0
  57. data/features/steps/sessions.rb +37 -0
  58. data/features/steps/start_dm.rb +46 -0
  59. data/features/steps/start_player.rb +65 -0
  60. data/features/steps/timeout.rb +32 -0
  61. data/features/steps/type_verification.rb +36 -0
  62. data/features/steps/wizard.rb +123 -0
  63. data/features/support/common.rb +29 -0
  64. data/features/support/env.rb +14 -0
  65. data/features/support/matchers.rb +11 -0
  66. data/features/timeout.feature +11 -0
  67. data/features/type_verification.feature +48 -0
  68. data/features/wizard.feature +50 -0
  69. data/lib/carps/crypt/accept_handshake.rb +40 -0
  70. data/lib/carps/crypt/default_messages.rb +29 -0
  71. data/lib/carps/crypt/handshake.rb +41 -0
  72. data/lib/carps/crypt/mailbox.rb +265 -0
  73. data/lib/carps/crypt/mailer.rb +220 -0
  74. data/lib/carps/crypt/peer.rb +123 -0
  75. data/lib/carps/crypt/public_key.rb +60 -0
  76. data/lib/carps/crypt.rb +23 -0
  77. data/lib/carps/email/config.rb +122 -0
  78. data/lib/carps/email/imap.rb +156 -0
  79. data/lib/carps/email/smtp.rb +119 -0
  80. data/lib/carps/email/string.rb +30 -0
  81. data/lib/carps/email.rb +21 -0
  82. data/lib/carps/mod/action.rb +36 -0
  83. data/lib/carps/mod/answers.rb +76 -0
  84. data/lib/carps/mod/client_turn.rb +88 -0
  85. data/lib/carps/mod/dice.rb +360 -0
  86. data/lib/carps/mod/dm/interface.rb +160 -0
  87. data/lib/carps/mod/dm/mod.rb +409 -0
  88. data/lib/carps/mod/dm/reporter.rb +112 -0
  89. data/lib/carps/mod/dm/resource.rb +88 -0
  90. data/lib/carps/mod/dm/room.rb +33 -0
  91. data/lib/carps/mod/interface.rb +73 -0
  92. data/lib/carps/mod/launch.rb +108 -0
  93. data/lib/carps/mod/mod.rb +52 -0
  94. data/lib/carps/mod/player/interface.rb +76 -0
  95. data/lib/carps/mod/player/mod.rb +109 -0
  96. data/lib/carps/mod/question.rb +63 -0
  97. data/lib/carps/mod/rule.rb +112 -0
  98. data/lib/carps/mod/sheet/character.rb +82 -0
  99. data/lib/carps/mod/sheet/editor.rb +97 -0
  100. data/lib/carps/mod/sheet/new_sheet.rb +71 -0
  101. data/lib/carps/mod/sheet/schema.rb +84 -0
  102. data/lib/carps/mod/sheet/type.rb +161 -0
  103. data/lib/carps/mod/sheet/verifier.rb +41 -0
  104. data/lib/carps/mod/status_report.rb +51 -0
  105. data/lib/carps/mod.rb +40 -0
  106. data/lib/carps/protocol/keyword.rb +104 -0
  107. data/lib/carps/protocol/message.rb +138 -0
  108. data/lib/carps/protocol.rb +19 -0
  109. data/lib/carps/service/client_parser.rb +34 -0
  110. data/lib/carps/service/dm/config.rb +76 -0
  111. data/lib/carps/service/dm/mailer.rb +70 -0
  112. data/lib/carps/service/dm/new_game.rb +101 -0
  113. data/lib/carps/service/dm/start.rb +47 -0
  114. data/lib/carps/service/game.rb +101 -0
  115. data/lib/carps/service/interface.rb +174 -0
  116. data/lib/carps/service/invite.rb +79 -0
  117. data/lib/carps/service/mod.rb +43 -0
  118. data/lib/carps/service/player/config.rb +78 -0
  119. data/lib/carps/service/player/mailer.rb +49 -0
  120. data/lib/carps/service/player/start.rb +60 -0
  121. data/lib/carps/service/server_parser.rb +33 -0
  122. data/lib/carps/service/session.rb +96 -0
  123. data/lib/carps/service/start/config.rb +71 -0
  124. data/lib/carps/service/start/interface.rb +101 -0
  125. data/lib/carps/service/start/mailer.rb +46 -0
  126. data/lib/carps/service.rb +35 -0
  127. data/lib/carps/test.rb +34 -0
  128. data/lib/carps/ui/colour.rb +28 -0
  129. data/lib/carps/ui/error.rb +39 -0
  130. data/lib/carps/ui/highlight.rb +32 -0
  131. data/lib/carps/ui/question.rb +63 -0
  132. data/lib/carps/ui/warn.rb +37 -0
  133. data/lib/carps/ui.rb +21 -0
  134. data/lib/carps/util/config.rb +162 -0
  135. data/lib/carps/util/editor.rb +147 -0
  136. data/lib/carps/util/error.rb +75 -0
  137. data/lib/carps/util/files.rb +48 -0
  138. data/lib/carps/util/init.rb +93 -0
  139. data/lib/carps/util/process.rb +150 -0
  140. data/lib/carps/util/timeout.rb +31 -0
  141. data/lib/carps/util/windows.rb +29 -0
  142. data/lib/carps/util.rb +24 -0
  143. data/lib/carps/wizard/dm.rb +41 -0
  144. data/lib/carps/wizard/player.rb +40 -0
  145. data/lib/carps/wizard/steps.rb +494 -0
  146. data/lib/carps/wizard/wizard.rb +126 -0
  147. data/lib/carps/wizard.rb +21 -0
  148. data/lib/carps.rb +45 -0
  149. data/permission +16 -0
  150. data/script/console +10 -0
  151. data/script/destroy +14 -0
  152. data/script/generate +14 -0
  153. data/tasks/readme_site.rake +28 -0
  154. data/test/test_carps.rb +11 -0
  155. data/test/test_helper.rb +3 -0
  156. data/website/index.html +271 -0
  157. metadata +304 -0
@@ -0,0 +1,39 @@
1
+ # Copyright 2010 John Morrice
2
+
3
+ # This file is part of CARPS.
4
+
5
+ # CARPS is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+
10
+ # CARPS is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with CARPS. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ require "carps/ui/colour"
19
+
20
+ module CARPS
21
+
22
+ module UI
23
+
24
+ # Output an error message
25
+ #
26
+ # If the second parameter is true, the error message will begin with
27
+ # "Error:"
28
+ def UI::put_error msg, default_error=true
29
+ h = HighLine.new
30
+ prelude = ""
31
+ if default_error
32
+ prelude = "Error: "
33
+ end
34
+ $stderr.write h.color("#{prelude}#{msg}", :error)
35
+ puts "\a"
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,32 @@
1
+ # Copyright 2010 John Morrice
2
+
3
+ # This file is part of CARPS.
4
+
5
+ # CARPS is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+
10
+ # CARPS is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with CARPS. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ require "highline"
19
+
20
+ module CARPS
21
+
22
+ module UI
23
+
24
+ # Highlight text
25
+ def UI::highlight text
26
+ h = HighLine.new
27
+ puts h.color text, :magenta, :bold
28
+ end
29
+
30
+ end
31
+
32
+ end
@@ -0,0 +1,63 @@
1
+ # Copyright 2010 John Morrice
2
+
3
+ # This file is part of CARPS.
4
+
5
+ # CARPS is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+
10
+ # CARPS is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with CARPS. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ require "highline"
19
+
20
+ require "carps/ui/colour"
21
+
22
+ module CARPS
23
+
24
+ module UI
25
+
26
+ # Because we mess with the modes, and we're meant to run in a safe environment, need to hack highline.
27
+ HighLine::SystemExtensions.module_eval do
28
+ def restore_mode
29
+ @state.untaint
30
+ system "stty #{@state}"
31
+ end
32
+ end
33
+
34
+ # Ask a question, return a boolean
35
+ def UI::confirm question
36
+ h = HighLine.new
37
+ resp = h.ask h.color("#{question}\n(Type anything beginning with y to accept)", :green)
38
+ resp[0] == "y"
39
+ end
40
+
41
+ # Ask a question. Get a string for an answer
42
+ #
43
+ # Calls untaint on the answer
44
+ def UI::question msg
45
+ h = HighLine.new
46
+ res = h.ask h.color(msg, :green)
47
+ # Trust the user
48
+ res.untaint
49
+ end
50
+
51
+ # Ask a question and don't echo what is typed.
52
+ #
53
+ # Calls untaint on the password
54
+ def UI::secret msg
55
+ h = HighLine.new
56
+ ooh = h.ask(h.color(msg, :green)) {|q| q.echo = "*"}
57
+ h.untaint
58
+ ooh
59
+ end
60
+
61
+ end
62
+
63
+ end
@@ -0,0 +1,37 @@
1
+ # Copyright 2010 John Morrice
2
+
3
+ # This file is part of CARPS.
4
+
5
+ # CARPS is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+
10
+ # CARPS is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with CARPS. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ require "carps/ui/colour"
19
+
20
+ module CARPS
21
+
22
+ module UI
23
+
24
+ # Print a warning message to stderr
25
+ def UI::warn reason, *msgs
26
+ h = HighLine.new
27
+ $stderr.write h.color("Warning:\n", :warning)
28
+ $stderr.write h.color(reason + "\n", :warning)
29
+ msgs.each do |msg|
30
+ $stderr.write msg + "\n"
31
+ end
32
+ puts "\a"
33
+ end
34
+
35
+ end
36
+
37
+ end
data/lib/carps/ui.rb ADDED
@@ -0,0 +1,21 @@
1
+ # Copyright 2010 John Morrice
2
+
3
+ # This file is part of CARPS.
4
+
5
+ # CARPS is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+
10
+ # CARPS is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with CARPS. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ require "carps/ui/error"
19
+ require "carps/ui/warn"
20
+ require "carps/ui/question"
21
+ require "carps/ui/highlight"
@@ -0,0 +1,162 @@
1
+ # Copyright 2010 John Morrice
2
+
3
+ # This file is part of CARPS.
4
+
5
+ # CARPS is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+
10
+ # CARPS is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with CARPS. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ require "carps/util/error"
19
+
20
+ require "carps/ui/warn"
21
+
22
+ require "yaml"
23
+
24
+ module CARPS
25
+
26
+ # Configuration files that read yaml
27
+ class YamlConfig
28
+
29
+ # Should we fail hard, quiting the program?
30
+ def fail_hard fatal
31
+ @fatal = fatal
32
+ end
33
+
34
+ # Read a resource using the subclass' parse_yaml.
35
+ #
36
+ # Then load this resource using the subclass' load_resource
37
+ def read filepath
38
+ filepath = $CONFIG + filepath
39
+ contents = ""
40
+ result = nil
41
+ # Try to read the file
42
+ begin
43
+ contents = File.read filepath
44
+ rescue
45
+ # On failure, write a message to stderr and exit
46
+ err "Could not read configuration file: " + filepath
47
+ end
48
+
49
+ # Try to parse the file
50
+ begin
51
+ conf = YAML.load contents
52
+ result = parse_yaml conf
53
+ rescue
54
+ err "Error parsing #{filepath}:\n#{$!}"
55
+ end
56
+
57
+ if result
58
+ load_resources *result
59
+ end
60
+ end
61
+
62
+ protected
63
+
64
+ # Save as a YAML file
65
+ def save_file path
66
+ y = emit.to_yaml
67
+ begin
68
+ file = File.new $CONFIG + path, "w"
69
+ file.write y
70
+ file.close
71
+ rescue StandardError => e
72
+ UI::warn "Could not save #{self.class} as #{path}: #{e}"
73
+ end
74
+ end
75
+
76
+ # Emit as yaml
77
+ def emit
78
+ end
79
+
80
+ # Subclasses must create a method parse_yaml which takes YAML returns an array
81
+ def parse_yaml conf
82
+ []
83
+ end
84
+
85
+ # Subclasses may create a method load_resource
86
+ #
87
+ # This is called after parse_yaml - hence errors which occur here are not attributed to parsing the configuration file
88
+ #
89
+ # Takes each element of parse_yaml's return array as an argument, as in
90
+ # it is called with the result of parse_yaml, like so:
91
+ #
92
+ # load_resources *parse_yaml conf
93
+ def load_resources *forget
94
+ end
95
+
96
+ # Attempt to find field within the conf hash
97
+ #
98
+ # Untaints the field.
99
+ def read_conf conf, field
100
+ unless conf.include? field
101
+ raise "Could not find field: #{field}"
102
+ end
103
+ conf[field].untaint
104
+ end
105
+
106
+ # Raise error
107
+ def err msg
108
+ if @fatal
109
+ CARPS::fatal msg
110
+ else
111
+ raise StandardError, msg
112
+ end
113
+ end
114
+
115
+ end
116
+
117
+ # User configurations, which may be stored in many files
118
+ # and which should not crash the system on an error
119
+ class UserConfig < YamlConfig
120
+
121
+ # Subclasses must call super
122
+ def initialize
123
+ fail_hard false
124
+ end
125
+
126
+ # Load a user file.
127
+ def self.load filepath
128
+ config = self.allocate
129
+ config.read filepath
130
+ config.fail_hard false
131
+ config
132
+ end
133
+
134
+ end
135
+
136
+ # System configurations, which exist in strictly predefined locations
137
+ # and which should crash the system if they do not exist, because they
138
+ # are critical to its operation.
139
+ class SystemConfig < YamlConfig
140
+
141
+ # Subclasses must call super
142
+ def initialize
143
+ fail_hard true
144
+ end
145
+
146
+ # Load a system file.
147
+ def self.load
148
+ config = self.allocate
149
+ config.read self.filepath
150
+ config.fail_hard false
151
+ config
152
+ end
153
+
154
+ # Save the user config
155
+ def save
156
+ save_file self.class.filepath
157
+ end
158
+
159
+
160
+ end
161
+
162
+ end
@@ -0,0 +1,147 @@
1
+ # Copyright 2010 John Morrice
2
+
3
+ # This file is part of CARPS.
4
+
5
+ # CARPS is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+
10
+ # CARPS is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with CARPS. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ require "carps/util"
19
+
20
+ require "carps/ui/error"
21
+
22
+ require "carps/test"
23
+
24
+ require "fileutils"
25
+
26
+ require "tempfile"
27
+
28
+ module CARPS
29
+
30
+ # Expects a field called "launch_editor"
31
+ class Editor < SystemConfig
32
+
33
+ def Editor.filepath
34
+ "editor.yaml"
35
+ end
36
+
37
+ def initialize editor, wait_for_confirm = false
38
+ @editor = editor
39
+ @wait_confirm = wait_for_confirm
40
+ end
41
+
42
+ def parse_yaml config
43
+ @editor = read_conf config, "launch_editor"
44
+ @wait_confirm = read_conf config, "wait"
45
+ end
46
+
47
+ # Edit a string
48
+ #
49
+ # Performs an untaint operation
50
+ #
51
+ # Not re-entrant
52
+ def edit msg
53
+ begin
54
+ dir = Dir.tmpdir.untaint
55
+ unless File.exists?(dir)
56
+ FileUtils.mkdir dir
57
+ end
58
+ file = Tempfile.new "carp_edit", dir
59
+ path = file.path
60
+ file.write "# Lines starting with # will be ignored.\n" + msg
61
+ file.close
62
+ contents = edit_file path
63
+ contents.untaint
64
+ lines = contents.split /\n/
65
+ lines.reject! do |line|
66
+ line[0] == '#'
67
+ end
68
+ lines.join "\n"
69
+ rescue StandardError => e
70
+ UI::put_error e.to_s
71
+ nil
72
+ end
73
+ end
74
+
75
+ protected
76
+
77
+ def edit_file filepath
78
+ system @editor.gsub("%f", filepath)
79
+
80
+ if @wait_confirm
81
+ UI::question "Press enter when you are done editing."
82
+ end
83
+
84
+ if File.exists? filepath
85
+ return File.read filepath
86
+ else
87
+ return ""
88
+ end
89
+ end
90
+
91
+
92
+ # Emit as hash
93
+ def emit
94
+ {
95
+ "launch_editor" => @editor,
96
+ "wait" => @wait_confirm
97
+ }
98
+ end
99
+
100
+ end
101
+
102
+ module Test
103
+
104
+
105
+ # Testing for editor
106
+ module Editor
107
+
108
+ def Editor::load_fail
109
+ Editor::test_failed "The editor did not load the file correctly."
110
+ end
111
+
112
+ def Editor::save_fail
113
+ Editor::test_failed "The editor did not save the file correctly."
114
+ end
115
+
116
+ end
117
+
118
+ # Test the editor
119
+ def Test::editor editor
120
+ puts "The editor should launch, then you should edit this paragraph:"
121
+ before = "Please edit me."
122
+ puts before
123
+ puts "Once you are done editing, save the file and close the editor."
124
+ if after = editor.edit(before)
125
+ if after == before
126
+ Test::multi_fail "Your editor is detaching itself into the background.", "You did not edit the paragraph. Do so!", "The editor did not save the file correctly.", "The editor did not load the file correctly."
127
+ else
128
+ before_good = UI::confirm "Before you starting editing, did the editor display this text?\n#{before}"
129
+ if before_good
130
+ after_good = UI::confirm "Did you change that to this?\n#{after}"
131
+ if after_good
132
+ return true
133
+ else
134
+ Editor::save_fail
135
+ end
136
+ else
137
+ Editor::load_fail
138
+ end
139
+ end
140
+ else
141
+ Editor::save_fail
142
+ end
143
+
144
+ end
145
+ end
146
+
147
+ end
@@ -0,0 +1,75 @@
1
+ # Copyright 2010 John Morrice
2
+
3
+ # This file is part of CARPS.
4
+
5
+ # CARPS is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+
10
+ # CARPS is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with CARPS. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ require "carps/ui"
19
+ require "carps/util"
20
+
21
+ module CARPS
22
+
23
+
24
+ # Press enter to quit
25
+ def CARPS::enter_quit status=0
26
+ UI::question "Press enter to quit."
27
+ CARPS::shutdown_properly status
28
+ end
29
+
30
+ # Output an error message and quit with exit code 1
31
+ def CARPS::fatal msg
32
+ h = HighLine.new
33
+ $stderr.write h.color("\nFATAL ERROR\n#{msg}\n", :error)
34
+ puts "\a"
35
+ exit 1
36
+ end
37
+
38
+
39
+ # Kill all threads and exit with status
40
+ def CARPS::shutdown_properly status
41
+ # Stop all threads
42
+ Thread.list.each do |thr|
43
+ unless thr == Thread.main
44
+ Thread.kill thr
45
+ thr.join
46
+ end
47
+ end
48
+ exit status
49
+ end
50
+
51
+ # Catch errors and print out a stack trace if they occur.
52
+ #
53
+ # If wait is true, then wait for the user to press enter.
54
+ #
55
+ # Pass a block.
56
+ #
57
+ # Intented to be run at the top level (Eg by the binaries)
58
+ def CARPS::with_crash_report wait=false
59
+ begin
60
+ yield
61
+ rescue SystemExit => e
62
+ CARPS::shutdown_properly e.status
63
+ rescue Interrupt => e
64
+ CARPS::shutdown_properly 1
65
+ rescue Exception => e
66
+ UI::put_error "CRASHED!\n#{e.class} reports:\n #{e.message}\n\nStack trace:\n#{e.backtrace.join("\n")}", false
67
+ if wait
68
+ CARPS::enter_quit 1
69
+ else
70
+ CARPS::shutdown_properly 1
71
+ end
72
+ end
73
+ end
74
+
75
+ end
@@ -0,0 +1,48 @@
1
+ # Copyright 2010 John Morrice
2
+
3
+ # This file is part of CARPS.
4
+
5
+ # CARPS is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+
10
+ # CARPS is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with CARPS. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ module CARPS
19
+
20
+ # Get the file names from inside a directory
21
+ def files dir
22
+ file_names = Dir.open(dir).entries.reject do |file|
23
+ file.untaint
24
+ file[0] == "." or File.ftype(dir + "/" + file) != "file"
25
+ end
26
+ file_names.map do |fn|
27
+ dir + "/" + fn
28
+ end
29
+ end
30
+
31
+ # Write contents into a new file in a directory with an arbitrary, unique name
32
+ #
33
+ # Returns the path
34
+ def write_file_in dir, contents
35
+ t = Time.now
36
+ valid_path = false
37
+ path = $CONFIG + dir + "/" + t.to_f.to_s.gsub(/(\.|@, \?!#'"~\(\))/, "")
38
+ until valid_path
39
+ path += "_"
40
+ valid_path = not(File.exists?(path))
41
+ end
42
+ file = File.new path, "w"
43
+ file.write contents
44
+ file.close
45
+ path
46
+ end
47
+
48
+ end