amp 0.5.2 → 0.5.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +12 -0
- data/.hgignore +3 -0
- data/AUTHORS +1 -1
- data/Manifest.txt +99 -38
- data/README.md +3 -3
- data/Rakefile +53 -18
- data/SCHEDULE.markdown +5 -1
- data/TODO.markdown +120 -149
- data/ampfile.rb +3 -1
- data/bin/amp +4 -1
- data/ext/amp/bz2/extconf.rb +1 -1
- data/ext/amp/mercurial_patch/extconf.rb +1 -1
- data/ext/amp/mercurial_patch/mpatch.c +4 -3
- data/ext/amp/priority_queue/extconf.rb +1 -1
- data/ext/amp/support/extconf.rb +1 -1
- data/ext/amp/support/support.c +1 -1
- data/lib/amp.rb +125 -67
- data/lib/amp/commands/command.rb +12 -10
- data/lib/amp/commands/command_support.rb +8 -1
- data/lib/amp/commands/commands/help.rb +2 -20
- data/lib/amp/commands/commands/init.rb +14 -2
- data/lib/amp/commands/commands/templates.rb +6 -4
- data/lib/amp/commands/commands/version.rb +15 -1
- data/lib/amp/commands/commands/workflow.rb +3 -3
- data/lib/amp/commands/commands/workflows/git/add.rb +3 -3
- data/lib/amp/commands/commands/workflows/git/copy.rb +1 -1
- data/lib/amp/commands/commands/workflows/git/rm.rb +4 -2
- data/lib/amp/commands/commands/workflows/hg/add.rb +1 -1
- data/lib/amp/commands/commands/workflows/hg/addremove.rb +2 -2
- data/lib/amp/commands/commands/workflows/hg/annotate.rb +8 -2
- data/lib/amp/commands/commands/workflows/hg/bisect.rb +253 -0
- data/lib/amp/commands/commands/workflows/hg/branch.rb +1 -1
- data/lib/amp/commands/commands/workflows/hg/branches.rb +3 -3
- data/lib/amp/commands/commands/workflows/hg/bundle.rb +3 -3
- data/lib/amp/commands/commands/workflows/hg/clone.rb +4 -5
- data/lib/amp/commands/commands/workflows/hg/commit.rb +37 -1
- data/lib/amp/commands/commands/workflows/hg/copy.rb +2 -1
- data/lib/amp/commands/commands/workflows/hg/debug/index.rb +1 -1
- data/lib/amp/commands/commands/workflows/hg/diff.rb +3 -8
- data/lib/amp/commands/commands/workflows/hg/forget.rb +5 -4
- data/lib/amp/commands/commands/workflows/hg/identify.rb +6 -6
- data/lib/amp/commands/commands/workflows/hg/import.rb +1 -1
- data/lib/amp/commands/commands/workflows/hg/incoming.rb +2 -2
- data/lib/amp/commands/commands/workflows/hg/log.rb +5 -4
- data/lib/amp/commands/commands/workflows/hg/merge.rb +1 -1
- data/lib/amp/commands/commands/workflows/hg/move.rb +5 -3
- data/lib/amp/commands/commands/workflows/hg/outgoing.rb +1 -1
- data/lib/amp/commands/commands/workflows/hg/push.rb +6 -7
- data/lib/amp/commands/commands/workflows/hg/remove.rb +2 -2
- data/lib/amp/commands/commands/workflows/hg/resolve.rb +6 -23
- data/lib/amp/commands/commands/workflows/hg/root.rb +1 -2
- data/lib/amp/commands/commands/workflows/hg/status.rb +21 -12
- data/lib/amp/commands/commands/workflows/hg/tag.rb +2 -2
- data/lib/amp/commands/commands/workflows/hg/untrack.rb +12 -0
- data/lib/amp/commands/commands/workflows/hg/verify.rb +13 -3
- data/lib/amp/commands/commands/workflows/hg/what_changed.rb +18 -0
- data/lib/amp/commands/dispatch.rb +12 -13
- data/lib/amp/dependencies/amp_support.rb +1 -1
- data/lib/amp/dependencies/amp_support/ruby_amp_support.rb +1 -0
- data/lib/amp/dependencies/maruku.rb +136 -0
- data/lib/amp/dependencies/maruku/attributes.rb +227 -0
- data/lib/amp/dependencies/maruku/defaults.rb +71 -0
- data/lib/amp/dependencies/maruku/errors_management.rb +92 -0
- data/lib/amp/dependencies/maruku/helpers.rb +260 -0
- data/lib/amp/dependencies/maruku/input/charsource.rb +326 -0
- data/lib/amp/dependencies/maruku/input/extensions.rb +69 -0
- data/lib/amp/dependencies/maruku/input/html_helper.rb +189 -0
- data/lib/amp/dependencies/maruku/input/linesource.rb +111 -0
- data/lib/amp/dependencies/maruku/input/parse_block.rb +615 -0
- data/lib/amp/dependencies/maruku/input/parse_doc.rb +234 -0
- data/lib/amp/dependencies/maruku/input/parse_span_better.rb +746 -0
- data/lib/amp/dependencies/maruku/input/rubypants.rb +225 -0
- data/lib/amp/dependencies/maruku/input/type_detection.rb +147 -0
- data/lib/amp/dependencies/maruku/input_textile2/t2_parser.rb +163 -0
- data/lib/amp/dependencies/maruku/maruku.rb +33 -0
- data/lib/amp/dependencies/maruku/output/to_ansi.rb +223 -0
- data/lib/amp/dependencies/maruku/output/to_html.rb +991 -0
- data/lib/amp/dependencies/maruku/output/to_markdown.rb +164 -0
- data/lib/amp/dependencies/maruku/output/to_s.rb +56 -0
- data/lib/amp/dependencies/maruku/string_utils.rb +191 -0
- data/lib/amp/dependencies/maruku/structures.rb +167 -0
- data/lib/amp/dependencies/maruku/structures_inspect.rb +87 -0
- data/lib/amp/dependencies/maruku/structures_iterators.rb +61 -0
- data/lib/amp/dependencies/maruku/textile2.rb +1 -0
- data/lib/amp/dependencies/maruku/toc.rb +199 -0
- data/lib/amp/dependencies/maruku/usage/example1.rb +33 -0
- data/lib/amp/dependencies/maruku/version.rb +40 -0
- data/lib/amp/dependencies/priority_queue.rb +2 -1
- data/lib/amp/dependencies/python_config.rb +2 -1
- data/lib/amp/graphs/ancestor.rb +2 -1
- data/lib/amp/graphs/copies.rb +236 -233
- data/lib/amp/help/entries/__default__.erb +31 -0
- data/lib/amp/help/entries/commands.erb +6 -0
- data/lib/amp/help/entries/mdtest.md +35 -0
- data/lib/amp/help/entries/silly +3 -0
- data/lib/amp/help/help.rb +288 -0
- data/lib/amp/profiling_hacks.rb +5 -3
- data/lib/amp/repository/abstract/abstract_changeset.rb +97 -0
- data/lib/amp/repository/abstract/abstract_local_repo.rb +181 -0
- data/lib/amp/repository/abstract/abstract_staging_area.rb +180 -0
- data/lib/amp/repository/abstract/abstract_versioned_file.rb +100 -0
- data/lib/amp/repository/abstract/common_methods/changeset.rb +75 -0
- data/lib/amp/repository/abstract/common_methods/local_repo.rb +277 -0
- data/lib/amp/repository/abstract/common_methods/staging_area.rb +233 -0
- data/lib/amp/repository/abstract/common_methods/versioned_file.rb +71 -0
- data/lib/amp/repository/generic_repo_picker.rb +78 -0
- data/lib/amp/repository/git/repo_format/changeset.rb +336 -0
- data/lib/amp/repository/git/repo_format/staging_area.rb +192 -0
- data/lib/amp/repository/git/repo_format/versioned_file.rb +119 -0
- data/lib/amp/repository/git/repositories/local_repository.rb +164 -0
- data/lib/amp/repository/git/repository.rb +41 -0
- data/lib/amp/repository/mercurial/encoding/mercurial_diff.rb +382 -0
- data/lib/amp/repository/mercurial/encoding/mercurial_patch.rb +1 -0
- data/lib/amp/repository/mercurial/encoding/patch.rb +294 -0
- data/lib/amp/repository/mercurial/encoding/pure_ruby/ruby_mercurial_patch.rb +124 -0
- data/lib/amp/repository/mercurial/merging/merge_ui.rb +327 -0
- data/lib/amp/repository/mercurial/merging/simple_merge.rb +452 -0
- data/lib/amp/repository/mercurial/repo_format/branch_manager.rb +266 -0
- data/lib/amp/repository/mercurial/repo_format/changeset.rb +768 -0
- data/lib/amp/repository/mercurial/repo_format/dir_state.rb +716 -0
- data/lib/amp/repository/mercurial/repo_format/journal.rb +218 -0
- data/lib/amp/repository/mercurial/repo_format/lock.rb +210 -0
- data/lib/amp/repository/mercurial/repo_format/merge_state.rb +228 -0
- data/lib/amp/repository/mercurial/repo_format/staging_area.rb +367 -0
- data/lib/amp/repository/mercurial/repo_format/store.rb +487 -0
- data/lib/amp/repository/mercurial/repo_format/tag_manager.rb +322 -0
- data/lib/amp/repository/mercurial/repo_format/updatable.rb +543 -0
- data/lib/amp/repository/mercurial/repo_format/updater.rb +848 -0
- data/lib/amp/repository/mercurial/repo_format/verification.rb +433 -0
- data/lib/amp/repository/mercurial/repositories/bundle_repository.rb +216 -0
- data/lib/amp/repository/mercurial/repositories/http_repository.rb +386 -0
- data/lib/amp/repository/mercurial/repositories/local_repository.rb +2034 -0
- data/lib/amp/repository/mercurial/repository.rb +119 -0
- data/lib/amp/repository/mercurial/revlogs/bundle_revlogs.rb +249 -0
- data/lib/amp/repository/mercurial/revlogs/changegroup.rb +217 -0
- data/lib/amp/repository/mercurial/revlogs/changelog.rb +339 -0
- data/lib/amp/repository/mercurial/revlogs/file_log.rb +152 -0
- data/lib/amp/repository/mercurial/revlogs/index.rb +500 -0
- data/lib/amp/repository/mercurial/revlogs/manifest.rb +201 -0
- data/lib/amp/repository/mercurial/revlogs/node.rb +20 -0
- data/lib/amp/repository/mercurial/revlogs/revlog.rb +1026 -0
- data/lib/amp/repository/mercurial/revlogs/revlog_support.rb +129 -0
- data/lib/amp/repository/mercurial/revlogs/versioned_file.rb +597 -0
- data/lib/amp/repository/repository.rb +11 -88
- data/lib/amp/server/extension/amp_extension.rb +3 -3
- data/lib/amp/server/fancy_http_server.rb +1 -1
- data/lib/amp/server/fancy_views/_browser.haml +1 -1
- data/lib/amp/server/fancy_views/_diff_file.haml +1 -8
- data/lib/amp/server/fancy_views/changeset.haml +2 -2
- data/lib/amp/server/fancy_views/file.haml +1 -1
- data/lib/amp/server/fancy_views/file_diff.haml +1 -1
- data/lib/amp/support/amp_ui.rb +13 -29
- data/lib/amp/support/generator.rb +1 -1
- data/lib/amp/support/loaders.rb +1 -2
- data/lib/amp/support/logger.rb +10 -16
- data/lib/amp/support/match.rb +18 -4
- data/lib/amp/support/mercurial/ignore.rb +151 -0
- data/lib/amp/support/openers.rb +8 -3
- data/lib/amp/support/support.rb +91 -46
- data/lib/amp/templates/{blank.commit.erb → mercurial/blank.commit.erb} +0 -0
- data/lib/amp/templates/{blank.log.erb → mercurial/blank.log.erb} +0 -0
- data/lib/amp/templates/{default.commit.erb → mercurial/default.commit.erb} +0 -0
- data/lib/amp/templates/{default.log.erb → mercurial/default.log.erb} +0 -0
- data/lib/amp/templates/template.rb +18 -18
- data/man/amp.1 +51 -0
- data/site/src/about/commands.haml +1 -1
- data/site/src/css/amp.css +1 -1
- data/site/src/index.haml +3 -3
- data/tasks/man.rake +39 -0
- data/tasks/stats.rake +1 -10
- data/tasks/yard.rake +1 -50
- data/test/dirstate_tests/test_dir_state.rb +10 -8
- data/test/functional_tests/annotate.out +31 -0
- data/test/functional_tests/test_functional.rb +155 -63
- data/test/localrepo_tests/ampfile.rb +12 -0
- data/test/localrepo_tests/test_local_repo.rb +56 -57
- data/test/manifest_tests/test_manifest.rb +3 -5
- data/test/merge_tests/test_merge.rb +3 -3
- data/test/revlog_tests/test_revlog.rb +14 -6
- data/test/store_tests/test_fncache_store.rb +19 -19
- data/test/test_19_compatibility.rb +46 -0
- data/test/test_base85.rb +2 -2
- data/test/test_bdiff.rb +2 -2
- data/test/test_changegroup.rb +59 -0
- data/test/test_commands.rb +2 -2
- data/test/test_difflib.rb +2 -2
- data/test/test_generator.rb +34 -0
- data/test/test_ignore.rb +203 -0
- data/test/test_journal.rb +18 -13
- data/test/test_match.rb +2 -2
- data/test/test_mdiff.rb +3 -3
- data/test/test_mpatch.rb +3 -3
- data/test/test_multi_io.rb +40 -0
- data/test/test_support.rb +18 -2
- data/test/test_templates.rb +38 -0
- data/test/test_ui.rb +79 -0
- data/test/testutilities.rb +56 -0
- metadata +168 -49
- data/ext/amp/bz2/mkmf.log +0 -38
- data/lib/amp/encoding/mercurial_diff.rb +0 -378
- data/lib/amp/encoding/mercurial_patch.rb +0 -1
- data/lib/amp/encoding/patch.rb +0 -292
- data/lib/amp/encoding/pure_ruby/ruby_mercurial_patch.rb +0 -123
- data/lib/amp/merges/merge_state.rb +0 -164
- data/lib/amp/merges/merge_ui.rb +0 -322
- data/lib/amp/merges/simple_merge.rb +0 -450
- data/lib/amp/repository/branch_manager.rb +0 -234
- data/lib/amp/repository/dir_state.rb +0 -950
- data/lib/amp/repository/journal.rb +0 -203
- data/lib/amp/repository/lock.rb +0 -207
- data/lib/amp/repository/repositories/bundle_repository.rb +0 -214
- data/lib/amp/repository/repositories/http_repository.rb +0 -377
- data/lib/amp/repository/repositories/local_repository.rb +0 -2661
- data/lib/amp/repository/store.rb +0 -485
- data/lib/amp/repository/tag_manager.rb +0 -319
- data/lib/amp/repository/updatable.rb +0 -532
- data/lib/amp/repository/verification.rb +0 -431
- data/lib/amp/repository/versioned_file.rb +0 -475
- data/lib/amp/revlogs/bundle_revlogs.rb +0 -246
- data/lib/amp/revlogs/changegroup.rb +0 -217
- data/lib/amp/revlogs/changelog.rb +0 -338
- data/lib/amp/revlogs/changeset.rb +0 -521
- data/lib/amp/revlogs/file_log.rb +0 -165
- data/lib/amp/revlogs/index.rb +0 -493
- data/lib/amp/revlogs/manifest.rb +0 -195
- data/lib/amp/revlogs/node.rb +0 -18
- data/lib/amp/revlogs/revlog.rb +0 -1045
- data/lib/amp/revlogs/revlog_support.rb +0 -126
- data/lib/amp/support/ignore.rb +0 -144
- data/site/Rakefile +0 -38
- data/test/test_amp.rb +0 -9
- data/test/test_helper.rb +0 -15
@@ -5,25 +5,7 @@ command :help do |c|
|
|
5
5
|
c.on_run do |options, args|
|
6
6
|
output = ""
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
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|
|
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", Symbol, :hg])[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
|
8
|
+
cmd_name = args.empty? ? "__default__" : args.first
|
9
|
+
Amp::Help::HelpUI.print_entry(cmd_name, options)
|
28
10
|
end
|
29
11
|
end
|
@@ -1,10 +1,22 @@
|
|
1
1
|
command :init do |c|
|
2
2
|
c.workflow :all
|
3
|
+
|
3
4
|
c.desc "Initializes a new repository in the current directory."
|
5
|
+
c.opt :type, "Which type of repository (git, hg)", :short => '-t', :type => :string, :default => 'hg'
|
6
|
+
|
4
7
|
c.on_run do |options, args|
|
5
8
|
path = args.first ? args.first : '.'
|
6
9
|
|
7
|
-
|
8
|
-
|
10
|
+
case options[:type]
|
11
|
+
when 'hg'
|
12
|
+
Amp::Repositories::Mercurial::LocalRepository.new(path, true, options[:global_config])
|
13
|
+
when 'git'
|
14
|
+
Amp::Repositories::Git::LocalRepository.new(path, true, options[:global_config])
|
15
|
+
else
|
16
|
+
raise "Unknown repostiory type #{options[:type].inspect}"
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
puts "New #{options[:type]} repository initialized."
|
9
21
|
end
|
10
22
|
end
|
@@ -66,20 +66,22 @@ Module.new do
|
|
66
66
|
end
|
67
67
|
Amp::UI.edit_file(filename) if filename
|
68
68
|
when TEMPLATE_ADD_MODE
|
69
|
+
type = Amp::UI.ask("What VCS would you like your template to be associated with?", String)
|
69
70
|
filename = Amp::UI.ask("What would you like to name your template? ", String)
|
70
71
|
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")
|
72
|
+
old_file = Amp::Support::Template[type, "blank-#{type}"].file
|
73
|
+
new_file = File.join(template_directory, type, filename + ".erb")
|
73
74
|
File.copy(old_file, new_file)
|
74
75
|
Amp::UI.edit_file new_file
|
75
|
-
Amp::Support::FileTemplate.new(filename, new_file)
|
76
|
+
Amp::Support::FileTemplate.new(type, filename, new_file)
|
76
77
|
when TEMPLATE_DELETE_MODE
|
77
78
|
filename = nil
|
78
79
|
Amp::UI.choose do |menu|
|
80
|
+
type = Amp::UI.ask("Which VCS's templates are we modifying?", String)
|
79
81
|
menu.prompt = "Which template would you like to delete?"
|
80
82
|
templates_for_scope(scope, repo).each do |template|
|
81
83
|
menu.choice(template.name) do
|
82
|
-
Amp::Support::Template.unregister template.name
|
84
|
+
Amp::Support::Template.unregister type, template.name
|
83
85
|
filename = template.file
|
84
86
|
end
|
85
87
|
end
|
@@ -1,7 +1,21 @@
|
|
1
1
|
command :version do |c|
|
2
|
-
c.desc "Prints the current version of Amp."
|
3
2
|
c.workflow :all
|
3
|
+
|
4
|
+
c.desc "Prints the current version of Amp."
|
5
|
+
c.opt :super, "Print out a hash of the source for amp to verify its integrity"
|
4
6
|
c.on_run do |options, args|
|
5
7
|
puts "Amp version #{Amp::VERSION} (#{Amp::VERSION_TITLE})"
|
8
|
+
|
9
|
+
if options[:super]
|
10
|
+
require 'digest/md5'
|
11
|
+
digest = Digest::MD5.new
|
12
|
+
|
13
|
+
files = Dir["#{Amp::CODE_ROOT}/**/**/**/**/**/**/**/**/**/*.rb"]
|
14
|
+
files.each do |file|
|
15
|
+
open(file) {|f| digest << f.read(8192) } # read in the file in 8K chunks
|
16
|
+
end
|
17
|
+
|
18
|
+
puts "\tIntegrity Digest: #{digest.hexdigest}"
|
19
|
+
end
|
6
20
|
end
|
7
21
|
end
|
@@ -42,19 +42,19 @@ HELP
|
|
42
42
|
exact = {}
|
43
43
|
working_changeset.walk(matcher, true).each do |file, _|
|
44
44
|
if matcher.exact? file
|
45
|
-
if repo.
|
45
|
+
if repo.staging_area.ignoring_file?(file) && !opts[:force]
|
46
46
|
raise abort("Can't add the ignored file #{file}. Use --force to override")
|
47
47
|
end
|
48
48
|
Amp::UI.status "adding #{file.relative_path repo.root}" if opts[:verbose]
|
49
49
|
names << file
|
50
50
|
exact[file] = true
|
51
|
-
elsif !repo.
|
51
|
+
elsif !repo.staging_area.include?(file) && (!repo.staging_area.ignoring_file?(file) || opts[:force])
|
52
52
|
Amp::UI.status "adding #{file.relative_path repo.root}"
|
53
53
|
names << file
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
-
rejected = repo.
|
57
|
+
rejected = repo.staging_area.stage names unless opts[:"dry-run"]
|
58
58
|
|
59
59
|
if names.size == 1
|
60
60
|
Amp::UI.say "File #{names.first.blue} has been added at #{Time.now}"
|
@@ -4,8 +4,10 @@ command :rm do |c|
|
|
4
4
|
c.opt :force, "Forces removal of files", :short => "-f", :default => false
|
5
5
|
c.opt :quiet, "Doesn't print which files are removed", :short => "-q"
|
6
6
|
c.opt :"dry-run", "Doesn't actually remove files - just prints output", :short => "-n"
|
7
|
-
c.opt :cached, "Removes the file only from the
|
7
|
+
c.opt :cached, "Removes the file only from the staging area (doesn't unlink file)"
|
8
8
|
c.opt :recursive, "Recursively remove named directories", :short => "-r"
|
9
|
+
c.opt :"no-unlink", "Don't remove the file - just forget it", :short => '-s'
|
10
|
+
|
9
11
|
c.on_run do |opts, args|
|
10
12
|
repo = opts[:repository]
|
11
13
|
working_changeset = repo[nil]
|
@@ -46,7 +48,7 @@ command :rm do |c|
|
|
46
48
|
(remove + forget).sort.each {|f| Amp::UI.say "removing #{f}" }
|
47
49
|
end
|
48
50
|
|
49
|
-
repo.remove remove, :unlink =>
|
51
|
+
repo.staging_area.remove remove, :unlink => opts[:"no-unlink"] unless opts[:"dry-run"] # forgetting occurs here
|
50
52
|
repo.forget forget unless opts[:"dry-run"]
|
51
53
|
|
52
54
|
remove += forget
|
@@ -61,7 +61,7 @@ EOS
|
|
61
61
|
results[:unknown].each {|file| Amp::UI.say "Adding #{file.relative_path repo.root}" }
|
62
62
|
to_add = results[:unknown]
|
63
63
|
end
|
64
|
-
repo.add(to_add) unless opts[:"dry-run"]
|
64
|
+
repo.staging_area.add(to_add) unless opts[:"dry-run"]
|
65
65
|
|
66
66
|
Amp::UI.say
|
67
67
|
# Prettified, add check later if user disables colors
|
@@ -80,7 +80,7 @@ EOS
|
|
80
80
|
results[:deleted].each {|file| Amp::UI.say "Removing #{file.relative_path repo.root}" }
|
81
81
|
to_del = results[:deleted]
|
82
82
|
end
|
83
|
-
repo.remove to_del unless opts[:"dry-run"]
|
83
|
+
repo.staging_area.remove to_del unless opts[:"dry-run"]
|
84
84
|
|
85
85
|
end
|
86
86
|
end
|
@@ -7,6 +7,7 @@ command :annotate do |c|
|
|
7
7
|
c.opt :changeset, "Show the changeset ID instead of revision number", :short => "-c"
|
8
8
|
c.opt :user, "Shows the user who committed instead of the revision", :short => "-u"
|
9
9
|
c.opt :date, "Shows the date when the line was committed", :short => "-d"
|
10
|
+
c.opt :number, "Show the revision number of the committed line", :short => "-n"
|
10
11
|
c.synonyms :blame, :praise
|
11
12
|
|
12
13
|
c.on_run do |opts, args|
|
@@ -20,11 +21,16 @@ command :annotate do |c|
|
|
20
21
|
max_size = 0
|
21
22
|
full_results = results.map do |file, line_number, line|
|
22
23
|
revpart = ""
|
23
|
-
showrev = !([opts[:changeset], opts[:user], opts[:date]].any?)
|
24
|
+
showrev = opts[:number] || !([opts[:changeset], opts[:user], opts[:date]].any?)
|
24
25
|
|
26
|
+
# What did this line do? There is no Array#count
|
27
|
+
#totalparts = [opts[:user], opts[:date], opts[:changeset], showrev].count {|x| x }
|
25
28
|
revpart += (opts[:verbose] ? file.changeset.user : file.changeset.user.split("@").first[0..15]) if opts[:user]
|
29
|
+
revpart += " " if opts[:user] and opts[:date] || opts[:changeset] || showrev
|
26
30
|
revpart += Time.at(file.changeset.date.first).to_s if opts[:date]
|
27
|
-
revpart += " "
|
31
|
+
revpart += " " if opts[:date] and opts[:changeset] || showrev
|
32
|
+
revpart += file.changeset.node_id.hexlify[0..11] if opts[:changeset]
|
33
|
+
revpart += " " if opts[:changeset] and showrev
|
28
34
|
revpart += file.change_id.to_s if showrev
|
29
35
|
|
30
36
|
if line_number
|
@@ -0,0 +1,253 @@
|
|
1
|
+
command :bisect do |c|
|
2
|
+
c.workflow :hg
|
3
|
+
|
4
|
+
c.desc "subdivision search of changesets"
|
5
|
+
c.help <<-EOS
|
6
|
+
amp bisect [-gbsr] [-c CMD] [REV]
|
7
|
+
|
8
|
+
This command helps to find changesets which introduce problems.
|
9
|
+
To use, mark the earliest changeset you know exhibits the problem
|
10
|
+
as bad, then mark the latest changeset which is free from the
|
11
|
+
problem as good. Bisect will update your working directory to a
|
12
|
+
revision for testing (unless the --noupdate option is specified).
|
13
|
+
Once you have performed tests, mark the working directory as bad
|
14
|
+
or good and bisect will either update to another candidate changeset
|
15
|
+
or announce that it has found the bad revision.
|
16
|
+
|
17
|
+
As a shortcut, you can also use the revision argument to mark a
|
18
|
+
revision as good or bad without checking it out first.
|
19
|
+
|
20
|
+
If you supply a command it will be used for automatic bisection. Its exit
|
21
|
+
status will be used as flag to mark revision as bad or good. In case exit
|
22
|
+
status is 0 the revision is marked as good, 125 - skipped, 127 (command not
|
23
|
+
found) - bisection will be aborted and any other status bigger than 0 will
|
24
|
+
mark revision as bad."
|
25
|
+
|
26
|
+
Where options are:
|
27
|
+
EOS
|
28
|
+
|
29
|
+
c.opt :command, "The command to run to test", :short => '-c', :type => :string, :default => 'ruby'
|
30
|
+
c.opt :"dirty-room", "Eval the ruby code in -f in the context of this amp binary (faster than shelling out)", :short => '-d'
|
31
|
+
c.opt :file, "The file to run with --command (which defaults to ruby) for testing", :short => '-f', :type => :string
|
32
|
+
c.opt :"no-update", "Don't update the working directory during tests", :short => '-U'
|
33
|
+
c.opt :revs, "The revision range to search in", :short => '-r', :type => :string, :default => '0'
|
34
|
+
|
35
|
+
c.before do |opts, args|
|
36
|
+
# Set the command to be the command and the file joined together in
|
37
|
+
# perfect harmony. If file isn't set, command will still work.
|
38
|
+
# If command isn't set, it defaults to 'ruby' up in the command parsing
|
39
|
+
# so actually it's always set unless there's a problem between the keyboard
|
40
|
+
# and chair. I'm sorry this isn't cross platform. Find room in your heart
|
41
|
+
# to forgive me.
|
42
|
+
opts[:command] = "#{opts[:command]} #{opts[:file]} 1>/dev/null 2>/dev/null"
|
43
|
+
|
44
|
+
if opts[:"dirty-room"]
|
45
|
+
raise "The --dirty-room option needs --file as well" unless opts[:file]
|
46
|
+
end
|
47
|
+
|
48
|
+
# If we have to preserve the working directory, then copy
|
49
|
+
# it to a super secret location and do the work there
|
50
|
+
if opts[:"no-update"]
|
51
|
+
require 'fileutils'
|
52
|
+
|
53
|
+
opts[:testing_repo] = "../.amp_bisect_#{Time.now}"
|
54
|
+
FileUtils.cp_r repo.path, opts[:testing_repo]
|
55
|
+
end
|
56
|
+
|
57
|
+
true
|
58
|
+
end
|
59
|
+
|
60
|
+
c.after do |opts, args|
|
61
|
+
if opts[:"no-update"]
|
62
|
+
FileUtils.rm_rf opts[:testing_repo]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
c.on_run do |opts, args|
|
67
|
+
#################################
|
68
|
+
# VARIABLE PREP
|
69
|
+
#################################
|
70
|
+
# Set up some variables and make
|
71
|
+
# $display be set to false.
|
72
|
+
# Also set up what the proc is to
|
73
|
+
# test each revision. Assign a cute
|
74
|
+
# phrase to tell the user what's going
|
75
|
+
# on.
|
76
|
+
#
|
77
|
+
|
78
|
+
repo = opts[:repository]
|
79
|
+
old = $display
|
80
|
+
$display = false # so revert won't be so chatty!
|
81
|
+
|
82
|
+
# This is the sample to run. The proc needs to return true
|
83
|
+
# or false
|
84
|
+
if opts[:command]
|
85
|
+
using = "use `#{opts[:command].red}`"
|
86
|
+
run_sample = proc { system opts[:command] }
|
87
|
+
elsif opts[:"dirty-room"]
|
88
|
+
using = "evaluate #{opts[:file]} in this Ruby interpreter"
|
89
|
+
run_sample = proc { eval File.read(opts[:file]) }
|
90
|
+
else
|
91
|
+
raise "Must have the --command or --dirty-room option set!"
|
92
|
+
end
|
93
|
+
|
94
|
+
last_good, last_bad = *c.parse_revision_range(opts[:revs])
|
95
|
+
last_bad ||= repo.size - 1
|
96
|
+
history = [last_bad] # KILLME
|
97
|
+
|
98
|
+
test_rev = last_bad
|
99
|
+
is_good = {} # {revision :: integer => good? :: boolean}
|
100
|
+
last_good.upto(last_bad) {|i| is_good[i] = nil }
|
101
|
+
|
102
|
+
########################################
|
103
|
+
# COMPLIMENT WHOEVER IS READING THE CODE
|
104
|
+
########################################
|
105
|
+
|
106
|
+
# Hey! That's a really nice shirt. Where'd you get it?
|
107
|
+
Amp::UI.say "Sweet computer, btw. I'm really digging this hardware.\n"
|
108
|
+
|
109
|
+
|
110
|
+
########################################
|
111
|
+
# EXPLICITLY SAY WHAT WE'RE DOING
|
112
|
+
########################################
|
113
|
+
Amp::UI.say <<-EOS
|
114
|
+
OK! Terve! Today we're going to be bisecting your repository find a bug.
|
115
|
+
Let's see... We're set to #{using} to do some bug hunting between revisions
|
116
|
+
#{last_good.to_s.red} and #{last_bad.to_s.red}.
|
117
|
+
|
118
|
+
Enough talk, let's go Orkin-Man on this bug!
|
119
|
+
========
|
120
|
+
EOS
|
121
|
+
|
122
|
+
|
123
|
+
#############################################
|
124
|
+
# BINARY SEARCH
|
125
|
+
#############################################
|
126
|
+
# Here's where we actually do the work. We're
|
127
|
+
# just going through in a standard binary
|
128
|
+
# search method. I haven't actually written
|
129
|
+
# a BS method in a long time so I don't know
|
130
|
+
# if this is official, but it works.
|
131
|
+
#
|
132
|
+
|
133
|
+
until (last_good - last_bad).abs < 1
|
134
|
+
repo.clean test_rev
|
135
|
+
|
136
|
+
# keep the user updated
|
137
|
+
pretty_print is_good
|
138
|
+
|
139
|
+
# if the code sample works
|
140
|
+
if run_sample[]
|
141
|
+
is_good[test_rev] = true # then it's a success and mark it as such
|
142
|
+
break if test_rev == last_good
|
143
|
+
last_good = test_rev
|
144
|
+
else
|
145
|
+
is_good[test_rev] = false
|
146
|
+
last_bad = test_rev
|
147
|
+
end
|
148
|
+
|
149
|
+
test_rev = (last_good + last_bad) / 2
|
150
|
+
history << test_rev
|
151
|
+
end
|
152
|
+
puts # clear the progress bar business
|
153
|
+
|
154
|
+
############################################
|
155
|
+
# CLEANING UP
|
156
|
+
############################################
|
157
|
+
# Restore the working directory to its proper
|
158
|
+
# state and restore the $display variable.
|
159
|
+
# Report on the results of the binary search
|
160
|
+
# and say whether there is a bug, and if there
|
161
|
+
# is a bug, say where it starts.
|
162
|
+
#
|
163
|
+
|
164
|
+
repo.clean(repo.size - 1)
|
165
|
+
$display = old # and put things as they were
|
166
|
+
|
167
|
+
if is_good[last_bad]
|
168
|
+
Amp::UI.say "The selected range of history passes the test. No bug found."
|
169
|
+
else
|
170
|
+
Amp::UI.say "Revision #{last_bad} has the bug!"
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def pretty_print(hash)
|
175
|
+
print("\b" * hash.size * 3)
|
176
|
+
print "\r"
|
177
|
+
print '['
|
178
|
+
hash.keys.sort[0..-2].each do |key|
|
179
|
+
case hash[key]
|
180
|
+
when true
|
181
|
+
print 'o, '
|
182
|
+
when false
|
183
|
+
print 'x, '
|
184
|
+
when nil
|
185
|
+
print '_, '
|
186
|
+
end
|
187
|
+
end
|
188
|
+
case hash[hash.keys.sort.last]
|
189
|
+
when true
|
190
|
+
print 'o'
|
191
|
+
when false
|
192
|
+
print 'x'
|
193
|
+
when nil
|
194
|
+
print '_'
|
195
|
+
end
|
196
|
+
print ']'
|
197
|
+
end
|
198
|
+
|
199
|
+
# c.on_run do |opts, args|
|
200
|
+
# repo = opts[:repository]
|
201
|
+
#
|
202
|
+
# # Hey! That's a really nice shirt. Where'd you get it?
|
203
|
+
# last_good = 0
|
204
|
+
# last_bad = repo.size - 1
|
205
|
+
# test_rev = last_bad
|
206
|
+
# is_good = {} # {revision :: integer => good? :: boolean}
|
207
|
+
# a = [true] * 1#((repo.size / 2) + 3)
|
208
|
+
# a.concat([false] * (repo.size - a.size))
|
209
|
+
# p a
|
210
|
+
#
|
211
|
+
# run_sample = proc do |test_rev|
|
212
|
+
# a[test_rev]
|
213
|
+
# end
|
214
|
+
#
|
215
|
+
# until (last_good - last_bad).abs < 1
|
216
|
+
# #repo.revert [], :to => test_rev
|
217
|
+
# p [last_good, last_bad]
|
218
|
+
#
|
219
|
+
# # if the code sample works
|
220
|
+
# if run_sample[test_rev]
|
221
|
+
# is_good[test_rev] = true # then it's a success and mark it as such
|
222
|
+
# break if test_rev == last_good
|
223
|
+
# last_good = test_rev
|
224
|
+
# else
|
225
|
+
# is_good[test_rev] = false
|
226
|
+
# last_bad = test_rev
|
227
|
+
# end
|
228
|
+
#
|
229
|
+
# test_rev = (last_good + last_bad) / 2
|
230
|
+
# end
|
231
|
+
#
|
232
|
+
# if is_good[last_bad]
|
233
|
+
# Amp::UI.say "The selected range of history passes the test. No bug found."
|
234
|
+
# else
|
235
|
+
# Amp::UI.say "Revision #{last_bad} has the bug!"
|
236
|
+
# end
|
237
|
+
# end
|
238
|
+
end
|
239
|
+
|
240
|
+
# Now for some helpers!
|
241
|
+
module Kernel
|
242
|
+
def bisect_command(name, opts={})
|
243
|
+
command name.to_sym do |c|
|
244
|
+
|
245
|
+
# set the default options as passed in
|
246
|
+
opts.each do |k, v|
|
247
|
+
c.default k, v
|
248
|
+
end
|
249
|
+
|
250
|
+
yield self if block_given?
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|