ame 0.1.1 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +7 -0
  2. data/README +541 -3
  3. data/Rakefile +15 -6
  4. data/lib/ame-1.0.rb +31 -0
  5. data/lib/ame-1.0/argument.rb +63 -0
  6. data/lib/ame-1.0/arguments.rb +44 -0
  7. data/lib/ame-1.0/arguments/complete.rb +37 -0
  8. data/lib/ame-1.0/arguments/optional.rb +34 -0
  9. data/lib/ame-1.0/arguments/undefined.rb +71 -0
  10. data/lib/ame-1.0/class.rb +436 -0
  11. data/lib/ame-1.0/flag.rb +101 -0
  12. data/lib/{ame → ame-1.0}/help.rb +1 -1
  13. data/lib/ame-1.0/help/delegate.rb +19 -0
  14. data/lib/ame-1.0/help/terminal.rb +132 -0
  15. data/lib/ame-1.0/method.rb +75 -0
  16. data/lib/ame-1.0/method/undefined.rb +184 -0
  17. data/lib/ame-1.0/methods.rb +40 -0
  18. data/lib/ame-1.0/multioption.rb +36 -0
  19. data/lib/ame-1.0/option.rb +37 -0
  20. data/lib/ame-1.0/optional.rb +31 -0
  21. data/lib/ame-1.0/options.rb +68 -0
  22. data/lib/ame-1.0/options/undefined.rb +114 -0
  23. data/lib/ame-1.0/root.rb +174 -0
  24. data/lib/ame-1.0/splat.rb +16 -0
  25. data/lib/ame-1.0/splus.rb +22 -0
  26. data/lib/ame-1.0/switch.rb +39 -0
  27. data/lib/ame-1.0/types.rb +60 -0
  28. data/lib/ame-1.0/types/boolean.rb +13 -0
  29. data/lib/ame-1.0/types/enumeration.rb +40 -0
  30. data/lib/ame-1.0/types/float.rb +11 -0
  31. data/lib/{ame → ame-1.0}/types/integer.rb +3 -3
  32. data/lib/{ame → ame-1.0}/types/string.rb +2 -2
  33. data/lib/ame-1.0/types/symbol.rb +9 -0
  34. data/lib/ame-1.0/version.rb +62 -0
  35. data/test/unit/ame-1.0.rb +4 -0
  36. data/test/unit/ame-1.0/argument.rb +46 -0
  37. data/test/unit/ame-1.0/arguments.rb +63 -0
  38. data/test/unit/ame-1.0/arguments/complete.rb +4 -0
  39. data/test/unit/ame-1.0/arguments/optional.rb +4 -0
  40. data/test/unit/ame-1.0/arguments/undefined.rb +63 -0
  41. data/test/unit/ame-1.0/class.rb +4 -0
  42. data/test/unit/ame-1.0/flag.rb +31 -0
  43. data/test/unit/ame-1.0/help.rb +4 -0
  44. data/test/unit/ame-1.0/help/delegate.rb +4 -0
  45. data/test/unit/{ame/help/console.rb → ame-1.0/help/terminal.rb} +34 -23
  46. data/test/unit/ame-1.0/method.rb +4 -0
  47. data/test/unit/ame-1.0/method/undefined.rb +33 -0
  48. data/test/unit/ame-1.0/methods.rb +9 -0
  49. data/test/unit/ame-1.0/multioption.rb +4 -0
  50. data/test/unit/ame-1.0/option.rb +11 -0
  51. data/test/unit/ame-1.0/optional.rb +9 -0
  52. data/test/unit/ame-1.0/options.rb +149 -0
  53. data/test/unit/ame-1.0/options/undefined.rb +33 -0
  54. data/test/unit/ame-1.0/root.rb +4 -0
  55. data/test/unit/ame-1.0/splat.rb +9 -0
  56. data/test/unit/ame-1.0/splus.rb +4 -0
  57. data/test/unit/ame-1.0/switch.rb +15 -0
  58. data/test/unit/ame-1.0/types.rb +4 -0
  59. data/test/{ame → unit/ame-1.0}/types/boolean.rb +0 -0
  60. data/test/unit/ame-1.0/types/enumeration.rb +4 -0
  61. data/test/unit/ame-1.0/types/float.rb +7 -0
  62. data/test/{ame → unit/ame-1.0}/types/integer.rb +0 -0
  63. data/test/{ame → unit/ame-1.0}/types/string.rb +0 -0
  64. data/test/unit/ame-1.0/types/symbol.rb +5 -0
  65. data/test/unit/ame-1.0/version.rb +4 -0
  66. metadata +690 -60
  67. data/lib/ame.rb +0 -26
  68. data/lib/ame/argument.rb +0 -56
  69. data/lib/ame/arguments.rb +0 -65
  70. data/lib/ame/class.rb +0 -117
  71. data/lib/ame/help/console.rb +0 -96
  72. data/lib/ame/method.rb +0 -94
  73. data/lib/ame/methods.rb +0 -30
  74. data/lib/ame/option.rb +0 -50
  75. data/lib/ame/options.rb +0 -102
  76. data/lib/ame/root.rb +0 -57
  77. data/lib/ame/splat.rb +0 -12
  78. data/lib/ame/types.rb +0 -29
  79. data/lib/ame/types/array.rb +0 -16
  80. data/lib/ame/types/boolean.rb +0 -16
  81. data/lib/ame/version.rb +0 -5
  82. data/test/ame/types/array.rb +0 -13
  83. data/test/unit/ame/argument.rb +0 -66
  84. data/test/unit/ame/arguments.rb +0 -106
  85. data/test/unit/ame/method.rb +0 -40
  86. data/test/unit/ame/methods.rb +0 -10
  87. data/test/unit/ame/option.rb +0 -75
  88. data/test/unit/ame/options.rb +0 -136
  89. data/test/unit/ame/root.rb +0 -15
  90. data/test/unit/ame/splat.rb +0 -11
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 73e51aff907a8f591d1a5a594cbce76d920a34cd
4
+ data.tar.gz: 4e6373393521e2a419dbf49dfe0d901c2a93f82e
5
+ SHA512:
6
+ metadata.gz: cf80a785ab37c5a4c24ef852731d1cf454fb1bdaf88ae0013ddf495e51040498f78ffd5b415541d4e208d0862d249bff8e574f391d289e05254310b3afd3e5f2
7
+ data.tar.gz: d4cee0fad8867fed99bf8484dad8672f5897590e47cdad8a72c993341eb55fb9a4d3e76face9e7392140ff0b636d1ab4fbc55c7f228f6f62cde6d3ce76891457
data/README CHANGED
@@ -1,4 +1,542 @@
1
- # Ame #
1
+ Ame
2
2
 
