appril 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
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