annotate 2.7.5 → 3.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/CHANGELOG.rdoc +10 -0
- data/README.rdoc +27 -7
- data/annotate.gemspec +0 -1
- data/bin/annotate +6 -190
- data/lib/annotate.rb +4 -3
- data/lib/annotate/annotate_models.rb +28 -8
- data/lib/annotate/annotate_routes.rb +150 -148
- data/lib/annotate/version.rb +1 -1
- data/lib/generators/annotate/templates/auto_annotate_models.rake +43 -41
- data/lib/tasks/annotate_models.rake +1 -0
- metadata +4 -3
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 0e4ee3c38fb2ebf3d88712e8836f00570e891cd1a43a6c2bc32c95dc35b7a0d2
         | 
| 4 | 
            +
              data.tar.gz: 1082be239480425543d84491e8c03d54ad99b362cc142b93224517499d4417fa
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 4896d07fc9b6d6b95d5916e566cc0d9a304cd16c1592ac0a0546bb273d533c7dfb275c55b2833586e677027e7f34f6a4f38281053e6e454553be527f4e23055c
         | 
| 7 | 
            +
              data.tar.gz: c72e8ba788014600e40ba24fe7385b9c6c10c08d293ee98bd71e0d91cc235c1a14242293ae963c9265c8e318fa09a104e60547a24c7697218b06be68f320fa63
         | 
    
        data/CHANGELOG.rdoc
    CHANGED
    
    | @@ -1,3 +1,13 @@ | |
| 1 | 
            +
            == 3.0.0
         | 
| 2 | 
            +
            * Added `--models` CLI option fixing issue #563 (#647)
         | 
