appril-cli 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/Rakefile +1 -0
- data/appril-cli.gemspec +19 -0
- data/bin/appril +4 -0
- data/boilerplate/app/.gitignore +6 -0
- data/boilerplate/app/.pryrc +1 -0
- data/boilerplate/app/Gemfile +6 -0
- data/boilerplate/app/Rakefile +1 -0
- data/boilerplate/app/base/api/base_controller.rb +21 -0
- data/boilerplate/app/base/api/index/client.coffee +4 -0
- data/boilerplate/app/base/api/index/layout.html +3 -0
- data/boilerplate/app/base/api/index/server.rb +3 -0
- data/boilerplate/app/base/api/rtcp_controller.rb +22 -0
- data/boilerplate/app/base/assets/styles.css +0 -0
- data/boilerplate/app/base/boot.rb +2 -0
- data/boilerplate/app/base/core.coffee +143 -0
- data/boilerplate/app/base/helpers/application_helpers.coffee +1 -0
- data/boilerplate/app/base/helpers/application_helpers.rb +4 -0
- data/boilerplate/app/base/load.rb +0 -0
- data/boilerplate/app/base/models/base_model.rb +0 -0
- data/boilerplate/app/base/templates/access_denied.html +3 -0
- data/boilerplate/app/base/templates/layout.liquid +11 -0
- data/boilerplate/app/base/templates/layouts/main.html +1 -0
- data/boilerplate/app/base/templates/layouts/none.html +1 -0
- data/boilerplate/app/config/config.rb +9 -0
- data/boilerplate/app/config/config.yml +18 -0
- data/boilerplate/app/config/env/development.yml +0 -0
- data/boilerplate/app/config/env/production.yml +0 -0
- data/boilerplate/app/config/env/stage.yml +0 -0
- data/boilerplate/app/config/env/test.yml +0 -0
- data/boilerplate/app/config.ru +3 -0
- data/boilerplate/app/core/Gemfile +4 -0
- data/boilerplate/app/core/boot.rb +16 -0
- data/boilerplate/app/core/generate_configs.rb +125 -0
- data/boilerplate/app/core/load.rb +14 -0
- data/boilerplate/app/core/load_controllers.rb +14 -0
- data/boilerplate/app/generators/api/client.coffee +4 -0
- data/boilerplate/app/generators/api/layout.html +0 -0
- data/boilerplate/app/generators/api/server.rb +3 -0
- data/boilerplate/app/package.json +10 -0
- data/boilerplate/app/public/.ignore +0 -0
- data/boilerplate/app/tmp/.ignore +0 -0
- data/boilerplate/app/var/.ignore +0 -0
- data/boilerplate/app/webpack.config.js +53 -0
- data/boilerplate/crudle/Gemfile +7 -0
- data/boilerplate/crudle/base/core.coffee +128 -0
- data/boilerplate/crudle/base/templates/menu.html +3 -0
- data/boilerplate/crudle/generators/api/client.coffee +11 -0
- data/boilerplate/crudle/generators/api/editor.html +0 -0
- data/boilerplate/crudle/generators/api/server.rb +26 -0
- data/boilerplate/crudle/package.json +15 -0
- data/boilerplate/crudle/webpack.config.js +54 -0
- data/docker/Dockerfile +5 -0
- data/docker/run +66 -0
- data/docker/skel/build.sh +1 -0
- data/docker/skel/cleanup.sh +7 -0
- data/docker/skel/config.yml +24 -0
- data/docker/skel/prepare_build.sh +5 -0
- data/docker/skel/start.sh +1 -0
- data/docker/start +7 -0
- data/lib/appril-cli/app/install.rb +46 -0
- data/lib/appril-cli/app/update.rb +27 -0
- data/lib/appril-cli/app.rb +46 -0
- data/lib/appril-cli/assertions.rb +60 -0
- data/lib/appril-cli/docker/build.rb +152 -0
- data/lib/appril-cli/docker/install.rb +23 -0
- data/lib/appril-cli/docker/update.rb +26 -0
- data/lib/appril-cli/docker.rb +61 -0
- data/lib/appril-cli/generator/api.rb +16 -0
- data/lib/appril-cli/generator.rb +32 -0
- data/lib/appril-cli/helpers.rb +47 -0
- data/lib/appril-cli/version.rb +5 -0
- data/lib/appril-cli.rb +102 -0
- data/sandbox/.gitignore +6 -0
- data/sandbox/.pryrc +1 -0
- data/sandbox/Gemfile +7 -0
- data/sandbox/Rakefile +1 -0
- data/sandbox/base/api/base_controller.rb +21 -0
- data/sandbox/base/api/index/client.coffee +4 -0
- data/sandbox/base/api/index/layout.html +3 -0
- data/sandbox/base/api/index/server.rb +3 -0
- data/sandbox/base/api/rtcp_controller.rb +22 -0
- data/sandbox/base/assets/styles.css +0 -0
- data/sandbox/base/boot.rb +2 -0
- data/sandbox/base/core.coffee +128 -0
- data/sandbox/base/helpers/application_helpers.coffee +1 -0
- data/sandbox/base/helpers/application_helpers.rb +4 -0
- data/sandbox/base/load.rb +0 -0
- data/sandbox/base/models/base_model.rb +0 -0
- data/sandbox/base/templates/access_denied.html +3 -0
- data/sandbox/base/templates/layout.liquid +11 -0
- data/sandbox/base/templates/layouts/main.html +1 -0
- data/sandbox/base/templates/layouts/none.html +1 -0
- data/sandbox/base/templates/menu.html +3 -0
- data/sandbox/config/config.rb +9 -0
- data/sandbox/config/config.yml +18 -0
- data/sandbox/config/env/development.yml +0 -0
- data/sandbox/config/env/production.yml +0 -0
- data/sandbox/config/env/stage.yml +0 -0
- data/sandbox/config/env/test.yml +0 -0
- data/sandbox/config.ru +3 -0
- data/sandbox/core/Gemfile +4 -0
- data/sandbox/core/boot.rb +16 -0
- data/sandbox/core/generate_configs.rb +125 -0
- data/sandbox/core/load.rb +14 -0
- data/sandbox/core/load_controllers.rb +14 -0
- data/sandbox/generators/api/client.coffee +11 -0
- data/sandbox/generators/api/editor.html +0 -0
- data/sandbox/generators/api/layout.html +0 -0
- data/sandbox/generators/api/server.rb +26 -0
- data/sandbox/package.json +15 -0
- data/sandbox/webpack.config.js +54 -0
- metadata +157 -0
@@ -0,0 +1,128 @@
|
|
1
|
+
_ =
|
2
|
+
merge: require('lodash/merge')
|
3
|
+
has: require('lodash/has')
|
4
|
+
isFunction: require('lodash/isFunction')
|
5
|
+
#end
|
6
|
+
|
7
|
+
Core = require('appril')
|
8
|
+
Page = require('appril-page')
|
9
|
+
Render = require('appril-ractive')
|
10
|
+
Reporter = require('appril-reporter')
|
11
|
+
require 'appril-polyfills'
|
12
|
+
require 'assets/styles.css'
|
13
|
+
|
14
|
+
CONSIDER_IDLE_AFTER = 5 * 60
|
15
|
+
|
16
|
+
window.Cfg = {}
|
17
|
+
window.Util = {}
|
18
|
+
window.App = {}
|
19
|
+
# window.Alert = require('appril-alert')
|
20
|
+
|
21
|
+
for k, v of require('appril-util')
|
22
|
+
Util[k] = v
|
23
|
+
#end
|
24
|
+
|
25
|
+
# for k, v of require('appril-datetime')
|
26
|
+
# Util[k] = v
|
27
|
+
# #end
|
28
|
+
|
29
|
+
for k, v of require('helpers/application_helpers.coffee')
|
30
|
+
Util[k] = v
|
31
|
+
#end
|
32
|
+
|
33
|
+
Object.freeze(Util)
|
34
|
+
|
35
|
+
Render.default_el = -> '#content'
|
36
|
+
Render.global_data = -> {App: App, Cfg: Cfg, Util: Util}
|
37
|
+
Render.global_handlers = -> {}
|
38
|
+
|
39
|
+
for name, controller of Core.controllers
|
40
|
+
App[name] = controller
|
41
|
+
#end
|
42
|
+
|
43
|
+
Core.on_initialize = (msg) ->
|
44
|
+
if window.Cfg = msg.data.cfg
|
45
|
+
delete msg.data.cfg
|
46
|
+
Object.freeze(Cfg)
|
47
|
+
|
48
|
+
for k, v of msg.data
|
49
|
+
App[k] = v
|
50
|
+
#end
|
51
|
+
|
52
|
+
Reporter CONSIDER_IDLE_AFTER, (status) ->
|
53
|
+
# close connection if user went away
|
54
|
+
Core.disconnect() if status == 'away'
|
55
|
+
#end
|
56
|
+
#end
|
57
|
+
|
58
|
+
templates =
|
59
|
+
none: require('templates/layouts/none.html')
|
60
|
+
main: require('templates/layouts/main.html')
|
61
|
+
access_denied: require('templates/access_denied.html')
|
62
|
+
#end
|
63
|
+
|
64
|
+
partials = {}
|
65
|
+
|
66
|
+
Crudle = require('crudle')
|
67
|
+
CrudleList = require('crudle-list')
|
68
|
+
CrudleEditor = require('crudle-editor')
|
69
|
+
|
70
|
+
deploy_api = (api) ->
|
71
|
+
|
72
|
+
page = new Page
|
73
|
+
env = _.merge({
|
74
|
+
render: Render
|
75
|
+
render_component: Render.component
|
76
|
+
render_string: Render.string
|
77
|
+
}, page)
|
78
|
+
|
79
|
+
crudle = Crudle(api.controller.ws, page)
|
80
|
+
crudle.partials.menu = require('templates/menu.html')
|
81
|
+
crudle.data.url = api.controller.url
|
82
|
+
|
83
|
+
api(
|
84
|
+
env,
|
85
|
+
crudle,
|
86
|
+
CrudleList(api.controller.ws, page),
|
87
|
+
CrudleEditor(api.controller.ws, page)
|
88
|
+
)
|
89
|
+
#end
|
90
|
+
|
91
|
+
previous_api = null
|
92
|
+
Core.on_controller_matched = (controller, context) ->
|
93
|
+
|
94
|
+
controller.load (api) ->
|
95
|
+
context.save()
|
96
|
+
|
97
|
+
api.controller = controller
|
98
|
+
|
99
|
+
if previous_api?.teardown
|
100
|
+
previous_api.teardown()
|
101
|
+
#end
|
102
|
+
previous_api = api
|
103
|
+
|
104
|
+
if _.has(api, 'acl')
|
105
|
+
unless _.isFunction(api.acl)
|
106
|
+
throw new Error("#{controller.name}.acl should be a function")
|
107
|
+
|
108
|
+
if api.acl()
|
109
|
+
deploy_api(api)
|
110
|
+
else
|
111
|
+
Render
|
112
|
+
el: 'body'
|
113
|
+
template: templates.main
|
114
|
+
partials: partials
|
115
|
+
oncomplete: ->
|
116
|
+
Render(template: templates.access_denied)
|
117
|
+
#end
|
118
|
+
|
119
|
+
else
|
120
|
+
deploy_api(api)
|
121
|
+
#end
|
122
|
+
#end
|
123
|
+
#end
|
124
|
+
|
125
|
+
document.addEventListener 'DOMContentLoaded', ->
|
126
|
+
# make sure this matches the RTCPController URL.
|
127
|
+
Core.connect('__rtcp__')
|
128
|
+
#end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# refer to underlying controller as self.controller
|
2
|
+
|
3
|
+
self = (env, layout, list, editor) ->
|
4
|
+
editor.partials.editor = require('./editor')
|
5
|
+
layout.components =
|
6
|
+
list: env.render_component(list)
|
7
|
+
editor: env.render_component(editor)
|
8
|
+
env.render(layout)
|
9
|
+
#end
|
10
|
+
|
11
|
+
module.exports = self
|
File without changes
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class CONTROLLER_NAME < BaseController
|
2
|
+
include Crudle::Controller
|
3
|
+
|
4
|
+
private
|
5
|
+
def model; MODEL_NAME end
|
6
|
+
|
7
|
+
# def order; end
|
8
|
+
|
9
|
+
# def filter_by_name params, dataset
|
10
|
+
# return if params[:name].nil? || params[:name].empty?
|
11
|
+
# dataset.where('name LIKE ?', params[:name] + '%')
|
12
|
+
# end
|
13
|
+
|
14
|
+
# def list_serializer item
|
15
|
+
# serializer(item)
|
16
|
+
# end
|
17
|
+
|
18
|
+
# def editor_serializer item
|
19
|
+
# serializer(item)
|
20
|
+
# end
|
21
|
+
|
22
|
+
# def serializer item
|
23
|
+
# item
|
24
|
+
# end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
{
|
2
|
+
"name": "MyApp",
|
3
|
+
"version": "0.0.0",
|
4
|
+
"description": "...",
|
5
|
+
"dependencies": {
|
6
|
+
"appril": "*",
|
7
|
+
"appril-ractive": "*",
|
8
|
+
"appril-reporter": "*",
|
9
|
+
"appril-polyfills": "*",
|
10
|
+
"crudle": "*",
|
11
|
+
"crudle-list": "*",
|
12
|
+
"crudle-editor": "*",
|
13
|
+
"extract-text-webpack-plugin": "1"
|
14
|
+
}
|
15
|
+
}
|
@@ -0,0 +1,54 @@
|
|
1
|
+
var webpack = require('webpack'),
|
2
|
+
fs = require('fs'),
|
3
|
+
ExtractTextPlugin = require("extract-text-webpack-plugin"),
|
4
|
+
child_process = require('child_process')
|
5
|
+
;
|
6
|
+
|
7
|
+
if (process.env.APP_ENV == 'development') {
|
8
|
+
console.log('Generating configs...');
|
9
|
+
child_process.execSync('./core/generate_configs.rb');
|
10
|
+
}
|
11
|
+
|
12
|
+
var setup = JSON.parse(fs.readFileSync('./config.json')).webpack;
|
13
|
+
console.log(JSON.stringify(setup, null, 2))
|
14
|
+
|
15
|
+
module.exports = {
|
16
|
+
entry: setup.entries,
|
17
|
+
output: {
|
18
|
+
path: [setup.path, setup.url].join('/'),
|
19
|
+
filename: '[name].js',
|
20
|
+
publicPath: setup.url + '/', // trailing slash required
|
21
|
+
libraryTarget: 'commonjs2'
|
22
|
+
},
|
23
|
+
module: {
|
24
|
+
loaders: [
|
25
|
+
{ test: /\.coffee$/, loader: 'coffee-loader' },
|
26
|
+
{ test: /\.html$/, loader: 'ractive-loader' },
|
27
|
+
{ test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader") },
|
28
|
+
{ test: /\.json$/, loader: 'json-loader' },
|
29
|
+
{ test: /\.otf($|\?)/, loader: require.resolve('file-loader') },
|
30
|
+
{ test: /\.ttf($|\?)/, loader: require.resolve('file-loader') },
|
31
|
+
{ test: /\.eot($|\?)/, loader: require.resolve('file-loader') },
|
32
|
+
{ test: /\.svg($|\?)/, loader: require.resolve('file-loader') },
|
33
|
+
{ test: /\.png($|\?)/, loader: require.resolve('url-loader') + '?limit=10000&mimetype=image/png' },
|
34
|
+
{ test: /\.jpg($|\?)/, loader: require.resolve('file-loader') },
|
35
|
+
{ test: /\.gif($|\?)/, loader: require.resolve('file-loader') },
|
36
|
+
{ test: /\.woff[2]?($|\?)/, loader: require.resolve('url-loader') + '?limit=10000&mimetype=application/font-woff' },
|
37
|
+
]
|
38
|
+
},
|
39
|
+
resolve: {
|
40
|
+
extensions: ['', '.js', '.css', '.json', '.coffee', '.html'],
|
41
|
+
alias: {
|
42
|
+
app: __dirname,
|
43
|
+
base: 'app/base',
|
44
|
+
api: 'base/api',
|
45
|
+
helpers: 'base/helpers',
|
46
|
+
assets: 'base/assets',
|
47
|
+
templates: 'base/templates'
|
48
|
+
}
|
49
|
+
},
|
50
|
+
plugins: [
|
51
|
+
new webpack.optimize.CommonsChunkPlugin('core', 'core.js'),
|
52
|
+
new ExtractTextPlugin("[name].css")
|
53
|
+
]
|
54
|
+
}
|
data/docker/Dockerfile
ADDED
data/docker/run
ADDED
@@ -0,0 +1,66 @@
|
|
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
|
+
echo "Let's set APP_ENV"
|
30
|
+
echo "{environments}"
|
31
|
+
echo -n "> "
|
32
|
+
env_prompt
|
33
|
+
|
34
|
+
set -e
|
35
|
+
|
36
|
+
{container_definitions}
|
37
|
+
|
38
|
+
if [ "$CONTAINER_NAME" = "" ]; then
|
39
|
+
echo -e "\n\t::: $APP_ENV environment not supported. Use one of: {environments} :::\n"
|
40
|
+
exit 1
|
41
|
+
fi
|
42
|
+
|
43
|
+
APP_UID="$(id -u)"
|
44
|
+
APP_GID="$(id -g)"
|
45
|
+
APP_DIR="$(cd "$(dirname ${BASH_SOURCE[0]})/{script_path_traversal}"; pwd)"
|
46
|
+
|
47
|
+
if [ "$APP_UID" = "0" ]; then
|
48
|
+
echo -e "\n\t::: No superpowers accepted here! Run this as a regular user :::\n"
|
49
|
+
exit 1
|
50
|
+
fi
|
51
|
+
|
52
|
+
run docker pull {image}
|
53
|
+
container_is_running && stop_container
|
54
|
+
container_is_built && remove_container
|
55
|
+
|
56
|
+
run docker run \
|
57
|
+
--name "$CONTAINER_NAME" \
|
58
|
+
-e APP_ENV="$APP_ENV" \
|
59
|
+
-e APP_UID="$APP_UID" \
|
60
|
+
-e APP_GID="$APP_GID" \
|
61
|
+
-e LANG="en_US.UTF-8" \
|
62
|
+
-e LC_ALL="en_US.UTF-8" \
|
63
|
+
-e LC_TYPE="en_US.UTF-8" \
|
64
|
+
-v "$APP_DIR":/app \
|
65
|
+
{run_opts} {image}
|
66
|
+
echo
|
@@ -0,0 +1 @@
|
|
1
|
+
# running inside container.
|
@@ -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,46 @@
|
|
1
|
+
module Appril
|
2
|
+
class CLI
|
3
|
+
module App
|
4
|
+
|
5
|
+
class Install
|
6
|
+
include Helpers
|
7
|
+
|
8
|
+
def initialize dir, namespace: nil, working_dir_opted: false, crudle_app: false
|
9
|
+
install(dir, working_dir_opted, crudle_app)
|
10
|
+
make_executable(dir / 'core/generate_configs.rb')
|
11
|
+
add_namespace(dir, namespace) if namespace
|
12
|
+
puts "Done. All files installed into #{dir}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def install dir, working_dir_opted, crudle_app
|
16
|
+
src = working_dir_opted ? APP_DIR.to_path + '/.' : APP_DIR
|
17
|
+
FileUtils.cp_r(src, dir)
|
18
|
+
if crudle_app
|
19
|
+
FileUtils.cp_r(CRUDLE_DIR.to_path + '/.', dir)
|
20
|
+
end
|
21
|
+
cleanup(dir)
|
22
|
+
end
|
23
|
+
|
24
|
+
def add_namespace dir, namespace
|
25
|
+
%w[
|
26
|
+
base/base_controller.rb
|
27
|
+
base/rtcp_controller.rb
|
28
|
+
config/config.rb
|
29
|
+
].each do |file|
|
30
|
+
code = File.read(dir / file)
|
31
|
+
File.open dir / file, 'w' do |f|
|
32
|
+
f.puts "module #{namespace}"
|
33
|
+
code.split("\n").each {|l| f.puts " #{l}"}
|
34
|
+
f.puts "end"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def cleanup dir
|
40
|
+
Dir[dir / "**/.ignore"].each {|f| FileUtils.rm_f(f)}
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Appril
|
2
|
+
class CLI
|
3
|
+
module App
|
4
|
+
|
5
|
+
class Update
|
6
|
+
include Helpers
|
7
|
+
|
8
|
+
def initialize dir
|
9
|
+
FileUtils.rm_rf(dir / 'core')
|
10
|
+
Dir.chdir APP_DIR do
|
11
|
+
|
12
|
+
Dir['**/*'].select {|e| File.file?(e)}.each do |file|
|
13
|
+
next if File.file?(dir / file)
|
14
|
+
create_dirname_for(dir / file)
|
15
|
+
puts "Installing #{File.basename(dir)}/#{file}"
|
16
|
+
FileUtils.cp(file, dir / file)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
make_executable(dir / 'core/generate_configs.rb')
|
21
|
+
puts "Done"
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Appril
|
2
|
+
class CLI
|
3
|
+
module App
|
4
|
+
|
5
|
+
APP_DIR = BOILERPLATE_DIR / 'app'
|
6
|
+
CRUDLE_DIR = BOILERPLATE_DIR / 'crudle'
|
7
|
+
|
8
|
+
def app args
|
9
|
+
opted_dir = args[2]
|
10
|
+
assert_directory_provided(opted_dir)
|
11
|
+
dir = expanded_path(opted_dir)
|
12
|
+
|
13
|
+
case instruction = args[1]
|
14
|
+
when 'i', 'install'
|
15
|
+
|
16
|
+
app_install(dir, {
|
17
|
+
working_dir_opted: working_dir_opted?(opted_dir),
|
18
|
+
namespace: extract_namespace(args),
|
19
|
+
crudle_app: args.find {|a| a == '-crudle'}
|
20
|
+
})
|
21
|
+
|
22
|
+
when 'u', 'update'
|
23
|
+
|
24
|
+
app_update(dir)
|
25
|
+
|
26
|
+
else
|
27
|
+
unknown_instruction_error!(instruction, 'install (or i)', 'update (or u)')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def app_install dir, opts
|
32
|
+
create_dirname_for(dir)
|
33
|
+
assert_installable_dir(dir, opts[:working_dir_opted])
|
34
|
+
App::Install.new(dir, opts)
|
35
|
+
end
|
36
|
+
|
37
|
+
def app_update dir
|
38
|
+
assert_is_app_dir(dir)
|
39
|
+
App::Update.new(dir)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
require 'appril-cli/app/install'
|
46
|
+
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
|