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
@@ -1,94 +1,17 @@
1
1
  module Amp
2
2
  module Repositories
3
-
4
- def self.pick(config, path='', create=false)
5
- # hot path so we don't load the HTTP repos!
6
- unless path[0,4] == "http"
7
- return LocalRepository.new(find_repo(path), create, config)
8
- end
9
- return HTTPSRepository.new(path, create, config) if path[0,5] == "https"
10
- return HTTPRepository.new(path, create, config) if path[0,4] == "http"
11
- end
12
-
13
- def self.find_repo path
14
- while !(File.directory?(File.join(path, ".hg")))
15
- old_path, path = path, File.dirname(path)
16
- if path == old_path
17
- raise "No Repository Found"
18
- end
19
- end
20
- path
21
- end
22
-
23
- class RepositoryCapabilityError < StandardError; end
24
3
  class RepoError < StandardError; end
25
4
 
26
- ##
27
- # = Repository
28
- # This is an abstract class that represents a repository.
29
- # All repositories must inherit from this class.
30
- class Repository
31
-
32
- ##
33
- # Is this repository capable of the given action/format? Or, if the capability
34
- # has a value assigned to it (like "revlog" = "version2"), what is it?
35
- #
36
- # @param [String] capability the name of the action/format/what have you that we need to test
37
- # @return [Boolean, String] whether or not we support the given capability; or, for
38
- # capabilities that have a value, the string value.
39
- def capable?(capability)
40
- get_capabilities
41
- @capabilities[capability]
42
- end
43
-
44
- ##
45
- # No-op, to be implemented by remote repo classes.
46
- def get_capabilities; end
47
-
48
- ##
49
- # Raises an exception if we don't have a given capability.
50
- #
51
- # @param [String] capability what capability we are requiring
52
- # @param [String] purpose why we need it - enhances the output
53
- # @raise [RepositoryCapabilityError] if we don't support it, this is raised
54
- def require_capability(capability, purpose)
55
- get_capabilities
56
- raise RepositoryCapabilityError.new(<<-EOF
57
- Can't #{purpose}; remote repository doesn't support the #{capability} capability.
58
- EOF
59
- ) unless @capabilities[capability]
60
- end
61
-
62
- ##
63
- # is the repository a local repo?
64
- #
65
- # @return [Boolean] is the repository local?
66
- def local?
67
- false
68
- end
69
-
70
- ##
71
- # can we copy files? Only for local repos.
72
- #
73
- # @return [Boolean] whether we are able to copy files
74
- def can_copy?
75
- local?
5
+ # make this git-hg-svn-cvs-whatever friendly!
6
+ def self.pick(config, path='', create=false)
7
+ GenericRepoPicker.each do |picker|
8
+ return picker.pick(config, path, create) if picker.repo_in_dir?(path)
76
9
  end
77
10
 
78
- ##
79
- # Joins the given path with our URL. Necessary due to the difference between local
80
- # and remote repos.
81
- #
82
- # @param [String] path the path we are appending
83
- # @return [String] our URL joined with the requested path
84
- def add_path(path)
85
- myurl = self.url
86
- if myurl.end_with? '/'
87
- myurl + path
88
- else
89
- myurl + '/' + path
90
- end
91
- end
92
- end
93
- end
94
- end
11
+ # We have found... nothing
12
+ nil
13
+ end # def self.pick
14
+
15
+ end # module Repositories
16
+
17
+ end # module Amp
@@ -144,7 +144,7 @@ module Sinatra
144
144
  def amp_get_capabilities(amp_repo)
145
145
  caps = ["lookup", "changegroupsubset"]
146
146
  # uncompressed for streaming?
147
- caps << "unbundle=#{Amp::RevlogSupport::ChangeGroup::FORMAT_PRIORITIES.join(',')}"
147
+ caps << "unbundle=#{Amp::Mercurial::RevlogSupport::ChangeGroup::FORMAT_PRIORITIES.join(',')}"
148
148
  caps.join ' '
149
149
  end
150
150
 
@@ -380,11 +380,11 @@ module Sinatra
380
380
  header = fp.read(6)