3
- Ame is a simple command-line parser and build system. Its aim is to replace
4
- the need for other command-line parsers and Rake.
3
+ Ame provides a simple command-line interface API for Ruby¹. It can be used
4
+ to provide both simple interfaces like that of ‹rm›² and complex ones like
5
+ that of ‹git›³. It uses Ruby’s own classes, methods, and argument lists to
6
+ provide an interface that is both simple to use from the command-line side
7
+ and from the Ruby side. The provided command-line interface is flexible and
8
+ follows commond standards for command-line processing.
9
+
10
+ ¹ See http://ruby-lang.org/
11
+ ² See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/rm.html
12
+ ³ See http://git-scm.com/docs/
13
+
14
+ § Usage
15
+
16
+ Let’s begin by looking at two examples, one where we mimic the POSIX¹
17
+ command-line interface to the ‹rm› command. Looking at the entry² in the
18
+ standard, ‹rm› takes the following options:
19
+
20
+ = -f. = Do not prompt for confirmation.
21
+ = -i. = Prompt for confirmation.
22
+ = -R. = Remove file hierarchies.
23
+ = -r. = Equivalent to /-r/.
24
+
25
+ It also takes the following arguments:
26
+
27
+ = FILE. = A pathname or directory entry to be removed.
28
+
29
+ And actually allows one or more of these /FILE/ arguments to be given.
30
+
31
+ We also note that the ‹rm› command is described as a command to “remove
32
+ directory entries”.
33
+
34
+ ¹ See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/contents.html
35
+ ² See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/rm.html
36
+
37
+ Let’s turn this specification into one using Ame’s API. We begin by adding
38
+ a flag for each of the options listed above:
39
+
40
+ class Rm < Ame::Root
41
+ flag 'f', '', false, 'Do not prompt for confirmation'
42
+ flag 'i', '', nil, 'Prompt for confirmation' do |options|
43
+ options['f'] = false
44
+ end
45
+ flag 'R', '', false, 'Remove file hierarchies'
46
+ flag 'r', '', nil, 'Equivalent to -R' do |options|
47
+ options['r'] = true
48
+ end
49
+
50
+ A flag¹ is a boolean option that doesn’t take an argument. Each flag gets
51
+ a short and long name, where an empty name means that there’s no
52
+ corresponding short or long name for the flag, a default value (true,
53
+ false, or nil), and a description of what the flag does. Each flag can
54
+ also optionally take a block that can do further processing. In this case
55
+ we use this block to modify the Hash that maps option names to their values
56
+ passed to the block to set other flags’ values than the ones that the block
57
+ is associated with. As these flags (‘i’ and ‘r’) aren’t themselves of
58
+ interest, their default values have been set to nil, which means that they
59
+ won’t be included in the Hash that maps option names to their values when
60
+ passed to the method.
61
+
62
+ ¹ See http://disu.se/software/ame-1.0/api/user/Ame/Class#flag-class-method
63
+
64
+ There are quite a few other kinds of options besides flags that can be
65
+ defined using Ame, but flags are all that are required for this example.
66
+ We’ll get to the other kinds in later examples.
67
+
68
+ Next we add a “splus” argument.
69
+
70
+ splus 'FILE', String, 'File to remove'
71
+
72
+ A splus¹ argument is like a Ruby “splat”, that is, an Array argument at the
73
+ end of the argument list to a method preceded by a star, except that a
74
+ splus requires at least one argument. A splus argument gets a name for the
75
+ argument (‹FILE›), the type of argument it represents (String), and a
76
+ description.
77
+
78
+ ¹ See http://disu.se/software/ame-1.0/api/user/Ame/Class#splus-class-method
79
+
80
+ Then we add a description of the command (method) itself:
81
+
82
+ description 'Remove directory entries'
83
+
84
+ Descriptions¹ will be used in help output to assist the user in using the
85
+ command.
86
+
87
+ ¹ See http://disu.se/software/ame-1.0/api/user/Ame/Class#description-class-method
88
+
89
+ Finally, we add the Ruby method that’ll implement the command (all
90
+ preceding code included here for completeness):
91
+
92
+ class Rm < Ame::Root
93
+ version '1.0.0'
94
+
95
+ flag 'f', '', false, 'Do not prompt for confirmation'
96
+ flag 'i', '', nil, 'Prompt for confirmation' do |options|
97
+ options['f'] = false
98
+ end
99
+ flag 'R', '', false, 'Remove file hierarchies'
100
+ flag 'r', '', nil, 'Equivalent to -R' do |options|
101
+ options['r'] = true
102
+ end
103
+ splus 'FILE', String, 'File to remove'
104
+ description 'Remove directory entries'
105
+ def rm(files, options = {})
106
+ require 'fileutils'
107
+ FileUtils.send options['R'] ? :rm_r : :rm,
108
+ [first] + rest, :force => options['f']
109
+ end
110
+ end
111
+
112
+ Actually, another bit of code was also added, namely
113
+
114
+ version '1.0.0'
115
+
116
+ This sets the version¹ String of the command. This information is used
117
+ when the command is invoked with the “‹--version›” flag. This flag is
118
+ automatically added, so you don’t need to add it yourself. Another flag,
119
+ “‹--help›”, is also added automatically. When given, this flag’ll make Ame
120
+ output usage information of the command.
121
+
122
+ ¹ See http://disu.se/software/ame-1.0/api/user/Ame/Class#version-class-method
123
+
124
+ To actually run the command, all you need to do is invoke
125
+
126
+ Rm.process
127
+
128
+ This’ll invoke the command using the command-line arguments stored in
129
+ ‹ARGV›, but you can also specify other ones if you want to:
130
+
131
+ Rm.process 'rm', %w[-r /tmp/*]
132
+
133
+ The first argument to #process¹ is the name of the method to invoke, which
134
+ defaults to ‹File.basename($0)›, and the second argument is an Array of
135
+ Strings that should be processed as command-line arguments passed to the
136
+ command.
137
+
138
+ ¹ See http://disu.se/software/ame-1.0/api/user/Ame/Class#process-class-method
139
+
140
+ If you’d store the complete ‹Rm› class defined above in a file called ‹rm›
141
+ and add ‹#! /usr/bin/ruby -w› at the beginning and ‹Rm.process› at the end,
142
+ you’d have a fully functional ‹rm› command (after making it executable).
143
+ Let’s see it in action:
144
+
145
+ % rm --help
146
+ Usage: rm [OPTIONS]... FILE...
147
+ Remove directory entries
148
+
149
+ Arguments:
150
+ FILE... File to remove
151
+
152
+ Options:
153
+ -R Remove file hierarchies
154
+ -f Do not prompt for confirmation
155
+ --help Display help for this method
156
+ -i Prompt for confirmation
157
+ -r Equivalent to -R
158
+ --version Display version information
159
+ % rm --version
160
+ rm 1.0.0
161
+
162
+ Some commands are more complex than ‹rm›. For example, ‹git›¹ has a rather
163
+ complex command-line interface. We won’t mimic it all here, but let’s
164
+ introduce the rest of the Ame API using a fake ‹git› clone as an example.
165
+
166
+ ¹ See http://git-scm.com/docs/
167
+
168
+ ‹Git› uses sub-commands to achieve most things. Implementing sub-commands
169
+ with Ame is done using a “dispatch”. We’ll discuss dispatches in more
170
+ detail later, but suffice it to say that a dispatch delegates processing to
171
+ a child class that’ll handle the sub-command in question. We begin by
172
+ defining our main ‹git› command using a class called ‹Git› under the
173
+ ‹Git::CLI› namespace:
174
+
175
+ module Git end
176
+ class Git::CLI < Ame::Root
177
+ version '1.0.0'
178
+ class Git < Ame::Class
179
+ description 'The stupid content tracker'
180
+ def initialize; end
181
+
182
+ We’re setting things up to use the ‹Git› class as a dispatch in the
183
+ ‹Git::CLI› class. The description on the ‹initialize› method will be used
184
+ as a description of the ‹git› dispatch command itself.
185
+
186
+ Next, let’s add the ‹format-patch›¹ sub-command:
187
+
188
+ description 'Prepare patches for e-mail submission'
189
+ flag ?n, 'numbered', false, 'Name output in [PATCH n/m] format'
190
+ flag ?N, 'no-numbered', nil,
191
+ 'Name output in [PATCH] format' do |options|
192
+ options['numbered'] = false
193
+ end
194
+ toggle ?s, 'signoff', false,
195
+ 'Add Signed-off-by: line to the commit message'
196
+ switch '', 'thread', 'STYLE', nil,
197
+ Ame::Types::Enumeration[:shallow, :deep],
198
+ 'Controls addition of In-Reply-To and References headers'
199
+ flag '', 'no-thread', nil,
200
+ 'Disables addition of In-Reply-To and Reference headers' do |options, _|
201
+ options.delete 'thread'
202
+ end
203
+ option '', 'start-number', 'N', 1,
204
+ 'Start numbering the patches at N instead of 1'
205
+ multioption '', 'to', 'ADDRESS', String,
206
+ 'Add a To: header to the email headers'
207
+ optional 'SINCE', 'N/A', 'Generate patches for commits after SINCE'
208
+ def format_patch(since = '', options = {})
209
+ p since, options
210
+ end
211
+
212
+ ¹ See http://git-scm.com/docs/git-format-patch/
213
+
214
+ We’re using quite a few new Ame commands here. Let’s look at each in turn:
215
+
216
+ toggle ?s, 'signoff', false,
217
+ 'Add Signed-off-by: line to the commit message'
218
+
219
+ A “toggle”¹ is a flag that also has an inverse. Beyond the flags ‘s’ and
220
+ “signoff”, the toggle also defines “no-signoff”, which will set “signoff”
221
+ to false. This is useful if you want to support configuration files that
222
+ set “signoff”’s default to true, but still allow it to be overridden on the
223
+ command line.
224
+
225
+ ¹ See http://disu.se/software/ame-1.0/api/user/Ame/Class#toggle-class-method
226
+
227
+ When using the short form of a toggle (and flag and switch), multiple ones
228
+ may be juxtaposed after the initial one. For example, “‹-sn›” is
229
+ equivalent to “‹-s -n›” to “git format-patch›”.
230
+
231
+ switch '', 'thread', 'STYLE', nil,
232
+ Ame::Types::Enumeration[:shallow, :deep],
233
+ 'Controls addition of In-Reply-To and References headers'
234
+
235
+ A “switch”¹ is an option that takes an optional argument. This allows you
236
+ to have separate defaults for when the switch isn’t present on the command
237
+ line and for when it’s given without an argument. The third argument to a
238
+ switch is the name of the argument. We’re also introducing a new concept
239
+ here in ‹Ame::Types::Enumeration›. An enumeration² allows you to limit the
240
+ allowed input to a set of Symbols. An enumeration also has a default value
241
+ in the first item to its constructor (which is aliased as ‹.[]›). In this
242
+ case, the “thread” switch defaults to nil, but, when given, will default to
243
+ ‹:shallow› if no argument is given. If an argument is given it must be
244
+ either “shallow” or “deep”. A switch isn’t required to take an enumeration
245
+ as its argument default and can take any kind of default value for its
246
+ argument that Ame knows how to handle. We’ll look at this in more detail
247
+ later, but know that the type of the default value will be used to inform
248
+ Ame how to parse a command-line argument into a Ruby value.
249
+
250
+ An argument to a switch must be given, in this case, as “‹--thread=deep›”
251
+ on the command line.
252
+
253
+ ¹ See http://disu.se/software/ame-1.0/api/user/Ame/Class#switch-class-method
254
+ ² See http://disu.se/software/ame-1.0/api/user/Ame/Types/Enumeration/
255
+
256
+ option '', 'start-number', 'N', 1,
257
+ 'Start numbering the patches at N instead of 1'
258
+
259
+ An “option”¹ is an option that takes an argument. The argument must always
260
+ be present and may be given, in this case, as “‹--start-number=2›” or
261
+ “‹--start-number 2›” on the command line. For a short-form option,
262
+ anything that follows the option is seen as an argument, so assuming that
263
+ “start-number” also had a short name of ‘S’, “‹-S2›” would be equivalent to
264
+ “‹-S 2›”, which would be equivalent to “‹--start-number 2›”. Note that
265
+ “‹-snS2›” would still work as expected.
266
+
267
+ ¹ See http://disu.se/software/ame-1.0/api/user/Ame/Class#option-class-method
268
+
269
+ multioption '', 'to', 'ADDRESS', String,
270
+ 'Add a To: header to the email headers'
271
+
272
+ A “multioption”¹ is an option that takes an argument and may be repeated
273
+ any number of times. Each argument will be added to an Array stored in the
274
+ Hash that maps option names to their values. Instead of taking a default
275
+ argument, it takes a type for the argument (String, in this case). Again,
276
+ types are used to inform Ame how to parse command-line arguments into Ruby
277
+ values.
278
+
279
+ ¹ See http://disu.se/software/ame-1.0/api/user/Ame/Class#multioption-class-method
280
+
281
+ optional 'SINCE', 'N/A', 'Generate patches for commits after SINCE'
282
+
283
+ An “optional”¹ argument is an argument that isn’t required. If it’s not
284
+ present on the command line it’ll get its default value (the String
285
+ ‹'N/A'›, in this case).
286
+
287
+ ¹ See http://disu.se/software/ame-1.0/api/user/Ame/Class#optional-class-method
288
+
289
+ We’ve now covered all kinds of options and one new kind of argument. There
290
+ are three more types of argument (one that we’ve already seen and two new)
291
+ that we’ll look into now: “argument”, “splat”, and “splus”.
292
+
293
+ description 'Annotate file lines with commit information'
294
+ argument 'FILE', String, 'File to annotate'
295
+ def annotate(file)
296
+ p file
297
+ end
298
+
299
+ An “argument”¹ is an argument that’s required. If it’s not present on the
300
+ command line, an error will be raised (and by default reported to the
301
+ terminal). As it’s required, it doesn’t take a default, but rather a type.
302
+
303
+ ¹ See http://disu.se/software/ame-1.0/api/user/Ame/Class#argument-class-method
304
+
305
+ description 'Add file contents to the index'
306
+ splat 'PATHSPEC', String, 'Files to add content from'
307
+ def add(paths)
308
+ p paths
309
+ end
310
+
311
+ A “splat”¹ is an argument that’s not required, but may be given any number
312
+ of times. The type of a splat is the type of one argument and the type of
313
+ a splat as a whole is an Array of values of that type.
314
+
315
+ ¹ See http://disu.se/software/ame-1.0/api/user/Ame/Class#splat-class-method
316
+
317
+ description 'Display gitattributes information'
318
+ splus 'PATHNAME', String, 'Files to list attributes of'
319
+ def check_attr(paths)
320
+ p paths
321
+ end
322
+
323
+ A “splus”¹ is an argument that’s required, but may also be given any number
324
+ of times. The type of a splus is the type of one argument and the type of
325
+ a splus as a whole is an Array of values of that type.
326
+
327
+ ¹ See http://disu.se/software/ame-1.0/api/user/Ame/Class#splus-class-method
328
+
329
+ Now that we’ve seen all kinds of options and arguments, let’s look on an
330
+ additional tool at our disposal, the dispatch¹.
331
+
332
+ class Remote < Ame::Class
333
+ description 'Manage set of remote repositories'
334
+ def initialize; end
335
+
336
+ description 'Shows a list of existing remotes'
337
+ flag 'v', 'verbose', false, 'Show remote URL after name'
338
+ def list(options = {})
339
+ p options
340
+ end
341
+
342
+ description 'Adds a remote named NAME for the repository at URL'
343
+ argument 'name', String, 'Name of the remote to add'
344
+ argument 'url', String, 'URL to the repository of the remote to add'
345
+ def add(name, url)
346
+ p name, url
347
+ end
348
+ end
349
+
350
+ ¹ See http://disu.se/software/ame-1.0/api/user/Ame/Class#dispatch-class-method
351
+
352
+ Here we’re defining a child class to Git::CLI::Git called “Remote” that
353
+ doesn’t introduce anything new. Then we set up the dispatch:
354
+
355
+ dispatch Remote, :default => 'list'
356
+
357
+ This adds a method called “remote” to Git::CLI::Git that will dispatch
358
+ processing of the command line to an instance of the Remote class when
359
+ “‹git remote›” is seen on the command line. The “remote” method expects an
360
+ argument that’ll be used to decide what sub-command to execute. Here we’ve
361
+ specified that in the absence of such an argument, the “list” method should
362
+ be invoked.
363
+
364
+ We add the same kind of dispatch to Git under Git::CLI:
365
+
366
+ dispatch Git
367
+
368
+ and then we’re done. Here’s all the previous code in its entirety:
369
+
370
+ module Git end
371
+ class Git::CLI < Ame::Root
372
+ version '1.0.0'
373
+ class Git < Ame::Class
374
+ description 'The stupid content tracker'
375
+ def initialize; end
376
+
377
+ description 'Prepare patches for e-mail submission'
378
+ flag ?n, 'numbered', false, 'Name output in [PATCH n/m] format'
379
+ flag ?N, 'no-numbered', nil,
380
+ 'Name output in [PATCH] format' do |options|
381
+ options['numbered'] = false
382
+ end
383
+ toggle ?s, 'signoff', false,
384
+ 'Add Signed-off-by: line to the commit message'
385
+ switch '', 'thread', 'STYLE', nil,
386
+ Ame::Types::Enumeration[:shallow, :deep],
387
+ 'Controls addition of In-Reply-To and References headers'
388
+ flag '', 'no-thread', nil,
389
+ 'Disables addition of In-Reply-To and Reference headers' do |options, _|
390
+ options.delete 'thread'
391
+ end
392
+ option '', 'start-number', 'N', 1,
393
+ 'Start numbering the patches at N instead of 1'
394
+ multioption '', 'to', 'ADDRESS', String,
395
+ 'Add a To: header to the email headers'
396
+ optional 'SINCE', 'N/A', 'Generate patches for commits after SINCE'
397
+ def format_patch(since = '', options = {})
398
+ p since, options
399
+ end
400
+
401
+ description 'Annotate file lines with commit information'
402
+ argument 'FILE', String, 'File to annotate'
403
+ def annotate(file)
404
+ p file
405
+ end
406
+
407
+ description 'Add file contents to the index'
408
+ splat 'PATHSPEC', String, 'Files to add content from'
409
+ def add(paths)
410
+ p paths
411
+ end
412
+
413
+ description 'Display gitattributes information'
414
+ splus 'PATHNAME', String, 'Files to list attributes of'
415
+ def check_attr(paths)
416
+ p paths
417
+ end
418
+
419
+ class Remote < Ame::Class
420
+ description 'Manage set of remote repositories'
421
+ def initialize; end
422
+
423
+ description 'Shows a list of existing remotes'
424
+ flag 'v', 'verbose', false, 'Show remote URL after name'
425
+ def list(options = {})
426
+ p options
427
+ end
428
+
429
+ description 'Adds a remote named NAME for the repository at URL'
430
+ argument 'name', String, 'Name of the remote to add'
431
+ argument 'url', String, 'URL to the repository of the remote to add'
432
+ def add(name, url)
433
+ p name, url
434
+ end
435
+ end
436
+ dispatch Remote, :default => 'list'
437
+ end
438
+ dispatch Git
439
+ end
440
+
441
+ If we put this code in a file called “git” and add ‹#! /usr/bin/ruby -w› at
442
+ the beginning and ‹Git::CLI.process› at the end, you’ll have a very
443
+ incomplete git command-line interface on your hands. Let’s look at what
444
+ some of its ‹--help› output looks like:
445
+
446
+ % git --help
447
+ Usage: git [OPTIONS]... METHOD [ARGUMENTS]...
448
+ The stupid content tracker
449
+
450
+ Arguments:
451
+ METHOD Method to run
452
+ [ARGUMENTS]... Arguments to pass to METHOD
453
+
454
+ Options:
455
+ --help Display help for this method
456
+ --version Display version information
457
+
458
+ Methods:
459
+ add Add file contents to the index
460
+ annotate Annotate file lines with commit information
461
+ check-attr Display gitattributes information
462
+ format-patch Prepare patches for e-mail submission
463
+ remote Manage set of remote repositories
464
+ % git format-patch --help
465
+ Usage: git format-patch [OPTIONS]... [SINCE]
466
+ Prepare patches for e-mail submission
467
+
468
+ Arguments:
469
+ [SINCE=N/A] Generate patches for commits after SINCE
470
+
471
+ Options:
472
+ -N, --no-numbered Name output in [PATCH] format
473
+ --help Display help for this method
474
+ -n, --numbered Name output in [PATCH n/m] format
475
+ --no-thread Disables addition of In-Reply-To and Reference headers
476
+ -s, --signoff Add Signed-off-by: line to the commit message
477
+ --start-number=N Start numbering the patches at N instead of 1
478
+ --thread[=STYLE] Controls addition of In-Reply-To and References headers
479
+ --to=ADDRESS* Add a To: header to the email headers
480
+ % git remote --help
481
+ Usage: git remote [OPTIONS]... [METHOD] [ARGUMENTS]...
482
+ Manage set of remote repositories
483
+
484
+ Arguments:
485
+ [METHOD=list] Method to run
486
+ [ARGUMENTS]... Arguments to pass to METHOD
487
+
488
+ Options:
489
+ --help Display help for this method
490
+
491
+ Methods:
492
+ add Adds a remote named NAME for the repository at URL
493
+ list Shows a list of existing remotes
494
+
495
+ § API
496
+
497
+ The previous section gave an introduction to the whole user API in an
498
+ informal and introductory way. For an indepth reference to the user API,
499
+ see the {user API documentation}¹.
500
+
501
+ ¹ See http://disu.se/software/ame-1.0/api/user/Ame/
502
+
503
+ If you want to extend the API or use it in some way other than as a
504
+ command-line-interface writer, see the {developer API documentation}¹.
505
+
506
+ ¹ See http://disu.se/software/ame-1.0/api/developer/Ame/
507
+
508
+ § Financing
509
+
510
+ Currently, most of my time is spent at my day job and in my rather busy
511
+ private life. Please motivate me to spend time on this piece of software
512
+ by donating some of your money to this project. Yeah, I realize that
513
+ requesting money to develop software is a bit, well, capitalistic of me.
514
+ But please realize that I live in a capitalistic society and I need money
515
+ to have other people give me the things that I need to continue living
516
+ under the rules of said society. So, if you feel that this piece of
517
+ software has helped you out enough to warrant a reward, please PayPal a
518
+ donation to now@disu.se¹. Thanks! Your support won’t go unnoticed!
519
+
520
+ ¹ Send a donation:
521
+ https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=now@disu.se&item_name=Ame
522
+
523
+ § Reporting Bugs
524
+
525
+ Please report any bugs that you encounter to the {issue tracker}¹.
526
+
527
+ ¹ See https://github.com/now/ame/issues
528
+
529
+ § Authors
530
+
531
+ Nikolai Weibull wrote the code, the tests, the documentation, and this
532
+ README.
533
+
534
+ § Licensing
535
+
536
+ Ame is free software: you may redistribute it and/or modify it under the
537
+ terms of the {GNU Lesser General Public License, version 3}¹ or later², as
538
+ published by the {Free Software Foundation}³.
539
+
540
+ ¹ See http://disu.se/licenses/lgpl-3.0/
541
+ ² See http://gnu.org/licenses/
542
+ ³ See http://fsf.org/