| 3 | 
            +
            * Added `--additional_file_patterns` option for additional file patterns (#633) #636) #637)
         | 
| 4 | 
            +
            * Refactored CLI parser (#646)
         | 
| 5 | 
            +
            * Fixed BigDecimal.new deprecation warning (#634)
         | 
| 6 | 
            +
            * Fixed annotations for columns with long data types (#622)
         | 
| 7 | 
            +
            * Made methods private in AnnotateRoutes (#598)
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            See https://github.com/ctran/annotate_models/releases/tag/v3.0.0
         | 
| 10 | 
            +
             | 
| 1 11 | 
             
            == 2.7.5
         | 
| 2 12 | 
             
            See https://github.com/ctran/annotate_models/releases/tag/v2.7.5
         | 
| 3 13 |  | 
    
        data/README.rdoc
    CHANGED
    
    | @@ -6,7 +6,6 @@ | |
| 6 6 | 
             
            {<img src="https://coveralls.io/repos/ctran/annotate_models/badge.svg?branch=develop" />}[https://coveralls.io/r/ctran/annotate_models?branch=develop]
         | 
| 7 7 | 
             
            {<img src="https://codeclimate.com/github/ctran/annotate_models/badges/gpa.svg" />}[https://codeclimate.com/github/ctran/annotate_models]
         | 
| 8 8 | 
             
            {<img src="http://inch-ci.org/github/ctran/annotate_models.svg?branch=develop" alt="Inline docs" />}[http://inch-ci.org/github/ctran/annotate_models]
         | 
| 9 | 
            -
            {<img src="https://gemnasium.com/ctran/annotate_models.png" />}[https://gemnasium.com/ctran/annotate_models]
         | 
| 10 9 |  | 
| 11 10 | 
             
            Add a comment summarizing the current schema to the top or bottom of each of
         | 
| 12 11 | 
             
            your...
         | 
| @@ -90,11 +89,11 @@ To annotate all your models, tests, fixtures, and factories: | |
| 90 89 |  | 
| 91 90 | 
             
            To annotate just your models, tests, and factories:
         | 
| 92 91 |  | 
| 93 | 
            -
                annotate --exclude fixtures
         | 
| 92 | 
            +
                annotate --models --exclude fixtures
         | 
| 94 93 |  | 
| 95 94 | 
             
            To annotate just your models:
         | 
| 96 95 |  | 
| 97 | 
            -
                annotate -- | 
| 96 | 
            +
                annotate --models
         | 
| 98 97 |  | 
| 99 98 | 
             
            To annotate routes.rb:
         | 
| 100 99 |  | 
| @@ -164,6 +163,7 @@ you can do so with a simple environment variable, instead of editing the | |
| 164 163 | 
             
            == Options
         | 
| 165 164 |  | 
| 166 165 | 
             
                Usage: annotate [options] [model_file]*
         | 
| 166 | 
            +
                        --additional_file_patterns   Additional file paths or globs to annotate, separated by commas (e.g. `/foo/bar/%model_name%/*.rb,/baz/%model_name%.rb`)
         | 
| 167 167 | 
             
                    -d, --delete                     Remove annotations from all model files or the routes.rb file
         | 
| 168 168 | 
             
                    -p [before|top|after|bottom],    Place the annotations at the top (before) or the bottom (after) of the model/test/fixture/factory/route/serializer file(s)
         | 
| 169 169 | 
             
                        --position
         | 
| @@ -184,6 +184,7 @@ you can do so with a simple environment variable, instead of editing the | |
| 184 184 | 
             
                        --wo, --wrapper-open STR     Annotation wrapper opening.
         | 
| 185 185 | 
             
                        --wc, --wrapper-close STR    Annotation wrapper closing
         | 
| 186 186 | 
             
                    -r, --routes                     Annotate routes.rb with the output of 'rake routes'
         | 
| 187 | 
            +
                        --models                     Annotate ActiveRecord models
         | 
| 187 188 | 
             
                    -a, --active-admin               Annotate active_admin models
         | 
| 188 189 | 
             
                    -v, --version                    Show the current version of this gem
         | 
| 189 190 | 
             
                    -m, --show-migration             Include the migration version number in the annotation
         | 
| @@ -206,16 +207,35 @@ you can do so with a simple environment variable, instead of editing the | |
| 206 207 | 
             
                        --frozen                     Do not allow to change annotations. Exits non-zero if there are going to be changes to files.
         | 
| 207 208 | 
             
                        --timestamp                  Include timestamp in (routes) annotation
         | 
| 208 209 | 
             
                        --trace                      If unable to annotate a file, print the full stack trace, not just the exception message.
         | 
| 209 | 
            -
                    -I, --ignore-columns REGEX       don't annotate columns that match a given REGEX ( | 
| 210 | 
            -
                        --ignore-routes REGEX        don't annotate routes that match a given REGEX ( | 
| 210 | 
            +
                    -I, --ignore-columns REGEX       don't annotate columns that match a given REGEX (e.g. `annotate -I '^(id|updated_at|created_at)'`)
         | 
| 211 | 
            +
                        --ignore-routes REGEX        don't annotate routes that match a given REGEX (e.g. `annotate -I '(mobile|resque|pghero)'`)_
         | 
| 211 212 | 
             
                        --hide-limit-column-types VALUES
         | 
| 212 | 
            -
                                                     don't show limit for given column types, separated by commas ( | 
| 213 | 
            +
                                                     don't show limit for given column types, separated by commas (e.g. `integer,boolean,text`)
         | 
| 213 214 | 
             
                        --hide-default-column-types VALUES
         | 
| 214 | 
            -
                                                     don't show default for given column types, separated by commas ( | 
| 215 | 
            +
                                                     don't show default for given column types, separated by commas (e.g. `json,jsonb,hstore`)
         | 
| 215 216 | 
             
                        --ignore-unknown-models      don't display warnings for bad model files
         | 
| 216 217 | 
             
                        --with-comment               include database comments in model annotations
         | 
| 217 218 |  | 
| 219 | 
            +
            === Option: +additional_file_patterns+
         | 
| 218 220 |  | 
| 221 | 
            +
            CLI: +--additional_file_patterns+<br>
         | 
| 222 | 
            +
            Ruby: +:additional_file_patterns+
         | 
| 223 | 
            +
             | 
| 224 | 
            +
            Provide additional paths for the gem to annotate.  These paths can include globs.
         | 
| 225 | 
            +
            It is recommended to use absolute paths.  Here are some examples:
         | 
| 226 | 
            +
             | 
| 227 | 
            +
             | 
| 228 | 
            +
            - <code>/app/lib/decorates/%MODEL_NAME%/*.rb</code>
         | 
| 229 | 
            +
            - <code>/app/lib/forms/%PLURALIZED_MODEL_NAME%/**/*.rb</code>
         | 
| 230 | 
            +
            - <code>/app/lib/forms/%TABLE_NAME%/*.rb</code>
         | 
| 231 | 
            +
             | 
| 232 | 
            +
            The appropriate model will be inferred using the <code>%*%</code> syntax, annotating any matching files.
         | 
| 233 | 
            +
            It works with existing filename resolutions (options for which can be found in the +resolve_filename+ method of
         | 
| 234 | 
            +
            +annotate_models.rb+).
         | 
| 235 | 
            +
             | 
| 236 | 
            +
            When using in a Rails config, you can use the following:
         | 
| 237 | 
            +
             | 
| 238 | 
            +
            <code>File.join(Rails.application.root, 'app/lib/forms/%PLURALIZED_MODEL_NAME%/**/*.rb')</code>
         | 
| 219 239 |  | 
| 220 240 | 
             
            == Sorting
         | 
| 221 241 |  | 
    
        data/annotate.gemspec
    CHANGED
    
    | @@ -38,7 +38,6 @@ Gem::Specification.new do |s| | |
| 38 38 | 
             
              s.homepage = 'http://github.com/ctran/annotate_models'
         | 
| 39 39 | 
             
              s.licenses = ['Ruby']
         | 
| 40 40 | 
             
              s.require_paths = ['lib']
         | 
| 41 | 
            -
              s.rubyforge_project = 'annotate'
         | 
| 42 41 | 
             
              s.rubygems_version = '2.1.11'
         | 
| 43 42 | 
             
              s.summary = 'Annotates Rails Models, routes, fixtures, and others based on the database schema.'
         | 
| 44 43 |  | 
    
        data/bin/annotate
    CHANGED
    
    | @@ -14,203 +14,19 @@ end | |
| 14 14 | 
             
            here = File.expand_path(File.dirname __FILE__)
         | 
| 15 15 | 
             
            $LOAD_PATH << "#{here}/../lib"
         | 
| 16 16 |  | 
| 17 | 
            -
            require 'optparse'
         | 
| 18 17 | 
             
            require 'annotate'
         | 
| 19 | 
            -
             | 
| 20 | 
            -
             | 
| 21 | 
            -
            has_set_position = {}
         | 
| 22 | 
            -
            target_action = :do_annotations
         | 
| 23 | 
            -
            positions = %w(before top after bottom)
         | 
| 24 | 
            -
             | 
| 25 | 
            -
            OptionParser.new do |opts|
         | 
| 26 | 
            -
              opts.banner = 'Usage: annotate [options] [model_file]*'
         | 
| 27 | 
            -
             | 
| 28 | 
            -
              opts.on('-d', '--delete', 'Remove annotations from all model files or the routes.rb file') do
         | 
| 29 | 
            -
                target_action = :remove_annotations
         | 
| 30 | 
            -
              end
         | 
| 31 | 
            -
             | 
| 32 | 
            -
              opts.on('-p', '--position [before|top|after|bottom]', positions,
         | 
| 33 | 
            -
                      'Place the annotations at the top (before) or the bottom (after) of the model/test/fixture/factory/route/serializer file(s)') do |p|
         | 
| 34 | 
            -
                ENV['position'] = p
         | 
| 35 | 
            -
                %w(position_in_class position_in_factory position_in_fixture position_in_test position_in_routes position_in_serializer).each do |key|
         | 
| 36 | 
            -
                  ENV[key] = p unless has_set_position[key]
         | 
| 37 | 
            -
                end
         | 
| 38 | 
            -
              end
         | 
| 39 | 
            -
             | 
| 40 | 
            -
              opts.on('--pc', '--position-in-class [before|top|after|bottom]', positions,
         | 
| 41 | 
            -
                      'Place the annotations at the top (before) or the bottom (after) of the model file') do |p|
         | 
| 42 | 
            -
                ENV['position_in_class'] = p
         | 
| 43 | 
            -
                has_set_position['position_in_class'] = true
         | 
| 44 | 
            -
              end
         | 
| 45 | 
            -
             | 
| 46 | 
            -
              opts.on('--pf', '--position-in-factory [before|top|after|bottom]', positions,
         | 
| 47 | 
            -
                      'Place the annotations at the top (before) or the bottom (after) of any factory files') do |p|
         | 
| 48 | 
            -
                ENV['position_in_factory'] = p
         | 
| 49 | 
            -
                has_set_position['position_in_factory'] = true
         | 
| 50 | 
            -
              end
         | 
| 51 | 
            -
             | 
| 52 | 
            -
              opts.on('--px', '--position-in-fixture [before|top|after|bottom]', positions,
         | 
| 53 | 
            -
                      'Place the annotations at the top (before) or the bottom (after) of any fixture files') do |p|
         | 
| 54 | 
            -
                ENV['position_in_fixture'] = p
         | 
| 55 | 
            -
                has_set_position['position_in_fixture'] = true
         | 
| 56 | 
            -
              end
         | 
| 57 | 
            -
             | 
| 58 | 
            -
              opts.on('--pt', '--position-in-test [before|top|after|bottom]', positions,
         | 
| 59 | 
            -
                      'Place the annotations at the top (before) or the bottom (after) of any test files') do |p|
         | 
| 60 | 
            -
                ENV['position_in_test'] = p
         | 
| 61 | 
            -
                has_set_position['position_in_test'] = true
         | 
| 62 | 
            -
              end
         | 
| 63 | 
            -
             | 
| 64 | 
            -
              opts.on('--pr', '--position-in-routes [before|top|after|bottom]', positions,
         | 
| 65 | 
            -
                      'Place the annotations at the top (before) or the bottom (after) of the routes.rb file') do |p|
         | 
| 66 | 
            -
                ENV['position_in_routes'] = p
         | 
| 67 | 
            -
                has_set_position['position_in_routes'] = true
         | 
| 68 | 
            -
              end
         | 
| 69 | 
            -
             | 
| 70 | 
            -
              opts.on('--ps', '--position-in-serializer [before|top|after|bottom]', positions,
         | 
| 71 | 
            -
                      'Place the annotations at the top (before) or the bottom (after) of the serializer files') do |p|
         | 
| 72 | 
            -
                ENV['position_in_serializer'] = p
         | 
| 73 | 
            -
                has_set_position['position_in_serializer'] = true
         | 
| 74 | 
            -
              end
         | 
| 75 | 
            -
             | 
| 76 | 
            -
              opts.on('--w', '--wrapper STR', 'Wrap annotation with the text passed as parameter.',
         | 
| 77 | 
            -
                      'If --w option is used, the same text will be used as opening and closing') do |p|
         | 
| 78 | 
            -
                ENV['wrapper'] = p
         | 
| 79 | 
            -
              end
         | 
| 80 | 
            -
             | 
| 81 | 
            -
              opts.on('--wo', '--wrapper-open STR', 'Annotation wrapper opening.') do |p|
         | 
| 82 | 
            -
                ENV['wrapper_open'] = p
         | 
| 83 | 
            -
              end
         | 
| 84 | 
            -
             | 
| 85 | 
            -
              opts.on('--wc', '--wrapper-close STR', 'Annotation wrapper closing') do |p|
         | 
| 86 | 
            -
                ENV['wrapper_close'] = p
         | 
| 87 | 
            -
              end
         | 
| 88 | 
            -
             | 
| 89 | 
            -
              opts.on('-r', '--routes', "Annotate routes.rb with the output of 'rake routes'") do
         | 
| 90 | 
            -
                ENV['routes'] = 'true'
         | 
| 91 | 
            -
              end
         | 
| 92 | 
            -
             | 
| 93 | 
            -
              opts.on('-a', '--active-admin', 'Annotate active_admin models') do
         | 
| 94 | 
            -
                ENV['active_admin'] = 'true'
         | 
| 95 | 
            -
              end
         | 
| 96 | 
            -
             | 
| 97 | 
            -
              opts.on('-v', '--version', 'Show the current version of this gem') do
         | 
| 98 | 
            -
                puts "annotate v#{Annotate.version}"; exit
         | 
| 99 | 
            -
              end
         | 
| 100 | 
            -
             | 
| 101 | 
            -
              opts.on('-m', '--show-migration', 'Include the migration version number in the annotation') do
         | 
| 102 | 
            -
                ENV['include_version'] = 'yes'
         | 
| 103 | 
            -
              end
         | 
| 104 | 
            -
             | 
| 105 | 
            -
              opts.on('-k', '--show-foreign-keys',
         | 
| 106 | 
            -
                      "List the table's foreign key constraints in the annotation") do
         | 
| 107 | 
            -
                ENV['show_foreign_keys'] = 'yes'
         | 
| 108 | 
            -
              end
         | 
| 18 | 
            +
            require 'annotate/parser'
         | 
| 109 19 |  | 
| 110 | 
            -
             | 
| 111 | 
            -
                      '--complete-foreign-keys', 'Complete foreign key names in the annotation') do
         | 
| 112 | 
            -
                ENV['show_foreign_keys'] = 'yes'
         | 
| 113 | 
            -
                ENV['show_complete_foreign_keys'] = 'yes'
         | 
| 114 | 
            -
              end
         | 
| 115 | 
            -
             | 
| 116 | 
            -
              opts.on('-i', '--show-indexes',
         | 
| 117 | 
            -
                      "List the table's database indexes in the annotation") do
         | 
| 118 | 
            -
                ENV['show_indexes'] = 'yes'
         | 
| 119 | 
            -
              end
         | 
| 120 | 
            -
             | 
| 121 | 
            -
              opts.on('-s', '--simple-indexes',
         | 
| 122 | 
            -
                      "Concat the column's related indexes in the annotation") do
         | 
| 123 | 
            -
                ENV['simple_indexes'] = 'yes'
         | 
| 124 | 
            -
              end
         | 
| 125 | 
            -
             | 
| 126 | 
            -
              opts.on('--model-dir dir',
         | 
| 127 | 
            -
                      "Annotate model files stored in dir rather than app/models, separate multiple dirs with commas") do |dir|
         | 
| 128 | 
            -
                ENV['model_dir'] = dir
         | 
| 129 | 
            -
              end
         | 
| 130 | 
            -
             | 
| 131 | 
            -
              opts.on('--root-dir dir',
         | 
| 132 | 
            -
                      "Annotate files stored within root dir projects, separate multiple dirs with commas") do |dir|
         | 
| 133 | 
            -
                ENV['root_dir'] = dir
         | 
| 134 | 
            -
              end
         | 
| 135 | 
            -
             | 
| 136 | 
            -
              opts.on('--ignore-model-subdirects',
         | 
| 137 | 
            -
                      "Ignore subdirectories of the models directory") do |dir|
         | 
| 138 | 
            -
                ENV['ignore_model_sub_dir'] = 'yes'
         | 
| 139 | 
            -
              end
         | 
| 140 | 
            -
             | 
| 141 | 
            -
              opts.on('--sort',
         | 
| 142 | 
            -
                      "Sort columns alphabetically, rather than in creation order") do |dir|
         | 
| 143 | 
            -
                ENV['sort'] = 'yes'
         | 
| 144 | 
            -
              end
         | 
| 145 | 
            -
             | 
| 146 | 
            -
              opts.on('--classified-sort',
         | 
| 147 | 
            -
                      "Sort columns alphabetically, but first goes id, then the rest columns, then the timestamp columns and then the association columns") do |dir|
         | 
| 148 | 
            -
                ENV['classified_sort'] = 'yes'
         | 
| 149 | 
            -
              end
         | 
| 150 | 
            -
             | 
| 151 | 
            -
              opts.on('-R', '--require path',
         | 
| 152 | 
            -
                      "Additional file to require before loading models, may be used multiple times") do |path|
         | 
| 153 | 
            -
                if !ENV['require'].blank?
         | 
| 154 | 
            -
                  ENV['require'] = ENV['require'] + ",#{path}"
         | 
| 155 | 
            -
                else
         | 
| 156 | 
            -
                  ENV['require'] = path
         | 
| 157 | 
            -
                end
         | 
| 158 | 
            -
              end
         | 
| 159 | 
            -
             | 
| 160 | 
            -
              opts.on('-e', '--exclude [tests,fixtures,factories,serializers]', Array, "Do not annotate fixtures, test files, factories, and/or serializers") do |exclusions|
         | 
| 161 | 
            -
                exclusions ||= %w(tests fixtures factories)
         | 
| 162 | 
            -
                exclusions.each { |exclusion| ENV["exclude_#{exclusion}"] = 'yes' }
         | 
| 163 | 
            -
              end
         | 
| 164 | 
            -
             | 
| 165 | 
            -
              opts.on('-f', '--format [bare|rdoc|markdown]', %w(bare rdoc markdown), 'Render Schema Infomation as plain/RDoc/Markdown') do |fmt|
         | 
| 166 | 
            -
                ENV["format_#{fmt}"] = 'yes'
         | 
| 167 | 
            -
              end
         | 
| 168 | 
            -
             | 
| 169 | 
            -
              opts.on('--force', 'Force new annotations even if there are no changes.') do |force|
         | 
| 170 | 
            -
                ENV['force'] = 'yes'
         | 
| 171 | 
            -
              end
         | 
| 172 | 
            -
             | 
| 173 | 
            -
              opts.on('--frozen', 'Do not allow to change annotations. Exits non-zero if there are going to be changes to files.') do
         | 
| 174 | 
            -
                ENV['frozen'] = 'yes'
         | 
| 175 | 
            -
              end
         | 
| 176 | 
            -
             | 
| 177 | 
            -
              opts.on('--timestamp', 'Include timestamp in (routes) annotation') do
         | 
| 178 | 
            -
                ENV['timestamp'] = 'true'
         | 
| 179 | 
            -
              end
         | 
| 180 | 
            -
             | 
| 181 | 
            -
              opts.on('--trace', 'If unable to annotate a file, print the full stack trace, not just the exception message.') do |value|
         | 
| 182 | 
            -
                ENV['trace'] = 'yes'
         | 
| 183 | 
            -
              end
         | 
| 184 | 
            -
             | 
| 185 | 
            -
              opts.on('-I', '--ignore-columns REGEX', "don't annotate columns that match a given REGEX (i.e., `annotate -I '^(id|updated_at|created_at)'`") do |regex|
         | 
| 186 | 
            -
                ENV['ignore_columns'] = regex
         | 
| 187 | 
            -
              end
         | 
| 188 | 
            -
             | 
| 189 | 
            -
              opts.on('--ignore-routes REGEX', "don't annotate routes that match a given REGEX (i.e., `annotate -I '(mobile|resque|pghero)'`") do |regex|
         | 
| 190 | 
            -
                ENV['ignore_routes'] = regex
         | 
| 191 | 
            -
              end
         | 
| 192 | 
            -
             | 
| 193 | 
            -
              opts.on('--hide-limit-column-types VALUES', "don't show limit for given column types, separated by commas (i.e., `integer,boolean,text`)") do |values|
         | 
| 194 | 
            -
                ENV['hide_limit_column_types'] = "#{values}"
         | 
| 195 | 
            -
              end
         | 
| 196 | 
            -
             | 
| 197 | 
            -
              opts.on('--hide-default-column-types VALUES', "don't show default for given column types, separated by commas (i.e., `json,jsonb,hstore`)") do |values|
         | 
| 198 | 
            -
                ENV['hide_default_column_types'] = "#{values}"
         | 
| 199 | 
            -
              end
         | 
| 20 | 
            +
            Annotate.bootstrap_rake
         | 
| 200 21 |  | 
| 201 | 
            -
             | 
| 202 | 
            -
                ENV['ignore_unknown_models'] = 'true'
         | 
| 203 | 
            -
              end
         | 
| 22 | 
            +
            options_result = Annotate::Parser.parse(ARGV)
         | 
| 204 23 |  | 
| 205 | 
            -
             | 
| 206 | 
            -
                ENV['with_comment'] = 'true'
         | 
| 207 | 
            -
              end
         | 
| 208 | 
            -
            end.parse!
         | 
| 24 | 
            +
            exit if options_result[:exit]
         | 
| 209 25 |  | 
| 210 26 | 
             
            options = Annotate.setup_options(
         | 
| 211 27 | 
             
              is_rake: ENV['is_rake'] && !ENV['is_rake'].empty?
         | 
| 212 28 | 
             
            )
         | 
| 213 29 | 
             
            Annotate.eager_load(options) if Annotate.include_models?
         | 
| 214 30 |  | 
| 215 | 
            -
            AnnotateModels.send(target_action, options) if Annotate.include_models?
         | 
| 216 | 
            -
            AnnotateRoutes.send(target_action, options) if Annotate.include_routes?
         | 
| 31 | 
            +
            AnnotateModels.send(options_result[:target_action], options) if Annotate.include_models?
         | 
| 32 | 
            +
            AnnotateRoutes.send(options_result[:target_action], options) if Annotate.include_routes?
         | 
    
        data/lib/annotate.rb
    CHANGED
    
    | @@ -36,8 +36,8 @@ module Annotate | |
| 36 36 | 
             
                :exclude_sti_subclasses, :ignore_unknown_models, :with_comment
         | 
| 37 37 | 
             
              ].freeze
         | 
| 38 38 | 
             
              OTHER_OPTIONS = [
         | 
| 39 | 
            -
                :ignore_columns, :skip_on_db_migrate, :wrapper_open, :wrapper_close,
         | 
| 40 | 
            -
                :wrapper, :routes, :hide_limit_column_types, :hide_default_column_types,
         | 
| 39 | 
            +
                :additional_file_patterns, :ignore_columns, :skip_on_db_migrate, :wrapper_open, :wrapper_close,
         | 
| 40 | 
            +
                :wrapper, :routes, :models, :hide_limit_column_types, :hide_default_column_types,
         | 
| 41 41 | 
             
                :ignore_routes, :active_admin
         | 
| 42 42 | 
             
              ].freeze
         | 
| 43 43 | 
             
              PATH_OPTIONS = [
         | 
| @@ -88,6 +88,7 @@ module Annotate | |
| 88 88 | 
             
                  options[key] = !ENV[key.to_s].blank? ? ENV[key.to_s].split(',') : []
         | 
| 89 89 | 
             
                end
         | 
| 90 90 |  | 
| 91 | 
            +
                options[:additional_file_patterns] ||= []
         | 
| 91 92 | 
             
                options[:model_dir] = ['app/models'] if options[:model_dir].empty?
         | 
| 92 93 |  | 
| 93 94 | 
             
                options[:wrapper_open] ||= options[:wrapper]
         | 
| @@ -114,7 +115,7 @@ module Annotate | |
| 114 115 | 
             
              end
         | 
| 115 116 |  | 
| 116 117 | 
             
              def self.include_models?
         | 
| 117 | 
            -
                ENV[' | 
| 118 | 
            +
                ENV['models'] =~ TRUE_RE
         | 
| 118 119 | 
             
              end
         | 
| 119 120 |  | 
| 120 121 | 
             
              def self.loaded_tasks=(val)
         | 
| @@ -159,13 +159,15 @@ module AnnotateModels | |
| 159 159 | 
             
                  ]
         | 
| 160 160 | 
             
                end
         | 
| 161 161 |  | 
| 162 | 
            -
                def files_by_pattern(root_directory, pattern_type)
         | 
| 162 | 
            +
                def files_by_pattern(root_directory, pattern_type, options)
         | 
| 163 163 | 
             
                  case pattern_type
         | 
| 164 164 | 
             
                  when 'test'       then test_files(root_directory)
         | 
| 165 165 | 
             
                  when 'fixture'    then fixture_files(root_directory)
         | 
| 166 166 | 
             
                  when 'scaffold'   then scaffold_files(root_directory)
         | 
| 167 167 | 
             
                  when 'factory'    then factory_files(root_directory)
         | 
| 168 168 | 
             
                  when 'serializer' then serialize_files(root_directory)
         | 
| 169 | 
            +
                  when 'additional_file_patterns'
         | 
| 170 | 
            +
                    [options[:additional_file_patterns] || []].flatten
         | 
| 169 171 | 
             
                  when 'controller'
         | 
| 170 172 | 
             
                    [File.join(root_directory, CONTROLLER_DIR, "%PLURALIZED_MODEL_NAME%_controller.rb")]
         | 
| 171 173 | 
             
                  when 'admin'
         | 
| @@ -177,14 +179,20 @@ module AnnotateModels | |
| 177 179 | 
             
                  end
         | 
| 178 180 | 
             
                end
         | 
| 179 181 |  | 
| 180 | 
            -
                def get_patterns(pattern_types = [])
         | 
| 182 | 
            +
                def get_patterns(options, pattern_types = [])
         | 
| 181 183 | 
             
                  current_patterns = []
         | 
| 182 184 | 
             
                  root_dir.each do |root_directory|
         | 
| 183 185 | 
             
                    Array(pattern_types).each do |pattern_type|
         | 
| 184 | 
            -
                       | 
| 186 | 
            +
                      patterns = files_by_pattern(root_directory, pattern_type, options)
         | 
| 187 | 
            +
             | 
| 188 | 
            +
                      current_patterns += if pattern_type.to_sym == :additional_file_patterns
         | 
| 189 | 
            +
                                            patterns
         | 
| 190 | 
            +
                                          else
         | 
| 191 | 
            +
                                            patterns.map { |p| p.sub(/^[\/]*/, '') }
         | 
| 192 | 
            +
                                          end
         | 
| 185 193 | 
             
                    end
         | 
| 186 194 | 
             
                  end
         | 
| 187 | 
            -
                  current_patterns | 
| 195 | 
            +
                  current_patterns
         | 
| 188 196 | 
             
                end
         | 
| 189 197 |  | 
| 190 198 | 
             
                # Simple quoting for the default column value
         | 
| @@ -581,8 +589,9 @@ module AnnotateModels | |
| 581 589 | 
             
                end
         | 
| 582 590 |  | 
| 583 591 | 
             
                def matched_types(options)
         | 
| 584 | 
            -
                  types = MATCHED_TYPES
         | 
| 592 | 
            +
                  types = MATCHED_TYPES.dup
         | 
| 585 593 | 
             
                  types << 'admin' if options[:active_admin] =~ TRUE_RE && !types.include?('admin')
         | 
| 594 | 
            +
                  types << 'additional_file_patterns' if options[:additional_file_patterns].present?
         | 
| 586 595 |  | 
| 587 596 | 
             
                  types
         | 
| 588 597 | 
             
                end
         | 
| @@ -634,8 +643,11 @@ module AnnotateModels | |
| 634 643 | 
             
                      end
         | 
| 635 644 |  | 
| 636 645 | 
             
                      next if options[exclusion_key]
         | 
| 637 | 
            -
             | 
| 646 | 
            +
             | 
| 647 | 
            +
                      get_patterns(options, key)
         | 
| 638 648 | 
             
                        .map { |f| resolve_filename(f, model_name, table_name) }
         | 
| 649 | 
            +
                        .map { |f| expand_glob_into_files(f) }
         | 
| 650 | 
            +
                        .flatten
         | 
| 639 651 | 
             
                        .each do |f|
         | 
| 640 652 | 
             
                          if annotate_one_file(f, info, position_key, options_with_position(options, position_key))
         | 
| 641 653 | 
             
                            annotated << f
         | 
| @@ -793,6 +805,10 @@ module AnnotateModels | |
| 793 805 | 
             
                  end
         | 
| 794 806 | 
             
                end
         | 
| 795 807 |  | 
| 808 | 
            +
                def expand_glob_into_files(glob)
         | 
| 809 | 
            +
                  Dir.glob(glob)
         | 
| 810 | 
            +
                end
         | 
| 811 | 
            +
             | 
| 796 812 | 
             
                def annotate_model_file(annotated, file, header, options)
         | 
| 797 813 | 
             
                  begin
         | 
| 798 814 | 
             
                    return false if /#{SKIP_ANNOTATION_PREFIX}.*/ =~ (File.exist?(file) ? File.read(file) : '')
         | 
| @@ -830,7 +846,7 @@ module AnnotateModels | |
| 830 846 | 
             
                        model_file_name = file
         | 
| 831 847 | 
             
                        deannotated_klass = true if remove_annotation_of_file(model_file_name, options)
         | 
| 832 848 |  | 
| 833 | 
            -
                        get_patterns(matched_types(options))
         | 
| 849 | 
            +
                        get_patterns(options, matched_types(options))
         | 
| 834 850 | 
             
                          .map { |f| resolve_filename(f, model_name, table_name) }
         | 
| 835 851 | 
             
                          .each do |f|
         | 
| 836 852 | 
             
                            if File.exist?(f)
         | 
| @@ -910,7 +926,11 @@ module AnnotateModels | |
| 910 926 | 
             
                def mb_chars_ljust(string, length)
         | 
| 911 927 | 
             
                  string = string.to_s
         | 
| 912 928 | 
             
                  padding = length - width(string)
         | 
| 913 | 
            -
                   | 
| 929 | 
            +
                  if padding > 0
         | 
| 930 | 
            +
                    string + (' ' * padding)
         | 
| 931 | 
            +
                  else
         | 
| 932 | 
            +
                    string[0..length-1]
         | 
| 933 | 
            +
                  end
         | 
| 914 934 | 
             
                end
         | 
| 915 935 | 
             
              end
         | 
| 916 936 |  | 
| @@ -10,7 +10,7 @@ | |
| 10 10 | 
             
            # Yes, it's simple but I'm thick and often need a reminder of what my routes
         | 
| 11 11 | 
             
            # mean.
         | 
| 12 12 | 
             
            #
         | 
| 13 | 
            -
            # Running this task will replace any  | 
| 13 | 
            +
            # Running this task will replace any existing route comment generated by the
         | 
| 14 14 | 
             
            # task. Best to back up your routes file before running:
         | 
| 15 15 | 
             
            #
         | 
| 16 16 | 
             
            # Author:
         | 
| @@ -25,14 +25,53 @@ module AnnotateRoutes | |
| 25 25 | 
             
              HEADER_ROW = ['Prefix', 'Verb', 'URI Pattern', 'Controller#Action']
         | 
| 26 26 |  | 
| 27 27 | 
             
              class << self
         | 
| 28 | 
            -
                def  | 
| 29 | 
            -
                  return  | 
| 28 | 
            +
                def do_annotations(options = {})
         | 
| 29 | 
            +
                  return unless routes_exists?
         | 
| 30 | 
            +
                  existing_text = File.read(routes_file)
         | 
| 30 31 |  | 
| 31 | 
            -
                   | 
| 32 | 
            -
                     | 
| 32 | 
            +
                  if rewrite_contents_with_header(existing_text, header(options), options)
         | 
| 33 | 
            +
                    puts "#{routes_file} annotated."
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
                end
         | 
| 33 36 |  | 
| 34 | 
            -
             | 
| 35 | 
            -
                   | 
| 37 | 
            +
                def remove_annotations(_options={})
         | 
| 38 | 
            +
                  return unless routes_exists?
         | 
| 39 | 
            +
                  existing_text = File.read(routes_file)
         | 
| 40 | 
            +
                  content, where_header_found = strip_annotations(existing_text)
         | 
| 41 | 
            +
                  new_content = strip_on_removal(content, where_header_found)
         | 
| 42 | 
            +
                  if rewrite_contents(existing_text, new_content)
         | 
| 43 | 
            +
                    puts "Removed annotations from #{routes_file}."
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                private
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                def routes_exists?
         | 
| 50 | 
            +
                  routes_exists = File.exists?(routes_file)
         | 
| 51 | 
            +
                  puts "Can't find routes.rb" unless routes_exists
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                  routes_exists
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                def routes_file
         | 
| 57 | 
            +
                  @routes_rb ||= File.join('config', 'routes.rb')
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                def rewrite_contents_with_header(existing_text, header, options = {})
         | 
| 61 | 
            +
                  content, where_header_found = strip_annotations(existing_text)
         | 
| 62 | 
            +
                  new_content = annotate_routes(header, content, where_header_found, options)
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                  # Make sure we end on a trailing newline.
         | 
| 65 | 
            +
                  new_content << '' unless new_content.last == ''
         | 
| 66 | 
            +
                  new_text = new_content.join("\n")
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                  if existing_text == new_text
         | 
| 69 | 
            +
                    puts "#{routes_file} unchanged."
         | 
| 70 | 
            +
                    false
         | 
| 71 | 
            +
                  else
         | 
| 72 | 
            +
                    File.open(routes_file, 'wb') { |f| f.puts(new_text) }
         | 
| 73 | 
            +
                    true
         | 
| 74 | 
            +
                  end
         | 
| 36 75 | 
             
                end
         | 
| 37 76 |  | 
| 38 77 | 
             
                def header(options = {})
         | 
| @@ -70,180 +109,143 @@ module AnnotateRoutes | |
| 70 109 | 
             
                  out
         | 
| 71 110 | 
             
                end
         | 
| 72 111 |  | 
| 73 | 
            -
                 | 
| 74 | 
            -
             | 
| 75 | 
            -
             | 
| 76 | 
            -
             | 
| 77 | 
            -
             | 
| 78 | 
            -
             | 
| 112 | 
            +
                # TODO: write the method doc using ruby rdoc formats
         | 
| 113 | 
            +
                # where_header_found => This will either be :before, :after, or
         | 
| 114 | 
            +
                # a number.  If the number is > 0, the
         | 
| 115 | 
            +
                # annotation was found somewhere in the
         | 
| 116 | 
            +
                # middle of the file.  If the number is
         | 
| 117 | 
            +
                # zero, no annotation was found.
         | 
| 118 | 
            +
                def strip_annotations(content)
         | 
| 119 | 
            +
                  real_content = []
         | 
| 120 | 
            +
                  mode = :content
         | 
| 121 | 
            +
                  header_found_at = 0
         | 
| 122 | 
            +
             | 
| 123 | 
            +
                  content.split(/\n/, -1).each_with_index do |line, line_number|
         | 
| 124 | 
            +
                    if mode == :header && line !~ /\s*#/
         | 
| 125 | 
            +
                      mode = :content
         | 
| 126 | 
            +
                      real_content << line unless line.blank?
         | 
| 127 | 
            +
                    elsif mode == :content
         | 
| 128 | 
            +
                      if line =~ /^\s*#\s*== Route.*$/
         | 
| 129 | 
            +
                        header_found_at = line_number + 1 # index start's at 0
         | 
| 130 | 
            +
                        mode = :header
         | 
| 131 | 
            +
                      else
         | 
| 132 | 
            +
                        real_content << line
         | 
| 133 | 
            +
                      end
         | 
| 134 | 
            +
                    end
         | 
| 79 135 | 
             
                  end
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                  where_header_found(real_content, header_found_at)
         | 
| 80 138 | 
             
                end
         | 
| 81 139 |  | 
| 82 | 
            -
                def  | 
| 83 | 
            -
                   | 
| 84 | 
            -
             | 
| 85 | 
            -
                   | 
| 86 | 
            -
             | 
| 87 | 
            -
                  if rewrite_contents(existing_text, new_content)
         | 
| 88 | 
            -
                    puts "Removed annotations from #{routes_file}."
         | 
| 140 | 
            +
                def strip_on_removal(content, where_header_found)
         | 
| 141 | 
            +
                  if where_header_found == :before
         | 
| 142 | 
            +
                    content.shift while content.first == ''
         | 
| 143 | 
            +
                  elsif where_header_found == :after
         | 
| 144 | 
            +
                    content.pop while content.last == ''
         | 
| 89 145 | 
             
                  end
         | 
| 90 | 
            -
                end
         | 
| 91 | 
            -
              end
         | 
| 92 146 |  | 
| 93 | 
            -
             | 
| 94 | 
            -
             | 
| 95 | 
            -
             | 
| 147 | 
            +
                  # TODO: If the user buried it in the middle, we should probably see about
         | 
| 148 | 
            +
                  # TODO: preserving a single line of space between the content above and
         | 
| 149 | 
            +
                  # TODO: below...
         | 
| 150 | 
            +
                  content
         | 
| 151 | 
            +
                end
         | 
| 96 152 |  | 
| 97 | 
            -
             | 
| 98 | 
            -
             | 
| 99 | 
            -
             | 
| 100 | 
            -
             | 
| 101 | 
            -
             | 
| 102 | 
            -
                new_content = []
         | 
| 153 | 
            +
                # @param [String, Array<String>]
         | 
| 154 | 
            +
                def rewrite_contents(existing_text, new_content)
         | 
| 155 | 
            +
                  # Make sure we end on a trailing newline.
         | 
| 156 | 
            +
                  new_content << '' unless new_content.last == ''
         | 
| 157 | 
            +
                  new_text = new_content.join("\n")
         | 
| 103 158 |  | 
| 104 | 
            -
             | 
| 105 | 
            -
             | 
| 106 | 
            -
                     | 
| 159 | 
            +
                  if existing_text == new_text
         | 
| 160 | 
            +
                    puts "#{routes_file} unchanged."
         | 
| 161 | 
            +
                    false
         | 
| 107 162 | 
             
                  else
         | 
| 108 | 
            -
                     | 
| 163 | 
            +
                    File.open(routes_file, 'wb') { |f| f.puts(new_text) }
         | 
| 164 | 
            +
                    true
         | 
| 109 165 | 
             
                  end
         | 
| 110 166 | 
             
                end
         | 
| 111 167 |  | 
| 112 | 
            -
                 | 
| 113 | 
            -
             | 
| 114 | 
            -
             | 
| 115 | 
            -
             | 
| 116 | 
            -
             | 
| 117 | 
            -
             | 
| 118 | 
            -
             | 
| 119 | 
            -
             | 
| 120 | 
            -
             | 
| 121 | 
            -
             | 
| 122 | 
            -
             | 
| 123 | 
            -
                # Skip routes which match given regex
         | 
| 124 | 
            -
                # Note: it matches the complete line (route_name, path, controller/action)
         | 
| 125 | 
            -
                if options[:ignore_routes]
         | 
| 126 | 
            -
                  routes_map.reject! { |line| line =~ /#{options[:ignore_routes]}/ }
         | 
| 127 | 
            -
                end
         | 
| 128 | 
            -
             | 
| 129 | 
            -
                routes_map
         | 
| 130 | 
            -
              end
         | 
| 131 | 
            -
             | 
| 132 | 
            -
              def self.routes_file
         | 
| 133 | 
            -
                @routes_rb ||= File.join('config', 'routes.rb')
         | 
| 134 | 
            -
              end
         | 
| 168 | 
            +
                def annotate_routes(header, content, where_header_found, options = {})
         | 
| 169 | 
            +
                  magic_comments_map, content = extract_magic_comments_from_array(content)
         | 
| 170 | 
            +
                  if %w(before top).include?(options[:position_in_routes])
         | 
| 171 | 
            +
                    header = header << '' if content.first != ''
         | 
| 172 | 
            +
                    magic_comments_map << '' if magic_comments_map.any?
         | 
| 173 | 
            +
                    new_content = magic_comments_map + header + content
         | 
| 174 | 
            +
                  else
         | 
| 175 | 
            +
                    # Ensure we have adequate trailing newlines at the end of the file to
         | 
| 176 | 
            +
                    # ensure a blank line separating the content from the annotation.
         | 
| 177 | 
            +
                    content << '' unless content.last == ''
         | 
| 135 178 |  | 
| 136 | 
            -
             | 
| 137 | 
            -
             | 
| 138 | 
            -
             | 
| 179 | 
            +
                    # We're moving something from the top of the file to the bottom, so ditch
         | 
| 180 | 
            +
                    # the spacer we put in the first time around.
         | 
| 181 | 
            +
                    content.shift if where_header_found == :before && content.first == ''
         | 
| 139 182 |  | 
| 140 | 
            -
             | 
| 141 | 
            -
             | 
| 183 | 
            +
                    new_content = magic_comments_map + content + header
         | 
| 184 | 
            +
                  end
         | 
| 142 185 |  | 
| 143 | 
            -
             | 
| 144 | 
            -
              def self.rewrite_contents(existing_text, new_content)
         | 
| 145 | 
            -
                # Make sure we end on a trailing newline.
         | 
| 146 | 
            -
                new_content << '' unless new_content.last == ''
         | 
| 147 | 
            -
                new_text = new_content.join("\n")
         | 
| 148 | 
            -
             | 
| 149 | 
            -
                if existing_text == new_text
         | 
| 150 | 
            -
                  puts "#{routes_file} unchanged."
         | 
| 151 | 
            -
                  false
         | 
| 152 | 
            -
                else
         | 
| 153 | 
            -
                  File.open(routes_file, 'wb') { |f| f.puts(new_text) }
         | 
| 154 | 
            -
                  true
         | 
| 186 | 
            +
                  new_content
         | 
| 155 187 | 
             
                end
         | 
| 156 | 
            -
              end
         | 
| 157 188 |  | 
| 158 | 
            -
             | 
| 159 | 
            -
             | 
| 160 | 
            -
                new_content = annotate_routes(header, content, where_header_found, options)
         | 
| 189 | 
            +
                def app_routes_map(options)
         | 
| 190 | 
            +
                  routes_map = `rake routes`.chomp("\n").split(/\n/, -1)
         | 
| 161 191 |  | 
| 162 | 
            -
             | 
| 163 | 
            -
             | 
| 164 | 
            -
             | 
| 192 | 
            +
                  # In old versions of Rake, the first line of output was the cwd.  Not so
         | 
| 193 | 
            +
                  # much in newer ones.  We ditch that line if it exists, and if not, we
         | 
| 194 | 
            +
                  # keep the line around.
         | 
| 195 | 
            +
                  routes_map.shift if routes_map.first =~ /^\(in \//
         | 
| 165 196 |  | 
| 166 | 
            -
             | 
| 167 | 
            -
                   | 
| 168 | 
            -
                   | 
| 169 | 
            -
             | 
| 170 | 
            -
                   | 
| 171 | 
            -
                  true
         | 
| 172 | 
            -
                end
         | 
| 173 | 
            -
              end
         | 
| 197 | 
            +
                  # Skip routes which match given regex
         | 
| 198 | 
            +
                  # Note: it matches the complete line (route_name, path, controller/action)
         | 
| 199 | 
            +
                  if options[:ignore_routes]
         | 
| 200 | 
            +
                    routes_map.reject! { |line| line =~ /#{options[:ignore_routes]}/ }
         | 
| 201 | 
            +
                  end
         | 
| 174 202 |  | 
| 175 | 
            -
             | 
| 176 | 
            -
                magic_comments_map, content = extract_magic_comments_from_array(content)
         | 
| 177 | 
            -
                if %w(before top).include?(options[:position_in_routes])
         | 
| 178 | 
            -
                  header = header << '' if content.first != ''
         | 
| 179 | 
            -
                  magic_comments_map << '' if magic_comments_map.any?
         | 
| 180 | 
            -
                  new_content = magic_comments_map + header + content
         | 
| 181 | 
            -
                else
         | 
| 182 | 
            -
                  # Ensure we have adequate trailing newlines at the end of the file to
         | 
| 183 | 
            -
                  # ensure a blank line separating the content from the annotation.
         | 
| 184 | 
            -
                  content << '' unless content.last == ''
         | 
| 185 | 
            -
             | 
| 186 | 
            -
                  # We're moving something from the top of the file to the bottom, so ditch
         | 
| 187 | 
            -
                  # the spacer we put in the first time around.
         | 
| 188 | 
            -
                  content.shift if where_header_found == :before && content.first == ''
         | 
| 189 | 
            -
             | 
| 190 | 
            -
                  new_content = magic_comments_map + content + header
         | 
| 203 | 
            +
                  routes_map
         | 
| 191 204 | 
             
                end
         | 
| 192 205 |  | 
| 193 | 
            -
                 | 
| 194 | 
            -
             | 
| 206 | 
            +
                # @param [Array<String>] content
         | 
| 207 | 
            +
                # @return [Array<String>] all found magic comments
         | 
| 208 | 
            +
                # @return [Array<String>] content without magic comments
         | 
| 209 | 
            +
                def extract_magic_comments_from_array(content_array)
         | 
| 210 | 
            +
                  magic_comments = []
         | 
| 211 | 
            +
                  new_content = []
         | 
| 195 212 |  | 
| 196 | 
            -
             | 
| 197 | 
            -
             | 
| 198 | 
            -
             | 
| 199 | 
            -
              # annotation was found somewhere in the
         | 
| 200 | 
            -
              # middle of the file.  If the number is
         | 
| 201 | 
            -
              # zero, no annotation was found.
         | 
| 202 | 
            -
              def self.strip_annotations(content)
         | 
| 203 | 
            -
                real_content = []
         | 
| 204 | 
            -
                mode = :content
         | 
| 205 | 
            -
                header_found_at = 0
         | 
| 206 | 
            -
             | 
| 207 | 
            -
                content.split(/\n/, -1).each_with_index do |line, line_number|
         | 
| 208 | 
            -
                  if mode == :header && line !~ /\s*#/
         | 
| 209 | 
            -
                    mode = :content
         | 
| 210 | 
            -
                    real_content << line unless line.blank?
         | 
| 211 | 
            -
                  elsif mode == :content
         | 
| 212 | 
            -
                    if line =~ /^\s*#\s*== Route.*$/
         | 
| 213 | 
            -
                      header_found_at = line_number + 1 # index start's at 0
         | 
| 214 | 
            -
                      mode = :header
         | 
| 213 | 
            +
                  content_array.map do |row|
         | 
| 214 | 
            +
                    if row =~ magic_comment_matcher
         | 
| 215 | 
            +
                      magic_comments << row.strip
         | 
| 215 216 | 
             
                    else
         | 
| 216 | 
            -
                       | 
| 217 | 
            +
                      new_content << row
         | 
| 217 218 | 
             
                    end
         | 
| 218 219 | 
             
                  end
         | 
| 220 | 
            +
             | 
| 221 | 
            +
                  [magic_comments, new_content]
         | 
| 219 222 | 
             
                end
         | 
| 220 223 |  | 
| 221 | 
            -
                 | 
| 222 | 
            -
             | 
| 224 | 
            +
                def content(line, maxs, options = {})
         | 
| 225 | 
            +
                  return line.rstrip unless options[:format_markdown]
         | 
| 226 | 
            +
             | 
| 227 | 
            +
                  line.each_with_index.map do |elem, index|
         | 
| 228 | 
            +
                    min_length = maxs.map { |arr| arr[index] }.max || 0
         | 
| 223 229 |  | 
| 224 | 
            -
             | 
| 225 | 
            -
             | 
| 230 | 
            +
                    sprintf("%-#{min_length}.#{min_length}s", elem.tr('|', '-'))
         | 
| 231 | 
            +
                  end.join(' | ')
         | 
| 232 | 
            +
                end
         | 
| 226 233 |  | 
| 227 | 
            -
                 | 
| 228 | 
            -
             | 
| 234 | 
            +
                def where_header_found(real_content, header_found_at)
         | 
| 235 | 
            +
                  # By default assume the annotation was found in the middle of the file
         | 
| 229 236 |  | 
| 230 | 
            -
             | 
| 231 | 
            -
             | 
| 237 | 
            +
                  # ... unless we have evidence it was at the beginning ...
         | 
| 238 | 
            +
                  return real_content, :before if header_found_at == 1
         | 
| 232 239 |  | 
| 233 | 
            -
             | 
| 234 | 
            -
             | 
| 235 | 
            -
              end
         | 
| 240 | 
            +
                  # ... or that it was at the end.
         | 
| 241 | 
            +
                  return real_content, :after if header_found_at >= real_content.count
         | 
| 236 242 |  | 
| 237 | 
            -
             | 
| 238 | 
            -
             | 
| 239 | 
            -
                  content.shift while content.first == ''
         | 
| 240 | 
            -
                elsif where_header_found == :after
         | 
| 241 | 
            -
                  content.pop while content.last == ''
         | 
| 243 | 
            +
                  # and the default
         | 
| 244 | 
            +
                  return real_content, header_found_at
         | 
| 242 245 | 
             
                end
         | 
| 243 246 |  | 
| 244 | 
            -
                 | 
| 245 | 
            -
             | 
| 246 | 
            -
                 | 
| 247 | 
            -
                content
         | 
| 247 | 
            +
                def magic_comment_matcher
         | 
| 248 | 
            +
                  Regexp.new(/(^#\s*encoding:.*)|(^# coding:.*)|(^# -\*- coding:.*)|(^# -\*- encoding\s?:.*)|(^#\s*frozen_string_literal:.+)|(^# -\*- frozen_string_literal\s*:.+-\*-)/)
         | 
| 249 | 
            +
                end
         | 
| 248 250 | 
             
              end
         | 
| 249 251 | 
             
            end
         | 
    
        data/lib/annotate/version.rb
    CHANGED
    
    
| @@ -7,47 +7,49 @@ if Rails.env.development? | |
| 7 7 | 
             
                # You can override any of these by setting an environment variable of the
         | 
| 8 8 | 
             
                # same name.
         | 
| 9 9 | 
             
                Annotate.set_defaults(
         | 
| 10 | 
            -
                  ' | 
| 11 | 
            -
                  ' | 
| 12 | 
            -
                  ' | 
| 13 | 
            -
                  ' | 
| 14 | 
            -
                  ' | 
| 15 | 
            -
                  ' | 
| 16 | 
            -
                  ' | 
| 17 | 
            -
                  ' | 
| 18 | 
            -
                  ' | 
| 19 | 
            -
                  ' | 
| 20 | 
            -
                  ' | 
| 21 | 
            -
                  ' | 
| 22 | 
            -
                  ' | 
| 23 | 
            -
                  ' | 
| 24 | 
            -
                  ' | 
| 25 | 
            -
                  ' | 
| 26 | 
            -
                  ' | 
| 27 | 
            -
                  ' | 
| 28 | 
            -
                  ' | 
| 29 | 
            -
                  ' | 
| 30 | 
            -
                  ' | 
| 31 | 
            -
                  ' | 
| 32 | 
            -
                  ' | 
| 33 | 
            -
                  ' | 
| 34 | 
            -
                  ' | 
| 35 | 
            -
                  ' | 
| 36 | 
            -
                  ' | 
| 37 | 
            -
                  ' | 
| 38 | 
            -
                  ' | 
| 39 | 
            -
                  ' | 
| 40 | 
            -
                  ' | 
| 41 | 
            -
                  ' | 
| 42 | 
            -
                  ' | 
| 43 | 
            -
                  ' | 
| 44 | 
            -
                  ' | 
| 45 | 
            -
                  ' | 
| 46 | 
            -
                  ' | 
| 47 | 
            -
                  ' | 
| 48 | 
            -
                  ' | 
| 49 | 
            -
                  ' | 
| 50 | 
            -
                  ' | 
| 10 | 
            +
                  'additional_file_patterns'    => [],
         | 
| 11 | 
            +
                  'routes'                      => 'false',
         | 
| 12 | 
            +
                  'models'                      => 'false',
         | 
| 13 | 
            +
                  'position_in_routes'          => 'before',
         | 
| 14 | 
            +
                  'position_in_class'           => 'before',
         | 
| 15 | 
            +
                  'position_in_test'            => 'before',
         | 
| 16 | 
            +
                  'position_in_fixture'         => 'before',
         | 
| 17 | 
            +
                  'position_in_factory'         => 'before',
         | 
| 18 | 
            +
                  'position_in_serializer'      => 'before',
         | 
| 19 | 
            +
                  'show_foreign_keys'           => 'true',
         | 
| 20 | 
            +
                  'show_complete_foreign_keys'  => 'false',
         | 
| 21 | 
            +
                  'show_indexes'                => 'true',
         | 
| 22 | 
            +
                  'simple_indexes'              => 'false',
         | 
| 23 | 
            +
                  'model_dir'                   => 'app/models',
         | 
| 24 | 
            +
                  'root_dir'                    => '',
         | 
| 25 | 
            +
                  'include_version'             => 'false',
         | 
| 26 | 
            +
                  'require'                     => '',
         | 
| 27 | 
            +
                  'exclude_tests'               => 'false',
         | 
| 28 | 
            +
                  'exclude_fixtures'            => 'false',
         | 
| 29 | 
            +
                  'exclude_factories'           => 'false',
         | 
| 30 | 
            +
                  'exclude_serializers'         => 'false',
         | 
| 31 | 
            +
                  'exclude_scaffolds'           => 'true',
         | 
| 32 | 
            +
                  'exclude_controllers'         => 'true',
         | 
| 33 | 
            +
                  'exclude_helpers'             => 'true',
         | 
| 34 | 
            +
                  'exclude_sti_subclasses'      => 'false',
         | 
| 35 | 
            +
                  'ignore_model_sub_dir'        => 'false',
         | 
| 36 | 
            +
                  'ignore_columns'              => nil,
         | 
| 37 | 
            +
                  'ignore_routes'               => nil,
         | 
| 38 | 
            +
                  'ignore_unknown_models'       => 'false',
         | 
| 39 | 
            +
                  'hide_limit_column_types'     => '<%= AnnotateModels::NO_LIMIT_COL_TYPES.join(",") %>',
         | 
| 40 | 
            +
                  'hide_default_column_types'   => '<%= AnnotateModels::NO_DEFAULT_COL_TYPES.join(",") %>',
         | 
| 41 | 
            +
                  'skip_on_db_migrate'          => 'false',
         | 
| 42 | 
            +
                  'format_bare'                 => 'true',
         | 
| 43 | 
            +
                  'format_rdoc'                 => 'false',
         | 
| 44 | 
            +
                  'format_markdown'             => 'false',
         | 
| 45 | 
            +
                  'sort'                        => 'false',
         | 
| 46 | 
            +
                  'force'                       => 'false',
         | 
| 47 | 
            +
                  'frozen'                      => 'false',
         | 
| 48 | 
            +
                  'classified_sort'             => 'true',
         | 
| 49 | 
            +
                  'trace'                       => 'false',
         | 
| 50 | 
            +
                  'wrapper_open'                => nil,
         | 
| 51 | 
            +
                  'wrapper_close'               => nil,
         | 
| 52 | 
            +
                  'with_comment'                => 'true'
         | 
| 51 53 | 
             
                )
         | 
| 52 54 | 
             
              end
         | 
| 53 55 |  | 
| @@ -12,6 +12,7 @@ task annotate_models: :environment do | |
| 12 12 |  | 
| 13 13 | 
             
              options = {is_rake: true}
         | 
| 14 14 | 
             
              ENV['position'] = options[:position] = Annotate.fallback(ENV['position'], 'before')
         | 
| 15 | 
            +
              options[:additional_file_patterns] = ENV['additional_file_patterns'] ? ENV['additional_file_patterns'].split(',') : []
         | 
| 15 16 | 
             
              options[:position_in_class] = Annotate.fallback(ENV['position_in_class'], ENV['position'])
         | 
| 16 17 | 
             
              options[:position_in_fixture] = Annotate.fallback(ENV['position_in_fixture'], ENV['position'])
         | 
| 17 18 | 
             
              options[:position_in_factory] = Annotate.fallback(ENV['position_in_factory'], ENV['position'])
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: annotate
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version:  | 
| 4 | 
            +
              version: 3.0.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Alex Chaffee
         | 
| @@ -12,7 +12,7 @@ authors: | |
| 12 12 | 
             
            autorequire: 
         | 
| 13 13 | 
             
            bindir: bin
         | 
| 14 14 | 
             
            cert_chain: []
         | 
| 15 | 
            -
            date: 2019- | 
| 15 | 
            +
            date: 2019-09-27 00:00:00.000000000 Z
         | 
| 16 16 | 
             
            dependencies:
         | 
| 17 17 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 18 18 | 
             
              name: rake
         | 
| @@ -108,7 +108,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 108 108 | 
             
                - !ruby/object:Gem::Version
         | 
| 109 109 | 
             
                  version: '0'
         | 
| 110 110 | 
             
            requirements: []
         | 
| 111 | 
            -
             | 
| 111 | 
            +
            rubyforge_project: 
         | 
| 112 | 
            +
            rubygems_version: 2.7.7
         | 
| 112 113 | 
             
            signing_key: 
         | 
| 113 114 | 
             
            specification_version: 4
         | 
| 114 115 | 
             
            summary: Annotates Rails Models, routes, fixtures, and others based on the database
         |