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