bullet_train-super_scaffolding 1.0.1 → 1.0.5

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