natra 0.0.7 → 2.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 +4 -4
- data/.github/dependabot.yml +17 -0
- data/.github/workflows/ci.yml +50 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +26 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +58 -0
- data/CODE_OF_CONDUCT.md +0 -0
- data/Gemfile +12 -6
- data/Gemfile.lock +157 -116
- data/Guardfile +7 -5
- data/LICENSE.txt +0 -0
- data/README.md +138 -32
- data/Rakefile +4 -2
- data/bin/console +2 -0
- data/bin/natra +5 -3
- data/lib/extensions/string.rb +15 -11
- data/lib/natra/cli.rb +7 -2
- data/lib/natra/generators/app/app_generator.rb +32 -19
- data/lib/natra/generators/app/templates/Dockerfile +28 -10
- data/lib/natra/generators/app/templates/Gemfile +26 -20
- data/lib/natra/generators/app/templates/Guardfile +2 -0
- data/lib/natra/generators/app/templates/README.md +29 -30
- data/lib/natra/generators/app/templates/Rakefile +3 -2
- data/lib/natra/generators/app/templates/app/controllers/application_controller.rb +2 -0
- data/lib/natra/generators/app/templates/app/views/welcome.erb +2 -1
- data/lib/natra/generators/app/templates/bin/setup +4 -4
- data/lib/natra/generators/app/templates/config/database.yml +6 -6
- data/lib/natra/generators/app/templates/config/environment.rb +4 -5
- data/lib/natra/generators/app/templates/config/initializers/oj.rb +5 -4
- data/lib/natra/generators/app/templates/config/initializers/redis.rb +5 -3
- data/lib/natra/generators/app/templates/config/puma.rb +11 -5
- data/lib/natra/generators/app/templates/config.ru +2 -0
- data/lib/natra/generators/app/templates/db/migrate/add_extensions.rb +3 -1
- data/lib/natra/generators/app/templates/docker-compose.yml +3 -5
- data/lib/natra/generators/app/templates/rubocop.yml +8 -11
- data/lib/natra/generators/app/templates/spec/application_controller_spec.rb +2 -0
- data/lib/natra/generators/app/templates/spec/spec_helper.rb +10 -9
- data/lib/natra/generators/controller/controller_generator.rb +4 -0
- data/lib/natra/generators/model/migration.rb.erb +1 -1
- data/lib/natra/generators/model/model_generator.rb +8 -2
- data/lib/natra/generators/scaffold/scaffold_generator.rb +3 -0
- data/lib/natra/generators/service/service_generator.rb +31 -0
- data/lib/natra/generators/service/template/service.rb.erb +11 -0
- data/lib/natra/version.rb +3 -1
- data/lib/natra.rb +4 -0
- data/natra.gemspec +14 -11
- metadata +35 -39
- data/.coveralls.yml +0 -2
- data/.travis.yml +0 -3
data/README.md
CHANGED
|
@@ -1,61 +1,167 @@
|
|
|
1
1
|
# Natra
|
|
2
|
-
|
|
3
|
-
[](https://github.com/jamesnjuguna0419/natra/actions/workflows/ci.yml)
|
|
4
|
+
[](https://rubygems.org/gems/natra)
|
|
5
|
+
[](https://rubygems.org/gems/natra)
|
|
6
|
+
[](LICENSE.txt)
|
|
7
|
+
|
|
8
|
+
Natra is a command line generator for small Sinatra services. `natra new` creates a JSON API skeleton with ActiveRecord, PostgreSQL, Puma, RSpec, RuboCop and a Docker setup. Inside that app, `natra model`, `natra controller`, `natra scaffold` and `natra service_object` add models with migrations, controllers with views, and plain Ruby service objects.
|
|
9
|
+
|
|
10
|
+
## Requirements
|
|
11
|
+
|
|
12
|
+
- Ruby 3.3 or newer to run natra and the apps it generates.
|
|
13
|
+
- PostgreSQL for the generated app's database.
|
|
14
|
+
- Docker with Compose v2, only if you want the generated Docker setup. `natra new` runs `docker compose build --pull` as its last step. Without Docker that step prints an error, but the app is still generated and you can run it locally.
|
|
6
15
|
|
|
7
16
|
## Installation
|
|
8
17
|
|
|
9
|
-
|
|
18
|
+
```sh
|
|
19
|
+
gem install natra
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Quick start
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
natra new my-api
|
|
26
|
+
cd my-api
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Run with Docker
|
|
30
|
+
|
|
31
|
+
`secrets.env` holds the database settings for the `web` and `db` containers.
|
|
10
32
|
|
|
11
|
-
```
|
|
12
|
-
|
|
33
|
+
```sh
|
|
34
|
+
docker compose run --rm web bin/setup
|
|
35
|
+
docker compose up
|
|
13
36
|
```
|
|
14
37
|
|
|
15
|
-
|
|
38
|
+
### Run locally
|
|
16
39
|
|
|
17
|
-
|
|
40
|
+
Start PostgreSQL first. Without `DATABASE_URL`, `config/database.yml` uses the databases `development_my_api` and `test_my_api` (override them with `DEV_DATABASE` and `TEST_DATABASE`).
|
|
18
41
|
|
|
19
|
-
|
|
42
|
+
```sh
|
|
43
|
+
bundle install
|
|
44
|
+
bundle exec rake db:create db:migrate
|
|
45
|
+
bundle exec puma -C config/puma.rb
|
|
46
|
+
```
|
|
20
47
|
|
|
21
|
-
|
|
48
|
+
Either way the app listens on http://localhost:9292. Run its specs with `bundle exec rspec` after `RACK_ENV=test bundle exec rake db:create db:migrate`.
|
|
22
49
|
|
|
23
50
|
## Commands
|
|
51
|
+
|
|
52
|
+
| Command | What it does | Options |
|
|
53
|
+
| --- | --- | --- |
|
|
54
|
+
| `natra new APP_PATH` | Creates a new Sinatra application in `APP_PATH` | `--git` runs `git init` and `git add .`<br>`--bundle` runs `bundle install`<br>`--redis` adds the redis gem, `config/redis.yml` and a Redis initializer<br>`--capistrano` runs `cap install`<br>`--rvm` writes `.ruby-version` (the Ruby running natra) and `.ruby-gemset`, and skips `--bundle` |
|
|
55
|
+
| `natra model NAME [field:type ...]` | Generates a model and a migration that creates its table | `--no-migration` skips the migration |
|
|
56
|
+
| `natra controller NAME` | Generates a controller with routes, mounts it in `config.ru` and adds its views | `--no-views` skips the views |
|
|
57
|
+
| `natra scaffold NAME [field:type ...]` | Runs `model` and `controller` for `NAME` | |
|
|
58
|
+
| `natra service_object NAME` | Generates a service object in `app/services` | |
|
|
59
|
+
| `natra -v`, `natra --version` | Prints the natra version | |
|
|
60
|
+
| `natra help [COMMAND]` | Lists the commands, or describes one | |
|
|
61
|
+
|
|
62
|
+
Run `model`, `controller`, `scaffold` and `service_object` from the root of a generated app.
|
|
63
|
+
|
|
64
|
+
Naming rules:
|
|
65
|
+
|
|
66
|
+
- `APP_PATH` is lowercased, and characters other than letters, `-` and `_` are dropped. `natra new My-Blog` creates `my-blog`.
|
|
67
|
+
- Fields are written `name:type`, for example `title:string body:text published:boolean`. The type defaults to `string`, so `title` is the same as `title:string`.
|
|
68
|
+
- Models are singular (a plural name is singularized with a warning). Controllers and service objects are pluralized: `natra controller post` creates `PostsController`, and `natra service_object payment` creates `PaymentsService`.
|
|
69
|
+
|
|
70
|
+
## What you get
|
|
71
|
+
|
|
72
|
+
`natra new blog` creates:
|
|
73
|
+
|
|
24
74
|
```
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
75
|
+
blog/
|
|
76
|
+
├── .gitignore
|
|
77
|
+
├── .rspec
|
|
78
|
+
├── .rubocop.yml
|
|
79
|
+
├── Dockerfile
|
|
80
|
+
├── Gemfile
|
|
81
|
+
├── Guardfile
|
|
82
|
+
├── README.md
|
|
83
|
+
├── Rakefile
|
|
84
|
+
├── config.ru
|
|
85
|
+
├── docker-compose.yml
|
|
86
|
+
├── secrets.env
|
|
87
|
+
├── app/
|
|
88
|
+
│ ├── controllers/application_controller.rb
|
|
89
|
+
│ ├── models/
|
|
90
|
+
│ ├── services/
|
|
91
|
+
│ └── views/
|
|
92
|
+
│ ├── layout.erb
|
|
93
|
+
│ └── welcome.erb
|
|
94
|
+
├── bin/setup
|
|
95
|
+
├── config/
|
|
96
|
+
│ ├── database.yml
|
|
97
|
+
│ ├── environment.rb
|
|
98
|
+
│ ├── puma.rb
|
|
99
|
+
│ └── initializers/oj.rb
|
|
100
|
+
├── db/
|
|
101
|
+
│ ├── migrate/YYYYMMDD0000_add_extensions.rb
|
|
102
|
+
│ └── seeds.rb
|
|
103
|
+
├── lib/
|
|
104
|
+
├── public/favicon.ico
|
|
105
|
+
└── spec/
|
|
106
|
+
├── application_controller_spec.rb
|
|
107
|
+
├── spec_helper.rb
|
|
108
|
+
└── support/
|
|
31
109
|
```
|
|
32
|
-
The controller generator also have an optional views flag `--no-views` to create controllers without views.
|
|
33
110
|
|
|
34
|
-
|
|
111
|
+
The Gemfile uses Sinatra 4, ActiveRecord 8.1 through sinatra-activerecord, pg, Puma, Oj, rack-timeout and Scout APM, with RSpec, Capybara, FactoryBot, Faker, DatabaseCleaner, SimpleCov and Guard for tests. The first migration enables the `hstore`, `uuid-ossp` and `pgcrypto` PostgreSQL extensions. The Rakefile loads the sinatra-activerecord tasks, such as `db:create`, `db:migrate`, `db:seed` and `db:create_migration`.
|
|
35
112
|
|
|
36
|
-
|
|
113
|
+
`natra scaffold post title:string body:text` then creates:
|
|
37
114
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
115
|
+
```
|
|
116
|
+
app/models/post.rb # class Post < ActiveRecord::Base
|
|
117
|
+
db/migrate/YYYYMMDDHHMMSS_create_posts.rb # posts table with a UUID id, title, body and timestamps
|
|
118
|
+
app/controllers/posts_controller.rb # index, new, create, show, edit, update and delete routes
|
|
119
|
+
app/views/posts/index.html.erb
|
|
120
|
+
app/views/posts/new.html.erb
|
|
121
|
+
app/views/posts/show.html.erb
|
|
122
|
+
app/views/posts/edit.html.erb
|
|
123
|
+
```
|
|
41
124
|
|
|
42
|
-
|
|
43
|
-
bundle install
|
|
125
|
+
It also adds `use PostsController` to `config.ru`.
|
|
44
126
|
|
|
45
127
|
## Development
|
|
46
128
|
|
|
47
|
-
|
|
129
|
+
Natra is developed on Ruby 3.3.10 (see `.ruby-version`). CI runs on Ruby 3.3 and 3.4.
|
|
48
130
|
|
|
49
|
-
|
|
131
|
+
```sh
|
|
132
|
+
bin/setup # install dependencies
|
|
133
|
+
bundle exec rspec # run the specs
|
|
134
|
+
bundle exec rubocop # lint
|
|
135
|
+
bin/console # Pry session with natra loaded
|
|
136
|
+
```
|
|
50
137
|
|
|
51
|
-
|
|
138
|
+
SimpleCov measures line and branch coverage and writes a report to `coverage/`. CI requires 100% line and branch coverage. Run `CI=true bundle exec rspec` to apply the same check locally.
|
|
52
139
|
|
|
53
|
-
|
|
140
|
+
To release a new version:
|
|
54
141
|
|
|
55
|
-
|
|
142
|
+
1. Update the version number in `lib/natra/version.rb`.
|
|
143
|
+
2. Move the entries under "Unreleased" in [CHANGELOG.md](CHANGELOG.md) to a section for the new version.
|
|
144
|
+
3. Commit, then run `bundle exec rake release`. This builds the gem, tags the version, pushes the commit and tag, and pushes the gem to [rubygems.org](https://rubygems.org/gems/natra).
|
|
56
145
|
|
|
57
|
-
|
|
146
|
+
## Changelog
|
|
147
|
+
|
|
148
|
+
Notable changes are listed in [CHANGELOG.md](CHANGELOG.md).
|
|
149
|
+
|
|
150
|
+
## Contributing
|
|
151
|
+
|
|
152
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/jamesnjuguna0419/natra.
|
|
153
|
+
|
|
154
|
+
1. Open an issue first for larger changes, so the approach can be agreed before you write code.
|
|
155
|
+
2. Fork the repository and create a branch from `master`.
|
|
156
|
+
3. Make your change and add or update specs for it. If you change what a generator produces, update its spec under `spec/natra/generators/`.
|
|
157
|
+
4. Check that `CI=true bundle exec rspec` passes with 100% line and branch coverage, and that `bundle exec rubocop` reports no offenses.
|
|
158
|
+
5. Add a line to the "Unreleased" section of [CHANGELOG.md](CHANGELOG.md).
|
|
159
|
+
6. Open a pull request that explains what changed and why.
|
|
58
160
|
|
|
59
161
|
## Code of Conduct
|
|
60
162
|
|
|
61
|
-
Everyone interacting in the Natra project
|
|
163
|
+
This project is intended to be a safe, welcoming space for collaboration. Everyone interacting in the Natra project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [Code of Conduct](CODE_OF_CONDUCT.md), which is adapted from the [Contributor Covenant](https://www.contributor-covenant.org).
|
|
164
|
+
|
|
165
|
+
## License
|
|
166
|
+
|
|
167
|
+
The gem is available as open source under the terms of the [MIT License](LICENSE.txt).
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
data/bin/natra
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
$LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')))
|
|
5
|
+
require 'natra'
|
|
4
6
|
Natra::CLI.start
|
data/lib/extensions/string.rb
CHANGED
|
@@ -1,34 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Natra
|
|
2
4
|
module Extensions
|
|
5
|
+
# Naming helpers mixed into String for turning user input into Ruby names.
|
|
3
6
|
module String
|
|
4
7
|
def camel_case
|
|
5
|
-
return
|
|
6
|
-
|
|
8
|
+
return gsub(/^./, &:capitalize) unless match(/[_-]/)
|
|
9
|
+
|
|
10
|
+
altered_self = downcase.capitalize
|
|
7
11
|
altered_self.scan(/[_-][a-zA-Z]/).each { |match| altered_self.gsub!(match, match[1].upcase) }
|
|
8
12
|
altered_self
|
|
9
13
|
end
|
|
10
14
|
|
|
11
15
|
def camel_case!
|
|
12
|
-
|
|
16
|
+
replace camel_case
|
|
13
17
|
end
|
|
14
18
|
|
|
15
19
|
def directory_name
|
|
16
|
-
|
|
20
|
+
downcase.gsub(/[^a-z|_-]/, '')
|
|
17
21
|
end
|
|
18
22
|
|
|
19
23
|
def file_name
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
gsub(/[-| ]/, '_')
|
|
25
|
+
.gsub(/([A-Z]+|[A-Z][a-z])/) { |x| "_#{x}" }
|
|
26
|
+
.sub(/^_/, '')
|
|
27
|
+
.gsub(/_{2,}+/, '_')
|
|
28
|
+
.downcase
|
|
25
29
|
end
|
|
26
30
|
|
|
27
31
|
def file_name!
|
|
28
|
-
|
|
32
|
+
replace file_name
|
|
29
33
|
end
|
|
30
34
|
end
|
|
31
35
|
end
|
|
32
36
|
end
|
|
33
37
|
|
|
34
|
-
String.
|
|
38
|
+
String.include(Natra::Extensions::String)
|
data/lib/natra/cli.rb
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'thor'
|
|
2
4
|
module Natra
|
|
5
|
+
# Entry point for the natra executable: maps commands onto generators.
|
|
3
6
|
class CLI < Thor
|
|
4
7
|
desc '-v', 'Show Natra version number'
|
|
5
8
|
map %w[-v --version] => :version
|
|
@@ -11,9 +14,11 @@ module Natra
|
|
|
11
14
|
register Natra::Generators::AppGenerator, 'new', 'new APP_PATH', 'Creates a new Sinatra application'
|
|
12
15
|
register Natra::Generators::ModelGenerator, 'model', 'model NAME', 'Generate a model'
|
|
13
16
|
register Natra::Generators::ControllerGenerator, 'controller', 'controller NAME', 'Generate a controller'
|
|
14
|
-
register Natra::Generators::ScaffoldGenerator, 'scaffold', 'scaffold NAME',
|
|
17
|
+
register Natra::Generators::ScaffoldGenerator, 'scaffold', 'scaffold NAME',
|
|
18
|
+
'Generate a model with its associated views and controllers'
|
|
19
|
+
register Natra::Generators::ServiceGenerator, 'service_object', 'service_object NAME', 'Generate a service object'
|
|
15
20
|
|
|
16
|
-
def self.exit_on_failure
|
|
21
|
+
def self.exit_on_failure?
|
|
17
22
|
true
|
|
18
23
|
end
|
|
19
24
|
end
|
|
@@ -1,20 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'shellwords'
|
|
1
4
|
require 'thor/group'
|
|
2
5
|
module Natra
|
|
3
6
|
module Generators
|
|
7
|
+
# Generates a new Sinatra application skeleton (natra new).
|
|
4
8
|
class AppGenerator < Thor::Group
|
|
5
9
|
include Thor::Actions
|
|
10
|
+
|
|
6
11
|
desc 'Creates a new Sinatra application'
|
|
7
12
|
argument :name, type: :string, desc: 'The name of the new application'
|
|
8
13
|
class_option :capistrano, type: :boolean, desc: 'Include Capistrano configuration'
|
|
9
14
|
class_option :redis, type: :boolean, desc: 'Include Redis configuration'
|
|
10
|
-
class_option :rvm, type: :boolean, desc: 'Create .ruby-version (
|
|
15
|
+
class_option :rvm, type: :boolean, desc: 'Create .ruby-version (the Ruby running natra, 3.3+) and .ruby-gemset'
|
|
11
16
|
class_option :bundle, type: :boolean, desc: 'Run bundle after generating the app'
|
|
12
17
|
class_option :git, type: :boolean, desc: 'Initialize a Git repository'
|
|
13
18
|
|
|
14
19
|
def setup
|
|
15
20
|
@app_path = name.directory_name
|
|
16
21
|
@name = name.file_name
|
|
17
|
-
options.each { |key, value| instance_variable_set "@#{key}"
|
|
22
|
+
options.each { |key, value| instance_variable_set :"@#{key}", value }
|
|
18
23
|
end
|
|
19
24
|
|
|
20
25
|
def self.source_root
|
|
@@ -22,22 +27,24 @@ module Natra
|
|
|
22
27
|
end
|
|
23
28
|
|
|
24
29
|
def create_empty_directories
|
|
25
|
-
%w[config/initializers lib spec].each {|dir| empty_directory File.join(@app_path, dir)}
|
|
30
|
+
%w[config/initializers lib spec app/services].each { |dir| empty_directory File.join(@app_path, dir) }
|
|
26
31
|
empty_directory File.join(@app_path, 'db/migrate')
|
|
27
32
|
create_file File.join(@app_path, 'lib', '.keep')
|
|
28
33
|
template 'config/environment.rb', File.join(@app_path, 'config/environment.rb')
|
|
29
34
|
end
|
|
30
35
|
|
|
31
36
|
def create_seeds_file
|
|
32
|
-
create_file File.join(@app_path, 'db', 'seeds.rb')
|
|
37
|
+
create_file File.join(@app_path, 'db', 'seeds.rb'), "# Seed data, loaded by rake db:seed.\n"
|
|
33
38
|
end
|
|
34
39
|
|
|
35
40
|
def initialize_db
|
|
36
41
|
copy_file('bin/setup', File.join(@app_path, 'bin/setup'))
|
|
42
|
+
chmod(File.join(@app_path, 'bin/setup'), 0o755)
|
|
37
43
|
end
|
|
38
44
|
|
|
39
45
|
def uuid_setup
|
|
40
|
-
template 'db/migrate/add_extensions.rb',
|
|
46
|
+
template 'db/migrate/add_extensions.rb',
|
|
47
|
+
File.join(@app_path, "db/migrate/#{Time.now.strftime('%Y%m%d')}0000_add_extensions.rb")
|
|
41
48
|
end
|
|
42
49
|
|
|
43
50
|
def create_public_directory
|
|
@@ -45,7 +52,7 @@ module Natra
|
|
|
45
52
|
end
|
|
46
53
|
|
|
47
54
|
def create_app_directory
|
|
48
|
-
%w[app/controllers app/views app/models].each {|dir| directory dir, File.join(@app_path, dir)}
|
|
55
|
+
%w[app/controllers app/views app/models].each { |dir| directory dir, File.join(@app_path, dir) }
|
|
49
56
|
end
|
|
50
57
|
|
|
51
58
|
def create_app_spec
|
|
@@ -60,6 +67,14 @@ module Natra
|
|
|
60
67
|
template 'config.ru', File.join(@app_path, 'config.ru')
|
|
61
68
|
end
|
|
62
69
|
|
|
70
|
+
def create_puma_config
|
|
71
|
+
copy_file 'config/puma.rb', File.join(@app_path, 'config/puma.rb')
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def create_oj_initializer
|
|
75
|
+
copy_file 'config/initializers/oj.rb', File.join(@app_path, 'config/initializers/oj.rb')
|
|
76
|
+
end
|
|
77
|
+
|
|
63
78
|
def create_gemfile
|
|
64
79
|
template 'Gemfile', File.join(@app_path, 'Gemfile')
|
|
65
80
|
end
|
|
@@ -121,13 +136,13 @@ module Natra
|
|
|
121
136
|
end
|
|
122
137
|
|
|
123
138
|
def create_rvm_gemset
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
139
|
+
return unless @rvm
|
|
140
|
+
|
|
141
|
+
create_file(File.join(@app_path, '.ruby-version'), "ruby-#{RUBY_VERSION}")
|
|
142
|
+
create_file(File.join(@app_path, '.ruby-gemset'), @app_path)
|
|
127
143
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
end
|
|
144
|
+
@bundle = false
|
|
145
|
+
puts "You need to run 'bundle install' manually."
|
|
131
146
|
end
|
|
132
147
|
|
|
133
148
|
def initialize_git_repo
|
|
@@ -138,14 +153,12 @@ module Natra
|
|
|
138
153
|
inside(@app_path) { run('bundle') if @bundle }
|
|
139
154
|
end
|
|
140
155
|
|
|
156
|
+
# The Git repository, if any, was created by initialize_git_repo.
|
|
141
157
|
def initialize_app
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
git add .
|
|
147
|
-
docker-compose build --pull
|
|
148
|
-
SCRIPT
|
|
158
|
+
commands = ["cd #{Shellwords.escape(@app_path)}"]
|
|
159
|
+
commands << 'git add .' if @git
|
|
160
|
+
commands << 'docker compose build --pull'
|
|
161
|
+
system commands.join("\n")
|
|
149
162
|
end
|
|
150
163
|
end
|
|
151
164
|
end
|
|
@@ -1,13 +1,31 @@
|
|
|
1
|
-
FROM ruby AS base
|
|
1
|
+
FROM ruby:3.3-slim AS base
|
|
2
|
+
|
|
3
|
+
# build-essential compiles native gems (bcrypt, oj, puma); libpq-dev is needed by pg.
|
|
4
|
+
RUN apt-get update -qq \
|
|
5
|
+
&& apt-get install -y --no-install-recommends build-essential git libpq-dev libyaml-dev \
|
|
6
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
7
|
+
|
|
2
8
|
WORKDIR /usr/src/app
|
|
3
|
-
|
|
4
|
-
COPY Gemfile
|
|
9
|
+
|
|
10
|
+
COPY Gemfile Gemfile.lock* ./
|
|
11
|
+
|
|
5
12
|
FROM base AS development
|
|
6
|
-
|
|
7
|
-
|
|
13
|
+
|
|
14
|
+
RUN bundle install -j5
|
|
15
|
+
|
|
16
|
+
COPY . .
|
|
17
|
+
|
|
8
18
|
FROM base AS release
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
19
|
+
|
|
20
|
+
ENV RACK_ENV=production \
|
|
21
|
+
BUNDLE_WITHOUT=development:test
|
|
22
|
+
|
|
23
|
+
RUN bundle install -j5
|
|
24
|
+
|
|
25
|
+
COPY . .
|
|
26
|
+
|
|
27
|
+
RUN chmod 755 bin/setup
|
|
28
|
+
|
|
29
|
+
EXPOSE 9292
|
|
30
|
+
|
|
31
|
+
CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]
|
|
@@ -1,32 +1,38 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
gem '
|
|
7
|
-
gem '
|
|
8
|
-
gem '
|
|
9
|
-
gem '
|
|
10
|
-
gem '
|
|
11
|
-
gem '
|
|
12
|
-
gem '
|
|
13
|
-
|
|
14
|
-
gem '
|
|
15
|
-
|
|
16
|
-
gem '
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
source 'https://rubygems.org'
|
|
4
|
+
ruby '~> 3.3'
|
|
5
|
+
|
|
6
|
+
gem 'activerecord', '~> 8.1'
|
|
7
|
+
gem 'bcrypt', '~> 3.1'
|
|
8
|
+
gem 'oj', '~> 3.16'
|
|
9
|
+
gem 'pg', '~> 1.5'
|
|
10
|
+
gem 'puma', '>= 6.4'
|
|
11
|
+
gem 'rack-timeout', '~> 0.7'
|
|
12
|
+
gem 'rake', '~> 13.0'
|
|
13
|
+
<% if @redis -%>
|
|
14
|
+
gem 'redis', '~> 5.0'
|
|
15
|
+
<% end -%>
|
|
16
|
+
gem 'require_all', '~> 3.0'
|
|
17
|
+
gem 'scout_apm', '~> 6.0'
|
|
18
|
+
gem 'seed-fu', '~> 2.3'
|
|
19
|
+
gem 'sinatra', '~> 4.1'
|
|
20
|
+
gem 'sinatra-activerecord', '~> 2.0', require: 'sinatra/activerecord'
|
|
21
|
+
|
|
17
22
|
group :development, :test do
|
|
18
|
-
gem 'pry-byebug'
|
|
19
23
|
gem 'pry'
|
|
24
|
+
gem 'pry-byebug'
|
|
20
25
|
end
|
|
26
|
+
|
|
21
27
|
group :test do
|
|
22
|
-
gem '
|
|
28
|
+
gem 'amazing_print'
|
|
23
29
|
gem 'capybara'
|
|
24
|
-
gem 'database_cleaner'
|
|
30
|
+
gem 'database_cleaner-active_record'
|
|
25
31
|
gem 'factory_bot'
|
|
26
32
|
gem 'faker'
|
|
27
33
|
gem 'guard-rspec'
|
|
28
34
|
gem 'guard-rubocop'
|
|
29
|
-
gem 'simplecov'
|
|
30
35
|
gem 'rack-test'
|
|
31
36
|
gem 'rspec'
|
|
37
|
+
gem 'simplecov', require: false
|
|
32
38
|
end
|
|
@@ -1,52 +1,51 @@
|
|
|
1
1
|
# <%= @name %> service
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
```
|
|
5
|
-
natra -v # Show Natra version number
|
|
6
|
-
natra help [COMMAND] # Describe available commands or one specific command
|
|
7
|
-
natra new APP-NAME # Creates a new Sinatra application
|
|
8
|
-
natra model NAME # Generate a model
|
|
9
|
-
natra controller NAME # Generate a controller
|
|
10
|
-
natra scaffold NAME # Generate a model with its associated views and controllers
|
|
11
|
-
```
|
|
12
|
-
The controller generator also have an optional views flag `--no-views` to create controllers without views.
|
|
13
|
-
|
|
14
|
-
## Using Natra
|
|
3
|
+
A Sinatra JSON API with ActiveRecord and PostgreSQL, generated by [natra](https://github.com/jamesnjuguna0419/natra).
|
|
15
4
|
|
|
16
|
-
|
|
5
|
+
## Running with Docker
|
|
17
6
|
|
|
18
|
-
|
|
7
|
+
The database settings come from `secrets.env`.
|
|
19
8
|
|
|
20
|
-
|
|
9
|
+
```sh
|
|
10
|
+
docker compose build
|
|
11
|
+
docker compose run --rm web bin/setup
|
|
12
|
+
docker compose up
|
|
13
|
+
```
|
|
21
14
|
|
|
22
|
-
|
|
23
|
-
bundle install
|
|
15
|
+
The app listens on http://localhost:9292.
|
|
24
16
|
|
|
25
|
-
##
|
|
17
|
+
## Running locally
|
|
26
18
|
|
|
27
|
-
|
|
19
|
+
You need Ruby 3.3 and a running PostgreSQL server.
|
|
28
20
|
|
|
21
|
+
```sh
|
|
22
|
+
bundle install
|
|
23
|
+
bundle exec rake db:create db:migrate
|
|
24
|
+
bundle exec puma -C config/puma.rb
|
|
25
|
+
```
|
|
29
26
|
|
|
30
|
-
|
|
27
|
+
`config/database.yml` reads the database names from `DEV_DATABASE`, `TEST_DATABASE` and `PROD_DATABASE`, and falls back to `development_<%= @name.directory_name %>`, `test_<%= @name.directory_name %>` and `production_<%= @name.directory_name %>`. If `DATABASE_URL` is set, it is used instead.
|
|
31
28
|
|
|
32
|
-
|
|
29
|
+
## Tests
|
|
33
30
|
|
|
34
31
|
```sh
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
RACK_ENV=test bundle exec rake db:create db:migrate
|
|
33
|
+
bundle exec rspec
|
|
37
34
|
```
|
|
38
35
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
The app is configured to use [guard](https://github.com/guard/guard) facilitate running the tests as files change. To start up guard run:
|
|
36
|
+
To run the specs and RuboCop as files change:
|
|
42
37
|
|
|
43
38
|
```sh
|
|
44
|
-
|
|
39
|
+
bundle exec guard
|
|
45
40
|
```
|
|
46
41
|
|
|
47
|
-
|
|
42
|
+
## Generators
|
|
43
|
+
|
|
44
|
+
Run these from the app directory:
|
|
48
45
|
|
|
49
46
|
```sh
|
|
50
|
-
|
|
47
|
+
natra model NAME [field:type ...] # Generate a model and its migration
|
|
48
|
+
natra controller NAME # Generate a controller and its views
|
|
49
|
+
natra scaffold NAME [field:type ...] # Generate a model, controller and views
|
|
50
|
+
natra service_object NAME # Generate a service object in app/services
|
|
51
51
|
```
|
|
52
|
-
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
<h1>Welcome to the Sinatra Template!</h1>
|
|
1
2
|
<div class="sidebar">
|
|
2
3
|
<h3>Environment</h3>
|
|
3
4
|
<ul>
|
|
@@ -5,6 +6,6 @@
|
|
|
5
6
|
<li><b>Environment:</b> <%= ENV["RACK_ENV"] %></li>
|
|
6
7
|
<li><b>Server:</b> <%= @env["SERVER_SOFTWARE"] %></li>
|
|
7
8
|
<li><b>Port:</b> <%= @env["SERVER_PORT"] %></li>
|
|
8
|
-
<li><b>Help:</b>see the <a href="https://github.com/
|
|
9
|
+
<li><b>Help:</b> see the <a href="https://github.com/jamesnjuguna0419/natra">README</a></li>
|
|
9
10
|
</ul>
|
|
10
11
|
</div>
|