amp 0.5.2 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (232) hide show
  1. data/.gitignore +12 -0
  2. data/.hgignore +3 -0
  3. data/AUTHORS +1 -1
  4. data/Manifest.txt +99 -38
  5. data/README.md +3 -3
  6. data/Rakefile +53 -18
  7. data/SCHEDULE.markdown +5 -1
  8. data/TODO.markdown +120 -149
  9. data/ampfile.rb +3 -1
  10. data/bin/amp +4 -1
  11. data/ext/amp/bz2/extconf.rb +1 -1
  12. data/ext/amp/mercurial_patch/extconf.rb +1 -1
  13. data/ext/amp/mercurial_patch/mpatch.c +4 -3
  14. data/ext/amp/priority_queue/extconf.rb +1 -1
  15. data/ext/amp/support/extconf.rb +1 -1
  16. data/ext/amp/support/support.c +1 -1
  17. data/lib/amp.rb +125 -67
  18. data/lib/amp/commands/command.rb +12 -10
  19. data/lib/amp/commands/command_support.rb +8 -1
  20. data/lib/amp/commands/commands/help.rb +2 -20
  21. data/lib/amp/commands/commands/init.rb +14 -2
  22. data/lib/amp/commands/commands/templates.rb +6 -4
  23. data/lib/amp/commands/commands/version.rb +15 -1
  24. data/lib/amp/commands/commands/workflow.rb +3 -3
  25. data/lib/amp/commands/commands/workflows/git/add.rb +3 -3
  26. data/lib/amp/commands/commands/workflows/git/copy.rb +1 -1
  27. data/lib/amp/commands/commands/workflows/git/rm.rb +4 -2
  28. data/lib/amp/commands/commands/workflows/hg/add.rb +1 -1
  29. data/lib/amp/commands/commands/workflows/hg/addremove.rb +2 -2
  30. data/lib/amp/commands/commands/workflows/hg/annotate.rb +8 -2
  31. data/lib/amp/commands/commands/workflows/hg/bisect.rb +253 -0
  32. data/lib/amp/commands/commands/workflows/hg/branch.rb +1 -1
  33. data/lib/amp/commands/commands/workflows/hg/branches.rb +3 -3
  34. data/lib/amp/commands/commands/workflows/hg/bundle.rb +3 -3
  35. data/lib/amp/commands/commands/workflows/hg/clone.rb +4 -5
  36. data/lib/amp/commands/commands/workflows/hg/commit.rb +37 -1
  37. data/lib/amp/commands/commands/workflows/hg/copy.rb +2 -1
  38. data/lib/amp/commands/commands/workflows/hg/debug/index.rb +1 -1
  39. data/lib/amp/commands/commands/workflows/hg/diff.rb +3 -8
  40. data/lib/amp/commands/commands/workflows/hg/forget.rb +5 -4
  41. data/lib/amp/commands/commands/workflows/hg/identify.rb +6 -6
  42. data/lib/amp/commands/commands/workflows/hg/import.rb +1 -1
  43. data/lib/amp/commands/commands/workflows/hg/incoming.rb +2 -2
  44. data/lib/amp/commands/commands/workflows/hg/log.rb +5 -4
  45. data/lib/amp/commands/commands/workflows/hg/merge.rb +1 -1
  46. data/lib/amp/commands/commands/workflows/hg/move.rb +5 -3
  47. data/lib/amp/commands/commands/workflows/hg/outgoing.rb +1 -1
  48. data/lib/amp/commands/commands/workflows/hg/push.rb +6 -7
  49. data/lib/amp/commands/commands/workflows/hg/remove.rb +2 -2
  50. data/lib/amp/commands/commands/workflows/hg/resolve.rb +6 -23
  51. data/lib/amp/commands/commands/workflows/hg/root.rb +1 -2
  52. data/lib/amp/commands/commands/workflows/hg/status.rb +21 -12
  53. data/lib/amp/commands/commands/workflows/hg/tag.rb +2 -2
  54. data/lib/amp/commands/commands/workflows/hg/untrack.rb +12 -0
  55. data/lib/amp/commands/commands/workflows/hg/verify.rb +13 -3
  56. data/lib/amp/commands/commands/workflows/hg/what_changed.rb +18 -0
  57. data/lib/amp/commands/dispatch.rb +12 -13
  58. data/lib/amp/dependencies/amp_support.rb +1 -1
  59. data/lib/amp/dependencies/amp_support/ruby_amp_support.rb +1 -0
  60. data/lib/amp/dependencies/maruku.rb +136 -0
  61. data/lib/amp/dependencies/maruku/attributes.rb +227 -0
  62. data/lib/amp/dependencies/maruku/defaults.rb +71 -0
  63. data/lib/amp/dependencies/maruku/errors_management.rb +92 -0
  64. data/lib/amp/dependencies/maruku/helpers.rb +260 -0
  65. data/lib/amp/dependencies/maruku/input/charsource.rb +326 -0
  66. data/lib/amp/dependencies/maruku/input/extensions.rb +69 -0
  67. data/lib/amp/dependencies/maruku/input/html_helper.rb +189 -0
  68. data/lib/amp/dependencies/maruku/input/linesource.rb +111 -0
  69. data/lib/amp/dependencies/maruku/input/parse_block.rb +615 -0
  70. data/lib/amp/dependencies/maruku/input/parse_doc.rb +234 -0
  71. data/lib/amp/dependencies/maruku/input/parse_span_better.rb +746 -0
  72. data/lib/amp/dependencies/maruku/input/rubypants.rb +225 -0
  73. data/lib/amp/dependencies/maruku/input/type_detection.rb +147 -0
  74. data/lib/amp/dependencies/maruku/input_textile2/t2_parser.rb +163 -0
  75. data/lib/amp/dependencies/maruku/maruku.rb +33 -0
  76. data/lib/amp/dependencies/maruku/output/to_ansi.rb +223 -0
  77. data/lib/amp/dependencies/maruku/output/to_html.rb +991 -0
  78. data/lib/amp/dependencies/maruku/output/to_markdown.rb +164 -0
  79. data/lib/amp/dependencies/maruku/output/to_s.rb +56 -0
  80. data/lib/amp/dependencies/maruku/string_utils.rb +191 -0
  81. data/lib/amp/dependencies/maruku/structures.rb +167 -0
  82. data/lib/amp/dependencies/maruku/structures_inspect.rb +87 -0
  83. data/lib/amp/dependencies/maruku/structures_iterators.rb +61 -0
  84. data/lib/amp/dependencies/maruku/textile2.rb +1 -0
  85. data/lib/amp/dependencies/maruku/toc.rb +199 -0
  86. data/lib/amp/dependencies/maruku/usage/example1.rb +33 -0
  87. data/lib/amp/dependencies/maruku/version.rb +40 -0
  88. data/lib/amp/dependencies/priority_queue.rb +2 -1
  89. data/lib/amp/dependencies/python_config.rb +2 -1
  90. data/lib/amp/graphs/ancestor.rb +2 -1
  91. data/lib/amp/graphs/copies.rb +236 -233
  92. data/lib/amp/help/entries/__default__.erb +31 -0
  93. data/lib/amp/help/entries/commands.erb +6 -0
  94. data/lib/amp/help/entries/mdtest.md +35 -0
  95. data/lib/amp/help/entries/silly +3 -0
  96. data/lib/amp/help/help.rb +288 -0
  97. data/lib/amp/profiling_hacks.rb +5 -3
  98. data/lib/amp/repository/abstract/abstract_changeset.rb +97 -0
  99. data/lib/amp/repository/abstract/abstract_local_repo.rb +181 -0
  100. data/lib/amp/repository/abstract/abstract_staging_area.rb +180 -0
  101. data/lib/amp/repository/abstract/abstract_versioned_file.rb +100 -0
  102. data/lib/amp/repository/abstract/common_methods/changeset.rb +75 -0
  103. data/lib/amp/repository/abstract/common_methods/local_repo.rb +277 -0
  104. data/lib/amp/repository/abstract/common_methods/staging_area.rb +233 -0
  105. data/lib/amp/repository/abstract/common_methods/versioned_file.rb +71 -0
  106. data/lib/amp/repository/generic_repo_picker.rb +78 -0
  107. data/lib/amp/repository/git/repo_format/changeset.rb +336 -0
  108. data/lib/amp/repository/git/repo_format/staging_area.rb +192 -0
  109. data/lib/amp/repository/git/repo_format/versioned_file.rb +119 -0
  110. data/lib/amp/repository/git/repositories/local_repository.rb +164 -0
  111. data/lib/amp/repository/git/repository.rb +41 -0
  112. data/lib/amp/repository/mercurial/encoding/mercurial_diff.rb +382 -0
  113. data/lib/amp/repository/mercurial/encoding/mercurial_patch.rb +1 -0
  114. data/lib/amp/repository/mercurial/encoding/patch.rb +294 -0
  115. data/lib/amp/repository/mercurial/encoding/pure_ruby/ruby_mercurial_patch.rb +124 -0
  116. data/lib/amp/repository/mercurial/merging/merge_ui.rb +327 -0
  117. data/lib/amp/repository/mercurial/merging/simple_merge.rb +452 -0
  118. data/lib/amp/repository/mercurial/repo_format/branch_manager.rb +266 -0
  119. data/lib/amp/repository/mercurial/repo_format/changeset.rb +768 -0
  120. data/lib/amp/repository/mercurial/repo_format/dir_state.rb +716 -0
  121. data/lib/amp/repository/mercurial/repo_format/journal.rb +218 -0
  122. data/lib/amp/repository/mercurial/repo_format/lock.rb +210 -0
  123. data/lib/amp/repository/mercurial/repo_format/merge_state.rb +228 -0
  124. data/lib/amp/repository/mercurial/repo_format/staging_area.rb +367 -0
  125. data/lib/amp/repository/mercurial/repo_format/store.rb +487 -0
  126. data/lib/amp/repository/mercurial/repo_format/tag_manager.rb +322 -0
  127. data/lib/amp/repository/mercurial/repo_format/updatable.rb +543 -0
  128. data/lib/amp/repository/mercurial/repo_format/updater.rb +848 -0
  129. data/lib/amp/repository/mercurial/repo_format/verification.rb +433 -0
  130. data/lib/amp/repository/mercurial/repositories/bundle_repository.rb +216 -0
  131. data/lib/amp/repository/mercurial/repositories/http_repository.rb +386 -0
  132. data/lib/amp/repository/mercurial/repositories/local_repository.rb +2034 -0
  133. data/lib/amp/repository/mercurial/repository.rb +119 -0
  134. data/lib/amp/repository/mercurial/revlogs/bundle_revlogs.rb +249 -0
  135. data/lib/amp/repository/mercurial/revlogs/changegroup.rb +217 -0
  136. data/lib/amp/repository/mercurial/revlogs/changelog.rb +339 -0
  137. data/lib/amp/repository/mercurial/revlogs/file_log.rb +152 -0
  138. data/lib/amp/repository/mercurial/revlogs/index.rb +500 -0
  139. data/lib/amp/repository/mercurial/revlogs/manifest.rb +201 -0
  140. data/lib/amp/repository/mercurial/revlogs/node.rb +20 -0
  141. data/lib/amp/repository/mercurial/revlogs/revlog.rb +1026 -0
  142. data/lib/amp/repository/mercurial/revlogs/revlog_support.rb +129 -0
  143. data/lib/amp/repository/mercurial/revlogs/versioned_file.rb +597 -0
  144. data/lib/amp/repository/repository.rb +11 -88
  145. data/lib/amp/server/extension/amp_extension.rb +3 -3
  146. data/lib/amp/server/fancy_http_server.rb +1 -1
  147. data/lib/amp/server/fancy_views/_browser.haml +1 -1
  148. data/lib/amp/server/fancy_views/_diff_file.haml +1 -8
  149. data/lib/amp/server/fancy_views/changeset.haml +2 -2
  150. data/lib/amp/server/fancy_views/file.haml +1 -1
  151. data/lib/amp/server/fancy_views/file_diff.haml +1 -1
  152. data/lib/amp/support/amp_ui.rb +13 -29
  153. data/lib/amp/support/generator.rb +1 -1
  154. data/lib/amp/support/loaders.rb +1 -2
  155. data/lib/amp/support/logger.rb +10 -16
  156. data/lib/amp/support/match.rb +18 -4
  157. data/lib/amp/support/mercurial/ignore.rb +151 -0
  158. data/lib/amp/support/openers.rb +8 -3
  159. data/lib/amp/support/support.rb +91 -46
  160. data/lib/amp/templates/{blank.commit.erb → mercurial/blank.commit.erb} +0 -0
  161. data/lib/amp/templates/{blank.log.erb → mercurial/blank.log.erb} +0 -0
  162. data/lib/amp/templates/{default.commit.erb → mercurial/default.commit.erb} +0 -0
  163. data/lib/amp/templates/{default.log.erb → mercurial/default.log.erb} +0 -0
  164. data/lib/amp/templates/template.rb +18 -18
  165. data/man/amp.1 +51 -0
  166. data/site/src/about/commands.haml +1 -1
  167. data/site/src/css/amp.css +1 -1
  168. data/site/src/index.haml +3 -3
  169. data/tasks/man.rake +39 -0
  170. data/tasks/stats.rake +1 -10
  171. data/tasks/yard.rake +1 -50
  172. data/test/dirstate_tests/test_dir_state.rb +10 -8
  173. data/test/functional_tests/annotate.out +31 -0
  174. data/test/functional_tests/test_functional.rb +155 -63
  175. data/test/localrepo_tests/ampfile.rb +12 -0
  176. data/test/localrepo_tests/test_local_repo.rb +56 -57
  177. data/test/manifest_tests/test_manifest.rb +3 -5
  178. data/test/merge_tests/test_merge.rb +3 -3
  179. data/test/revlog_tests/test_revlog.rb +14 -6
  180. data/test/store_tests/test_fncache_store.rb +19 -19
  181. data/test/test_19_compatibility.rb +46 -0
  182. data/test/test_base85.rb +2 -2
  183. data/test/test_bdiff.rb +2 -2
  184. data/test/test_changegroup.rb +59 -0
  185. data/test/test_commands.rb +2 -2
  186. data/test/test_difflib.rb +2 -2
  187. data/test/test_generator.rb +34 -0
  188. data/test/test_ignore.rb +203 -0
  189. data/test/test_journal.rb +18 -13
  190. data/test/test_match.rb +2 -2
  191. data/test/test_mdiff.rb +3 -3
  192. data/test/test_mpatch.rb +3 -3
  193. data/test/test_multi_io.rb +40 -0
  194. data/test/test_support.rb +18 -2
  195. data/test/test_templates.rb +38 -0
  196. data/test/test_ui.rb +79 -0
  197. data/test/testutilities.rb +56 -0
  198. metadata +168 -49
  199. data/ext/amp/bz2/mkmf.log +0 -38
  200. data/lib/amp/encoding/mercurial_diff.rb +0 -378
  201. data/lib/amp/encoding/mercurial_patch.rb +0 -1
  202. data/lib/amp/encoding/patch.rb +0 -292
  203. data/lib/amp/encoding/pure_ruby/ruby_mercurial_patch.rb +0 -123
  204. data/lib/amp/merges/merge_state.rb +0 -164
  205. data/lib/amp/merges/merge_ui.rb +0 -322
  206. data/lib/amp/merges/simple_merge.rb +0 -450
  207. data/lib/amp/repository/branch_manager.rb +0 -234
  208. data/lib/amp/repository/dir_state.rb +0 -950
  209. data/lib/amp/repository/journal.rb +0 -203
  210. data/lib/amp/repository/lock.rb +0 -207
  211. data/lib/amp/repository/repositories/bundle_repository.rb +0 -214
  212. data/lib/amp/repository/repositories/http_repository.rb +0 -377
  213. data/lib/amp/repository/repositories/local_repository.rb +0 -2661
  214. data/lib/amp/repository/store.rb +0 -485
  215. data/lib/amp/repository/tag_manager.rb +0 -319
  216. data/lib/amp/repository/updatable.rb +0 -532
  217. data/lib/amp/repository/verification.rb +0 -431
  218. data/lib/amp/repository/versioned_file.rb +0 -475
  219. data/lib/amp/revlogs/bundle_revlogs.rb +0 -246
  220. data/lib/amp/revlogs/changegroup.rb +0 -217
  221. data/lib/amp/revlogs/changelog.rb +0 -338
  222. data/lib/amp/revlogs/changeset.rb +0 -521
  223. data/lib/amp/revlogs/file_log.rb +0 -165
  224. data/lib/amp/revlogs/index.rb +0 -493
  225. data/lib/amp/revlogs/manifest.rb +0 -195
  226. data/lib/amp/revlogs/node.rb +0 -18
  227. data/lib/amp/revlogs/revlog.rb +0 -1045
  228. data/lib/amp/revlogs/revlog_support.rb +0 -126
  229. data/lib/amp/support/ignore.rb +0 -144
  230. data/site/Rakefile +0 -38
  231. data/test/test_amp.rb +0 -9
  232. data/test/test_helper.rb +0 -15
