appril 0.0.0

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.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +4 -0
  3. data/Rakefile +1 -0
  4. data/app/.gitignore +6 -0
  5. data/app/.pryrc +1 -0
  6. data/app/Gemfile +5 -0
  7. data/app/Rakefile +1 -0
  8. data/app/base/api/.ignore +0 -0
  9. data/app/base/base_controller.rb +3 -0
  10. data/app/base/boot.rb +2 -0
  11. data/app/base/core.coffee +91 -0
  12. data/app/base/helpers/application_helpers.rb +1 -0
  13. data/app/base/load.rb +0 -0
  14. data/app/base/load_controllers.rb +2 -0
  15. data/app/base/rtcp_controller.rb +22 -0
  16. data/app/config/config.rb +9 -0
  17. data/app/config/config.yml +18 -0
  18. data/app/config/env/development.yml +0 -0
  19. data/app/config/env/production.yml +0 -0
  20. data/app/config/env/stage.yml +0 -0
  21. data/app/config/env/test.yml +0 -0
  22. data/app/config.ru +3 -0
  23. data/app/core/Gemfile +4 -0
  24. data/app/core/boot.rb +16 -0
  25. data/app/core/generate_configs.rb +7 -0
  26. data/app/core/load.rb +7 -0
  27. data/app/core/load_controllers.rb +15 -0
  28. data/app/generators/api/.ignore +0 -0
  29. data/app/package.json +5 -0
  30. data/app/public/.ignore +0 -0
  31. data/app/webpack.config.js +48 -0
  32. data/appril.gemspec +22 -0
  33. data/bin/appril +5 -0
  34. data/docker/Dockerfile +5 -0
  35. data/docker/run +68 -0
  36. data/docker/skel/build.sh +1 -0
  37. data/docker/skel/cleanup.sh +7 -0
  38. data/docker/skel/config.yml +24 -0
  39. data/docker/skel/prepare_build.sh +5 -0
  40. data/docker/skel/start.sh +1 -0
  41. data/docker/start +7 -0
  42. data/lib/appril/base_controller.rb +5 -0
  43. data/lib/appril/cli/app/install.rb +42 -0
  44. data/lib/appril/cli/app/update.rb +26 -0
  45. data/lib/appril/cli/app.rb +10 -0
  46. data/lib/appril/cli/assertions.rb +60 -0
  47. data/lib/appril/cli/docker/build.rb +150 -0
  48. data/lib/appril/cli/docker/install.rb +21 -0
  49. data/lib/appril/cli/docker/update.rb +24 -0
  50. data/lib/appril/cli/docker.rb +16 -0
  51. data/lib/appril/cli/generator.rb +15 -0
  52. data/lib/appril/cli/helpers.rb +47 -0
  53. data/lib/appril/cli.rb +197 -0
  54. data/lib/appril/rtcp_controller.rb +103 -0
  55. data/lib/appril/version.rb +3 -0
  56. data/lib/appril.rb +124 -0
  57. metadata +128 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 24e685cd503a9c6bfec968166f714202f28f361f
