sincli 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rspec +3 -0
  4. data/CODE_OF_CONDUCT.md +74 -0
  5. data/Gemfile +5 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +53 -0
  8. data/Rakefile +6 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +8 -0
  11. data/exe/sincli +3 -0
  12. data/lib/sincli.rb +16 -0
  13. data/lib/sincli/generator.rb +18 -0
  14. data/lib/sincli/generators/application.rb +60 -0
  15. data/lib/sincli/generators/assets.rb +13 -0
  16. data/lib/sincli/generators/base.rb +46 -0
  17. data/lib/sincli/generators/config.rb +56 -0
  18. data/lib/sincli/generators/executions.rb +51 -0
  19. data/lib/sincli/generators/models_and_controllers.rb +16 -0
  20. data/lib/sincli/generators/root_files.rb +47 -0
  21. data/lib/sincli/generators/views.rb +14 -0
  22. data/lib/sincli/templates/basic/.gitignore +20 -0
  23. data/lib/sincli/templates/basic/Gemfile.tt +44 -0
  24. data/lib/sincli/templates/basic/Rakefile +5 -0
  25. data/lib/sincli/templates/basic/app/assets/javascripts/application.js +5 -0
  26. data/lib/sincli/templates/basic/app/assets/stylesheets/application.css +14 -0
  27. data/lib/sincli/templates/basic/app/controllers/application_controller.rb.tt +15 -0
  28. data/lib/sincli/templates/basic/app/models/application_record.rb +3 -0
  29. data/lib/sincli/templates/basic/app/views/layout.erb.tt +28 -0
  30. data/lib/sincli/templates/basic/config.ru.tt +36 -0
  31. data/lib/sincli/templates/basic/config/application.rb.tt +61 -0
  32. data/lib/sincli/templates/basic/config/database.yml.tt +18 -0
  33. data/lib/sincli/templates/basic/config/environment.rb +9 -0
  34. data/lib/sincli/templates/basic/config/locales/en.yml +215 -0
  35. data/lib/sincli/templates/basic/config/puma.rb +38 -0
  36. data/lib/sincli/utils/string.rb +9 -0
  37. data/lib/sincli/version.rb +3 -0
  38. data/sincli.gemspec +31 -0
  39. metadata +140 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 6397df9fb77a8eef5e5f9c88be1f6cb2b602c9fdebbd71ac942ecc8e7a99e58b
