bullet_train-super_scaffolding 1.0.1 → 1.0.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 70a403bf2e245f8843548f1f20f0cccaa3195b4d2f26aa9e3977a7b134bbfbdc
4
- data.tar.gz: f0afe6854f9f764a8c100f3022ec013d11fd51a3011c8b1ebe4831049fa5b710
3
+ metadata.gz: 718da72ec75872187974897a5213689485797049c7ebdf1ddb564a30163cc3b1
4
+ data.tar.gz: 0d19c7282a403fee1baa0fb1c3c8e45cc72defe674ce58243099ea00aa245fff
5
5
  SHA512:
6
- metadata.gz: b935a5defa4a2417f61f4772f9e7539dd724196a6cafcce299a035c827d7675e45523b551b80479d6041191adce72a15c1ba999977d56695bb77de4b602e8225
7
- data.tar.gz: a045389719135c5d40416b2afcf59240b5db456c7b415e7adfcf6bd8f0aaeb3b893269bbcd741d279e16289d853a806c7a23735cd0146a00b5bb8602eff6d48c
6
+ metadata.gz: b5034959fedec36b6c8312e64ed757f25834399744d69f95a5dfb84f5f88b01b1e7bff080a0161048ae4ab8140147c4c818edd7e49356b424cbc2326940ad970
7
+ data.tar.gz: d1ddfc16f3035831d95531bb2ca8fa62b88d413c4aba4f181703f2e6d1c0d02fe37edf48c6313da8d5e35525a20b1d236d48cd69f774e12bd9507e7f9507b971
@@ -0,0 +1,13 @@
1
+ module BulletTrain
2
+ module SuperScaffolding
3
+ class Scaffolder
4
+ attr_accessor :argv
5
+
6
+ def initialize(argv, options)
7
+ # Just setting these like this so the code we moved around still runs.
8
+ self.argv = argv
9
+ @options = options
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,44 @@
1
+ module BulletTrain
2
+ module SuperScaffolding
3
+ module Scaffolders
4
+ class CrudFieldScaffolder < Scaffolder
5
+ def run
6
+ unless argv.count >= 2
7
+ puts ""
8
+ puts "🚅 usage: bin/super-scaffold crud-field <Model> <attribute:type> <attribute:type> ... [options]"
9
+ puts ""
10
+ puts "E.g. add a description and body to Pages:"
11
+ puts " rails g migration add_description_etc_to_pages description:text body:text"
12
+ puts " bin/super-scaffold crud-field Page description:text body:text"
13
+ puts ""
14
+ puts "Options:"
15
+ puts ""
16
+ puts " --skip-table: Only add to the new/edit form and show view."
17
+ puts ""
18
+ exit
19
+ end
20
+
21
+ # We pass this value to parents to create a new Scaffolding::Transformer because
22
+ # we don't actually need knowledge of the parent to add the new field.
23
+ parents = [""]
24
+ child = argv[0]
25
+
26
+ # get all the attributes.
27
+ attributes = argv[1..-1]
28
+
29
+ check_required_options_for_attributes('crud-field', attributes, child)
30
+
31
+ transformer = Scaffolding::Transformer.new(child, parents, @options)
32
+ transformer.add_attributes_to_various_views(attributes, type: :crud_field)
33
+
34
+ transformer.additional_steps.uniq.each_with_index do |additional_step, index|
35
+ color, message = additional_step
36
+ puts ""
37
+ puts "#{index + 1}. #{message}".send(color)
38
+ end
39
+ puts ""
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,65 @@
1
+ module BulletTrain
2
+ module SuperScaffolding
3
+ module Scaffolders
4
+ class CrudScaffolder < Scaffolder
5
+ def run
6
+ unless argv.count >= 3
7
+ puts ""
8
+ puts "🚅 usage: bin/super-scaffold crud <Model> <ParentModel[s]> <attribute:type> <attribute:type> ..."
9
+ puts ""
10
+ puts "E.g. a Team has many Sites with some attributes:"
11
+ puts " rails g model Site team:references name:string url:text"
12
+ puts " bin/super-scaffold crud Site Team name:string url:text"
13
+ puts ""
14
+ puts "E.g. a Section belongs to a Page, which belongs to a Site, which belongs to a Team:"
15
+ puts " rails g model Section page:references title:text body:text"
16
+ puts " bin/super-scaffold crud Section Page,Site,Team title:text body:text"
17
+ puts ""
18
+ puts "E.g. an Image belongs to either a Page or a Site:"
19
+ puts " Doable! See https://bit.ly/2NvO8El for a step by step guide."
20
+ puts ""
21
+ puts "E.g. Pages belong to a Site and are sortable via drag-and-drop:"
22
+ puts " rails g model Page site:references name:string path:text"
23
+ puts " bin/super-scaffold crud Page Site,Team name:text path:text --sortable"
24
+ puts ""
25
+ puts "🏆 Protip: Commit your other changes before running Super Scaffolding so it's easy to undo if you (or we) make any mistakes."
26
+ puts "If you do that, you can reset to your last commit state by using `git checkout .` and `git clean -d -f` ."
27
+ puts ""
28
+ puts "Give it a shot! Let us know if you have any trouble with it! ✌️"
29
+ puts ""
30
+ exit
31
+ end
32
+
33
+ child = argv[0]
34
+ parents = argv[1] ? argv[1].split(",") : []
35
+ parents = parents.map(&:classify).uniq
36
+ parent = parents.first
37
+
38
+ unless parents.include?("Team")
39
+ raise "Parents for #{child} should trace back to the Team model, but Team wasn't provided. Please confirm that all of the parents tracing back to the Team model are present and try again.\n" +
40
+ "E.g.:\n" +
41
+ "rails g model Section page:references title:text body:text\n" +
42
+ "bin/super-scaffold crud Section Page,Site,Team title:text body:text\n"
43
+ end
44
+
45
+ # get all the attributes.
46
+ attributes = argv[2..-1]
47
+
48
+ check_required_options_for_attributes('crud', attributes, child, parent)
49
+
50
+ binding.pry
51
+
52
+ transformer = Scaffolding::Transformer.new(child, parents, @options)
53
+ transformer.scaffold_crud(attributes)
54
+
55
+ transformer.additional_steps.each_with_index do |additional_step, index|
56
+ color, message = additional_step
57
+ puts ""
58
+ puts "#{index + 1}. #{message}".send(color)
59
+ end
60
+ puts ""
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,96 @@
1
+ module BulletTrain
2
+ module SuperScaffolding
3
+ module Scaffolders
4
+ class JoinModelScaffolder < Scaffolder
5
+ def run
6
+ unless argv.count >= 3
7
+ puts ""
8
+ puts "🚅 usage: bin/super-scaffold join-model <JoinModel> <left_association> <right_association>"
9
+ puts ""
10
+ puts "E.g. Add project-specific tags to a project:"
11
+ puts ""
12
+ puts " Given the following example models:".blue
13
+ puts ""
14
+ puts " rails g model Project team:references name:string description:text"
15
+ puts " bin/super-scaffold crud Project Team name:text_field description:trix_editor"
16
+ puts ""
17
+ puts " rails g model Projects::Tag team:references name:string"
18
+ puts " bin/super-scaffold crud Projects::Tag Team name:text_field"
19
+ puts ""
20
+ puts " 1️⃣ Use the standard Rails model generator to generate the join model:".blue
21
+ puts ""
22
+ puts " rails g model Projects::AppliedTag project:references tag:references"
23
+ puts ""
24
+ puts " 👋 Don't run migrations yet! Sometimes Super Scaffolding updates them for you.".yellow
25
+ puts ""
26
+ puts " 2️⃣ Use `join-model` scaffolding to prepare the join model for use in `crud-field` scaffolding:".blue
27
+ puts ""
28
+ puts " bin/super-scaffold join-model Projects::AppliedTag project_id[class_name=Project] tag_id[class_name=Projects::Tag]"
29
+ puts ""
30
+ puts " 3️⃣ Now you can use `crud-field` scaffolding to actually add the field to the form of the parent model:".blue
31
+ puts ""
32
+ puts " bin/super-scaffold crud-field Project tag_ids:super_select[class_name=Projects::Tag]"
33
+ puts ""
34
+ puts " 👋 Heads up! There will be one follow-up step output by this command that you need to take action on."
35
+ puts ""
36
+ puts " 4️⃣ Now you can run your migrations.".blue
37
+ exit
38
+ end
39
+
40
+ child = argv[0]
41
+ primary_parent = argv[1].split("class_name=").last.split(",").first.split("]").first
42
+ secondary_parent = argv[2].split("class_name=").last.split(",").first.split("]").first
43
+
44
+ # There should only be two attributes.
45
+ attributes = [argv[1], argv[2]]
46
+
47
+ # Pretend we're doing a `super_select` scaffolding because it will do the correct thing.
48
+ attributes = attributes.map { |attribute| attribute.gsub("\[", ":super_select\[") }
49
+ attributes = attributes.map { |attribute| attribute.gsub("\]", ",required\]") }
50
+
51
+ transformer = Scaffolding::Transformer.new(child, [primary_parent], @options)
52
+
53
+ # We need this transformer to reflect on the class names _just_ between e.g. `Project` and `Projects::Tag`, without the join model.
54
+ has_many_through_transformer = Scaffolding::Transformer.new(secondary_parent, [primary_parent], @options)
55
+
56
+ # We need this transformer to reflect on the association between `Projects::Tag` and `Projects::AppliedTag` backwards.
57
+ inverse_transformer = Scaffolding::Transformer.new(child, [secondary_parent], @options)
58
+
59
+ # We need this transformer to reflect on the class names _just_ between e.g. `Projects::Tag` and `Project`, without the join model.
60
+ inverse_has_many_through_transformer = Scaffolding::Transformer.new(primary_parent, [secondary_parent], @options)
61
+
62
+ # However, for the first attribute, we actually don't need the scope validator (and can't really implement it).
63
+ attributes[0] = attributes[0].gsub("\]", ",unscoped\]")
64
+
65
+ has_many_through_association = has_many_through_transformer.transform_string("completely_concrete_tangible_things")
66
+ source = transformer.transform_string("absolutely_abstract_creative_concept.valid_$HAS_MANY_THROUGH_ASSOCIATION")
67
+ source.gsub!("$HAS_MANY_THROUGH_ASSOCIATION", has_many_through_association)
68
+
69
+ # For the second one, we don't want users to have to define the list of valid options in the join model, so we do this:
70
+ attributes[1] = attributes[1].gsub("\]", ",source=#{source}\]")
71
+
72
+ # This model hasn't been crud scaffolded, so a bunch of views are skipped here, but that's OK!
73
+ # It does what we need on the files that exist.
74
+ transformer.add_scaffolding_hooks_to_model
75
+
76
+ transformer.suppress_could_not_find = true
77
+ transformer.add_attributes_to_various_views(attributes, type: :crud_field)
78
+ transformer.suppress_could_not_find = false
79
+
80
+ # Add the `has_many ... through:` association in both directions.
81
+ transformer.add_has_many_through_associations(has_many_through_transformer)
82
+ inverse_transformer.add_has_many_through_associations(inverse_has_many_through_transformer)
83
+
84
+ additional_steps = (transformer.additional_steps + has_many_through_transformer.additional_steps + inverse_transformer.additional_steps + inverse_has_many_through_transformer.additional_steps).uniq
85
+
86
+ additional_steps.each_with_index do |additional_step, index|
87
+ color, message = additional_step
88
+ puts ""
89
+ puts "#{index + 1}. #{message}".send(color)
90
+ end
91
+ puts ""
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,173 @@
1
+ module BulletTrain
2
+ module SuperScaffolding
3
+ module Scaffolders
4
+ class OauthProviderScaffolder < Scaffolder
5
+ def run
6
+ unless argv.count >= 5
7
+ puts ""
8
+ puts "🚅 usage: bin/super-scaffold oauth-provider <omniauth_gem> <gems_provider_name> <our_provider_name> <PROVIDER_API_KEY_IN_ENV> <PROVIDER_API_SECRET_IN_ENV> [options]"
9
+ puts ""
10
+ puts "E.g. what we'd do to start Stripe off (if we didn't already do it):"
11
+ puts " bin/super-scaffold oauth-provider omniauth-stripe-connect stripe_connect Oauth::StripeAccount STRIPE_CLIENT_ID STRIPE_SECRET_KEY --icon=ti-money"
12
+ puts ""
13
+ puts "E.g. what we actually did to start Shopify off:"
14
+ puts " bin/super-scaffold oauth-provider omniauth-shopify-oauth2 shopify Oauth::ShopifyAccount SHOPIFY_API_KEY SHOPIFY_API_SECRET_KEY --icon=ti-shopping-cart"
15
+ puts ""
16
+ puts "Options:"
17
+ puts ""
18
+ puts " --icon={ti-*}: Specify an icon."
19
+ puts ""
20
+ puts "For a list of readily available provider strategies, see https://github.com/omniauth/omniauth/wiki/List-of-Strategies ."
21
+ puts ""
22
+ exit
23
+ end
24
+
25
+ _, omniauth_gem, gems_provider_name, our_provider_name, api_key, api_secret = *ARGV
26
+
27
+ unless match = our_provider_name.match(/Oauth::(.*)Account/)
28
+ puts "\n🚨 Your provider name must match the pattern of `Oauth::{Name}Account`, e.g. `Oauth::StripeAccount`\n".red
29
+ return
30
+ end
31
+
32
+ options = {
33
+ omniauth_gem: omniauth_gem,
34
+ gems_provider_name: gems_provider_name,
35
+ our_provider_name: match[1],
36
+ api_key: api_key,
37
+ api_secret: api_secret
38
+ }
39
+
40
+ unless File.exist?(oauth_transform_string("./app/models/oauth/stripe_account.rb", options)) &&
41
+ File.exist?(oauth_transform_string("./app/models/integrations/stripe_installation.rb", options)) &&
42
+ File.exist?(oauth_transform_string("./app/models/webhooks/incoming/oauth/stripe_account_webhook.rb", options))
43
+ puts ""
44
+ puts oauth_transform_string("🚨 Before doing the actual Super Scaffolding, you'll need to generate the models like so:", options).red
45
+ puts ""
46
+ puts oauth_transform_string(" rails g model Oauth::StripeAccount uid:string data:jsonb user:references", options).red
47
+ puts oauth_transform_string(" rails g model Integrations::StripeInstallation team:references oauth_stripe_account:references name:string", options).red
48
+ puts oauth_transform_string(" rails g model Webhooks::Incoming::Oauth::StripeAccountWebhook data:jsonb processed_at:datetime verified_at:datetime oauth_stripe_account:references", options).red
49
+ puts ""
50
+ puts "However, don't do the `rake db:migrate` until after you re-run Super Scaffolding, as it will need to update some settings in those migrations.".red
51
+ puts ""
52
+ return
53
+ end
54
+
55
+ icon_name = nil
56
+ if @options["icon"].present?
57
+ icon_name = @options["icon"]
58
+ else
59
+ puts "OK, great! Let's do this! By default providers will appear with a dollar symbol,"
60
+ puts "but after you hit enter I'll open a page where you can view other icon options."
61
+ puts "When you find one you like, hover your mouse over it and then come back here and"
62
+ puts "and enter the name of the icon you want to use."
63
+ response = STDIN.gets.chomp
64
+ `open http://light.pinsupreme.com/icon_fonts_themefy.html`
65
+ puts ""
66
+ puts "Did you find an icon you wanted to use? Enter the name here or hit enter to just"
67
+ puts "use the dollar symbol:"
68
+ icon_name = STDIN.gets.chomp
69
+ puts ""
70
+ unless icon_name.length > 0 || icon_name.downcase == "y"
71
+ icon_name = "icon-puzzle"
72
+ end
73
+ end
74
+
75
+ options[:icon] = icon_name
76
+
77
+ [
78
+
79
+ # User OAuth.
80
+ "./app/models/oauth/stripe_account.rb",
81
+ "./app/models/webhooks/incoming/oauth/stripe_account_webhook.rb",
82
+ "./app/controllers/account/oauth/stripe_accounts_controller.rb",
83
+ "./app/controllers/webhooks/incoming/oauth/stripe_account_webhooks_controller.rb",
84
+ "./app/views/account/oauth/stripe_accounts",
85
+ "./test/models/oauth/stripe_account_test.rb",
86
+ "./test/factories/oauth/stripe_accounts.rb",
87
+ "./config/locales/en/oauth/stripe_accounts.en.yml",
88
+ "./app/views/devise/shared/oauth/_stripe.html.erb",
89
+
90
+ # Team Integration.
91
+ "./app/models/integrations/stripe_installation.rb",
92
+ # './app/serializers/api/v1/integrations/stripe_installation_serializer.rb',
93
+ "./app/controllers/account/integrations/stripe_installations_controller.rb",
94
+ "./app/views/account/integrations/stripe_installations",
95
+ "./test/models/integrations/stripe_installation_test.rb",
96
+ "./test/factories/integrations/stripe_installations.rb",
97
+ "./config/locales/en/integrations/stripe_installations.en.yml",
98
+
99
+ # Webhook.
100
+ "./app/models/webhooks/incoming/oauth/stripe_account_webhook.rb",
101
+ "./app/controllers/webhooks/incoming/oauth/stripe_account_webhooks_controller.rb"
102
+
103
+ ].each do |name|
104
+ if File.directory?(name)
105
+ oauth_scaffold_directory(name, options)
106
+ else
107
+ oauth_scaffold_file(name, options)
108
+ end
109
+ end
110
+
111
+ oauth_scaffold_add_line_to_file("./app/views/devise/shared/_oauth.html.erb", "<%= render 'devise/shared/oauth/stripe', verb: verb if stripe_enabled? %>", "<%# 🚅 super scaffolding will insert new oauth providers above this line. %>", options, prepend: true)
112
+ oauth_scaffold_add_line_to_file("./app/views/account/users/edit.html.erb", "<%= render 'account/oauth/stripe_accounts/index', context: @user, stripe_accounts: @user.oauth_stripe_accounts if stripe_enabled? %>", "<% # 🚅 super scaffolding will insert new oauth providers above this line. %>", options, prepend: true)
113
+ oauth_scaffold_add_line_to_file("./config/initializers/devise.rb", "config.omniauth :stripe_connect, ENV['STRIPE_CLIENT_ID'], ENV['STRIPE_SECRET_KEY'], {\n ## specify options for your oauth provider here, e.g.:\n # scope: 'read_products,read_orders,write_content',\n }\n", "# 🚅 super scaffolding will insert new oauth providers above this line.", options, prepend: true)
114
+ oauth_scaffold_add_line_to_file("./app/controllers/account/oauth/omniauth_callbacks_controller.rb", "def stripe_connect\n callback(\"Stripe\", team_id_from_env)\n end\n", "# 🚅 super scaffolding will insert new oauth providers above this line.", options, prepend: true)
115
+ oauth_scaffold_add_line_to_file("./app/models/team.rb", "has_many :integrations_stripe_installations, class_name: 'Integrations::StripeInstallation', dependent: :destroy if stripe_enabled?", "# 🚅 add oauth providers above.", options, prepend: true)
116
+ oauth_scaffold_add_line_to_file("./app/models/user.rb", "has_many :oauth_stripe_accounts, class_name: 'Oauth::StripeAccount' if stripe_enabled?", "# 🚅 add oauth providers above.", options, prepend: true)
117
+ oauth_scaffold_add_line_to_file("./config/locales/en/oauth.en.yml", "stripe_connect: Stripe", "# 🚅 super scaffolding will insert new oauth providers above this line.", options, prepend: true)
118
+ oauth_scaffold_add_line_to_file("./app/views/account/shared/_menu.html.erb", "<%= render 'account/integrations/stripe_installations/menu_item' if stripe_enabled? %>", "<%# 🚅 super scaffolding will insert new oauth providers above this line. %>", options, prepend: true)
119
+ oauth_scaffold_add_line_to_file("./config/routes.rb", "resources :stripe_account_webhooks if stripe_enabled?", "# 🚅 super scaffolding will insert new oauth provider webhooks above this line.", options, prepend: true)
120
+ oauth_scaffold_add_line_to_file("./config/routes.rb", "resources :stripe_accounts if stripe_enabled?", "# 🚅 super scaffolding will insert new oauth providers above this line.", options, prepend: true)
121
+ oauth_scaffold_add_line_to_file("./config/routes.rb", "resources :stripe_installations if stripe_enabled?", "# 🚅 super scaffolding will insert new integration installations above this line.", options, prepend: true)
122
+ oauth_scaffold_add_line_to_file("./Gemfile", "gem 'omniauth-stripe-connect'", "# 🚅 super scaffolding will insert new oauth providers above this line.", options, prepend: true)
123
+ oauth_scaffold_add_line_to_file("./lib/bullet_train.rb", "def stripe_enabled?\n ENV['STRIPE_CLIENT_ID'].present? && ENV['STRIPE_SECRET_KEY'].present?\nend\n", "# 🚅 super scaffolding will insert new oauth providers above this line.", options, prepend: true)
124
+ oauth_scaffold_add_line_to_file("./lib/bullet_train.rb", "stripe_enabled?,", "# 🚅 super scaffolding will insert new oauth provider checks above this line.", options, prepend: true)
125
+ oauth_scaffold_add_line_to_file("./app/models/ability.rb", "if stripe_enabled?
126
+ can [:read, :create, :destroy], Oauth::StripeAccount, user_id: user.id
127
+ can :manage, Integrations::StripeInstallation, team_id: user.team_ids
128
+ can :destroy, Integrations::StripeInstallation, oauth_stripe_account: {user_id: user.id}
129
+ end
130
+ ", "# 🚅 super scaffolding will insert any new oauth providers above.", options, prepend: true)
131
+
132
+ # find the database migration that defines this relationship.
133
+ migration_file_name = `grep "create_table #{oauth_transform_string(":oauth_stripe_accounts", options)}" db/migrate/*`.split(":").first
134
+ legacy_replace_in_file(migration_file_name, "null: false", "null: true")
135
+
136
+ migration_file_name = `grep "create_table #{oauth_transform_string(":integrations_stripe_installations", options)}" db/migrate/*`.split(":").first
137
+ legacy_replace_in_file(migration_file_name,
138
+ oauth_transform_string("t.references :oauth_stripe_account, null: false, foreign_key: true", options),
139
+ oauth_transform_string('t.references :oauth_stripe_account, null: false, foreign_key: true, index: {name: "index_stripe_installations_on_oauth_stripe_account_id"}', options))
140
+
141
+ migration_file_name = `grep "create_table #{oauth_transform_string(":webhooks_incoming_oauth_stripe_account_webhooks", options)}" db/migrate/*`.split(":").first
142
+ legacy_replace_in_file(migration_file_name, "null: false", "null: true")
143
+ legacy_replace_in_file(migration_file_name, "foreign_key: true", 'foreign_key: true, index: {name: "index_stripe_webhooks_on_oauth_stripe_account_id"}')
144
+
145
+ puts ""
146
+ puts "🎉"
147
+ puts ""
148
+ puts "You'll probably need to `bundle install`.".green
149
+ puts ""
150
+ puts "If the OAuth provider asks you for some whitelisted callback URLs, the URL structure for those is as so:"
151
+ puts ""
152
+ path = "users/auth/stripe_connect/callback"
153
+ puts oauth_transform_string(" https://yourdomain.co/#{path}", options)
154
+ puts oauth_transform_string(" https://yourtunnel.ngrok.io/#{path}", options)
155
+ puts oauth_transform_string(" http://localhost:3000/#{path}", options)
156
+ puts ""
157
+ puts "If you're able to specify an endpoint to receive webhooks from this provider, use this URL:"
158
+ puts ""
159
+ path = "webhooks/incoming/oauth/stripe_account_webhooks"
160
+ puts oauth_transform_string(" https://yourdomain.co/#{path}", options)
161
+ puts oauth_transform_string(" https://yourtunnel.ngrok.io/#{path}", options)
162
+ puts oauth_transform_string(" http://localhost:3000/#{path}", options)
163
+ puts ""
164
+ puts ""
165
+ puts "If you'd like to edit how your Bullet Train application refers to this provider, just edit the locale file at `config/locales/en/oauth.en.yml`."
166
+ puts ""
167
+ puts "And finally, if you need to specify any custom authorizations or options for your OAuth integration with this provider, you can configure those in `config/initializers/devise.rb`."
168
+ puts ""
169
+ end
170
+ end
171
+ end
172
+ end
173
+ end
@@ -1,5 +1,5 @@
1
1
  module BulletTrain
2
2
  module SuperScaffolding
3
- VERSION = "1.0.1"
3
+ VERSION = "1.0.5"
4
4
  end
5
5
  end
@@ -1,8 +1,26 @@
1
1
  require "bullet_train/super_scaffolding/version"
2
2
  require "bullet_train/super_scaffolding/engine"
3
+ require "bullet_train/super_scaffolding/scaffolder"
4
+ require "bullet_train/super_scaffolding/scaffolders/crud_scaffolder"
5
+ require "bullet_train/super_scaffolding/scaffolders/crud_field_scaffolder"
6
+ require "bullet_train/super_scaffolding/scaffolders/join_model_scaffolder"
7
+ require "bullet_train/super_scaffolding/scaffolders/oauth_provider_scaffolder"
3
8
 
4
9
  module BulletTrain
5
10
  module SuperScaffolding
6
- # Your code goes here...
11
+ mattr_accessor :template_paths, default: []
12
+ mattr_accessor :scaffolders, default: {
13
+ "crud" => "BulletTrain::SuperScaffolding::Scaffolders::CrudScaffolder",
14
+ "crud-field" => "BulletTrain::SuperScaffolding::Scaffolders::CrudFieldScaffolder",
15
+ "join-model" => "BulletTrain::SuperScaffolding::Scaffolders::JoinModelScaffolder",
16
+ "oauth-provider" => "BulletTrain::SuperScaffolding::Scaffolders::OauthProviderScaffolder",
17
+ }
18
+
19
+ class Runner
20
+ def run
21
+ # Make `rake` invocation compatible with how this was run historically.
22
+ require "scaffolding/script"
23
+ end
24
+ end
7
25
  end
8
26
  end
@@ -1,3 +1,57 @@
1
+ def legacy_replace_in_file(file, before, after)
2
+ puts "Replacing in '#{file}'."
3
+ target_file_content = File.read(file)
4
+ target_file_content.gsub!(before, after)
5
+ File.write(file, target_file_content)
6
+ end
7
+
8
+ def legacy_add_line_to_file(file, content, hook, child, parent, options = {})
9
+ increase_indent = options[:increase_indent]
10
+ add_before = options[:add_before]
11
+ add_after = options[:add_after]
12
+
13
+ transformed_file_name = file
14
+ transformed_content = content
15
+ transform_hook = hook
16
+
17
+ target_file_content = File.read(transformed_file_name)
18
+
19
+ if target_file_content.include?(transformed_content)
20
+ puts "No need to update '#{transformed_file_name}'. It already has '#{transformed_content}'."
21
+ else
22
+ new_target_file_content = []
23
+ target_file_content.split("\n").each do |line|
24
+ if /#{Regexp.escape(transform_hook)}\s*$/.match?(line)
25
+
26
+ if add_before
27
+ new_target_file_content << "#{line} #{add_before}"
28
+ else
29
+ unless options[:prepend]
30
+ new_target_file_content << line
31
+ end
32
+ end
33
+
34
+ # get leading whitespace.
35
+ line =~ /^(\s*).*#{Regexp.escape(transform_hook)}.*/
36
+ leading_whitespace = $1
37
+ new_target_file_content << "#{leading_whitespace}#{" " if increase_indent}#{transformed_content}"
38
+
39
+ new_target_file_content << "#{leading_whitespace}#{add_after}" if add_after
40
+
41
+ if options[:prepend]
42
+ new_target_file_content << line
43
+ end
44
+ else
45
+ new_target_file_content << line
46
+ end
47
+ end
48
+
49
+ puts "Updating '#{transformed_file_name}'."
50
+
51
+ File.write(transformed_file_name, new_target_file_content.join("\n") + "\n")
52
+ end
53
+ end
54
+
1
55
  def encode_double_replacement_fix(string)
2
56
  string.chars.join("~!@BT@!~")
3
57
  end
@@ -1,71 +1,11 @@
1
- require "active_support/inflector"
2
- require "fileutils"
3
- require "pry"
4
- require "colorize"
5
- require "scaffolding"
6
- require "#{APP_ROOT}/config/initializers/inflections"
7
-
8
- # TODO This is a hack to allow Super Scaffolding modules to register their path. We'll do this differently once we've
9
- # properly migrated all the code into the Rails engine structure and Rails is being initialized as part of
10
- # `bin/super-scaffold`.
11
- $super_scaffolding_template_paths ||= []
12
-
13
1
  # TODO these methods were removed from the global scope in super scaffolding and moved to `Scaffolding::Transformer`,
14
2
  # but oauth provider scaffolding hasn't been updated yet.
15
3
 
16
- def legacy_replace_in_file(file, before, after)
17
- puts "Replacing in '#{file}'."
18
- target_file_content = File.read(file)
19
- target_file_content.gsub!(before, after)
20
- File.write(file, target_file_content)
21
- end
22
-
23
- def legacy_add_line_to_file(file, content, hook, child, parent, options = {})
24
- increase_indent = options[:increase_indent]
25
- add_before = options[:add_before]
26
- add_after = options[:add_after]
27
-
28
- transformed_file_name = file
29
- transformed_content = content
30
- transform_hook = hook
31
-
32
- target_file_content = File.read(transformed_file_name)
33
-
34
- if target_file_content.include?(transformed_content)
35
- puts "No need to update '#{transformed_file_name}'. It already has '#{transformed_content}'."
36
- else
37
- new_target_file_content = []
38
- target_file_content.split("\n").each do |line|
39
- if /#{Regexp.escape(transform_hook)}\s*$/.match?(line)
40
-
41
- if add_before
42
- new_target_file_content << "#{line} #{add_before}"
43
- else
44
- unless options[:prepend]
45
- new_target_file_content << line
46
- end
47
- end
48
-
49
- # get leading whitespace.
50
- line =~ /^(\s*).*#{Regexp.escape(transform_hook)}.*/
51
- leading_whitespace = $1
52
- new_target_file_content << "#{leading_whitespace}#{" " if increase_indent}#{transformed_content}"
53
-
54
- new_target_file_content << "#{leading_whitespace}#{add_after}" if add_after
55
-
56
- if options[:prepend]
57
- new_target_file_content << line
58
- end
59
- else
60
- new_target_file_content << line
61
- end
62
- end
63
-
64
- puts "Updating '#{transformed_file_name}'."
65
-
66
- File.write(transformed_file_name, new_target_file_content.join("\n") + "\n")
67
- end
68
- end
4
+ require "scaffolding"
5
+ require "scaffolding/transformer"
6
+ require "scaffolding/class_names_transformer"
7
+ require "scaffolding/oauth_providers"
8
+ require "scaffolding/routes_file_manipulator"
69
9
 
70
10
  # filter out options.
71
11
  argv = []
@@ -83,6 +23,11 @@ ARGV.each do |arg|
83
23
  end
84
24
  end
85
25
 
26
+ def standard_protip
27
+ puts "🏆 Protip: Commit your other changes before running Super Scaffolding so it's easy to undo if you (or we) make any mistakes."
28
+ puts "If you do that, you can reset to your last commit state by using `git checkout .` and `git clean -d -f` ."
29
+ end
30
+
86
31
  def check_required_options_for_attributes(scaffolding_type, attributes, child, parent = nil)
87
32
  attributes.each do |attribute|
88
33
  parts = attribute.split(":")
@@ -137,11 +82,9 @@ def show_usage
137
82
  puts ""
138
83
  puts "Supported types of scaffolding:"
139
84
  puts ""
140
- puts " crud"
141
- puts " crud-field"
142
- puts " join-model"
143
- puts " oauth-provider"
144
- puts " breadcrumbs"
85
+ BulletTrain::SuperScaffolding.scaffolders.each do |key, _|
86
+ puts " #{key}"
87
+ end
145
88
  puts ""
146
89
  puts "Try \`bin/super-scaffold [type]` for usage examples.".blue
147
90
  puts ""
@@ -150,394 +93,16 @@ end
150
93
  # grab the _type_ of scaffold we're doing.
151
94
  scaffolding_type = argv.shift
152
95
 
153
- # if we're doing the classic super scaffolding ..
154
- if scaffolding_type == "crud"
155
-
156
- unless argv.count >= 3
157
- puts ""
158
- puts "🚅 usage: bin/super-scaffold crud <Model> <ParentModel[s]> <attribute:type> <attribute:type> ..."
159
- puts ""
160
- puts "E.g. a Team has many Sites with some attributes:"
161
- puts " rails g model Site team:references name:string url:text"
162
- puts " bin/super-scaffold crud Site Team name:string url:text"
163
- puts ""
164
- puts "E.g. a Section belongs to a Page, which belongs to a Site, which belongs to a Team:"
165
- puts " rails g model Section page:references title:text body:text"
166
- puts " bin/super-scaffold crud Section Page,Site,Team title:text body:text"
167
- puts ""
168
- puts "E.g. an Image belongs to either a Page or a Site:"
169
- puts " Doable! See https://bit.ly/2NvO8El for a step by step guide."
170
- puts ""
171
- puts "E.g. Pages belong to a Site and are sortable via drag-and-drop:"
172
- puts " rails g model Page site:references name:string path:text"
173
- puts " bin/super-scaffold crud Page Site,Team name:text path:text --sortable"
174
- puts ""
175
- puts "🏆 Protip: Commit your other changes before running Super Scaffolding so it's easy to undo if you (or we) make any mistakes."
176
- puts "If you do that, you can reset to your last commit state by using `git checkout .` and `git clean -d -f` ."
177
- puts ""
178
- puts "Give it a shot! Let us know if you have any trouble with it! ✌️"
179
- puts ""
180
- exit
181
- end
182
-
183
- child = argv[0]
184
- parents = argv[1] ? argv[1].split(",") : []
185
- parents = parents.map(&:classify).uniq
186
- parent = parents.first
187
-
188
- unless parents.include?("Team")
189
- raise "Parents for #{child} should trace back to the Team model, but Team wasn't provided. Please confirm that all of the parents tracing back to the Team model are present and try again.\n" +
190
- "E.g.:\n" +
191
- "rails g model Section page:references title:text body:text\n" +
192
- "bin/super-scaffold crud Section Page,Site,Team title:text body:text\n"
193
- end
194
-
195
- # get all the attributes.
196
- attributes = argv[2..-1]
197
-
198
- check_required_options_for_attributes(scaffolding_type, attributes, child, parent)
199
-
200
- transformer = Scaffolding::Transformer.new(child, parents, @options)
201
- transformer.scaffold_crud(attributes)
202
-
203
- transformer.additional_steps.each_with_index do |additional_step, index|
204
- color, message = additional_step
205
- puts ""
206
- puts "#{index + 1}. #{message}".send(color)
207
- end
208
- puts ""
209
-
210
- elsif scaffolding_type == "crud-field"
211
-
212
- unless argv.count >= 2
213
- puts ""
214
- puts "🚅 usage: bin/super-scaffold crud-field <Model> <attribute:type> <attribute:type> ... [options]"
215
- puts ""
216
- puts "E.g. add a description and body to Pages:"
217
- puts " rails g migration add_description_etc_to_pages description:text body:text"
218
- puts " bin/super-scaffold crud-field Page description:text body:text"
219
- puts ""
220
- puts "Options:"
221
- puts ""
222
- puts " --skip-table: Only add to the new/edit form and show view."
223
- puts ""
224
- exit
225
- end
226
-
227
- # We pass this value to parents to create a new Scaffolding::Transformer because
228
- # we don't actually need knowledge of the parent to add the new field.
229
- parents = [""]
230
- child = argv[0]
231
-
232
- # get all the attributes.
233
- attributes = argv[1..-1]
234
-
235
- check_required_options_for_attributes(scaffolding_type, attributes, child)
236
-
237
- transformer = Scaffolding::Transformer.new(child, parents, @options)
238
- transformer.add_attributes_to_various_views(attributes, type: :crud_field)
239
-
240
- transformer.additional_steps.uniq.each_with_index do |additional_step, index|
241
- color, message = additional_step
242
- puts ""
243
- puts "#{index + 1}. #{message}".send(color)
244
- end
245
- puts ""
246
-
247
- elsif scaffolding_type == "join-model"
248
-
249
- unless argv.count >= 3
250
- puts ""
251
- puts "🚅 usage: bin/super-scaffold join-model <JoinModel> <left_association> <right_association>"
252
- puts ""
253
- puts "E.g. Add project-specific tags to a project:"
254
- puts ""
255
- puts " Given the following example models:".blue
256
- puts ""
257
- puts " rails g model Project team:references name:string description:text"
258
- puts " bin/super-scaffold crud Project Team name:text_field description:trix_editor"
259
- puts ""
260
- puts " rails g model Projects::Tag team:references name:string"
261
- puts " bin/super-scaffold crud Projects::Tag Team name:text_field"
262
- puts ""
263
- puts " 1️⃣ Use the standard Rails model generator to generate the join model:".blue
264
- puts ""
265
- puts " rails g model Projects::AppliedTag project:references tag:references"
266
- puts ""
267
- puts " 👋 Don't run migrations yet! Sometimes Super Scaffolding updates them for you.".yellow
268
- puts ""
269
- puts " 2️⃣ Use `join-model` scaffolding to prepare the join model for use in `crud-field` scaffolding:".blue
270
- puts ""
271
- puts " bin/super-scaffold join-model Projects::AppliedTag project_id[class_name=Project] tag_id[class_name=Projects::Tag]"
272
- puts ""
273
- puts " 3️⃣ Now you can use `crud-field` scaffolding to actually add the field to the form of the parent model:".blue
274
- puts ""
275
- puts " bin/super-scaffold crud-field Project tag_ids:super_select[class_name=Projects::Tag]"
276
- puts ""
277
- puts " 👋 Heads up! There will be one follow-up step output by this command that you need to take action on."
278
- puts ""
279
- puts " 4️⃣ Now you can run your migrations.".blue
280
- exit
281
- end
282
-
283
- child = argv[0]
284
- primary_parent = argv[1].split("class_name=").last.split(",").first.split("]").first
285
- secondary_parent = argv[2].split("class_name=").last.split(",").first.split("]").first
286
-
287
- # There should only be two attributes.
288
- attributes = [argv[1], argv[2]]
289
-
290
- # Pretend we're doing a `super_select` scaffolding because it will do the correct thing.
291
- attributes = attributes.map { |attribute| attribute.gsub("\[", ":super_select\[") }
292
- attributes = attributes.map { |attribute| attribute.gsub("\]", ",required\]") }
293
-
294
- transformer = Scaffolding::Transformer.new(child, [primary_parent], @options)
295
-
296
- # We need this transformer to reflect on the class names _just_ between e.g. `Project` and `Projects::Tag`, without the join model.
297
- has_many_through_transformer = Scaffolding::Transformer.new(secondary_parent, [primary_parent], @options)
298
-
299
- # We need this transformer to reflect on the association between `Projects::Tag` and `Projects::AppliedTag` backwards.
300
- inverse_transformer = Scaffolding::Transformer.new(child, [secondary_parent], @options)
301
-
302
- # We need this transformer to reflect on the class names _just_ between e.g. `Projects::Tag` and `Project`, without the join model.
303
- inverse_has_many_through_transformer = Scaffolding::Transformer.new(primary_parent, [secondary_parent], @options)
304
-
305
- # However, for the first attribute, we actually don't need the scope validator (and can't really implement it).
306
- attributes[0] = attributes[0].gsub("\]", ",unscoped\]")
307
-
308
- has_many_through_association = has_many_through_transformer.transform_string("completely_concrete_tangible_things")
309
- source = transformer.transform_string("absolutely_abstract_creative_concept.valid_$HAS_MANY_THROUGH_ASSOCIATION")
310
- source.gsub!("$HAS_MANY_THROUGH_ASSOCIATION", has_many_through_association)
311
-
312
- # For the second one, we don't want users to have to define the list of valid options in the join model, so we do this:
313
- attributes[1] = attributes[1].gsub("\]", ",source=#{source}\]")
314
-
315
- # This model hasn't been crud scaffolded, so a bunch of views are skipped here, but that's OK!
316
- # It does what we need on the files that exist.
317
- transformer.add_scaffolding_hooks_to_model
318
-
319
- transformer.suppress_could_not_find = true
320
- transformer.add_attributes_to_various_views(attributes, type: :crud_field)
321
- transformer.suppress_could_not_find = false
322
-
323
- # Add the `has_many ... through:` association in both directions.
324
- transformer.add_has_many_through_associations(has_many_through_transformer)
325
- inverse_transformer.add_has_many_through_associations(inverse_has_many_through_transformer)
326
-
327
- additional_steps = (transformer.additional_steps + has_many_through_transformer.additional_steps + inverse_transformer.additional_steps + inverse_has_many_through_transformer.additional_steps).uniq
328
-
329
- additional_steps.each_with_index do |additional_step, index|
330
- color, message = additional_step
331
- puts ""
332
- puts "#{index + 1}. #{message}".send(color)
333
- end
334
- puts ""
335
-
336
- elsif scaffolding_type == "breadcrumbs"
337
-
338
- unless argv.count == 2
339
- puts ""
340
- puts "🚅 usage: bin/super-scaffold breadcrumbs <Model> <ParentModel[s]>"
341
- puts ""
342
- puts "Heads up! You only need to use this if you generated your views before the new Bullet Train breadcrumbs implementation came into effect.".green
343
- puts ""
344
- puts "E.g. create updated breadcrumbs for Pages:"
345
- puts " bin/super-scaffold breadcrumbs Page Site,Team"
346
- puts ""
347
- puts "When Super Scaffolding breadcrumbs, you have to specify the entire path of the immediate parent back to Team."
348
- puts ""
349
- exit
350
- end
351
-
352
- child = argv[0]
353
- parents = argv[1] ? argv[1].split(",") : []
354
- parents = parents.map(&:classify).uniq
355
- parent = parents.first
356
-
357
- unless parents.include?("Team")
358
- raise "Parents for #{child} should trace back to the Team model, but Team wasn't provided. Please confirm that all of the parents tracing back to the Team model are present and try again.\n" +
359
- "E.g.:\n" +
360
- "bin/super-scaffold breadcrumbs Page Site,Team\n"
361
- end
362
-
363
- # get all the attributes.
364
- transformer = Scaffolding::Transformer.new(child, parents, @options)
365
- transformer.scaffold_new_breadcrumbs(child, parents)
366
-
367
- elsif scaffolding_type == "oauth-provider"
368
-
369
- unless argv.count >= 5
370
- puts ""
371
- puts "🚅 usage: bin/super-scaffold oauth-provider <omniauth_gem> <gems_provider_name> <our_provider_name> <PROVIDER_API_KEY_IN_ENV> <PROVIDER_API_SECRET_IN_ENV> [options]"
372
- puts ""
373
- puts "E.g. what we'd do to start Stripe off (if we didn't already do it):"
374
- puts " bin/super-scaffold oauth-provider omniauth-stripe-connect stripe_connect Oauth::StripeAccount STRIPE_CLIENT_ID STRIPE_SECRET_KEY --icon=ti-money"
375
- puts ""
376
- puts "E.g. what we actually did to start Shopify off:"
377
- puts " bin/super-scaffold oauth-provider omniauth-shopify-oauth2 shopify Oauth::ShopifyAccount SHOPIFY_API_KEY SHOPIFY_API_SECRET_KEY --icon=ti-shopping-cart"
378
- puts ""
379
- puts "Options:"
380
- puts ""
381
- puts " --icon={ti-*}: Specify an icon."
382
- puts ""
383
- puts "For a list of readily available provider strategies, see https://github.com/omniauth/omniauth/wiki/List-of-Strategies ."
384
- puts ""
385
- exit
386
- end
387
-
388
- _, omniauth_gem, gems_provider_name, our_provider_name, api_key, api_secret = *ARGV
389
-
390
- unless match = our_provider_name.match(/Oauth::(.*)Account/)
391
- puts "\n🚨 Your provider name must match the pattern of `Oauth::{Name}Account`, e.g. `Oauth::StripeAccount`\n".red
392
- return
393
- end
394
-
395
- options = {
396
- omniauth_gem: omniauth_gem,
397
- gems_provider_name: gems_provider_name,
398
- our_provider_name: match[1],
399
- api_key: api_key,
400
- api_secret: api_secret
401
- }
402
-
403
- unless File.exist?(oauth_transform_string("./app/models/oauth/stripe_account.rb", options)) &&
404
- File.exist?(oauth_transform_string("./app/models/integrations/stripe_installation.rb", options)) &&
405
- File.exist?(oauth_transform_string("./app/models/webhooks/incoming/oauth/stripe_account_webhook.rb", options))
406
- puts ""
407
- puts oauth_transform_string("🚨 Before doing the actual Super Scaffolding, you'll need to generate the models like so:", options).red
408
- puts ""
409
- puts oauth_transform_string(" rails g model Oauth::StripeAccount uid:string data:jsonb user:references", options).red
410
- puts oauth_transform_string(" rails g model Integrations::StripeInstallation team:references oauth_stripe_account:references name:string", options).red
411
- puts oauth_transform_string(" rails g model Webhooks::Incoming::Oauth::StripeAccountWebhook data:jsonb processed_at:datetime verified_at:datetime oauth_stripe_account:references", options).red
412
- puts ""
413
- puts "However, don't do the `rake db:migrate` until after you re-run Super Scaffolding, as it will need to update some settings in those migrations.".red
414
- puts ""
415
- return
416
- end
417
-
418
- icon_name = nil
419
- if @options["icon"].present?
420
- icon_name = @options["icon"]
421
- else
422
- puts "OK, great! Let's do this! By default providers will appear with a dollar symbol,"
423
- puts "but after you hit enter I'll open a page where you can view other icon options."
424
- puts "When you find one you like, hover your mouse over it and then come back here and"
425
- puts "and enter the name of the icon you want to use."
426
- response = STDIN.gets.chomp
427
- `open http://light.pinsupreme.com/icon_fonts_themefy.html`
428
- puts ""
429
- puts "Did you find an icon you wanted to use? Enter the name here or hit enter to just"
430
- puts "use the dollar symbol:"
431
- icon_name = STDIN.gets.chomp
432
- puts ""
433
- unless icon_name.length > 0 || icon_name.downcase == "y"
434
- icon_name = "icon-puzzle"
435
- end
436
- end
437
-
438
- options[:icon] = icon_name
439
-
440
- [
441
-
442
- # User OAuth.
443
- "./app/models/oauth/stripe_account.rb",
444
- "./app/models/webhooks/incoming/oauth/stripe_account_webhook.rb",
445
- "./app/controllers/account/oauth/stripe_accounts_controller.rb",
446
- "./app/controllers/webhooks/incoming/oauth/stripe_account_webhooks_controller.rb",
447
- "./app/views/account/oauth/stripe_accounts",
448
- "./test/models/oauth/stripe_account_test.rb",
449
- "./test/factories/oauth/stripe_accounts.rb",
450
- "./config/locales/en/oauth/stripe_accounts.en.yml",
451
- "./app/views/devise/shared/oauth/_stripe.html.erb",
452
-
453
- # Team Integration.
454
- "./app/models/integrations/stripe_installation.rb",
455
- # './app/serializers/api/v1/integrations/stripe_installation_serializer.rb',
456
- "./app/controllers/account/integrations/stripe_installations_controller.rb",
457
- "./app/views/account/integrations/stripe_installations",
458
- "./test/models/integrations/stripe_installation_test.rb",
459
- "./test/factories/integrations/stripe_installations.rb",
460
- "./config/locales/en/integrations/stripe_installations.en.yml",
461
-
462
- # Webhook.
463
- "./app/models/webhooks/incoming/oauth/stripe_account_webhook.rb",
464
- "./app/controllers/webhooks/incoming/oauth/stripe_account_webhooks_controller.rb"
465
-
466
- ].each do |name|
467
- if File.directory?(name)
468
- oauth_scaffold_directory(name, options)
469
- else
470
- oauth_scaffold_file(name, options)
471
- end
472
- end
473
-
474
- oauth_scaffold_add_line_to_file("./app/views/devise/shared/_oauth.html.erb", "<%= render 'devise/shared/oauth/stripe', verb: verb if stripe_enabled? %>", "<%# 🚅 super scaffolding will insert new oauth providers above this line. %>", options, prepend: true)
475
- oauth_scaffold_add_line_to_file("./app/views/account/users/edit.html.erb", "<%= render 'account/oauth/stripe_accounts/index', context: @user, stripe_accounts: @user.oauth_stripe_accounts if stripe_enabled? %>", "<% # 🚅 super scaffolding will insert new oauth providers above this line. %>", options, prepend: true)
476
- oauth_scaffold_add_line_to_file("./config/initializers/devise.rb", "config.omniauth :stripe_connect, ENV['STRIPE_CLIENT_ID'], ENV['STRIPE_SECRET_KEY'], {\n ## specify options for your oauth provider here, e.g.:\n # scope: 'read_products,read_orders,write_content',\n }\n", "# 🚅 super scaffolding will insert new oauth providers above this line.", options, prepend: true)
477
- oauth_scaffold_add_line_to_file("./app/controllers/account/oauth/omniauth_callbacks_controller.rb", "def stripe_connect\n callback(\"Stripe\", team_id_from_env)\n end\n", "# 🚅 super scaffolding will insert new oauth providers above this line.", options, prepend: true)
478
- oauth_scaffold_add_line_to_file("./app/models/team.rb", "has_many :integrations_stripe_installations, class_name: 'Integrations::StripeInstallation', dependent: :destroy if stripe_enabled?", "# 🚅 add oauth providers above.", options, prepend: true)
479
- oauth_scaffold_add_line_to_file("./app/models/user.rb", "has_many :oauth_stripe_accounts, class_name: 'Oauth::StripeAccount' if stripe_enabled?", "# 🚅 add oauth providers above.", options, prepend: true)
480
- oauth_scaffold_add_line_to_file("./config/locales/en/oauth.en.yml", "stripe_connect: Stripe", "# 🚅 super scaffolding will insert new oauth providers above this line.", options, prepend: true)
481
- oauth_scaffold_add_line_to_file("./app/views/account/shared/_menu.html.erb", "<%= render 'account/integrations/stripe_installations/menu_item' if stripe_enabled? %>", "<%# 🚅 super scaffolding will insert new oauth providers above this line. %>", options, prepend: true)
482
- oauth_scaffold_add_line_to_file("./config/routes.rb", "resources :stripe_account_webhooks if stripe_enabled?", "# 🚅 super scaffolding will insert new oauth provider webhooks above this line.", options, prepend: true)
483
- oauth_scaffold_add_line_to_file("./config/routes.rb", "resources :stripe_accounts if stripe_enabled?", "# 🚅 super scaffolding will insert new oauth providers above this line.", options, prepend: true)
484
- oauth_scaffold_add_line_to_file("./config/routes.rb", "resources :stripe_installations if stripe_enabled?", "# 🚅 super scaffolding will insert new integration installations above this line.", options, prepend: true)
485
- oauth_scaffold_add_line_to_file("./Gemfile", "gem 'omniauth-stripe-connect'", "# 🚅 super scaffolding will insert new oauth providers above this line.", options, prepend: true)
486
- oauth_scaffold_add_line_to_file("./lib/bullet_train.rb", "def stripe_enabled?\n ENV['STRIPE_CLIENT_ID'].present? && ENV['STRIPE_SECRET_KEY'].present?\nend\n", "# 🚅 super scaffolding will insert new oauth providers above this line.", options, prepend: true)
487
- oauth_scaffold_add_line_to_file("./lib/bullet_train.rb", "stripe_enabled?,", "# 🚅 super scaffolding will insert new oauth provider checks above this line.", options, prepend: true)
488
- oauth_scaffold_add_line_to_file("./app/models/ability.rb", "if stripe_enabled?
489
- can [:read, :create, :destroy], Oauth::StripeAccount, user_id: user.id
490
- can :manage, Integrations::StripeInstallation, team_id: user.team_ids
491
- can :destroy, Integrations::StripeInstallation, oauth_stripe_account: {user_id: user.id}
492
- end
493
- ", "# 🚅 super scaffolding will insert any new oauth providers above.", options, prepend: true)
494
-
495
- # find the database migration that defines this relationship.
496
- migration_file_name = `grep "create_table #{oauth_transform_string(":oauth_stripe_accounts", options)}" db/migrate/*`.split(":").first
497
- legacy_replace_in_file(migration_file_name, "null: false", "null: true")
498
-
499
- migration_file_name = `grep "create_table #{oauth_transform_string(":integrations_stripe_installations", options)}" db/migrate/*`.split(":").first
500
- legacy_replace_in_file(migration_file_name,
501
- oauth_transform_string("t.references :oauth_stripe_account, null: false, foreign_key: true", options),
502
- oauth_transform_string('t.references :oauth_stripe_account, null: false, foreign_key: true, index: {name: "index_stripe_installations_on_oauth_stripe_account_id"}', options))
503
-
504
- migration_file_name = `grep "create_table #{oauth_transform_string(":webhooks_incoming_oauth_stripe_account_webhooks", options)}" db/migrate/*`.split(":").first
505
- legacy_replace_in_file(migration_file_name, "null: false", "null: true")
506
- legacy_replace_in_file(migration_file_name, "foreign_key: true", 'foreign_key: true, index: {name: "index_stripe_webhooks_on_oauth_stripe_account_id"}')
507
-
508
- puts ""
509
- puts "🎉"
510
- puts ""
511
- puts "You'll probably need to `bundle install`.".green
512
- puts ""
513
- puts "If the OAuth provider asks you for some whitelisted callback URLs, the URL structure for those is as so:"
514
- puts ""
515
- path = "users/auth/stripe_connect/callback"
516
- puts oauth_transform_string(" https://yourdomain.co/#{path}", options)
517
- puts oauth_transform_string(" https://yourtunnel.ngrok.io/#{path}", options)
518
- puts oauth_transform_string(" http://localhost:3000/#{path}", options)
519
- puts ""
520
- puts "If you're able to specify an endpoint to receive webhooks from this provider, use this URL:"
521
- puts ""
522
- path = "webhooks/incoming/oauth/stripe_account_webhooks"
523
- puts oauth_transform_string(" https://yourdomain.co/#{path}", options)
524
- puts oauth_transform_string(" https://yourtunnel.ngrok.io/#{path}", options)
525
- puts oauth_transform_string(" http://localhost:3000/#{path}", options)
526
- puts ""
527
- puts ""
528
- puts "If you'd like to edit how your Bullet Train application refers to this provider, just edit the locale file at `config/locales/en/oauth.en.yml`."
529
- puts ""
530
- puts "And finally, if you need to specify any custom authorizations or options for your OAuth integration with this provider, you can configure those in `config/initializers/devise.rb`."
531
- puts ""
532
-
96
+ if BulletTrain::SuperScaffolding.scaffolders.include?(scaffolding_type)
97
+ scaffolder = BulletTrain::SuperScaffolding.scaffolders[scaffolding_type].constantize
98
+ scaffolder.new(argv, @options).run
533
99
  elsif argv.count > 1
534
-
535
100
  puts ""
536
101
  puts "👋"
537
102
  puts "The command line options for Super Scaffolding have changed slightly:".yellow
538
103
  puts "To use the original Super Scaffolding that you know and love, use the `crud` option.".yellow
539
- show_usage
540
104
 
105
+ show_usage
541
106
  else
542
107
  if ARGV.first.present?
543
108
  puts ""
@@ -111,7 +111,8 @@ class Scaffolding::Transformer
111
111
  # Originally all the potential source files were in the repository alongside the application.
112
112
  # Now the files could be provided by an included Ruby gem, so we allow those Ruby gems to register their base
113
113
  # path and then we check them in order to see which template we should use.
114
- $super_scaffolding_template_paths.reverse.map do |base_path|
114
+ BulletTrain::SuperScaffolding.template_paths.reverse.map do |base_path|
115
+ base_path = Pathname.new(base_path)
115
116
  resolved_path = base_path.join(file).to_s
116
117
  File.exists?(resolved_path) ? resolved_path : file
117
118
  end.compact.first
data/lib/scaffolding.rb CHANGED
@@ -1,7 +1,2 @@
1
1
  module Scaffolding
2
2
  end
3
-
4
- require_relative "scaffolding/oauth_providers"
5
- require_relative "scaffolding/transformer"
6
- require_relative "scaffolding/class_names_transformer"
7
- require_relative "scaffolding/routes_file_manipulator"
@@ -1,4 +1,12 @@
1
- # desc "Explaining what the task does"
2
- # task :bullet_train_super_scaffolding do
3
- # # Task goes here
4
- # end
1
+ namespace :bullet_train do
2
+ desc "Next-level code generation"
3
+ task :super_scaffolding, [:all_options] => :environment do |t, arguments|
4
+ ARGV.pop while ARGV.any?
5
+
6
+ arguments[:all_options]&.split&.each do |argument|
7
+ ARGV.push(argument)
8
+ end
9
+
10
+ BulletTrain::SuperScaffolding::Runner.new.run
11
+ end
12
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bullet_train-super_scaffolding
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Culver
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-01 00:00:00.000000000 Z
11
+ date: 2022-02-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 7.0.0
19
+ version: 6.0.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 7.0.0
26
+ version: 6.0.0
27
27
  description: Bullet Train Super Scaffolding
28
28
  email:
29
29
  - andrew.culver@gmail.com
@@ -38,6 +38,11 @@ files:
38
38
  - config/routes.rb
39
39
  - lib/bullet_train/super_scaffolding.rb
40
40
  - lib/bullet_train/super_scaffolding/engine.rb
41
+ - lib/bullet_train/super_scaffolding/scaffolder.rb
42
+ - lib/bullet_train/super_scaffolding/scaffolders/crud_field_scaffolder.rb
43
+ - lib/bullet_train/super_scaffolding/scaffolders/crud_scaffolder.rb
44
+ - lib/bullet_train/super_scaffolding/scaffolders/join_model_scaffolder.rb
45
+ - lib/bullet_train/super_scaffolding/scaffolders/oauth_provider_scaffolder.rb
41
46
  - lib/bullet_train/super_scaffolding/version.rb
42
47
  - lib/scaffolding.rb
43
48
  - lib/scaffolding/class_names_transformer.rb