amp 0.5.0

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 (295) hide show
  1. data/.gitignore +1 -0
  2. data/.hgignore +26 -0
  3. data/AUTHORS +2 -0
  4. data/History.txt +6 -0
  5. data/LICENSE +37 -0
  6. data/MANIFESTO +7 -0
  7. data/Manifest.txt +294 -0
  8. data/README.md +129 -0
  9. data/Rakefile +102 -0
  10. data/SCHEDULE.markdown +12 -0
  11. data/STYLE +27 -0
  12. data/TODO.markdown +149 -0
  13. data/ampfile.rb +47 -0
  14. data/bin/amp +30 -0
  15. data/bin/amp1.9 +30 -0
  16. data/ext/amp/bz2/README.txt +39 -0
  17. data/ext/amp/bz2/bz2.c +1582 -0
  18. data/ext/amp/bz2/extconf.rb +77 -0
  19. data/ext/amp/bz2/mkmf.log +29 -0
  20. data/ext/amp/mercurial_patch/extconf.rb +5 -0
  21. data/ext/amp/mercurial_patch/mpatch.c +405 -0
  22. data/ext/amp/priority_queue/extconf.rb +5 -0
  23. data/ext/amp/priority_queue/priority_queue.c +947 -0
  24. data/ext/amp/support/extconf.rb +5 -0
  25. data/ext/amp/support/support.c +250 -0
  26. data/lib/amp.rb +200 -0
  27. data/lib/amp/commands/command.rb +507 -0
  28. data/lib/amp/commands/command_support.rb +137 -0
  29. data/lib/amp/commands/commands/config.rb +143 -0
  30. data/lib/amp/commands/commands/help.rb +29 -0
  31. data/lib/amp/commands/commands/init.rb +10 -0
  32. data/lib/amp/commands/commands/templates.rb +137 -0
  33. data/lib/amp/commands/commands/version.rb +7 -0
  34. data/lib/amp/commands/commands/workflow.rb +28 -0
  35. data/lib/amp/commands/commands/workflows/git/add.rb +65 -0
  36. data/lib/amp/commands/commands/workflows/git/copy.rb +27 -0
  37. data/lib/amp/commands/commands/workflows/git/mv.rb +23 -0
  38. data/lib/amp/commands/commands/workflows/git/rm.rb +60 -0
  39. data/lib/amp/commands/commands/workflows/hg/add.rb +53 -0
  40. data/lib/amp/commands/commands/workflows/hg/addremove.rb +86 -0
  41. data/lib/amp/commands/commands/workflows/hg/annotate.rb +46 -0
  42. data/lib/amp/commands/commands/workflows/hg/archive.rb +126 -0
  43. data/lib/amp/commands/commands/workflows/hg/branch.rb +28 -0
  44. data/lib/amp/commands/commands/workflows/hg/branches.rb +30 -0
  45. data/lib/amp/commands/commands/workflows/hg/bundle.rb +115 -0
  46. data/lib/amp/commands/commands/workflows/hg/clone.rb +95 -0
  47. data/lib/amp/commands/commands/workflows/hg/commit.rb +42 -0
  48. data/lib/amp/commands/commands/workflows/hg/copy.rb +31 -0
  49. data/lib/amp/commands/commands/workflows/hg/debug/dirstate.rb +32 -0
  50. data/lib/amp/commands/commands/workflows/hg/debug/index.rb +36 -0
  51. data/lib/amp/commands/commands/workflows/hg/default.rb +9 -0
  52. data/lib/amp/commands/commands/workflows/hg/diff.rb +30 -0
  53. data/lib/amp/commands/commands/workflows/hg/forget.rb +11 -0
  54. data/lib/amp/commands/commands/workflows/hg/heads.rb +25 -0
  55. data/lib/amp/commands/commands/workflows/hg/identify.rb +23 -0
  56. data/lib/amp/commands/commands/workflows/hg/import.rb +135 -0
  57. data/lib/amp/commands/commands/workflows/hg/incoming.rb +85 -0
  58. data/lib/amp/commands/commands/workflows/hg/info.rb +18 -0
  59. data/lib/amp/commands/commands/workflows/hg/log.rb +21 -0
  60. data/lib/amp/commands/commands/workflows/hg/manifest.rb +13 -0
  61. data/lib/amp/commands/commands/workflows/hg/merge.rb +53 -0
  62. data/lib/amp/commands/commands/workflows/hg/move.rb +28 -0
  63. data/lib/amp/commands/commands/workflows/hg/outgoing.rb +61 -0
  64. data/lib/amp/commands/commands/workflows/hg/pull.rb +74 -0
  65. data/lib/amp/commands/commands/workflows/hg/push.rb +20 -0
  66. data/lib/amp/commands/commands/workflows/hg/remove.rb +45 -0
  67. data/lib/amp/commands/commands/workflows/hg/resolve.rb +83 -0
  68. data/lib/amp/commands/commands/workflows/hg/revert.rb +53 -0
  69. data/lib/amp/commands/commands/workflows/hg/root.rb +13 -0
  70. data/lib/amp/commands/commands/workflows/hg/serve.rb +38 -0
  71. data/lib/amp/commands/commands/workflows/hg/status.rb +116 -0
  72. data/lib/amp/commands/commands/workflows/hg/tag.rb +69 -0
  73. data/lib/amp/commands/commands/workflows/hg/tags.rb +27 -0
  74. data/lib/amp/commands/commands/workflows/hg/tip.rb +13 -0
  75. data/lib/amp/commands/commands/workflows/hg/update.rb +27 -0
  76. data/lib/amp/commands/commands/workflows/hg/verify.rb +9 -0
  77. data/lib/amp/commands/commands/workflows/hg/view.rb +36 -0
  78. data/lib/amp/commands/dispatch.rb +181 -0
  79. data/lib/amp/commands/hooks.rb +81 -0
  80. data/lib/amp/dependencies/amp_support.rb +1 -0
  81. data/lib/amp/dependencies/amp_support/ruby_amp_support.rb +103 -0
  82. data/lib/amp/dependencies/minitar.rb +979 -0
  83. data/lib/amp/dependencies/priority_queue.rb +18 -0
  84. data/lib/amp/dependencies/priority_queue/c_priority_queue.rb +1 -0
  85. data/lib/amp/dependencies/priority_queue/poor_priority_queue.rb +46 -0
  86. data/lib/amp/dependencies/priority_queue/ruby_priority_queue.rb +525 -0
  87. data/lib/amp/dependencies/python_config.rb +211 -0
  88. data/lib/amp/dependencies/trollop.rb +713 -0
  89. data/lib/amp/dependencies/zip/ioextras.rb +155 -0
  90. data/lib/amp/dependencies/zip/stdrubyext.rb +111 -0
  91. data/lib/amp/dependencies/zip/tempfile_bugfixed.rb +186 -0
  92. data/lib/amp/dependencies/zip/zip.rb +1850 -0
  93. data/lib/amp/dependencies/zip/zipfilesystem.rb +609 -0
  94. data/lib/amp/dependencies/zip/ziprequire.rb +90 -0
  95. data/lib/amp/encoding/base85.rb +97 -0
  96. data/lib/amp/encoding/binary_diff.rb +82 -0
  97. data/lib/amp/encoding/difflib.rb +166 -0
  98. data/lib/amp/encoding/mercurial_diff.rb +378 -0
  99. data/lib/amp/encoding/mercurial_patch.rb +1 -0
  100. data/lib/amp/encoding/patch.rb +292 -0
  101. data/lib/amp/encoding/pure_ruby/ruby_mercurial_patch.rb +123 -0
  102. data/lib/amp/extensions/ditz.rb +41 -0
  103. data/lib/amp/extensions/lighthouse.rb +167 -0
  104. data/lib/amp/graphs/ancestor.rb +147 -0
  105. data/lib/amp/graphs/copies.rb +261 -0
  106. data/lib/amp/merges/merge_state.rb +164 -0
  107. data/lib/amp/merges/merge_ui.rb +322 -0
  108. data/lib/amp/merges/simple_merge.rb +450 -0
  109. data/lib/amp/profiling_hacks.rb +36 -0
  110. data/lib/amp/repository/branch_manager.rb +234 -0
  111. data/lib/amp/repository/dir_state.rb +950 -0
  112. data/lib/amp/repository/journal.rb +203 -0
  113. data/lib/amp/repository/lock.rb +207 -0
  114. data/lib/amp/repository/repositories/bundle_repository.rb +214 -0
  115. data/lib/amp/repository/repositories/http_repository.rb +377 -0
  116. data/lib/amp/repository/repositories/local_repository.rb +2661 -0
  117. data/lib/amp/repository/repository.rb +94 -0
  118. data/lib/amp/repository/store.rb +485 -0
  119. data/lib/amp/repository/tag_manager.rb +319 -0
  120. data/lib/amp/repository/updatable.rb +532 -0
  121. data/lib/amp/repository/verification.rb +431 -0
  122. data/lib/amp/repository/versioned_file.rb +475 -0
  123. data/lib/amp/revlogs/bundle_revlogs.rb +246 -0
  124. data/lib/amp/revlogs/changegroup.rb +217 -0
  125. data/lib/amp/revlogs/changelog.rb +338 -0
  126. data/lib/amp/revlogs/changeset.rb +521 -0
  127. data/lib/amp/revlogs/file_log.rb +165 -0
  128. data/lib/amp/revlogs/index.rb +493 -0
  129. data/lib/amp/revlogs/manifest.rb +195 -0
  130. data/lib/amp/revlogs/node.rb +18 -0
  131. data/lib/amp/revlogs/revlog.rb +1032 -0
  132. data/lib/amp/revlogs/revlog_support.rb +126 -0
  133. data/lib/amp/server/amp_user.rb +44 -0
  134. data/lib/amp/server/extension/amp_extension.rb +396 -0
  135. data/lib/amp/server/extension/authorization.rb +201 -0
  136. data/lib/amp/server/fancy_http_server.rb +252 -0
  137. data/lib/amp/server/fancy_views/_browser.haml +28 -0
  138. data/lib/amp/server/fancy_views/_diff_file.haml +13 -0
  139. data/lib/amp/server/fancy_views/_navbar.haml +17 -0
  140. data/lib/amp/server/fancy_views/changeset.haml +31 -0
  141. data/lib/amp/server/fancy_views/commits.haml +32 -0
  142. data/lib/amp/server/fancy_views/file.haml +35 -0
  143. data/lib/amp/server/fancy_views/file_diff.haml +23 -0
  144. data/lib/amp/server/fancy_views/harshcss/all_hallows_eve.css +72 -0
  145. data/lib/amp/server/fancy_views/harshcss/amy.css +147 -0
  146. data/lib/amp/server/fancy_views/harshcss/twilight.css +138 -0
  147. data/lib/amp/server/fancy_views/stylesheet.sass +175 -0
  148. data/lib/amp/server/http_server.rb +140 -0
  149. data/lib/amp/server/repo_user_management.rb +287 -0
  150. data/lib/amp/support/amp_config.rb +164 -0
  151. data/lib/amp/support/amp_ui.rb +287 -0
  152. data/lib/amp/support/docs.rb +54 -0
  153. data/lib/amp/support/generator.rb +78 -0
  154. data/lib/amp/support/ignore.rb +144 -0
  155. data/lib/amp/support/loaders.rb +93 -0
  156. data/lib/amp/support/logger.rb +103 -0
  157. data/lib/amp/support/match.rb +151 -0
  158. data/lib/amp/support/multi_io.rb +87 -0
  159. data/lib/amp/support/openers.rb +121 -0
  160. data/lib/amp/support/ruby_19_compatibility.rb +66 -0
  161. data/lib/amp/support/support.rb +1095 -0
  162. data/lib/amp/templates/blank.commit.erb +23 -0
  163. data/lib/amp/templates/blank.log.erb +18 -0
  164. data/lib/amp/templates/default.commit.erb +23 -0
  165. data/lib/amp/templates/default.log.erb +26 -0
  166. data/lib/amp/templates/template.rb +165 -0
  167. data/site/Rakefile +24 -0
  168. data/site/src/about/ampfile.haml +57 -0
  169. data/site/src/about/commands.haml +106 -0
  170. data/site/src/about/index.haml +33 -0
  171. data/site/src/about/performance.haml +31 -0
  172. data/site/src/about/workflows.haml +34 -0
  173. data/site/src/contribute/index.haml +65 -0
  174. data/site/src/contribute/style.haml +297 -0
  175. data/site/src/css/active4d.css +114 -0
  176. data/site/src/css/all_hallows_eve.css +72 -0
  177. data/site/src/css/all_themes.css +3299 -0
  178. data/site/src/css/amp.css +260 -0
  179. data/site/src/css/amy.css +147 -0
  180. data/site/src/css/blackboard.css +88 -0
  181. data/site/src/css/brilliance_black.css +605 -0
  182. data/site/src/css/brilliance_dull.css +599 -0
  183. data/site/src/css/cobalt.css +149 -0
  184. data/site/src/css/cur_amp.css +185 -0
  185. data/site/src/css/dawn.css +121 -0
  186. data/site/src/css/eiffel.css +121 -0
  187. data/site/src/css/espresso_libre.css +109 -0
  188. data/site/src/css/idle.css +62 -0
  189. data/site/src/css/iplastic.css +80 -0
  190. data/site/src/css/lazy.css +73 -0
  191. data/site/src/css/mac_classic.css +123 -0
  192. data/site/src/css/magicwb_amiga.css +104 -0
  193. data/site/src/css/pastels_on_dark.css +188 -0
  194. data/site/src/css/reset.css +55 -0
  195. data/site/src/css/slush_poppies.css +85 -0
  196. data/site/src/css/spacecadet.css +51 -0
  197. data/site/src/css/sunburst.css +180 -0
  198. data/site/src/css/twilight.css +137 -0
  199. data/site/src/css/zenburnesque.css +91 -0
  200. data/site/src/get/index.haml +32 -0
  201. data/site/src/helpers.rb +121 -0
  202. data/site/src/images/amp_logo.png +0 -0
  203. data/site/src/images/carbonica.png +0 -0
  204. data/site/src/images/revolution.png +0 -0
  205. data/site/src/images/tab-bg.png +0 -0
  206. data/site/src/images/tab-sliding-left.png +0 -0
  207. data/site/src/images/tab-sliding-right.png +0 -0
  208. data/site/src/include/_footer.haml +22 -0
  209. data/site/src/include/_header.haml +17 -0
  210. data/site/src/index.haml +104 -0
  211. data/site/src/learn/index.haml +46 -0
  212. data/site/src/scripts/jquery-1.3.2.min.js +19 -0
  213. data/site/src/scripts/jquery.cookie.js +96 -0
  214. data/tasks/stats.rake +155 -0
  215. data/tasks/yard.rake +171 -0
  216. data/test/dirstate_tests/dirstate +0 -0
  217. data/test/dirstate_tests/hgrc +5 -0
  218. data/test/dirstate_tests/test_dir_state.rb +192 -0
  219. data/test/functional_tests/resources/.hgignore +2 -0
  220. data/test/functional_tests/resources/STYLE.txt +25 -0
  221. data/test/functional_tests/resources/command.rb +372 -0
  222. data/test/functional_tests/resources/commands/annotate.rb +57 -0
  223. data/test/functional_tests/resources/commands/experimental/lolcats.rb +17 -0
  224. data/test/functional_tests/resources/commands/heads.rb +22 -0
  225. data/test/functional_tests/resources/commands/manifest.rb +12 -0
  226. data/test/functional_tests/resources/commands/status.rb +90 -0
  227. data/test/functional_tests/resources/version2/.hgignore +5 -0
  228. data/test/functional_tests/resources/version2/STYLE.txt +25 -0
  229. data/test/functional_tests/resources/version2/command.rb +372 -0
  230. data/test/functional_tests/resources/version2/commands/annotate.rb +45 -0
  231. data/test/functional_tests/resources/version2/commands/experimental/lolcats.rb +17 -0
  232. data/test/functional_tests/resources/version2/commands/heads.rb +22 -0
  233. data/test/functional_tests/resources/version2/commands/manifest.rb +12 -0
  234. data/test/functional_tests/resources/version2/commands/status.rb +90 -0
  235. data/test/functional_tests/resources/version3/.hgignore +5 -0
  236. data/test/functional_tests/resources/version3/STYLE.txt +31 -0
  237. data/test/functional_tests/resources/version3/command.rb +376 -0
  238. data/test/functional_tests/resources/version3/commands/annotate.rb +45 -0
  239. data/test/functional_tests/resources/version3/commands/experimental/lolcats.rb +17 -0
  240. data/test/functional_tests/resources/version3/commands/heads.rb +22 -0
  241. data/test/functional_tests/resources/version3/commands/manifest.rb +12 -0
  242. data/test/functional_tests/resources/version3/commands/status.rb +90 -0
  243. data/test/functional_tests/resources/version4/.hgignore +5 -0
  244. data/test/functional_tests/resources/version4/STYLE.txt +31 -0
  245. data/test/functional_tests/resources/version4/command.rb +376 -0
  246. data/test/functional_tests/resources/version4/commands/experimental/lolcats.rb +17 -0
  247. data/test/functional_tests/resources/version4/commands/heads.rb +22 -0
  248. data/test/functional_tests/resources/version4/commands/manifest.rb +12 -0
  249. data/test/functional_tests/resources/version4/commands/stats.rb +25 -0
  250. data/test/functional_tests/resources/version4/commands/status.rb +90 -0
  251. data/test/functional_tests/resources/version5_1/.hgignore +5 -0
  252. data/test/functional_tests/resources/version5_1/STYLE.txt +2 -0
  253. data/test/functional_tests/resources/version5_1/command.rb +374 -0
  254. data/test/functional_tests/resources/version5_1/commands/experimental/lolcats.rb +17 -0
  255. data/test/functional_tests/resources/version5_1/commands/heads.rb +22 -0
  256. data/test/functional_tests/resources/version5_1/commands/manifest.rb +12 -0
  257. data/test/functional_tests/resources/version5_1/commands/stats.rb +25 -0
  258. data/test/functional_tests/resources/version5_1/commands/status.rb +90 -0
  259. data/test/functional_tests/resources/version5_2/.hgignore +5 -0
  260. data/test/functional_tests/resources/version5_2/STYLE.txt +14 -0
  261. data/test/functional_tests/resources/version5_2/command.rb +376 -0
  262. data/test/functional_tests/resources/version5_2/commands/experimental/lolcats.rb +17 -0
  263. data/test/functional_tests/resources/version5_2/commands/manifest.rb +12 -0
  264. data/test/functional_tests/resources/version5_2/commands/newz.rb +12 -0
  265. data/test/functional_tests/resources/version5_2/commands/stats.rb +25 -0
  266. data/test/functional_tests/resources/version5_2/commands/status.rb +90 -0
  267. data/test/functional_tests/test_functional.rb +604 -0
  268. data/test/localrepo_tests/test_local_repo.rb +121 -0
  269. data/test/localrepo_tests/testrepo.tar.gz +0 -0
  270. data/test/manifest_tests/00manifest.i +0 -0
  271. data/test/manifest_tests/test_manifest.rb +72 -0
  272. data/test/merge_tests/base.txt +10 -0
  273. data/test/merge_tests/expected.local.txt +16 -0
  274. data/test/merge_tests/local.txt +11 -0
  275. data/test/merge_tests/remote.txt +11 -0
  276. data/test/merge_tests/test_merge.rb +26 -0
  277. data/test/revlog_tests/00changelog.i +0 -0
  278. data/test/revlog_tests/revision_added_changelog.i +0 -0
  279. data/test/revlog_tests/test_adding_index.i +0 -0
  280. data/test/revlog_tests/test_revlog.rb +333 -0
  281. data/test/revlog_tests/testindex.i +0 -0
  282. data/test/store_tests/store.tar.gz +0 -0
  283. data/test/store_tests/test_fncache_store.rb +122 -0
  284. data/test/test_amp.rb +9 -0
  285. data/test/test_base85.rb +14 -0
  286. data/test/test_bdiff.rb +42 -0
  287. data/test/test_commands.rb +122 -0
  288. data/test/test_difflib.rb +50 -0
  289. data/test/test_helper.rb +15 -0
  290. data/test/test_journal.rb +29 -0
  291. data/test/test_match.rb +134 -0
  292. data/test/test_mdiff.rb +74 -0
  293. data/test/test_mpatch.rb +14 -0
  294. data/test/test_support.rb +24 -0
  295. metadata +385 -0