381
381
  if header.start_with?("HG") && !header.start_with?("HG10")
382
382
  raise ArgumentError.new("unknown bundle version")
383
- elsif !Amp::RevlogSupport::ChangeGroup::BUNDLE_HEADERS.include?(header)
383
+ elsif !Amp::Mercurial::RevlogSupport::ChangeGroup::BUNDLE_HEADERS.include?(header)
384
384
  raise ArgumentError.new("unknown bundle compression type")
385
385
  end
386
386
 
387
- stream = Amp::RevlogSupport::ChangeGroup.unbundle(header, fp)
387
+ stream = Amp::Mercurial::RevlogSupport::ChangeGroup.unbundle(header, fp)
388
388
 
389
389
  end
390
390
 
@@ -108,7 +108,7 @@ module Amp
108
108
 
109
109
  def load_browser_info(changeset, path)
110
110
 
111
- mapping = changeset.manifest
111
+ mapping = changeset.manifest_entry
112
112
  orig_path = nil
113
113
  # if the path is a file (because we only keep track of files)
114
114
  if mapping[path]
@@ -14,7 +14,7 @@
14
14
  - file_list.each do |file|
15
15
  %tr{:class => (path + "/" + file[:link] == orig_path) ? "selected" : ""}
16
16
  - if file[:type] == :file
17
- - fl = repo.file(path + '/' + file[:name])
17
+ - fl = repo.file_log(path + '/' + file[:name])
18
18
  - last = fl.index[-2].link_rev
19
19
  %td.filename
20
20
  = link_to_file root, changeset_node, file[:link], :text => file[:name]
@@ -1,13 +1,6 @@
1
1
  - vf_cur = changeset.get_file file
2
- - new_rev = vf_cur.file_rev
3
- - parents = vf_cur.parents
4
2
  - vf_parent = parents.first
5
- - parent_rev = vf_parent && vf_parent.file_rev
6
- - old_date = vf_parent && vf_parent.changeset.easy_date
7
- - new_date = changeset.easy_date
8
- - new_path = vf_cur.path
9
- - old_path = vf_parent ? vf_parent.path : "/dev/null"
10
3
  %li
11
4
  %h2= vf_cur.path
12
5
  %ul.diff
13
- = parse_diff(vf_cur.file_log.unified_revision_diff(parent_rev, old_date, new_rev, new_date, old_path, new_path))
6
+ = parse_diff(vf_cur.unified_diff_with(vf_parent))
@@ -25,7 +25,7 @@
25
25
  %td.data= @changeset.children.map {|c| link_to_changeset(root, c.node_id.hexlify) }.join(" ")
26
26
  %tr
27
27
  %td.label files
28
- %td.data= @changeset.files.map {|file| link_to_file(root, @changeset.node_id.hexlify, file) }.join("<br />")
28
+ %td.data= @changeset.changed_files.keys.map {|file| link_to_file(root, @changeset.node_id.hexlify, file) }.join("<br />")
29
29
  %ul.diff-list
30
- - @changeset.files.each do |file|
30
+ - @changeset.changed_files.keys.each do |file|
31
31
  = haml :_diff_file, :locals => {:file => file, :changeset => @changeset}
@@ -13,7 +13,7 @@
13
13
  = haml :_browser, :locals => {:root => root, :vf_cur => vf_cur, :path => path, :orig_path => orig_path, :file_list => file_list, :changeset_node => changeset_node, :repo => repo}
14
14
  .browser-file
15
15
  - if vf_cur
16
- - filelog = repo.file orig_path
16
+ - filelog = repo.file_log orig_path
17
17
  %h2.header Versions
18
18
  %ul.versions
19
19
  - filelog.each do |rev|
@@ -13,7 +13,7 @@
13
13
  = haml :_browser, :locals => {:root => root, :vf_cur => vf_cur, :path => path, :orig_path => orig_path, :file_list => file_list, :changeset_node => changeset_node, :repo => repo}
14
14
  .browser-file
15
15
  - if vf_cur
16
- - filelog = repo.file orig_path
16
+ - filelog = repo.file_log orig_path
17
17
  %h2.header Versions
