mobilis 0.0.3 → 0.0.4

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: 3cd47dc94e879a945b060720f6ee453228b266749ebab21264f8a03c1af833ef
4
- data.tar.gz: 22c7ce3af384fc3bda6b19790ea086919341466b8d37310d1c5b68fe5c169c6d
3
+ metadata.gz: a79181b97bf2572ac73e8dce659320884665aa649e955970d95bda0251c295dc
4
+ data.tar.gz: 303979cb4e400a188c6ca99d75f8c8857b4926661287e485b0999f0341f30611
5
5
  SHA512:
6
- metadata.gz: 8e9064d8564ee716bc4d4dcf0806638ca3ce16036b6e3225593bf07a470a2fca3bb42da8a7bc63996b2fcf7aefa502b9311f53fbbe5a4434216cfe700c218eaf
7
- data.tar.gz: a6f42ea29dd0b3605b3df3fe79bb768252bbc570cb5afdcb8a0c3245907af95bb8d7f5faefa687e057b4adf1feb686b60b66bfb7cfbc8f10f39649aed48598ba
6
+ metadata.gz: 561a375e73c458745e72415ab88ee6e19d7fe7b299a576ee2a619bc5e66e45ff4f25d763f8a58a2d8465661c6f861b6e5e1642c2e3f2da7084c57a5c5dbe2b2a
7
+ data.tar.gz: 02aabfdd670aeb2d7138b3507d36f15e4c2009656430ac9ec73c6829627f0e87f52949e8b9ce0d911786c24ed685e2ee1396a97a4cb98bb60fc829e2a0f26940
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.0.4] - 2022-09-11
4
+
5
+ - Added command line options load and build
6
+ - Added wait-until to rails w/postgresql or mysql to wait for the db to be ready before starting rails
7
+ - Fixed per-state display not working
8
+ - Use table_print to display some information such as linked projects
9
+
3
10
  ## [0.0.1] - 2022-06-26
4
11
 
5
12
  - Initial release
data/Gemfile.lock CHANGED
@@ -1,9 +1,12 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mobilis (0.1.0)
4
+ mobilis (0.0.4)
5
5
  awesome_print
6
+ optimist
7
+ pry
6
8
  state_machine
9
+ table_print
7
10
  tty-prompt
8
11
 
9
12
  GEM
@@ -41,6 +44,7 @@ GEM
41
44
  attr_extras (>= 6.2.4)
42
45
  diff-lcs
43
46
  patience_diff
47
+ table_print (1.5.7)
44
48
  tty-color (0.6.0)
45
49
  tty-cursor (0.7.1)
46
50
  tty-prompt (0.23.1)
