shellopts 2.0.16 → 2.0.19

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/main CHANGED
@@ -1,1199 +1,29 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'bundler'
4
- Bundler.setup
3
+ $LOAD_PATH.unshift "#{Dir.getwd}/lib"
5
4
 
6
5
  require 'shellopts'
7
6
 
8
- include ShellOpts
7
+ #include ShellOpts::Message
8
+ include ShellOpts::Verbose
9
+ #include ShellOpts::Debug
9
10
 
10
- p ShellOpts::ShellOpts.default_version
11
- exit
12
-
13
- VERSION = "1.2.3"
14
-
15
- SPEC = %(
16
- -a @ An option
17
- )
18
- opts, args = ShellOpts.process(SPEC, ARGV, version: VERSION)
19
- #ShellOpts::ShellOpts.help
20
-
21
-
22
-
23
-
24
-
25
-
26
- __END__
27
-
28
-
29
- #SPEC = %(
30
- # -a,alpha @ Brief comment for -a and --alpha options
31
- # Longer and more elaborate description of the --alpha option
32
- #
33
- # -b,beta=ARG
34
- # @ Alternative style of brief comment
35
- #
36
- # Longer and more elaborate description of the --beta option
37
- #)
38
- #
39
- #opts, args = ShellOpts.process(SPEC, ARGV)
40
- #puts "opts.alpha?: #{opts.alpha?.inspect}"
41
- #puts "opts.alpha: #{opts.alpha.inspect}"
42
- #puts "opts.beta?: #{opts.beta?.inspect}"
43
- #puts "opts.beta: #{opts.beta.inspect}"
44
- #exit
45
- #ShellOpts::ShellOpts.brief
46
- #exit
47
-
48
-
49
-
50
-
51
-
52
-
53
-
54
- # Standard options
55
- # -h,help
56
- # --version
57
- #
58
- # Message options
59
- # -q,quiet
60
- # -v,verbose
61
-
62
- # ShellOpts.parse(spec, argv)
63
- # ShellOpts.stdopt(spec, argv)
64
- # ShellOpts.msgopt(spec, argv)
65
-
66
-
67
-
68
- SPEC = %(
69
- # Comment
70
-
71
- @ Program brief
72
-
73
- This should end up in the DESCRIPTION section in the @help format. Bla bla
74
- bla. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
75
- tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
76
- quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
77
- consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
78
- cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
79
- proident, sunt in culpa qui officia deserunt mollit anim id est laborum
80
-
81
- Here comes some code
82
-
83
- if this_is_printed_correctly?
84
- puts "Success"
85
- end
86
-
87
- Here is a paragraph
88
-
89
- Here is another paragraph
90
-
91
- OPTIONS
92
-
93
- This should be in the OPTIONS section (not supported for now - now it is!)
94
-
95
- -a,all
96
- -b,beta Brief inline comment
97
- +v,verbose -h,help -version @ Multi option line. Option group.
98
- -c
99
- @ Alternative brief.
100
- -f,file=FILE
101
- Indented comment
102
-
103
- Some free text not related to a single options. Eg. an introduction to the
104
- next set of options and some more text to make this wrap
105
-
106
- --multiple --options --on --one --line --with --brief
107
- @ Brief for multi-option line - aka. option group. Lorem ipsum dolor sit amet, consectetur adipiscing elit
108
-
109
- Common comment for previous multi-option line. Lorem ipsum dolor sit amet,
110
- consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
111
- dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
112
- ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
113
- dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
114
- nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
115
- culpa qui officia deserunt mollit anim id est laborum
116
-
117
- Here comes some more code:
118
-
119
- if something
120
- this
121
- else
122
- that
123
- end
124
-
125
- And some more text
126
-
127
-
128
- # --multiple
129
- # --options
130
- # --on
131
- # --multiple
132
- # --lines
133
- # Common comment for previous multi-option lines (not doable, but this is how
134
- # the previous multi-option line will be rendered in one of the formats).
135
- # However, the same is not true for commands that can't have a common comment
136
-
137
-
138
- # A comment that should not be included in the source (useful to out-comment
139
- # sections of source)
140
- #
141
- # The following blank line should be ignored
142
-
143
- -l=MODE:short,long
144
- Another indented comment. The following blank line should be included
145
-
146
- But not if it is the last blank line.
147
- \\hep! initiates a line but is not a command because it is escaped
148
-
149
- a_code_example()
150
- if something == 42
151
- # Something that looks like a command
152
- doit!
153
-
154
- # Something that looks like a option
155
- --i_miss_this
156
- end
157
-
158
- -- ARG1 ARG2
159
-
160
- cmd! @ Brief description of command
161
- Description of command.
162
-
163
- Another paragraph.
164
- Another line in paragraph
165
-
166
- -c,copt @ Inline comment
167
- -d,dopt @ Brief and nested comment
168
- Even more nested comment
169
- -a,all @ Duplicate
170
-
171
- Here is some text where
172
-
173
- the next line is indented (interpreted as code)
174
-
175
- subcmd! -i,inc ++ SUB ARGS @ Brief description of sub-command
176
- A description
177
-
178
- This text should be included too
179
-
180
- ++ CMD_ARG1 CMD_ARG2
181
-
182
- Longer indented text is not related to the previous
183
- description of arguments but is considered code
184
-
185
- is this code
186
-
187
- ++ CMD_ARG_A CMD_ARG_B
188
-
189
- with something that is not a a description
190
-
191
- # -- GLOBAL ARGS
192
-
193
- --another-global-option
194
-
195
- a regular paragraph
196
- )
197
-
198
- ONELINE = "-a,all -b,beta --verbose -h,help -v,version -c -f=FILE --multiple --options --on --one --line -l=MODE:short,long? cmd! -c,copt -d,dopt cmd.subcmd! -- GLOBAL ARGS"
199
-
200
- SPEC2 = %(
201
- @ Program brief
202
-
203
- text text text
204
-
205
- OPTIONS
206
-
207
- Some option intro text
208
-
209
- -a
210
- Option brief 1. Help text
211
-
212
- -b Option brief 2
213
-
214
- -c @ Option brief 3
215
-
216
- -d
217
- @ Option brief 4
218
-
219
- text text text
220
-
221
- COMMANDS
222
-
223
- Some command intro text
224
-
225
- cmd1! -- ARG1 ARG2 Command brief 1
226
- cmd2! @ Command brief 2
227
- cmd3!
228
- First-line option brief. After the first dot
229
-
230
- )
231
-
232
- # #{$stderr.puts "Oops"; "32"}
233
-
234
- SPEC3 = %q(
235
- Description
236
-
237
- -- ARG1 ARG2
238
- -- ARG3 ARG4
239
-
240
- OPTIONS
241
- Some text
242
-
243
- -a An option and not code
244
-
245
- Some code
246
-
247
- \\-b A code line # Because we escaped it
248
- -c # this is not an option
249
- this_is_more_code()
250
-
251
- Another option
252
-
253
- -d Another
254
-
255
- More code
256
-
257
- # A command
258
- -e # is not an option
259
-
260
- COMMANDS
261
- Some commands text
262
-
263
- cmd1! A command
264
- cmd1! A dup
265
-
266
- Some code
267
-
268
- \\cmd2! A code line
269
- cmd3! # this is not a command
270
-
271
- Final
272
- )
273
-
274
- SPEC4 = %(
275
- cmd!
276
- A command
277
-
278
- cmd.nested!
279
- A nested command
280
-
281
- cmd.subcmd!
282
- A subcommand
283
- )
284
-
285
- SPEC5 = "cmd! cmd!"
286
-
287
- shellopts = ShellOpts::ShellOpts.new(exception: true)
288
- #shellopts.compile("cmd! cmd!")
289
-
290
- shellopts.compile(SPEC)
291
- #shellopts.compile(SPEC2)
292
- #shellopts.compile(SPEC3)
293
- #shellopts.compile(SPEC4)
294
- #shellopts.compile(SPEC5)
295
-
296
- #shellopts.tokens.each(&:dump)
297
- #exit
298
-
299
- #shellopts.usage
300
- #shellopts.brief
301
- shellopts.help
302
- #shellopts.help("cmd")
303
- #shellopts.help(ARGV.first)
304
-
305
- #p shellopts.tokens
306
-
307
- #
308
- #shellopts = ShellOpts::ShellOpts.new
309
- #shellopts.compile(SPEC4)
310
- #p shellopts.file
311
- #ShellOpts.process(SPEC4, [])
312
- #exit
313
-
314
-
315
- #argv = ARGV.empty? ? %w(-a cmd -c) : ARGV
316
- #prog, args = ShellOpts::ShellOpts.process SPEC2, argv
317
-
318
- #tokens = ShellOpts::Lexer.lex("main", SPEC4)
319
- #tokens.each(&:dump)
320
- #exit
321
-
322
- #ast = ShellOpts::Parser.parse(tokens)
323
- #ast.dump_ast
324
- #exit
325
-
326
- #idr = ShellOpts::Analyzer.analyze(ast) # @idr and @ast refer to the same object
327
- #idr.dump_idr
328
- #exit
329
-
330
- #puts "-" * 80
331
- #ShellOpts::Formatter.usage(idr)
332
- #puts "-" * 80
333
- #ShellOpts::Formatter.brief(idr)
334
- #puts "-" * 80
335
- #ShellOpts::Formatter.help(idr)
336
- #puts "-" * 80
337
-
338
- #ShellOpts.process(SPEC, [])
339
- #ShellOpts.error("Hej")
340
-
341
-
342
-
343
-
344
-
345
-
346
-
347
-
348
- __END__
349
- exit
350
-
351
- puts "prog.verbose: #{prog.verbose.inspect}"
352
- puts "prog.all?: #{prog.all?}"
353
- puts "prog.file: #{prog.file.inspect}"
354
- puts "prog.subcommand: #{prog.subcommand.inspect}"
355
- puts "prog[:cmd!]: #{prog[:cmd!].__ident__}"
356
- puts "prog[\"cmd\"]: #{prog["cmd"].__ident__}"
357
- puts "prog.subcommand!.subcommand: #{prog.subcommand!.subcommand.inspect}"
358
- #shellopts = ShellOpts::ShellOpts.new ONELINE, ARGV
359
-
360
-
361
-
362
- puts "---------------------"
363
- puts ShellOpts::Formatter.option_help(prog)
364
-
365
- #spec = %(
366
- #hej
367
- #med dig
368
- #)
369
- #shellopts = ShellOpts::ShellOpts.new spec, ARGV
370
-
371
- #shellopts.tokens.each(&:dump)
372
-
373
-
374
- __END__
375
-
376
-
377
- shellopts = ShellOpts::ShellOpts.new(SPEC, ARGV)
378
- opts, args = shellopts.result
379
-
380
- #opts, args = ShellOpts.make(SPEC, ARGV)
381
-
382
- #opts.help? # True if present
383
- #opts.file? # True if present
384
- #opts.file # Not nil if argument was given
385
-
386
- shellopts.mesg "This is a message"
387
- shellopts.quiet!
388
- shellopts.mesg "Not printed"
389
-
390
- shellopts.verb "Not printed"
391
- shellopts.verbose!
392
- shellopts.verb "Printed"
393
-
394
-
395
- #ShellOpts.failure "Something went wrong"
396
- #
397
- #
398
- #ShellOpts.mesg "This is a message"
399
- #ShellOpts.quiet!
400
- #ShellOpts.mesg "Not printed"
401
- #
402
- #ShellOpts.verb "Not printed"
403
- #ShellOpts.verbose!
404
- #ShellOpts.verb "Printed"
405
- #
406
- #
407
- #ShellOpts.failure "Something went wrong"
408
-
409
- #include ShellOpts::Include
410
- #
411
- #mesg "This is a message"
412
- #quiet!
413
- #mesg "Not printed"
414
- #
415
- #verb "Not printed"
416
- #verbose!
417
- #verb "Printed"
418
- #
419
- #
420
- #failure "Something went wrong"
421
-
422
-
423
-
424
- __END__
425
-
426
- opts, args = ShellOpts.process(OPTIONS, ARGV, exception: true)
427
-
428
- if opts.version?
429
- puts "pg_graph-#{PgGraph::VERSION}"
430
- exit
431
- end
432
-
433
- if opts.help?
434
- puts "Name"
435
- puts " #{PROGRAM}"
436
- puts
437
- puts "Usage"
438
- puts " #{PROGRAM} #{USAGE}"
439
- puts
440
- print "Options"
441
- puts OPTIONS
442
- exit
443
- end
444
-
445
- timing = opts.time?
446
- timer = Timer::Timer.new
447
-
448
- # Process options
449
- meta = opts.meta
450
- reflections = opts.reflections
451
-
452
- !opts.kind? || %w(meta type data).include?(opts.kind) or
453
- raise "Unknown argument for --kind option - '#{opts.kind}'"
454
- kind = opts.kind? ? opts.kind : "type"
455
-
456
- !opts.format? || %w(sql exec psql yaml).include?(opts.format) or
457
- raise "Unknown argument for --format option - '#{opts.format}'"
458
- format = opts.format? ? opts.format : "yaml"
459
-
460
- case opts.subcommand || :dump
461
- when :load
462
- opts = opts.subcommand!
463
- !opts.format? || %w(sql exec psql yaml).include?(opts.format) or
464
- raise "Unknown argument for --format option - '#{opts.format}'"
465
-
466
- database = args.expect(-1)
467
- file = args.expect(0..1) || "/dev/stdin"
468
-
469
- if opts.format?
470
- format = opts.format
471
- else
472
- format =
473
- case File.extname(file)
474
- when ".sql"; "sql"
475
- when ".yaml", ".yml"; "yaml"
476
- else
477
- "yaml"
478
- end
479
- end
480
-
481
- case format
482
- when "sql", "exec";
483
- connection = timer.time("connect") { PgConn.new(database) }
484
- timer.time("load file") {
485
- connection.exec(IO.read(file))
486
- }
487
- when "psql"
488
- timer.time("psql") {
489
- system "psql -d #{database} < #{file} >/dev/null"
490
- }
491
- when "yaml"
492
- connection, type = load_type(timer, opts, database)
493
- tg = timer.group("read data")
494
- data = tg.time("data") { PgGraph::Data.new(type, YAML.load(IO.read(file))) }
495
- tg = timer.group("write data")
496
- for label, sql in PgGraph::Data::SqlRender.new(data, :exec).to_h
497
- tg.time(label) { connection.exec(sql.join) }
498
- end
499
- end
500
-
501
- when :dump
502
- if opts # When pg_graph is called without a subcommand
503
- kind = "type"
504
- format = "yaml"
505
- else
506
- !opts.kind? || %w(meta type data).include?(opts.kind) or
507
- raise "Unknown argument for --kind option - '#{opts.kind}'"
508
- kind = opts.kind? ? opts.kind : "type"
509
-
510
- !opts.format? || %w(sql exec psql yaml).include?(opts.format) or
511
- raise "Unknown argument for --format option - '#{opts.format}'"
512
- format = opts.format? ? opts.format : "yaml"
513
- end
514
-
515
- database = args.expect(1)
516
-
517
- case kind
518
- when "meta"
519
- connection = timer.time("connect") { PgConn.new(database) if !opts.meta? }
520
- meta = timer.time("meta") { opts.meta? ? PgMeta.load_file(opts.meta) : PgMeta.new(connection) }
521
- meta.dump
522
- when "type"
523
- connection, type = load_type(timer, opts, database)
524
- type.dump
525
- when "data"
526
- connection, type = load_type(timer, opts, database)
527
- data = timer.time("instantiate") { type.instantiate(connection) }
528
- timer.time("dump") {
529
- case format
530
- when "sql"; puts data.to_sql
531
- when "exec"; puts data.to_exec_sql
532
- when "psql"; puts data.to_psql_sql
533
- when "yaml"; puts data.to_yaml.to_yaml
534
- end
535
- }
536
- end
537
-
538
- when :clean
539
- opts = opts.subcommand!
540
- database = args.expect(1)
541
-
542
- tg = timer.group("initialization")
543
- connection = tg.time("connect") { PgConn.new(database) }
544
- meta = tg.time("meta") { opts.meta? ? PgMeta.new(opts.meta) : PgMeta.new(connection) }
545
- type = tg.time("type") { PgGraph::Type.new(meta) }
546
- data = tg.time("data") { type.instantiate }
547
-
548
- tg = timer.group("clean data")
549
- for label, sql in PgGraph::Data::SqlRender.new(data, :exec).to_h
550
- tg.time(label) { connection.exec(sql.join) }
551
- end
552
- else
553
- puts "else"
554
- end
555
-
556
- timer.dump($stderr) if timing
557
-
558
- rescue ShellOpts::Error => ex
559
- $stderr.puts "#{PROGRAM}: #{ex.message}"
560
- $stderr.puts "Usage: #{PROGRAM} #{USAGE}"
561
- exit 1
562
- end
563
-
564
- include ShellOpts
565
- include Prick
566
-
567
- TIME = false
11
+ #include ShellOpts::Messages
12
+ #p ShellOpts::Messages.is_included?
568
13
 
