mobilis 0.0.1

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.
@@ -0,0 +1,261 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+ require "json"
5
+ require "yaml"
6
+
7
+ require 'mobilis/actions_projects_take'
8
+ require "mobilis/docker_compose_projector"
9
+ require "mobilis/mysql_instance"
10
+ require "mobilis/new_relic"
11
+ require "mobilis/postgresql_instance"
12
+ require "mobilis/rails_project"
13
+ require "mobilis/rack_project"
14
+ require "mobilis/redis_instance"
15
+
16
+ module Mobilis
17
+
18
+ ##
19
+ # this is NOT a GenericProject, this is the metaproject
20
+ # TODO: s/Project/Meta/g
21
+ class Project
22
+ include ActionsProjectsTake
23
+ include Mobilis::NewRelic
24
+
25
+ attr_reader :name
26
+
27
+ def initialize
28
+ @data = {
29
+ projects: [],
30
+ username: ENV.fetch('USER', ENV.fetch('USERNAME', '')),
31
+ starting_port_no: 10000,
32
+ port_gap: 100
33
+ }
34
+ end
35
+
36
+ def attributes
37
+ generate_attributes
38
+ end
39
+
40
+ def username
41
+ @data[:username]
42
+ end
43
+
44
+ def generate_files
45
+ if Dir.exist? 'generate'
46
+ puts "Removing existing generate directory"
47
+ FileUtils.rm_rf('generate')
48
+ end
49
+
50
+ Dir.mkdir 'generate'
51
+
52
+ Dir.chdir 'generate' do
53
+ save_project
54
+ create_rails_builder if has_rails_project?
55
+ projects.each_with_index do |project, index|
56
+ project.generate
57
+ end
58
+ save_docker_compose
59
+ end
60
+ end
61
+
62
+ def create_rails_builder
63
+ Dir.mkdir 'rails-builder'
64
+ Dir.chdir 'rails-builder' do
65
+ create_rails_builder_dockerfile
66
+ create_rails_builder_gemfile
67
+ build_rails_builder
68
+ end
69
+ end
70
+
71
+ def create_rails_builder_dockerfile
72
+ set_file_contents 'Dockerfile', <<EOF
73
+ FROM ruby:latest
74
+ RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
75
+ # Common dependencies
76
+ RUN apt-get update -qq \\
77
+ && DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends \\
78
+ build-essential \\
79
+ gnupg2 \\
80
+ curl \\
81
+ less \\
82
+ git \\
83
+ nodejs \\
84
+ postgresql-client \\
85
+ && apt-get clean \\
86
+ && rm -rf /var/cache/apt/archives/* \\
87
+ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \\
88
+ && truncate -s 0 /var/log/*log
89
+ RUN gem update bundle
90
+ RUN gem update --system
91
+ COPY Gemfile .
92
+ RUN bundle install
93
+ EOF
94
+ end
95
+
96
+ def create_rails_builder_gemfile
97
+ set_file_contents 'Gemfile', <<EOF
98
+ source "https://rubygems.org"
99
+ # FIXME
100
+ #git_source(:github) { |repo| "https://github.com/repo.git" }
101
+
102
+ ruby "3.1.2"
103
+
104
+ gem "rails", "~> 7.0.3", ">= 7.0.3.1"
105
+ gem "sqlite3", "~> 1.4"
106
+ gem "puma", "~> 5.0"
107
+ gem "jbuilder"
108
+ gem "redis", "~> 4.0"
109
+ gem "kredis"
110
+ gem "bcrypt", "~> 3.1.7"
111
+ gem "bootsnap", require: false
112
+ gem "image_processing", "~> 1.2"
113
+ gem "rack-cors"
114
+ gem "pg"
115
+ gem "mysql2"
116
+ gem "minitest"
117
+
118
+ group :development, :test do
119
+ gem "debug", platforms: %i[ mri mingw x64_mingw ]
120
+ end
121
+
122
+ group :development do
123
+ gem "spring"
124
+ end
125
+
126
+ gem "rspec-rails", group: [:development, :test]
127
+ EOF
128
+
129
+ end
130
+
131
+ def has_rails_project?
132
+ projects.each do |p|
133
+ return true if p.type == :rails
134
+ end
135
+ return false
136
+ end
137
+
138
+ def generate_attributes
139
+ attributes = {projects: {}, new_relic_license_key: ENV.fetch("NEW_RELIC_LICENSE_KEY", "some_invalid_key_NREAL")}
140
+ projects.each_with_index do |project, index|
141
+ attributes["#{project.name}_internal_port_no".to_sym] =
142
+ @data[:starting_port_no] + (index * @data[:port_gap])
143
+ end
144
+ attributes
145
+ end
146
+
147
+ def build
148
+ # logger.info "# build"
149
+ Dir.chdir 'generate' do
150
+ run_command "docker compose build"
151
+ end
152
+ end
153
+
154
+ def rails_builder_image
155
+ "#{ username }/rails-builder"
156
+ end
157
+
158
+ def build_rails_builder
159
+ run_docker "build -t #{ rails_builder_image } ."
160
+ end
161
+
162
+ def save_project
163
+ File.open("mproj.json", "w") do |f|
164
+ f.write(JSON.pretty_generate(@data))
165
+ end
166
+ end
167
+
168
+ def save_docker_compose
169
+ docker = DockerComposeProjector.project self
170
+
171
+ File.open("docker-compose.yml", "w") do |f|
172
+ f.write(docker.to_yaml)
173
+ end
174
+ end
175
+
176
+ def projects
177
+ mapping = {
178
+ rails: RailsProject,
179
+ postgresql: PostgresqlInstance,
180
+ mysql: MysqlInstance,
181
+ redis: RedisInstance,
182
+ rack: RackProject
183
+ }
184
+ @data[:projects].map {|p| mapping[p[:type]].new p, self}
185
+ end
186
+
187
+ def project_by_name name
188
+ projects.find {|p| p.name == name }
189
+ end
190
+
191
+ def display
192
+ ap @data
193
+ end
194
+
195
+ def add_prime_stack_rails_project name
196
+ add_rails_project name, [:rspec, :api, :simplecov, :standard, :factorybot]
197
+ end
198
+
199
+ def add_omakase_stack_rails_project name
200
+ add_rails_project name, [:simplecov, :standard, :api]
201
+ end
202
+
203
+ def add_postgresql_instance name
204
+ data = {
205
+ name: name,
206
+ type: :postgresql
207
+ }
208
+ @data[:projects] << data
209
+ GenericProject.new data, self
210
+ end
211
+
212
+ def add_mysql_instance name
213
+ data = {
214
+ name: name,
215
+ type: :mysql
216
+ }
217
+ @data[:projects] << data
218
+ GenericProject.new data, self
219
+ end
220
+
221
+ def add_redis_instance name
222
+ data = {
223
+ name: name,
224
+ type: :redis,
225
+ }
226
+ @data[:projects] << data
227
+ RedisInstance.new data, self
228
+ end
229
+
230
+ def add_rails_project name, options
231
+ data = {
232
+ name: name,
233
+ type: :rails,
234
+ controllers: [],
235
+ models: [],
236
+ options: options.clone,
237
+ attributes: {}
238
+ }
239
+ @data[:projects] << data
240
+ RailsProject.new data, self
241
+ end
242
+
243
+ def add_rack_project name
244
+ data = {
245
+ name: name,
246
+ type: :rack,
247
+ attributes: {}
248
+ }
249
+ @data[:projects] << data
250
+ RackProject.new data, self
251
+ end
252
+
253
+ def getwd
254
+ wd = Dir.getwd
255
+ return wd unless wd[1] == ":"
256
+ return "/#{wd[0]}#{wd[2...]}"
257
+ end
258
+
259
+
260
+ end
261
+ end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "mobilis/generic_project"
4
+ require "mobilis/os"
5
+
6
+ module Mobilis
7
+ class RackProject < GenericProject
8
+
9
+ def name
10
+ @data[:name]
11
+ end
12
+
13
+ def generate
14
+ Dir.mkdir name
15
+ Dir.chdir name do
16
+ generate_config_ru
17
+ generate_Gemfile
18
+ generate_Gemfile_lock
19
+ generate_Dockerfile
20
+ end
21
+ end
22
+
23
+ def generate_config_ru
24
+ set_file_contents "config.ru", '# config.ru
25
+ app = Proc.new {
26
+ [
27
+ 200,
28
+ { "content-type" => "text/html" },
29
+ ["Hello, Rack"]
30
+ ]
31
+ }
32
+ run app
33
+ '
34
+ end
35
+
36
+ def generate_Gemfile
37
+ set_file_contents "Gemfile", '# frozen_string_literal: true
38
+
39
+ source "https://rubygems.org"
40
+
41
+ # gem "rails"
42
+
43
+ gem "rack", "= 3.0.0.beta1"
44
+
45
+ gem "rackup", "~> 0.2.2"
46
+ '
47
+ end
48
+
49
+ def generate_Gemfile_lock
50
+ set_file_contents "Gemfile.lock", 'GEM
51
+ remote: https://rubygems.org/
52
+ specs:
53
+ rack (3.0.0.beta1)
54
+ rackup (0.2.2)
55
+ rack (>= 3.0.0.beta1)
56
+ webrick
57
+ webrick (1.7.0)
58
+
59
+ PLATFORMS
60
+ x64-mingw-ucrt
61
+
62
+ DEPENDENCIES
63
+ rack (= 3.0.0.beta1)
64
+ rackup (~> 0.2.2)
65
+
66
+ BUNDLED WITH
67
+ 2.3.16
68
+ '
69
+ end
70
+
71
+ def generate_Dockerfile
72
+ set_file_contents "Dockerfile", '
73
+ FROM ruby:latest
74
+ RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
75
+ WORKDIR /myapp
76
+ COPY Gemfile /myapp/Gemfile
77
+ COPY Gemfile.lock /myapp/Gemfile.lock
78
+ RUN bundle install
79
+ COPY . /myapp
80
+
81
+ # Add a script to be executed every time the container starts.
82
+ ENTRYPOINT ["rackup"]
83
+ EXPOSE 9292
84
+
85
+ '
86
+ end
87
+
88
+ end
89
+ end
@@ -0,0 +1,179 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "mobilis/generic_project"
4
+ require "mobilis/os"
5
+
6
+ module Mobilis
7
+ class RailsProject < GenericProject
8
+
9
+ def child_env_vars
10
+ [
11
+ "#{ name.upcase }_HOST=#{ name }"
12
+ ]
13
+ end
14
+
15
+ def controllers
16
+ @data[:controllers]
17
+ end
18
+
19
+ def models
20
+ @data[:models]
21
+ end
22
+
23
+ def database
24
+ links.each do |link|
25
+ project = @metaproject.project_by_name link
26
+ return project if project.instance_of? Mobilis::PostgresqlInstance
27
+ return project if project.instance_of? Mobilis::MysqlInstance
28
+ end
29
+ return nil
30
+ end
31
+
32
+ def toggle_rails_api_mode
33
+ if options.include? :api then
34
+ remove_rails_option :api
35
+ add_rails_option :haml
36
+ else
37
+ add_rails_option :api
38
+ remove_rails_option :haml
39
+ end
40
+ end
41
+
42
+ def add_rails_option option
43
+ remove_rails_option option
44
+ options << option
45
+ end
46
+
47
+ def remove_rails_option option
48
+ options.reject! {|x| x == option }
49
+ end
50
+
51
+ def add_controller name
52
+ controller = {name: name, actions: []}
53
+ @data[:controllers] << controller
54
+ controller
55
+ end
56
+
57
+ def add_model name
58
+ model = {name: name, fields: []}
59
+ @data[:models] << model
60
+ model
61
+ end
62
+
63
+ def rails_builder_image
64
+ "#{ @metaproject.username }/rails-builder"
65
+ end
66
+
67
+ def rails_run_command command
68
+ run_docker "run --rm -v #{ getwd }:/usr/src/app -w /usr/src/app #{ rails_builder_image } #{ command }"
69
+ end
70
+
71
+ def bundle_run command
72
+ rails_run_command "./bundle_run.sh #{ command }"
73
+ end
74
+
75
+ def generate
76
+ rails_run_command rails_new_command_line
77
+ Dir.chdir name do
78
+ git_commit_all "rails new"
79
+ generate_bundle_run
80
+ read_rails_master_key
81
+ install_rspec if options.include? :rspec
82
+ install_factory_bot if options.include? :factory_bot
83
+ git_commit_all "add Gems"
84
+ generate_Dockerfile
85
+ generate_entrypoint_sh
86
+ generate_build_sh
87
+ git_commit_all "add Dockerfile and build script etc"
88
+ end
89
+ end
90
+
91
+ def read_rails_master_key
92
+ @data[:attributes][:rails_master_key] = File.read("config/master.key")
93
+ end
94
+
95
+ def rails_master_key
96
+ @data[:attributes][:rails_master_key]
97
+ end
98
+
99
+ def generate_Dockerfile
100
+ set_file_contents "Dockerfile", 'FROM ruby:latest
101
+ RUN apt-get update -qq && apt-get install -y nodejs postgresql-client dos2unix
102
+ WORKDIR /myapp
103
+ COPY Gemfile /myapp/Gemfile
104
+ COPY Gemfile.lock /myapp/Gemfile.lock
105
+ RUN bundle install
106
+ COPY . /myapp
107
+
108
+ # Add a script to be executed every time the container starts.
109
+ RUN chmod +x /myapp/entrypoint.sh
110
+ ENTRYPOINT ["/myapp/entrypoint.sh"]
111
+ EXPOSE 3000
112
+ RUN dos2unix /myapp/entrypoint.sh
113
+
114
+ # Configure the main process to run when running the image
115
+ CMD ["rails", "server", "-b", "0.0.0.0"]
116
+ '
117
+ end
118
+
119
+ def generate_entrypoint_sh
120
+ set_file_contents "entrypoint.sh", "#!/bin/sh
121
+
122
+ # https://stackoverflow.com/a/38732187/1935918
123
+ set -e
124
+
125
+ if [ -f /app/tmp/pids/server.pid ]; then
126
+ rm /app/tmp/pids/server.pid
127
+ fi
128
+
129
+ bundle exec rake db:migrate 2>/dev/null || bundle exec rake db:setup
130
+
131
+ exec bundle exec \"$@\"
132
+ "
133
+ end
134
+
135
+ def install_rspec
136
+ Mobilis.logger.info "Installing rspec"
137
+ append_line "Gemfile", 'gem "rspec-rails", group: [:development, :test]'
138
+ bundle_run "rails generate rspec:install"
139
+ end
140
+
141
+ def install_factory_bot
142
+ Mobilis.logger.info "Installing FactoryBot"
143
+ append_line "Gemfile", "gem 'factory_bot_rails'"
144
+ set_file_contents "spec/support/factory_bot.rb", "RSpec.configure do |config|
145
+ config.include FactoryBot::Syntax::Methods
146
+ end
147
+ "
148
+ end
149
+
150
+ def generate_bundle_run
151
+ Mobilis.logger.info "Installing bundle_run.sh"
152
+
153
+ set_file_contents "bundle_run.sh", "#!/bin/bash
154
+ set -euo pipefail
155
+ bundle install
156
+ $@
157
+ "
158
+ end
159
+
160
+ def install_super_diff
161
+ append_line "Gemfile", "gem 'super_diff', group: [:development]"
162
+ set_second_line 'spec/spec_helper.rb', 'require "super_diff/rspec"'
163
+ end
164
+
165
+ def rails_new_command_line
166
+ pieces = ["bundle", "exec", "rails", "new", name, "."]
167
+ pieces << "--api" if options.include? :api
168
+ my_db = database
169
+ if my_db then
170
+ pieces << "--database=#{ my_db.type }"
171
+ end
172
+ if Mobilis::OS.linux?
173
+ pieces << "-u #{ Process.uid }:#{ Process.gid }"
174
+ end
175
+ pieces.join " "
176
+ end
177
+
178
+ end
179
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "mobilis/generic_project"
4
+
5
+ module Mobilis
6
+ class RedisInstance < GenericProject
7
+
8
+ def generate
9
+ FileUtils.mkdir_p data_dir
10
+ end
11
+
12
+ def child_env_vars
13
+ [
14
+ "REDIS_HOST=#{ name }",
15
+ "REDIS_PORT=6379",
16
+ "REDIS_PASSWORD=#{ password }"
17
+ ]
18
+ end
19
+
20
+ def data_dir
21
+ "./data/#{ name }"
22
+ end
23
+
24
+ def has_local_build
25
+ false
26
+ end
27
+
28
+ def username
29
+ name
30
+ end
31
+
32
+ def password
33
+ "#{name}_password"
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mobilis
4
+ VERSION = "0.0.1"
5
+ end
data/lib/mobilis.rb ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "mobilis/version"
4
+ require_relative "mobilis/project"
5
+ require_relative "mobilis/docker_compose_projector"
6
+
7
+ module Mobilis
8
+ class Error < StandardError; end
9
+ end
data/sig/mobilis.rbs ADDED
@@ -0,0 +1,4 @@
1
+ module Mobilis
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata ADDED
@@ -0,0 +1,125 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mobilis
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Meleneth
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2022-08-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: awesome_print
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: state_machine
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: tty-prompt
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: super_diff
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description:
70
+ email:
71
+ - meleneth@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".rspec"
77
+ - ".rubocop.yml"
78
+ - CHANGELOG.md
79
+ - Gemfile
80
+ - Gemfile.lock
81
+ - README.md
82
+ - Rakefile
83
+ - lib/mobilis.rb
84
+ - lib/mobilis/actions_projects_take.rb
85
+ - lib/mobilis/command_line.rb
86
+ - lib/mobilis/docker_compose_projector.rb
87
+ - lib/mobilis/generic_project.rb
88
+ - lib/mobilis/interactive_designer.rb
89
+ - lib/mobilis/logger.rb
90
+ - lib/mobilis/mysql_instance.rb
91
+ - lib/mobilis/new_relic.rb
92
+ - lib/mobilis/os.rb
93
+ - lib/mobilis/postgresql_instance.rb
94
+ - lib/mobilis/project.rb
95
+ - lib/mobilis/rack_project.rb
96
+ - lib/mobilis/rails_project.rb
97
+ - lib/mobilis/redis_instance.rb
98
+ - lib/mobilis/version.rb
99
+ - sig/mobilis.rbs
100
+ homepage: https://github.com/meleneth/mobilis
101
+ licenses: []
102
+ metadata:
103
+ homepage_uri: https://github.com/meleneth/mobilis
104
+ source_code_uri: https://github.com/meleneth/mobilis
105
+ changelog_uri: https://github.com/meleneth/mobilis/CHANGELOG.md
106
+ post_install_message:
107
+ rdoc_options: []
108
+ require_paths:
109
+ - lib
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: 2.6.0
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ requirements: []
121
+ rubygems_version: 3.3.7
122
+ signing_key:
123
+ specification_version: 4
124
+ summary: Generate and scaffold multiple projects and a docker compose file
125
+ test_files: []