18
18
  %ul.versions
19
19
  - filelog.each do |rev|
@@ -19,8 +19,9 @@ module Amp
19
19
  # @return [UIMenu] the new menu
20
20
  def initialize
21
21
  @choices = []
22
- @prompt = "Pick an option, please."
23
- @index = :number
22
+ @prompt = "Pick an option, please."
23
+ @index = :number
24
+ @config = nil
24
25
  end
25
26
 
26
27
  ##
@@ -60,7 +61,6 @@ module Amp
60
61
 
61
62
  module UI
62
63
  extend self
63
- extend Amp::Merges::MergeUI
64
64
 
65
65
  class << self
66
66
  attr_accessor :config
@@ -72,7 +72,7 @@ module Amp
72
72
  #
73
73
  # @param [#to_s] warning the warning to print to standard output
74
74
  def warn(warning)
75
- if !@config || @config["ui","amp-show-warnings",Boolean,true]
75
+ if !config || config["ui", "amp-show-warnings", Boolean, true]
76
76
  err "warning: #{warning}"
77
77
  end
78
78
  end
@@ -112,7 +112,7 @@ module Amp
112
112
  # @return [NilClass]
113
113
  def status(update='')
114
114
  return unless $display
115
- if !@config || @config["ui", "amp-show-status", Boolean, true]
115
+ if !config || config["ui", "amp-show-status", Boolean, true]
116
116
  say "status: #{update}"
117
117
  end
118
118
  end
@@ -124,7 +124,7 @@ module Amp
124
124
  # @return [NilClass]
125
125
  def note(note='')
126
126
  return unless $display
127
- if !@config || @config["ui", "amp-show-notes", Boolean, false]
127
+ if !config || config["ui", "amp-show-notes", Boolean, false]
128
128
  say "note: #{note}"
129
129
  end
130
130
  end
@@ -165,8 +165,8 @@ module Amp
165
165
  def ask(question='', type=String)
166
166
  type = type.to_s.downcase.to_sym
167
167
 
168
- print question.to_s
169
- result = gets.chomp unless type == :password
168
+ tell question.to_s
169
+ result = $stdin.gets.chomp unless type == :password
170
170
 
171
171
  # type conversion
172
172
  case type
@@ -174,6 +174,8 @@ module Amp
174
174
  result
175
175
  when :integer, :fixnum, :bignum, :numeric
176
176
  result.to_i
177
+ when :float
178
+ result.to_f
177
179
  when :array
178
180
  result.split(',').map {|e| e.strip }
179
181
  when :password
@@ -225,7 +227,7 @@ EOS
225
227
  #
226
228
  # @param [String, #to_s] message The debug message to be printed
227
229
  def debug(message='')
228
- if @config && @config["debug","messages", Boolean, false]
230
+ if config && config["debug","messages", Boolean, false]
229
231
  say message
230
232
  end
231
233
  end
@@ -245,7 +247,7 @@ EOS
245
247
  tempfile.write text
246
248
  tempfile.close
247
249
 
248
- ENV["AMPUSER"] = username
250
+ ENV["HGUSER"] = username
249
251
  edit_file path
250
252
 
251
253
  text = File.open(path) {|tf| tf.read } || ''
@@ -255,24 +257,6 @@ EOS
255
257
  text.gsub!(/^AMP:.*\n/,"")
256
258
  text
257
259
  end
258
-
259
- ##
260
- # Asks the user something.
261
- #
262
- # @deprecated
263
- # @param [#to_s] message the message to send
264
- # @param [Class, lambda] type anything to force a type. If you supply
265
- # a class, then the answer will be parsed into that class. If you
266
- # supply a lambda, the string will be provided, and you do the conversion
267
- # @param [] default Whatever the default answer is, if they fail to provide
268
- # a valid answer.
269
- # @return [String] their response with whitespace removed, or the default value
270
- def prompt(message='', type=String, default=nil)
271
- say message.to_s
272
- response = STDIN.gets.strip
273
- response = default if response == ""
274
- return response
275
- end
276
260
 
277
261
  ##
278
262
  # Gets the editor for the current system using environment variables or
