layered_stack 0.0.3 → 0.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: 5fd088f84a3ff64374b06adcb67007c1a45a66441bd614c3999f7e58a6b4a69a
4
- data.tar.gz: 58db5902a26ffdf015274e35a763d52be0ed0e47b72514a6c4a040f34f448722
3
+ metadata.gz: 55f427f78d61429bd0cdf47d1573e5945efa2c00229d3b90268087d90c2a256b
4
+ data.tar.gz: 7a2d65ac4c1df34dcfeeed1bc5298d772260398203cdb1a06bc395c7ff5a77fd
5
5
  SHA512:
6
- metadata.gz: 0a316be0dabaaa1c7ace214107c5346eccc2a08a2d7af0c32a3a24515398c661f54a56a3335e6e908c9aee1780786a5b23b20d19682a8f9f654052d7e8e316cf
7
- data.tar.gz: 92521bccf4d65d63bfd1fcafe4177241b32d819be004403d95c979236de3bd10fe20c48c7f7a12f8d6295e56ad93e1aeb11d9acb580202436f8fc9532f3f3764
6
+ metadata.gz: e4523c1c8a0f52d4ab5308b55552a507e3b5e90eab7581f6cfeb18976161a0feb036517a55cf0df8566fe848a4e27e5a290ce14b53e501ba2a10c465926723aa
7
+ data.tar.gz: 92be417e561bc0c8794e195ecbcf502cae7a8a718a2d0cadf77090b169203d9092b153c3cf04c515ec0c863dc18f3a4a571f3364e0f4c3e6d2c48ed0c844e548
@@ -0,0 +1,53 @@
1
+ gem "rack-cors", "~> 2.0.2"
2
+
3
+ after_bundle do
4
+ # rails_command "db:create"
5
+ # rails_command "db:migrate"
6
+
7
+ # Remove the line "allow_browser versions: :modern" in backend/app/controllers/application_controller.rb
8
+ gsub_file 'app/controllers/application_controller.rb', /^(\s*allow_browser versions: :modern)/, ''
9
+
10
+ # Configure rack-cors in config/application.rb
11
+ inject_into_file 'config/application.rb', before: /^ end/ do
12
+ <<-TEXT
13
+
14
+ # Configure CORS
15
+ config.middleware.insert_before 0, Rack::Cors do
16
+ allow do
17
+ origins 'localhost:3001'
18
+ resource '*',
19
+ headers: :any,
20
+ methods: [:get, :post, :put, :patch, :delete, :options, :head]
21
+ end
22
+ end
23
+ TEXT
24
+ end
25
+
26
+ # Create the example API controller file
27
+ create_file "app/controllers/api/v1/examples_controller.rb", <<-TEXT
28
+ module Api
29
+ module V1
30
+ class ExamplesController < ApplicationController
31
+ def index
32
+ render json: { message: "Hello from Rails #{Rails.version}" }
33
+ end
34
+ end
35
+ end
36
+ end
37
+ TEXT
38
+
39
+ # Create the example API route
40
+ route <<-TEXT
41
+ namespace :api do
42
+ namespace :v1 do
43
+ resources 'examples', only: [:index]
44
+ end
45
+ end
46
+ TEXT
47
+
48
+ # Create the Procfile
49
+ create_file "Procfile", <<-TEXT
50
+ backend: rails s -p 3000
51
+ frontend: cd ../frontend && npm run dev
52
+ TEXT
53
+ end
data/assets/page.js CHANGED
@@ -18,10 +18,11 @@ export default function Home() {
18
18
 
19
19
  return (
20
20
  <Page
21
+ backendUrl="http://localhost:3000"
21
22
  logoDark={logoDark}
22
23
  logoLight={logoLight}
23
24
  metadata={metadata}
24
- mobileMenuIcon={mobileMenuIcon}
25
+ // mobileMenuIcon={mobileMenuIcon}
25
26
  useTheme={useTheme}
26
27
  user={{
27
28
  initials: 'TG'
data/bin/layered_stack CHANGED
@@ -1,3 +1,3 @@
1
- #!/usr/bin/env ruby
1
+ #!/usr/bin/env ruby -wU
2
2
  require 'layered_stack'
3
- LayeredStack::Cli::Runner.start(ARGV)
3
+ LayeredStack::Cli.start(ARGV)
@@ -0,0 +1,42 @@
1
+ require 'fileutils'
2
+ require 'thor'
3
+ require 'logger'
4
+
5
+ module LayeredStack
6
+ module Backend
7
+ class Create < Thor
8
+ def self.execute
9
+ new.execute
10
+ end
11
+
12
+ no_commands do
13
+ def execute
14
+ check_and_remove_backend
15
+ create_new_backend
16
+ end
17
+
18
+ private
19
+
20
+ def logger
21
+ @logger ||= Logger.new(STDOUT)
22
+ end
23
+
24
+ def run_command(command, message)
25
+ logger.info(message)
26
+ system(command)
27
+ end
28
+
29
+ def check_and_remove_backend
30
+ if Dir.exist?('backend')
31
+ run_command('rm -rf backend', 'Removing backend directory')
32
+ end
33
+ end
34
+
35
+ def create_new_backend
36
+ template_path = File.expand_path('../../../assets/backend/template.rb', __dir__)
37
+ run_command("rails new backend --minimal --devcontainer --template=#{template_path}", 'Creating new Rails application named backend')
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,30 @@
1
+ require 'thor'
2
+ require 'logger'
3
+
4
+ module LayeredStack
5
+ module Backend
6
+ class Start < Thor
7
+ def self.execute
8
+ new.execute
9
+ end
10
+
11
+ no_commands do
12
+ def execute
13
+ logger.info("> layered_stack/frontend/start")
14
+ run_command('code backend', 'Starting VS Code in /backend directory')
15
+ end
16
+
17
+ private
18
+
19
+ def logger
20
+ @logger ||= Logger.new(STDOUT)
21
+ end
22
+
23
+ def run_command(command, message)
24
+ logger.info(message)
25
+ system(command)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,137 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+ require 'thor'
5
+ require 'logger'
6
+
7
+ module LayeredStack
8
+ module Frontend
9
+ class Create < Thor
10
+ CREATE_NEXT_APP_SWITCHES = "--js --tailwind --eslint --app --src-dir --import-alias @/* --use-npm"
11
+
12
+ FRONTEND_DIR = "frontend"
13
+
14
+ def self.asset_path(relative_path)
15
+ File.expand_path("../../../../assets/#{relative_path}", __FILE__)
16
+ end
17
+
18
+ ASSET_FILES = {
19
+ asset_path("tailwind.config.js") => "frontend/tailwind.config.js",
20
+ asset_path("layout.js") => "frontend/src/app/layout.js",
21
+ asset_path("page.js") => "frontend/src/app/page.js",
22
+ asset_path("images/logo_dark.svg") => "frontend/src/app/logo_dark.svg",
23
+ asset_path("images/logo_light.svg") => "frontend/src/app/logo_light.svg",
24
+ }
25
+
26
+ LOGO_FILES = {
27
+ "assets/images/logo_dark.svg" => "frontend/src/app/logo_dark.svg",
28
+ "assets/images/logo_light.svg" => "frontend/src/app/logo_light.svg",
29
+ }
30
+
31
+ def self.execute
32
+ new.execute
33
+ end
34
+
35
+ no_commands do
36
+ def execute
37
+ logger.info("> layered_stack/create")
38
+ remove_existing_frontend
39
+ run_create_next_app
40
+ Dir.chdir(FRONTEND_DIR) do
41
+ install_dependencies
42
+ update_package_json
43
+ end
44
+ copy_asset_files
45
+ copy_logo_files
46
+ print_next_step
47
+ end
48
+
49
+ private
50
+
51
+ def logger
52
+ @logger ||= Logger.new(STDOUT)
53
+ end
54
+
55
+ def remove_existing_frontend
56
+ if Dir.exist?(FRONTEND_DIR)
57
+ logger.info("\n# Removing existing /#{FRONTEND_DIR} directory")
58
+ FileUtils.rm_rf(FRONTEND_DIR)
59
+ end
60
+ end
61
+
62
+ def run_create_next_app
63
+ command = "npx create-next-app@latest #{CREATE_NEXT_APP_SWITCHES} #{FRONTEND_DIR}"
64
+ run_command(command, "Running create-next-app")
65
+ end
66
+
67
+ def install_dependencies
68
+ dependencies = [
69
+ "next-themes",
70
+ "@heroicons/react@latest",
71
+ "@layeredstack/ui@latest"
72
+ ]
73
+ dependencies.each do |dep|
74
+ run_command("npm install #{dep}", "Installing #{dep}")
75
+ end
76
+ end
77
+
78
+ def update_package_json
79
+ logger.info("# Updating package.json to change the port to 3001")
80
+ update_file("package.json", '"dev": "next dev"', '"dev": "next dev -p 3001"')
81
+ update_file("package.json", '"start": "next start"', '"start": "next start -p 3001"')
82
+ end
83
+
84
+ def copy_asset_files
85
+ logger.info("\n# Copying asset files to the frontend directory")
86
+ copy_files(ASSET_FILES)
87
+ end
88
+
89
+ def copy_logo_files
90
+ logger.info("\n# Copying logo files to the frontend directory")
91
+ copy_files(LOGO_FILES) { |src, dest| copy_logo_file(src, dest) }
92
+ end
93
+
94
+ def copy_files(files)
95
+ files.each do |src, dest|
96
+ if block_given?
97
+ yield(src, dest)
98
+ else
99
+ FileUtils.cp(src, dest)
100
+ end
101
+ end
102
+ end
103
+
104
+ def copy_logo_file(src, dest)
105
+ if File.exist?(src)
106
+ logger.info("User provided logo exists in assets, copying #{src} to #{dest}")
107
+ FileUtils.cp(src, dest)
108
+ else
109
+ template_src = ASSET_FILES.find { |k, _| k.include?(File.basename(src)) }&.first
110
+ if template_src
111
+ logger.info("No user provided logo found in 'assets/images/', copying default logo from #{template_src} to #{dest}")
112
+ FileUtils.cp(template_src, dest)
113
+ else
114
+ logger.warn("Default logo file #{src} not found")
115
+ end
116
+ end
117
+ end
118
+
119
+ def run_command(command, message)
120
+ logger.info(message)
121
+ system(command)
122
+ end
123
+
124
+ def update_file(file, old_content, new_content)
125
+ content = File.read(file)
126
+ new_content = content.gsub(old_content, new_content)
127
+ File.write(file, new_content)
128
+ end
129
+
130
+ def print_next_step
131
+ logger.info("\n# Next step:")
132
+ logger.info("bundle exec layered_stack frontend start")
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,33 @@
1
+ require 'thor'
2
+ require 'logger'
3
+
4
+ module LayeredStack
5
+ module Frontend
6
+ class Start < Thor
7
+ def self.execute
8
+ new.execute
9
+ end
10
+
11
+ no_commands do
12
+ def execute
13
+ logger.info("> layered_stack/frontend/start")
14
+ run_command('code frontend', 'Starting VS Code in frontend directory', 'Failed to start VS Code')
15
+ end
16
+
17
+ private
18
+
19
+ def logger
20
+ @logger ||= Logger.new(STDOUT)
21
+ end
22
+
23
+ def run_command(command, success_message, error_message)
24
+ if system(command)
25
+ logger.info(success_message)
26
+ else
27
+ logger.error(error_message)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LayeredStack
4
- VERSION = '0.0.3'
4
+ VERSION = '0.0.5'
5
5
  end
data/lib/layered_stack.rb CHANGED
@@ -4,22 +4,45 @@ require 'thor'
4
4
  Dir[File.join(__dir__, 'layered_stack/**/*.rb')].each { |file| require_relative file }
5
5
 
6
6
  module LayeredStack
7
- module Cli
8
- class Runner < Thor
9
- desc "hello", "say hello"
10
- def hello(name)
11
- puts "> layered_stack/hello"
12
- puts "Hello #{name} from Layered Stack CLI version #{LayeredStack::VERSION}!"
7
+ class Cli < Thor
8
+ desc "start", "Start"
9
+ def start
10
+ Frontend.new.start
11
+ Backend.new.start
12
+ end
13
+
14
+ class Frontend < Thor
15
+ namespace :frontend
16
+
17
+ desc "create", "Create"
18
+ def create
19
+ LayeredStack::Frontend::Create.execute
20
+ end
21
+
22
+ desc "start", "Start"
23
+ def start
24
+ LayeredStack::Frontend::Start.execute
13
25
  end
14
26
 
27
+ desc "create_and_start", "Create and start"
28
+ def create_and_start
29
+ create
30
+ start
31
+ end
32
+ end
33
+ register(Frontend, 'frontend', 'frontend [COMMAND]', 'Commands for the frontend')
34
+
35
+ class Backend < Thor
36
+ namespace :backend
37
+
15
38
  desc "create", "Create"
16
39
  def create
17
- LayeredStack::Cli::Commands::CreateCommand.execute
40
+ LayeredStack::Backend::Create.execute
18
41
  end
19
42
 
20
43
  desc "start", "Start"
21
44
  def start
22
- LayeredStack::Cli::Commands::StartCommand.execute
45
+ LayeredStack::Backend::Start.execute
23
46
  end
24
47
 
25
48
  desc "create_and_start", "Create and start"
@@ -28,5 +51,6 @@ module LayeredStack
28
51
  start
29
52
  end
30
53
  end
54
+ register(Backend, 'backend', 'backend [COMMAND]', 'Commands for the backend')
31
55
  end
32
56
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: layered_stack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Layered Stack
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-09-05 00:00:00.000000000 Z
11
+ date: 2024-09-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 1.3.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: rails
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 7.0.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 7.0.0
27
41
  description: CLI for Layered Stack
28
42
  email:
29
43
  - support@layeredstack.com
@@ -32,6 +46,7 @@ executables:
32
46
  extensions: []
33
47
  extra_rdoc_files: []
34
48
  files:
49
+ - assets/backend/template.rb
35
50
  - assets/images/logo_dark.svg
36
51
  - assets/images/logo_light.svg
37
52
  - assets/layout.js
@@ -39,8 +54,10 @@ files:
39
54
  - assets/tailwind.config.js
40
55
  - bin/layered_stack
41
56
  - lib/layered_stack.rb
42
- - lib/layered_stack/commands/create_command.rb
43
- - lib/layered_stack/commands/start_command.rb
57
+ - lib/layered_stack/backend/create.rb
58
+ - lib/layered_stack/backend/start.rb
59
+ - lib/layered_stack/frontend/create.rb
60
+ - lib/layered_stack/frontend/start.rb
44
61
  - lib/layered_stack/version.rb
45
62
  homepage: https://www.layeredstack.com/
46
63
  licenses:
@@ -63,7 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
63
80
  - !ruby/object:Gem::Version
64
81
  version: '0'
65
82
  requirements: []
66
- rubygems_version: 3.5.9
83
+ rubygems_version: 3.5.11
67
84
  signing_key:
68
85
  specification_version: 4
69
86
  summary: Layered Stack CLI
@@ -1,139 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'fileutils'
4
- require 'thor'
5
- require 'logger'
6
-
7
- module LayeredStack
8
- module Cli
9
- module Commands
10
- class CreateCommand < Thor
11
- CREATE_NEXT_APP_SWITCHES = "--js --tailwind --eslint --app --src-dir --import-alias @/* --use-npm"
12
-
13
- FRONTEND_DIR = "frontend"
14
-
15
- def self.asset_path(relative_path)
16
- File.expand_path("../../../../assets/#{relative_path}", __FILE__)
17
- end
18
-
19
- ASSET_FILES = {
20
- asset_path("tailwind.config.js") => "frontend/tailwind.config.js",
21
- asset_path("layout.js") => "frontend/src/app/layout.js",
22
- asset_path("page.js") => "frontend/src/app/page.js",
23
- asset_path("images/logo_dark.svg") => "frontend/src/app/logo_dark.svg",
24
- asset_path("images/logo_light.svg") => "frontend/src/app/logo_light.svg",
25
- }
26
-
27
- LOGO_FILES = {
28
- "assets/images/logo_dark.svg" => "frontend/src/app/logo_dark.svg",
29
- "assets/images/logo_light.svg" => "frontend/src/app/logo_light.svg",
30
- }
31
-
32
- def self.execute
33
- new.execute
34
- end
35
-
36
- no_commands do
37
- def execute
38
- logger.info("> layered_stack/create")
39
- remove_existing_frontend
40
- run_create_next_app
41
- Dir.chdir(FRONTEND_DIR) do
42
- install_dependencies
43
- update_package_json
44
- end
45
- copy_asset_files
46
- copy_logo_files
47
- print_next_step
48
- end
49
-
50
- private
51
-
52
- def logger
53
- @logger ||= Logger.new(STDOUT)
54
- end
55
-
56
- def remove_existing_frontend
57
- if Dir.exist?(FRONTEND_DIR)
58
- logger.info("\n# Removing existing /#{FRONTEND_DIR} directory")
59
- FileUtils.rm_rf(FRONTEND_DIR)
60
- end
61
- end
62
-
63
- def run_create_next_app
64
- command = "npx create-next-app@latest #{CREATE_NEXT_APP_SWITCHES} #{FRONTEND_DIR}"
65
- run_command(command, "Running create-next-app")
66
- end
67
-
68
- def install_dependencies
69
- dependencies = [
70
- "next-themes",
71
- "@heroicons/react@latest",
72
- "@layeredstack/ui@latest"
73
- ]
74
- dependencies.each do |dep|
75
- run_command("npm install #{dep}", "Installing #{dep}")
76
- end
77
- end
78
-
79
- def update_package_json
80
- logger.info("# Updating package.json to change the port to 3001")
81
- update_file("package.json", '"dev": "next dev"', '"dev": "next dev -p 3001"')
82
- update_file("package.json", '"start": "next start"', '"start": "next start -p 3001"')
83
- end
84
-
85
- def copy_asset_files
86
- logger.info("\n# Copying asset files to the frontend directory")
87
- copy_files(ASSET_FILES)
88
- end
89
-
90
- def copy_logo_files
91
- logger.info("\n# Copying logo files to the frontend directory")
92
- copy_files(LOGO_FILES) { |src, dest| copy_logo_file(src, dest) }
93
- end
94
-
95
- def copy_files(files)
96
- files.each do |src, dest|
97
- if block_given?
98
- yield(src, dest)
99
- else
100
- FileUtils.cp(src, dest)
101
- end
102
- end
103
- end
104
-
105
- def copy_logo_file(src, dest)
106
- if File.exist?(src)
107
- logger.info("User provided logo exists in assets, copying #{src} to #{dest}")
108
- FileUtils.cp(src, dest)
109
- else
110
- template_src = ASSET_FILES.find { |k, _| k.include?(File.basename(src)) }&.first
111
- if template_src
112
- logger.info("No user provided logo found in 'assets/images/', copying default logo from #{template_src} to #{dest}")
113
- FileUtils.cp(template_src, dest)
114
- else
115
- logger.warn("Default logo file #{src} not found")
116
- end
117
- end
118
- end
119
-
120
- def run_command(command, message)
121
- logger.info(message)
122
- system(command)
123
- end
124
-
125
- def update_file(file, old_content, new_content)
126
- content = File.read(file)
127
- new_content = content.gsub(old_content, new_content)
128
- File.write(file, new_content)
129
- end
130
-
131
- def print_next_step
132
- logger.info("\n# Next step:")
133
- logger.info("bundle exec layered_stack start")
134
- end
135
- end
136
- end
137
- end
138
- end
139
- end
@@ -1,70 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'thor'
4
- require 'logger'
5
-
6
- module LayeredStack
7
- module Cli
8
- module Commands
9
- class StartCommand < Thor
10
- FRONTEND_DIR = "frontend"
11
- LOCALHOST_URL = "http://localhost:3001"
12
-
13
- def self.execute
14
- new.execute
15
- end
16
-
17
- no_commands do
18
- def execute
19
- logger.info("> layered_stack/start")
20
-
21
- if change_directory
22
- open_browser
23
- run_development_server
24
- end
25
- end
26
-
27
- private
28
-
29
- def logger
30
- @logger ||= Logger.new(STDOUT)
31
- end
32
-
33
- def change_directory
34
- if Dir.exist?(FRONTEND_DIR)
35
- begin
36
- Dir.chdir(FRONTEND_DIR)
37
- logger.info("Changed directory to '#{FRONTEND_DIR}'")
38
- true
39
- rescue => e
40
- logger.error("Failed to change directory: #{e.message}")
41
- false
42
- end
43
- else
44
- logger.error("Directory '#{FRONTEND_DIR}' does not exist")
45
- false
46
- end
47
- end
48
-
49
- def open_browser
50
- logger.info("\n# Opening the browser")
51
- run_command("open #{LOCALHOST_URL}", "Browser opened successfully", "Failed to open the browser")
52
- end
53
-
54
- def run_development_server
55
- logger.info("\n# Running the development server")
56
- run_command("npm run dev", "Development server started successfully", "Failed to start the development server")
57
- end
58
-
59
- def run_command(command, success_message, error_message)
60
- if system(command)
61
- logger.info(success_message)
62
- else
63
- logger.error(error_message)
64
- end
65
- end
66
- end
67
- end
68
- end
69
- end
70
- end