Class: Mobilis::RailsProject

Inherits:
GenericProject show all
Defined in:
lib/mobilis/rails_project.rb

Instance Method Summary collapse

Methods inherited from GenericProject

#children, #display, #docker_image_name, #env_vars, #generate_build_sh, #git_commit_all, #initialize, #linked_to_rails_project, #links, #name, #options, #parents, #set_links, #type

Methods included from ActionsProjectsTake

#append_line, #oblivious_run_command, #run_command, #run_docker, #set_file_contents, #set_second_line, #write_file

Constructor Details

This class inherits a constructor from Mobilis::GenericProject

Instance Method Details

#add_controller(name) ⇒ Object



51
52
53
54
55
# File 'lib/mobilis/rails_project.rb', line 51

def add_controller name
  controller = {name: name, actions: []}
  @data[:controllers] << controller
  controller
end

#add_model(name) ⇒ Object



57
58
59
60
61
# File 'lib/mobilis/rails_project.rb', line 57

def add_model name
  model = {name: name, fields: []}
  @data[:models] << model
  model
end

#add_rails_option(option) ⇒ Object



42
43
44
45
# File 'lib/mobilis/rails_project.rb', line 42

def add_rails_option option
  remove_rails_option option
  options << option
end

#bundle_run(command) ⇒ Object



71
72
73
# File 'lib/mobilis/rails_project.rb', line 71

def bundle_run command
  rails_run_command "./bundle_run.sh #{ command }"
end

#child_env_varsObject



9
10
11
12
13
# File 'lib/mobilis/rails_project.rb', line 9

def child_env_vars
  [
    "#{ name.upcase }_HOST=#{ name }"
  ]
end

#controllersObject



15
16
17
# File 'lib/mobilis/rails_project.rb', line 15

def controllers
  @data[:controllers]
end

#databaseObject



23
24
25
26
27
28
29
30
# File 'lib/mobilis/rails_project.rb', line 23

def database
  links.each do |link|
    project = @metaproject.project_by_name link
    return project if project.instance_of? Mobilis::PostgresqlInstance
    return project if project.instance_of? Mobilis::MysqlInstance
  end
  return nil
end

#generateObject



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/mobilis/rails_project.rb', line 75

def generate
  rails_run_command rails_new_command_line
  Dir.chdir name do
    git_commit_all "rails new"
    generate_bundle_run
    read_rails_master_key
    install_rspec if options.include? :rspec
    install_factory_bot if options.include? :factory_bot
    git_commit_all "add Gems"
    generate_wait_until
    generate_Dockerfile
    generate_entrypoint_sh
    generate_build_sh
    git_commit_all "add Dockerfile and build script etc"
  end
end

#generate_bundle_runObject



192
193
194
195
196
197
198
199
200
# File 'lib/mobilis/rails_project.rb', line 192

def generate_bundle_run
  Mobilis.logger.info "Installing bundle_run.sh"

  set_file_contents "bundle_run.sh", "#!/bin/bash
set -euo pipefail
bundle install
$@
"
end

#generate_DockerfileObject



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/mobilis/rails_project.rb', line 124

def generate_Dockerfile
  set_file_contents "Dockerfile", <<DOCKER_END
FROM ruby:latest
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client default-mysql-client dos2unix
WORKDIR /myapp
COPY --chmod=0755 wait-until /myapp/wait-until
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp

# Add a script to be executed every time the container starts.
RUN chmod +x /myapp/entrypoint.sh
ENTRYPOINT ["/myapp/entrypoint.sh"]
EXPOSE 3000
RUN dos2unix /myapp/entrypoint.sh

# Configure the main process to run when running the image
CMD ["rails", "server", "-b", "0.0.0.0"]
DOCKER_END
end

#generate_entrypoint_shObject



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/mobilis/rails_project.rb', line 146

def generate_entrypoint_sh
  set_file_contents "entrypoint.sh", <<ENTRYPOINT_SH
#!/bin/sh

# https://stackoverflow.com/a/38732187/1935918
set -e

if [ -f /app/tmp/pids/server.pid ]; then
  rm /app/tmp/pids/server.pid
fi
#{ wait_until_line }
bundle exec rake db:migrate 2>/dev/null || bundle exec rake db:setup

exec bundle exec "$@"
ENTRYPOINT_SH
end