data/README.md CHANGED
@@ -1,22 +1,44 @@
1
1
  # Mobilis
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/mobilis`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ Mobilis is a ruby app for generating linked sets of docker containers, for rapid
4
+ prototyping of arbitrary project architecture.
4
5
 
5
- TODO: Delete this and the text above, and describe your gem
6
+ It has some smarts built in to make common things simple, and will allow you to
7
+ further customize the output for more complex needs.
6
8
 
7
9
  ## Installation
8
10
 
9
- Install the gem and add to the application's Gemfile by executing:
11
+ $ gem install mobilis
10
12
 
11
- $ bundle add mobilis
13
+ ## Usage
12
14
 
13
- If bundler is not being used to manage dependencies, install the gem by executing:
15
+ $ mobilis
14
16
 
15
- $ gem install mobilis
17
+ This will start the console based user interface.
16
18
 
17
- ## Usage
19
+ Add projects of the various kinds. The input doesn't save you from mistakes
20
+ like entering spaces for service names, so don't do it.
21
+
22
+ If you need any containers to connect to other containers via the internal
23
+ names, you will want to add a link from the project that is connecting to the
24
+ project that is being connected to.
25
+
26
+ When configured to your liking, select the generate option to generate the
27
+ projects. This will *DESTROY* any data in an existing 'generate' directory.
18
28
 
19
- TODO: Write usage instructions here
29
+ ## Special Rails support
30
+ If a Ruby on Rails project is linked to a postgres or mysql instance, it will
31
+ be setup with a DATABASE_URL environment variable that has the connection
32
+ information.
33
+
34
+ In addition, the database instance will receive a environment variable with the
35
+ name of the default production database that is based on the rails project's name
36
+
37
+ ## Security
38
+ The generated projects are insecure, because of credential handling details.
39
+
40
+ If you want to deploy the projects into a production environment, you are
41
+ responsible for secrets management.
20
42
 
21
43
  ## Development
22
44
 
@@ -26,4 +48,13 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
26
48
 
27
49
  ## Contributing
28
50
 
29
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/mobilis.
51
+ Bug reports and pull requests are welcome on GitHub at https://github.com/Meleneth/mobilis.
52
+
53
+ ## Plans
54
+
55
+ Adding more project types + smart integrations
56
+ Instrumenting generated projects with New Relic
57
+ Smoothing out the flow of the UI
58
+ Be able to load a previous configured set of projects for further editing
59
+ ~~Make generated rails projects wait at startup until the database is usable~~
60
+ More details in TODO.md
data/TODO.md ADDED
@@ -0,0 +1,18 @@
1
+ make links look better ( table_print )
2
+ make link flow not redirect back to main menu
3
+ write down every time a flow feels bad
4
+ fix NR integration
5
+ ~~fix having to restart several times to go through db create, db migrate, start service loop~~
6
+ add flask app
7
+ rails: add interactive service designer (models / controllers)
8
+ add a rack service wrapper that deploys as a sidecar (*handwave*)
9
+ use graphviz to show a diagram for current metaproject
10
+ ~~give some documentation for expected usage / security concerns~~
11
+ rails: add multi-db-at-once support
12
+ add docker registry support (i.e. the docker container to host a docker registry)
13
+ no matter if you create a db or a rails project first, the flow should be easy and obvious to add the other, associated with whatever you made first
14
+ add ability to re-load old configuration
15
+ if generate/data exists already with data, have an option to keep or wipe the data
16
+ fix git integration so we have proper commit points between each step
17
+ add command line builder, so you can generate a tree based on an existing config
18
+ in a complex config, it feels bad when the config gets big
data/exe/mobilis CHANGED
@@ -5,9 +5,11 @@ require 'pry'
5
5
  require "mobilis/command_line"
6
6
  require "mobilis/interactive_designer"
7
7
 
8
- # options parsing is TODO
9
- #options = Mobilis::CommandLine.parse_args(ARGV)
8
+ options = Mobilis::CommandLine.parse_args(ARGV)
10
9
  program = Mobilis::InteractiveDesigner.new
10
+ if options[:subcommand] == :load
11
+ program.load_from_file options[:filename]
12
+ end
11
13
  program.go_main_menu
12
14
 
13
15
  loop do
@@ -5,37 +5,23 @@ module Mobilis
5
5
  def self.parse_args(args)
6
6
  options = {}
7
7
  Optimist.options(args) do
8
- banner "checklist code janitor"
9
- stop_on ["new", "check", "add"]
8
+ banner "multi-project codebase generation toolkit"
9
+ stop_on ["load", "build", "help"]
10
10
  end
11
- if args.length == 0
12
- options[:subcommand] = :help
11
+ if args == []
12
+ options[:subcommand] = :interactive
13
13
  return options
14
14
  end
15
15
  options[:subcommand] = args.shift.to_sym
16
16
  case options[:subcommand]
17
- when :new
18
- Optimist.options(args) do
19
- stop_on ["gem", "railsapp", "railsapi"]
20
- end
21
- options[:new_type] = args.shift.to_sym
22
- options[:name] = case options[:new_type]
23
- when :gem
24
- args.shift
25
- when :railsapp
26
- args.shift
27
- when :railsapi
28
- args.shift
29
- end
30
- when :add
31
- Optimist.options(args) do
32
- stop_on ["gem", "docker"]
33
- end
34
- options[:add_type] = args.shift.to_sym
35
- case options[:add_type]
36
- when :gem
37
- options[:name] = args.shift
38
- end
17
+ when :load
18
+ options[:filename] = args.shift
19
+ when :build
20
+ options[:filename] = args.shift
21
+ when :help
22
+ puts "I think we'd all like a little help."
23
+ else
24
+ Optimist::die "unknown subcommand #{cmd.inspect}"
39
25
  end
40
26
  options
41
27
  end
@@ -73,10 +73,7 @@ def postgresql_service service
73
73
  {
74
74
  "image" => "postgres:14.1-alpine",
75
75
  "restart" => "always",
76
- "environment" => [
77
- "POSTGRES_USER=#{ service.name }",
78
- "POSTGRES_PASSWORD=#{ service.password }"
79
- ],
76
+ "environment" => service.env_vars,
80
77
  "ports" => ["#{ attributes[keyname] }:5432"],
81
78
  "volumes" => [
82
79
  "#{ service.data_dir }:/var/lib/postgresql/data"
@@ -1,9 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'state_machine'
4
- require 'tty-prompt'
5
3
  require 'awesome_print'
6
4
  require 'forwardable'
5
+ require 'state_machine'
6
+ require 'table_print'
7
+ require 'tty-prompt'
7
8
 
8
9
  require 'mobilis/logger'
9
10
  require 'mobilis/project'
@@ -16,7 +17,7 @@ extend Forwardable
16
17
  attr_accessor :project
17
18
  attr_reader :prompt
18
19
 
19
- def_delegators :@project, :projects, :display
20
+ def_delegators :@project, :projects, :load_from_file
20
21
 
21
22
  state_machine :state, initial: :intialize do
22
23
 
@@ -44,6 +45,11 @@ state_machine :state, initial: :intialize do
44
45
  transition [:main_menu] => :add_redis_instance
45
46
  end
46
47
 
48
+ event :go_back do
49
+ transition [:edit_rails_project] => :main_menu
50
+ transition [:edit_generic_project] => :main_menu
51
+ end
52
+
47
53
  event :go_add_rack_project do
48
54
  transition [:main_menu] => :add_rack_project
49
55
  end
@@ -107,7 +113,10 @@ state_machine :state, initial: :intialize do
107
113
 
108
114
  state :main_menu do
109
115
  def display
110
- project.display
116
+ puts
117
+ tp.set :max_width, 160
118
+ tp projects, 'name', 'type', 'options': lambda {|p| p.options.join ", "}
119
+ puts
111
120
  end
112
121
  def choices
113
122
  project_choices = projects.map do |project|
@@ -141,12 +150,18 @@ state_machine :state, initial: :intialize do
141
150
  end
142
151
 
143
152
  state :edit_links_select_project do
144
- def display = false
153
+ def display
154
+ puts
155
+ tp.set :max_width, 160
156
+ tp projects, 'name', 'type', 'links': lambda {|p| p.links.join ", "}
157
+ puts
158
+ end
145
159
  def choices
146
160
  [
147
161
  {name: "return to Main Menu", value: -> { go_main_menu }},
148
162
  *( projects.map do |project|
149
- { name: "Edit '#{ project.name }' links", value: -> { @selected_project = project ; go_edit_links } }
163
+ links_txt = project.links.join ", "
164
+ { name: "Edit '#{ project.name }' links (#{ links_txt })", value: -> { @selected_project = project ; go_edit_links } }
150
165
  end)
151
166
  ]
152
167
  end
@@ -274,7 +289,7 @@ state_machine :state, initial: :intialize do
274
289
 
275
290
  state :toggle_rails_api_mode do
276
291
  def display
277
- Mobilis.logger.info "Toggled rails API mode for '#{@selected_rails_project.name}'"
292
+ Mobilis.logger.info "Toggled rails API mode for '#{ @selected_rails_project.name }'"
278
293
  end
279
294
  def choices = false
280
295
  def action
@@ -347,10 +362,10 @@ def initialize
347
362
  @project = Project.new
348
363
  end
349
364
 
350
-
365
+ ##
366
+ # display, choices, and action methods all change per-state
351
367
  def choose_destination
352
368
  Mobilis.logger.info "#choose_destination"
353
-
354
369
  blank_space
355
370
  spacer
356
371
  display
@@ -13,6 +13,17 @@ def child_env_vars
13
13
  [ ]
14
14
  end
15
15
 
16
+ def env_vars
17
+ vars = []
18
+ if linked_to_rails_project
19
+ vars << "POSTGRES_DB=#{ linked_to_rails_project.name }_production"
20
+ end
21
+ vars.concat [
22
+ "POSTGRES_USER=#{ name }",
23
+ "POSTGRES_PASSWORD=#{ password }"
24
+ ]
25
+ end
26
+
16
27
  def data_dir
17
28
  "./data/#{ name }"
18
29
  end
@@ -159,6 +159,11 @@ def build_rails_builder
159
159
  run_docker "build -t #{ rails_builder_image } ."
160
160
  end
161
161
 
162
+ def load_from_file filename
163
+ data = File.read filename
164
+ @data = JSON.parse data, {:symbolize_names => true}
165
+ end
166
+
162
167
  def save_project
163
168
  File.open("mproj.json", "w") do |f|
164
169
  f.write(JSON.pretty_generate(@data))
@@ -181,7 +186,7 @@ def projects
181
186
  redis: RedisInstance,
182
187
  rack: RackProject
183
188
  }
184
- @data[:projects].map {|p| mapping[p[:type]].new p, self}
189
+ @data[:projects].map {|p| mapping[p[:type].to_sym].new p, self}
185
190
  end
186
191
 
187
192
  def project_by_name name
@@ -21,7 +21,8 @@ def generate
21
21
  end
22
22
 
23
23
  def generate_config_ru
24
- set_file_contents "config.ru", '# config.ru
24
+ set_file_contents "config.ru", <<CONFIG_RU
25
+ # config.ru
25
26
  app = Proc.new {
26
27
  [
27
28
  200,
@@ -30,11 +31,12 @@ app = Proc.new {
30
31
  ]
31
32
  }
32
33
  run app
33
- '
34
+ CONFIG_RU
34
35
  end
35
36
 
36
37
  def generate_Gemfile
37
- set_file_contents "Gemfile", '# frozen_string_literal: true
38
+ set_file_contents "Gemfile", <<GEMFILE
39
+ # frozen_string_literal: true
38
40
 
39
41
  source "https://rubygems.org"
40
42
 
@@ -43,11 +45,12 @@ source "https://rubygems.org"
43
45
  gem "rack", "= 3.0.0.beta1"
44
46
 
45
47
  gem "rackup", "~> 0.2.2"
46
- '
48
+ GEMFILE
47
49
  end
48
50
 
49
51
  def generate_Gemfile_lock
50
- set_file_contents "Gemfile.lock", 'GEM
52
+ set_file_contents "Gemfile.lock", <<GEMFILE_LOCK
53
+ GEM
51
54
  remote: https://rubygems.org/
52
55
  specs:
53
56
  rack (3.0.0.beta1)
@@ -65,11 +68,11 @@ DEPENDENCIES
65
68
 
66
69
  BUNDLED WITH
67
70
  2.3.16
68
- '
71
+ GEMFILE_LOCK
69
72
  end
70
73
 
71
74
  def generate_Dockerfile
72
- set_file_contents "Dockerfile", '
75
+ set_file_contents "Dockerfile", <<DOCKER_END
73
76
  FROM ruby:latest
74
77
  RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
75
78
  WORKDIR /myapp
@@ -79,10 +82,9 @@ RUN bundle install
79
82
  COPY . /myapp
80
83
 
81
84
  # Add a script to be executed every time the container starts.
82
- ENTRYPOINT ["rackup"]
85
+ ENTRYPOINT ["rackup", "-o", "#{ name }"]
83
86
  EXPOSE 9292
84
-
85
- '
87
+ DOCKER_END
86
88
  end
87
89
 
88
90
  end
@@ -81,6 +81,7 @@ def generate
81
81
  install_rspec if options.include? :rspec
82
82
  install_factory_bot if options.include? :factory_bot
83
83
  git_commit_all "add Gems"
84
+ generate_wait_until
84
85
  generate_Dockerfile
85
86
  generate_entrypoint_sh
86
87
  generate_build_sh
@@ -96,10 +97,36 @@ def rails_master_key
96
97
  @data[:attributes][:rails_master_key]
97
98
  end
98
99
 
100
+ def generate_wait_until
101
+ set_file_contents 'wait-until', <<WAITUNTIL
102
+ #!/usr/bin/env bash
103
+ # https://github.com/nickjj/wait-until under MIT license
104
+
105
+ command="${1}"
106
+ timeout="${2:-30}"
107
+
108
+ i=1
109
+ until eval "${command}"
110
+ do
111
+ ((i++))
112
+
113
+ if [ "${i}" -gt "${timeout}" ]; then
114
+ echo "command was never successful, aborting due to ${timeout}s timeout!"
115
+ exit 1
116
+ fi
117
+
118
+ sleep 1
119
+ done
120
+ WAITUNTIL
121
+ end
122
+
123
+
99
124
  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
125
+ set_file_contents "Dockerfile", <<DOCKER_END
126
+ FROM ruby:latest
127
+ RUN apt-get update -qq && apt-get install -y nodejs postgresql-client default-mysql-client dos2unix
102
128
  WORKDIR /myapp
129
+ COPY wait-until /myapp/wait-until
103
130
  COPY Gemfile /myapp/Gemfile
104
131
  COPY Gemfile.lock /myapp/Gemfile.lock
105
132
  RUN bundle install
@@ -113,11 +140,12 @@ RUN dos2unix /myapp/entrypoint.sh
113
140
 
114
141
  # Configure the main process to run when running the image
115
142
  CMD ["rails", "server", "-b", "0.0.0.0"]
116
- '
143
+ DOCKER_END
117
144
  end
118
145
 
119
146
  def generate_entrypoint_sh
120
- set_file_contents "entrypoint.sh", "#!/bin/sh
147
+ set_file_contents "entrypoint.sh", <<ENTRYPOINT_SH
148
+ #!/bin/sh
121
149
 
122
150
  # https://stackoverflow.com/a/38732187/1935918
123
151
  set -e
@@ -125,11 +153,25 @@ set -e
125
153
  if [ -f /app/tmp/pids/server.pid ]; then
126
154
  rm /app/tmp/pids/server.pid
127
155
  fi
128
-
156
+ #{ wait_until_line }
129
157
  bundle exec rake db:migrate 2>/dev/null || bundle exec rake db:setup
130
158
 
131
- exec bundle exec \"$@\"
132
- "
159
+ exec bundle exec "$@"
160
+ ENTRYPOINT_SH
161
+ end
162
+
163
+ def wait_until_line
164
+ if database.instance_of? Mobilis::PostgresqlInstance
165
+ return <<POSTGRES_LINE
166
+ /myapp/wait-until "psql postgres://#{ database.username }:#{ database.password }@#{ database.name }/#{ name }_production -c 'select 1'"
167
+ POSTGRES_LINE
168
+ end
169
+ # instance_of? is a code smell - maybe this should be database.wait_until_line ?
170
+ if database.instance_of? Mobilis::MysqlInstance
171
+ return <<MYSQL_LINE
172
+ /myapp/wait-until "mysql -D #{ name }_production -h #{ database.name } -u #{ database.username } -p#{ database.password } -e 'select 1'"
173
+ MYSQL_LINE
174
+ end
133
175
  end
134
176
 
135
177
  def install_rspec
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mobilis
4
- VERSION = "0.0.3"
4
+ VERSION = "0.0.4"
5
5
  end
data/lib/mobilis.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "mobilis/version"
4
+ require_relative "mobilis/command_line"
4
5
  require_relative "mobilis/project"
5
6
  require_relative "mobilis/docker_compose_projector"
6
7
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mobilis
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Meleneth
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-08-20 00:00:00.000000000 Z
11
+ date: 2022-09-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: awesome_print
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: state_machine
28
+ name: optimist
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: tty-prompt
42
+ name: pry
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: pry
56
+ name: state_machine
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -67,7 +67,21 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: optimist
70
+ name: table_print
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: tty-prompt
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
87
  - - ">="
@@ -109,6 +123,7 @@ files:
109
123
  - Gemfile.lock
110
124
  - README.md
111
125
  - Rakefile
126
+ - TODO.md
112
127
  - exe/mobilis
113
128
  - lib/mobilis.rb
114
129
  - lib/mobilis/actions_projects_take.rb