@@ -280,7 +264,7 @@ EOS
280
264
  #
281
265
  # @return [String] the name of the editor command to execute
282
266
  def get_editor
283
- return ENV["AMPEDITOR"] || ENV["HGEDITOR"] || (@config && @config["ui","editor"]) ||
267
+ return ENV["AMPEDITOR"] || ENV["HGEDITOR"] || (config && config["ui","editor"]) ||
284
268
  ENV["VISUAL"] || ENV["EDITOR"] || "vi"
285
269
  end
286
270
  end
@@ -43,7 +43,7 @@ class Generator
43
43
  # return to its caller.
44
44
  callcc do |here|
45
45
  @current_context = here
46
- if @yield_context
46
+ if (@yield_context ||= nil)
47
47
  # Run next iteration of the running loop
48
48
  @yield_context.call
49
49
  else
@@ -76,7 +76,6 @@ private :caller_file
76
76
  # @param [String] path_to_alt the path to the pure ruby version of the C library. Will
77
77
  # be loaded relative to the caller's file
78
78
  def amp_c_extension(path_to_c, path_to_alt)
79
-
80
79
  if $USE_RUBY
81
80
  Amp::UI.debug "Loading alternative ruby: #{path_to_alt}"
82
81
  require File.join(File.dirname(caller_file(1)), path_to_alt)
@@ -85,7 +84,7 @@ def amp_c_extension(path_to_c, path_to_alt)
85
84
 
86
85
  begin
87
86
  offset = RUBY_VERSION < "1.9" ? 1 : 0
88
- require File.expand_path(File.join(File.dirname(caller_file(offset)), path_to_c))
87
+ require path_to_c #File.expand_path(File.join(File.dirname(caller_file(offset)), path_to_c))
89
88
  rescue LoadError # C Version could not be found, try ruby version
90
89
  Amp::UI.debug "Loading alternative ruby: #{path_to_alt}"
91
90
  require File.join(File.dirname(caller_file(1)), path_to_alt)
@@ -2,17 +2,16 @@ require 'delegate'
2
2
  require 'logger'
3
3
  module Amp
4
4
  module Support
5
+ LOGGER_LEVELS = [:warn, :info, :fatal, :error, :debug]
5
6
  module SingletonLogger
6
7
  attr_accessor :singleton_object
7
8
  def global_logger
8
9
  singleton_object
9
10
  end
10
11
 
11
- def warn(*args); global_logger.warn(*args); end
12
- def info(*args); global_logger.info(*args); end
13
- def fatal(*args); global_logger.fatal(*args); end
14
- def error(*args); global_logger.error(*args); end
15
- def debug(*args); global_logger.debug(*args); end
12
+ LOGGER_LEVELS.each do |message|
13
+ define_method(message) { |*args| global_logger.send(message, *args) }
14
+ end
16
15
 
17
16
  def method_missing(meth, *args, &block)
18
17
  if global_logger.respond_to?(meth)
@@ -28,11 +27,9 @@ module Amp
28
27
  @output = output
29
28
  end
30
29
 
31
- def warn(input); @output.puts(input); end
32
- def info(input); @output.puts(input); end
33
- def fatal(input); @output.puts(input); end
34
- def error(input); @output.puts(input); end
35
- def debug(input); @output.puts(input); end
30
+ LOGGER_LEVELS.each do |message|
31
+ define_method(message) {|input| @output.puts(input) }
32
+ end
36
33
  end
37
34
 
38
35
  class Logger < DelegateClass(::Logger)
@@ -72,12 +69,9 @@ module Amp
72
69
  self
73
70
  end
74
71
 
75
- def warn(input); @source.warn( "\t\t"*@indent + input); self; end
76
- def info(input); @source.info( "\t\t"*@indent + input); self; end
77
- def fatal(input); @source.fatal("\t\t"*@indent + input); self; end
78
- def error(input); @source.error("\t\t"*@indent + input); self; end
79
- def debug(input); @source.debug("\t\t"*@indent + input); self; end
80
-
72
+ LOGGER_LEVELS.each do |message|
73
+ define_method(message) { |input| @source.send(message, "\t\t"*@indent + input); self }
74
+ end
81
75
 
