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.
- data/.gitignore +1 -0
- data/.hgignore +26 -0
- data/AUTHORS +2 -0
- data/History.txt +6 -0
- data/LICENSE +37 -0
- data/MANIFESTO +7 -0
- data/Manifest.txt +294 -0
- data/README.md +129 -0
- data/Rakefile +102 -0
- data/SCHEDULE.markdown +12 -0
- data/STYLE +27 -0
- data/TODO.markdown +149 -0
- data/ampfile.rb +47 -0
- data/bin/amp +30 -0
- data/bin/amp1.9 +30 -0
- data/ext/amp/bz2/README.txt +39 -0
- data/ext/amp/bz2/bz2.c +1582 -0
- data/ext/amp/bz2/extconf.rb +77 -0
- data/ext/amp/bz2/mkmf.log +29 -0
- data/ext/amp/mercurial_patch/extconf.rb +5 -0
- data/ext/amp/mercurial_patch/mpatch.c +405 -0
- data/ext/amp/priority_queue/extconf.rb +5 -0
- data/ext/amp/priority_queue/priority_queue.c +947 -0
- data/ext/amp/support/extconf.rb +5 -0
- data/ext/amp/support/support.c +250 -0
- data/lib/amp.rb +200 -0
- data/lib/amp/commands/command.rb +507 -0
- data/lib/amp/commands/command_support.rb +137 -0
- data/lib/amp/commands/commands/config.rb +143 -0
- data/lib/amp/commands/commands/help.rb +29 -0
- data/lib/amp/commands/commands/init.rb +10 -0
- data/lib/amp/commands/commands/templates.rb +137 -0
- data/lib/amp/commands/commands/version.rb +7 -0
- data/lib/amp/commands/commands/workflow.rb +28 -0
- data/lib/amp/commands/commands/workflows/git/add.rb +65 -0
- data/lib/amp/commands/commands/workflows/git/copy.rb +27 -0
- data/lib/amp/commands/commands/workflows/git/mv.rb +23 -0
- data/lib/amp/commands/commands/workflows/git/rm.rb +60 -0
- data/lib/amp/commands/commands/workflows/hg/add.rb +53 -0
- data/lib/amp/commands/commands/workflows/hg/addremove.rb +86 -0
- data/lib/amp/commands/commands/workflows/hg/annotate.rb +46 -0
- data/lib/amp/commands/commands/workflows/hg/archive.rb +126 -0
- data/lib/amp/commands/commands/workflows/hg/branch.rb +28 -0
- data/lib/amp/commands/commands/workflows/hg/branches.rb +30 -0
- data/lib/amp/commands/commands/workflows/hg/bundle.rb +115 -0
- data/lib/amp/commands/commands/workflows/hg/clone.rb +95 -0
- data/lib/amp/commands/commands/workflows/hg/commit.rb +42 -0
- data/lib/amp/commands/commands/workflows/hg/copy.rb +31 -0
- data/lib/amp/commands/commands/workflows/hg/debug/dirstate.rb +32 -0
- data/lib/amp/commands/commands/workflows/hg/debug/index.rb +36 -0
- data/lib/amp/commands/commands/workflows/hg/default.rb +9 -0
- data/lib/amp/commands/commands/workflows/hg/diff.rb +30 -0
- data/lib/amp/commands/commands/workflows/hg/forget.rb +11 -0
- data/lib/amp/commands/commands/workflows/hg/heads.rb +25 -0
- data/lib/amp/commands/commands/workflows/hg/identify.rb +23 -0
- data/lib/amp/commands/commands/workflows/hg/import.rb +135 -0
- data/lib/amp/commands/commands/workflows/hg/incoming.rb +85 -0
- data/lib/amp/commands/commands/workflows/hg/info.rb +18 -0
- data/lib/amp/commands/commands/workflows/hg/log.rb +21 -0
- data/lib/amp/commands/commands/workflows/hg/manifest.rb +13 -0
- data/lib/amp/commands/commands/workflows/hg/merge.rb +53 -0
- data/lib/amp/commands/commands/workflows/hg/move.rb +28 -0
- data/lib/amp/commands/commands/workflows/hg/outgoing.rb +61 -0
- data/lib/amp/commands/commands/workflows/hg/pull.rb +74 -0
- data/lib/amp/commands/commands/workflows/hg/push.rb +20 -0
- data/lib/amp/commands/commands/workflows/hg/remove.rb +45 -0
- data/lib/amp/commands/commands/workflows/hg/resolve.rb +83 -0
- data/lib/amp/commands/commands/workflows/hg/revert.rb +53 -0
- data/lib/amp/commands/commands/workflows/hg/root.rb +13 -0
- data/lib/amp/commands/commands/workflows/hg/serve.rb +38 -0
- data/lib/amp/commands/commands/workflows/hg/status.rb +116 -0
- data/lib/amp/commands/commands/workflows/hg/tag.rb +69 -0
- data/lib/amp/commands/commands/workflows/hg/tags.rb +27 -0
- data/lib/amp/commands/commands/workflows/hg/tip.rb +13 -0
- data/lib/amp/commands/commands/workflows/hg/update.rb +27 -0
- data/lib/amp/commands/commands/workflows/hg/verify.rb +9 -0
- data/lib/amp/commands/commands/workflows/hg/view.rb +36 -0
- data/lib/amp/commands/dispatch.rb +181 -0
- data/lib/amp/commands/hooks.rb +81 -0
- data/lib/amp/dependencies/amp_support.rb +1 -0
- data/lib/amp/dependencies/amp_support/ruby_amp_support.rb +103 -0
- data/lib/amp/dependencies/minitar.rb +979 -0
- data/lib/amp/dependencies/priority_queue.rb +18 -0
- data/lib/amp/dependencies/priority_queue/c_priority_queue.rb +1 -0
- data/lib/amp/dependencies/priority_queue/poor_priority_queue.rb +46 -0
- data/lib/amp/dependencies/priority_queue/ruby_priority_queue.rb +525 -0
- data/lib/amp/dependencies/python_config.rb +211 -0
- data/lib/amp/dependencies/trollop.rb +713 -0
- data/lib/amp/dependencies/zip/ioextras.rb +155 -0
- data/lib/amp/dependencies/zip/stdrubyext.rb +111 -0
- data/lib/amp/dependencies/zip/tempfile_bugfixed.rb +186 -0
- data/lib/amp/dependencies/zip/zip.rb +1850 -0
- data/lib/amp/dependencies/zip/zipfilesystem.rb +609 -0
- data/lib/amp/dependencies/zip/ziprequire.rb +90 -0
- data/lib/amp/encoding/base85.rb +97 -0
- data/lib/amp/encoding/binary_diff.rb +82 -0
- data/lib/amp/encoding/difflib.rb +166 -0
- data/lib/amp/encoding/mercurial_diff.rb +378 -0
- data/lib/amp/encoding/mercurial_patch.rb +1 -0
- data/lib/amp/encoding/patch.rb +292 -0
- data/lib/amp/encoding/pure_ruby/ruby_mercurial_patch.rb +123 -0
- data/lib/amp/extensions/ditz.rb +41 -0
- data/lib/amp/extensions/lighthouse.rb +167 -0
- data/lib/amp/graphs/ancestor.rb +147 -0
- data/lib/amp/graphs/copies.rb +261 -0
- data/lib/amp/merges/merge_state.rb +164 -0
- data/lib/amp/merges/merge_ui.rb +322 -0
- data/lib/amp/merges/simple_merge.rb +450 -0
- data/lib/amp/profiling_hacks.rb +36 -0
- data/lib/amp/repository/branch_manager.rb +234 -0
- data/lib/amp/repository/dir_state.rb +950 -0
- data/lib/amp/repository/journal.rb +203 -0
- data/lib/amp/repository/lock.rb +207 -0
- data/lib/amp/repository/repositories/bundle_repository.rb +214 -0
- data/lib/amp/repository/repositories/http_repository.rb +377 -0
- data/lib/amp/repository/repositories/local_repository.rb +2661 -0
- data/lib/amp/repository/repository.rb +94 -0
- data/lib/amp/repository/store.rb +485 -0
- data/lib/amp/repository/tag_manager.rb +319 -0
- data/lib/amp/repository/updatable.rb +532 -0
- data/lib/amp/repository/verification.rb +431 -0
- data/lib/amp/repository/versioned_file.rb +475 -0
- data/lib/amp/revlogs/bundle_revlogs.rb +246 -0
- data/lib/amp/revlogs/changegroup.rb +217 -0
- data/lib/amp/revlogs/changelog.rb +338 -0
- data/lib/amp/revlogs/changeset.rb +521 -0
- data/lib/amp/revlogs/file_log.rb +165 -0
- data/lib/amp/revlogs/index.rb +493 -0
- data/lib/amp/revlogs/manifest.rb +195 -0
- data/lib/amp/revlogs/node.rb +18 -0
- data/lib/amp/revlogs/revlog.rb +1032 -0
- data/lib/amp/revlogs/revlog_support.rb +126 -0
- data/lib/amp/server/amp_user.rb +44 -0
- data/lib/amp/server/extension/amp_extension.rb +396 -0
- data/lib/amp/server/extension/authorization.rb +201 -0
- data/lib/amp/server/fancy_http_server.rb +252 -0
- data/lib/amp/server/fancy_views/_browser.haml +28 -0
- data/lib/amp/server/fancy_views/_diff_file.haml +13 -0
- data/lib/amp/server/fancy_views/_navbar.haml +17 -0
- data/lib/amp/server/fancy_views/changeset.haml +31 -0
- data/lib/amp/server/fancy_views/commits.haml +32 -0
- data/lib/amp/server/fancy_views/file.haml +35 -0
- data/lib/amp/server/fancy_views/file_diff.haml +23 -0
- data/lib/amp/server/fancy_views/harshcss/all_hallows_eve.css +72 -0
- data/lib/amp/server/fancy_views/harshcss/amy.css +147 -0
- data/lib/amp/server/fancy_views/harshcss/twilight.css +138 -0
- data/lib/amp/server/fancy_views/stylesheet.sass +175 -0
- data/lib/amp/server/http_server.rb +140 -0
- data/lib/amp/server/repo_user_management.rb +287 -0
- data/lib/amp/support/amp_config.rb +164 -0
- data/lib/amp/support/amp_ui.rb +287 -0
- data/lib/amp/support/docs.rb +54 -0
- data/lib/amp/support/generator.rb +78 -0
- data/lib/amp/support/ignore.rb +144 -0
- data/lib/amp/support/loaders.rb +93 -0
- data/lib/amp/support/logger.rb +103 -0
- data/lib/amp/support/match.rb +151 -0
- data/lib/amp/support/multi_io.rb +87 -0
- data/lib/amp/support/openers.rb +121 -0
- data/lib/amp/support/ruby_19_compatibility.rb +66 -0
- data/lib/amp/support/support.rb +1095 -0
- data/lib/amp/templates/blank.commit.erb +23 -0
- data/lib/amp/templates/blank.log.erb +18 -0
- data/lib/amp/templates/default.commit.erb +23 -0
- data/lib/amp/templates/default.log.erb +26 -0
- data/lib/amp/templates/template.rb +165 -0
- data/site/Rakefile +24 -0
- data/site/src/about/ampfile.haml +57 -0
- data/site/src/about/commands.haml +106 -0
- data/site/src/about/index.haml +33 -0
- data/site/src/about/performance.haml +31 -0
- data/site/src/about/workflows.haml +34 -0
- data/site/src/contribute/index.haml +65 -0
- data/site/src/contribute/style.haml +297 -0
- data/site/src/css/active4d.css +114 -0
- data/site/src/css/all_hallows_eve.css +72 -0
- data/site/src/css/all_themes.css +3299 -0
- data/site/src/css/amp.css +260 -0
- data/site/src/css/amy.css +147 -0
- data/site/src/css/blackboard.css +88 -0
- data/site/src/css/brilliance_black.css +605 -0
- data/site/src/css/brilliance_dull.css +599 -0
- data/site/src/css/cobalt.css +149 -0
- data/site/src/css/cur_amp.css +185 -0
- data/site/src/css/dawn.css +121 -0
- data/site/src/css/eiffel.css +121 -0
- data/site/src/css/espresso_libre.css +109 -0
- data/site/src/css/idle.css +62 -0
- data/site/src/css/iplastic.css +80 -0
- data/site/src/css/lazy.css +73 -0
- data/site/src/css/mac_classic.css +123 -0
- data/site/src/css/magicwb_amiga.css +104 -0
- data/site/src/css/pastels_on_dark.css +188 -0
- data/site/src/css/reset.css +55 -0
- data/site/src/css/slush_poppies.css +85 -0
- data/site/src/css/spacecadet.css +51 -0
- data/site/src/css/sunburst.css +180 -0
- data/site/src/css/twilight.css +137 -0
- data/site/src/css/zenburnesque.css +91 -0
- data/site/src/get/index.haml +32 -0
- data/site/src/helpers.rb +121 -0
- data/site/src/images/amp_logo.png +0 -0
- data/site/src/images/carbonica.png +0 -0
- data/site/src/images/revolution.png +0 -0
- data/site/src/images/tab-bg.png +0 -0
- data/site/src/images/tab-sliding-left.png +0 -0
- data/site/src/images/tab-sliding-right.png +0 -0
- data/site/src/include/_footer.haml +22 -0
- data/site/src/include/_header.haml +17 -0
- data/site/src/index.haml +104 -0
- data/site/src/learn/index.haml +46 -0
- data/site/src/scripts/jquery-1.3.2.min.js +19 -0
- data/site/src/scripts/jquery.cookie.js +96 -0
- data/tasks/stats.rake +155 -0
- data/tasks/yard.rake +171 -0
- data/test/dirstate_tests/dirstate +0 -0
- data/test/dirstate_tests/hgrc +5 -0
- data/test/dirstate_tests/test_dir_state.rb +192 -0
- data/test/functional_tests/resources/.hgignore +2 -0
- data/test/functional_tests/resources/STYLE.txt +25 -0
- data/test/functional_tests/resources/command.rb +372 -0
- data/test/functional_tests/resources/commands/annotate.rb +57 -0
- data/test/functional_tests/resources/commands/experimental/lolcats.rb +17 -0
- data/test/functional_tests/resources/commands/heads.rb +22 -0
- data/test/functional_tests/resources/commands/manifest.rb +12 -0
- data/test/functional_tests/resources/commands/status.rb +90 -0
- data/test/functional_tests/resources/version2/.hgignore +5 -0
- data/test/functional_tests/resources/version2/STYLE.txt +25 -0
- data/test/functional_tests/resources/version2/command.rb +372 -0
- data/test/functional_tests/resources/version2/commands/annotate.rb +45 -0
- data/test/functional_tests/resources/version2/commands/experimental/lolcats.rb +17 -0
- data/test/functional_tests/resources/version2/commands/heads.rb +22 -0
- data/test/functional_tests/resources/version2/commands/manifest.rb +12 -0
- data/test/functional_tests/resources/version2/commands/status.rb +90 -0
- data/test/functional_tests/resources/version3/.hgignore +5 -0
- data/test/functional_tests/resources/version3/STYLE.txt +31 -0
- data/test/functional_tests/resources/version3/command.rb +376 -0
- data/test/functional_tests/resources/version3/commands/annotate.rb +45 -0
- data/test/functional_tests/resources/version3/commands/experimental/lolcats.rb +17 -0
- data/test/functional_tests/resources/version3/commands/heads.rb +22 -0
- data/test/functional_tests/resources/version3/commands/manifest.rb +12 -0
- data/test/functional_tests/resources/version3/commands/status.rb +90 -0
- data/test/functional_tests/resources/version4/.hgignore +5 -0
- data/test/functional_tests/resources/version4/STYLE.txt +31 -0
- data/test/functional_tests/resources/version4/command.rb +376 -0
- data/test/functional_tests/resources/version4/commands/experimental/lolcats.rb +17 -0
- data/test/functional_tests/resources/version4/commands/heads.rb +22 -0
- data/test/functional_tests/resources/version4/commands/manifest.rb +12 -0
- data/test/functional_tests/resources/version4/commands/stats.rb +25 -0
- data/test/functional_tests/resources/version4/commands/status.rb +90 -0
- data/test/functional_tests/resources/version5_1/.hgignore +5 -0
- data/test/functional_tests/resources/version5_1/STYLE.txt +2 -0
- data/test/functional_tests/resources/version5_1/command.rb +374 -0
- data/test/functional_tests/resources/version5_1/commands/experimental/lolcats.rb +17 -0
- data/test/functional_tests/resources/version5_1/commands/heads.rb +22 -0
- data/test/functional_tests/resources/version5_1/commands/manifest.rb +12 -0
- data/test/functional_tests/resources/version5_1/commands/stats.rb +25 -0
- data/test/functional_tests/resources/version5_1/commands/status.rb +90 -0
- data/test/functional_tests/resources/version5_2/.hgignore +5 -0
- data/test/functional_tests/resources/version5_2/STYLE.txt +14 -0
- data/test/functional_tests/resources/version5_2/command.rb +376 -0
- data/test/functional_tests/resources/version5_2/commands/experimental/lolcats.rb +17 -0
- data/test/functional_tests/resources/version5_2/commands/manifest.rb +12 -0
- data/test/functional_tests/resources/version5_2/commands/newz.rb +12 -0
- data/test/functional_tests/resources/version5_2/commands/stats.rb +25 -0
- data/test/functional_tests/resources/version5_2/commands/status.rb +90 -0
- data/test/functional_tests/test_functional.rb +604 -0
- data/test/localrepo_tests/test_local_repo.rb +121 -0
- data/test/localrepo_tests/testrepo.tar.gz +0 -0
- data/test/manifest_tests/00manifest.i +0 -0
- data/test/manifest_tests/test_manifest.rb +72 -0
- data/test/merge_tests/base.txt +10 -0
- data/test/merge_tests/expected.local.txt +16 -0
- data/test/merge_tests/local.txt +11 -0
- data/test/merge_tests/remote.txt +11 -0
- data/test/merge_tests/test_merge.rb +26 -0
- data/test/revlog_tests/00changelog.i +0 -0
- data/test/revlog_tests/revision_added_changelog.i +0 -0
- data/test/revlog_tests/test_adding_index.i +0 -0
- data/test/revlog_tests/test_revlog.rb +333 -0
- data/test/revlog_tests/testindex.i +0 -0
- data/test/store_tests/store.tar.gz +0 -0
- data/test/store_tests/test_fncache_store.rb +122 -0
- data/test/test_amp.rb +9 -0
- data/test/test_base85.rb +14 -0
- data/test/test_bdiff.rb +42 -0
- data/test/test_commands.rb +122 -0
- data/test/test_difflib.rb +50 -0
- data/test/test_helper.rb +15 -0
- data/test/test_journal.rb +29 -0
- data/test/test_match.rb +134 -0
- data/test/test_mdiff.rb +74 -0
- data/test/test_mpatch.rb +14 -0
- data/test/test_support.rb +24 -0
- metadata +385 -0
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
require 'amp/commands/command_support.rb'
|
|
2
|
+
|
|
3
|
+
module Amp
|
|
4
|
+
|
|
5
|
+
##
|
|
6
|
+
# Represents a command within the Amp system. Simply instantiating a new
|
|
7
|
+
# command will make it available to the Amp executable. You configure the
|
|
8
|
+
# command by filling out a block in the command's initializer.
|
|
9
|
+
# @example
|
|
10
|
+
# Command.new "add" do |c|
|
|
11
|
+
# c.workflow :hg
|
|
12
|
+
# c.opt :include, "Paths to include",
|
|
13
|
+
# :options => {:short => "-I", :multi => true}
|
|
14
|
+
# c.opt :print_names, :desc => "Print the filenames",
|
|
15
|
+
# :options => {:short => "-p" ,
|
|
16
|
+
# :default => false,
|
|
17
|
+
# :type => :boolean}
|
|
18
|
+
# c.on_run do |options, arguments|
|
|
19
|
+
# if options[:print_names]
|
|
20
|
+
# arguments.each do |filename|
|
|
21
|
+
# puts filename
|
|
22
|
+
# end
|
|
23
|
+
# end
|
|
24
|
+
# end
|
|
25
|
+
# c.help "This is the help text when the user runs `amp help add`"
|
|
26
|
+
# end
|
|
27
|
+
#
|
|
28
|
+
class Command
|
|
29
|
+
include CommandSupport
|
|
30
|
+
|
|
31
|
+
# The current namespace to append to any new commands
|
|
32
|
+
# Not thread-safe at all
|
|
33
|
+
@current_namespaces = []
|
|
34
|
+
|
|
35
|
+
# All the commands registered in the system
|
|
36
|
+
@all_commands = {}
|
|
37
|
+
|
|
38
|
+
# Synonyms for commands. Used as a backup.
|
|
39
|
+
@all_synonyms = {}
|
|
40
|
+
|
|
41
|
+
# Workflows for splitting up commands into groups.
|
|
42
|
+
# The hash will automatically fill slots with empty hashes
|
|
43
|
+
# upon reads if they are empty.
|
|
44
|
+
#
|
|
45
|
+
# Workflows are doubly linked, in that the cvar +self.class.workflows+ keeps track of
|
|
46
|
+
# what commands belong to it, and the commands themselves keep track of which
|
|
47
|
+
# workflows they belong to.
|
|
48
|
+
@workflows = Hash.new {|h, k| h[k] = {} }
|
|
49
|
+
|
|
50
|
+
# These are options that all commands support. Allows the user to put
|
|
51
|
+
# them after the subcommand.
|
|
52
|
+
GLOBAL_OPTIONS = []
|
|
53
|
+
# {:name => :verbose, :desc => "Verbose output", :options => {:short => "-v"}}
|
|
54
|
+
|
|
55
|
+
class << self
|
|
56
|
+
|
|
57
|
+
attr_reader :current_namespaces
|
|
58
|
+
|
|
59
|
+
##
|
|
60
|
+
# Returns all of the commands registered in the system.
|
|
61
|
+
#
|
|
62
|
+
# @return [Hash<Symbol => Amp::Command>] the commands, keyed by command name as a string
|
|
63
|
+
attr_reader :all_commands
|
|
64
|
+
|
|
65
|
+
##
|
|
66
|
+
# Returns all the synonyms registered in the system.
|
|
67
|
+
#
|
|
68
|
+
# @return [Hash<Symbol => Amp::Command>] the synonyms, keyed by the synonym as a string
|
|
69
|
+
attr_reader :all_synonyms
|
|
70
|
+
attr_reader :workflows
|
|
71
|
+
|
|
72
|
+
##
|
|
73
|
+
# Appends the given namespace to the active namespace for new commands.
|
|
74
|
+
#
|
|
75
|
+
# @param [String, #to_s] namespace the new namespace to add
|
|
76
|
+
def use_namespace(namespace)
|
|
77
|
+
current_namespaces.push namespace
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
##
|
|
81
|
+
# Removes one namespace from the active namespaces for new commands
|
|
82
|
+
def pop_namespace
|
|
83
|
+
current_namespaces.pop
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
##
|
|
87
|
+
# Returns all commands and synonyms registered in the system.
|
|
88
|
+
# The commands are merged into the synonyms so that any synonym with
|
|
89
|
+
# the same name as a command will be overwritten in the hash.
|
|
90
|
+
#
|
|
91
|
+
# @return [Hash<Symbol => Amp::Command>] the commands and synonyms,
|
|
92
|
+
# keyed by command name as a string
|
|
93
|
+
def all
|
|
94
|
+
all_synonyms.merge all_commands
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
##
|
|
98
|
+
# Returns all commands and synonyms registered in the system for a
|
|
99
|
+
# given workflow. The ":all" workflow is automatically merged in, as well.
|
|
100
|
+
#
|
|
101
|
+
# @param [Symbol] workflow the workflow whose commands we need
|
|
102
|
+
# @return [Hash<Symbol => Amp::Command>] the commands and synonyms for the
|
|
103
|
+
# workflow (and all global commands), keyed by command name as a string
|
|
104
|
+
def all_for_workflow(flow, synonyms=true)
|
|
105
|
+
flow = flow.to_sym
|
|
106
|
+
|
|
107
|
+
cmds = workflows[flow].merge workflows[:all]
|
|
108
|
+
|
|
109
|
+
if synonyms
|
|
110
|
+
# because there is no way to view all synonyms with workflow +flow+,
|
|
111
|
+
# we have to work bottom up (hence the doubly linked aspect for commands,
|
|
112
|
+
# which is reduced to singly linked)
|
|
113
|
+
syns = all_synonyms.select {|k, v| v.workflows.include? flow }
|
|
114
|
+
syns = syns.to_hash
|
|
115
|
+
else
|
|
116
|
+
syns = {}
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
syns.merge cmds
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
##
|
|
123
|
+
# Gets a specific command, for a given workflow. This is necessary because it
|
|
124
|
+
# will be expected that 2 different workflows have a command with the same name
|
|
125
|
+
# (such as "move").
|
|
126
|
+
#
|
|
127
|
+
# @param [String, Symbol] cmd the command to look up
|
|
128
|
+
# @param [Symbol] the workflow to use for the lookup
|
|
129
|
+
# @return [Amp::Command] the command for the given name and workflow
|
|
130
|
+
def command_for_workflow(cmd, flow)
|
|
131
|
+
all_for_workflow(flow)[cmd.to_sym]
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
##
|
|
135
|
+
# Returns all of the commands registered in the system.
|
|
136
|
+
#
|
|
137
|
+
# @return [Hash<Symbol => Amp::Command>, NilClass] the commands, keyed by
|
|
138
|
+
# command name as a symbol. returns nil if nothing is found
|
|
139
|
+
def [](arg)
|
|
140
|
+
all[arg.to_sym]
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# Command-specific command-line options
|
|
145
|
+
attr_accessor :options
|
|
146
|
+
# The name of the command (eg 'add', 'init')
|
|
147
|
+
attr_accessor :name
|
|
148
|
+
# Short, 1-line description of the command
|
|
149
|
+
attr_accessor :description
|
|
150
|
+
# The Trollop parser
|
|
151
|
+
attr_accessor :parser
|
|
152
|
+
|
|
153
|
+
##
|
|
154
|
+
# Creates a command in the Amp system. Simply instantiating a new
|
|
155
|
+
# command will make it available to the Amp executable. You configure the
|
|
156
|
+
# command by filling out a block in the command's initializer.
|
|
157
|
+
#
|
|
158
|
+
# @example
|
|
159
|
+
# Command.new("add") do |c|
|
|
160
|
+
# c.opt :include, "Paths to include",
|
|
161
|
+
# :options => {:short => "-I", :multi => true}
|
|
162
|
+
# c.opt :print_names, :desc => "Print the filenames",
|
|
163
|
+
# :options => {:short => "-p", :default => false,
|
|
164
|
+
# :type => :boolean}
|
|
165
|
+
# c.on_run do |options, arguments|
|
|
166
|
+
# puts "silly!"
|
|
167
|
+
# end
|
|
168
|
+
# end
|
|
169
|
+
# @param name the name of the command that the user will use to call
|
|
170
|
+
# the command
|
|
171
|
+
# @param &block a block of code where you can configure the command
|
|
172
|
+
# @yield This block configures the command. Set up options, add an on_run
|
|
173
|
+
# handler, and so on.
|
|
174
|
+
# @yieldparam The command itself - it is yielded so you can modify it.
|
|
175
|
+
def initialize(name, require_new = false)
|
|
176
|
+
# so that you can do additions to commands, just like ammending rake tasks
|
|
177
|
+
full_name = (self.class.current_namespaces + [name]).join(":")
|
|
178
|
+
name = full_name.to_sym
|
|
179
|
+
if self.class.all_commands[name]
|
|
180
|
+
yield self.class.all_commands[name] if block_given?
|
|
181
|
+
return self.class.all_commands[name]
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
@name = name
|
|
185
|
+
@help = ""
|
|
186
|
+
@options = []
|
|
187
|
+
self.class.all_commands[name] = self
|
|
188
|
+
@before = []
|
|
189
|
+
@after = []
|
|
190
|
+
|
|
191
|
+
@workflows = []
|
|
192
|
+
@synonyms = []
|
|
193
|
+
yield(self) if block_given?
|
|
194
|
+
workflow :all if @workflows.empty?
|
|
195
|
+
@options += GLOBAL_OPTIONS
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
##
|
|
199
|
+
# Adds an command-line option to the command.
|
|
200
|
+
#
|
|
201
|
+
# @param name the name of the command the user will type to run it
|
|
202
|
+
# @param desc the short, one-line description of the command
|
|
203
|
+
# @param options the options that configure the command-line option
|
|
204
|
+
# (too meta? sorry!)
|
|
205
|
+
# @option [String] options :short (nil) the short version of the option
|
|
206
|
+
# (e.g. "-I")
|
|
207
|
+
# @option [String] options :default (nil) the default value of the option.
|
|
208
|
+
# @option [Symbol] options :type (:string) the type of the option. Allows
|
|
209
|
+
# you to force Integer or URL matches.
|
|
210
|
+
# @option [Boolean] options :multi (false) can this option take multiple
|
|
211
|
+
# values?
|
|
212
|
+
def opt(name, desc='', options={})
|
|
213
|
+
@options << {:name => name, :desc => desc, :options => options}
|
|
214
|
+
end
|
|
215
|
+
alias_method :add_opt, :opt
|
|
216
|
+
|
|
217
|
+
##
|
|
218
|
+
# Override a default value for a command option. Useful for user-provided
|
|
219
|
+
# ampfiles.
|
|
220
|
+
#
|
|
221
|
+
# @example This example will make `amp status` default to mercurial-style
|
|
222
|
+
# output, instead of amp's colorful, easy-to-read output.
|
|
223
|
+
# command :status do |c|
|
|
224
|
+
# default :hg, true
|
|
225
|
+
# default :"no-color", true
|
|
226
|
+
# end
|
|
227
|
+
# @param [Symbol, #to_sym] opt the option to modify. Can be symbol or string.
|
|
228
|
+
# @param value the new default value for the option
|
|
229
|
+
def default(opt, value)
|
|
230
|
+
opt = opt.to_sym
|
|
231
|
+
the_opt = @options.select {|o| o[:name] == opt}.first
|
|
232
|
+
if the_opt
|
|
233
|
+
the_opt[:options][:default] = value
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
##
|
|
238
|
+
# This method is how you set what the command does when it is run.
|
|
239
|
+
#
|
|
240
|
+
# @param &block the code to run when the command runs
|
|
241
|
+
# @yield The code to run when the command is executed, after options
|
|
242
|
+
# are prepared.
|
|
243
|
+
# @yieldparam options The options that the dispatcher has prepared for
|
|
244
|
+
# the command. Includes global and local.
|
|
245
|
+
# @yieldparam arguments All arguments passed to the command, after
|
|
246
|
+
# the options.
|
|
247
|
+
# @example
|
|
248
|
+
# Command.new("email_news") do |c|
|
|
249
|
+
# c.on_run do |options, arguments|
|
|
250
|
+
# arguments.each do |email_address|
|
|
251
|
+
# send_some_email(options[:email_subject],email_address)
|
|
252
|
+
# end
|
|
253
|
+
# end
|
|
254
|
+
# end
|
|
255
|
+
def on_run(&block)
|
|
256
|
+
@code = proc(&block) # this way we have the ability to do `return`
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
##
|
|
260
|
+
# This method lets you set a synonym (or synonyms) for this command.
|
|
261
|
+
# For example, the "remove" command has the synonym "rm". Example:
|
|
262
|
+
# command :remove do |c|
|
|
263
|
+
# c.synonym :rm, :destroy, :nuke
|
|
264
|
+
# end
|
|
265
|
+
# then you can do
|
|
266
|
+
# amp nuke badfile.rb
|
|
267
|
+
def synonym(*args)
|
|
268
|
+
args.each do |arg|
|
|
269
|
+
@synonyms << arg
|
|
270
|
+
self.class.all_synonyms[arg.to_sym] = self
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
alias_method :synonyms, :synonym
|
|
274
|
+
|
|
275
|
+
##
|
|
276
|
+
# Specifies a workflow that may access this command. Workflows are
|
|
277
|
+
# groups of commands, pure and simple. If the user has no specified
|
|
278
|
+
# workflow, the mercurial workflow is used by default.
|
|
279
|
+
def workflow(*args)
|
|
280
|
+
if args.any? # unless args.empty?
|
|
281
|
+
args.each do |arg|
|
|
282
|
+
self.class.workflows[arg][self.name.to_sym] = self # register globally
|
|
283
|
+
@workflows << arg # register locally
|
|
284
|
+
end
|
|
285
|
+
else
|
|
286
|
+
@workflows
|
|
287
|
+
end
|
|
288
|
+
end
|
|
289
|
+
alias_method :workflows, :workflow
|
|
290
|
+
|
|
291
|
+
##
|
|
292
|
+
# This returns the list of actions to run before the command, in order (first
|
|
293
|
+
# ones are run first). You can modify this array in any way you choose, and
|
|
294
|
+
# it is run _before_ the command is run.
|
|
295
|
+
#
|
|
296
|
+
# @yield Extra code to run before the command is executed, after options
|
|
297
|
+
# are prepared.
|
|
298
|
+
# @yieldparam options The options that the dispatcher has prepared
|
|
299
|
+
# for the command. Includes global and local.
|
|
300
|
+
# @yieldparam arguments All arguments passed to the command, after the options.
|
|
301
|
+
# @return [Hash] an array of strings and blocks. Strings are assumed to
|
|
302
|
+
# be command names and blocks are pieces of code to be run.
|
|
303
|
+
def before(*args, &block)
|
|
304
|
+
args.each do |arg|
|
|
305
|
+
@before << proc {|opts, args| Amp::Command[arg.to_sym].run(opts, args) }
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
@before << block if block
|
|
309
|
+
@before
|
|
310
|
+
end
|
|
311
|
+
##
|
|
312
|
+
# This returns the list of actions to run after the command, in order (first
|
|
313
|
+
# ones are run first). You can modify this array in any way you choose, and
|
|
314
|
+
# it is run _after_ the command is run.
|
|
315
|
+
#
|
|
316
|
+
# @yield Extra code to run after the command is executed, after options are prepared.
|
|
317
|
+
# @yieldparam options The options that the dispatcher has prepared for the command.
|
|
318
|
+
# Includes global and local.
|
|
319
|
+
# @yieldparam arguments All arguments passed to the command, after the options.
|
|
320
|
+
# @return [Hash] an array of strings and blocks. Strings are assumed to be command
|
|
321
|
+
# names and blocks are pieces of code to be run.
|
|
322
|
+
def after(*args, &block)
|
|
323
|
+
args.each do |arg|
|
|
324
|
+
@after << proc {|opts, args| Amp::Command[arg.to_sym].run(opts, args) }
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
@after << block if block
|
|
328
|
+
@after
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
##
|
|
332
|
+
# The one-line description of the command. This is the first line
|
|
333
|
+
# of the help text. If no argument is passed, then the desription
|
|
334
|
+
# is returned. If an argument is passed, it will be set to be the
|
|
335
|
+
# first line of the help text.
|
|
336
|
+
#
|
|
337
|
+
# @example cmd.desc # => "This command is useless."
|
|
338
|
+
# @param [String, nil] str the help text to set
|
|
339
|
+
def desc(str=nil)
|
|
340
|
+
str ? @help = "#{str}\n\n#{@help}" : @help.split("\n").first
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
##
|
|
344
|
+
# Trollop's help info for the command
|
|
345
|
+
def educate
|
|
346
|
+
@parser ? @parser.educate : ''
|
|
347
|
+
end
|
|
348
|
+
alias_method :education, :educate
|
|
349
|
+
|
|
350
|
+
##
|
|
351
|
+
# Sets the command to not laod a repository when run. Useful for purely
|
|
352
|
+
# informational commands (such as version) or initializing a new
|
|
353
|
+
# repository.
|
|
354
|
+
def no_repo
|
|
355
|
+
NO_REPO_ALLOWED[@name] = true
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
# @see no_repo
|
|
359
|
+
def no_repo=(value)
|
|
360
|
+
NO_REPO_ALLOWED[@name] = value
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
##
|
|
364
|
+
# Sets the command to not require a repository to run, but try to load one.
|
|
365
|
+
# Used, for example, for the templates command, which sometimes stores
|
|
366
|
+
# information in the local repository.
|
|
367
|
+
def maybe_repo
|
|
368
|
+
MAYBE_REPO_ALLOWED[@name] = true
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
# @see no_repo
|
|
372
|
+
def maybe_repo=(value)
|
|
373
|
+
MAYBE_REPO_ALLOWED[@name] = value
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
##
|
|
377
|
+
# Sets the help text for the command. This can be a very long string,
|
|
378
|
+
# as it is what the user sees when they type `amp help +name+`
|
|
379
|
+
#
|
|
380
|
+
# @param str the help text to set
|
|
381
|
+
# @example cmd.help %Q{
|
|
382
|
+
# Big help text!
|
|
383
|
+
# }
|
|
384
|
+
def help(str=nil)
|
|
385
|
+
str ? @help << str : @help
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
##
|
|
389
|
+
# Sets the help text for the command. This can be a very long string,
|
|
390
|
+
# as it is what the user sees when they type `amp help +name+`
|
|
391
|
+
#
|
|
392
|
+
# @param str the help text to set
|
|
393
|
+
alias :help= :help
|
|
394
|
+
|
|
395
|
+
##
|
|
396
|
+
# Parses the commands from the command line using Trollop. You probably
|
|
397
|
+
# shouldn't override this method, but if you have good reason, go for it.
|
|
398
|
+
#
|
|
399
|
+
# @return [Hash<Symbol => Object>] The parsed command-line options
|
|
400
|
+
def collect_options
|
|
401
|
+
options = @options # hack to get around the fact that
|
|
402
|
+
help = @help # Trollop uses instance eval
|
|
403
|
+
|
|
404
|
+
ret = Trollop::options do
|
|
405
|
+
banner help
|
|
406
|
+
|
|
407
|
+
# we can't use @options here because Trollop::options uses instance_eval
|
|
408
|
+
# therefore we have to use a local to cheat death^H^H^H^H^Hinstance_eval
|
|
409
|
+
options.each do |option|
|
|
410
|
+
opt option[:name], option[:desc], option[:options]
|
|
411
|
+
end
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
@parser = ret.pop
|
|
415
|
+
ret.first
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
def inspect
|
|
419
|
+
"#<Amp::Command #{name}>"
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
##
|
|
423
|
+
# Adds a namespace to the name of the command. This extra method is
|
|
424
|
+
# needed because many class variables expect this command based on its name -
|
|
425
|
+
# if we don't update these, then our entire program will expect a
|
|
426
|
+
# command with the old name. Not cool.
|
|
427
|
+
#
|
|
428
|
+
# @param [String] ns the namespace to put in front of the command's name
|
|
429
|
+
def add_namespace(ns)
|
|
430
|
+
to = "#{ns}:#{name}".to_sym
|
|
431
|
+
if self.class.all_commands[name] == self
|
|
432
|
+
self.class.all_commands[to] = self.class.all_commands.delete name
|
|
433
|
+
end
|
|
434
|
+
@workflows.each do |flow|
|
|
435
|
+
if self.class.workflows[flow][name] == self
|
|
436
|
+
self.class.workflows[flow][to] = self.class.workflows[flow].delete name
|
|
437
|
+
end
|
|
438
|
+
end
|
|
439
|
+
@synonyms.each do |syn|
|
|
440
|
+
if self.class.all_synonyms[syn] == self
|
|
441
|
+
self.class.all_synonyms["#{ns}:#{syn}"] = self.class.all_synonyms.delete syn
|
|
442
|
+
end
|
|
443
|
+
end
|
|
444
|
+
@name = to
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
##
|
|
448
|
+
# Called by the dispatcher to execute the command. You really don't need to
|
|
449
|
+
# override this. The `$break` global can be set by anything, which
|
|
450
|
+
# will halt the chain.
|
|
451
|
+
#
|
|
452
|
+
# @param [Hash<Symbol => Object>] options The global options, merged with the command-specific
|
|
453
|
+
# options, as decided by the dispatcher.
|
|
454
|
+
# @param [Array<String>] arguments The list of arguments, passed after the options. Could
|
|
455
|
+
# be a filename, for example.
|
|
456
|
+
# @return [Amp::Command] the command being run
|
|
457
|
+
def run(options={}, args=[])
|
|
458
|
+
# run the before commands
|
|
459
|
+
@before.each {|cmd| result = cmd.run options, args; return if !result || $break }
|
|
460
|
+
|
|
461
|
+
@code[options, args] # and of course the actual command...
|
|
462
|
+
|
|
463
|
+
# top it off with the after commands
|
|
464
|
+
@after.each {|cmd| result = cmd.run options, args; return if !result || $break }
|
|
465
|
+
|
|
466
|
+
self
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
NO_REPO_ALLOWED = {}
|
|
470
|
+
%w(clone init help version debugcomplete debugdata debugindex
|
|
471
|
+
debugindexdot debugdate debuginstall debugfsinfo).each do |k|
|
|
472
|
+
NO_REPO_ALLOWED[k.to_sym] = true
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
MAYBE_REPO_ALLOWED = {}
|
|
476
|
+
%w().each do |k|
|
|
477
|
+
MAYBE_REPO_ALLOWED[k.to_sym] = true
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
end
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
module Amp
|
|
484
|
+
module KernelMethods
|
|
485
|
+
# shortcut
|
|
486
|
+
def command(name, &block)
|
|
487
|
+
Amp::Command.new name, &block
|
|
488
|
+
end
|
|
489
|
+
|
|
490
|
+
##
|
|
491
|
+
# Stops the command from running any further - uses the global options.
|
|
492
|
+
def cut!; $break = true; end
|
|
493
|
+
|
|
494
|
+
# Rake style namespacing
|
|
495
|
+
# After new commands are made, alter their names
|
|
496
|
+
# so that they're "#{namespace}:#{command}"
|
|
497
|
+
# NOTE: THIS IS NOT RAKE-FRIENDLY
|
|
498
|
+
# If you load this into a script with Rake, they will
|
|
499
|
+
# fight to the death and only one will have a proper namespace method!
|
|
500
|
+
def namespace(name)
|
|
501
|
+
# current commands
|
|
502
|
+
Amp::Command.use_namespace name.to_s
|
|
503
|
+
yield
|
|
504
|
+
Amp::Command.pop_namespace
|
|
505
|
+
end
|
|
506
|
+
end
|
|
507
|
+
end
|