kolo-roda 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +32 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/LICENSE +21 -0
- data/README.md +14 -0
- data/Rakefile +17 -0
- data/bin/kolo +44 -0
- data/kolo.gemspec +25 -0
- data/lib/kolo.rb +11 -0
- data/lib/kolo/app_generator.rb +122 -0
- data/lib/kolo/cli.rb +57 -0
- data/lib/kolo/configurations/default_config.json +126 -0
- data/lib/kolo/error.rb +7 -0
- data/lib/kolo/template.rb +32 -0
- data/lib/kolo/templates/Gemfile.tt +12 -0
- data/lib/kolo/templates/README.md.tt +11 -0
- data/lib/kolo/templates/Rakefile.tt +13 -0
- data/lib/kolo/templates/app.rb.tt +21 -0
- data/lib/kolo/templates/config.ru.tt +12 -0
- data/lib/kolo/templates/db.rb.tt +14 -0
- data/lib/kolo/templates/env.rb.tt +13 -0
- data/lib/kolo/templates/gitignore.tt +1 -0
- data/lib/kolo/templates/lib/tasks/database.rake.tt +55 -0
- data/lib/kolo/templates/lib/tasks/irb.rake.tt +11 -0
- data/lib/kolo/templates/lib/tasks/seed.rake.tt +2 -0
- data/lib/kolo/templates/models.rb.tt +13 -0
- data/lib/kolo/templates/puma.rb.tt +6 -0
- data/lib/kolo/templates/ruby-version.tt +1 -0
- data/lib/kolo/templates/views/404.erb.tt +1 -0
- data/lib/kolo/templates/views/index.erb.tt +1 -0
- data/lib/kolo/templates/views/layout.erb.tt +11 -0
- data/lib/kolo/version.rb +9 -0
- metadata +118 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 92e08026ebe74400c8ea82921adcb5366768b3a766a54de932ae32e6c200a956
|
4
|
+
data.tar.gz: 0a6ac40745b127cea4a0c807ef68ecce7b9a001eb5ad86429735403e6935e3ea
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ba494d059faa3c1a5e518f011eb278b7a0db7a486d1e928257365d2510b21dc8f63808230ebe4db0edbb6870662d8b7301ce6c72f0b44458a2a3643f7a4db265
|
7
|
+
data.tar.gz: 8ef66ec8bfb2beffa6698e3954201c259be873b0cf12b9e747b3a6029f59435266a1aa83b6f1c31831a2437d0c619f9e34bbec858b577a562ed8924a1bbf5ba0
|
data/.gitignore
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
/.config
|
4
|
+
/coverage/
|
5
|
+
/InstalledFiles
|
6
|
+
/pkg/
|
7
|
+
/spec/reports/
|
8
|
+
/spec/examples.txt
|
9
|
+
/test/tmp/
|
10
|
+
/test/version_tmp/
|
11
|
+
/tmp/
|
12
|
+
|
13
|
+
# ignore byebug command history file
|
14
|
+
.byebug_history
|
15
|
+
|
16
|
+
# documentation cache and generated files:
|
17
|
+
/.yardoc/
|
18
|
+
/_yardoc/
|
19
|
+
/doc/
|
20
|
+
/rdoc/
|
21
|
+
|
22
|
+
# environment normalization:
|
23
|
+
/.bundle/
|
24
|
+
/vendor/bundle
|
25
|
+
/lib/bundler/man/
|
26
|
+
|
27
|
+
|
28
|
+
Gemfile.lock
|
29
|
+
.ruby-version
|
30
|
+
.ruby-gemset
|
31
|
+
|
32
|
+
.rvmrc
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2019 Maksym Chumak
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# Kolo
|
2
|
+
Kolo is a simple app generator for building a bare-bones Roda/Sequel stack apps running on top of PosgreSQL database.
|
3
|
+
|
4
|
+
## Usage:
|
5
|
+
```
|
6
|
+
gem install kolo
|
7
|
+
|
8
|
+
kolo new <app_name> --config_file <path> --template_dir <path>
|
9
|
+
cd <app_name>
|
10
|
+
|
11
|
+
bundle install
|
12
|
+
rake db:create
|
13
|
+
rackup
|
14
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
begin
|
4
|
+
require "rspec/core/rake_task"
|
5
|
+
RSpec::Core::RakeTask.new(:spec)
|
6
|
+
rescue LoadError
|
7
|
+
end
|
8
|
+
|
9
|
+
task default: :spec
|
10
|
+
|
11
|
+
desc "build the gem and publish it to RubyGems"
|
12
|
+
task :publish do
|
13
|
+
tag = "kolo-#{Kolo::VERSION}.gem"
|
14
|
+
|
15
|
+
system "gem build kolo.gemspec --silent --output #{tag}"
|
16
|
+
system "gem push #{tag}"
|
17
|
+
end
|
data/bin/kolo
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require_relative "../lib/kolo"
|
3
|
+
require "optparse"
|
4
|
+
|
5
|
+
options = {
|
6
|
+
config_file: nil,
|
7
|
+
template_dir: nil
|
8
|
+
}
|
9
|
+
|
10
|
+
option_parser = OptionParser.new do |opts|
|
11
|
+
opts.banner = "usage: kolo new app_name [options]"
|
12
|
+
|
13
|
+
opts.on("--config_file path", "specify path to configuration file") do |path|
|
14
|
+
options[:config_file] = path
|
15
|
+
end
|
16
|
+
|
17
|
+
opts.on("--template_dir path", "specify path to template directory") do |path|
|
18
|
+
options[:template_dir] = path
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
option_parser.parse!
|
23
|
+
|
24
|
+
ARGV.size == 2 or ($stderr.puts option_parser.banner; exit(1))
|
25
|
+
|
26
|
+
def handle_error(message)
|
27
|
+
$stderr.puts message
|
28
|
+
exit(1)
|
29
|
+
end
|
30
|
+
|
31
|
+
begin
|
32
|
+
Kolo::CLI.new(command: ARGV[0], app_name: ARGV[1], options: options).call
|
33
|
+
rescue Kolo::InvalidCommandError
|
34
|
+
handle_error(option_parser.banner)
|
35
|
+
rescue Kolo::InvalidInputError => e
|
36
|
+
handle_error(e.message)
|
37
|
+
rescue Kolo::InvalidConfigurationError => e
|
38
|
+
handle_error(e.message)
|
39
|
+
rescue Kolo::AppExistsError => e
|
40
|
+
handle_error(e.message)
|
41
|
+
rescue Kolo::TemplateError => e
|
42
|
+
handle_error(e.message)
|
43
|
+
end
|
44
|
+
|
data/kolo.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require "kolo/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "kolo-roda"
|
7
|
+
spec.version = Kolo::VERSION
|
8
|
+
spec.platform = Gem::Platform::RUBY
|
9
|
+
spec.authors = ["Maksym Chumak"]
|
10
|
+
spec.email = ["chumachok11@gmail.com"]
|
11
|
+
spec.summary = "Roda/Sequel stack app generator"
|
12
|
+
spec.description = "Command line utility for generating Roda/Sequel stack applications"
|
13
|
+
spec.homepage = "https://github.com/chumachok/kolo"
|
14
|
+
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files`.split($/).reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.executables = ["kolo"]
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_development_dependency "rspec", "~> 3.9"
|
23
|
+
spec.add_development_dependency "bundler", "~> 2.1"
|
24
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
25
|
+
end
|
data/lib/kolo.rb
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kolo
|
4
|
+
|
5
|
+
##
|
6
|
+
# AppGenerator class is responsible for generating files based on the provided configuration file and templates
|
7
|
+
class AppGenerator
|
8
|
+
APP_EXISTS_ERROR_MESSAGE = "error when generating application: application already exists at '%s'"
|
9
|
+
FILE_PARSE_ERROR_MESSAGE = "error when attempting to parse configuration file: file is missing or invalid"
|
10
|
+
INVALID_CONFIGURATION_ERROR_MESSAGE = "configuration file is invalid: configuration for '%s' is missing or invalid"
|
11
|
+
TEMPLATE_ERROR_MESSAGE = "template error: %s"
|
12
|
+
|
13
|
+
##
|
14
|
+
# Initializes AppGenerator class
|
15
|
+
#
|
16
|
+
# @param [String] app_name
|
17
|
+
# Name of the new application.
|
18
|
+
#
|
19
|
+
# @param [String] config_file
|
20
|
+
# Path to the configuration file.
|
21
|
+
# Configuration file must be follow the format defined in ./lib/kolo/configurations/default_configuration.json.
|
22
|
+
#
|
23
|
+
# @param [String] template_dir
|
24
|
+
# Directory that contains templates referenced from configuration file.
|
25
|
+
# A template should have .tt extension, and can use features of ERB templating system.
|
26
|
+
#
|
27
|
+
# @param [Tempate] template_class
|
28
|
+
# Class which is responsible for rendering ERB templates, must implement +initialize+ and +call+ methods.
|
29
|
+
def initialize(app_name:, config_file:, template_dir:, template_class: Template)
|
30
|
+
@app_name = app_name
|
31
|
+
@config = validate_config(config_file)
|
32
|
+
@template_dir = template_dir
|
33
|
+
@template_class = template_class
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
# +call+ method contains the logic for generating the application.
|
38
|
+
# See ./spec/lib/kolo/app_generator_spec.rb for documentation of the expected behaviour.
|
39
|
+
def call
|
40
|
+
raise AppExistsError, APP_EXISTS_ERROR_MESSAGE % File.join(File.dirname(__FILE__), @app_name) if app_exists?
|
41
|
+
|
42
|
+
create_app_structure
|
43
|
+
generate_files
|
44
|
+
generate_template_files
|
45
|
+
generate_keep_files
|
46
|
+
initialize_git
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
def create_app_structure
|
51
|
+
@config[:dirs].each do |d|
|
52
|
+
FileUtils.mkdir_p(File.join(@app_name, d))
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def generate_template_files
|
57
|
+
@config[:template_files].each do |f|
|
58
|
+
relative_src = File.join(@template_dir, f[:src])
|
59
|
+
relative_dest = File.join(@app_name, f[:dest])
|
60
|
+
template(relative_src, relative_dest, params: f[:params])
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def generate_files
|
65
|
+
@config[:files].each do |f|
|
66
|
+
relative_src = File.join(@template_dir, f[:src])
|
67
|
+
relative_dest = File.join(@app_name, f[:dest])
|
68
|
+
copy_file(relative_src, relative_dest)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def generate_keep_files
|
73
|
+
@config[:dirs].each do |d|
|
74
|
+
dir = File.join(@app_name, d)
|
75
|
+
FileUtils.touch(File.join(dir, ".keep")) if Dir.empty?(dir)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def initialize_git
|
80
|
+
FileUtils.cd(@app_name) do
|
81
|
+
system("git init")
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def template(relative_src, relative_dest, params: {})
|
86
|
+
validate_template_presence(relative_src)
|
87
|
+
@template_class.new(params).call(relative_src, relative_dest)
|
88
|
+
end
|
89
|
+
|
90
|
+
def copy_file(relative_src, relative_dest)
|
91
|
+
validate_template_presence(relative_src)
|
92
|
+
FileUtils.cp(relative_src, relative_dest)
|
93
|
+
end
|
94
|
+
|
95
|
+
def app_exists?
|
96
|
+
File.exist?(@app_name)
|
97
|
+
end
|
98
|
+
|
99
|
+
def validate_config(config_file)
|
100
|
+
begin
|
101
|
+
config = JSON.parse(File.read(config_file), symbolize_names: true)
|
102
|
+
rescue StandardError
|
103
|
+
raise InvalidConfigurationError, FILE_PARSE_ERROR_MESSAGE
|
104
|
+
end
|
105
|
+
|
106
|
+
raise InvalidConfigurationError, INVALID_CONFIGURATION_ERROR_MESSAGE % "template files" unless config[:template_files] &&
|
107
|
+
config[:template_files].all? { |h| h[:src] && h[:dest] && h[:params] }
|
108
|
+
|
109
|
+
raise InvalidConfigurationError, INVALID_CONFIGURATION_ERROR_MESSAGE % "files" unless config[:files] &&
|
110
|
+
config[:files].all? { |h| h[:src] && h[:dest] }
|
111
|
+
|
112
|
+
raise InvalidConfigurationError, INVALID_CONFIGURATION_ERROR_MESSAGE % "dirs" unless config[:dirs]
|
113
|
+
|
114
|
+
config
|
115
|
+
end
|
116
|
+
|
117
|
+
def validate_template_presence(path)
|
118
|
+
raise TemplateError, TEMPLATE_ERROR_MESSAGE % "template is missing at #{path}" unless File.exist?(path)
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
data/lib/kolo/cli.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kolo
|
4
|
+
|
5
|
+
##
|
6
|
+
# CLI class is responsible for handling delegation logic based on user's command
|
7
|
+
class CLI
|
8
|
+
INVALID_APP_NAME_MESSAGE = "app name must contain lowercase letters or underscore character only"
|
9
|
+
DEFAULT_TEMPLATE_DIR = File.join(File.dirname(__FILE__), "templates")
|
10
|
+
DEFAULT_CONFIG_FILE = File.join(File.dirname(__FILE__), "configurations", "default_config.json")
|
11
|
+
|
12
|
+
##
|
13
|
+
# Initializes CLI class
|
14
|
+
#
|
15
|
+
# @param [String] command
|
16
|
+
# CLI command to be executed.
|
17
|
+
#
|
18
|
+
# @param [String] app_name
|
19
|
+
# Name of the new application.
|
20
|
+
#
|
21
|
+
# @param [Hash] options
|
22
|
+
# Contains a hash of configuration options.
|
23
|
+
#
|
24
|
+
# @param [AppGenerator] app_generator_class
|
25
|
+
# Class which is responsible for generation of the application, must implement +initialize+ and +call+ methods.
|
26
|
+
def initialize(command:, app_name:, options:, app_generator_class: AppGenerator)
|
27
|
+
@command = command
|
28
|
+
@app_name = app_name
|
29
|
+
@options = options
|
30
|
+
@app_generator_class = app_generator_class
|
31
|
+
|
32
|
+
validate_input
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# +call+ method contains the logic validating the input and delegating to the provided app generator
|
37
|
+
# See ./spec/lib/kolo/cli_spec.rb for documentation of the expected behaviour.
|
38
|
+
def call
|
39
|
+
case @command
|
40
|
+
when "new"
|
41
|
+
@options[:config_file] ||= DEFAULT_CONFIG_FILE
|
42
|
+
@options[:template_dir] ||= DEFAULT_TEMPLATE_DIR
|
43
|
+
|
44
|
+
@app_generator_class.new(app_name: @app_name, config_file: @options[:config_file], template_dir: @options[:template_dir]).call
|
45
|
+
else
|
46
|
+
raise InvalidCommandError
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def validate_input
|
53
|
+
raise InvalidInputError, INVALID_APP_NAME_MESSAGE unless @app_name =~ /^[a-z_]+$/
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
{
|
2
|
+
"dirs": [
|
3
|
+
"models",
|
4
|
+
"views",
|
5
|
+
"lib/tasks",
|
6
|
+
"public",
|
7
|
+
"assets/css",
|
8
|
+
"assets/js"
|
9
|
+
],
|
10
|
+
"template_files": [
|
11
|
+
{
|
12
|
+
"src": "app.rb.tt",
|
13
|
+
"dest": "app.rb",
|
14
|
+
"params": {
|
15
|
+
"class_name": "App"
|
16
|
+
}
|
17
|
+
},
|
18
|
+
{
|
19
|
+
"src": "Gemfile.tt",
|
20
|
+
"dest": "Gemfile",
|
21
|
+
"params":
|
22
|
+
{
|
23
|
+
"gems": [
|
24
|
+
{
|
25
|
+
"name": "roda"
|
26
|
+
},
|
27
|
+
{
|
28
|
+
"name": "sequel"
|
29
|
+
},
|
30
|
+
{
|
31
|
+
"name": "sequel_pg"
|
32
|
+
},
|
33
|
+
{
|
34
|
+
"name": "tilt"
|
35
|
+
},
|
36
|
+
{
|
37
|
+
"name": "erubis"
|
38
|
+
},
|
39
|
+
{
|
40
|
+
"name": "rack-unreloader"
|
41
|
+
},
|
42
|
+
{
|
43
|
+
"name": "puma"
|
44
|
+
}
|
45
|
+
],
|
46
|
+
"ruby_version": "2.6.5"
|
47
|
+
}
|
48
|
+
},
|
49
|
+
{
|
50
|
+
"src": "ruby-version.tt",
|
51
|
+
"dest": "ruby-version",
|
52
|
+
"params": {
|
53
|
+
"version": "2.6.5"
|
54
|
+
}
|
55
|
+
},
|
56
|
+
{
|
57
|
+
"src": "config.ru.tt",
|
58
|
+
"dest": "config.ru",
|
59
|
+
"params": {
|
60
|
+
"class_name": "App",
|
61
|
+
"filename": "app.rb"
|
62
|
+
}
|
63
|
+
},
|
64
|
+
{
|
65
|
+
"src": "env.rb.tt",
|
66
|
+
"dest": ".env.rb",
|
67
|
+
"params": {
|
68
|
+
"db_name": "app"
|
69
|
+
}
|
70
|
+
}
|
71
|
+
],
|
72
|
+
"files": [
|
73
|
+
{
|
74
|
+
"src": "models.rb.tt",
|
75
|
+
"dest": "models.rb"
|
76
|
+
},
|
77
|
+
{
|
78
|
+
"src": "puma.rb.tt",
|
79
|
+
"dest": "puma.rb"
|
80
|
+
},
|
81
|
+
{
|
82
|
+
"src": "Rakefile.tt",
|
83
|
+
"dest": "Rakefile"
|
84
|
+
},
|
85
|
+
{
|
86
|
+
"src": "README.md.tt",
|
87
|
+
"dest": "README.md"
|
88
|
+
},
|
89
|
+
{
|
90
|
+
"src": "gitignore.tt",
|
91
|
+
"dest": ".gitignore"
|
92
|
+
},
|
93
|
+
{
|
94
|
+
"src": "README.md.tt",
|
95
|
+
"dest": "README.md"
|
96
|
+
},
|
97
|
+
{
|
98
|
+
"src": "lib/tasks/seed.rake.tt",
|
99
|
+
"dest": "lib/tasks/seed.rake"
|
100
|
+
},
|
101
|
+
{
|
102
|
+
"src": "lib/tasks/irb.rake.tt",
|
103
|
+
"dest": "lib/tasks/irb.rake"
|
104
|
+
},
|
105
|
+
{
|
106
|
+
"src": "lib/tasks/database.rake.tt",
|
107
|
+
"dest": "lib/tasks/database.rake"
|
108
|
+
},
|
109
|
+
{
|
110
|
+
"src": "db.rb.tt",
|
111
|
+
"dest": "db.rb"
|
112
|
+
},
|
113
|
+
{
|
114
|
+
"src": "views/index.erb.tt",
|
115
|
+
"dest": "views/index.erb"
|
116
|
+
},
|
117
|
+
{
|
118
|
+
"src": "views/404.erb.tt",
|
119
|
+
"dest": "views/404.erb"
|
120
|
+
},
|
121
|
+
{
|
122
|
+
"src": "views/layout.erb.tt",
|
123
|
+
"dest": "views/layout.erb"
|
124
|
+
}
|
125
|
+
]
|
126
|
+
}
|
data/lib/kolo/error.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kolo
|
4
|
+
|
5
|
+
##
|
6
|
+
# Template class is responsible for template rendering logic
|
7
|
+
class Template
|
8
|
+
|
9
|
+
##
|
10
|
+
# Initializes Template class
|
11
|
+
#
|
12
|
+
# @param [Hash] params
|
13
|
+
# Contains a hash of parameters passed to ERB template
|
14
|
+
def initialize(params={})
|
15
|
+
# dynamically set instant variables to be used by ERB template
|
16
|
+
params.each { |k, v| instance_variable_set("@#{k}", v) }
|
17
|
+
end
|
18
|
+
|
19
|
+
# +call+ method contains the logic for rendering the ERB template using the parameters passed to the +initialize+ method
|
20
|
+
# @param [String] src
|
21
|
+
# source of the template file
|
22
|
+
# @param [String] dest
|
23
|
+
# destination where the template will be rendered
|
24
|
+
# See ./spec/lib/kolo/template_spec.rb for documentation of the expected behaviour.
|
25
|
+
def call(src, dest)
|
26
|
+
content = File.open(src, "rb", &:read)
|
27
|
+
template = ERB.new(content, nil, "-").result(binding)
|
28
|
+
File.open(dest, "w") { |f| f.write(template) }
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
3
|
+
|
4
|
+
<% @gems.each do |gem| -%>
|
5
|
+
<%- if gem[:version] -%>
|
6
|
+
gem "<%= gem[:name] %>", "~> <%= gem[:version] %>"
|
7
|
+
<%- else -%>
|
8
|
+
gem "<%= gem[:name] %>"
|
9
|
+
<%- end -%>
|
10
|
+
<%- end -%>
|
11
|
+
|
12
|
+
ruby "<%= @ruby_version %>"
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative "models"
|
2
|
+
require "roda"
|
3
|
+
|
4
|
+
class <%= @class_name %> < Roda
|
5
|
+
plugin :render
|
6
|
+
|
7
|
+
plugin :default_headers, "Content-Type" => "text/html", "X-Frame-Options" => "deny",
|
8
|
+
"X-Content-Type-Options" => "nosniff", "X-XSS-Protection" => "1; mode=block"
|
9
|
+
|
10
|
+
plugin :not_found do
|
11
|
+
view("404")
|
12
|
+
end
|
13
|
+
|
14
|
+
route do |r|
|
15
|
+
|
16
|
+
r. root do
|
17
|
+
view("index")
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
dev_env = ENV["RACK_ENV"] == "development"
|
2
|
+
if dev_env
|
3
|
+
require "logger"
|
4
|
+
logger = Logger.new($stdout)
|
5
|
+
end
|
6
|
+
|
7
|
+
require "rack/unreloader"
|
8
|
+
require_relative "models"
|
9
|
+
|
10
|
+
Unreloader = Rack::Unreloader.new(subclasses: %w(Roda Sequel::Model), logger: logger, reload: dev_env) { <%= @class_name %> }
|
11
|
+
Unreloader.require("<%= @filename %>"){ "<%= @class_name %>" }
|
12
|
+
run(dev_env ? Unreloader : <%= @class_name %>.freeze.app)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
ENV["RACK_ENV"] ||= "development"
|
2
|
+
|
3
|
+
ENV["DB_USER"] = "developer"
|
4
|
+
ENV["DB_PASSWORD"] = "secret"
|
5
|
+
ENV["DB_HOST"] = "127.0.0.1"
|
6
|
+
ENV["DB_NAME"] ||= case ENV["RACK_ENV"]
|
7
|
+
when "test"
|
8
|
+
"<%= @db_name %>-test"
|
9
|
+
when "production"
|
10
|
+
"<%= @db_name %>-production"
|
11
|
+
else
|
12
|
+
"<%= @db_name %>-development"
|
13
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
/.env.rb
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require "sequel"
|
2
|
+
|
3
|
+
namespace :db do
|
4
|
+
desc "Perform migration up to latest migration available"
|
5
|
+
task migrate: :with_connection do
|
6
|
+
migrate(ENV["RACK_ENV"], nil)
|
7
|
+
puts "db:migrate executed"
|
8
|
+
end
|
9
|
+
|
10
|
+
desc "Rollback database all the way down"
|
11
|
+
task rollback: :with_connection do
|
12
|
+
migrate(ENV["RACK_ENV"], 0)
|
13
|
+
puts "db:rollback executed"
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "Create the database"
|
17
|
+
task :create do
|
18
|
+
puts "Creating database '#{ENV["DB_NAME"]}'"
|
19
|
+
create_db
|
20
|
+
puts "db:create executed"
|
21
|
+
end
|
22
|
+
|
23
|
+
desc "Drop the database"
|
24
|
+
task drop: :with_connection do
|
25
|
+
Sequel::Model.db.disconnect
|
26
|
+
puts "Dropping database '#{ENV["DB_NAME"]}'"
|
27
|
+
drop_db
|
28
|
+
puts "db:drop executed"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.migrate(env, version)
|
33
|
+
ENV["RACK_ENV"] = env
|
34
|
+
require "logger"
|
35
|
+
Sequel.extension :migration
|
36
|
+
DB.loggers << Logger.new($stdout)
|
37
|
+
Sequel::Migrator.apply(DB, "#{ROOT}/migrate", version)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.create_db
|
41
|
+
args = []
|
42
|
+
args << "--encoding=utf8"
|
43
|
+
args << "--host=#{ENV["DB_HOST"]}" if ENV["DB_HOST"]
|
44
|
+
args << "--username=#{ENV["DB_USER"]}" if ENV["DB_USER"]
|
45
|
+
args << ENV["DB_NAME"]
|
46
|
+
system("createdb", *args)
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.drop_db
|
50
|
+
args = []
|
51
|
+
args << "--host=#{ENV["DB_HOST"]}" if ENV["DB_HOST"]
|
52
|
+
args << "--username=#{ENV["DB_USER"]}" if ENV["DB_USER"]
|
53
|
+
args << ENV["DB_NAME"]
|
54
|
+
system("dropdb", *args)
|
55
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require_relative "db"
|
2
|
+
|
3
|
+
unless defined?(Unreloader)
|
4
|
+
require "rack/unreloader"
|
5
|
+
Unreloader = Rack::Unreloader.new(reload: false)
|
6
|
+
end
|
7
|
+
|
8
|
+
Unreloader.require("models") { |f| Sequel::Model.send(:camelize, File.basename(f).sub(/\.rb\z/, "")) }
|
9
|
+
|
10
|
+
if ENV["RACK_ENV"] == "development"
|
11
|
+
require "logger"
|
12
|
+
DB.loggers << Logger.new($stdout)
|
13
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= @version %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<h1>404 - Page not found</h1>
|
@@ -0,0 +1 @@
|
|
1
|
+
<h1>Hello World!</h1>
|
data/lib/kolo/version.rb
ADDED
metadata
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: kolo-roda
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Maksym Chumak
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-01-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.9'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.9'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.1'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.1'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '13.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '13.0'
|
55
|
+
description: Command line utility for generating Roda/Sequel stack applications
|
56
|
+
email:
|
57
|
+
- chumachok11@gmail.com
|
58
|
+
executables:
|
59
|
+
- kolo
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- ".gitignore"
|
64
|
+
- ".rspec"
|
65
|
+
- Gemfile
|
66
|
+
- LICENSE
|
67
|
+
- README.md
|
68
|
+
- Rakefile
|
69
|
+
- bin/kolo
|
70
|
+
- kolo.gemspec
|
71
|
+
- lib/kolo.rb
|
72
|
+
- lib/kolo/app_generator.rb
|
73
|
+
- lib/kolo/cli.rb
|
74
|
+
- lib/kolo/configurations/default_config.json
|
75
|
+
- lib/kolo/error.rb
|
76
|
+
- lib/kolo/template.rb
|
77
|
+
- lib/kolo/templates/Gemfile.tt
|
78
|
+
- lib/kolo/templates/README.md.tt
|
79
|
+
- lib/kolo/templates/Rakefile.tt
|
80
|
+
- lib/kolo/templates/app.rb.tt
|
81
|
+
- lib/kolo/templates/config.ru.tt
|
82
|
+
- lib/kolo/templates/db.rb.tt
|
83
|
+
- lib/kolo/templates/env.rb.tt
|
84
|
+
- lib/kolo/templates/gitignore.tt
|
85
|
+
- lib/kolo/templates/lib/tasks/database.rake.tt
|
86
|
+
- lib/kolo/templates/lib/tasks/irb.rake.tt
|
87
|
+
- lib/kolo/templates/lib/tasks/seed.rake.tt
|
88
|
+
- lib/kolo/templates/models.rb.tt
|
89
|
+
- lib/kolo/templates/puma.rb.tt
|
90
|
+
- lib/kolo/templates/ruby-version.tt
|
91
|
+
- lib/kolo/templates/views/404.erb.tt
|
92
|
+
- lib/kolo/templates/views/index.erb.tt
|
93
|
+
- lib/kolo/templates/views/layout.erb.tt
|
94
|
+
- lib/kolo/version.rb
|
95
|
+
homepage: https://github.com/chumachok/kolo
|
96
|
+
licenses:
|
97
|
+
- MIT
|
98
|
+
metadata: {}
|
99
|
+
post_install_message:
|
100
|
+
rdoc_options: []
|
101
|
+
require_paths:
|
102
|
+
- lib
|
103
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
requirements: []
|
114
|
+
rubygems_version: 3.0.3
|
115
|
+
signing_key:
|
116
|
+
specification_version: 4
|
117
|
+
summary: Roda/Sequel stack app generator
|
118
|
+
test_files: []
|