jksinatra 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 +9 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/README.md +38 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/devlog.md +556 -0
- data/exe/jksinatra +4 -0
- data/jksinatra.gemspec +36 -0
- data/lib/jksinatra.rb +25 -0
- data/lib/jksinatra/project.rb +28 -0
- data/lib/jksinatra/template.rb +19 -0
- data/lib/jksinatra/version.rb +3 -0
- data/lib/path.rb +10 -0
- data/templates/root/.gitignore.erb +1 -0
- data/templates/root/Gemfile.erb +13 -0
- data/templates/root/Rakefile.erb +7 -0
- data/templates/root/Readme.md.erb +1 -0
- data/templates/root/config.ru.erb +18 -0
- data/templates/root/config/mongoid.yml.erb +6 -0
- data/templates/root/controllers/application_controller.rb.erb +12 -0
- data/templates/root/controllers/protected_controller.rb.erb +13 -0
- data/templates/root/specs/ApplicationController_spec.rb.erb +18 -0
- metadata +153 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 42a9add13444a9c289c19d46fe1b4a1b224c98a8
|
4
|
+
data.tar.gz: 8c1a388b82ecc06c67992a903b622a96d12af9fb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 91239bbedb489457ba09ddc4201f7a68653f12a0c40240f7132fe083bfeda9c51d579119a6e067b747351d0a7ca1107fcfbfe2963bf7aab0236e9b5999845123
|
7
|
+
data.tar.gz: a05421f1b2bb685416f3205e0a80f929c1dbcef757edad0655b490fb95553515ebd1d01d6c32e2a1b37f85fd5d793782347c4c2c465557677241fa17dd835ad7
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# Jksinatra
|
2
|
+
|
3
|
+
![Travis Badges](https://travis-ci.org/JadeKharats/jksinatra.svg?branch=develop)
|
4
|
+
|
5
|
+
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/jksinatra`. To experiment with that code, run `bin/console` for an interactive prompt.
|
6
|
+
|
7
|
+
TODO: Delete this and the text above, and describe your gem
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
gem 'jksinatra'
|
15
|
+
```
|
16
|
+
|
17
|
+
And then execute:
|
18
|
+
|
19
|
+
$ bundle
|
20
|
+
|
21
|
+
Or install it yourself as:
|
22
|
+
|
23
|
+
$ gem install jksinatra
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
TODO: Write usage instructions here
|
28
|
+
|
29
|
+
## Development
|
30
|
+
|
31
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
32
|
+
|
33
|
+
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).
|
34
|
+
|
35
|
+
## Contributing
|
36
|
+
|
37
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/jksinatra.
|
38
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'jksinatra'
|
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
|
data/bin/setup
ADDED
data/devlog.md
ADDED
@@ -0,0 +1,556 @@
|
|
1
|
+
# Journal de dev
|
2
|
+
|
3
|
+
Voici mon journal de dev à propos de la contruction de la gem jksinatra.
|
4
|
+
Le but de cette gem est de fabriqué un projet sinatra en suivant mes habitudes de devs et en essayant de respecter, le plus possible, les bonnes pratique ruby, sinatra, web.
|
5
|
+
|
6
|
+
## Pourquoi cette gem?
|
7
|
+
|
8
|
+
En ce moment, je suis amené à faire des API de type micro-service. Pour ce faire, j'utilise sinatra à outrance. Mais certaines tâches et structures sont similaire d'un projet à l'autre. Plutot que de cloner sans cesse le même repos et d'y faire les modifs en fonction du stockage des données ou de l'authetification ou autre, je préfère faire cette gem pour générer mes projets.
|
9
|
+
|
10
|
+
## Comment je vais commencer?
|
11
|
+
|
12
|
+
Je vais :
|
13
|
+
* prendre un de mes projets
|
14
|
+
* créer le repertoire `templates` avec l'arborescence de ce projet
|
15
|
+
* remplir les templates avec le contenu le plus simple pour un fonctionnement de type `hello world`
|
16
|
+
* rendre paramétrable le fichier en fonction d'option saisie en entrée de la gem.
|
17
|
+
|
18
|
+
## Les templates
|
19
|
+
|
20
|
+
* Gemfile : l'indispensable à tout projet ruby.
|
21
|
+
* Rakefile : pour les tâches de tests.
|
22
|
+
* README.md : pour le repo git(lab/hub).
|
23
|
+
* .gitignore : pour une meilleure gestion de git.
|
24
|
+
* config.ru : Pour le mapping de l'application sinatra.
|
25
|
+
* config/mongoid.yml : dans le cas d'un persistence mongo.
|
26
|
+
* controllers/application_controller.rb : Controlleur pour factoriser les traitements des appels à l'application.
|
27
|
+
* controllers/protected_controller.rb : Controlleur pour ajouter une couche d'authentification.
|
28
|
+
* specs/ApplicationController_spec.rb : Tester le controlleur Application.
|
29
|
+
* models/ : Un repertoire pour stocker les sources des objets.
|
30
|
+
|
31
|
+
## Création du projet
|
32
|
+
|
33
|
+
J'ai utilisé `bundler` avec la commande `bundle gem jksinatra`. Cette commande crée la structure d'une gem avec le nécessaire pour heberger la gem sur un repos git, la construire en continu avec travis et la tester. Par contre, j'utilise rubocop pour avoir un code, à peu près, propre et je ne comprends pas pourquoi le code source généré cause autant d'`offense` dans rubocop.
|
34
|
+
|
35
|
+
Il y a quelques informations à renseigner dans le fichier `jksinatra.gemspec` avant de pouvoir construire la gem.
|
36
|
+
|
37
|
+
Je mets ici mon gemspec modifié pour ce projet :
|
38
|
+
```ruby
|
39
|
+
# coding: utf-8
|
40
|
+
lib = File.expand_path('../lib', __FILE__)
|
41
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
42
|
+
require 'jksinatra/version'
|
43
|
+
|
44
|
+
Gem::Specification.new do |spec|
|
45
|
+
spec.name = 'jksinatra'
|
46
|
+
spec.version = Jksinatra::VERSION
|
47
|
+
spec.authors = ['Jade D. Kharats']
|
48
|
+
spec.email = ['jade.kharats@gmail.com']
|
49
|
+
|
50
|
+
spec.summary = 'Sinatra template gem by Jade Kharats'
|
51
|
+
spec.description =
|
52
|
+
'This gem build a sinatra application with my usual template'
|
53
|
+
spec.homepage = 'https://github.com/JadeKharats/jksinatra'
|
54
|
+
|
55
|
+
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
|
56
|
+
# delete this section to allow pushing this gem to any host.
|
57
|
+
if spec.respond_to?(:metadata)
|
58
|
+
spec.metadata['allowed_push_host'] = 'http://rubygems.org'
|
59
|
+
else
|
60
|
+
fail 'RubyGems 2.0 or newer is required'
|
61
|
+
end
|
62
|
+
|
63
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
64
|
+
spec.bindir = 'exe'
|
65
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
66
|
+
spec.require_paths = ['lib']
|
67
|
+
|
68
|
+
spec.add_development_dependency 'bundler', '~> 1.10'
|
69
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
70
|
+
spec.add_development_dependency 'minitest'
|
71
|
+
end
|
72
|
+
```
|
73
|
+
|
74
|
+
Je mets aussi la liste des tâches disponibles à la création de la gem :
|
75
|
+
|
76
|
+
```shell
|
77
|
+
$ rake -T 1 ↵
|
78
|
+
rake build # Build jksinatra-0.1.0.gem into the pkg directory
|
79
|
+
rake clean # Remove any temporary products
|
80
|
+
rake clobber # Remove any generated files
|
81
|
+
rake install # Build and install jksinatra-0.1.0.gem into system gems
|
82
|
+
rake install:local # Build and install jksinatra-0.1.0.gem into system gems without network access
|
83
|
+
rake release[remote] # Create tag v0.1.0 and build and push jksinatra-0.1.0.gem to Rubygems
|
84
|
+
rake test # Run tests
|
85
|
+
```
|
86
|
+
|
87
|
+
Le but étant d'avoir une ligne de commande pour créer mes projets sinatra, j'ajoute le répertoire `exe` dans ce projet. Et j'y mets un fichier `jksinatra` contenant juste un `puts 'Hello World'`.
|
88
|
+
|
89
|
+
Je commit tout ça et le push sur mon github après avoir configurer travis.
|
90
|
+
|
91
|
+
En allant sur travis, j'ai un `build failed`. Mais c'est tout à fait normal. Comme écrit plus haut, la commande `bundle gem jksinatra` a créé un fichier de test. Dans ce fichier, il y a un test passant et un non passant. Pour ma part, je supprime le test non passant.
|
92
|
+
|
93
|
+
## Le code
|
94
|
+
|
95
|
+
Comme le but est de créer une gem accessible en ligne de commande, je vais utiliser une gem pratique pour ça : `Thor`.
|
96
|
+
|
97
|
+
### De quelle commande ai-je besoin pour créer mon projet?
|
98
|
+
|
99
|
+
On va commencer par le commande `new` pour créer le projet : `jksinatra new [projet]`.
|
100
|
+
|
101
|
+
Dans notre fichier `lib/jksinatra.rb`, on va ajouter notre première classe `CLI` et la méthode `new` comme suit :
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
# lib/jksinatra.rb
|
105
|
+
require 'jksinatra/version'
|
106
|
+
require 'thor'
|
107
|
+
|
108
|
+
# Main class
|
109
|
+
module Jksinatra
|
110
|
+
class CLI < Thor
|
111
|
+
|
112
|
+
desc 'new PROJECT', 'Create new sinatra project with PROJECT name'
|
113
|
+
def new(project)
|
114
|
+
puts "Create #{project}"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
```
|
119
|
+
|
120
|
+
Dans le fichier `exe/jksinatra`, on va charger le contenu de `lib` et appeler notre nouvel classe.
|
121
|
+
|
122
|
+
```ruby
|
123
|
+
# exe/jksinatra
|
124
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
125
|
+
require 'jksinatra'
|
126
|
+
|
127
|
+
Jksinatra::CLI.start(ARGV)
|
128
|
+
```
|
129
|
+
|
130
|
+
Testons notre premier bout de code. Dans le fichier `test\jksinatra_test.rb`, on ajoute la méthode suivante :
|
131
|
+
|
132
|
+
```ruby
|
133
|
+
# test\jksinatra_test.rb
|
134
|
+
require 'test_helper'
|
135
|
+
|
136
|
+
class JksinatraTest < Minitest::Test
|
137
|
+
def test_that_it_has_a_version_number
|
138
|
+
refute_nil ::Jksinatra::VERSION
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_cli_new_with_project_argument
|
142
|
+
args = ['new', 'pikachu']
|
143
|
+
out,err = capture_io do
|
144
|
+
Jksinatra::CLI.start(args)
|
145
|
+
end
|
146
|
+
assert_match %r%Create%, out
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_cli_new_without_argument
|
150
|
+
out,err = capture_io do
|
151
|
+
Jksinatra::CLI.start()
|
152
|
+
end
|
153
|
+
assert_match %r%Commands:%, out
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
157
|
+
```
|
158
|
+
|
159
|
+
### La première chose à créer est le repertoire projet.
|
160
|
+
|
161
|
+
Pour pouvoir test la création de repertoire sans bouffer votre filesystem, il existe un gem ruby de test qui se nomme `fakefs`. Je vais donc l'ajouter au fichier `gemspec` puis lancer la commande `bundle`
|
162
|
+
|
163
|
+
On ajoute ensuite `require 'fakefs'` au fichier `test/test_helper.rb`
|
164
|
+
|
165
|
+
Et enfin, on ecrit notre test.
|
166
|
+
|
167
|
+
```ruby
|
168
|
+
def test_cli_new__with_argument_create_project_folder
|
169
|
+
args = ['new', 'pikachu2']
|
170
|
+
out,err = capture_io do
|
171
|
+
Jksinatra::CLI.start(args)
|
172
|
+
end
|
173
|
+
assert File.directory?("pikachu2"), "pikachu2 folder doesn't exist"
|
174
|
+
end
|
175
|
+
|
176
|
+
def test_cli_new__with_argument_dont_create_exist_folder
|
177
|
+
Dir.mkdir 'pikachu3'
|
178
|
+
args = ['new', 'pikachu']
|
179
|
+
out,err = capture_io do
|
180
|
+
Jksinatra::CLI.start(args)
|
181
|
+
end
|
182
|
+
assert File.directory?("pikachu3"), "pikachu3 folder doesn't exist"
|
183
|
+
end
|
184
|
+
```
|
185
|
+
|
186
|
+
Le retour de la commande `rake` tombe bien en echec sur ce test.
|
187
|
+
|
188
|
+
```shell
|
189
|
+
$ rake 1 ↵
|
190
|
+
Run options: --seed 7386
|
191
|
+
|
192
|
+
# Running:
|
193
|
+
|
194
|
+
...F
|
195
|
+
|
196
|
+
Finished in 0.004513s, 886.3633 runs/s, 1329.5450 assertions/s.
|
197
|
+
|
198
|
+
1) Failure:
|
199
|
+
JksinatraTest#test_cli_new__with_argument_create_project_folder [/home/jade/Workspace/gems/jksinatra/test/jksinatra_test.rb:28]:
|
200
|
+
pikachu folder doesn't exist
|
201
|
+
|
202
|
+
4 runs, 6 assertions, 1 failures, 0 errors, 0 skips
|
203
|
+
```
|
204
|
+
|
205
|
+
Modifions la class pour passer ce test.
|
206
|
+
|
207
|
+
```ruby
|
208
|
+
# lib/jksinatra.rb
|
209
|
+
|
210
|
+
require 'jksinatra/version'
|
211
|
+
require 'thor'
|
212
|
+
|
213
|
+
# Main class
|
214
|
+
module Jksinatra
|
215
|
+
class CLI < Thor
|
216
|
+
|
217
|
+
desc 'new PROJECT', 'Create new sinatra project with PROJECT name'
|
218
|
+
def new(project)
|
219
|
+
if File.exists?(project)
|
220
|
+
message = "Folder #{project} already exist on filesystem"
|
221
|
+
else
|
222
|
+
Dir.mkdir(project)
|
223
|
+
puts "Create #{project}"
|
224
|
+
message = "Create #{project}"
|
225
|
+
end
|
226
|
+
puts message
|
227
|
+
return message
|
228
|
+
end
|
229
|
+
|
230
|
+
end
|
231
|
+
end
|
232
|
+
```
|
233
|
+
|
234
|
+
Et on relance le test
|
235
|
+
|
236
|
+
```shell
|
237
|
+
$ rake 1 ↵
|
238
|
+
Run options: --seed 23605
|
239
|
+
|
240
|
+
# Running:
|
241
|
+
|
242
|
+
.....
|
243
|
+
|
244
|
+
Finished in 0.004460s, 1121.1961 runs/s, 1569.6746 assertions/s.
|
245
|
+
|
246
|
+
5 runs, 7 assertions, 0 failures, 0 errors, 0 skips
|
247
|
+
```
|
248
|
+
|
249
|
+
Tout est ok!
|
250
|
+
|
251
|
+
|
252
|
+
### Un petit refactor
|
253
|
+
|
254
|
+
Soyons un peu plus logique. Le code source de la classe CLI est là pour définir et intercepter les commandes, pas pour créer le projet en lui même. Le code permettant de créer le dossier racine du projet et la suite de l'arborescence devrait être dans une classe spécifique.
|
255
|
+
|
256
|
+
Je rajoute donc le fichier `lib/jksinatra/project.rb`
|
257
|
+
|
258
|
+
```ruby
|
259
|
+
module Jksinatra
|
260
|
+
class Project
|
261
|
+
def render(project)
|
262
|
+
if File.exists?(project)
|
263
|
+
message = "Folder #{project} already exist on filesystem"
|
264
|
+
else
|
265
|
+
Dir.mkdir(project)
|
266
|
+
puts "Create #{project}"
|
267
|
+
message = "Create #{project}"
|
268
|
+
end
|
269
|
+
puts message
|
270
|
+
return message
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
```
|
275
|
+
|
276
|
+
Dans la classe CLI, je modifie le code pour faire appel à cette nouvelle classe.
|
277
|
+
|
278
|
+
```ruby
|
279
|
+
# lib/jksinatra.rb
|
280
|
+
require 'jksinatra/version'
|
281
|
+
require 'jksinatra/project'
|
282
|
+
require 'thor'
|
283
|
+
|
284
|
+
# Main class
|
285
|
+
module Jksinatra
|
286
|
+
class CLI < Thor
|
287
|
+
|
288
|
+
desc 'new PROJECT', 'Create new sinatra project with PROJECT name'
|
289
|
+
def new(project)
|
290
|
+
Project.new.render(project)
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
end
|
295
|
+
```
|
296
|
+
|
297
|
+
Après quelques tests, je me suis rendu compte que fakejs mettait du temps à supprimer son arboresence fictive. Je mets donc mes tests à jour avec des controles avant execution.
|
298
|
+
|
299
|
+
```ruby
|
300
|
+
# test/jksinatra_test.rb
|
301
|
+
require 'test_helper'
|
302
|
+
|
303
|
+
class JksinatraTest < Minitest::Test
|
304
|
+
def test_that_it_has_a_version_number
|
305
|
+
refute_nil ::Jksinatra::VERSION
|
306
|
+
end
|
307
|
+
|
308
|
+
def test_cli_new_with_project_argument
|
309
|
+
Dir.delete('pikachu') if File.exists?('pikachu')
|
310
|
+
args = ['new', 'pikachu']
|
311
|
+
out,err = capture_io do
|
312
|
+
Jksinatra::CLI.start(args)
|
313
|
+
end
|
314
|
+
assert_match %r%Create%, out
|
315
|
+
end
|
316
|
+
|
317
|
+
def test_cli_new_without_argument
|
318
|
+
out,err = capture_io do
|
319
|
+
Jksinatra::CLI.start()
|
320
|
+
end
|
321
|
+
assert_match %r%Commands:%, out
|
322
|
+
end
|
323
|
+
|
324
|
+
def test_cli_new__with_argument_create_project_folder
|
325
|
+
Dir.delete('pikachu') if File.exists?('pikachu')
|
326
|
+
args = ['new', 'pikachu']
|
327
|
+
out,err = capture_io do
|
328
|
+
Jksinatra::CLI.start(args)
|
329
|
+
end
|
330
|
+
assert File.directory?("pikachu"), "pikachu folder doesn't exist"
|
331
|
+
end
|
332
|
+
|
333
|
+
def test_cli_new__with_argument_dont_create_exist_folder
|
334
|
+
Dir.delete('pikachu') if File.exists?('pikachu')
|
335
|
+
Dir.mkdir 'pikachu'
|
336
|
+
args = ['new', 'pikachu']
|
337
|
+
out,err = capture_io do
|
338
|
+
Jksinatra::CLI.start(args)
|
339
|
+
end
|
340
|
+
assert File.directory?("pikachu"), "pikachu folder doesn't exist"
|
341
|
+
end
|
342
|
+
|
343
|
+
end
|
344
|
+
```
|
345
|
+
|
346
|
+
J'execute les tests pour voir si mes modifications n'ont rien cassé.
|
347
|
+
|
348
|
+
```shell
|
349
|
+
$ rake 1 ↵
|
350
|
+
Run options: --seed 63157
|
351
|
+
|
352
|
+
# Running:
|
353
|
+
|
354
|
+
.....
|
355
|
+
|
356
|
+
Finished in 0.006166s, 810.9261 runs/s, 1135.2965 assertions/s.
|
357
|
+
|
358
|
+
5 runs, 7 assertions, 0 failures, 0 errors, 0 skips
|
359
|
+
```
|
360
|
+
|
361
|
+
C'est bon, on a des bonnes bases pour attaquer la suite de l'arboresence
|
362
|
+
|
363
|
+
### Maintenant, nous allons créer l'arborescence du projet.
|
364
|
+
|
365
|
+
Pour créer les fichiers et les remplir, je vais utiliser ERB. C'est la librairie de templating ruby. Je vais aussi créer une classe par fichier à créer.
|
366
|
+
|
367
|
+
#### Commençons par le `Gemfile` et nos premiers paramètres jksinatra.
|
368
|
+
|
369
|
+
Voici le `Gemfile` que j'utilise pour mes projets :
|
370
|
+
```ruby
|
371
|
+
# templates/Gemfile.erb
|
372
|
+
source 'https://rubygems.org'
|
373
|
+
|
374
|
+
gem 'sinatra'
|
375
|
+
gem 'sinatra-contrib'
|
376
|
+
gem 'puma'
|
377
|
+
|
378
|
+
gem 'mongoid'
|
379
|
+
gem 'bcrypt'
|
380
|
+
|
381
|
+
group :test do
|
382
|
+
gem 'minitest'
|
383
|
+
gem 'cucumber'
|
384
|
+
end
|
385
|
+
```
|
386
|
+
|
387
|
+
La gem `sinatra` sera toujours présente, ainsi que minitest et cucumber. En revanche, on ajoutera :
|
388
|
+
* `sinatra-contrib` si l'option `--api` est saisie à la création.
|
389
|
+
* le serveur en fonction de l'option `--server` et puma par défaut.
|
390
|
+
* l'orm en fonction de l'option `--orm` et mongoid par défaut.
|
391
|
+
* `bcrypt` si l'option `--auth` est saisie à la création.
|
392
|
+
|
393
|
+
Dans le fonctionnement de la gem, on fait appel à Project.new.render(project) et c'est dans cette appel que l'on ajoutera la création des fichiers racine de l'application.
|
394
|
+
|
395
|
+
Ajoutons une nouvelle classe de test pour commencer.
|
396
|
+
|
397
|
+
```ruby
|
398
|
+
# test/gemfile_test.rb
|
399
|
+
require 'test_helper'
|
400
|
+
|
401
|
+
class GemfileTest < Minitest::Test
|
402
|
+
|
403
|
+
def test_if_file_exist_after_new_project
|
404
|
+
args = ['new', 'pikachu']
|
405
|
+
out,err = capture_io do
|
406
|
+
Jksinatra::CLI.start(args)
|
407
|
+
end
|
408
|
+
assert File.exists?('pikachu/Gemfile')
|
409
|
+
end
|
410
|
+
end
|
411
|
+
```
|
412
|
+
|
413
|
+
Le test est en échec, donc tout va bien.
|
414
|
+
|
415
|
+
Ajoutons la classe Gemfile.
|
416
|
+
```ruby
|
417
|
+
# lib/jksinatra/root/gemfile.rb
|
418
|
+
require 'erb'
|
419
|
+
module Jksinatra
|
420
|
+
class Gemfile
|
421
|
+
def render(project)
|
422
|
+
template_path = File.join Jksinatra.templates, 'root/Gemfile.erb'
|
423
|
+
template = File.read template_path
|
424
|
+
File.open("#{project}/Gemfile", 'a+') do |file|
|
425
|
+
file.puts ERB.new(template).result(binding)
|
426
|
+
end
|
427
|
+
end
|
428
|
+
end
|
429
|
+
end
|
430
|
+
```
|
431
|
+
|
432
|
+
Comme vous pouvez le voir, pour accèder au repertoire des templates, j'utilise une méthode de `Jksinatra` qui n'existe pas encore. En effet, pour un coté pratique, je vais ajouter un fichier avec des racourcis vers certains chemin du projet.
|
433
|
+
|
434
|
+
```ruby
|
435
|
+
# lib/path.rb
|
436
|
+
module Jksinatra
|
437
|
+
def self.root
|
438
|
+
File.dirname __dir__
|
439
|
+
end
|
440
|
+
|
441
|
+
def self.lib
|
442
|
+
File.join root, 'lib'
|
443
|
+
end
|
444
|
+
|
445
|
+
def self.templates
|
446
|
+
File.join root, 'templates'
|
447
|
+
end
|
448
|
+
end
|
449
|
+
```
|
450
|
+
|
451
|
+
Je vais également modifier les tests pour que chaque test supprime le repertoire projet avant et après execution.
|
452
|
+
|
453
|
+
```ruby
|
454
|
+
# test/jksinatra_test.rb
|
455
|
+
require 'test_helper'
|
456
|
+
|
457
|
+
class JksinatraTest < Minitest::Test
|
458
|
+
|
459
|
+
def setup
|
460
|
+
FileUtils.rm_rf('pikachu')
|
461
|
+
end
|
462
|
+
|
463
|
+
def teardown
|
464
|
+
FileUtils.rm_rf('pikachu')
|
465
|
+
end
|
466
|
+
|
467
|
+
def test_that_it_has_a_version_number
|
468
|
+
refute_nil ::Jksinatra::VERSION
|
469
|
+
end
|
470
|
+
|
471
|
+
def test_cli_new_with_project_argument
|
472
|
+
args = ['new', 'pikachu']
|
473
|
+
out,err = capture_io do
|
474
|
+
Jksinatra::CLI.start(args)
|
475
|
+
end
|
476
|
+
assert_match %r%Create%, out
|
477
|
+
end
|
478
|
+
|
479
|
+
def test_cli_new_without_argument
|
480
|
+
out,err = capture_io do
|
481
|
+
Jksinatra::CLI.start()
|
482
|
+
end
|
483
|
+
assert_match %r%Commands:%, out
|
484
|
+
end
|
485
|
+
|
486
|
+
def test_cli_new__with_argument_create_project_folder
|
487
|
+
args = ['new', 'pikachu']
|
488
|
+
out,err = capture_io do
|
489
|
+
Jksinatra::CLI.start(args)
|
490
|
+
end
|
491
|
+
assert File.directory?("pikachu"), "pikachu folder doesn't exist"
|
492
|
+
end
|
493
|
+
|
494
|
+
def test_cli_new__with_argument_dont_create_exist_folder
|
495
|
+
Dir.mkdir 'pikachu'
|
496
|
+
args = ['new', 'pikachu']
|
497
|
+
out,err = capture_io do
|
498
|
+
Jksinatra::CLI.start(args)
|
499
|
+
end
|
500
|
+
assert File.directory?("pikachu"), "pikachu folder doesn't exist"
|
501
|
+
end
|
502
|
+
|
503
|
+
def test_if_file_exist_after_new_project
|
504
|
+
args = ['new', 'pikachu']
|
505
|
+
out,err = capture_io do
|
506
|
+
Jksinatra::CLI.start(args)
|
507
|
+
end
|
508
|
+
assert File.exists?('pikachu/Gemfile')
|
509
|
+
end
|
510
|
+
|
511
|
+
end
|
512
|
+
```
|
513
|
+
|
514
|
+
Executons les tests :
|
515
|
+
```shell
|
516
|
+
$ rake 1 ↵
|
517
|
+
Run options: --seed 30962
|
518
|
+
|
519
|
+
# Running:
|
520
|
+
|
521
|
+
......
|
522
|
+
|
523
|
+
Finished in 0.005841s, 1027.2692 runs/s, 1369.6923 assertions/s.
|
524
|
+
|
525
|
+
6 runs, 8 assertions, 0 failures, 0 errors, 0 skips
|
526
|
+
```
|
527
|
+
|
528
|
+
Tout est revenu au vert.
|
529
|
+
|
530
|
+
Nous allons maintenant rendre parametrable ce fichier Gemfile. Pour cela, on va rajouter des options à notre méthode `new` de la classe `CLI`.
|
531
|
+
|
532
|
+
```ruby
|
533
|
+
# lib/jksinatra.rb
|
534
|
+
require 'jksinatra/version'
|
535
|
+
require 'jksinatra/project'
|
536
|
+
require 'jksinatra/root/gemfile'
|
537
|
+
require 'path'
|
538
|
+
require 'thor'
|
539
|
+
|
540
|
+
# Main class
|
541
|
+
module Jksinatra
|
542
|
+
class CLI < Thor
|
543
|
+
|
544
|
+
option :api, :type => :boolean
|
545
|
+
option :server
|
546
|
+
option :orm
|
547
|
+
option :auth, :type => :boolean
|
548
|
+
desc 'new PROJECT', 'Create new sinatra project with PROJECT name'
|
549
|
+
def new(project)
|
550
|
+
Project.new.render(project,options)
|
551
|
+
end
|
552
|
+
end
|
553
|
+
end
|
554
|
+
```
|
555
|
+
|
556
|
+
Vous noterez que l'on passe `options` à la méthode `render`, il faut donc penser à modifier la signature de la méthode en même temps.
|
data/exe/jksinatra
ADDED
data/jksinatra.gemspec
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'jksinatra/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'jksinatra'
|
8
|
+
spec.version = Jksinatra::VERSION
|
9
|
+
spec.authors = ['Jade D. Kharats']
|
10
|
+
spec.email = ['jade.kharats@gmail.com']
|
11
|
+
|
12
|
+
spec.summary = 'Sinatra template gem by Jade Kharats'
|
13
|
+
spec.description =
|
14
|
+
'This gem build a sinatra application with my usual template'
|
15
|
+
spec.homepage = 'https://github.com/JadeKharats/jksinatra'
|
16
|
+
|
17
|
+
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
|
18
|
+
# delete this section to allow pushing this gem to any host.
|
19
|
+
if spec.respond_to?(:metadata)
|
20
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
21
|
+
else
|
22
|
+
fail 'RubyGems 2.0 or newer is required'
|
23
|
+
end
|
24
|
+
|
25
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
26
|
+
spec.bindir = 'exe'
|
27
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
28
|
+
spec.require_paths = ['lib']
|
29
|
+
|
30
|
+
spec.add_development_dependency 'bundler', '~> 1.10'
|
31
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
32
|
+
spec.add_development_dependency 'minitest'
|
33
|
+
spec.add_development_dependency 'rubycritic'
|
34
|
+
spec.add_development_dependency 'coveralls'
|
35
|
+
spec.add_dependency 'thor'
|
36
|
+
end
|
data/lib/jksinatra.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'jksinatra/version'
|
2
|
+
require 'jksinatra/project'
|
3
|
+
require 'jksinatra/template'
|
4
|
+
require 'path'
|
5
|
+
require 'thor'
|
6
|
+
|
7
|
+
# Main class
|
8
|
+
module Jksinatra
|
9
|
+
# Class for CLI.
|
10
|
+
# methods : new
|
11
|
+
class CLI < Thor
|
12
|
+
option :api, type: :boolean
|
13
|
+
option :server
|
14
|
+
option :orm
|
15
|
+
option :auth, type: :boolean
|
16
|
+
desc 'new PROJECT', 'Create new sinatra project with PROJECT name'
|
17
|
+
def new(name)
|
18
|
+
puts Project
|
19
|
+
.new(
|
20
|
+
name,
|
21
|
+
options)
|
22
|
+
.generate
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Jksinatra
|
2
|
+
# Class for generate all folders
|
3
|
+
class Project
|
4
|
+
def initialize(name, options)
|
5
|
+
@name = name
|
6
|
+
@options = options
|
7
|
+
@folders = [
|
8
|
+
@name,
|
9
|
+
"#{@name}/config",
|
10
|
+
"#{@name}/controllers",
|
11
|
+
"#{@name}/specs"]
|
12
|
+
@templates_file_list = Dir['templates/root/**/*.erb']
|
13
|
+
end
|
14
|
+
|
15
|
+
def generate
|
16
|
+
if File.exist?(@name)
|
17
|
+
message = "Folder #{@name} already exist on filesystem"
|
18
|
+
else
|
19
|
+
@folders.each { |folder| Dir.mkdir folder }
|
20
|
+
@templates_file_list.each do |template|
|
21
|
+
Template.new(@name, @options, template[15..-1]).generate
|
22
|
+
end
|
23
|
+
message = "Create #{@name}"
|
24
|
+
end
|
25
|
+
message
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'erb'
|
2
|
+
module Jksinatra
|
3
|
+
# Class for generate file
|
4
|
+
class Template
|
5
|
+
def initialize(project_name, options, file_name)
|
6
|
+
@project_name = project_name
|
7
|
+
@options = options
|
8
|
+
@file_name = file_name
|
9
|
+
end
|
10
|
+
|
11
|
+
def generate
|
12
|
+
template_path = File.join Jksinatra.templates, "root/#{@file_name}"
|
13
|
+
template = File.read template_path
|
14
|
+
File.open("#{@project_name}/#{@file_name[0..-5]}", 'a+') do |file|
|
15
|
+
file.puts ERB.new(template).result(binding)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/path.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Gemfile.lock
|
@@ -0,0 +1,13 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'sinatra'
|
4
|
+
<%= "gem 'sinatra-contrib'" if @options[:api]%>
|
5
|
+
gem '<%= @options[:server] || "puma" %>'
|
6
|
+
|
7
|
+
gem '<%= @options[:orm] || 'mongoid'%>'
|
8
|
+
<%= "gem 'bcrypt'" if @options[:auth]%>
|
9
|
+
|
10
|
+
group :test do
|
11
|
+
gem 'minitest'
|
12
|
+
gem 'cucumber'
|
13
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
# Microservice
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'sinatra'
|
2
|
+
require 'securerandom'
|
3
|
+
require 'json'
|
4
|
+
require 'mongoid'
|
5
|
+
require 'bcrypt'
|
6
|
+
require 'securerandom'
|
7
|
+
|
8
|
+
|
9
|
+
require_relative 'controllers/application_controller'
|
10
|
+
|
11
|
+
Dir.glob('./{models,controllers}/*.rb').each { |file| require file }
|
12
|
+
|
13
|
+
Mongoid.load!("config/mongoid.yml")
|
14
|
+
|
15
|
+
# map here routes and controllers
|
16
|
+
# example map('/users') {run UserController}
|
17
|
+
map('/') {run ApplicationController}
|
18
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
<%= "require 'sinatra/json'" if @options[:api]%>
|
3
|
+
|
4
|
+
class ApplicationController < Sinatra::Base
|
5
|
+
|
6
|
+
routes_missing = lambda do
|
7
|
+
<%= "json :response =>" if @options[:api]%> "Cette route n'existe pas"
|
8
|
+
end
|
9
|
+
|
10
|
+
get '*', &routes_missing
|
11
|
+
|
12
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class ProtectedController < ApplicationController
|
2
|
+
|
3
|
+
<% if @options[:auth]%>
|
4
|
+
before do
|
5
|
+
halt 403 unless User.where(api_token: env['HTTP_AUTHORIZATION']).first
|
6
|
+
end
|
7
|
+
<% else %>
|
8
|
+
# add here your authentification condition, example :
|
9
|
+
# before do
|
10
|
+
# halt 403 unless User.where(api_token: env['HTTP_AUTHORIZATION']).first
|
11
|
+
# end
|
12
|
+
<% end %>
|
13
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.expand_path '../../controllers/application_controller.rb', __FILE__
|
2
|
+
|
3
|
+
ENV['RACK_ENV'] = 'test'
|
4
|
+
require 'minitest/autorun'
|
5
|
+
require 'rack/test'
|
6
|
+
|
7
|
+
include Rack::Test::Methods
|
8
|
+
|
9
|
+
def app
|
10
|
+
ApplicationController
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "call a missing route" do
|
14
|
+
it "should return a message about routes missing" do
|
15
|
+
get '/'
|
16
|
+
last_response.body.must_include "Cette route n'existe pas"
|
17
|
+
end
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jksinatra
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jade D. Kharats
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-01-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.10'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.10'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubycritic
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: coveralls
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: thor
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: This gem build a sinatra application with my usual template
|
98
|
+
email:
|
99
|
+
- jade.kharats@gmail.com
|
100
|
+
executables:
|
101
|
+
- jksinatra
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- ".gitignore"
|
106
|
+
- ".travis.yml"
|
107
|
+
- Gemfile
|
108
|
+
- README.md
|
109
|
+
- Rakefile
|
110
|
+
- bin/console
|
111
|
+
- bin/setup
|
112
|
+
- devlog.md
|
113
|
+
- exe/jksinatra
|
114
|
+
- jksinatra.gemspec
|
115
|
+
- lib/jksinatra.rb
|
116
|
+
- lib/jksinatra/project.rb
|
117
|
+
- lib/jksinatra/template.rb
|
118
|
+
- lib/jksinatra/version.rb
|
119
|
+
- lib/path.rb
|
120
|
+
- templates/root/.gitignore.erb
|
121
|
+
- templates/root/Gemfile.erb
|
122
|
+
- templates/root/Rakefile.erb
|
123
|
+
- templates/root/Readme.md.erb
|
124
|
+
- templates/root/config.ru.erb
|
125
|
+
- templates/root/config/mongoid.yml.erb
|
126
|
+
- templates/root/controllers/application_controller.rb.erb
|
127
|
+
- templates/root/controllers/protected_controller.rb.erb
|
128
|
+
- templates/root/specs/ApplicationController_spec.rb.erb
|
129
|
+
homepage: https://github.com/JadeKharats/jksinatra
|
130
|
+
licenses: []
|
131
|
+
metadata:
|
132
|
+
allowed_push_host: https://rubygems.org
|
133
|
+
post_install_message:
|
134
|
+
rdoc_options: []
|
135
|
+
require_paths:
|
136
|
+
- lib
|
137
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
138
|
+
requirements:
|
139
|
+
- - ">="
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
requirements: []
|
148
|
+
rubyforge_project:
|
149
|
+
rubygems_version: 2.4.8
|
150
|
+
signing_key:
|
151
|
+
specification_version: 4
|
152
|
+
summary: Sinatra template gem by Jade Kharats
|
153
|
+
test_files: []
|