ame 0.1.1 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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/