sinator 3.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 +5 -0
- data/.rspec +2 -0
- data/CHANGELOG.md +46 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +33 -0
- data/LICENSE.txt +22 -0
- data/README.md +126 -0
- data/bin/sinator +5 -0
- data/lib/sinator/command.rb +61 -0
- data/lib/sinator/generator.rb +106 -0
- data/lib/sinator/templates/Gemfile.erb +15 -0
- data/lib/sinator/templates/Rakefile.erb +33 -0
- data/lib/sinator/templates/app/routes/home.erb +6 -0
- data/lib/sinator/templates/app/views/home/index.erb +1 -0
- data/lib/sinator/templates/app/views/layout.erb +21 -0
- data/lib/sinator/templates/app.erb +71 -0
- data/lib/sinator/templates/assets/javascripts/app.js +2 -0
- data/lib/sinator/templates/assets/javascripts/main.js +1 -0
- data/lib/sinator/templates/assets/javascripts/plugins.js +24 -0
- data/lib/sinator/templates/assets/stylesheets/app.css.scss +1 -0
- data/lib/sinator/templates/assets/stylesheets/main.css.scss +8 -0
- data/lib/sinator/templates/config/application.rb +7 -0
- data/lib/sinator/templates/config/boot.rb +10 -0
- data/lib/sinator/templates/config/database.yml +8 -0
- data/lib/sinator/templates/config/puma/development.erb +7 -0
- data/lib/sinator/templates/config/puma/production.erb +16 -0
- data/lib/sinator/templates/config.ru.erb +5 -0
- data/lib/sinator/templates/db/migrations/000_example.rb +12 -0
- data/lib/sinator/templates/public/404.html +60 -0
- data/lib/sinator/templates/public/apple-touch-icon.png +0 -0
- data/lib/sinator/templates/public/browserconfig.xml +12 -0
- data/lib/sinator/templates/public/crossdomain.xml +15 -0
- data/lib/sinator/templates/public/favicon.ico +0 -0
- data/lib/sinator/templates/public/humans.txt +15 -0
- data/lib/sinator/templates/public/robots.txt +5 -0
- data/lib/sinator/templates/public/tile-wide.png +0 -0
- data/lib/sinator/templates/public/tile.png +0 -0
- data/lib/sinator/version.rb +3 -0
- data/lib/sinator.rb +1 -0
- data/sinator.gemspec +19 -0
- data/spec/fixtures/app_routes_home.txt +6 -0
- data/spec/fixtures/config/puma/development.txt +7 -0
- data/spec/fixtures/config/puma/production.txt +16 -0
- data/spec/fixtures/config_ru.txt +5 -0
- data/spec/fixtures/with_db/app.txt +50 -0
- data/spec/fixtures/with_db/gemfile.txt +13 -0
- data/spec/fixtures/with_db/rakefile.txt +32 -0
- data/spec/fixtures/without_db/app.txt +31 -0
- data/spec/fixtures/without_db/gemfile.txt +11 -0
- data/spec/fixtures/without_db/rakefile.txt +15 -0
- data/spec/helpers/generator.rb +46 -0
- data/spec/sinator/command_spec.rb +70 -0
- data/spec/sinator/generator_spec.rb +184 -0
- data/spec/sinator_spec.rb +1 -0
- data/spec/spec_helper.rb +29 -0
- metadata +128 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
environment 'production'
|
2
|
+
bind 'unix:///path/to/shared/tmp/sockets/puma.sock'
|
3
|
+
pidfile '/path/to/shared/tmp/pids/puma.pid'
|
4
|
+
ctl_socket = '/path/to/shared/tmp/sockets/pumactl.sock'
|
5
|
+
state_path '/path/to/shared/tmp/sockets/puma.state'
|
6
|
+
activate_control_app 'unix:///path/to/shared/tmp/sockets/pumactl.sock'
|
7
|
+
daemonize
|
8
|
+
quiet
|
9
|
+
|
10
|
+
threads 5, 5
|
11
|
+
workers 2
|
12
|
+
preload_app!
|
13
|
+
|
14
|
+
before_fork do
|
15
|
+
<%= @app_class_name %>::DB.disconnect if defined?(<%= @app_class_name %>::DB)
|
16
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# http://sequel.jeremyevans.net/rdoc/files/doc/migration_rdoc.html
|
2
|
+
|
3
|
+
# Sequel.migration do
|
4
|
+
# up do
|
5
|
+
# add_column :artists, :location, String
|
6
|
+
# from(:artists).update(:location=>'Sacramento')
|
7
|
+
# end
|
8
|
+
#
|
9
|
+
# down do
|
10
|
+
# drop_column :artists, :location
|
11
|
+
# end
|
12
|
+
# end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<title>Page Not Found</title>
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
7
|
+
<style>
|
8
|
+
|
9
|
+
* {
|
10
|
+
line-height: 1.2;
|
11
|
+
margin: 0;
|
12
|
+
}
|
13
|
+
|
14
|
+
html {
|
15
|
+
color: #888;
|
16
|
+
display: table;
|
17
|
+
font-family: sans-serif;
|
18
|
+
height: 100%;
|
19
|
+
text-align: center;
|
20
|
+
width: 100%;
|
21
|
+
}
|
22
|
+
|
23
|
+
body {
|
24
|
+
display: table-cell;
|
25
|
+
vertical-align: middle;
|
26
|
+
margin: 2em auto;
|
27
|
+
}
|
28
|
+
|
29
|
+
h1 {
|
30
|
+
color: #555;
|
31
|
+
font-size: 2em;
|
32
|
+
font-weight: 400;
|
33
|
+
}
|
34
|
+
|
35
|
+
p {
|
36
|
+
margin: 0 auto;
|
37
|
+
width: 280px;
|
38
|
+
}
|
39
|
+
|
40
|
+
@media only screen and (max-width: 280px) {
|
41
|
+
|
42
|
+
body, p {
|
43
|
+
width: 95%;
|
44
|
+
}
|
45
|
+
|
46
|
+
h1 {
|
47
|
+
font-size: 1.5em;
|
48
|
+
margin: 0 0 0.3em;
|
49
|
+
}
|
50
|
+
|
51
|
+
}
|
52
|
+
|
53
|
+
</style>
|
54
|
+
</head>
|
55
|
+
<body>
|
56
|
+
<h1>Page Not Found</h1>
|
57
|
+
<p>Sorry, but the page you were trying to view does not exist.</p>
|
58
|
+
</body>
|
59
|
+
</html>
|
60
|
+
<!-- IE needs 512+ bytes: http://blogs.msdn.com/b/ieinternals/archive/2010/08/19/http-error-pages-in-internet-explorer.aspx -->
|
Binary file
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<!-- Please read: http://msdn.microsoft.com/en-us/library/ie/dn455106.aspx -->
|
3
|
+
<browserconfig>
|
4
|
+
<msapplication>
|
5
|
+
<tile>
|
6
|
+
<square70x70logo src="tile.png"/>
|
7
|
+
<square150x150logo src="tile.png"/>
|
8
|
+
<wide310x150logo src="tile-wide.png"/>
|
9
|
+
<square310x310logo src="tile.png"/>
|
10
|
+
</tile>
|
11
|
+
</msapplication>
|
12
|
+
</browserconfig>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
|
3
|
+
<cross-domain-policy>
|
4
|
+
<!-- Read this: www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html -->
|
5
|
+
|
6
|
+
<!-- Most restrictive policy: -->
|
7
|
+
<site-control permitted-cross-domain-policies="none"/>
|
8
|
+
|
9
|
+
<!-- Least restrictive policy: -->
|
10
|
+
<!--
|
11
|
+
<site-control permitted-cross-domain-policies="all"/>
|
12
|
+
<allow-access-from domain="*" to-ports="*" secure="false"/>
|
13
|
+
<allow-http-request-headers-from domain="*" headers="*" secure="false"/>
|
14
|
+
-->
|
15
|
+
</cross-domain-policy>
|
Binary file
|
Binary file
|
Binary file
|
data/lib/sinator.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# :)
|
data/sinator.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative 'lib/sinator/version'
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'sinator'
|
5
|
+
s.version = Sinator::VERSION
|
6
|
+
s.date = Date.today.to_s
|
7
|
+
s.summary = "Sinatra application boilerplate generator"
|
8
|
+
s.description = "Sinator provides generator and contains minimal configuration to develop application with Sinatra"
|
9
|
+
s.author = 'Kunto Aji Kristianto'
|
10
|
+
s.email = 'kuntoaji@kaklabs.com'
|
11
|
+
s.files = `git ls-files -z`.split("\x0")
|
12
|
+
s.executables << 'sinator'
|
13
|
+
s.homepage = 'http://github.com/kuntoaji/sinator'
|
14
|
+
s.license = 'MIT'
|
15
|
+
|
16
|
+
s.required_ruby_version = '>= 2.1'
|
17
|
+
s.add_development_dependency 'bundler', '~> 1.7'
|
18
|
+
s.add_development_dependency 'rspec', '3.2.0'
|
19
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
environment 'production'
|
2
|
+
bind 'unix:///path/to/shared/tmp/sockets/puma.sock'
|
3
|
+
pidfile '/path/to/shared/tmp/pids/puma.pid'
|
4
|
+
ctl_socket = '/path/to/shared/tmp/sockets/pumactl.sock'
|
5
|
+
state_path '/path/to/shared/tmp/sockets/puma.state'
|
6
|
+
activate_control_app 'unix:///path/to/shared/tmp/sockets/pumactl.sock'
|
7
|
+
daemonize
|
8
|
+
quiet
|
9
|
+
|
10
|
+
threads 5, 5
|
11
|
+
workers 2
|
12
|
+
preload_app!
|
13
|
+
|
14
|
+
before_fork do
|
15
|
+
MyApp::DB.disconnect if defined?(MyApp::DB)
|
16
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
class MyApp < Sinatra::Application
|
4
|
+
use Rack::Session::EncryptedCookie,
|
5
|
+
secret: 'supersecretcookiefromgenerator'
|
6
|
+
|
7
|
+
set :app_file, __FILE__
|
8
|
+
set :server, :puma
|
9
|
+
set :views, Proc.new { File.join(root, "app/views") }
|
10
|
+
set :assets, Sprockets::Environment.new
|
11
|
+
set :assets_manifest, %w(app.js app.css)
|
12
|
+
use Rack::Csrf, raise: true
|
13
|
+
|
14
|
+
configure do
|
15
|
+
Sequel::Database.extension :pagination
|
16
|
+
Sequel::Model.plugin :timestamps
|
17
|
+
Sequel::Model.plugin :auto_validations,
|
18
|
+
not_null: :presence, unique_opts: { only_if_modified: true }
|
19
|
+
|
20
|
+
assets.append_path 'assets/stylesheets'
|
21
|
+
assets.append_path 'assets/javascripts'
|
22
|
+
end
|
23
|
+
|
24
|
+
configure :development do
|
25
|
+
require 'sinatra/reloader'
|
26
|
+
require 'logger'
|
27
|
+
|
28
|
+
register Sinatra::Reloader
|
29
|
+
Sequel.connect YAML.load_file(File.expand_path("../config/database.yml", __FILE__))['development'],
|
30
|
+
loggers: [Logger.new($stdout)]
|
31
|
+
|
32
|
+
get '/assets/*' do
|
33
|
+
env['PATH_INFO'].sub!('/assets', '')
|
34
|
+
settings.assets.call(env)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
configure :test do
|
39
|
+
Sequel.connect YAML.load_file(File.expand_path("../config/database.yml", __FILE__))['test']
|
40
|
+
end
|
41
|
+
|
42
|
+
configure :production do
|
43
|
+
# Serve assets via Nginx or Apache
|
44
|
+
disable :static
|
45
|
+
|
46
|
+
assets.js_compressor = :uglify
|
47
|
+
assets.css_compressor = :sass
|
48
|
+
Sequel.connect YAML.load_file(File.expand_path("../config/database.yml", __FILE__))['production']
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'sinatra', '2.0.0'
|
4
|
+
gem 'sinatra-contrib', '2.0.0', require: false
|
5
|
+
gem 'encrypted_cookie', '0.0.5'
|
6
|
+
gem 'rack_csrf', '2.6.0', require: 'rack/csrf'
|
7
|
+
gem 'puma', '3.11.0'
|
8
|
+
gem 'tux', '0.3.0', require: false
|
9
|
+
gem 'uglifier', '4.1.3', require: false
|
10
|
+
gem 'sass', '3.5.5', require: false
|
11
|
+
gem 'sprockets', '3.7.1'
|
12
|
+
gem 'sequel', '5.4.0'
|
13
|
+
gem 'sequel_pg', '1.8.1', require: 'sequel'
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require_relative 'config/boot'
|
2
|
+
require_relative 'my_app'
|
3
|
+
|
4
|
+
namespace :assets do
|
5
|
+
desc "Precompile assets"
|
6
|
+
task :precompile do
|
7
|
+
manifest = ::Sprockets::Manifest.new(MyApp.assets.index, "#{MyApp.public_folder}/assets")
|
8
|
+
manifest.compile(MyApp.assets_manifest)
|
9
|
+
end
|
10
|
+
|
11
|
+
desc "Clean assets"
|
12
|
+
task :clean do
|
13
|
+
FileUtils.rm_rf("#{MyApp.public_folder}/assets")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
namespace :db do
|
18
|
+
desc "Run migrations"
|
19
|
+
task :migrate, [:version] do |t, args|
|
20
|
+
Sequel.extension :migration
|
21
|
+
db = Sequel.connect(YAML.load_file("#{Sinator::ROOT}/config/database.yml")[ENV['APP_ENV']])
|
22
|
+
migration_path = "#{Sinator::ROOT}/db/migrations"
|
23
|
+
|
24
|
+
if args[:version]
|
25
|
+
puts "Migrating to version #{args[:version]}"
|
26
|
+
Sequel::Migrator.run(db, migration_path, target: args[:version].to_i)
|
27
|
+
else
|
28
|
+
puts "Migrating to latest"
|
29
|
+
Sequel::Migrator.run(db, migration_path)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class MyApp < Sinatra::Application
|
2
|
+
use Rack::Session::EncryptedCookie,
|
3
|
+
secret: 'supersecretcookiefromgenerator'
|
4
|
+
|
5
|
+
set :app_file, __FILE__
|
6
|
+
set :server, :puma
|
7
|
+
set :views, Proc.new { File.join(root, "app/views") }
|
8
|
+
set :assets, Sprockets::Environment.new
|
9
|
+
set :assets_manifest, %w(app.js app.css)
|
10
|
+
use Rack::Csrf, raise: true
|
11
|
+
|
12
|
+
configure do
|
13
|
+
assets.append_path 'assets/stylesheets'
|
14
|
+
assets.append_path 'assets/javascripts'
|
15
|
+
end
|
16
|
+
|
17
|
+
configure :development do
|
18
|
+
get '/assets/*' do
|
19
|
+
env['PATH_INFO'].sub!('/assets', '')
|
20
|
+
settings.assets.call(env)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
configure :production do
|
25
|
+
# Serve assets via Nginx or Apache
|
26
|
+
disable :static
|
27
|
+
|
28
|
+
assets.js_compressor = :uglify
|
29
|
+
assets.css_compressor = :sass
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'sinatra', '2.0.0'
|
4
|
+
gem 'sinatra-contrib', '2.0.0', require: false
|
5
|
+
gem 'encrypted_cookie', '0.0.5'
|
6
|
+
gem 'rack_csrf', '2.6.0', require: 'rack/csrf'
|
7
|
+
gem 'puma', '3.11.0'
|
8
|
+
gem 'tux', '0.3.0', require: false
|
9
|
+
gem 'uglifier', '4.1.3', require: false
|
10
|
+
gem 'sass', '3.5.5', require: false
|
11
|
+
gem 'sprockets', '3.7.1'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require_relative 'config/boot'
|
2
|
+
require_relative 'my_app'
|
3
|
+
|
4
|
+
namespace :assets do
|
5
|
+
desc "Precompile assets"
|
6
|
+
task :precompile do
|
7
|
+
manifest = ::Sprockets::Manifest.new(MyApp.assets.index, "#{MyApp.public_folder}/assets")
|
8
|
+
manifest.compile(MyApp.assets_manifest)
|
9
|
+
end
|
10
|
+
|
11
|
+
desc "Clean assets"
|
12
|
+
task :clean do
|
13
|
+
FileUtils.rm_rf("#{MyApp.public_folder}/assets")
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Helper
|
2
|
+
module Generator
|
3
|
+
def expect_file_eq(file, expected_file)
|
4
|
+
file_content = File.read(file)
|
5
|
+
expected_file_content = File.read(expected_file)
|
6
|
+
|
7
|
+
expect(File.exists?(file)).to be_truthy
|
8
|
+
expect(file_content).to eq(expected_file_content)
|
9
|
+
end
|
10
|
+
|
11
|
+
def expected_default_files(target_dir, expected_value)
|
12
|
+
config_dir = "#{target_dir}/config"
|
13
|
+
assets_dir = "#{target_dir}/assets"
|
14
|
+
public_dir = "#{target_dir}/public"
|
15
|
+
boot = "#{config_dir}/boot.rb"
|
16
|
+
application = "#{config_dir}/application.rb"
|
17
|
+
|
18
|
+
app_dir = "#{target_dir}/app"
|
19
|
+
routes_dir = "#{target_dir}/app/routes"
|
20
|
+
views_dir = "#{target_dir}/app/views"
|
21
|
+
layout = "#{target_dir}/app/views/layout.erb"
|
22
|
+
home_index = "#{target_dir}/app/views/home/index.erb"
|
23
|
+
|
24
|
+
expect(File.exists?(config_dir)).to eq(expected_value)
|
25
|
+
expect(File.exists?("#{config_dir}/boot.rb")).to eq(expected_value)
|
26
|
+
expect(File.exists?("#{config_dir}/application.rb")).to eq(expected_value)
|
27
|
+
expect(File.exists?(assets_dir)).to eq(expected_value)
|
28
|
+
expect(File.exists?(public_dir)).to eq(expected_value)
|
29
|
+
|
30
|
+
expect(Dir.exists?(app_dir)).to eq(expected_value)
|
31
|
+
expect(Dir.exists?(routes_dir)).to eq(expected_value)
|
32
|
+
expect(Dir.exists?(views_dir)).to eq(expected_value)
|
33
|
+
expect(File.exists?(layout)).to eq(expected_value)
|
34
|
+
expect(File.exists?(home_index)).to eq(expected_value)
|
35
|
+
end
|
36
|
+
|
37
|
+
def expected_generated_files_with_db(target_dir, expected_value)
|
38
|
+
sample_migration = "#{target_dir}/db/migrations/000_example.rb"
|
39
|
+
|
40
|
+
expect(Dir.exists?("#{target_dir}/app/models")).to eq(expected_value)
|
41
|
+
expect(File.exists?("#{target_dir}/config/database.yml")).to eq(expected_value)
|
42
|
+
expect(File.exists?(sample_migration)).to eq(expected_value)
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require_relative '../../lib/sinator/command'
|
2
|
+
|
3
|
+
describe Sinator::Command do
|
4
|
+
|
5
|
+
describe "parse" do
|
6
|
+
def remove_existing_app_if_exists
|
7
|
+
FileUtils.rm_r "my_app" if Dir.exists?("my_app")
|
8
|
+
FileUtils.rm_r "/tmp/my_app" if Dir.exists?("/tmp/my_app")
|
9
|
+
end
|
10
|
+
|
11
|
+
before do
|
12
|
+
remove_existing_app_if_exists
|
13
|
+
end
|
14
|
+
|
15
|
+
after :all do
|
16
|
+
remove_existing_app_if_exists
|
17
|
+
end
|
18
|
+
|
19
|
+
it "has --help option" do
|
20
|
+
help = Sinator::Command.parse %w(--help)
|
21
|
+
|
22
|
+
expect(help).to include "Usage: sinator [options]"
|
23
|
+
expect(help).to include "Print this help"
|
24
|
+
end
|
25
|
+
|
26
|
+
it "has --version option" do
|
27
|
+
version = Sinator::Command.parse %w(--version)
|
28
|
+
|
29
|
+
expect(version).to include Sinator::VERSION
|
30
|
+
end
|
31
|
+
|
32
|
+
it "has --name option as required option to generate application" do
|
33
|
+
app = Sinator::Command.parse %w(--name my_app)
|
34
|
+
|
35
|
+
expect(app).to include "my_app is successfully generated"
|
36
|
+
end
|
37
|
+
|
38
|
+
it "has --target option as target directory" do
|
39
|
+
app = Sinator::Command.parse %w(-n my_app --target /tmp)
|
40
|
+
|
41
|
+
expect(app).to include "my_app is successfully generated in /tmp"
|
42
|
+
expect(Dir.exists?("/tmp/my_app")).to be_truthy
|
43
|
+
end
|
44
|
+
|
45
|
+
it "has --database option" do
|
46
|
+
app = Sinator::Command.parse %w(-n my_app --target /tmp -d)
|
47
|
+
|
48
|
+
expect(app).to include "my_app is successfully generated in /tmp"
|
49
|
+
expect(Dir.exists?("/tmp/my_app/db")).to be_truthy
|
50
|
+
end
|
51
|
+
|
52
|
+
context "when has no --name option and only --target option" do
|
53
|
+
it "does nothing" do
|
54
|
+
app = Sinator::Command.parse %w(--target /tmp/sinator)
|
55
|
+
|
56
|
+
expect(app).to be_nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "when has no option" do
|
61
|
+
it "uses --help option by default" do
|
62
|
+
help = Sinator::Command.parse []
|
63
|
+
|
64
|
+
expect(help).to include "Usage: sinator [options]"
|
65
|
+
expect(help).to include "Print this help"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|