82
76
  def level=(level)
83
77
  receiver = @source
@@ -10,7 +10,7 @@ module Amp
10
10
  # their Match class, because we needed access to three things from this
11
11
  # one object: the explicit files passed, the includes, and the excludes.
12
12
  class Match
13
- extend Ignore
13
+ extend Mercurial::Ignore
14
14
 
15
15
  attr_reader :block
16
16
  attr_reader :files
@@ -109,6 +109,21 @@ module Amp
109
109
  @exclude && @exclude.any? {|r| file =~ r}
110
110
  end
111
111
 
112
+ ##
113
+ # Filters a list of filenames, weeding out ones that do not match at all.
114
+ #
115
+ # @param [Array<String>] list a list of filenames to run against the matcher
116
+ # @param [Hash] opts options for filtering. See below.
117
+ # @option opts [Boolean] :precision (false) returns the list not as a list of
118
+ # filenames, but as a list of hashes, with a key :filename for the file, and
119
+ # a key :exact with a boolean value specifying if the match was exact or not.
120
+ # @return [Array<String>] the filtered list of filenames
121
+ def filter_list(list, opts={})
122
+ result = list.select {|filename| self.call(filename)}
123
+ result.map! {|k| {:filename => k, :exact => exact?(k)}} if opts[:precision]
124
+ result
125
+ end
126
+
112
127
  ##
113
128
  # Is it an exact match or an approximate match and not
114
129
  # a file to be excluded?
@@ -119,11 +134,10 @@ module Amp
119
134
  # @param [String] file the file to test
120
135
  # @return [Boolean] does it pass?
121
136
  def call(file)
122
- if exact? file and failure? file
137
+ if exact?(file) && failure?(file)
123
138
  raise StandardError.new("File #{file.inspect} is to be both included and excluded")
124
139
  end
125
- # `and` because it's loosely binding
126
- exact?(file) || included?(file) || approximate?(file) and !failure?(file)
140
+ (exact?(file) || included?(file) || approximate?(file)) && !failure?(file)
127
141
  end
128
142
  alias_method :[], :call
129
143
 
