next_rails_scaffold 0.4.1 → 0.4.3

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: 7cfc0dd5220ecc60e9781e9844d08a3636b858e013572d66bbc8097b4928fa26
4
- data.tar.gz: b93eb19cd0e4d9ea2effa6cef7ff11fd5a4d4f792d5925ccb2baaad9eee5f5d4
3
+ metadata.gz: 1cc3d58eda573151a58994e22522dd40c516b5d2626ce68255787fae807fcbb8
4
+ data.tar.gz: 1ce21ee31c2e2aeae77da4f43203e07b23497d40a9bf44bd3df16fc2bf3dde0a
5
5
  SHA512:
6
- metadata.gz: 79bc08d233802b69d1a1b6745dc561d95c8c8e1c1f138eadf4116840ee11d95e55b3c03447e843740eb05ea88298a94e3141e152b184330d142a9afa5b2839fd
7
- data.tar.gz: 3f6245dd4badbfced192b0474541a27f14de49435fa43ed137afc2b0bb17542cc41d8d054396ba21614bcf211fcb37db980c37f710b60035029fe5e37cb41aa5
6
+ metadata.gz: f96f4a0a7e4bf885d1c431256f83efbaccf61cfa9c94f96448a9191267275e2d6539f11703bbac0984b897b2eccc3a3099d6a9984c10b83e5dd08ced758609c2
7
+ data.tar.gz: ab8d3d422e6ff1a631d28efc6b6a0c6d470928e8601d835ae2792e47ba448acc80abe28d9288594059a684f93436a87831254a6970a6881933215c285885527f
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "open3"
4
+ require "tty-prompt"
5
+
6
+ module NextRailsScaffold
7
+ module Generators
8
+ NodePackageManagerStruct = Struct.new(:fetch, :run, :add, :lock_file, :version) do
9
+ def to_s = run.split.first
10
+
11
+ def available?
12
+ version.present?
13
+ end
14
+
15
+ def version
16
+ @version ||= NodePackageManager.get_version(to_s)
17
+ end
18
+ end
19
+
20
+ NODE_REQUIRED_VERSION = ENV.fetch("NODE_REQUIRED_VERSION", ">= 18.20")
21
+ NEXT_VERSION = ENV.fetch("NEXT_VERSION", "15.1.6")
22
+
23
+ PACKAGE_MANAGERS = {
24
+ "npm" => NodePackageManagerStruct.new("npx", "npm run", "npm install", "package-lock.json"),
25
+ "yarn" => NodePackageManagerStruct.new("npx", "yarn", "yarn add", "yarn.lock"),
26
+ "pnpm" => NodePackageManagerStruct.new("pnpm dlx", "pnpm", "pnpm add", "pnpm-lock.yaml"),
27
+ "bun" => NodePackageManagerStruct.new("bunx", "bun run", "bun add", "bun.lock.json")
28
+ }.freeze
29
+
30
+ class NodePackageManager
31
+ attr_reader :selected_package_manager
32
+
33
+ def self.get_version(command)
34
+ Open3.capture3(command, "--version").first.gsub(/[^0-9.]/, "")
35
+ rescue Errno::ENOENT
36
+ nil
37
+ end
38
+
39
+ def initialize(shell)
40
+ @prompt = TTY::Prompt.new
41
+ @shell = shell
42
+ end
43
+
44
+ def check_node!
45
+ node_version = self.class.get_version("node")
46
+
47
+ return if Gem::Dependency.new("", NODE_REQUIRED_VERSION).match?("", node_version)
48
+
49
+ raise node_version ? "Your Node version is '#{node_version}'" : "Node not found"
50
+ end
51
+
52
+ def check_pm_version!
53
+ package_manager = @shell.base.options[:package_manager]
54
+
55
+ unless package_manager
56
+ PACKAGE_MANAGERS.each do |manager, details|
57
+ if File.exist?(details.lock_file)
58
+ package_manager = manager
59
+ break
60
+ end
61
+ end
62
+ end
63
+
64
+ until PACKAGE_MANAGERS.keys.include?(package_manager)
65
+ raise "Invalid package manager" unless package_manager.nil?
66
+
67
+ package_manager = @prompt.select(
68
+ "Which package manager do you want to use?",
69
+ PACKAGE_MANAGERS.keys.map { |pm| { name: pm, value: pm, disabled: !PACKAGE_MANAGERS[pm].available? } }
70
+ )
71
+ end
72
+
73
+ @selected_package_manager = PACKAGE_MANAGERS[package_manager]
74
+ end
75
+
76
+ def create_next_app!
77
+ return if File.exist?("package.json")
78
+
79
+ system(
80
+ "#{selected_package_manager.fetch} create-next-app@#{NEXT_VERSION} . --use-#{selected_package_manager} " \
81
+ "--no-app --src-dir --import-alias \"@/*\" #{Rails.env.test? ? "--yes" : ""}"
82
+ )
83
+
84
+ if selected_package_manager.to_s == "yarn" &&
85
+ Gem::Dependency.new("", ">= 2.0").match?("", selected_package_manager.version)
86
+ system("yarn config set nodeLinker node-modules")
87
+ end
88
+ end
89
+
90
+ def install_hygen!
91
+ return if Dir.exist?("_templates")
92
+
93
+ system("#{selected_package_manager.add} -D hygen hygen-add")
94
+ system("#{selected_package_manager.fetch} hygen-add next-rails-scaffold")
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators/rails/scaffold/scaffold_generator"
4
+ require_relative "node_package_manager"
5
+
6
+ module NextRailsScaffold
7
+ module Generators
8
+ class ScaffoldGenerator < Rails::Generators::ScaffoldGenerator
9
+ include ::NextRailsScaffold::Actions
10
+
11
+ source_root File.expand_path("templates", __dir__)
12
+
13
+ argument :attributes, type: :array, default: [], banner: "field:type field:type"
14
+ class_option :package_manager, type: :string, desc: "Package manager to use for frontend project"
15
+ class_option :skip_build, type: :boolean, default: false, desc: "Skip running Next.js build"
16
+ class_option :skip_routes, type: :boolean, default: false, desc: "Skip adding resources to routes.rb"
17
+
18
+ attr_accessor :selected_package_manager
19
+
20
+ def initialize(args, *options) # :nodoc:
21
+ super
22
+ self.attributes = shell.base.attributes
23
+ end
24
+
25
+ def add_resource_route
26
+ return if options[:actions].present? || options[:skip_routes]
27
+
28
+ route "resources :#{file_name.pluralize}", namespace: regular_class_path, scope: "/api"
29
+ end
30
+
31
+ def create_root_folder
32
+ empty_directory "frontend"
33
+ end
34
+
35
+ # Check Javascript dependencies and create a new Next.js project. Install the the useful packages and create the
36
+ # scaffold code for frontend application.
37
+ def create_frontend_project
38
+ return say_status :remove, "skip frontend folder", :yellow if shell.base.behavior == :revoke
39
+
40
+ append_gitignore!
41
+
42
+ node_package_manager = NodePackageManager.new(shell)
43
+
44
+ inside("frontend") do
45
+ node_package_manager.check_node!
46
+ node_package_manager.check_pm_version!
47
+ node_package_manager.create_next_app!
48
+ node_package_manager.install_hygen!
49
+
50
+ return if Rails.env.test?
51
+
52
+ selected_package_manager = node_package_manager.selected_package_manager
53
+ language = File.exist?("tsconfig.json") ? "typescript" : "javascript"
54
+
55
+ run("#{selected_package_manager.fetch} hygen scaffold #{language} #{name} #{mapped_attributes.join(" ")}")
56
+ if !options[:skip_build] && !@prompt.no?("Do you want to build your Next.js project?")
57
+ run("#{selected_package_manager.run} build")
58
+ end
59
+ end
60
+ end
61
+
62
+ private
63
+
64
+ def append_gitignore!
65
+ path = File.join(destination_root, ".gitignore")
66
+
67
+ return unless File.exist?(path)
68
+
69
+ rows = <<~HEREDOC
70
+
71
+ # Ignoring node modules for Rails and Next.js projects
72
+ node_modules/
73
+ HEREDOC
74
+
75
+ append_to_file path, rows
76
+ end
77
+
78
+ def mapped_attributes
79
+ attributes.map { |attr| "#{attr.name}:#{attr.type}" }
80
+ end
81
+ end
82
+ end
83
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module NextRailsScaffold
4
- VERSION = "0.4.1"
4
+ VERSION = "0.4.3"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: next_rails_scaffold
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Raphael Araújo
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-02-04 00:00:00.000000000 Z
11
+ date: 2025-02-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -68,8 +68,9 @@ files:
68
68
  - config/routes.rb