4
+ data.tar.gz: ddd7df1dc572ebb610994e745c6b309df303a1aa930c4108292d51aea5b646cc
5
+ SHA512:
6
+ metadata.gz: b1e1e170bac2bf77e3457e161545c4a52b02278013ff61a7b2717d7a8dc389aded8aba94dbd5d39017597138ffdf3563de12740b8cbc7e28a844e9f35207d7fb
7
+ data.tar.gz: 928ac2007c08247920801514be791ad56d312ef6a49b7763fa18e644c684ca1527ce22f484d390defec9155cab6b9e84392871b2f8259c3d1a26d278bb050c82
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ Gemfile.lock
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at ezenwaogbonna1@gmail.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [https://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: https://contributor-covenant.org
74
+ [version]: https://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in sinatra_app_generator.gemspec
4
+ gemspec
5
+ gem 'coveralls', require: false
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 OZONE4REAL
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
13
+ all 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
21
+ THE SOFTWARE.
@@ -0,0 +1,53 @@
1
+ [![Build Status](https://travis-ci.com/ozone4real/sincli.svg?branch=master)](https://travis-ci.com/ozone4real/sincli) [![Coverage Status](https://coveralls.io/repos/github/ozone4real/sincli/badge.svg?branch=master)](https://coveralls.io/github/ozone4real/sincli?branch=master)
2
+ # Sincli
3
+
4
+ Command line tool for initializing a new modular Sinatra application with default configurations. This includes the basic things that are needed to build any kind of application with Sinatra. The application is setup with a structure that is similar to Rails. The goal of this project is to help reduce the time spent in setting up and configuring your new Sinatra application.
5
+
6
+ ## Installation
7
+
8
+ Run this on your command line:
9
+
10
+ $ gem install sincli
11
+
12
+ ## Usage
13
+
14
+ Initialize a new Sinatra application:
15
+
16
+ ```
17
+ $ sincli new "APP_NAME"
18
+ ```
19
+
20
+ To view the list of available options run:
21
+
22
+ ```
23
+ $ sincli help new
24
+ ```
25
+
26
+ ## Some of the configurations set up
27
+
28
+ - Rack
29
+ - Assets Pipeline (with Sprockets)
30
+ - Puma (if 'puma' is passed as the server option)
31
+ - RSpec
32
+ - Sinatra extensions
33
+ - Internationalization (with 1i8n)
34
+ - Database
35
+ - CORS (if the --api-only flag is passed)
36
+
37
+ ## Development
38
+
39
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
40
+
41
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
42
+
43
+ ## Contributing
44
+
45
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ozone4real/sincli. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/ozone4real/sincli/blob/master/CODE_OF_CONDUCT.md).
46
+
47
+ ## License
48
+
49
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
50
+
51
+ ## Code of Conduct
52
+
53
+ Everyone interacting in the Sincli project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/ozone4reak/sincli/blob/master/CODE_OF_CONDUCT.md).
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'sincli'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby -W0
2
+ require 'sincli'
3
+ Sincli::Generator.start
@@ -0,0 +1,16 @@
1
+ require 'sincli/version'
2
+ require 'thor'
3
+ require 'active_support/core_ext/string'
4
+ require 'sincli/utils/string'
5
+ require 'sincli/generators/base'
6
+ require 'sincli/generators/application'
7
+ require 'sincli/generators/assets'
8
+ require 'sincli/generators/config'
9
+ require 'sincli/generators/executions'
10
+ require 'sincli/generators/models_and_controllers'
11
+ require 'sincli/generators/root_files'
12
+ require 'sincli/generators/views'
13
+
14
+ module Sincli
15
+ autoload :Generator, 'sincli/generator'
16
+ end
@@ -0,0 +1,18 @@
1
+ module Sincli
2
+ class Generator < Thor
3
+ def self.exit_on_failure?
4
+ true
5
+ end
6
+
7
+ desc 'new APP_NAME', 'bootstraps a new modular Sinatra application with default configurations'
8
+ option :db, aliases: 'd', default: 'sqlite', desc: 'Database to use. Negated if the --no-database flag is passed', enum: %w[sqlite postgres mysql]
9
+ option :api_only, default: false, type: :boolean, desc: 'Set up a Sinatra API application with only the basic things that are needed to build an API.'
10
+ option :server, aliases: 's', default: 'thin', desc: 'Rack-based server to use', enum: %w[puma thin falcon webrick]
11
+ option :no_contrib, default: false, type: :boolean, desc: 'Setup without sinatra-contrib extensions'
12
+ option :no_database, default: false, type: :boolean, desc: 'Setup without ActiveRecord and database config'
13
+
14
+ def new(app_name)
15
+ Generators::Application.new(app_name, options.dup).create
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,60 @@
1
+ module Sincli
2
+ module Generators
3
+ class Application
4
+ attr_reader :name, :options
5
+
6
+ def initialize(name, options)
7
+ @name = name
8
+ @options = options
9
+ @options.delete(:db) if @options[:no_database]
10
+ end
11
+
12
+ def create
13
+ create_root_dir
14
+ create_root_files
15
+ create_config
16
+ create_app_dir
17
+ create_views
18
+ create_assets
19
+ create_models_and_controllers
20
+ Dir.chdir('..')
21
+ Executions.new(name, options).execute
22
+ end
23
+
24
+ def create_root_files
25
+ RootFiles.new(name, options).generate
26
+ end
27
+
28
+ def create_config
29
+ Config.new(name, options).generate
30
+ end
31
+
32
+ def create_root_dir
33
+ dir_name = name.dash_case
34
+ dir = Dir.mkdir(dir_name)
35
+ Dir.chdir(dir_name)
36
+ end
37
+
38
+ def create_app_dir
39
+ Dir.mkdir 'app'
40
+ Dir.chdir 'app'
41
+ end
42
+
43
+ def create_views
44
+ return if options[:api_only]
45
+
46
+ Views.new(name, options).generate
47
+ end
48
+
49
+ def create_assets
50
+ return if options[:api_only]
51
+
52
+ Assets.new(name, options).generate
53
+ end
54
+
55
+ def create_models_and_controllers
56
+ ModelsAndControllers.new(name, options).generate
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,13 @@
1
+ module Sincli
2
+ module Generators
3
+ class Assets < Base
4
+ def self.source_root
5
+ super.join('basic/app')
6
+ end
7
+
8
+ def generate
9
+ directory('assets', 'assets')
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,46 @@
1
+ require 'pathname'
2
+
3
+ module Sincli
4
+ module Generators
5
+ class Base < Thor::Group
6
+ include Thor::Actions
7
+ attr_reader :options, :name
8
+
9
+ def initialize(name, options)
10
+ @name = name
11
+ @options = options
12
+ self.destination_root = Dir.pwd
13
+ self.behavior = :invoke
14
+ end
15
+
16
+ private
17
+
18
+ def git_keep
19
+ create_file('.', '.gitkeep')
20
+ end
21
+
22
+ def contrib_extensions
23
+ return [] if options[:no_contrib]
24
+
25
+ %w[reloader required_params].tap do |e|
26
+ if @options[:api_only]
27
+ e.push 'json'
28
+ else
29
+ e.push 'respond_with', 'content_for'
30
+ end
31
+ end
32
+ end
33
+
34
+ def extensions
35
+ return contrib_extensions if options[:api_only]
36
+
37
+ contrib_extensions + ['flash']
38
+ end
39
+
40
+ def self.source_root
41
+ f = File.expand_path('../templates', __dir__)
42
+ Pathname.new f
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,56 @@
1
+ module Sincli
2
+ module Generators
3
+ class Config < Base
4
+ def generate
5
+ Dir.mkdir('config')
6
+ sec_key
7
+ db_config
8
+ environment
9
+ puma_config
10
+ locales
11
+ end
12
+
13
+ def self.source_root
14
+ super.join('basic/config')
15
+ end
16
+ private_class_method :source_root
17
+
18
+ def sec_key
19
+ begin
20
+ require 'securerandom'
21
+ sec_key = SecureRandom.hex(64)
22
+ rescue LoadError, NotImplementedError
23
+ # SecureRandom raises a NotImplementedError if no random device is available
24
+ sec_key = '%064x' % Kernel.rand(2**256 - 1)
25
+ end
26
+ create_file('config/.secret_key', sec_key)
27
+ end
28
+
29
+ def db_config
30
+ return unless db = @options[:db]
31
+
32
+ @options[:adapter] = db == 'pg' ? 'postgresql' : db
33
+ template('database.yml.tt', 'config/database.yml')
34
+ end
35
+
36
+ def puma_config
37
+ return unless @options[:server] == 'puma'
38
+
39
+ copy_file('puma.rb', 'config/puma.rb')
40
+ end
41
+
42
+ def environment
43
+ copy_file('environment.rb', 'config/environment.rb')
44
+ @extensions = extensions.map do |e|
45
+ ext = e == 'json' ? e.upcase : e.camelize
46
+ "Sinatra::#{ext}"
47
+ end
48
+ template('application.rb.tt', 'config/application.rb')
49
+ end
50
+
51
+ def locales
52
+ directory('locales', 'config/locales')
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,51 @@
1
+ module Sincli
2
+ module Generators
3
+ class Executions < Base
4
+ def execute
5
+ run('git init')
6
+ run('bundle install')
7
+ run('rspec --init')
8
+ configure_rspec
9
+ end
10
+
11
+ private
12
+
13
+ def configure_rspec
14
+ insert_into_file('spec/spec_helper.rb', before: "RSpec.configure do |config|\n") do
15
+ <<~RUBY
16
+ ENV['SINATRA_ENV'] = 'test'
17
+ ENV['RACK_ENV'] = 'test'
18
+ require "./config/environment"
19
+ RUBY
20
+ end
21
+ insert_into_file('spec/spec_helper.rb', after: "RSpec.configure do |config|\n") do
22
+ <<~RUBY
23
+ # Sinatra application
24
+ \ def app
25
+ ApplicationController
26
+ \ end
27
+ \ config.include Rack::Test::Methods
28
+ \ #{dbcleaner_config}
29
+ RUBY
30
+ end
31
+ end
32
+
33
+ def dbcleaner_config
34
+ return if options[:no_database]
35
+
36
+ <<~RUBY
37
+ \ config.before(:suite) do
38
+ \ DatabaseCleaner.strategy = :transaction
39
+ \ DatabaseCleaner.clean_with(:truncation)
40
+ \ end
41
+
42
+ \ config.around(:each) do |example|
43
+ \ DatabaseCleaner.cleaning do
44
+ \ example.run
45
+ \ end
46
+ \ end
47
+ RUBY
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,16 @@
1
+ module Sincli
2
+ module Generators
3
+ class ModelsAndControllers < Base
4
+ def self.source_root
5
+ super.join('basic/app')
6
+ end
7
+ private_class_method :source_root
8
+
9
+ def generate
10
+ directory('models') if @options[:db]
11
+ empty_directory('controllers')
12
+ template('controllers/application_controller.rb.tt', 'controllers/application_controller.rb')
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,47 @@
1
+ module Sincli
2
+ module Generators
3
+ class RootFiles < Base
4
+ include Thor::Actions
5
+
6
+ def generate
7
+ set_options
8
+ gemfile
9
+ rackup
10
+ gitignore
11
+ rakefile
12
+ end
13
+
14
+ private
15
+
16
+ def rackup
17
+ template('basic/config.ru.tt', 'config.ru')
18
+ end
19
+
20
+ def gitignore
21
+ copy_file('basic/.gitignore', '.gitignore')
22
+ end
23
+
24
+ def gemfile
25
+ @contrib_extensions = contrib_extensions.map { |e| "sinatra/#{e}" }
26
+ template('basic/Gemfile.tt', 'Gemfile', verbose: true)
27
+ end
28
+
29
+ def rakefile
30
+ copy_file('basic/Rakefile', 'Rakefile')
31
+ end
32
+
33
+ def set_options
34
+ return unless @options[:db]
35
+
36
+ @options[:db] = case @options[:db]
37
+ when 'mysql'
38
+ 'mysql2'
39
+ when /^postgres|pg/
40
+ 'pg'
41
+ when /^sqlite/
42
+ 'sqlite3'
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,14 @@
1
+ module Sincli
2
+ module Generators
3
+ class Views < Base
4
+ def self.source_root
5
+ super.join('basic/app/views')
6
+ end
7
+ private_class_method :source_root
8
+
9
+ def generate
10
+ template('layout.erb.tt', 'views/layout.erb')
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,20 @@
1
+ # See https://help.github.com/articles/ignoring-files for more about ignoring files.
2
+ #
3
+ # If you find yourself ignoring temporary files generated by your text editor
4
+ # or operating system, you probably want to add a global ignore instead:
5
+ # git config --global core.excludesfile '~/.gitignore_global'
6
+
7
+ # Ignore bundler config.
8
+ /.bundle
9
+
10
+ # Ignore the default SQLite database.
11
+ /db/*.sqlite3
12
+ /db/*.sqlite3-journal
13
+
14
+ # Ignore uploaded files in development
15
+ /storage/*
16
+ !/storage/.keep
17
+
18
+ # Ignore secret key.
19
+ /config/.secret_key
20
+
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
6
+
7
+ gem 'sinatra'
8
+ <% if @options[:db] %>
9
+ gem 'activerecord', '~> 5.2.3'
10
+ gem 'sinatra-activerecord', '~> 2.0.1'
11
+ gem '<%= @options[:db] %>'
12
+ <% else %>
13
+ gem 'activesupport', '~> 5.2.3', require: 'active_support/all'
14
+ <% end %>
15
+ <% unless @options[:api_only] %>
16
+ gem 'sprockets', '~> 3.7'
17
+ gem 'sprockets-helpers', '~> 1.4.0'
18
+ gem 'sass', '~> 3.4', '>= 3.4.22'
19
+ gem 'uglifier', '~> 4.2.0'
20
+ gem 'sinatra-flash', '~> 0.3.0'
21
+ gem 'coffee-script', '~> 2.4.0'
22
+ <% end %>
23
+ <% if @options[:api_only] %>
24
+ gem 'rack-cors'
25
+ <%end%>gem 'rake'
26
+ gem 'require_all'
27
+ gem 'bcrypt'
28
+ gem '<%= @options[:server] %>'
29
+ gem 'i18n', '~> 1.8.0'
30
+ <% unless @options[:no_contrib] %>
31
+ gem 'sinatra-contrib', :require => <%= @contrib_extensions %>
32
+ <% end %>
33
+
34
+ group :development, :test do
35
+ gem 'pry'
36
+ end
37
+
38
+ group :test do
39
+ gem 'rspec'
40
+ gem 'rack-test'<% if @options[:db] %>
41
+ gem 'database_cleaner-active_record', "~> 1.8.0"
42
+ <% end %>
43
+ end
44
+
@@ -0,0 +1,5 @@
1
+ ENV['SINATRA_ENV'] ||= 'development'
2
+ ENV['RACK_ENV'] ||= 'development'
3
+
4
+ require_relative './config/environment'
5
+ require 'sinatra/activerecord/rake'
@@ -0,0 +1,5 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory can be referenced here using a relative path.
5
+ //= require_tree .
@@ -0,0 +1,14 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory
6
+ *
7
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
8
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
9
+ * files in this directory. Styles in this file should be added after the last require_* statement.
10
+ * It is generally better to create a new file per style scope.
11
+ *
12
+ *= require_tree .
13
+ *= require_self
14
+ */
@@ -0,0 +1,15 @@
1
+ class ApplicationController < Sinatra::Base
2
+ include Configuration
3
+
4
+ get '/' do <% if @options[:api_only] %><% unless @options[:no_contrib] %>
5
+ json({ message: "Hello World" })
6
+ <% end %><% else %>
7
+ erb "Hello World"
8
+ <% end %>
9
+ end
10
+
11
+ # methods that you want to be available in the views and controllers
12
+ helpers do
13
+
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ class ApplicationRecord < ActiveRecord::Base
2
+ self.abstract_class = true
3
+ end
@@ -0,0 +1,28 @@
1
+ <!DOCTYPE html>
2
+ <!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en"> <![endif]-->
3
+ <!--[if IE 7]> <html class="no-js ie7 oldie" lang="en"> <![endif]-->
4
+ <!--[if IE 8]> <html class="no-js ie8 oldie" lang="en"> <![endif]-->
5
+ <!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
6
+ <head>
7
+ <meta charset="utf-8" />
8
+ <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" />
9
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
10
+
11
+ <title><%= @name.titlecase %></title>
12
+
13
+ <link rel="stylesheet" href="<%%= stylesheet_path 'application' %>">
14
+ <script src="<%%= javascript_path 'application' %>"></script>
15
+ </head>
16
+ <body>
17
+ <div class="wrapper">
18
+ <%%= styled_flash %>
19
+ <main>
20
+ <%%= yield %>
21
+ </main>
22
+ </div>
23
+ <!--[if lt IE 7]>
24
+ <script src="//ajax.googleapis.com/ajax/libs/chrome-frame/1.0.2/CFInstall.min.js"></script>
25
+ <script>window.attachEvent("onload",function(){CFInstall.check({mode:"overlay"})})</script>
26
+ <![endif]-->
27
+ </body>
28
+ </html>
@@ -0,0 +1,36 @@
1
+ require './config/environment'
2
+ <% if @options[:db] %>
3
+ class MigrationCheck
4
+ def initialize(app)
5
+ @app = app
6
+ end
7
+
8
+ def call(env)
9
+ if ActiveRecord::MigrationContext.new('./db/migrate').needs_migration?
10
+ raise ActiveRecord::PendingMigrationError.new 'Migrations are pending. Run `rake db:migrate` to resolve the issue.'
11
+ end
12
+ @app.call(env)
13
+ end
14
+ end
15
+ <% end %>
16
+ <% unless @options[:api_only] %>
17
+ # Assets pipeline
18
+ map ApplicationController.assets_prefix do
19
+ run ApplicationController.sprockets
20
+ end
21
+ <% end %>
22
+ <% if @options[:api_only] %>
23
+ # Handle Cross-Origin Resource Sharing (CORS) in order to accept cross-origin AJAX requests.
24
+ # Read more: https://github.com/cyu/rack-cors
25
+ use Rack::Cors do
26
+ allow do
27
+ origins '*'
28
+ resource '*', headers: :any, methods: [:get, :post, :patch, :put]
29
+ end
30
+ end
31
+ <% end %>
32
+ run ApplicationController
33
+ <% if @options[:db] %>
34
+ use MigrationCheck
35
+ <% end %>
36
+ ApplicationController.subclasses.each {|klass| use klass }
@@ -0,0 +1,61 @@
1
+ module Configuration
2
+ extend ActiveSupport::Concern
3
+ included do
4
+ before do
5
+ if @env["CONTENT_TYPE"] == "application/json"
6
+ request.body.rewind
7
+ params.merge!(JSON.parse(request.body.read))
8
+ end
9
+ end
10
+
11
+ set :public_folder, 'public'
12
+ set :root, Pathname.new(__dir__).parent
13
+ <% @extensions.each do |e| %>
14
+ register <%= e %>
15
+ <% end %>
16
+ <% unless @options[:api_only] %>
17
+ # sessions
18
+ enable :sessions
19
+ set :session_secret, ENV["SINATRA_SECRET_KEY"] || File.read("config/.secret_key")
20
+
21
+ # Asset pipeline
22
+ set :assets_prefix, '/assets'
23
+ set :sprockets, Sprockets::Environment.new
24
+ set :digest_assets, false
25
+ set :views, 'app/views'
26
+
27
+ configure do
28
+ sprockets.append_path root.join('app', 'assets', 'stylesheets')
29
+ sprockets.append_path root.join('app', 'assets', 'javascripts')
30
+ sprockets.append_path root.join('app', 'assets', 'images')
31
+ uglify = Uglifier.new(:harmony => true)
32
+ sprockets.js_compressor = uglify
33
+ sprockets.css_compressor = :scss
34
+
35
+
36
+ Sprockets::Helpers.configure do |config|
37
+ config.environment = sprockets
38
+ config.prefix = assets_prefix
39
+ config.digest = digest_assets
40
+ config.public_path = public_folder
41
+
42
+ # Force to debug mode in development mode
43
+ # Debug mode automatically sets
44
+ # expand = true, digest = false, manifest = false
45
+ config.debug = true if development?
46
+ end
47
+ end
48
+
49
+ helpers do
50
+ include Sprockets::Helpers
51
+ end
52
+ <% end %>
53
+
54
+ # localisation
55
+ configure do
56
+ I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks)
57
+ I18n.load_path += Dir[root.join('config', 'locales', '*.yml')]
58
+ I18n.backend.load_translations
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,18 @@
1
+ <% name = @name.snake_case %>
2
+ default: &default
3
+ adapter: <%= @options[:adapter] %>
4
+
5
+ development:
6
+ <<: *default
7
+ database: <%= name + "_development" %>
8
+ username: ""
9
+ password: ""
10
+
11
+ test:
12
+ <<: *default
13
+ database: <%= name + "_test" %>
14
+ username: ""
15
+ password: ""
16
+
17
+ production:
18
+ <<: *default
@@ -0,0 +1,9 @@
1
+ ENV['SINATRA_ENV'] ||= 'development'
2
+
3
+ require 'bundler/setup'
4
+
5
+ Bundler.require(:default, ENV['SINATRA_ENV'])
6
+
7
+ require_relative './application.rb'
8
+ require './app/controllers/application_controller'
9
+ require_all 'app'
@@ -0,0 +1,215 @@
1
+ ---
2
+ en:
3
+ activerecord:
4
+ errors:
5
+ messages:
6
+ record_invalid: 'Validation failed: %{errors}'
7
+ restrict_dependent_destroy:
8
+ has_one: Cannot delete record because a dependent %{record} exists
9
+ has_many: Cannot delete record because dependent %{record} exist
10
+ date:
11
+ abbr_day_names:
12
+ - Sun
13
+ - Mon
14
+ - Tue
15
+ - Wed
16
+ - Thu
17
+ - Fri
18
+ - Sat
19
+ abbr_month_names:
20
+ -
21
+ - Jan
22
+ - Feb
23
+ - Mar
24
+ - Apr
25
+ - May
26
+ - Jun
27
+ - Jul
28
+ - Aug
29
+ - Sep
30
+ - Oct
31
+ - Nov
32
+ - Dec
33
+ day_names:
34
+ - Sunday
35
+ - Monday
36
+ - Tuesday
37
+ - Wednesday
38
+ - Thursday
39
+ - Friday
40
+ - Saturday
41
+ formats:
42
+ default: "%Y-%m-%d"
43
+ long: "%B %d, %Y"
44
+ short: "%b %d"
45
+ month_names:
46
+ -
47
+ - January
48
+ - February
49
+ - March
50
+ - April
51
+ - May
52
+ - June
53
+ - July
54
+ - August
55
+ - September
56
+ - October
57
+ - November
58
+ - December
59
+ order:
60
+ - :year
61
+ - :month
62
+ - :day
63
+ datetime:
64
+ distance_in_words:
65
+ about_x_hours:
66
+ one: about 1 hour
67
+ other: about %{count} hours
68
+ about_x_months:
69
+ one: about 1 month
70
+ other: about %{count} months
71
+ about_x_years:
72
+ one: about 1 year
73
+ other: about %{count} years
74
+ almost_x_years:
75
+ one: almost 1 year
76
+ other: almost %{count} years
77
+ half_a_minute: half a minute
78
+ less_than_x_seconds:
79
+ one: less than 1 second
80
+ other: less than %{count} seconds
81
+ less_than_x_minutes:
82
+ one: less than a minute
83
+ other: less than %{count} minutes
84
+ over_x_years:
85
+ one: over 1 year
86
+ other: over %{count} years
87
+ x_seconds:
88
+ one: 1 second
89
+ other: "%{count} seconds"
90
+ x_minutes:
91
+ one: 1 minute
92
+ other: "%{count} minutes"
93
+ x_days:
94
+ one: 1 day
95
+ other: "%{count} days"
96
+ x_months:
97
+ one: 1 month
98
+ other: "%{count} months"
99
+ x_years:
100
+ one: 1 year
101
+ other: "%{count} years"
102
+ prompts:
103
+ second: Second
104
+ minute: Minute
105
+ hour: Hour
106
+ day: Day
107
+ month: Month
108
+ year: Year
109
+ errors:
110
+ format: "%{attribute} %{message}"
111
+ messages:
112
+ accepted: must be accepted
113
+ blank: can't be blank
114
+ confirmation: doesn't match %{attribute}
115
+ empty: can't be empty
116
+ equal_to: must be equal to %{count}
117
+ even: must be even
118
+ exclusion: is reserved
119
+ greater_than: must be greater than %{count}
120
+ greater_than_or_equal_to: must be greater than or equal to %{count}
121
+ inclusion: is not included in the list
122
+ invalid: is invalid
123
+ less_than: must be less than %{count}
124
+ less_than_or_equal_to: must be less than or equal to %{count}
125
+ model_invalid: 'Validation failed: %{errors}'
126
+ not_a_number: is not a number
127
+ not_an_integer: must be an integer
128
+ odd: must be odd
129
+ other_than: must be other than %{count}
130
+ present: must be blank
131
+ required: must exist
132
+ taken: has already been taken
133
+ too_long:
134
+ one: is too long (maximum is 1 character)
135
+ other: is too long (maximum is %{count} characters)
136
+ too_short:
137
+ one: is too short (minimum is 1 character)
138
+ other: is too short (minimum is %{count} characters)
139
+ wrong_length:
140
+ one: is the wrong length (should be 1 character)
141
+ other: is the wrong length (should be %{count} characters)
142
+ template:
143
+ body: 'There were problems with the following fields:'
144
+ header:
145
+ one: 1 error prohibited this %{model} from being saved
146
+ other: "%{count} errors prohibited this %{model} from being saved"
147
+ helpers:
148
+ select:
149
+ prompt: Please select
150
+ submit:
151
+ create: Create %{model}
152
+ submit: Save %{model}
153
+ update: Update %{model}
154
+ number:
155
+ currency:
156
+ format:
157
+ delimiter: ","
158
+ format: "%u%n"
159
+ precision: 2
160
+ separator: "."
161
+ significant: false
162
+ strip_insignificant_zeros: false
163
+ unit: "$"
164
+ format:
165
+ delimiter: ","
166
+ precision: 3
167
+ separator: "."
168
+ significant: false
169
+ strip_insignificant_zeros: false
170
+ human:
171
+ decimal_units:
172
+ format: "%n %u"
173
+ units:
174
+ billion: Billion
175
+ million: Million
176
+ quadrillion: Quadrillion
177
+ thousand: Thousand
178
+ trillion: Trillion
179
+ unit: ''
180
+ format:
181
+ delimiter: ''
182
+ precision: 3
183
+ significant: true
184
+ strip_insignificant_zeros: true
185
+ storage_units:
186
+ format: "%n %u"
187
+ units:
188
+ byte:
189
+ one: Byte
190
+ other: Bytes
191
+ eb: EB
192
+ gb: GB
193
+ kb: KB
194
+ mb: MB
195
+ pb: PB
196
+ tb: TB
197
+ percentage:
198
+ format:
199
+ delimiter: ''
200
+ format: "%n%"
201
+ precision:
202
+ format:
203
+ delimiter: ''
204
+ support:
205
+ array:
206
+ last_word_connector: ", and "
207
+ two_words_connector: " and "
208
+ words_connector: ", "
209
+ time:
210
+ am: am
211
+ formats:
212
+ default: "%a, %d %b %Y %H:%M:%S %z"
213
+ long: "%B %d, %Y %H:%M"
214
+ short: "%d %b %H:%M"
215
+ pm: pm
@@ -0,0 +1,38 @@
1
+ # Puma can serve each request in a thread from an internal thread pool.
2
+ # The `threads` method setting takes two numbers: a minimum and maximum.
3
+ # Any libraries that use thread pools should be configured to match
4
+ # the maximum value specified for Puma. Default is set to 5 threads for minimum
5
+ # and maximum; this matches the default thread size of Active Record.
6
+ #
7
+ threads_count = ENV.fetch('SINATRA_MAX_THREADS') { 5 }
8
+ threads threads_count, threads_count
9
+
10
+ # Specifies the `port` that Puma will listen on to receive requests; default is 3000.
11
+ #
12
+ port ENV.fetch('PORT') { 3000 }
13
+
14
+ # Specifies the `environment` that Puma will run in.
15
+ #
16
+ environment ENV.fetch('SINATRA_ENV') { 'development' }
17
+
18
+ # Specifies the `pidfile` that Puma will use.
19
+ pidfile ENV.fetch('PIDFILE') {
20
+ path = 'tmp/pids'
21
+ FileUtils.mkdir_p(path) unless Dir.exist? path
22
+ path + '/server.pid'
23
+ }
24
+
25
+ # Specifies the number of `workers` to boot in clustered mode.
26
+ # Workers are forked webserver processes. If using threads and workers together
27
+ # the concurrency of the application would be max `threads` * `workers`.
28
+ # Workers do not work on JRuby or Windows (both of which do not support
29
+ # processes).
30
+ #
31
+ # workers ENV.fetch("WEB_CONCURRENCY") { 2 }
32
+
33
+ # Use the `preload_app!` method when specifying a `workers` number.
34
+ # This directive tells Puma to first boot the application and load code
35
+ # before forking the application. This takes advantage of Copy On Write
36
+ # process behavior so workers use less memory.
37
+ #
38
+ # preload_app!
@@ -0,0 +1,9 @@
1
+ class String
2
+ def dash_case
3
+ parameterize.dasherize
4
+ end
5
+
6
+ def snake_case
7
+ parameterize.underscore
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module Sincli
2
+ VERSION = '0.1.1'.freeze
3
+ end
@@ -0,0 +1,31 @@
1
+ require_relative 'lib/sincli/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = 'sincli'
5
+ spec.version = Sincli::VERSION
6
+ spec.authors = ['OZONE4REAL']
7
+ spec.email = ['ezenwaogbonna1@gmail.com']
8
+
9
+ spec.summary = 'Sinatra Cli'
10
+ spec.description = 'CLI for initializing a new modular Sinatra application with default configurations. The application is setup with a structure that is similar to Rails'
11
+ spec.homepage = 'https://github.com/ozone4real/sincli'
12
+ spec.license = 'MIT'
13
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.5.0')
14
+
15
+ spec.metadata['homepage_uri'] = spec.homepage
16
+ spec.metadata['source_code_uri'] = 'https://github.com/ozone4real/sincli'
17
+ spec.add_dependency 'activesupport', '~> 5.0'
18
+ spec.add_dependency 'thor', '~>1.0.1'
19
+ spec.add_development_dependency 'rake', '~> 12.0'
20
+ spec.add_development_dependency 'rspec', '~> 3.0'
21
+ # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
22
+
23
+ # Specify which files should be added to the gem when it is released.
24
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
25
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
26
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/|\.travis}) }
27
+ end
28
+ spec.bindir = 'exe'
29
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
+ spec.require_paths = ['lib']
31
+ end
metadata ADDED
@@ -0,0 +1,140 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sincli
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - OZONE4REAL
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-11-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '5.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '5.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: thor
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.0.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.0.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: '12.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '12.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ description: CLI for initializing a new modular Sinatra application with default configurations.
70
+ The application is setup with a structure that is similar to Rails
71
+ email:
72
+ - ezenwaogbonna1@gmail.com
73
+ executables:
74
+ - sincli
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - ".gitignore"
79
+ - ".rspec"
80
+ - CODE_OF_CONDUCT.md
81
+ - Gemfile
82
+ - LICENSE.txt
83
+ - README.md
84
+ - Rakefile
85
+ - bin/console
86
+ - bin/setup
87
+ - exe/sincli
88
+ - lib/sincli.rb
89
+ - lib/sincli/generator.rb
90
+ - lib/sincli/generators/application.rb
91
+ - lib/sincli/generators/assets.rb
92
+ - lib/sincli/generators/base.rb
93
+ - lib/sincli/generators/config.rb
94
+ - lib/sincli/generators/executions.rb
95
+ - lib/sincli/generators/models_and_controllers.rb
96
+ - lib/sincli/generators/root_files.rb
97
+ - lib/sincli/generators/views.rb
98
+ - lib/sincli/templates/basic/.gitignore
99
+ - lib/sincli/templates/basic/Gemfile.tt
100
+ - lib/sincli/templates/basic/Rakefile
101
+ - lib/sincli/templates/basic/app/assets/javascripts/application.js
102
+ - lib/sincli/templates/basic/app/assets/stylesheets/application.css
103
+ - lib/sincli/templates/basic/app/controllers/application_controller.rb.tt
104
+ - lib/sincli/templates/basic/app/models/application_record.rb
105
+ - lib/sincli/templates/basic/app/views/layout.erb.tt
106
+ - lib/sincli/templates/basic/config.ru.tt
107
+ - lib/sincli/templates/basic/config/application.rb.tt
108
+ - lib/sincli/templates/basic/config/database.yml.tt
109
+ - lib/sincli/templates/basic/config/environment.rb
110
+ - lib/sincli/templates/basic/config/locales/en.yml
111
+ - lib/sincli/templates/basic/config/puma.rb
112
+ - lib/sincli/utils/string.rb
113
+ - lib/sincli/version.rb
114
+ - sincli.gemspec
115
+ homepage: https://github.com/ozone4real/sincli
116
+ licenses:
117
+ - MIT
118
+ metadata:
119
+ homepage_uri: https://github.com/ozone4real/sincli
120
+ source_code_uri: https://github.com/ozone4real/sincli
121
+ post_install_message:
122
+ rdoc_options: []
123
+ require_paths:
124
+ - lib
125
+ required_ruby_version: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: 2.5.0
130
+ required_rubygems_version: !ruby/object:Gem::Requirement
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ requirements: []
136
+ rubygems_version: 3.0.8
137
+ signing_key:
138
+ specification_version: 4
139
+ summary: Sinatra Cli
140
+ test_files: []