569
14
  SPEC = %(
570
- -h,help COMMAND...
571
- Print this page
572
-
573
- +v,verbose
574
- Be verbose. Repeated -v options increase the verbosity level
575
-
576
- -q,quiet
577
- Be quiet
578
-
579
- --version
580
- Print prick version. Use 'prick version' to get the project version
581
-
582
- -C,directory=EDIR
583
- Change to directory DIR before doing anything else
584
-
585
- -d,database=DATABASE
586
- Override database name from prick.yml
587
-
588
- -U,username=USERNAME
589
- Override username from from prick.yml
590
-
591
- !version
592
- Print project version
593
-
594
- !init -n,name=NAME -t,title=TITLE -- [DIRECTORY]
595
- Initializes a prick project
596
-
597
- !setup
598
- Create the database user (if necessary) and an empty database
599
-
600
- !teardown
601
- Drop the database and the database user. TODO: Also run teardown scripts
602
-
603
- !create.data
604
- !create.schema
605
- !create.database
606
- !create.users
607
- !create.all
608
- Create an object. Fails if migration exist unless the --force flag is given
609
-
610
- !create.migration -f,force -o,file=NFILE -- VERSION
611
- Create a migration from VERSION to the current and write it to
612
- migration/VERSION. Fails if migration exist unless the --force flag is
613
- given. If --file is given, the migration is written to FILE instead of
614
- the migration directory. This doesn't require you to be on a release
615
- branch and can be used to create ad-hoc migration scripts
616
-
617
- !drop -- [KIND]
618
- Kind can be 'users', 'data', 'schema', 'database' (the default), or 'all'. It is
619
- not an error if the object doesn't exist. TODO Only 'users' is currently defined
620
-
621
- !build -t,time --dump=KIND? -- [SCHEMA]
622
- Build the project. If SCHEMA is defined, later schemas are excluded.
623
- KIND can be 'nodes', 'allnodes' or 'batches' (the default)
624
-
625
- !make -t,time --dump=KIND? -- [SCHEMA]
626
- Checks file timestamps against the time of the last build and only
627
- rebuild affected parts of the project. KIND can be 'nodes', 'allnodes' or
628
- 'batches'
629
-
630
- !fox -- FILE...
631
- Load fox file data. Data are reset to their initial state after build
632
- before the fox data are loaded
633
-
634
- !release -- KIND
635
- Create a release of the given kind. KIND can be 'major', 'minor', or
636
- 'patch'. Release checks that the current repo is clean and up to date
637
- with the origin
638
-
639
- !migrate -f,file=EFILE
640
- Execute a migration
641
-
642
- !dump.type
643
- !dump.data
644
- !dump.schema
645
- !dump.database
646
- TODO
647
-
648
- dump.migration! --force VERSION
649
- )
650
-
651
- opts, args = ShellOpts.process(SPEC, ARGV)
652
-
653
- # Handle --help
654
- if opts.help?
655
- puts "Name"
656
- puts " prick - Postgres project management tool"
657
- puts
658
- puts "Usage"
659
- puts " prick [GLOBAL-OPTIONS] command [COMMAND-OPTIONS] ARGUMENTS"
660
- puts
661
- puts "Options and commands"
662
- puts SPEC.sub(/^\s*\n/, "")
663
- exit
664
- end
665
-
666
- # Initial directory. Used to create relative paths in user messages
667
- #rundir = Dir.getwd
668
-
669
- begin
670
- # Handle --version
671
- if opts.version?
672
- puts "prick-#{VERSION}"
673
- exit
674
- end
675
-
676
- # Handle verbose and quiet
677
- $verbose = opts.verbose
678
- $quiet = opts.quiet?
679
-
680
- # Honor -C option
681
- if opts.directory?
682
- if File.exist?(opts.directory)
683
- begin
684
- Dir.chdir(opts.directory)
685
- rescue Errno::ENOENT
686
- raise Prick::Error, "Can't cd to '#{opts.directory}'"
687
- end
688
- else
689
- raise Prick::Error, "Can't find directory: #{opts.directory}"
690
- end
691
- end
692
-
693
- # Get subcommand
694
- cmd = opts.subcommand!
695
-
696
- # Process init command
697
- if opts.subcommand == :init
698
- dir, state = Prick::SubCommand.init(args.expect(0..1), cmd.name, cmd.title, opts.database, opts.username)
699
- puts "Initialized prick project '#{state.name}' in #{dir}"
700
- if opts.database.nil? || opts.username.nil?
701
- puts
702
- puts "Please check database/username in #{PRICK_CONTEXT_FILE}"
703
- end
704
- exit
705
- end
706
-
707
- # Load state
708
- Prick.state = State.load
709
-
710
- # Handle -d and -U options
711
- database = opts.database || Prick.state.database
712
- username = opts.username || Prick.state.username
713
-
714
- # Expect a sub-command
715
- cmd = opts.subcommand! or raise Prick::Error, "Subcomand expected"
716
-
717
- # Process subcommands
718
- case opts.subcommand
719
- when :version
720
- puts "#{Prick.state.name}-#{Prick.state.version}"
721
-
722
- when :setup
723
- Prick::SubCommand.setup(database, username)
724
-
725
- when :teardown
726
- Prick::SubCommand.teardown(database, username)
727
-
728
- when :create
729
- create_command = opts.create!
730
- case create_command.subcommand
731
- when :migration
732
- arg = args.expect(1)
733
- version = PrickVersion.try(arg) or raise Prick::Error, "Illegal version: #{arg}"
734
- Prick::SubCommand.create_migration(
735
- username, version,
736
- force: create_command.subcommand!.force?,
737
- file: create_command.subcommand!.file)
738
- else
739
- raise NotImplementedError
740
- end
741
-
742
- when :build
743
- dump = cmd.dump("batches")&.to_sym
744
- Prick::SubCommand.build(database, username, args.expect(0..1), timer: cmd.time?, dump: dump)
745
-
746
- when :make
747
- dump = cmd.dump("batches")&.to_sym
748
- Prick::SubCommand.make(database, username, args.expect(0..1), timer: cmd.time?, dump: dump)
749
-
750
- when :fox
751
- Prick::SubCommand.fox(database, username, args)
752
-
753
- when :drop
754
- case subject = args.expect(1).to_sym
755
- when :all
756
- Prick::SubCommand.drop_all(database)
757
- when :users
758
- Prick::SubCommand.drop_users(database)
759
- when :database
760
- Prick::SubCommand.drop_database(database)
761
- when :data, :schema, :database, :all
762
- raise NotImplementedError
763
- else
764
- raise Prick::Error, "Unknown subject: #{subject}"
765
- end
766
-
767
- when :release
768
- kind = args.expect(1).to_sym
769
- constrain? kind, :major, :minor, :patch or
770
- raise Prick::Fail, "Expected 'major', 'minor', or 'patch' argument, got '#{kind}'"
771
- Prick::SubCommand.release(kind)
772
-
773
- when :migrate
774
- args.expect(0)
775
- Prick::SubCommand.migrate(database, username, file: cmd.file)
776
-
777
- when :dump
778
- subject = cmd.subcommand!
779
- case cmd.subcommand
780
- when :migration
781
- arg = args.expect(1)
782
- version = PrickVersion.try(arg) or raise "Illegal version number: #{arg}"
783
- Prick::SubCommand.create_migration(username, version, force: subject.force?, file: "/dev/stdout")
784
- when :data, :schema, :database
785
- raise NotImplementedError
786
- else
787
- raise Prick::Error, "Unknown subject: #{subject}"
788
- end
789
-
790
- else
791
- raise Prick::Fail, "Internal error: Unhandled command - #{opts.subcommand.inspect}"
792
- end
793
-
794
- rescue ShellOpts::Fail, Prick::Fail, Prick::Build::PostgresError => ex
795
- ShellOpts.fail(ex.message)
796
-
797
- rescue ShellOpts::Error, Prick::Error => ex
798
- ShellOpts.error(ex.message)
799
- end
800
-
801
- __END__
802
-
803
- -n,name=NAME
804
- Name of project. Defauls to the environment variable `PRICK_PROJECT` if
805
- set and else the name of the current directory
15
+ Test
806
16
 
