appril-cli 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.
- 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,152 @@
|
|
|
1
|
+
module Appril
|
|
2
|
+
class CLI
|
|
3
|
+
module Docker
|
|
4
|
+
|
|
5
|
+
class Build
|
|
6
|
+
|
|
7
|
+
def initialize dir, update_runner_only: false, push_opted: false
|
|
8
|
+
Dir.chdir dir do
|
|
9
|
+
|
|
10
|
+
config = load_config
|
|
11
|
+
validate_config(config)
|
|
12
|
+
|
|
13
|
+
build_dir = Pathname.new(File.expand_path('__tmpbuildir__'))
|
|
14
|
+
|
|
15
|
+
prepare_build_dir(build_dir)
|
|
16
|
+
|
|
17
|
+
install_files(build_dir)
|
|
18
|
+
|
|
19
|
+
app_dir = Pathname.new(File.expand_path(config['APP_DIR']))
|
|
20
|
+
|
|
21
|
+
if update_runner_only
|
|
22
|
+
puts "Skipping image building"
|
|
23
|
+
else
|
|
24
|
+
prepare_build(build_dir, app_dir)
|
|
25
|
+
|
|
26
|
+
image_built = build_image(build_dir, config['IMAGE_NAME'], config['BUILD_OPTS'])
|
|
27
|
+
|
|
28
|
+
if image_built && push_opted
|
|
29
|
+
push_image(config['IMAGE_NAME'])
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
puts "Installing run script"
|
|
34
|
+
install_run_script(app_dir, *config.values_at('IMAGE_NAME', 'CONTAINER_NAME', 'RUN_SCRIPT', 'RUN_OPTS'))
|
|
35
|
+
|
|
36
|
+
FileUtils.rm_rf(build_dir)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def load_config
|
|
41
|
+
YAML.load(File.read(CONFIG_FILE))
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def validate_config config
|
|
45
|
+
{
|
|
46
|
+
'IMAGE_NAME' => :validate_config__image_name,
|
|
47
|
+
'CONTAINER_NAME' => :validate_config__container_name,
|
|
48
|
+
'APP_DIR' => :validate_config__app_dir,
|
|
49
|
+
'RUN_SCRIPT' => :validate_config__run_script,
|
|
50
|
+
}.each_pair do |key,validator|
|
|
51
|
+
next if send(validator, config[key])
|
|
52
|
+
puts "", "\t::: Please set #{key} in config.yml :::", ""
|
|
53
|
+
exit 1
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def validate_config__image_name value
|
|
58
|
+
!value.nil? && !value.empty?
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def validate_config__container_name value
|
|
62
|
+
!value.nil? && !value.empty? && value.values.any?
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def validate_config__app_dir value
|
|
66
|
+
!value.nil? && !value.empty?
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def validate_config__run_script value
|
|
70
|
+
!value.nil? && !value.empty?
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def prepare_build_dir dir
|
|
74
|
+
FileUtils.rm_rf(dir)
|
|
75
|
+
FileUtils.mkdir_p(dir / 'build')
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def install_files dir
|
|
79
|
+
install_dockerfile(dir)
|
|
80
|
+
install_start_file(dir)
|
|
81
|
+
install_build_files(dir)
|
|
82
|
+
install_cleanup_file(dir)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def install_dockerfile dir
|
|
86
|
+
FileUtils.cp(DOCKER_DIR / 'Dockerfile', dir)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def install_start_file dir
|
|
90
|
+
File.open dir / 'start', 'w' do |f|
|
|
91
|
+
f << File.read(DOCKER_DIR / 'start').sub('{start}', File.read(START_FILE))
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def install_build_files dir
|
|
96
|
+
FileUtils.cp(PREPARE_BUILD_FILE, dir / 'build')
|
|
97
|
+
FileUtils.cp(BUILD_FILE, dir / 'build/build')
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def install_cleanup_file dir
|
|
101
|
+
FileUtils.cp(CLEANUP_FILE, dir / 'build/cleanup')
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def prepare_build dir, app_dir
|
|
105
|
+
Dir.chdir dir / 'build' do
|
|
106
|
+
CLI.run "APP_DIR=#{app_dir} #{PREPARE_BUILD_FILE}"
|
|
107
|
+
exit 1 unless $? && $?.success?
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def build_image dir, image_name, build_opts
|
|
112
|
+
CLI.run "docker build -t #{image_name} #{build_opts} '#{dir}'"
|
|
113
|
+
$? && $?.success?
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def push_image image_name
|
|
117
|
+
CLI.run "docker push #{image_name}"
|
|
118
|
+
$? && $?.success?
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def install_run_script app_dir, image_name, container_name, run_script, run_opts
|
|
122
|
+
FileUtils.mkdir_p(app_dir / File.dirname(run_script))
|
|
123
|
+
|
|
124
|
+
script_path = app_dir / run_script
|
|
125
|
+
|
|
126
|
+
File.open script_path, 'w' do |f|
|
|
127
|
+
f << File.read(DOCKER_DIR / 'run').
|
|
128
|
+
gsub('{image}', image_name).
|
|
129
|
+
gsub('{script_path_traversal}', script_path_traversal(run_script)).
|
|
130
|
+
gsub('{run_opts}', run_opts).
|
|
131
|
+
gsub('{environments}', container_name.keys.join(' ')).
|
|
132
|
+
gsub('{container_definitions}', container_definitions(container_name))
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
FileUtils.chmod('+x', script_path)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def container_definitions container_name
|
|
139
|
+
container_name.map do |kv|
|
|
140
|
+
'[ "$APP_ENV" = "%s" ] && CONTAINER_NAME="%s"' % kv
|
|
141
|
+
end.join("\n")
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def script_path_traversal run_script
|
|
145
|
+
run_script.gsub(/\A\/+|\/+\Z/, '').scan(/\/+/).map {'..'}*'/'
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Appril
|
|
2
|
+
class CLI
|
|
3
|
+
module Docker
|
|
4
|
+
|
|
5
|
+
class Install
|
|
6
|
+
include Helpers
|
|
7
|
+
|
|
8
|
+
def initialize dir, working_dir_opted: false
|
|
9
|
+
install(dir, working_dir_opted)
|
|
10
|
+
make_executable(dir / PREPARE_BUILD_FILE)
|
|
11
|
+
puts "Done. All files installed into #{dir}"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def install dir, working_dir_opted
|
|
15
|
+
src = working_dir_opted ? DOCKER_DIR.to_path + '/skel/.' : DOCKER_DIR / 'skel'
|
|
16
|
+
FileUtils.cp_r(src, dir)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Appril
|
|
2
|
+
class CLI
|
|
3
|
+
module Docker
|
|
4
|
+
|
|
5
|
+
class Update
|
|
6
|
+
include Helpers
|
|
7
|
+
|
|
8
|
+
def initialize dir
|
|
9
|
+
Dir.chdir DOCKER_DIR / 'skel' 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
|
+
puts "Done"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
module Appril
|
|
2
|
+
class CLI
|
|
3
|
+
module Docker
|
|
4
|
+
|
|
5
|
+
DOCKER_DIR = BASE_DIR / 'docker'
|
|
6
|
+
|
|
7
|
+
CONFIG_FILE = './config.yml'.freeze
|
|
8
|
+
START_FILE = './start.sh'.freeze
|
|
9
|
+
PREPARE_BUILD_FILE = './prepare_build.sh'.freeze
|
|
10
|
+
BUILD_FILE = './build.sh'.freeze
|
|
11
|
+
CLEANUP_FILE = './cleanup.sh'.freeze
|
|
12
|
+
|
|
13
|
+
def docker args
|
|
14
|
+
opted_dir = args[2]
|
|
15
|
+
assert_directory_provided(opted_dir)
|
|
16
|
+
dir = expanded_path(opted_dir)
|
|
17
|
+
|
|
18
|
+
case instruction = args[1]
|
|
19
|
+
when 'i', 'install'
|
|
20
|
+
|
|
21
|
+
docker_install(dir, working_dir_opted: working_dir_opted?(opted_dir))
|
|
22
|
+
|
|
23
|
+
when 'b', 'build'
|
|
24
|
+
|
|
25
|
+
docker_build(dir, {
|
|
26
|
+
update_runner_only: args.find {|a| a == '-u'},
|
|
27
|
+
push_opted: args.find {|a| a == '-p'}
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
when 'u', 'update'
|
|
31
|
+
|
|
32
|
+
docker_update(dir)
|
|
33
|
+
|
|
34
|
+
else
|
|
35
|
+
unknown_instruction_error!(instruction, 'install (or i)', 'build (or b)', 'update (or u)')
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def docker_install dir, opts
|
|
40
|
+
create_dirname_for(dir)
|
|
41
|
+
assert_installable_dir(dir, opts[:working_dir_opted])
|
|
42
|
+
Docker::Install.new(dir, opts)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def docker_build dir, opts
|
|
46
|
+
assert_directory_exists(dir)
|
|
47
|
+
assert_config_file_exists(dir)
|
|
48
|
+
Docker::Build.new(dir, opts)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def docker_update dir
|
|
52
|
+
assert_is_docker_dir(dir)
|
|
53
|
+
Docker::Update.new(dir)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
require 'appril-cli/docker/install'
|
|
60
|
+
require 'appril-cli/docker/build'
|
|
61
|
+
require 'appril-cli/docker/update'
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Appril
|
|
2
|
+
class CLI
|
|
3
|
+
module Generator
|
|
4
|
+
|
|
5
|
+
def generator args
|
|
6
|
+
|
|
7
|
+
case instruction = args[1]
|
|
8
|
+
when 'api', 'a'
|
|
9
|
+
api_name = args[2]
|
|
10
|
+
assert_valid_api_name_given(api_name)
|
|
11
|
+
|
|
12
|
+
app_dir = args[3]
|
|
13
|
+
assert_directory_provided(app_dir)
|
|
14
|
+
app_dir = expanded_path(app_dir)
|
|
15
|
+
assert_is_app_dir(app_dir)
|
|
16
|
+
|
|
17
|
+
gen_dir = app_dir / 'generators/api'
|
|
18
|
+
assert_directory_exists(gen_dir)
|
|
19
|
+
|
|
20
|
+
api_dir = app_dir / "base/api/#{api_name}"
|
|
21
|
+
assert_directory_does_not_exists(api_dir)
|
|
22
|
+
|
|
23
|
+
Generator::API.new(gen_dir, api_dir, api_name)
|
|
24
|
+
else
|
|
25
|
+
unknown_instruction_error!(instruction, 'api (or a)')
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
require 'appril-cli/generator/api'
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module Appril
|
|
2
|
+
class CLI
|
|
3
|
+
module Helpers
|
|
4
|
+
|
|
5
|
+
def display_error error
|
|
6
|
+
puts "", "\t::: #{error} :::", ""
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def fatal_error! error, exit_code = 1
|
|
10
|
+
display_error(error)
|
|
11
|
+
exit exit_code
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def expanded_path *path
|
|
15
|
+
Pathname.new(File.expand_path(File.join(*path.map(&:to_s))))
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def create_dirname_for dir
|
|
19
|
+
FileUtils.mkdir_p(File.dirname(dir))
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def make_executable *entries
|
|
23
|
+
entries.flatten.each {|e| FileUtils.chmod('+x', e)}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def working_dir_opted? opted_dir
|
|
27
|
+
opted_dir == '.'
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def extract_namespace args
|
|
31
|
+
return unless index = args.index('-n')
|
|
32
|
+
return unless namespace = args[index + 1]
|
|
33
|
+
if namespace =~ /::/
|
|
34
|
+
fatal_error! "Nested namespaces not supported"
|
|
35
|
+
end
|
|
36
|
+
if namespace =~ /\W/
|
|
37
|
+
fatal_error! "Namespace may contain only alphanumerics"
|
|
38
|
+
end
|
|
39
|
+
unless namespace =~ /\A[A-Z]/
|
|
40
|
+
fatal_error! "Namespace should start with a capital letter"
|
|
41
|
+
end
|
|
42
|
+
namespace
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
data/lib/appril-cli.rb
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
require 'pathname'
|
|
3
|
+
require 'yaml'
|
|
4
|
+
require 'pty'
|
|
5
|
+
|
|
6
|
+
module Appril
|
|
7
|
+
class CLI
|
|
8
|
+
BASE_DIR = Pathname.new(File.expand_path('../..', __FILE__))
|
|
9
|
+
BOILERPLATE_DIR = BASE_DIR / 'boilerplate'
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
require 'appril-cli/version'
|
|
14
|
+
require 'appril-cli/helpers'
|
|
15
|
+
require 'appril-cli/assertions'
|
|
16
|
+
require 'appril-cli/app'
|
|
17
|
+
require 'appril-cli/generator'
|
|
18
|
+
require 'appril-cli/docker'
|
|
19
|
+
|
|
20
|
+
module Appril
|
|
21
|
+
class CLI
|
|
22
|
+
|
|
23
|
+
include Helpers
|
|
24
|
+
include Assertions
|
|
25
|
+
include Docker
|
|
26
|
+
include App
|
|
27
|
+
include Generator
|
|
28
|
+
|
|
29
|
+
def initialize args
|
|
30
|
+
case command = args[0]
|
|
31
|
+
when 'a', 'app'
|
|
32
|
+
app(args)
|
|
33
|
+
when 'g', 'gen', 'generate'
|
|
34
|
+
generator(args)
|
|
35
|
+
when 'd', 'docker'
|
|
36
|
+
docker(args)
|
|
37
|
+
when 'v', '-v', '--version'
|
|
38
|
+
puts VERSION
|
|
39
|
+
when nil, '-h', '--help'
|
|
40
|
+
usage
|
|
41
|
+
else
|
|
42
|
+
display_error "Unknown command #{command}"
|
|
43
|
+
usage
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def usage
|
|
49
|
+
puts "
|
|
50
|
+
Arguments in round brackets are required.
|
|
51
|
+
Arguments in square brackets are optional.
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
=== Install a new app ===
|
|
55
|
+
$ appril (app || a) (install || i) (dir || .) [-crudle]
|
|
56
|
+
* If -crudle option provided it will install a Crudle app
|
|
57
|
+
|
|
58
|
+
=== Update existing app ===
|
|
59
|
+
$ appril (app || a) (update || u) (dir || .)
|
|
60
|
+
|
|
61
|
+
=== Generate a new API ===
|
|
62
|
+
$ appril (generate || g) (api) (api name) (dir || .)
|
|
63
|
+
|
|
64
|
+
=== Install Docker builder ===
|
|
65
|
+
$ appril (docker || d) (install || i) (dir || .)
|
|
66
|
+
|
|
67
|
+
=== Update Docker builder ===
|
|
68
|
+
$ appril (docker || d) (update || u) (dir || .)
|
|
69
|
+
|
|
70
|
+
=== Build Docker image and install run script ===
|
|
71
|
+
$ appril (docker || d) (build || b) (dir || .) [-u] [-p]
|
|
72
|
+
* If -u option provided it will only update the run script without building the image.
|
|
73
|
+
* If -p option provided it will try to push the image to Docker registry after successful build.
|
|
74
|
+
|
|
75
|
+
=== Usage ===
|
|
76
|
+
$ appril [-h || --help]
|
|
77
|
+
".split("\n").map {|l| "\t" + l.strip}.join("\n")
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def unknown_instruction_error! instruction, *available_instructions
|
|
82
|
+
fatal_error! "Unknown instruction #{instruction}. Use one of #{available_instructions*', '}"
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def self.run cmd
|
|
87
|
+
puts "", "$ #{cmd}"
|
|
88
|
+
PTY.spawn cmd do |r, w, pid|
|
|
89
|
+
begin
|
|
90
|
+
r.sync
|
|
91
|
+
r.each_char do |char|
|
|
92
|
+
print(char)
|
|
93
|
+
end
|
|
94
|
+
rescue Errno::EIO => e
|
|
95
|
+
# simply ignoring this
|
|
96
|
+
ensure
|
|
97
|
+
Process.wait(pid)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
data/sandbox/.gitignore
ADDED
data/sandbox/.pryrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require File.expand_path('../core/load', __FILE__)
|
data/sandbox/Gemfile
ADDED
data/sandbox/Rakefile
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require File.expand_path('../core/load', __FILE__)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
class BaseController < Appril::BaseController
|
|
2
|
+
include Helpers
|
|
3
|
+
|
|
4
|
+
map Cfg.server_url
|
|
5
|
+
|
|
6
|
+
define_layout :layout, file: '../templates/layout'
|
|
7
|
+
layout :layout
|
|
8
|
+
engine :Liquid
|
|
9
|
+
define_template(:get) {''}
|
|
10
|
+
define_template_var(:client_url, Cfg.client_url)
|
|
11
|
+
|
|
12
|
+
def get
|
|
13
|
+
render
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
error 500 do |e|
|
|
17
|
+
puts "\e[0;31m%s\e[0m" % e.inspect
|
|
18
|
+
e.backtrace && e.backtrace.each {|l| puts " \e[0;36m%s\e[0m" % l}
|
|
19
|
+
e.message
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -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
|
|
File without changes
|
|
@@ -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 @@
|
|
|
1
|
+
# this file will be loaded before other files found in helpers/ folder
|