#generate_wait_untilObject



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/mobilis/rails_project.rb', line 100

def generate_wait_until
  set_file_contents 'wait-until', <<WAITUNTIL
#!/usr/bin/env bash
# https://github.com/nickjj/wait-until under MIT license

command="${1}"
timeout="${2:-30}"

i=1
until eval "${command}"
do
    ((i++))

    if [ "${i}" -gt "${timeout}" ]; then
        echo "command was never successful, aborting due to ${timeout}s timeout!"
        exit 1
    fi

    sleep 1
done
WAITUNTIL
end

#install_factory_botObject



183
184
185
186
187
188
189
190
# File 'lib/mobilis/rails_project.rb', line 183

def install_factory_bot
  Mobilis.logger.info "Installing FactoryBot"
  append_line "Gemfile", "gem 'factory_bot_rails'"
  set_file_contents "spec/support/factory_bot.rb", "RSpec.configure do |config|
  config.include FactoryBot::Syntax::Methods
end
"
end

#install_rspecObject



177
178
179
180
181
# File 'lib/mobilis/rails_project.rb', line 177

def install_rspec
  Mobilis.logger.info "Installing rspec"
  append_line "Gemfile", 'gem "rspec-rails", group: [:development, :test]'
  bundle_run "rails generate rspec:install"
end

#install_super_diffObject



202
203
204
205
# File 'lib/mobilis/rails_project.rb', line 202

def install_super_diff
  append_line "Gemfile", "gem 'super_diff', group: [:development]"
  set_second_line 'spec/spec_helper.rb', 'require "super_diff/rspec"'
end

#modelsObject



19
20
21
# File 'lib/mobilis/rails_project.rb', line 19

def models
  @data[:models]
end

#rails_builder_imageObject



63
64
65
# File 'lib/mobilis/rails_project.rb', line 63

def rails_builder_image
  "#{ @metaproject.username }/rails-builder"
end

#rails_master_keyObject



96
97
98
# File 'lib/mobilis/rails_project.rb', line 96

def rails_master_key
  @data[:attributes][:rails_master_key]
end

#rails_new_command_lineObject



207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/mobilis/rails_project.rb', line 207

def rails_new_command_line
  pieces = ["bundle", "exec", "rails", "new", name, "."]
  pieces << "--api" if options.include? :api
  my_db = database
  if my_db then
    pieces << "--database=#{ my_db.type }"
  end
  if Mobilis::OS.linux?
    pieces << "-u #{ Process.uid }:#{ Process.gid }"
  end
  pieces.join " "
end

#rails_run_command(command) ⇒ Object



67
68
69
# File 'lib/mobilis/rails_project.rb', line 67

def rails_run_command command
  run_docker "run --rm -v #{ getwd }:/usr/src/app -w /usr/src/app #{ rails_builder_image } #{ command }"
end

#read_rails_master_keyObject



92
93
94
# File 'lib/mobilis/rails_project.rb', line 92

def read_rails_master_key
  @data[:attributes][:rails_master_key] = File.read("config/master.key")
end

#remove_rails_option(option) ⇒ Object



47
48
49
# File 'lib/mobilis/rails_project.rb', line 47

def remove_rails_option option
  options.reject! {|x| x == option }
end

#toggle_rails_api_modeObject



32
33
34
35
36
37
38
39
40
# File 'lib/mobilis/rails_project.rb', line 32

def toggle_rails_api_mode
  if options.include? :api then
    remove_rails_option :api
    add_rails_option :haml
  else
    add_rails_option :api
    remove_rails_option :haml
  end
end

#wait_until_lineObject



163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/mobilis/rails_project.rb', line 163

def wait_until_line
  if database.instance_of? Mobilis::PostgresqlInstance
    return <<POSTGRES_LINE
/myapp/wait-until "psql postgres://#{ database.username }:#{ database.password }@#{ database.name }/#{ name }_production -c 'select 1'"
POSTGRES_LINE
  end
# instance_of? is a code smell - maybe this should be database.wait_until_line ?
  if database.instance_of? Mobilis::MysqlInstance
    return <<MYSQL_LINE
/myapp/wait-until "mysql -D #{ name }_production -h #{ database.name } -u #{ database.username } -p#{ database.password } -e 'select 1'"
MYSQL_LINE
  end
end