807
- init! -u,user=USER [NAME]
808
- Initialize a project in the given directory. The USER is the postgres
809
- user and defaults to the project name
810
-
811
- info!
812
- Print project information
813
-
814
- list.releases! -m,migrations -c,cancelled
815
- List releases. Include migration releases if the --migration option is
816
- present and also include cancelled releases if the --cancelled option is
817
- present
818
-
819
- list.migrations!
820
- List migrations
821
-
822
- list.upgrades! [FROM [TO]]
823
- List available upgrades
824
-
825
- list.cache!
826
- List cache files
827
-
828
- build! -d,database=DATABASE -s,state=FILE -C,no-cache [TAG]
829
- Drop all users associated with the database before building the current
830
- database from the content in the schemas/ directory. With a tag the
831
- version is built into the associated versioned database and the result is
832
- saved to cache unless the -C option is given. The -d option overrides the
833
- default database and the -s option overrides the default state file
834
- (fox.state)
835
-
836
- make! -d,database=DATABASE -C,no-cache [TAG]
837
- Build the current database from the content in the schemas/ directory.
838
- With a tag the associated versioned database is loaded from cache if
839
- present. The -C option ignores the cache and the -d option overrides
840
- the default database
841
-
842
- make.clean! -a,all
843
- Drop versioned databases and remove cached and other temporary files.
844
- Also drop the project database if the -a option is given
845
-
846
- load! -d,database=DATABASE VERSION|FILE
847
- Load the cached version or the file into the associated versioned
848
- database. It is an error if the version hasn't been cached. The --database
849
- argument overrides the database
850
-
851
- save! VERSION [FILE]
852
- Save the versioned database associated with version to the cache or the
853
- given file
854
-
855
- drop! -a,all [DATABASE]
856
- Drop the given database or all versioned databases. Users with a username
857
- on the form <database>__<username> are also dropped. The --all option
858
- also drops the project database
859
-
860
- drop.users! [DATABASE]
861
- Drop users with a username on the form <database>__<username>
862
-
863
- diff! -m,mark -t,tables -T,notables
864
- diff [FROM-DATABASE|FROM-VERSION [TO-DATABASE|TO-VERSION]]
865
- Create a schema diff between the given databases or versions. Default
866
- to-version is the current schema and default from-version is the base
867
- version of this branch/tag
868
-
869
- migrate!
870
- Not yet implemented
871
-
872
- prepare!
873
- Prepare a release. Just a shorthand for 'prick prepare release'
874
-
875
- prepare.release! [FORK]
876
- Populate the current migration directory with migration files
877
-
878
- prepare.feature! NAME
879
- Create and populate a feature as a subdirectory of the current directory.
880
- Also prepares the current release directory
881
-
882
- prepare.migration! [FROM]
883
- Create and populate a migration directory
884
-
885
- prepare.schema! NAME
886
- Create and populate a new schema directory. Existing files and
887
- directories are kept
888
-
889
- prepare.diff! [VERSION]
890
- Not yet implemented
891
-
892
- include.feature! FEATURE
893
- Include the given feature in the current pre-release
894
-
895
- check!
896
- Check that the current migration applied to the base version yields the
897
- same result as loading the current schema
898
-
899
- create.release! [RELEASE]
900
- Prepare a release and create release directory and migration file before
901
- tagging and branching to a release branch. The RELEASE argument can be
902
- left out if the current branch is a prerelease branch
903
-
904
- create.prerelease! RELEASE
905
- Prepare a release and create release directory and migration file before
906
- branching to a prerelease branch
907
-
908
- create.feature! NAME
909
- Prepare a feature before branching to a feature branch
910
-
911
- cancel!
912
- Cancel a release. Just a shorthand for 'prick cancel release'
913
-
914
- cancel.release!
915
- Cancel a release. Since tags are immutable, the release is cancelled by
916
- added a special cancel-tag to the release that makes prick ignore it
917
-
918
- generate.migration!
919
- Create a script to migrate the database
920
-
921
- generate.schema!
922
- Create a script to create the database
923
-
924
- upgrade!
925
- Migrate the database to match the current schema
926
-
927
- backup! [FILE]
928
- Saves a backup of the database to the given file or to the var/spool
929
- directory
930
-
931
- restore! [FILE]
932
- Restore the database from the given backup file or from the latest backup
933
- in the var/spool directory
17
+ -a
18
+ An option
934
19
  )
