shellopts 2.0.18 → 2.0.19

Sign up to get free protection for your applications and to get access to all the features.
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