@@ -0,0 +1,31 @@
1
+ <%= "Amp Help".bold.underline %>
2
+
3
+ Thanks for using Amp! This help file is a little sparse right now, but
4
+ here are some useful commands to help you get started:
5
+
6
+ <%= "add".blue %> add the specified files on the next commit
7
+ <%= "annotate".blue %> show changeset information per file line
8
+ <%= "clone".blue %> make a copy of an existing repository
9
+ <%= "commit".blue %> commit the specified files or all outstanding changes
10
+ <%= "diff".blue %> diff repository (or selected files)
11
+ <%= "export".blue %> dump the header and diffs for one or more changesets
12
+ <%= "init".blue %> create a new repository in the given directory
13
+ <%= "log".blue %> show revision history of entire repository or files
14
+ <%= "merge".blue %> merge working directory with another revision
15
+ <%= "parents".blue %> show the parents of the working dir or revision
16
+ <%= "pull".blue %> pull changes from the specified source
17
+ <%= "push".blue %> push changes to the specified destination
18
+ <%= "remove".blue %> remove the specified files on the next commit
19
+ <%= "serve".blue %> export the repository via HTTP
20
+ <%= "status".blue %> show changed files in the working directory
21
+ <%= "update".blue %> update working directory
22
+
23
+ Use <%= "amp help [command-name]".on_green.black %> to get help on a particular
24
+ command. Also, we have other pages that you might find interesting - view them
25
+ with <%= "amp help [page-name]".on_green.black %>!
26
+
27
+ <%= "ampfiles".blue %> - learn about your ampfile.rb
28
+ <%= "new-commands".blue %> - learn how to easily add commands to amp!
29
+ <%= "paths".blue %> - learn about how to pass in paths to files without going nuts!
30
+
31
+ Thanks again for using Amp!
@@ -0,0 +1,6 @@
1
+ These are the following commands available:
2
+
3
+ <% Amp::Command.all_for_workflow(options[:global_config]["amp"]["workflow", Symbol, :hg], false).sort {|k1, k2| k1.to_s <=> k2.to_s}.each do |k, v| -%>
4
+ <%= k.to_s.ljust(30, " ")%><%= v.desc %>
5
+ <%- end %>
6
+ Run "amp help [command]" for more information.
@@ -0,0 +1,35 @@
1
+ # Ampfiles
2
+
3
+ Here's a list of some stuff.
4
+
5
+ * One thing
6
+ * Two Things
7
+ * Three thigns
8
+
9
+ This is *sweet*, no **killer**. Don't you agree?
10
+
11
+ Here's some code:
12
+
13
+ puts "Silly.rb"
14
+ %x(amp "%x(amp \"%x(amp ....)")")
15
+ File.open("silly.txt","w") {|f| f << "We pushed this code once"}
16
+
17
+ Sup dude, I'm `mike`, and I use the `Find.find("files")` module now.
18
+
19
+ ## Second Level Header
20
+
21
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi sodales laoreet scelerisque. Suspendisse a interdum massa. Sed erat urna, vehicula sed **sollicitudin non, *rhoncus* sed risus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam sed nulla non nibh tincidunt** aliquet quis quis arcu. Vestibulum a sapien eu nisl dictum pellentesque ut nec lacus. Curabitur at eros vel lectus semper pellentesque non et nulla.
22
+
23
+ Nunc tristique augue id lorem bibendum a luctus ipsum ultrices. Mauris elementum nisl et arcu porttitor consequat. Ut egestas, lectus sed interdum fermentum, tortor libero aliquam velit, in malesuada libero nulla non quam. Pellentesque tincidunt tempus sapien sed faucibus. Duis vehicula, diam a luctus venenatis, tellus elit adipiscing justo, non placerat lacus purus sit amet massa. Donec fermentum sollicitudin elit, eget dapibus justo commodo id. In hac habitasse platea dictumst.
24
+
25
+ ### Third Level Header
26
+
27
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi sodales laoreet scelerisque. Suspendisse a interdum massa. Sed erat urna, vehicula sed sollicitudin non, rhoncus sed risus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam sed nulla non nibh tincidunt aliquet quis quis arcu. Vestibulum a sapien eu nisl dictum pellentesque ut nec lacus. Curabitur at eros vel lectus semper pellentesque non et nulla.
28
+
29
+ Nunc tristique augue id lorem bibendum a luctus ipsum ultrices. Mauris elementum nisl et arcu porttitor consequat. Ut egestas, lectus sed interdum fermentum, tortor libero aliquam velit, in malesuada libero nulla non quam. Pellentesque tincidunt tempus sapien sed faucibus. Duis vehicula, diam a luctus venenatis, tellus elit adipiscing justo, non placerat lacus purus sit amet massa. Donec fermentum sollicitudin elit, eget dapibus justo commodo id. In hac habitasse platea dictumst.
30
+
31
+ #### Fourth Level Header
32
+
33
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi sodales laoreet scelerisque. Suspendisse a interdum massa. Sed erat urna, vehicula sed sollicitudin non, rhoncus sed risus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nam sed nulla non nibh tincidunt aliquet quis quis arcu. Vestibulum a sapien eu nisl dictum pellentesque ut nec lacus. Curabitur at eros vel lectus semper pellentesque non et nulla.
34
+
35
+ Nunc tristique augue id lorem bibendum a luctus ipsum ultrices. Mauris elementum nisl et arcu porttitor consequat. Ut egestas, lectus sed interdum fermentum, tortor libero aliquam velit, in malesuada libero nulla non quam. Pellentesque tincidunt tempus sapien sed faucibus. Duis vehicula, diam a luctus venenatis, tellus elit adipiscing justo, non placerat lacus purus sit amet massa. Donec fermentum sollicitudin elit, eget dapibus justo commodo id. In hac habitasse platea dictumst.
@@ -0,0 +1,3 @@
1
+ Ampfiles
2
+
3
+ Sweetsauce amp files!
@@ -0,0 +1,288 @@
1
+ module Amp
2
+ ##
3
+ # The module covering all the help subsystems for the Amp binary.
4
+ module Help
5
+
6
+ ##
7
+ # Module handling the registration and retrieval of entries in the
8
+ # help system.
9
+ #
10
+ # This is a singleton module. Don't mix it in anywhere. That'd be silly.
11
+ module HelpRegistry
12
+ extend self
13
+
14
+ ##
15
+ # Retrives the entries hash which stores all the help entrys
16
+ #
17
+ # @return [Hash<String => Array<HelpEntry>>] the entry table for the help system
18
+ def entries
19
+ @entries ||= Hash.new() {|h, k| h[k] = []}
20
+ end
21
+
22
+ ##
23
+ # Returns a list of HelpEntrys with the given name. Since we allow for
24
+ # the possibility of overlap by name, this returns an array.
25
+ #
26
+ # @param [String, #to_s] entry the name of the entry(ies) to retrieve
27
+ # @return [Array<HelpEntry>] the help entries stored under the given name
28
+ def [](entry)
29
+ entries[entry]
30
+ end
31
+
32
+ ##
33
+ # Adds an entry to the registry. We take a name and an entry, and store
34
+ # the entry under the list of entries with the given name.
35
+ #
36
+ # @param [String, #to_s] name the name of the help entry. Allowed to
37
+ # conflict with other entries.
38
+ # @param [HelpEntry] entry the entry to store in the registry
39
+ def register(name, entry)
40
+ entries[name] << entry
41
+ end
42
+
43
+ ##
44
+ # Unregisters the given entry from the registry. Not sure why you might
45
+ # use this, but it's a capability.
46
+ #
47
+ # @param [String, #to_s] name the name of the entry. Note - you will also
48
+ # need to provide the entry, because there might be naming conflicts.
49
+ # @param [HelpEntry] entry the entry to remove from the registry.
50
+ def unregister(name, entry)
51
+ entries[name].delete entry
52
+ end
53
+ end
54
+
55
+ ##
56
+ # The generic HelpEntry class encapsulates a entry in the help system. The
57
+ # entry has text that it provides to the user, as well as a name. The base
58
+ # HelpEntry class does not track its own name, because well, that's not
59
+ # useful! All it needs to know how to do is present its text when asked for it.
60
+ class HelpEntry
61
+ class << self
62
+ ##
63
+ # Singleton method that opens a file and returns a HelpEntry representing it.
64
+ # What makes this method spiffy is that it tries to detect the type of file
65
+ # -- markdown, ERb, et cetera, based on the file's extension, and picks
66
+ # the appropriate class to represent that help entry.
67
+ #
68
+ # The entry is registered under the name of the file - without any extensions -
69
+ # and the file's full contents are provided as the initial text.
70
+ #
71
+ # @param [String] filename the path to the file to load
72
+ # @return [HelpEntry] a help entry representing the file as best as we can.
73
+ def from_file(filename)
74
+ klass = case File.extname(filename).downcase
75
+ when ".md", ".markdown"
76
+ MarkdownHelpEntry
77
+ when ".erb"
78
+ ErbHelpEntry
79
+ else
80
+ HelpEntry
81
+ end
82
+ without_entry_dir = File.expand_path(File.join(File.dirname(__FILE__), "entries"))
83
+ name = filename[without_entry_dir.size+1..-1].gsub(/\//,":")
84
+ klass.new(name.split(".", 2).first, File.read(filename))
85
+ end
86
+ end
87
+
88
+ ##
89
+ # Creates a new HelpEntry, and registers it in the Help system, making it
90
+ # immediately available. It is for this reason that all subclasses should
91
+ # call +super+, because that registration is important!
92
+ #
93
+ # @param [String, #to_s] name the name under which to register this help entry
94
+ # @param [String] text ("") the text for the entry.
95
+ def initialize(name, text = "")
96
+ @text = text
97
+ HelpRegistry.register(name, self)
98
+ end
99
+
100
+ ##
101
+ # Returns the help text to display for this entry.
102
+ #
103
+ # In the generic case, just return the @text variable.
104
+ #
105
+ # @param [Hash] options the options for the process - that way the help commands
106
+ # can access the user's run-time options and global configuration. For example,
107
+ # if the user passes in --verbose or --quiet, each help entry could handle that
108
+ # differently. Who are we to judge?
109
+ # @return [String] the help text for the entry.
110
+ def text(options = {})
111
+ @text
112
+ end
113
+
114
+ ##
115
+ # Describes the entry briefly, so if the user must pick, they have a decent
116
+ # shot at knowing what this entry is about. Hopefully.
117
+ #
118
+ # In the generic case, use the text and grab the first few words.
119
+ #
120
+ # @return a description of the entry based on its content
121
+ def desc
122
+ %Q{a regular help entry ("#{text.split[0..5].join(" ")} ...")}
123
+ end
124
+ end
125
+
126
+ ##
127
+ # Represents a help entry that filters its help text through a Markdown parser
128
+ # before returning.
129
+ #
130
+ # This makes it very easy to make very pretty help files, that are smart enough
131
+ # to look good in both HTML form and when printed to a terminal. This uses our
132
+ # additions to the markdown parser to provide an "ANSI" output format.
133
+ class MarkdownHelpEntry < HelpEntry
134
+ ##
135
+ # Returns the help text to display for this entry.
136
+ #
137
+ # For a markdown entry, we run this through Maruku and our special to_ansi
138
+ # output formatter. This will make things like *this* underlined and **these**
139
+ # bolded. Code blocks will be given a colored background, and headings are
140
+ # accentuated.
141
+ #
142
+ # @param [Hash] options the options for the process - that way the help commands
143
+ # can access the user's run-time options and global configuration. For example,
144
+ # if the user passes in --verbose or --quiet, each help entry could handle that
145
+ # differently. Who are we to judge?
146
+ # @return [String] the help text for the entry.
147
+ def text(options = {})
148
+ Maruku.new(super, {}).to_ansi
149
+ end
150
+ end
151
+
152
+ ##
153
+ # Represents a help entry that filters its help text through ERB before returning.
154
+ #
155
+ # This is useful because some entries might have programmatic logic to them -
156
+ # for example, the built in "commands" entry lists all the commands in the
157
+ # user's current workflow. That requires logic, and while we used to simply
158
+ # have that be its own class, we can now stuff it in an ERB file.
159
+ #
160
+ # Note: if you want to use pretty text in an ERB entry, you will have to use
161
+ # ruby code to do so. Use the following shortcuts:
162
+ #
163
+ # <%= "Ampfiles".bold.underline %> # bolds and underlines
164
+ # <%= "some.code()".black.on_green %> # changes to black and sets green bg color
165
+ #
166
+ # See our extensions to the String class for more.
167
+ class ErbHelpEntry < HelpEntry
168
+
169
+ ##
170
+ # Returns the help text to display for this entry.
171
+ #
172
+ # For an ERB entry, we run ERB on the text in the entry, while also exposing the
173
+ # options variable as local, so the ERB can access the user's runtime options.
174
+ #
175
+ # @param [Hash] options the options for the process - that way the help commands
176
+ # can access the user's run-time options and global configuration. For example,
177
+ # if the user passes in --verbose or --quiet, each help entry could handle that
178
+ # differently. Who are we to judge?
179
+ # @return [String] the help text for the entry.
180
+ def text(options = {})
181
+ full_text = super(options)
182
+
183
+ erb = ERB.new(full_text, 0, "-")
184
+ erb.result binding
185
+ end
186
+ end
187
+
188
+ ##
189
+ # Represents a command's help entry. All commands have one of these, and in fact,
190
+ # when the command is created, it creates a help entry to go with it.
191
+ #
192
+ # Commands are actually quite complicated, and themselves know how to educate
193
+ # users about their use, so we have surprisingly little logic in this class.
194
+ class CommandHelpEntry < HelpEntry
195
+
196
+ ##
197
+ # Creates a new command help entry. Differing arguments, because instead of
198
+ # text, we need the command itself. One might think: why not just pass in
199
+ # the command's help information instead? If you have a command object, you
200
+ # have command.help, no? Well, the reason is two-fold: the help information
201
+ # might be updated later, and there is more to printing a command's help entry
202
+ # than just the command.help() method.
203
+ #
204
+ # @param [String] name the name of the command
205
+ # @param [Amp::Command] command the command being represented.
206
+ def initialize(name, command)
207
+ super(name)
208
+ @command = command
209
+ end
210
+
211
+ ##
212
+ # Returns the help text to display for this entry.
213
+ #
214
+ # For a command-based entry, simply run its educate method, since commands know
215
+ # how to present their help information.
216
+ #
217
+ # @param [Hash] options the options for the process - that way the help commands
218
+ # can access the user's run-time options and global configuration. For example,
219
+ # if the user passes in --verbose or --quiet, each help entry could handle that
220
+ # differently. Who are we to judge?
221
+ # @return [String] the help text for the entry.
222
+ def text(options = {})
223
+ @command.collect_options
224
+ @command.educate
225
+ ""
226
+ end
227
+
228
+ ##
229
+ # Describes the entry briefly, so if the user must pick, they have a decent
230
+ # shot at knowing what this entry is about. Hopefully.
231
+ #
232
+ # In the case of a command, grab the command's "desc" information.
233
+ #
234
+ # @return a description of the entry based on its content
235
+ def desc
236
+ %Q{a command help entry ("#{@command.desc}")}
237
+ end
238
+ end
239
+
240
+ ##
241
+ # The really public-facing part of the Help system - the Help's UI.
242
+ # This lets the outside world get at entries based on their names.
243
+ module HelpUI
244
+ extend self
245
+
246
+ ##
247
+ # Asks the UI system to print the entry with the given name, with the
248
+ # process's current options.
249
+ #
250
+ # This method is "smart" - it has to check to see what entries are
251
+ # available. If there's more than one with the provided name, it
252
+ # helps the user pick the appropriate entry.
253
+ #
254
+ # @param [String] name the name of the entry to print
255
+ # @param [Hash] options the process's options
256
+ def print_entry(name, options = {})
257
+ result = HelpRegistry[name.to_s]
258
+ case result.size
259
+ when 0
260
+ raise abort("Could not find help entry \"#{name}\"")
261
+ when 1
262
+ puts result.first.text(options)
263
+ when 2
264
+ UI.choose do |menu|
265
+ result.each do |entry|
266
+ menu.choice("#{name} - #{entry.desc}") { puts entry.text(options) }
267
+ end
268
+ end
269
+ end
270
+ end
271
+ end
272
+
273
+ ##
274
+ # A method that loads in the default entries for the help system.
275
+ # Normally, I'd just put this code in the module itself, or perhaps
276
+ # at the end of the file, but I'm experimenting with an approach
277
+ # where I try to minimize the bare code, leaving only the invocation
278
+ # of this method to sit in the module.
279
+ def self.load_default_entries
280
+ Dir[File.join(File.dirname(__FILE__), "entries", "**")].each do |file|
281
+ HelpEntry.from_file(file)
282
+ end
283
+ end
284
+
285
+ # Load the default entries.
286
+ self.load_default_entries
287
+ end
288
+ end
@@ -23,14 +23,16 @@ HELP
23
23
  end
24
24
 
25
25
  $hash = Hash.new {|h, k| h[k] = 0 }
26
+
27
+ # Kernel.module_eval do
26
28
  #
27
- # String.class_eval do
28
- # show_caller_for :split_newlines, "$hash[caller[0]] += 1"
29
+ # show_caller_for :catch, "$hash[caller[0]] += 1"
30
+ # # show_caller_for :throw, "$hash[caller[0]] += 1"
29
31
  # end
30
32
 
31
33
  if ENV["TESTING"] == "true"
32
34
  END {
33
35
  require 'pp'
34
- STDERR.puts $hash.inspect if $hash.any?
36
+ puts $hash.sort.inspect if $hash.any?
35
37
  }
36
38
  end
@@ -0,0 +1,97 @@
1
+ module Amp
2
+ module Repositories
3
+ class AbstractChangeset
4
+ include CommonChangesetMethods
5
+ include Enumerable
6
+ include Comparable
7
+
8
+ ##
9
+ # the nodes that this node inherits from
10
+ #
11
+ # @return [Array<Abstract Changeset>]
12
+ def parents
13
+ raise NotImplementedError.new("parents() must be implemented by subclasses of AbstractChangeset.")
14
+ end
15
+
16
+ ##
17
+ # Iterates over every tracked file in this changeset.
18
+ #
19
+ # @return [AbstractChangeset] self
20
+ def each
21
+ raise NotImplementedError.new("each() must be implemented by subclasses of AbstractChangeset.")
22
+ end
23
+
24
+ ##
25
+ # How does this changeset compare to +other+? Used in sorting.
26
+ #
27
+ # @param [AbstractChangeset] other
28
+ # @return [Integer] -1, 0, or 1
29
+ def <=>(other)
30
+ raise NotImplementedError.new("<=>() must be implemented by subclasses of AbstractChangeset.")
31
+ end
32
+
33
+ ##
34
+ # Retrieve +filename+
35
+ #
36
+ # @return [AbstractVersionedFile]
37
+ def get_file(filename)
38
+ raise NotImplementedError.new("get_file() must be implemented by subclasses of AbstractChangeset.")
39
+ end
40
+ alias_method :[], :get_file
41
+
42
+ ##
43
+ # When was the changeset made?
44
+ #
45
+ # @return [Time]
46
+ def date
47
+ raise NotImplementedError.new("date() must be implemented by subclasses of AbstractChangeset.")
48
+ end
49
+
50
+ ##
51
+ # The user who made the changeset
52
+ #
53
+ # @return [String] the user who made the changeset
54
+ def user
55
+ raise NotImplementedError.new("user() must be implemented by subclasses of AbstractChangeset.")
56
+ end
57
+
58
+ ##
59
+ # Which branch this changeset belongs to
60
+ #
61
+ # @return [String] the user who made the changeset
62
+ def branch
63
+ raise NotImplementedError.new("branch() must be implemented by subclasses of AbstractChangeset.")
64
+ end
65
+
66
+ ##
67
+ # @return [String]
68
+ def description
69
+ raise NotImplementedError.new("description() must be implemented by subclasses of AbstractChangeset.")
70
+ end
71
+
72
+ ##
73
+ # What files have been altered in this changeset?
74
+ #
75
+ # @return [Array<String>]
76
+ def altered_files
77
+ raise NotImplementedError.new("altered_files() must be implemented by subclasses of AbstractChangeset.")
78
+ end
79
+
80
+ ##
81
+ # Returns a list of all files that are tracked at this current revision.
82
+ #
83
+ # @return [Array<String>] the files tracked at the given revision
84
+ def all_files
85
+ raise NotImplementedError.new("all_files() must be implemented by subclasses of AbstractChangeset.")
86
+ end
87
+
88
+ # Is this changeset a working changeset?
89
+ #
90
+ # @return [Boolean] is the changeset representing the working directory?
91
+ def working?
92
+ raise NotImplementedError.new("working() must be implemented by subclasses of AbstractChangeset.")
93
+ end
94
+
95
+ end
96
+ end
97
+ end