935
20
 
936
- __END__
937
-
938
-
939
-
940
-
941
-
942
-
943
- DEFAULT_STATE_FILE = "fox.state"
944
-
945
- opts, args = ShellOpts.process(SPEC, ARGV)
21
+ opts, args = ShellOpts.process(SPEC, ARGV, version: "--ver", version_number: "1.2.3", help: "-?,help")
946
22
 
947
- # Handle --help
948
- if opts.help?
949
- ShellOpts.help
950
- exit
951
- end
23
+ verb "Verbose default"
24
+ (0..3).each { |i| verb i, "Verbose #{i}" }
25
+ mesg "Message"
26
+ notice "Notice"
27
+ #debug "Debug"
952
28
 
953
- # Handle --version
954
- if opts.version?
955
- puts "prick-#{VERSION}"
956
- exit
957
- end
958
-
959
- begin
960
- # Honor -C option
961
- if opts.directory?
962
- if File.exist?(opts.directory)
963
- begin
964
- Dir.chdir(opts.directory)
965
- rescue Errno::ENOENT
966
- raise Prick::Error, "Can't cd to '#{opts.directory}'"
967
- end
968
- else
969
- raise Prick::Error, "Can't find directory: #{opts.directory}"
970
- end
971
- end
972
-
973
- # Create program object
974
- program = Program.new(quiet: opts.quiet?, verbose: opts.verbose?)
975
- $verbose = opts.verbose? ? opts.verbose : nil
976
-
977
- # Handle init command
978
- if opts.subcommand == :init
979
- directory = args.expect(0..1)
980
- name = opts.name || (directory && File.basename(directory)) || File.basename(Dir.getwd)
981
- user = opts.init!.user || name
982
- program.init(name, user, directory || ".")
983
- exit 0
984
- end
985
-
986
- # Change to parent directory containing the Prick version file if not found
987
- # in the current directory
988
- program.current_directory = Dir.getwd
989
- while Dir.getwd != "/" && !File.exist?(PRICK_VERSION_FILE)
990
- Dir.chdir("..")
991
- end
992
-
993
- # Check prick version
994
- file = PrickVersion.new
995
- file.exist? or raise Prick::Error, "Can't find prick version file '#{file.path}'"
996
- VERSION == file.read.to_s or
997
- raise Prick::Fail, ".prick-version required prick-#{file.read} but you're using prick-#{VERSION}"
998
-
999
- # TODO: Check for dirty detached head
1000
-
1001
- # Expect a sub-command
1002
- opts.subcommand or raise Prick::Error, "Subcomand expected"
1003
-
1004
- case opts.subcommand
1005
- when :info
1006
- args.expect(0)
1007
- program.info
1008
-
1009
- when :list
1010
- command = opts.list!
1011
- case command.subcommand
1012
- when :releases;
1013
- obj = command.releases!
1014
- program.list_releases(migrations: obj.migrations?, cancelled: obj.cancelled?)
1015
- when :migrations; program.list_migrations
1016
- when :upgrades; program.list_upgrades(*args.expect(0..2).compact)
1017
- when :cache;
1018
- args.expect(0)
1019
- program.list_cache
1020
- when NilClass; raise Prick::Error, "list requires a releases|migrations|upgrades sub-command"
1021
- else
1022
- raise Prick::Internal, "Subcommand #{opts.subcommand}.#{command.subcommand} is not matched"
1023
- end
1024
-
1025
- when :build
1026
- version = args.expect(0..1)
1027
- state_file = File.expand_path(opts.build!.state || DEFAULT_STATE_FILE)
1028
- FileUtils.rm_f(state_file)
1029
- program.build(opts.build!.database, version, state_file, opts.build!.no_cache?)
1030
-
1031
- when :make
1032
- command = opts.make!
1033
- case command.subcommand
1034
- when :clean
1035
- args.expect(0)
1036
- program.make_clean(command.clean!.all?)
1037
- else
1038
- version = args.expect(0..1)
1039
- program.make(opts.make!.database, version, opts.make!.no_cache?)
1040
- end
1041
-
1042
- when :load
1043
- version_or_file = args.expect(1)
1044
- program.load(opts.load!.database, version_or_file)
1045
-
1046
- when :save
1047
- version, file = args.expect(1..2)
1048
- program.save(version, file)
1049
-
1050
- when :drop
1051
- command = opts.drop!
1052
- case command.subcommand
1053
- when :users
1054
- database = args.extract(0..1) || program.project.database.name
1055
- args.expect(0)
1056
- program.drop_users(database)
1057
- else
1058
- program.drop(args.expect(0..1), opts.drop!.all?)
1059
- end
1060
-
1061
- when :diff
1062
- mark = opts.diff!.mark
1063
- tables = opts.diff!.tables
1064
- no_tables = opts.diff!.notables
1065
- tables.nil? && no_tables.nil? || tables ^ no_tables or
1066
- raise Error, "--tables and --no-tables options are exclusive"
1067
- select = tables ? :tables : (no_tables ? :no_tables : :all)
1068
- from, to = args.expect(0..2)
1069
- program.diff(from, to, mark, select)
1070
-
1071
- when :migrate
1072
- raise NotYet
1073
-
1074
- when :prepare
1075
- cmd = opts.prepare!.subcommand || :release
1076
- case cmd
1077
- when :release; program.prepare_release(args.expect(0..1))
1078
- when :feature; program.prepare_feature(args.expect(1))
1079
- when :migration; program.prepare_migration(args.expect(0..1))
1080
- when :schema; program.prepare_schema(args.expect(1))
1081
- when :diff; program.prepare_diff(args.expect(0..1))
1082
- else
1083
- raise Prick::Internal, "Subcommand #{opts.subcommand}.#{cmd} is not matched"
1084
- end
1085
-
1086
- when :include
1087
- cmd = opts.include!.subcommand || :feature
1088
- case cmd
1089
- when :feature; program.include_feature(args.expect(1))
1090
- else
1091
- raise Prick::Internal, "Subcommand #{opts.subcommand}.#{cmd} is not matched"
1092
- end
1093
-
1094
- when :check
1095
- args.expect(0)
1096
- program.check
1097
-
1098
- when :create
1099
- cmd = opts.create!.subcommand || :release
1100
- case cmd
1101
- when :release; program.create_release(args.expect(0..1))
1102
- when :prerelease; program.create_prerelease(args.expect(0..1))
1103
- when :feature; program.create_feature(args.expect(1))
1104
- else
1105
- raise Prick::Internal, "Subcommand #{opts.subcommand}.#{cmd} is not matched"
1106
- end
1107
-
1108
- when :cancel
1109
- cmd = opts.cancel!.subcommand
1110
- case cmd
1111
- when :release; program.cancel_release(args.expect(1))
1112
- when nil; raise Prick::Error, "'cancel' subcommand requires a release argument"
1113
- else
1114
- raise Prick::Internal, "Subcommand #{opts.subcommand}.#{cmd} is not matched"
1115
- end
1116
-
1117
- when :generate
1118
- cmd = opts.generate!.subcommand
1119
- case cmd
1120
- when :schema; program.generate_schema
1121
- when :migration; program.generate_migration
1122
- when nil; raise Prick::Error, "'generate' subcommand requires a 'schema' or 'migration' argument"
1123
- else
1124
- raise Prick::Internal, "Subcommand #{opts.subcommand}.#{cmd} is not matched"
1125
- end
1126
-
1127
- when :upgrade
1128
- args.expect(0)
1129
- program.upgrade
1130
-
1131
- when :backup
1132
- program.backup(args.expect(0..1))
1133
-
1134
- when :restore
1135
- program.restore(args.expect(0..1))
1136
- else
1137
- raise Prick::Internal, "Subcommand #{opts.subcommand} is not matched"
1138
- end
1139
-
1140
- rescue Prick::Fail => ex # Handling of Fail has to come first because Fail < Error
1141
- ShellOpts.fail(ex.message)
1142
- rescue Prick::Error => ex
1143
- ShellOpts.error(ex.message)
1144
- end
1145
-
1146
- __END__
1147
-
1148
- # Awaits support for sections in ShellOpts
1149
- HELP = %(
1150
- OPTIONS
1151
- -n, --name=NAME
1152
- -C, --directory=DIR
1153
- -h, --help
1154
- -v, --verbose
1155
- --version
1156
-
1157
- COMMANDS
1158
- INITIALIZATION
1159
- init --user=USER [DIR]
1160
-
1161
- INFO COMMANDS
1162
- info
1163
- list releases --migrations --cancelled
1164
- list migrations
1165
- list upgrades --all
1166
-
1167
- BUILDING
1168
- build -d DATABASE -C --nocache [TAG]
1169
- make -d DATABASE -C --nocache [TAG]
1170
- make clean -a
1171
- load -d DATABASE VERSION|FILE
1172
- save VERSION [FILE]
1173
- drop --all [DATABASE]
1174
- diff [FROM-DATABASE|FROM-VERSION [TO-DATABASE|TO-VERSION]]
1175
- migrate
1176
-
1177
- PREPARING RELEASES
1178
- prepare release [FORK]
1179
- prepare feature NAME
1180
- prepare migration FROM
1181
- prepare schema NAME
1182
- prepare diff [VERSION]
1183
- include feature FEATURE
1184
- check
1185
-
1186
- CREATING RELEASES
1187
- create release [RELEASE]
1188
- create prerelease RELEASE
1189
- create feature NAME
1190
- cancel release RELEASE
1191
-
1192
- DEPLOYING RELEASES
1193
- generate migration
1194
- generate schema
1195
- upgrade
1196
- backup [FILE]
1197
- restore [FILE]
1198
- )
1199
29