@@ -0,0 +1,151 @@
1
+ module Amp
2
+ module Mercurial
3
+ module Ignore
4
+ extend self
5
+
6
+ COMMENT = /((^|[^\\])(\\\\)*)#.*/
7
+ SYNTAXES = {'re' => :regexp, 'regexp' => :regexp, 'glob' => :glob,
8
+ 'relglob' => :relglob, 'relre' => :regexp, 'path' => :glob,
9
+ 'relpath' => :relglob}
10
+
11
+ ##
12
+ # Parses the ignore file, +file+ (or ".hgignore")
13
+ #
14
+ # @param [String] root the root of the repo
15
+ # @param [Array<String>] files absolute paths to files
16
+ def parse_ignore(root, files=[])
17
+ real_files = files.select {|f| File.exist? File.join(root, f) }
18
+ all_patterns = real_files.inject [] do |collection, file|
19
+ text = File.read File.join(root, file)
20
+ collection.concat matcher_for_text(text) # i know this is evil
21
+ end # real_files.inject
22
+
23
+ # here's the proc to do the tests
24
+ regexps_to_proc all_patterns
25
+ end
26
+
27
+ ##
28
+ # Parse the lines into valid syntax. Removes empty lines.
29
+ #
30
+ # @param [String] file and open file
31
+ def parse_lines(text)
32
+ lines = text.split("\n").inject [] do |lines, line|
33
+ line = strip_comment line
34
+ line.rstrip!
35
+ line.empty? ? lines : lines << line # I KNOW THIS IS EVIL
36
+ end
37
+ end
38
+
39
+ ##
40
+ # Strips comments from a line of text
41
+ #
42
+ # @param [String] line the line of text to de-commentify
43
+ # @return [String] the same line of text, with comments removed.
44
+ def strip_comment(line)
45
+ if line =~ /#/
46
+ line.sub! COMMENT, "\\1"
47
+ line.gsub! "\\#", "#"
48
+ end
49
+ line
50
+ end
51
+
52
+ ##
53
+ # Produces an array of regexps which can be used
54
+ # for matching files
55
+ #
56
+ # @param [String] text the text to parse
57
+ # @return [Array<Regexp>] the regexps generated from the strings and syntaxes
58
+ def matcher_for_text(text)
59
+ return [] unless text
60
+ syntax = nil
61
+ lines = parse_lines(text).reject {|line| line.empty? }
62
+
63
+ # take the lines and create a new array of the patterns
64
+ lines.inject [] do |lines, line|
65
+ # check for syntax changes
66
+ if line.start_with? "syntax:"
67
+ syntax = SYNTAXES[line[7..-1].strip] || :regexp
68
+ lines # move on
69
+ else
70
+ # I KNOW THIS IS EVIL
71
+ lines << parse_line(syntax, line) # could be nil, so we need to compact it
72
+ end
73
+ end # lines.inject
74
+ end
75
+
76
+ ##
77
+ # Much like matcher_for_text, except tailored to single line strings
78
+ #
79
+ # @see matcher_for_text
80
+ # @param [String] string the string to parse
81
+ # @return [Regexp] the regexps generated from the strings and syntaxes
82
+ def matcher_for_string(string)
83
+ scanpt = string =~ /(\w+):(.+)/
84
+ if scanpt.nil?
85
+ include_syntax = :regexp # just a line, no specified syntax
86
+ include_regexp = string # no syntax, thus whole thing is pattern
87
+ else
88
+ include_syntax = $1.to_sym # the syntax is the first match
89
+ include_regexp = $2.strip # the rest of the string is the pattern
90
+ end
91
+ parse_line include_syntax, include_regexp
92
+ end
93
+
94
+ ##
95
+ # Turns a single line, given a syntax, into either
96
+ # a valid regexp or nil. If it is nil, it means the
97
+ # syntax was incorrect.
98
+ #
99
+ # @param [Symbol] syntax the syntax to parse with (:regexp, :glob, :relglob)
100
+ # @param [String] line the line to parse
101
+ # @return [NilClass, Regexp] nil means the syntax was a bad choice
102
+ def parse_line(syntax, line)
103
+ return nil unless syntax
104
+ syntax = syntax.to_sym
105
+ # find more valid syntax stuff
106
+ # we need to make everything here valid regexps
107
+ case syntax
108
+ when :regexp
109
+ # basic regex
110
+ pattern = /#{line}/
111
+ when :glob, :relglob
112
+ # glob: glob (shell style), relative to the root of the repository
113
+ # relglob: glob, except we just match somewhere in the string, not
114
+ # from the root of the repository
115
+ ps = line.split '/**/'
116
+ ps.map! do |l|
117
+ parts = l.split '*' # split it up and we'll escape all the parts
118
+ parts.map! {|p| Regexp.escape p }
119
+ parts.join '[^/]*' # anything but a slash, ie, no change in directories
120
+ end
121
+ joined = ps.join '/(?:.*/)*'
122
+ pattern = syntax == :glob ? /^#{joined}/ : /#{joined}/
123
+ else
124
+ pattern = nil
125
+ end
126
+
127
+ pattern
128
+ end
129
+
130
+ ##
131
+ # Converts all the ignored regexps into a proc that matches against all of these
132
+ # regexps. That way we can pass around a single proc that checks if a file is ignored.
133
+ #
134
+ # @param [Array<Regexp>] regexps all of the regexes that we need to match against
135
+ # @return [Proc] a proc that, when called with a file's path, will return whether
136
+ # it matches any of the regexps.
137
+ def regexps_to_proc(*regexps)
138
+ # flatten: because if you pass in an array vs. three single args
139
+ # compact: because #parse_line can return nil (and it will travel to here)
140
+ regexps = regexps.flatten.compact
141
+ if regexps.empty?
142
+ proc { false }
143
+ else
144
+ proc { |file| regexps.any? {|p| file =~ p } }
145
+ end
146
+ end
147
+ alias_method :regexp_to_proc, :regexps_to_proc
148
+
149
+ end
150
+ end
151
+ end