annotated 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/annotated.rb ADDED
@@ -0,0 +1,147 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ require "annotated/version"
3
+ require "annotated/annotate_models"
4
+ require "annotated/annotate_routes"
5
+ require "annotated/constants"
6
+ require "annotated/helpers"
7
+
8
+ begin
9
+ # ActiveSupport 3.x...
10
+ require "active_support/hash_with_indifferent_access"
11
+ require "active_support/core_ext/object/blank"
12
+ rescue
13
+ # ActiveSupport 2.x...
14
+ require "active_support/core_ext/hash/indifferent_access"
15
+ require "active_support/core_ext/blank"
16
+ end
17
+
18
+ module Annotated
19
+ ##
20
+ # Set default values that can be overridden via environment variables.
21
+ #
22
+ def self.set_defaults(options = {})
23
+ return if @has_set_defaults
24
+ @has_set_defaults = true
25
+
26
+ options = ActiveSupport::HashWithIndifferentAccess.new(options)
27
+
28
+ Constants::ALL_ANNOTATE_OPTIONS.flatten.each do |key|
29
+ if options.key?(key)
30
+ default_value = if options[key].is_a?(Array)
31
+ options[key].join(",")
32
+ else
33
+ options[key]
34
+ end
35
+ end
36
+
37
+ default_value = ENV[key.to_s] unless ENV[key.to_s].blank?
38
+ ENV[key.to_s] = default_value.nil? ? nil : default_value.to_s
39
+ end
40
+ end
41
+
42
+ ##
43
+ # TODO: what is the difference between this and set_defaults?
44
+ #
45
+ def self.setup_options(options = {})
46
+ Constants::POSITION_OPTIONS.each do |key|
47
+ options[key] = Annotated::Helpers.fallback(ENV[key.to_s], ENV["position"], "before")
48
+ end
49
+ Constants::FLAG_OPTIONS.each do |key|
50
+ options[key] = Annotated::Helpers.true?(ENV[key.to_s])
51
+ end
52
+ Constants::OTHER_OPTIONS.each do |key|
53
+ options[key] = (!ENV[key.to_s].blank?) ? ENV[key.to_s] : nil
54
+ end
55
+ Constants::PATH_OPTIONS.each do |key|
56
+ options[key] = (!ENV[key.to_s].blank?) ? ENV[key.to_s].split(",") : []
57
+ end
58
+
59
+ options[:additional_file_patterns] ||= []
60
+ options[:additional_file_patterns] = options[:additional_file_patterns].split(",") if options[:additional_file_patterns].is_a?(String)
61
+ options[:model_dir] = ["app/models"] if options[:model_dir].empty?
62
+
63
+ options[:wrapper_open] ||= options[:wrapper]
64
+ options[:wrapper_close] ||= options[:wrapper]
65
+
66
+ # These were added in 2.7.0 but so this is to revert to old behavior by default
67
+ options[:exclude_scaffolds] = Annotated::Helpers.true?(ENV.fetch("exclude_scaffolds", "true"))
68
+ options[:exclude_controllers] = Annotated::Helpers.true?(ENV.fetch("exclude_controllers", "true"))
69
+ options[:exclude_helpers] = Annotated::Helpers.true?(ENV.fetch("exclude_helpers", "true"))
70
+
71
+ options
72
+ end
73
+
74
+ def self.load_tasks
75
+ return if @tasks_loaded
76
+
77
+ Dir[File.join(File.dirname(__FILE__), "tasks", "**/*.rake")].each do |rake|
78
+ load rake
79
+ end
80
+
81
+ @tasks_loaded = true
82
+ end
83
+
84
+ def self.eager_load(options)
85
+ load_requires(options)
86
+ require "annotated/active_record_patch"
87
+
88
+ if defined?(Rails::Application)
89
+ if Rails.version.split(".").first.to_i < 3
90
+ Rails.configuration.eager_load_paths.each do |load_path|
91
+ matcher = /\A#{Regexp.escape(load_path)}(.*)\.rb\Z/
92
+ Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
93
+ require_dependency file.sub(matcher, '\1')
94
+ end
95
+ end
96
+ else
97
+ klass = Rails::Application.send(:subclasses).first
98
+ klass.eager_load!
99
+ end
100
+ else
101
+ options[:model_dir].each do |dir|
102
+ FileList["#{dir}/**/*.rb"].each do |fname|
103
+ require File.expand_path(fname)
104
+ end
105
+ end
106
+ end
107
+ end
108
+
109
+ def self.bootstrap_rake
110
+ begin
111
+ require "rake/dsl_definition"
112
+ rescue => e
113
+ # We might just be on an old version of Rake...
114
+ warn e.message
115
+ exit e.status_code
116
+ end
117
+ require "rake"
118
+
119
+ load "./Rakefile" if File.exist?("./Rakefile")
120
+ begin
121
+ Rake::Task[:environment].invoke
122
+ rescue
123
+ nil
124
+ end
125
+ unless defined?(Rails)
126
+ # Not in a Rails project, so time to load up the parts of
127
+ # ActiveSupport we need.
128
+ require "active_support"
129
+ require "active_support/core_ext/class/subclasses"
130
+ require "active_support/core_ext/string/inflections"
131
+ end
132
+
133
+ load_tasks
134
+ Rake::Task[:set_annotation_options].invoke
135
+ end
136
+
137
+ class << self
138
+ private
139
+
140
+ def load_requires(options)
141
+ options[:require].count > 0 &&
142
+ options[:require].each { |path| require path }
143
+ end
144
+ end
145
+ end
146
+
147
+ # Annotate = Annotated unless defined?(Annotate)
@@ -0,0 +1,4 @@
1
+ Add a .rake file that automatically annotates models when you do a db:migrate
2
+ in development mode:
3
+
4
+ rails generate annotate:install
@@ -0,0 +1,15 @@
1
+ require "annotate"
2
+
3
+ module Annotated
4
+ module Generators
5
+ class InstallGenerator < Rails::Generators::Base
6
+ desc "Copy annotate_models rakefiles for automatic annotation"
7
+ source_root File.expand_path("templates", __dir__)
8
+
9
+ # copy rake tasks
10
+ def copy_tasks
11
+ template "auto_annotate_models.rake", "lib/tasks/auto_annotate_models.rake"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,61 @@
1
+ # NOTE: only doing this in development as some production environments (Heroku)
2
+ # NOTE: are sensitive to local FS writes, and besides -- it's just not proper
3
+ # NOTE: to have a dev-mode tool do its thing in production.
4
+ if Rails.env.development?
5
+ require "annotate"
6
+ task :set_annotation_options do
7
+ # You can override any of these by setting an environment variable of the
8
+ # same name.
9
+ Annotated.set_defaults(
10
+ "active_admin" => "false",
11
+ "additional_file_patterns" => [],
12
+ "routes" => "false",
13
+ "models" => "true",
14
+ "position_in_routes" => "before",
15
+ "position_in_class" => "before",
16
+ "position_in_test" => "before",
17
+ "position_in_fixture" => "before",
18
+ "position_in_factory" => "before",
19
+ "position_in_serializer" => "before",
20
+ "show_check_constraints" => "false",
21
+ "show_foreign_keys" => "true",
22
+ "show_complete_foreign_keys" => "false",
23
+ "show_indexes" => "true",
24
+ "simple_indexes" => "false",
25
+ "model_dir" => "app/models",
26
+ "root_dir" => "",
27
+ "include_version" => "false",
28
+ "require" => "",
29
+ "exclude_tests" => "false",
30
+ "exclude_fixtures" => "false",
31
+ "exclude_factories" => "false",
32
+ "exclude_serializers" => "false",
33
+ "exclude_scaffolds" => "true",
34
+ "exclude_controllers" => "true",
35
+ "exclude_helpers" => "true",
36
+ "exclude_sti_subclasses" => "false",
37
+ "ignore_model_sub_dir" => "false",
38
+ "ignore_columns" => nil,
39
+ "ignore_routes" => nil,
40
+ "ignore_unknown_models" => "false",
41
+ "hide_limit_column_types" => '<%= AnnotateModels::NO_LIMIT_COL_TYPES.join(",") %>',
42
+ "hide_default_column_types" => '<%= AnnotateModels::NO_DEFAULT_COL_TYPES.join(",") %>',
43
+ "skip_on_db_migrate" => "false",
44
+ "format_bare" => "true",
45
+ "format_rdoc" => "false",
46
+ "format_yard" => "false",
47
+ "format_markdown" => "false",
48
+ "sort" => "false",
49
+ "force" => "false",
50
+ "frozen" => "false",
51
+ "classified_sort" => "true",
52
+ "trace" => "false",
53
+ "wrapper_open" => nil,
54
+ "wrapper_close" => nil,
55
+ "with_comment" => "true",
56
+ "with_comment_column" => "false"
57
+ )
58
+ end
59
+
60
+ Annotated.load_tasks
61
+ end
@@ -0,0 +1,72 @@
1
+ annotate_lib = File.expand_path(File.dirname(__FILE__, 2))
2
+
3
+ unless ENV["is_cli"]
4
+ task :set_annotation_options
5
+ task annotate_models: :set_annotation_options
6
+ end
7
+
8
+ desc "Add schema information (as comments) to model and fixture files"
9
+ task annotate_models: :environment do
10
+ require "#{annotate_lib}/annotated/annotate_models"
11
+ require "#{annotate_lib}/annotated/active_record_patch"
12
+
13
+ options = {is_rake: true}
14
+ ENV["position"] = options[:position] = Annotated::Helpers.fallback(ENV["position"], "before")
15
+ options[:additional_file_patterns] = ENV["additional_file_patterns"] ? ENV["additional_file_patterns"].split(",") : []
16
+ options[:position_in_class] = Annotated::Helpers.fallback(ENV["position_in_class"], ENV["position"])
17
+ options[:position_in_fixture] = Annotated::Helpers.fallback(ENV["position_in_fixture"], ENV["position"])
18
+ options[:position_in_factory] = Annotated::Helpers.fallback(ENV["position_in_factory"], ENV["position"])
19
+ options[:position_in_test] = Annotated::Helpers.fallback(ENV["position_in_test"], ENV["position"])
20
+ options[:position_in_serializer] = Annotated::Helpers.fallback(ENV["position_in_serializer"], ENV["position"])
21
+ options[:show_check_constraints] = Annotated::Helpers.true?(ENV["show_check_constraints"])
22
+ options[:show_foreign_keys] = Annotated::Helpers.true?(ENV["show_foreign_keys"])
23
+ options[:show_complete_foreign_keys] = Annotated::Helpers.true?(ENV["show_complete_foreign_keys"])
24
+ options[:show_indexes] = Annotated::Helpers.true?(ENV["show_indexes"])
25
+ options[:simple_indexes] = Annotated::Helpers.true?(ENV["simple_indexes"])
26
+ options[:model_dir] = ENV["model_dir"] ? ENV["model_dir"].split(",") : ["app/models"]
27
+ options[:root_dir] = ENV["root_dir"]
28
+ options[:include_version] = Annotated::Helpers.true?(ENV["include_version"])
29
+ options[:require] = ENV["require"] ? ENV["require"].split(",") : []
30
+ options[:exclude_tests] = Annotated::Helpers.true?(ENV["exclude_tests"])
31
+ options[:exclude_factories] = Annotated::Helpers.true?(ENV["exclude_factories"])
32
+ options[:exclude_fixtures] = Annotated::Helpers.true?(ENV["exclude_fixtures"])
33
+ options[:exclude_serializers] = Annotated::Helpers.true?(ENV["exclude_serializers"])
34
+ options[:exclude_scaffolds] = Annotated::Helpers.true?(ENV["exclude_scaffolds"])
35
+ options[:exclude_controllers] = Annotated::Helpers.true?(ENV.fetch("exclude_controllers", "true"))
36
+ options[:exclude_helpers] = Annotated::Helpers.true?(ENV.fetch("exclude_helpers", "true"))
37
+ options[:exclude_sti_subclasses] = Annotated::Helpers.true?(ENV["exclude_sti_subclasses"])
38
+ options[:ignore_model_sub_dir] = Annotated::Helpers.true?(ENV["ignore_model_sub_dir"])
39
+ options[:format_bare] = Annotated::Helpers.true?(ENV["format_bare"])
40
+ options[:format_rdoc] = Annotated::Helpers.true?(ENV["format_rdoc"])
41
+ options[:format_yard] = Annotated::Helpers.true?(ENV["format_yard"])
42
+ options[:format_markdown] = Annotated::Helpers.true?(ENV["format_markdown"])
43
+ options[:sort] = Annotated::Helpers.true?(ENV["sort"])
44
+ options[:force] = Annotated::Helpers.true?(ENV["force"])
45
+ options[:frozen] = Annotated::Helpers.true?(ENV["frozen"])
46
+ options[:classified_sort] = Annotated::Helpers.true?(ENV["classified_sort"])
47
+ options[:trace] = Annotated::Helpers.true?(ENV["trace"])
48
+ options[:wrapper_open] = Annotated::Helpers.fallback(ENV["wrapper_open"], ENV["wrapper"])
49
+ options[:wrapper_close] = Annotated::Helpers.fallback(ENV["wrapper_close"], ENV["wrapper"])
50
+ options[:ignore_columns] = ENV.fetch("ignore_columns", nil)
51
+ options[:ignore_routes] = ENV.fetch("ignore_routes", nil)
52
+ options[:hide_limit_column_types] = Annotated::Helpers.fallback(ENV["hide_limit_column_types"], "")
53
+ options[:hide_default_column_types] = Annotated::Helpers.fallback(ENV["hide_default_column_types"], "")
54
+ options[:with_comment] = Annotated::Helpers.true?(ENV["with_comment"])
55
+ options[:with_comment_column] = Annotated::Helpers.true?(ENV["with_comment_column"])
56
+ options[:ignore_unknown_models] = Annotated::Helpers.true?(ENV.fetch("ignore_unknown_models", "false"))
57
+
58
+ AnnotateModels.do_annotations(options)
59
+ end
60
+
61
+ desc "Remove schema information from model and fixture files"
62
+ task remove_annotation: :environment do
63
+ require "#{annotate_lib}/annotated/annotate_models"
64
+ require "#{annotate_lib}/annotated/active_record_patch"
65
+
66
+ options = {is_rake: true}
67
+ options[:model_dir] = ENV["model_dir"]
68
+ options[:root_dir] = ENV["root_dir"]
69
+ options[:require] = ENV["require"] ? ENV["require"].split(",") : []
70
+ options[:trace] = Annotated::Helpers.true?(ENV["trace"])
71
+ AnnotateModels.remove_annotations(options)
72
+ end
@@ -0,0 +1,63 @@
1
+ # These tasks are added to the project if you install annotate as a Rails plugin.
2
+ # (They are not used to build annotate itself.)
3
+
4
+ # Append annotations to Rake tasks for ActiveRecord, so annotate automatically gets
5
+ # run after doing db:migrate.
6
+
7
+ migration_tasks = %w[db:migrate db:migrate:up db:migrate:down db:migrate:reset db:migrate:redo db:rollback]
8
+ if defined?(Rails::Application) && Rails.version.split(".").first.to_i >= 6
9
+ require "active_record"
10
+
11
+ databases = ActiveRecord::Tasks::DatabaseTasks.setup_initial_database_yaml
12
+
13
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |spec_name|
14
+ migration_tasks.concat(%w[db:migrate db:migrate:up db:migrate:down].map { |task| "#{task}:#{spec_name}" })
15
+ end
16
+ end
17
+
18
+ migration_tasks.each do |task|
19
+ next unless Rake::Task.task_defined?(task)
20
+
21
+ Rake::Task[task].enhance do
22
+ Rake::Task[Rake.application.top_level_tasks.last].enhance do
23
+ annotation_options_task = if Rake::Task.task_defined?("app:set_annotation_options")
24
+ "app:set_annotation_options"
25
+ else
26
+ "set_annotation_options"
27
+ end
28
+ Rake::Task[annotation_options_task].invoke
29
+ Annotated::Migration.update_annotations
30
+ end
31
+ end
32
+ end
33
+
34
+ module Annotated
35
+ class Migration
36
+ @@working = false
37
+
38
+ def self.update_annotations
39
+ unless @@working || Annotated::Helpers.skip_on_migration?
40
+ @@working = true
41
+
42
+ update_models if Annotated::Helpers.include_models?
43
+ update_routes if Annotated::Helpers.include_routes?
44
+ end
45
+ end
46
+
47
+ def self.update_models
48
+ if Rake::Task.task_defined?("annotate_models")
49
+ Rake::Task["annotate_models"].invoke
50
+ elsif Rake::Task.task_defined?("app:annotate_models")
51
+ Rake::Task["app:annotate_models"].invoke
52
+ end
53
+ end
54
+
55
+ def self.update_routes
56
+ if Rake::Task.task_defined?("annotate_routes")
57
+ Rake::Task["annotate_routes"].invoke
58
+ elsif Rake::Task.task_defined?("app:annotate_routes")
59
+ Rake::Task["app:annotate_routes"].invoke
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,31 @@
1
+ annotate_lib = File.expand_path(File.dirname(__FILE__, 2))
2
+
3
+ unless ENV["is_cli"]
4
+ task :set_annotation_options
5
+ task annotate_routes: :set_annotation_options
6
+ end
7
+
8
+ desc "Adds the route map to routes.rb"
9
+ task annotate_routes: :environment do
10
+ require "#{annotate_lib}/annotate/annotate_routes"
11
+
12
+ options = {}
13
+ ENV["position"] = options[:position] = Annotated::Helpers.fallback(ENV["position"], "before")
14
+ options[:position_in_routes] = Annotated::Helpers.fallback(ENV["position_in_routes"], ENV["position"])
15
+ options[:ignore_routes] = Annotated::Helpers.fallback(ENV["ignore_routes"], nil)
16
+ options[:require] = ENV["require"] ? ENV["require"].split(",") : []
17
+ options[:frozen] = Annotated::Helpers.true?(ENV["frozen"])
18
+ options[:wrapper_open] = Annotated::Helpers.fallback(ENV["wrapper_open"], ENV["wrapper"])
19
+ options[:wrapper_close] = Annotated::Helpers.fallback(ENV["wrapper_close"], ENV["wrapper"])
20
+ AnnotateRoutes.do_annotations(options)
21
+ end
22
+
23
+ desc "Removes the route map from routes.rb"
24
+ task remove_routes: :environment do
25
+ annotate_lib = File.expand_path(File.dirname(__FILE__, 2))
26
+ require "#{annotate_lib}/annotate/annotate_routes"
27
+
28
+ options = {}
29
+ options[:require] = ENV["require"] ? ENV["require"].split(",") : []
30
+ AnnotateRoutes.remove_annotations(options)
31
+ end
data/potato.md ADDED
@@ -0,0 +1,41 @@
1
+ Colons can be used to align columns.
2
+
3
+ | Tables | Are | Cool |
4
+ | ------------- |:-------------:| -----:|
5
+ | col 3 is | right-aligned | $1600 |
6
+ | col 2 is | centered | $12 |
7
+ | zebra stripes | are neat | $1 |
8
+
9
+ There must be at least 3 dashes separating each header cell.
10
+ The outer pipes (|) are optional, and you don't need to make the
11
+ raw Markdown line up prettily. You can also use inline Markdown.
12
+
13
+ Markdown | Less | Pretty
14
+ --- | --- | ---
15
+ *Still* | `renders` | **nicely**
16
+ 1 | 2 | 3
17
+
18
+
19
+ ## Route Map
20
+
21
+  Prefix | Verb | URI Pattern | Controller#Action
22
+ --------- | ---------- | --------------- | --------------------
23
+ myaction1 | GET | /url1(.:format) | mycontroller1#action
24
+ myaction2 | POST | /url2(.:format) | mycontroller2#action
25
+  myaction3 | DELETE-GET | /url3(.:format) | mycontroller3#action \n")
26
+
27
+
28
+
29
+ Table name: `users`
30
+
31
+ ### Columns
32
+
33
+ Name | Type | Attributes
34
+ ----------------------- | ------------------ | ---------------------------
35
+ **`id`** | `integer` | `not null, primary key`
36
+ **`foreign_thing_id`** | `integer` | `not null`
37
+
38
+ ### Foreign Keys
39
+
40
+ * `fk_rails_...` (_ON DELETE => on_delete_value ON UPDATE => on_update_value_):
41
+ * **`foreign_thing_id => foreign_things.id`**
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: annotated
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Stefan Froelich
8
+ - Alex Chaffee
9
+ - Cuong Tran
10
+ - Marcos Piccinini
11
+ - Turadg Aleahmad
12
+ - Jon Frisby
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+ date: 2025-01-11 00:00:00.000000000 Z
17
+ dependencies:
18
+ - !ruby/object:Gem::Dependency
19
+ name: activerecord
20
+ requirement: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: '3.2'
25
+ type: :runtime
26
+ prerelease: false
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: '3.2'
32
+ description: Annotates Rails/ActiveRecord Models, routes, fixtures, and others based
33
+ on the database schema.
34
+ email:
35
+ - sfroelich01@gmail.com
36
+ - alex@stinky.com
37
+ - cuong.tran@gmail.com
38
+ - x@nofxx.com
39
+ - turadg@aleahmad.net
40
+ - jon@cloudability.com
41
+ executables:
42
+ - annotated
43
+ extensions: []
44
+ extra_rdoc_files: []
45
+ files:
46
+ - AUTHORS.md
47
+ - CHANGELOG.md
48
+ - LICENSE.txt
49
+ - README.md
50
+ - RELEASE.md
51
+ - annotated.gemspec
52
+ - bin/annotated
53
+ - lib/annotated.rb
54
+ - lib/annotated/active_record_patch.rb
55
+ - lib/annotated/annotate_models.rb
56
+ - lib/annotated/annotate_models/file_patterns.rb
57
+ - lib/annotated/annotate_routes.rb
58
+ - lib/annotated/annotate_routes/header_generator.rb
59
+ - lib/annotated/annotate_routes/helpers.rb
60
+ - lib/annotated/constants.rb
61
+ - lib/annotated/helpers.rb
62
+ - lib/annotated/parser.rb
63
+ - lib/annotated/tasks.rb
64
+ - lib/annotated/version.rb
65
+ - lib/generators/annotate/USAGE
66
+ - lib/generators/annotate/install_generator.rb
67
+ - lib/generators/annotate/templates/auto_annotate_models.rake
68
+ - lib/tasks/annotate_models.rake
69
+ - lib/tasks/annotate_models_migrate.rake
70
+ - lib/tasks/annotate_routes.rake
71
+ - potato.md
72
+ homepage: https://github.com/thedumbtechguy/annotated
73
+ licenses:
74
+ - Ruby
75
+ metadata:
76
+ homepage_uri: https://github.com/thedumbtechguy/annotated
77
+ bug_tracker_uri: https://github.com/thedumbtechguy/annotated/issues
78
+ documentation_uri: https://github.com/thedumbtechguy/annotated
79
+ source_code_uri: https://github.com/thedumbtechguy/annotated
80
+ changelog_uri: https://github.com/thedumbtechguy/annotated/blob/master/CHANGELOG.md
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '3.2'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubygems_version: 3.5.16
97
+ signing_key:
98
+ specification_version: 4
99
+ summary: Annotates Rails Models, routes, fixtures, and others based on the database
100
+ schema.
101
+ test_files: []