4
+ data.tar.gz: bdd9a95c3d72a26b5a5684e3787a6d6cd0d3e413
5
+ SHA512:
6
+ metadata.gz: d22c4a7fdf3e7ba520ccd6bf22412e2b6ad4a7ff58ce524726257f7845e499c42ffa764e56db4a2f1384e2f830f90b26153c2f7fb4f45f453cb8673d2b19395d
7
+ data.tar.gz: 63c6c60a20397645e84f5048894fe52c640179ea5e388367ab9835430472e46e3bd068b6eecd188e4e68caf8d1cf883126a3049c8737bf9cb59ddc47eb30c486
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in appril.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
data/app/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ .git
2
+ node_modules
3
+ var
4
+ tmp
5
+ Gemfile.lock
6
+ __tmpbuildir__
data/app/.pryrc ADDED
@@ -0,0 +1 @@
1
+ require File.expand_path('../core/load', __FILE__)
data/app/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+ # keep this line
3
+ eval File.read(File.expand_path('../core/Gemfile', __FILE__))
4
+
5
+ # add your gems here
data/app/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require File.expand_path('../core/boot', __FILE__)
File without changes
@@ -0,0 +1,3 @@
1
+ class BaseController < Appril::BaseController
2
+ map Cfg.server_url
3
+ end
data/app/base/boot.rb ADDED
@@ -0,0 +1,2 @@
1
+ # first file to be loaded when app starts.
2
+ # it is loaded on bare metal, e.g. before any gems, configs, helpers.
@@ -0,0 +1,91 @@
1
+ _ =
2
+ merge: require('lodash/merge')
3
+ #end
4
+
5
+ CONSIDER_IDLE_AFTER = 5 * 60
6
+
7
+ Core = require('appril')
8
+ Page = require('appril/page')
9
+ Load = require('appril/load')
10
+ Render = require('appril/render')
11
+ ActivityObserver = require('appril/activity_observer')
12
+
13
+ # require 'appril/polyfills'
14
+
15
+ window.App = {}
16
+
17
+ for k, v of require('appril/util')
18
+ App[k] = v
19
+ #end
20
+
21
+ # for k, v of require('appril/util/datetime')
22
+ # App[k] = v
23
+ # #end
24
+ #
25
+ # for k, v of require('appril/util/alert')
26
+ # App[k] = v
27
+ # #end
28
+
29
+ Render.default_el = '#content'
30
+ Render.global_data = {App: App}
31
+ Render.global_handlers = {}
32
+
33
+
34
+ Core.on_initialize = (msg) ->
35
+
36
+ for k, v of msg.data
37
+ App[k] = v
38
+ #end
39
+
40
+ ActivityObserver CONSIDER_IDLE_AFTER, (status) ->
41
+ # close connection if user went away
42
+ Core.disconnect() if status == 'away'
43
+ #end
44
+
45
+ #end
46
+
47
+
48
+ Core.on_controllers_ready = (controllers) ->
49
+ for name, controller of controllers
50
+ App[name] = controller
51
+ #end
52
+ #end
53
+
54
+
55
+ deploy_api = (api) ->
56
+ try
57
+ App.layout?.teardown()
58
+ #end
59
+
60
+ env = _.merge({
61
+ render: Render,
62
+ render_component: Render.component,
63
+ render_string: Render.string
64
+ }, new Page)
65
+
66
+ App.layout = env.render
67
+ el: 'body'
68
+ template: "<div id='#{Render.default_el}'></div>"
69
+ oncomplete: ->
70
+ new api(env)
71
+ #end
72
+ #end
73
+ #end
74
+
75
+
76
+ Core.on_controller_matched = (controller, context) ->
77
+ controller.load (api) ->
78
+ context.save()
79
+ deploy_api(api)
80
+ #end
81
+
82
+ # Core.on_socket_open = (socket) ->
83
+
84
+ # Core.on_socket_close = ->
85
+
86
+ document.addEventListener 'DOMContentLoaded', ->
87
+ # make sure this matches the RTCPController URL.
88
+ # if URL differs on various environments determine effective environment and use appropriate URL.
89
+ # a good approach to determine effective environment is to look into window.location.hostname
90
+ Core.connect('__rtcp__')
91
+ #end
@@ -0,0 +1 @@
1
+ # this file will be loaded before other files found in helpers/ folder
data/app/base/load.rb ADDED
File without changes
@@ -0,0 +1,2 @@
1
+ # All "official" controllers are loaded by core/load_controllers.rb
2
+ # This file is intended to load any "custom" controllers, ones that are not seen by default loader.
@@ -0,0 +1,22 @@
1
+ class RTCPController < Appril::RTCPController
2
+ map File.join(Cfg.server_url, '__rtcp__')
3
+
4
+ private
5
+ # called after socket connection established
6
+ def connected
7
+ end
8
+
9
+ # data sent to client after connection established
10
+ def initialization_data
11
+ {}
12
+ end
13
+
14
+ # merged into original env when calling a controller
15
+ def rtcp_env
16
+ {}
17
+ end
18
+
19
+ # called when socket connection closed
20
+ def disconnected
21
+ end
22
+ end
@@ -0,0 +1,9 @@
1
+
2
+ # loading .yml configs from current directory. config.yml will be loaded first.
3
+ Cfg = Appril.load_config(File.expand_path('..', __FILE__))
4
+
5
+ # it is highly recommended to freeze configs so they stay unaltered on runtime.
6
+ Cfg.freeze
7
+
8
+ # loading any .rb files in current dir. this one will be skipped automatically.
9
+ Dir[File.expand_path('../**/*.rb', __FILE__)].each {|f| require(f)}
@@ -0,0 +1,18 @@
1
+
2
+ # configs here will be the same on all environments.
3
+ # if some configs differs on some environment,
4
+ # put them into appropriate env/[ENVIRONMENT].yml file
5
+
6
+ # multiple .yml files allowed in config folder.
7
+ # for example config/db.yml file will be loaded into Cfg.db in server app.
8
+ # arbitrary .yml files can have environment related configs.
9
+
10
+
11
+ # base URL for server app
12
+ server_url: /
13
+
14
+ # base URL for compiled client app
15
+ client_url: /app
16
+
17
+ # where webpack should install compiled app. relative to webpack.config.js
18
+ client_path: ./public
File without changes
File without changes
File without changes
File without changes
data/app/config.ru ADDED
@@ -0,0 +1,3 @@
1
+ require File.expand_path('../core/load', __FILE__)
2
+
3
+ run RocketIO::Application.new
data/app/core/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ # do NOT edit this file, edit ../Gemfile instead
2
+ gem 'appril'
3
+ gem 'rocketio'
4
+ gem 'tubesock'
data/app/core/boot.rb ADDED
@@ -0,0 +1,16 @@
1
+ # do NOT edit this file, edit base/boot.rb instead
2
+
3
+ require 'yaml'
4
+
5
+ Dir.chdir File.expand_path('../..', __FILE__) do
6
+ require './base/boot'
7
+
8
+ require 'bundler/setup'
9
+ Bundler.require(:default)
10
+ Bundler.require(RocketIO.environment)
11
+
12
+ require './config/config'
13
+
14
+ require './base/helpers/application_helpers'
15
+ Dir['./base/helpers/**/*.rb'].each {|f| require(f)}
16
+ end
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # do NOT edit this file
4
+
5
+ require File.expand_path('../load', __FILE__)
6
+
7
+ Appril.generate_configs(File.expand_path('../..', __FILE__))
data/app/core/load.rb ADDED
@@ -0,0 +1,7 @@
1
+ # do NOT edit this file, edit base/load.rb instead
2
+
3
+ %w[
4
+ boot
5
+ ../base/load
6
+ load_controllers
7
+ ].each {|f| require File.expand_path("../#{f}", __FILE__)}
@@ -0,0 +1,15 @@
1
+ # do NOT edit this file, edit base/load_controllers.rb instead
2
+
3
+ Dir.chdir File.expand_path('../..', __FILE__) do
4
+
5
+ require './base/base_controller'
6
+ require './base/rtcp_controller'
7
+
8
+ %w[
9
+ **/server.rb
10
+ ].each_with_object([]) {|f,o| o.concat(Dir["./base/api/#{f}"])}.sort {|a,b|
11
+ a.split(/\/+/).size <=> b.split(/\/+/).size
12
+ }.each {|f| require(f)}
13
+
14
+ require './base/load_controllers'
15
+ end
File without changes
data/app/package.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "dependencies": {
3
+ "appril": "*"
4
+ }
5
+ }
File without changes
@@ -0,0 +1,48 @@
1
+ var webpack = require('webpack'),
2
+ fs = require('fs'),
3
+ child_process = require('child_process')
4
+ ;
5
+
6
+ if (process.env.APP_ENV == 'development') {
7
+ console.log('Generating configs...');
8
+ child_process.execSync('./core/generate_configs.rb');
9
+ }
10
+
11
+ var setup = JSON.parse(fs.readFileSync('./config.json')).webpack;
12
+ console.log(JSON.stringify(setup, null, 2))
13
+
14
+ module.exports = {
15
+ entry: setup.entries,
16
+ output: {
17
+ path: [setup.path, setup.url].join('/'),
18
+ filename: '[name].js',
19
+ publicPath: setup.url + '/', // trailing slash required
20
+ libraryTarget: 'commonjs2'
21
+ },
22
+ module: {
23
+ loaders: [
24
+ // { test: /\.coffee$/, loader: 'coffee-loader' },
25
+ // { test: /\.css$/, loader: 'style-loader!css-loader' },
26
+ // { test: /\.json$/, loader: 'json-loader' },
27
+ // { test: /\.otf($|\?)/, loader: require.resolve('file-loader') },
28
+ // { test: /\.ttf($|\?)/, loader: require.resolve('file-loader') },
29
+ // { test: /\.eot($|\?)/, loader: require.resolve('file-loader') },
30
+ // { test: /\.svg($|\?)/, loader: require.resolve('file-loader') },
31
+ // { test: /\.png($|\?)/, loader: require.resolve('url-loader') + '?limit=10000&mimetype=image/png' },
32
+ // { test: /\.jpg($|\?)/, loader: require.resolve('file-loader') },
33
+ // { test: /\.gif($|\?)/, loader: require.resolve('file-loader') },
34
+ // { test: /\.woff[2]?($|\?)/, loader: require.resolve('url-loader') + '?limit=10000&mimetype=application/font-woff' },
35
+ ]
36
+ },
37
+ resolve: {
38
+ extensions: ['', '.js', '.css', '.json', '.coffee', '.html'],
39
+ alias: {
40
+ app: __dirname,
41
+ base: 'app/base',
42
+ api: 'base/api',
43
+ }
44
+ },
45
+ plugins: [
46
+ new webpack.optimize.CommonsChunkPlugin('core', 'core.js'),
47
+ ]
48
+ }
data/appril.gemspec ADDED
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+ require File.expand_path('../lib/appril/version', __FILE__)
3
+
4
+ Gem::Specification.new do |spec|
5
+ spec.name = 'appril'
6
+ spec.version = Appril::VERSION
7
+ spec.authors = ['Slee Woo']
8
+ spec.email = ['mail@sleewoo.com']
9
+ spec.summary = [spec.name, spec.version]*'-',
10
+ spec.description = 'Opinionated framework for building opinionated web applications'
11
+ spec.homepage = 'https://github.com/sleewoo/' + spec.name
12
+ spec.license = 'MIT'
13
+
14
+ spec.files = Dir['**/{*,.[a-z]*}'].reject {|e| e =~ /(gem|lock)\z/}
15
+ spec.require_paths = ['lib']
16
+ spec.executables = Dir['bin/*'].map {|f| File.basename(f)}
17
+
18
+ spec.required_ruby_version = '~> 2.0'
19
+
20
+ spec.add_runtime_dependency 'rocketio', '~> 0'
21
+ spec.add_runtime_dependency 'tubesock', '~> 0'
22
+ end
data/bin/appril ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift(File.expand_path('../../lib', __FILE__))
3
+ require 'appril'
4
+ require 'appril/cli'
5
+ Appril::CLI.new($*)
data/docker/Dockerfile ADDED
@@ -0,0 +1,5 @@
1
+ FROM appril/base
2
+ COPY start /
3
+ COPY build /build
4
+ RUN sh /build/build && sh /build/cleanup && mkdir /app
5
+ CMD sh /start
data/docker/run ADDED
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env bash
2
+
3
+ run() {
4
+ echo -e "\n$ $@"
5
+ "$@"
6
+ }
7
+
8
+ container_is_built() {
9
+ [[ -n $(docker ps -a | grep -E "\s$CONTAINER_NAME\s") ]]
10
+ }
11
+
12
+ container_is_running() {
13
+ [[ -n $(docker ps | grep -E "\s$CONTAINER_NAME\s") ]]
14
+ }
15
+
16
+ stop_container() {
17
+ run docker stop $CONTAINER_NAME
18
+ }
19
+
20
+ remove_container() {
21
+ run docker rm $CONTAINER_NAME
22
+ }
23
+
24
+ env_prompt() {
25
+ read APP_ENV
26
+ [ "$(echo " {environments} " | grep -E "\s$APP_ENV\s")" = "" ] && env_prompt
27
+ }
28
+
29
+ if [ "$APP_ENV" = "" ]; then
30
+ echo "APP_ENV not set, please use one of"
31
+ echo "{environments}"
32
+ echo -n "> "
33
+ env_prompt
34
+ fi
35
+
36
+ set -e
37
+
38
+ {container_definitions}
39
+
40
+ if [ "$CONTAINER_NAME" = "" ]; then
41
+ echo -e "\n\t::: $APP_ENV environment not supported. Use one of: {environments} :::\n"
42
+ exit 1
43
+ fi
44
+
45
+ APP_UID="$(id -u)"
46
+ APP_GID="$(id -g)"
47
+ APP_DIR="$(cd "$(dirname ${BASH_SOURCE[0]})/{script_path_traversal}"; pwd)"
48
+
49
+ if [ "$APP_UID" = "0" ]; then
50
+ echo -e "\n\t::: No superpowers accepted here! Run this as a regular user :::\n"
51
+ exit 1
52
+ fi
53
+
54
+ run docker pull {image}
55
+ container_is_running && stop_container
56
+ container_is_built && remove_container
57
+
58
+ run docker run \
59
+ --name "$CONTAINER_NAME" \
60
+ -e APP_ENV="$APP_ENV" \
61
+ -e APP_UID="$APP_UID" \
62
+ -e APP_GID="$APP_GID" \
63
+ -e LANG="en_US.UTF-8" \
64
+ -e LC_ALL="en_US.UTF-8" \
65
+ -e LC_TYPE="en_US.UTF-8" \
66
+ -v "$APP_DIR":/app \
67
+ {run_opts} {image}
68
+ echo
@@ -0,0 +1 @@
1
+ # running inside container.
@@ -0,0 +1,7 @@
1
+ set -e
2
+
3
+ apk del build-base libxml2-dev libxslt-dev \
4
+ ruby-dev postgresql-dev imagemagick-dev \
5
+ nodejs-dev python git
6
+
7
+ rm -rf /var/cache/apk/*
@@ -0,0 +1,24 @@
1
+ # a image with this name will be built (see prepare_build.sh and build.sh)
2
+ IMAGE_NAME:
3
+
4
+ # the name of container to be run on your server(s).
5
+ # name depends on APP_ENV variable.
6
+ # you can add/remove environments but at least one is required.
7
+ CONTAINER_NAME:
8
+ development:
9
+ test:
10
+ stage:
11
+ production:
12
+
13
+ # path to app.
14
+ # should be absolute or relative to this file.
15
+ APP_DIR:
16
+
17
+ # a file with this name will be generated and installed inside APP_DIR.
18
+ RUN_SCRIPT: docker/run
19
+
20
+ # options passed to `docker build`
21
+ BUILD_OPTS: --force-rm --no-cache
22
+
23
+ # options passed to `docker run`
24
+ RUN_OPTS: -d --restart always
@@ -0,0 +1,5 @@
1
+ # running before image building started.
2
+ # will run inside building dir so copy into ./ any files you need for building.
3
+ # APP_DIR variable points to your app directory
4
+ # so use it to copy any files from your app into building dir.
5
+ # running outside container, e.g. on your dev machine.
@@ -0,0 +1 @@
1
+ # start your app
data/docker/start ADDED
@@ -0,0 +1,7 @@
1
+ set -e
2
+
3
+ [ "$(getent group $APP_GID)" = "" ] && addgroup -g $APP_GID app
4
+
5
+ [ "$(getent passwd $APP_UID)" = "" ] && adduser -D -u $APP_UID -G app app
6
+
7
+ {start}
@@ -0,0 +1,5 @@
1
+ module Appril
2
+ class BaseController < RocketIO::Controller
3
+
4
+ end
5
+ end
@@ -0,0 +1,42 @@
1
+ module Appril
2
+ class CLI
3
+ class App
4
+ class Install
5
+ include Helpers
6
+
7
+ def initialize dir, namespace: nil, working_dir_opted: false
8
+ install(dir, working_dir_opted)
9
+ make_executable(dir / 'core/generate_configs.rb')
10
+ add_namespace(dir, namespace) if namespace
11
+ puts "Done. All files installed into #{dir}"
12
+ end
13
+
14
+ def install dir, working_dir_opted
15
+ src = working_dir_opted ? BASE_DIR.to_path + '/.' : BASE_DIR
16
+ FileUtils.cp_r(src, dir)
17
+ cleanup(dir)
18
+ end
19
+
20
+ def add_namespace dir, namespace
21
+ %w[
22
+ base/base_controller.rb
23
+ base/rtcp_controller.rb
24
+ config/config.rb
25
+ ].each do |file|
26
+ code = File.read(dir / file)
27
+ File.open dir / file, 'w' do |f|
28
+ f.puts "module #{namespace}"
29
+ code.split("\n").each {|l| f.puts " #{l}"}
30
+ f.puts "end"
31
+ end
32
+ end
33
+ end
34
+
35
+ def cleanup dir
36
+ Dir[dir / "**/.ignore"].each {|f| FileUtils.rm_f(f)}
37
+ end
38
+
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,26 @@
1
+ module Appril
2
+ class CLI
3
+ class App
4
+ class Update
5
+ include Helpers
6
+
7
+ def initialize dir
8
+ FileUtils.rm_rf(dir / 'core')
9
+ Dir.chdir BASE_DIR do
10
+
11
+ Dir['**/*'].select {|e| File.file?(e)}.each do |file|
12
+ next if File.file?(dir / file)
13
+ create_dirname_for(dir / file)
14
+ puts "Installing #{File.basename(dir)}/#{file}"
15
+ FileUtils.cp(file, dir / file)
16
+ end
17
+
18
+ end
19
+ make_executable(dir / 'core/generate_configs.rb')
20
+ puts "Done"
21
+ end
22
+
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,10 @@
1
+ module Appril
2
+ class CLI
3
+ class App
4
+ BASE_DIR = (Appril::BASE_DIR / 'app').freeze
5
+ end
6
+ end
7
+ end
8
+
9
+ require 'appril/cli/app/install'
10
+ require 'appril/cli/app/update'
@@ -0,0 +1,60 @@
1
+ module Appril
2
+ class CLI
3
+ module Assertions
4
+
5
+ def assert_directory_provided dir
6
+ return if dir
7
+ fatal_error! "Please provide a directory"
8
+ end
9
+
10
+ def assert_installable_dir dir, working_dir_opted
11
+ if working_dir_opted
12
+ assert_empty_directory(dir)
13
+ else
14
+ assert_directory_does_not_exists(dir)
15
+ end
16
+ end
17
+
18
+ def assert_is_docker_dir dir
19
+ return if File.exists?(dir / Docker::CONFIG_FILE)
20
+ fatal_error! "#{dir} does not look like a Appril docker dir"
21
+ end
22
+
23
+ def assert_is_app_dir dir
24
+ return if %w[
25
+ core
26
+ base/api
27
+ config
28
+ ].all? {|e| File.exists?(dir / e)}
29
+ fatal_error! "#{dir} does not look like a Appril app dir"
30
+ end
31
+
32
+ def assert_empty_directory dir
33
+ return if Dir[dir / '*'].empty?
34
+ fatal_error! "#{dir} should be empty"
35
+ end
36
+
37
+ def assert_directory_exists dir
38
+ return if File.directory?(dir)
39
+ fatal_error! "#{dir} should be a directory"
40
+ end
41
+
42
+ def assert_directory_does_not_exists dir
43
+ return unless File.exists?(dir)
44
+ fatal_error! "#{dir} already exists"
45
+ end
46
+
47
+ def assert_config_file_exists dir
48
+ return if File.file?(dir / Docker::CONFIG_FILE)
49
+ fatal_error! "#{dir / Docker::CONFIG_FILE} file is missing"
50
+ end
51
+
52
+ def assert_valid_api_name_given api_name
53
+ api_name || fatal_error!('Please provide api name')
54
+ api_name =~ /\W/ && fatal_error!('Api name should contain only alphanumerics')
55
+ api_name =~ /\A[a-z]/i || fatal_error!('Api name should start with a letter')
56
+ end
57
+
58
+ end
59
+ end
60
+ end