69
69
  - lib/generators/next_rails_scaffold/USAGE
70
70
  - lib/generators/next_rails_scaffold/install_generator.rb
71
+ - lib/generators/next_rails_scaffold/node_package_manager.rb
72
+ - lib/generators/next_rails_scaffold/scaffold_generator.rb
71
73
  - lib/generators/next_rails_scaffold/templates/config/initializers/next_rails_scaffold.rb
72
- - lib/generators/rails/next_rails_scaffold/next_rails_scaffold_generator.rb
73
74
  - lib/next_rails_scaffold.rb
74
75
  - lib/next_rails_scaffold/actions.rb
75
76
  - lib/next_rails_scaffold/engine.rb
@@ -1,158 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "tty-prompt"
4
-
5
- PackageManager = Struct.new(:fetch, :run, :add, :lock_file, :version) do
6
- def to_s = run.split.first
7
- end
8
-
9
- module Rails
10
- class NextRailsScaffoldGenerator < Rails::Generators::NamedBase
11
- include ::NextRailsScaffold::Actions
12
-
13
- source_root File.expand_path("templates", __dir__)
14
-
15
- PACKAGE_MANAGERS = {
16
- "npm" => PackageManager.new("npx", "npm run", "npm install", "package-lock.json"),
17
- "yarn" => PackageManager.new("yarn dlx", "yarn", "yarn add", "yarn.lock"),
18
- "pnpm" => PackageManager.new("pnpm dlx", "pnpm", "pnpm add", "pnpm-lock.yaml"),
19
- "bun" => PackageManager.new("bunx", "bun run", "bun add", "bun.lock.json")
20
- }.freeze
21
- NODE_REQUIRED_VERSION = ENV.fetch("NODE_REQUIRED_VERSION", ">= 18.20")
22
- NEXT_VERSION = ENV.fetch("NEXT_VERSION", "15.1.6")
23
-
24
- argument :attributes, type: :array, default: [], banner: "field:type field:type"
25
- class_option :package_manager, type: :string, desc: "Package manager to use for frontend project"
26
- class_option :skip_build, type: :boolean, default: false, desc: "Skip running Next.js build"
27
- class_option :skip_routes, type: :boolean, default: false, desc: "Skip adding resources to routes.rb"
28
-
29
- attr_accessor :selected_package_manager
30
-
31
- def initialize(args, *options) # :nodoc:
32
- super
33
-
34
- @prompt = TTY::Prompt.new
35
-
36
- self.attributes = shell.base.attributes
37
- end
38
-
39
- # Properly nests namespaces passed into a generator
40
- #
41
- # $ bin/rails generate resource admin/users/products
42
- #
43
- # should give you
44
- #
45
- # scope '/api' do
46
- # namespace :admin do
47
- # namespace :users do
48
- # resources :products
49
- # end
50
- # end
51
- # end
52
- def add_resource_route
53
- return if options[:actions].present? || options[:skip_routes]
54
-
55
- route "resources :#{file_name.pluralize}", namespace: regular_class_path, scope: "/api"
56
- end
57
-
58
- # Check Javascript dependencies and create a new Next.js project. Install the the useful packages and create the
59
- # scaffold code for frontend application.
60
- def create_frontend_project
61
- return say_status :remove, "skip frontend folder", :yellow if shell.base.behavior == :revoke
62
-
63
- append_gitignore!
64
-
65
- empty_directory "frontend"
66
-
67
- inside("frontend") do
68
- check_node!
69
- check_pm_version!
70
- create_next_app!
71
- install_hygen!
72
-
73
- language = File.exist?("tsconfig.json") ? "typescript" : "javascript"
74
-
75
- run("#{selected_package_manager} hygen scaffold #{language} #{name} #{mapped_attributes.join(" ")}")
76
- if !options[:skip_build] && @prompt.no?("Do you want to build your Next.js project? (y/N)")
77
- run("#{selected_package_manager.run} build")
78
- end
79
- end
80
- end
81
-
82
- private
83
-
84
- def check_node!
85
- node_version = run("node --version", capture: true).gsub(/[^0-9.]/, "")
86
-
87
- if Gem::Dependency.new("", NODE_REQUIRED_VERSION).match?("", node_version)
88
- log :node_version, "Your Node version is '#{node_version}'"
89
- else
90
- say_status :node_version, "You need to have a Node version '#{NODE_REQUIRED_VERSION}'", :red
91
- abort
92
- end
93
- end
94
-
95
- def check_pm_version!
96
- package_manager = shell.base.options[:package_manager]
97
-
98
- unless package_manager
99
- PACKAGE_MANAGERS.each do |manager, details|
100
- if File.exist?(details.lock_file)
101
- package_manager = manager
102
- break
103
- end
104
- end
105
- end
106
-
107
- until PACKAGE_MANAGERS.keys.include?(package_manager)
108
- puts "Invalid package manager" unless package_manager.nil?
109
-
110
- package_manager = @prompt.select("Which package manager do you want to use?", PACKAGE_MANAGERS.keys)
111
- end
112
-
113
- self.selected_package_manager = PACKAGE_MANAGERS[package_manager]
114
-
115
- selected_package_manager.version = run("#{selected_package_manager} --version", capture: true).gsub(/[^0-9.]/, "")
116
- log :package_manager, "Using #{selected_package_manager} version '#{selected_package_manager.version}'"
117
- end
118
-
119
- def append_gitignore!
120
- rows = <<~HEREDOC
121
-
122
- # Ingoring node modules for Rails and Next.js projects
123
- node_modules/
124
- HEREDOC
125
-
126
- append_to_file ".gitignore", rows
127
- end
128
-
129
- def create_next_app!
130
- return if File.exist?("package.json")
131
-
132
- run(
133
- "#{selected_package_manager.fetch} create-next-app@#{NEXT_VERSION} . " \
134
- "--no-app --src-dir --import-alias \"@/*\""
135
- )
136
-
137
- if selected_package_manager.to_s == "yarn" &&
138
- Gem::Dependency.new("", ">= 2.0").match?("", selected_package_manager.version)
139
- run("yarn config set nodeLinker node-modules")
140
- end
141
- end
142
-
143
- def install_hygen!
144
- return if Dir.exist?("_templates")
145
-
146
- run("#{selected_package_manager.add} -D hygen hygen-add")
147
- run("#{selected_package_manager} hygen-add next-rails-scaffold")
148
- end
149
-
150
- def mapped_attributes
151
- attributes.map { |attr| "#{attr.name}:#{attr.type}" }
152
- end
153
-
154
- def exit_on_failure?
155
- true
156
- end
157
- end
158
- end