@@ -0,0 +1,137 @@
1
+ module Amp
2
+
3
+ module CommandSupport
4
+ # When a user specifies a range, REV_SEP is between the given revisions.
5
+ REV_SEP = ":"
6
+
7
+ ##
8
+ # Looks up the node ID of a given revision in the repository. Since this method uses
9
+ # Repository#lookup, the choices for "value" are very flexible. You can choose a
10
+ # revision number, a partial node ID, "tip", and so on. See LocalRepository#lookup
11
+ # for more details.
12
+ #
13
+ # @see {LocalRepository#lookup}
14
+ # @param [Repository] repo the repository in which to lookup the node
15
+ # @param [String, Integer] value the search term for the node - could be a revision
16
+ # index #, a partial node ID, and so on
17
+ # @param [String, Integer] default the default search term, in case +value+ is nil.
18
+ # @return [String] the full node ID of the node that is found, or +nil+ if none is found.
19
+ def revision_lookup(repo, value, default = nil)
20
+ value ||= default
21
+ repo.lookup(value)
22
+ end
23
+
24
+ ##
25
+ # Prints the statistics returned from an update or merge. These are given in the form
26
+ # of a hash, such as {:added => 0, :unresolved => 3, ...}, and should be printed
27
+ # in a nice manner.
28
+ #
29
+ # @param [Hash<Symbol => Fixnum>] stats the statistics resulting from an update, merge
30
+ # or clean command.
31
+ def print_update_stats(stats)
32
+ Amp::UI.status stats.map {|note, files| "#{files.size} files #{note}" }.join(", ")
33
+ end
34
+
35
+ ##
36
+ # Parses strings that represent a range of
37
+ #
38
+ # @example
39
+ # revision_pair(repo, ["10:tip"]) #=> [repo.lookup(10), repo.lookup("tip")]
40
+ # revision_pair(repo, ["10", "tip"]) #=> [repo.lookup(10), repo.lookup("tip")]
41
+ # revision_pair(repo, ":tip") #=> [repo.lookup(0), repo.lookup("tip")]
42
+ # @param [Repository] repo the repository to use when looking up revisions
43
+ # @param [Array, String] revisions the revisions to parse. Could be a set of strings,
44
+ # passed directly in from the command line, or could just be 1 string.
45
+ # @return [Array<String>] the node IDs that correspond to the start and end of the
46
+ # specified range of changesets
47
+ def revision_pair(repo, revisions)
48
+ #revisions = [revisions] unless revisions.is_a?(Array)
49
+ if !revisions || revisions.empty?
50
+ return repo.dirstate.parents.first, nil
51
+ end
52
+ stop = nil
53
+
54
+ if revisions.size == 1
55
+ #old revision compared with working dir?
56
+ if revisions[0].include? REV_SEP
57
+ start, stop = revisions.first.split REV_SEP, 2
58
+ start = revision_lookup repo, start, 0
59
+ stop = revision_lookup repo, stop, repo.size - 1
60
+ else
61
+ start = revision_lookup repo, revisions.first
62
+ end
63
+ elsif revisions.size == 2
64
+ if revisions.first.include?(REV_SEP) ||
65
+ revisions.second.include?(REV_SEP)
66
+ raise ArgumentError.new("too many revisions specified")
67
+ end
68
+ start = revision_lookup(repo, revisions.first)
69
+ stop = revision_lookup(repo, revisions.second)
70
+ else
71
+ raise ArgumentError.new("too many revisions specified")
72
+ end
73
+ [start, stop]
74
+ end
75
+
76
+ # returns [String, Array || nil, String]
77
+ def parse_url(*arr)
78
+ url = arr.shift
79
+ revs = arr.shift || []
80
+
81
+ unless url =~ /#/
82
+ hds = revs.any? ? revs : []
83
+ return url, hds, revs[-1]
84
+ end
85
+
86
+ url, branch = url.split('#')[0..1]
87
+ checkout = revs[-1] || branch
88
+ [url, revs + [branch], checkout]
89
+ end
90
+
91
+ def local_path(path)
92
+ case path
93
+ when /file:\/\/localhost\//
94
+ path[17..-1]
95
+ when /file:\/\//
96
+ path[8..-1]
97
+ when /file:/
98
+ path[6..-1]
99
+ else
100
+ path
101
+ end
102
+ end
103
+
104
+ # Return repository location relative to cwd or from [paths]
105
+ def expand_path(*arr)
106
+ loc = arr.shift
107
+ dflt = arr.shift # dflt = default
108
+ cnfg = arr.pop # always take the last
109
+
110
+ return loc if loc =~ /:\/\// or File.directory?(File.join(loc, '.hg'))
111
+
112
+ path = cnfg['paths'][loc]
113
+
114
+ if !path && dflt
115
+ path = cnfg['paths'][dflt]
116
+ end
117
+ path || loc
118
+ end
119
+
120
+ def log_message(message, logfile)
121
+ if message && logfile
122
+ raise abort('options --message and --logfile are mutually exclusive')
123
+ end
124
+
125
+ if !message && logfile
126
+ begin
127
+ message = logfile == '-' ? $stdin.read : File.read(logfile)
128
+ rescue IOError => e
129
+ raise abort("can't read commit message '#{logfile}': #{e}")
130
+ end
131
+ end
132
+
133
+ message
134
+ end
135
+
136
+ end
137
+ end
@@ -0,0 +1,143 @@
1
+ command :config do |c|
2
+ c.workflow :all
3
+ c.desc "Configure amp interactively."
4
+ c.help <<-HELP
5
+ amp config
6
+
7
+ enter an interactive configuration program to adjust Amp's settings
8
+ This command:
9
+
10
+ * Allows the user to adjust Amp's settings without knowledge of
11
+ how these settings are stored, knowing obscure invisible files
12
+ and their formats
13
+
14
+ * Does not require that the user call it from within an amp repo-
15
+ sitory, as long as only global settings are changed.
16
+
17
+ HELP
18
+ c.maybe_repo
19
+ c.on_run do |opts, args|
20
+ repo = opts[:repository]
21
+
22
+ Amp::UI.say "Welcome to the Amp configuration editor. Pull up a seat!"
23
+ while true
24
+ choice = nil
25
+ Amp::UI.choose do |menu|
26
+ menu.prompt = "Would you like to work with local settings (repo-specific), or global ones?"
27
+ menu.choice("Local Settings") { choice = :local }
28
+ menu.choice("Global Settings") { choice = :global }
29
+ menu.choice("Exit") { exit(0) }
30
+ end
31
+
32
+ case choice
33
+ when :local
34
+ config = opts[:global_config]
35
+ when :global
36
+ config = opts[:global_config]
37
+ while config.parent_config
38
+ config = config.parent_config
39
+ end
40
+ end
41
+
42
+ choice = nil
43
+ Amp::UI.choose do |menu|
44
+ menu.prompt = "Would you like to view your configuration, or change settings?"
45
+ menu.choice("View Configuration") { choice = :view }
46
+ menu.choice("Change Settings") { choice = :edit }
47
+ menu.choice("Remove Setting") { choice = :remove }
48
+ menu.choice("Exit") { }
49
+ end
50
+
51
+ all_sections = config.config.sections.keys.map {|n| "[#{n}]"}.join(" ")
52
+
53
+ case choice
54
+ when :view
55
+ Amp::UI.say config.to_s
56
+ when :edit
57
+ section = Amp::UI.ask("Which section of settings would you like to edit? You may choose "+
58
+ "an existing section, or create a new one.\nCurrent sections:\n"+
59
+ all_sections+"\n> ")
60
+ key = Amp::UI.ask("Which setting would you like to change? You may choose an existing "+
61
+ "setting, or create a new one.\n Current settings: "+
62
+ config[section].keys.map {|n| "#{n}"}.join(" ")+"\n> ")
63
+ value = Amp::UI.ask("What would you like to set [#{section}:#{key}] to? ")
64
+ config[section,key] = value
65
+ config.save!
66
+ when :remove
67
+ section = Amp::UI.ask("Which section of settings would you like to edit? You may choose "+
68
+ "an existing section.\nCurrent sections:\n"+
69
+ all_sections+"\n> ")
70
+ key = Amp::UI.ask("Which setting would you like to change? You may choose an existing "+
71
+ "setting.\n Current settings: ["+
72
+ config[section].keys.map {|n| "#{n}"}.join(" ")+"]\n> ")
73
+ config[section].delete key
74
+ config.save!
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ namespace :config do
81
+ command :set do |c|
82
+ c.workflow :all
83
+ c.maybe_repo
84
+ c.opt :global, "Sets the value to the global configuration file", :short => "-g"
85
+ c.desc "Sets a configuration value in Amp's settings"
86
+ c.before do |opts, args|
87
+ if args.size < 2 || args.size > 3 || (args.size == 2 && args.first !~ /\:/)
88
+ puts "Usage: amp config:set setting-section:setting-name new-setting-value"
89
+ puts "Alt. Usage: amp config:set setting-section setting-name new-setting-value"
90
+ puts
91
+ c.break
92
+ end
93
+ true
94
+ end
95
+ c.on_run do |opts, args|
96
+ config = opts[:global_config]
97
+ if opts[:global]
98
+ while config.parent_config
99
+ config = config.parent_config
100
+ end
101
+ end
102
+ if args.size == 2
103
+ section, key = args.first.split(":")
104
+ value = args[1]
105
+ else
106
+ section, key, value = *args
107
+ end
108
+
109
+ config[section][key] = value
110
+ config.save!
111
+ end
112
+ end
113
+ command :get do |c|
114
+ c.workflow :all
115
+ c.maybe_repo
116
+ c.opt :global, "Gets the value from the global configuration file", :short => "-g"
117
+ c.desc "Gets a configuration value in Amp's settings"
118
+ c.before do |opts, args|
119
+ if args.size < 1 || args.size > 2 || (args.size == 1 && args.first !~ /\:/)
120
+ puts "Usage: amp config:get setting-section:setting-name"
121
+ puts "Alt. Usage: amp config:set setting-section setting-name"
122
+ puts
123
+ c.break
124
+ end
125
+ true
126
+ end
127
+ c.on_run do |opts, args|
128
+ config = opts[:global_config]
129
+ if opts[:global]
130
+ while config.parent_config
131
+ config = config.parent_config
132
+ end
133
+ end
134
+ if args.size == 1
135
+ section, key = args.first.split(":")
136
+ else
137
+ section, key = *args
138
+ end
139
+
140
+ Amp::UI.say config[section][key]
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,29 @@
1
+ command :help do |c|
2
+ c.workflow :all
3
+ c.desc "Prints the help for the program."
4
+
5
+ c.on_run do |options, args|
6
+ output = ""
7
+
8
+ if args.empty?
9
+ output << "These are the following commands available:\n"
10
+
11
+ Amp::Command.all_for_workflow(options[:global_config]["amp", "workflow"], false).sort {|k1, k2| k1.to_s <=> k2.to_s}.each do |k, v|
12
+ output << "\t#{k.to_s.ljust(30, " ")}#{v.desc}" + "\n"
13
+ end
14
+
15
+ output << 'Run "amp help [command]" for more information.'
16
+
17
+ Amp::UI.say output
18
+ else
19
+
20
+ unless cmd = Amp::Command.all_for_workflow(options[:global_config]["amp","workflow"])[args.first.to_sym]
21
+ Amp::UI.say "The command #{args.first} was not found."
22
+ else
23
+ cmd.collect_options
24
+ cmd.educate
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,10 @@
1
+ command :init do |c|
2
+ c.workflow :all
3
+ c.desc "Initializes a new repository in the current directory."
4
+ c.on_run do |options, args|
5
+ path = args.first ? args.first : '.'
6
+
7
+ Amp::Repositories::LocalRepository.new(path, true, options[:global_config])
8
+ puts "New repository initialized."
9
+ end
10
+ end
@@ -0,0 +1,137 @@
1
+ # Create an anonymous module so that the extra methods in the templates aren't
2
+ # entered into the global namespace
3
+ #
4
+ # This bears explanation:
5
+ # The `command` method operates regardless of location and communicates back to
6
+ # command HQ (command.rb). We use some helper methods here, which are defined at
7
+ # the bottom, and we want them to be hidden for everyone else. To do this, we wrap
8
+ # the entire `command` method call in an anonymous module so that `command`, which
9
+ # will operate anywhere, will work, but all extraneous data (the helper methods)
10
+ # is lost in memory.
11
+ Module.new do
12
+ command :templates do |c|
13
+ c.workflow :all
14
+ c.add_opt :list, "Lists all templates", :short => "-l"
15
+ c.desc "Starts an interactive template editor"
16
+ c.maybe_repo
17
+ c.on_run do |opts, args|
18
+
19
+
20
+
21
+ repo = opts[:repository]
22
+
23
+ if opts[:list]
24
+ print_templates(repo)
25
+ next
26
+ end
27
+ begin
28
+ Amp::UI.say "Welcome to the Amp template editor."
29
+
30
+ scope = 0
31
+ Amp::UI.choose do |menu|
32
+ menu.prompt = "Which kind of template do you want to modify?"
33
+ menu.choice("Global Templates") { scope = TEMPLATE_GLOBAL_SCOPE }
34
+ menu.choice("Local Templates (this Repo Only)") { scope = TEMPLATE_LOCAL_SCOPE }
35
+ menu.choice("Quit") { exit(0) }
36
+ menu.index = :number
37
+ end
38
+
39
+ if scope == TEMPLATE_LOCAL_SCOPE && !repo
40
+ puts "No local repository found! Sorry."
41
+ next
42
+ end
43
+
44
+ template_directory = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "templates"))
45
+ Amp::UI.say "\n"
46
+ mode = 0
47
+ Amp::UI.choose do |menu|
48
+ menu.prompt = "Do you want to edit, add, or remove a template?"
49
+ menu.choice("Edit") { mode = TEMPLATE_EDIT_MODE }
50
+ menu.choice("Add") { mode = TEMPLATE_ADD_MODE }
51
+ menu.choice("Remove") { mode = TEMPLATE_DELETE_MODE }
52
+ menu.choice("Start Over") { }
53
+ menu.index = :number
54
+ end
55
+ Amp::UI.say "\n"
56
+ case mode
57
+ when TEMPLATE_EDIT_MODE
58
+ filename = nil
59
+ Amp::UI.choose do |menu|
60
+ menu.prompt = "Which template would you like to edit?"
61
+ templates_for_scope(scope, repo).each do |template|
62
+ menu.choice(template.name) { filename = template.file }
63
+ end
64
+ menu.choice("Start Over") { } #do nothing
65
+ menu.index = :number
66
+ end
67
+ Amp::UI.edit_file(filename) if filename
68
+ when TEMPLATE_ADD_MODE
69
+ filename = Amp::UI.ask("What would you like to name your template? ", String)
70
+ type = Amp::UI.ask("What kind of template? (log, commit) ", String) {|q| q.in = ["log","commit"]}
71
+ old_file = Amp::Support::Template["blank-#{type}"].file
72
+ new_file = File.join(template_directory, filename + ".erb")
73
+ File.copy(old_file, new_file)
74
+ Amp::UI.edit_file new_file
75
+ Amp::Support::FileTemplate.new(filename, new_file)
76
+ when TEMPLATE_DELETE_MODE
77
+ filename = nil
78
+ Amp::UI.choose do |menu|
79
+ menu.prompt = "Which template would you like to delete?"
80
+ templates_for_scope(scope, repo).each do |template|
81
+ menu.choice(template.name) do
82
+ Amp::Support::Template.unregister template.name
83
+ filename = template.file
84
+ end
85
+ end
86
+ menu.choice("Start Over") { } #do nothing
87
+ menu.index = :number
88
+ end
89
+ if filename # didn't start over
90
+ shortname = filename.split("/").last.gsub(/\.erb/,"")
91
+ sure = Amp::UI.agree "Are you sure you want to delete the template \"#{shortname}\"? (y/n/yes/no) "
92
+ if sure
93
+ File.safe_unlink(filename)
94
+ end
95
+ end
96
+ end
97
+ Amp::UI.say "\n"
98
+ end while true
99
+
100
+ end
101
+
102
+
103
+ end
104
+ TEMPLATE_GLOBAL_SCOPE = 1
105
+ TEMPLATE_LOCAL_SCOPE = 2
106
+
107
+ TEMPLATE_EDIT_MODE = 1
108
+ TEMPLATE_ADD_MODE = 2
109
+ TEMPLATE_DELETE_MODE = 3
110
+ # This is how we scope methods such that the command has access to them, but nobody else, without
111
+ # defining nested methods.
112
+ class << self
113
+
114
+ def templates_for_scope(scope, repo)
115
+ case scope
116
+ when TEMPLATE_GLOBAL_SCOPE
117
+ Amp::Support::Template.all_templates.values
118
+ when TEMPLATE_LOCAL_SCOPE
119
+ path = repo.join("templates")
120
+ FileUtils.makedirs path unless File.exists? path
121
+ Dir.entries(path).reject {|e| e =~ /^\./}.map {|f| File.join(dir, f)}
122
+ end
123
+ end
124
+
125
+ def print_templates(repo)
126
+ Amp::UI.say "Global Templates"
127
+ Amp::UI.say "================"
128
+ templates_for_scope(TEMPLATE_GLOBAL_SCOPE, repo).each {|template| Amp::UI.say template.name}
129
+ if repo
130
+ Amp::UI.say "\nLocal Templates"
131
+ Amp::UI.say "================"
132
+ # templates_for_scope(TEMPLATE_LOCAL_SCOPE, repo).each {|f| Amp::UI.say f.split("/").last.gsub(/\.erb/,"")}
133
+ end
134
+ Amp::UI.say "\n"
135
+ end
136
+ end
137
+ end