mobile_workflow_cli 0.1.0 → 0.1.6
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/Gemfile.lock +71 -71
- data/README.md +8 -5
- data/bin/mwf +6 -1
- data/bin/mwf-delete +24 -0
- data/lib/mobile_workflow_cli.rb +5 -0
- data/lib/mobile_workflow_cli/app_builder.rb +75 -5
- data/lib/mobile_workflow_cli/app_cleaner.rb +24 -0
- data/lib/mobile_workflow_cli/app_generator.rb +47 -97
- data/lib/mobile_workflow_cli/aws_backend.rb +57 -0
- data/lib/mobile_workflow_cli/dokku_backend.rb +55 -0
- data/lib/mobile_workflow_cli/heroku_backend.rb +45 -0
- data/lib/mobile_workflow_cli/version.rb +1 -1
- data/mobile_workflow_cli.gemspec +2 -0
- data/templates/Gemfile.erb +47 -0
- data/templates/Procfile +2 -0
- data/templates/Procfile.dev +1 -0
- data/templates/ability.rb +7 -0
- data/templates/storage.s3.yml +14 -0
- metadata +14 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4981fe507e2bcc740e26bfc7667f0c2a308605f20ea39113fcc7694716049258
|
4
|
+
data.tar.gz: 73166990d43c3245b37f006b444df724f53f6348ae1b4912a64f39f0126bd663
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 25cc9ff4a539f6a4b15ca285c989265c433bb8ea31485c7f34d29eaae1aaf6ba0eb3a6025ee3483d0b4cda377a7c99b42289bc984aef0f8c96b22f8ecaf5234f
|
7
|
+
data.tar.gz: 02512a878c496d452fcc922aae23c0db0466619a2eaafe1b620073bf1f52c4e538f6b50971088a7f24122fbb79bc54ca5d48e7e4c54307e49bce091a25a12f41
|
data/Gemfile.lock
CHANGED
@@ -1,63 +1,63 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
mobile_workflow_cli (0.1.
|
4
|
+
mobile_workflow_cli (0.1.6)
|
5
5
|
administrate
|
6
6
|
rails (>= 6.0.0)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
-
actioncable (6.0.3)
|
12
|
-
actionpack (= 6.0.3)
|
11
|
+
actioncable (6.0.3.2)
|
12
|
+
actionpack (= 6.0.3.2)
|
13
13
|
nio4r (~> 2.0)
|
14
14
|
websocket-driver (>= 0.6.1)
|
15
|
-
actionmailbox (6.0.3)
|
16
|
-
actionpack (= 6.0.3)
|
17
|
-
activejob (= 6.0.3)
|
18
|
-
activerecord (= 6.0.3)
|
19
|
-
activestorage (= 6.0.3)
|
20
|
-
activesupport (= 6.0.3)
|
15
|
+
actionmailbox (6.0.3.2)
|
16
|
+
actionpack (= 6.0.3.2)
|
17
|
+
activejob (= 6.0.3.2)
|
18
|
+
activerecord (= 6.0.3.2)
|
19
|
+
activestorage (= 6.0.3.2)
|
20
|
+
activesupport (= 6.0.3.2)
|
21
21
|
mail (>= 2.7.1)
|
22
|
-
actionmailer (6.0.3)
|
23
|
-
actionpack (= 6.0.3)
|
24
|
-
actionview (= 6.0.3)
|
25
|
-
activejob (= 6.0.3)
|
22
|
+
actionmailer (6.0.3.2)
|
23
|
+
actionpack (= 6.0.3.2)
|
24
|
+
actionview (= 6.0.3.2)
|
25
|
+
activejob (= 6.0.3.2)
|
26
26
|
mail (~> 2.5, >= 2.5.4)
|
27
27
|
rails-dom-testing (~> 2.0)
|
28
|
-
actionpack (6.0.3)
|
29
|
-
actionview (= 6.0.3)
|
30
|
-
activesupport (= 6.0.3)
|
28
|
+
actionpack (6.0.3.2)
|
29
|
+
actionview (= 6.0.3.2)
|
30
|
+
activesupport (= 6.0.3.2)
|
31
31
|
rack (~> 2.0, >= 2.0.8)
|
32
32
|
rack-test (>= 0.6.3)
|
33
33
|
rails-dom-testing (~> 2.0)
|
34
34
|
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
35
|
-
actiontext (6.0.3)
|
36
|
-
actionpack (= 6.0.3)
|
37
|
-
activerecord (= 6.0.3)
|
38
|
-
activestorage (= 6.0.3)
|
39
|
-
activesupport (= 6.0.3)
|
35
|
+
actiontext (6.0.3.2)
|
36
|
+
actionpack (= 6.0.3.2)
|
37
|
+
activerecord (= 6.0.3.2)
|
38
|
+
activestorage (= 6.0.3.2)
|
39
|
+
activesupport (= 6.0.3.2)
|
40
40
|
nokogiri (>= 1.8.5)
|
41
|
-
actionview (6.0.3)
|
42
|
-
activesupport (= 6.0.3)
|
41
|
+
actionview (6.0.3.2)
|
42
|
+
activesupport (= 6.0.3.2)
|
43
43
|
builder (~> 3.1)
|
44
44
|
erubi (~> 1.4)
|
45
45
|
rails-dom-testing (~> 2.0)
|
46
46
|
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
47
|
-
activejob (6.0.3)
|
48
|
-
activesupport (= 6.0.3)
|
47
|
+
activejob (6.0.3.2)
|
48
|
+
activesupport (= 6.0.3.2)
|
49
49
|
globalid (>= 0.3.6)
|
50
|
-
activemodel (6.0.3)
|
51
|
-
activesupport (= 6.0.3)
|
52
|
-
activerecord (6.0.3)
|
53
|
-
activemodel (= 6.0.3)
|
54
|
-
activesupport (= 6.0.3)
|
55
|
-
activestorage (6.0.3)
|
56
|
-
actionpack (= 6.0.3)
|
57
|
-
activejob (= 6.0.3)
|
58
|
-
activerecord (= 6.0.3)
|
50
|
+
activemodel (6.0.3.2)
|
51
|
+
activesupport (= 6.0.3.2)
|
52
|
+
activerecord (6.0.3.2)
|
53
|
+
activemodel (= 6.0.3.2)
|
54
|
+
activesupport (= 6.0.3.2)
|
55
|
+
activestorage (6.0.3.2)
|
56
|
+
actionpack (= 6.0.3.2)
|
57
|
+
activejob (= 6.0.3.2)
|
58
|
+
activerecord (= 6.0.3.2)
|
59
59
|
marcel (~> 0.3.1)
|
60
|
-
activesupport (6.0.3)
|
60
|
+
activesupport (6.0.3.2)
|
61
61
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
62
62
|
i18n (>= 0.7, < 2)
|
63
63
|
minitest (~> 5.1)
|
@@ -74,7 +74,7 @@ GEM
|
|
74
74
|
momentjs-rails (~> 2.8)
|
75
75
|
sassc-rails (~> 2.1)
|
76
76
|
selectize-rails (~> 0.6)
|
77
|
-
autoprefixer-rails (9.
|
77
|
+
autoprefixer-rails (9.8.4)
|
78
78
|
execjs
|
79
79
|
builder (3.2.4)
|
80
80
|
byebug (11.1.3)
|
@@ -85,28 +85,28 @@ GEM
|
|
85
85
|
diff-lcs (1.3)
|
86
86
|
erubi (1.9.0)
|
87
87
|
execjs (2.7.0)
|
88
|
-
ffi (1.
|
88
|
+
ffi (1.13.1)
|
89
89
|
globalid (0.4.2)
|
90
90
|
activesupport (>= 4.2.0)
|
91
|
-
i18n (1.8.
|
91
|
+
i18n (1.8.3)
|
92
92
|
concurrent-ruby (~> 1.0)
|
93
93
|
jquery-rails (4.4.0)
|
94
94
|
rails-dom-testing (>= 1, < 3)
|
95
95
|
railties (>= 4.2.0)
|
96
96
|
thor (>= 0.14, < 2.0)
|
97
|
-
kaminari (1.2.
|
97
|
+
kaminari (1.2.1)
|
98
98
|
activesupport (>= 4.1.0)
|
99
|
-
kaminari-actionview (= 1.2.
|
100
|
-
kaminari-activerecord (= 1.2.
|
101
|
-
kaminari-core (= 1.2.
|
102
|
-
kaminari-actionview (1.2.
|
99
|
+
kaminari-actionview (= 1.2.1)
|
100
|
+
kaminari-activerecord (= 1.2.1)
|
101
|
+
kaminari-core (= 1.2.1)
|
102
|
+
kaminari-actionview (1.2.1)
|
103
103
|
actionview
|
104
|
-
kaminari-core (= 1.2.
|
105
|
-
kaminari-activerecord (1.2.
|
104
|
+
kaminari-core (= 1.2.1)
|
105
|
+
kaminari-activerecord (1.2.1)
|
106
106
|
activerecord
|
107
|
-
kaminari-core (= 1.2.
|
108
|
-
kaminari-core (1.2.
|
109
|
-
loofah (2.
|
107
|
+
kaminari-core (= 1.2.1)
|
108
|
+
kaminari-core (1.2.1)
|
109
|
+
loofah (2.6.0)
|
110
110
|
crass (~> 1.0.2)
|
111
111
|
nokogiri (>= 1.5.9)
|
112
112
|
mail (2.7.1)
|
@@ -117,38 +117,38 @@ GEM
|
|
117
117
|
mimemagic (0.3.5)
|
118
118
|
mini_mime (1.0.2)
|
119
119
|
mini_portile2 (2.4.0)
|
120
|
-
minitest (5.14.
|
120
|
+
minitest (5.14.1)
|
121
121
|
momentjs-rails (2.20.1)
|
122
122
|
railties (>= 3.1)
|
123
123
|
nio4r (2.5.2)
|
124
124
|
nokogiri (1.10.9)
|
125
125
|
mini_portile2 (~> 2.4.0)
|
126
|
-
rack (2.2.
|
126
|
+
rack (2.2.3)
|
127
127
|
rack-test (1.1.0)
|
128
128
|
rack (>= 1.0, < 3)
|
129
|
-
rails (6.0.3)
|
130
|
-
actioncable (= 6.0.3)
|
131
|
-
actionmailbox (= 6.0.3)
|
132
|
-
actionmailer (= 6.0.3)
|
133
|
-
actionpack (= 6.0.3)
|
134
|
-
actiontext (= 6.0.3)
|
135
|
-
actionview (= 6.0.3)
|
136
|
-
activejob (= 6.0.3)
|
137
|
-
activemodel (= 6.0.3)
|
138
|
-
activerecord (= 6.0.3)
|
139
|
-
activestorage (= 6.0.3)
|
140
|
-
activesupport (= 6.0.3)
|
129
|
+
rails (6.0.3.2)
|
130
|
+
actioncable (= 6.0.3.2)
|
131
|
+
actionmailbox (= 6.0.3.2)
|
132
|
+
actionmailer (= 6.0.3.2)
|
133
|
+
actionpack (= 6.0.3.2)
|
134
|
+
actiontext (= 6.0.3.2)
|
135
|
+
actionview (= 6.0.3.2)
|
136
|
+
activejob (= 6.0.3.2)
|
137
|
+
activemodel (= 6.0.3.2)
|
138
|
+
activerecord (= 6.0.3.2)
|
139
|
+
activestorage (= 6.0.3.2)
|
140
|
+
activesupport (= 6.0.3.2)
|
141
141
|
bundler (>= 1.3.0)
|
142
|
-
railties (= 6.0.3)
|
142
|
+
railties (= 6.0.3.2)
|
143
143
|
sprockets-rails (>= 2.0.0)
|
144
144
|
rails-dom-testing (2.0.3)
|
145
145
|
activesupport (>= 4.2.0)
|
146
146
|
nokogiri (>= 1.6)
|
147
147
|
rails-html-sanitizer (1.3.0)
|
148
148
|
loofah (~> 2.3)
|
149
|
-
railties (6.0.3)
|
150
|
-
actionpack (= 6.0.3)
|
151
|
-
activesupport (= 6.0.3)
|
149
|
+
railties (6.0.3.2)
|
150
|
+
actionpack (= 6.0.3.2)
|
151
|
+
activesupport (= 6.0.3.2)
|
152
152
|
method_source
|
153
153
|
rake (>= 0.8.7)
|
154
154
|
thor (>= 0.20.3, < 2.0)
|
@@ -166,7 +166,7 @@ GEM
|
|
166
166
|
diff-lcs (>= 1.2.0, < 2.0)
|
167
167
|
rspec-support (~> 3.9.0)
|
168
168
|
rspec-support (3.9.3)
|
169
|
-
sassc (2.
|
169
|
+
sassc (2.4.0)
|
170
170
|
ffi (~> 1.9)
|
171
171
|
sassc-rails (2.1.2)
|
172
172
|
railties (>= 4.0.0)
|
@@ -175,7 +175,7 @@ GEM
|
|
175
175
|
sprockets-rails
|
176
176
|
tilt
|
177
177
|
selectize-rails (0.12.6)
|
178
|
-
sprockets (4.0.
|
178
|
+
sprockets (4.0.2)
|
179
179
|
concurrent-ruby (~> 1.0)
|
180
180
|
rack (> 1, < 3)
|
181
181
|
sprockets-rails (3.2.1)
|
@@ -187,10 +187,10 @@ GEM
|
|
187
187
|
tilt (2.0.10)
|
188
188
|
tzinfo (1.2.7)
|
189
189
|
thread_safe (~> 0.1)
|
190
|
-
websocket-driver (0.7.
|
190
|
+
websocket-driver (0.7.2)
|
191
191
|
websocket-extensions (>= 0.1.0)
|
192
|
-
websocket-extensions (0.1.
|
193
|
-
zeitwerk (2.3.
|
192
|
+
websocket-extensions (0.1.5)
|
193
|
+
zeitwerk (2.3.1)
|
194
194
|
|
195
195
|
PLATFORMS
|
196
196
|
ruby
|
data/README.md
CHANGED
@@ -6,18 +6,21 @@ The server contains
|
|
6
6
|
* API
|
7
7
|
* Password protected admin console (for updating the data)
|
8
8
|
|
9
|
+
## Prereqs
|
10
|
+
|
11
|
+
Install RubyVersionManager (RVM) with latest stable Ruby and Rails
|
12
|
+
|
13
|
+
`\curl -sSL https://get.rvm.io | bash -s stable --rails`
|
14
|
+
|
9
15
|
## Installation
|
10
16
|
|
11
17
|
Install the utility
|
12
18
|
|
13
|
-
|
14
|
-
gem 'mobile_workflow_cli'
|
15
|
-
```
|
19
|
+
`gem 'mobile_workflow_cli'`
|
16
20
|
|
17
21
|
## Usage
|
18
22
|
|
19
|
-
|
20
|
-
|
23
|
+
`mwf --help`
|
21
24
|
|
22
25
|
## License
|
23
26
|
|
data/bin/mwf
CHANGED
data/bin/mwf-delete
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
# Byebug for dev
|
5
|
+
begin
|
6
|
+
require 'byebug'
|
7
|
+
rescue LoadError
|
8
|
+
end
|
9
|
+
|
10
|
+
source_path = (Pathname.new(__FILE__).dirname + '../lib').expand_path
|
11
|
+
$LOAD_PATH << source_path
|
12
|
+
|
13
|
+
require 'mobile_workflow_cli'
|
14
|
+
|
15
|
+
if ARGV.empty?
|
16
|
+
puts "USAGE: mwf-delete <directory>"
|
17
|
+
puts "See --help for more info"
|
18
|
+
exit 0
|
19
|
+
elsif ['-v', '--version'].include? ARGV[0]
|
20
|
+
puts MobileWorkflowCli::VERSION
|
21
|
+
exit 0
|
22
|
+
end
|
23
|
+
|
24
|
+
MobileWorkflowCli::AppCleaner.start
|
data/lib/mobile_workflow_cli.rb
CHANGED
@@ -2,6 +2,11 @@ require "mobile_workflow_cli/version"
|
|
2
2
|
|
3
3
|
require "mobile_workflow_cli/app_generator"
|
4
4
|
require "mobile_workflow_cli/app_builder"
|
5
|
+
require "mobile_workflow_cli/app_cleaner"
|
6
|
+
|
7
|
+
require "mobile_workflow_cli/aws_backend"
|
8
|
+
require "mobile_workflow_cli/heroku_backend"
|
9
|
+
require "mobile_workflow_cli/dokku_backend"
|
5
10
|
|
6
11
|
module MobileWorkflowCli
|
7
12
|
class Error < StandardError; end
|
@@ -5,12 +5,82 @@ module MobileWorkflowCli
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def gemfile
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
template 'Gemfile.erb', 'Gemfile'
|
9
|
+
end
|
10
|
+
|
11
|
+
def procfiles
|
12
|
+
copy_file 'Procfile', 'Procfile'
|
13
|
+
copy_file 'Procfile.dev', 'Procfile.dev'
|
14
|
+
end
|
15
|
+
|
16
|
+
def rspec_generator
|
17
|
+
generate 'rspec:install'
|
18
|
+
end
|
19
|
+
|
20
|
+
def ability_generator
|
21
|
+
copy_file 'ability.rb', 'app/models/ability.rb'
|
22
|
+
end
|
23
|
+
|
24
|
+
def active_storage
|
25
|
+
rails_command 'active_storage:install'
|
26
|
+
copy_file 'storage.s3.yml', 'config/storage.yml'
|
27
|
+
gsub_file 'config/environments/production.rb', 'config.active_storage.service = :local', 'config.active_storage.service = :amazon'
|
28
|
+
end
|
29
|
+
|
30
|
+
def mobile_workflow_generator(open_api_spec_path)
|
31
|
+
copy_file open_api_spec_path, 'config/open_api_spec.json'
|
32
|
+
generate 'mobile_workflow:install'
|
33
|
+
end
|
34
|
+
|
35
|
+
def s3_backend(region)
|
36
|
+
@region = region
|
37
|
+
aws_backend.create
|
38
|
+
say "AWS Access ID: #{aws_backend.access_id}"
|
39
|
+
say "AWS Secret Key: #{aws_backend.secret_key}"
|
11
40
|
|
12
|
-
|
13
|
-
|
41
|
+
open('.env', 'a') { |f|
|
42
|
+
f.puts "AWS_ACCESS_ID=#{aws_backend.access_id}"
|
43
|
+
f.puts "AWS_SECRET_KEY=#{aws_backend.secret_key}"
|
44
|
+
f.puts "AWS_REGION=#{aws_backend.region}"
|
45
|
+
f.puts "AWS_BUCKET_NAME=#{aws_backend.bucket_name}"
|
46
|
+
}
|
47
|
+
|
48
|
+
if options[:heroku]
|
49
|
+
heroku_backend.sync_dotenv
|
50
|
+
aws_backend.create_topic_subscription(heroku_backend.notifications_endpoint)
|
51
|
+
elsif options[:dokku]
|
52
|
+
dokku_backend.sync_dotenv
|
53
|
+
aws_backend.create_topic_subscription(dokku_backend.notifications_endpoint)
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
def heroku
|
59
|
+
heroku_backend.create
|
60
|
+
heroku_backend.configure_activestorage if options[:s3_storage]
|
61
|
+
heroku_backend.deploy
|
62
|
+
heroku_backend.sync_dotenv
|
63
|
+
end
|
64
|
+
|
65
|
+
def dokku(dokku_host)
|
66
|
+
@dokku_host = dokku_host
|
67
|
+
dokku_backend.create
|
68
|
+
dokku_backend.configure_activestorage if options[:s3_storage]
|
69
|
+
dokku_backend.deploy
|
70
|
+
dokku_backend.sync_dotenv
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
def aws_backend
|
75
|
+
@aws_backend ||= AwsBackend.new(app_name: app_name, region: @region)
|
76
|
+
end
|
77
|
+
|
78
|
+
def dokku_backend
|
79
|
+
@dokku_backend ||= DokkuBackend.new(app_name: app_name, dokku_host: @dokku_host)
|
80
|
+
end
|
81
|
+
|
82
|
+
def heroku_backend
|
83
|
+
@heroku_backend ||= HerokuBackend.new(app_name: app_name)
|
14
84
|
end
|
15
85
|
end
|
16
86
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'rails/generators/rails/app/app_generator'
|
3
|
+
require 'json'
|
4
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
5
|
+
|
6
|
+
module MobileWorkflowCli
|
7
|
+
class AppCleaner < Thor
|
8
|
+
class_option :version, type: :boolean, aliases: "-v", desc: "Show version number and quit"
|
9
|
+
class_option :help, type: :boolean, aliases: '-h', desc: "Show this help message and quit"
|
10
|
+
|
11
|
+
class_option :deploy_heroku, type: :boolean, aliases: "-H", default: false, desc: "Create Heroku app"
|
12
|
+
class_option :s3_storage, type: :boolean, default: false, desc: "Create an s3 backend for image upload and storage"
|
13
|
+
class_option :aws_region, type: :string, default: 'us-east-1', desc: "Specify a region to create AWS resources in"
|
14
|
+
|
15
|
+
desc "clean APP_NAME", "clean the app"
|
16
|
+
def clean(app_name)
|
17
|
+
`rm -rf #{app_name}`
|
18
|
+
AwsBackend.new(app_name: app_name, region: options[:aws_region]).destroy
|
19
|
+
HerokuBackend.new(app_name: app_name).destroy
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -5,37 +5,44 @@ require 'active_support/core_ext/hash/indifferent_access'
|
|
5
5
|
|
6
6
|
module MobileWorkflowCli
|
7
7
|
class AppGenerator < Rails::Generators::AppGenerator
|
8
|
-
hide!
|
9
|
-
|
10
|
-
class_option :database, type: :string, aliases: "-d", default: "postgresql", desc: "Configure for selected database (options: #{DATABASES.join("/")})"
|
8
|
+
hide!
|
11
9
|
class_option :skip_test, type: :boolean, default: true, desc: "Skip Test Unit"
|
12
10
|
class_option :force, type: :boolean, default: true, desc: "Force overwrite"
|
13
11
|
|
14
12
|
class_option :version, type: :boolean, aliases: "-v", desc: "Show version number and quit"
|
15
13
|
class_option :help, type: :boolean, aliases: '-h', desc: "Show this help message and quit"
|
16
14
|
|
17
|
-
class_option :heroku, type: :boolean,
|
15
|
+
class_option :heroku, type: :boolean, default: false, desc: "Create Heroku app"
|
16
|
+
|
17
|
+
class_option :dokku, type: :boolean, default: false, desc: "Create Dokku app"
|
18
|
+
class_option :dokku_host, type: :string, desc: "Specify the Dokku host machine e.g. 18.131.127.164"
|
19
|
+
|
20
|
+
class_option :s3_storage, type: :boolean, default: false, desc: "Create an s3 backend for image upload and storage"
|
21
|
+
class_option :aws_region, type: :string, default: 'us-east-1', desc: "Specify a region to create AWS resources in"
|
18
22
|
|
19
23
|
def self.banner
|
20
24
|
"mwf <directory> <OpenAPI Spec file path> [options]"
|
21
25
|
end
|
22
26
|
|
23
27
|
def finish_template
|
24
|
-
open_api_spec = read_openapi_spec
|
25
|
-
generate_models(open_api_spec)
|
26
|
-
setup_db
|
27
|
-
generate_administrate
|
28
|
-
generate_base_api_controller(open_api_spec)
|
29
|
-
generate_controllers_and_routes(open_api_spec)
|
30
|
-
generate_procfile
|
31
|
-
|
32
|
-
admin_user = 'admin'
|
33
|
-
admin_password = SecureRandom.base64(12)
|
34
|
-
generate_dot_env(admin_user, admin_password)
|
35
28
|
super
|
36
|
-
|
37
|
-
|
38
|
-
|
29
|
+
after_bundle do
|
30
|
+
run "spring stop"
|
31
|
+
build :procfiles
|
32
|
+
build :rspec_generator
|
33
|
+
build :ability_generator
|
34
|
+
build :active_storage if options[:s3_storage]
|
35
|
+
build :mobile_workflow_generator, ARGV[1]
|
36
|
+
setup_db
|
37
|
+
generate_administrate
|
38
|
+
|
39
|
+
generate_dot_env
|
40
|
+
initial_git_commit
|
41
|
+
|
42
|
+
build :heroku if options[:heroku]
|
43
|
+
build :dokku, options[:dokku_host] if options[:dokku]
|
44
|
+
build :s3_backend, options[:aws_region] if options[:s3_storage]
|
45
|
+
end
|
39
46
|
end
|
40
47
|
|
41
48
|
protected
|
@@ -47,84 +54,31 @@ module MobileWorkflowCli
|
|
47
54
|
# Todo: MBS - move these methods to the builder class
|
48
55
|
# Ideally override RailsBuilder methods
|
49
56
|
private
|
50
|
-
def read_openapi_spec
|
51
|
-
openapi_spec_path = ARGV[1]
|
52
|
-
say "Loading model from OpenAPI Spec: #{openapi_spec_path}"
|
53
|
-
return JSON.parse(File.read(openapi_spec_path)).with_indifferent_access
|
54
|
-
end
|
55
|
-
|
56
57
|
def generate_administrate
|
57
|
-
generate
|
58
|
+
generate 'administrate:install'
|
58
59
|
file 'app/assets/config/manifest.js', <<-CODE
|
59
|
-
|
60
|
-
|
60
|
+
//= link administrate/application.css
|
61
|
+
//= link administrate/application.js
|
61
62
|
CODE
|
62
63
|
|
63
64
|
file 'app/controllers/admin/application_controller.rb', <<-CODE
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
def authenticate_admin
|
69
|
-
self.class.http_basic_authenticate_with(name: ENV["ADMIN_USER"], password: ENV["ADMIN_PASSWORD"])
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
CODE
|
74
|
-
end
|
75
|
-
|
76
|
-
def generate_models(openapi_spec)
|
77
|
-
say "Generating models"
|
78
|
-
openapi_spec[:components][:schemas].each_pair do |name, schema|
|
79
|
-
properties_args = schema['properties'].keys.reject{|key| key == 'id'}.collect{|key| "#{key}:#{schema['properties'][key]['type']}" }.join(' ')
|
80
|
-
generate(:model, "#{name.underscore} #{properties_args}")
|
81
|
-
end
|
82
|
-
end
|
65
|
+
module Admin
|
66
|
+
class ApplicationController < Administrate::ApplicationController
|
67
|
+
before_action :authenticate_admin
|
83
68
|
|
84
|
-
def
|
85
|
-
|
86
|
-
class ApiController < ActionController::API
|
69
|
+
def authenticate_admin
|
70
|
+
self.class.http_basic_authenticate_with(name: ENV["ADMIN_USER"], password: ENV["ADMIN_PASSWORD"])
|
87
71
|
end
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
say "Generating controllers"
|
93
|
-
controller_names = []
|
94
|
-
openapi_spec[:paths].each_pair do |url_path, path|
|
95
|
-
controller_name = url_path.split('/').last.pluralize
|
96
|
-
model = path[:get][:responses]["200"][:content]['application/json'][:schema][:items]['$ref'].split('/').last
|
97
|
-
file "app/controllers/#{controller_name}_controller.rb", <<-CODE
|
98
|
-
class #{controller_name.titleize}Controller < ApiController
|
99
|
-
def index
|
100
|
-
render json: #{model}.where(filter_params)
|
101
|
-
end
|
102
|
-
|
103
|
-
private
|
104
|
-
def filter_params
|
105
|
-
params.permit() # Add any filter properties here
|
106
|
-
end
|
107
|
-
end
|
108
|
-
CODE
|
109
|
-
controller_names << controller_name
|
110
|
-
end
|
111
|
-
controller_names.each {|n| route "resources :#{n}, only: :index" }
|
112
|
-
|
113
|
-
# Root route
|
114
|
-
route "root to: 'admin/#{controller_names.first}#index'"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
CODE
|
75
|
+
generate 'administrate:routes'
|
115
76
|
end
|
116
77
|
|
117
78
|
def setup_db
|
118
|
-
rails_command
|
119
|
-
rails_command
|
120
|
-
rails_command
|
121
|
-
end
|
122
|
-
|
123
|
-
def generate_procfile
|
124
|
-
file 'Procfile', <<-CODE
|
125
|
-
web: bundle exec rackup config.ru -p $PORT
|
126
|
-
release: bundle exec rake db:migrate
|
127
|
-
CODE
|
79
|
+
rails_command "db:drop"
|
80
|
+
rails_command "db:create"
|
81
|
+
rails_command "db:migrate"
|
128
82
|
end
|
129
83
|
|
130
84
|
def initial_git_commit
|
@@ -132,18 +86,14 @@ module MobileWorkflowCli
|
|
132
86
|
git commit: %Q{ -m 'Initial commit' }
|
133
87
|
end
|
134
88
|
|
135
|
-
def generate_dot_env
|
89
|
+
def generate_dot_env
|
90
|
+
admin_user = 'admin'
|
91
|
+
admin_password = SecureRandom.base64(12)
|
92
|
+
|
136
93
|
file '.env', <<-CODE
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
end
|
141
|
-
|
142
|
-
def deploy_heroku(admin_user, admin_password)
|
143
|
-
heroku_output = `heroku create`
|
144
|
-
`git push heroku master`
|
145
|
-
`heroku config:set ADMIN_USER=#{admin_user} ADMIN_PASSWORD=#{admin_password}`
|
146
|
-
say "Server created: #{heroku_output}"
|
94
|
+
ADMIN_USER=#{admin_user}
|
95
|
+
ADMIN_PASSWORD=#{admin_password}
|
96
|
+
CODE
|
147
97
|
end
|
148
98
|
end
|
149
99
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
class AwsBackend
|
2
|
+
|
3
|
+
attr_accessor :access_id, :secret_key, :region, :bucket_name
|
4
|
+
|
5
|
+
def initialize(app_name:, region:)
|
6
|
+
@app_name = app_name
|
7
|
+
@aws_name = @app_name.gsub("_", "-")
|
8
|
+
@region = region
|
9
|
+
end
|
10
|
+
|
11
|
+
def bucket_name
|
12
|
+
@aws_name
|
13
|
+
end
|
14
|
+
|
15
|
+
def create
|
16
|
+
aws_command "aws s3api create-bucket --bucket #{@aws_name} --acl private --region #{@region} --create-bucket-configuration LocationConstraint=#{@region}"
|
17
|
+
@topic_arn = aws_command("aws sns create-topic --name #{@aws_name} --region #{@region}")["TopicArn"]
|
18
|
+
aws_command "aws iam create-user --user-name #{@aws_name}"
|
19
|
+
aws_command "aws iam put-user-policy --user-name #{@aws_name} --policy-name s3 --policy-document '{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":[\"s3:PutObject\",\"s3:PutObjectAcl\",\"s3:GetObject\", \"s3:DeleteObject\"],\"Resource\":[\"arn:aws:s3:::#{@aws_name}/*\"]}, {\"Effect\": \"Allow\", \"Action\": \"s3:ListBucket\", \"Resource\": \"arn:aws:s3:::#{@aws_name}\"}]}'"
|
20
|
+
aws_command "aws iam put-user-policy --user-name #{@aws_name} --policy-name sns --policy-document '{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":[\"sns:ConfirmSubscription\"],\"Resource\":[\"#{@topic_arn}\"]}]}'"
|
21
|
+
aws_command "aws sns set-topic-attributes --topic-arn #{@topic_arn} --region #{@region} --attribute-name Policy --attribute-value '{\"Version\": \"2012-10-17\", \"Id\": \"s3\", \"Statement\": [{\"Sid\": \"#{@aws_name}-s3-sid\", \"Effect\": \"Allow\", \"Principal\": {\"AWS\": \"*\"}, \"Action\": \"SNS:Publish\", \"Resource\": \"#{@topic_arn}\", \"Condition\": {\"ArnEquals\": {\"aws:SourceArn\": \"arn:aws:s3:::#{@aws_name}\"}}}]}'"
|
22
|
+
aws_command "aws s3api put-bucket-notification-configuration --bucket #{@aws_name} --notification-configuration '{\"TopicConfigurations\": [{\"TopicArn\": \"#{@topic_arn}\", \"Events\": [\"s3:ObjectCreated:*\"]}]}'"
|
23
|
+
aws_credentials_json = aws_command("aws iam create-access-key --user-name #{@aws_name}")["AccessKey"]
|
24
|
+
@access_id, @secret_key = aws_credentials_json["AccessKeyId"], aws_credentials_json["SecretAccessKey"]
|
25
|
+
|
26
|
+
return @access_id, @secret_key
|
27
|
+
end
|
28
|
+
|
29
|
+
def create_topic_subscription(endpoint)
|
30
|
+
aws_command "aws sns subscribe --topic-arn #{@topic_arn} --region #{@region} --protocol https --notification-endpoint #{endpoint}"
|
31
|
+
end
|
32
|
+
|
33
|
+
def destroy
|
34
|
+
aws_command "aws s3api delete-bucket --bucket #{@aws_name} --region #{@region}"
|
35
|
+
|
36
|
+
aws_command("aws sns list-topics")["Topics"].each do |topic|
|
37
|
+
topic_arn = topic["TopicArn"]
|
38
|
+
aws_command "aws sns delete-topic --topic-arn '#{topic_arn}'" if topic_arn.end_with?(@aws_name)
|
39
|
+
end
|
40
|
+
|
41
|
+
aws_command "aws iam delete-user-policy --user-name #{@aws_name} --policy-name s3"
|
42
|
+
aws_command "aws iam delete-user-policy --user-name #{@aws_name} --policy-name sns"
|
43
|
+
aws_command("aws iam list-access-keys --user-name #{@aws_name}")["AccessKeyMetadata"].each do |accessKeyMetadata|
|
44
|
+
aws_command "aws iam delete-access-key --user-name #{@aws_name} --access-key #{accessKeyMetadata["AccessKeyId"]}"
|
45
|
+
end
|
46
|
+
aws_command "aws iam delete-user --user-name #{@aws_name}"
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
def aws_command(command)
|
51
|
+
puts "Running: #{command}"
|
52
|
+
output = `#{command}`
|
53
|
+
puts "Output: #{output}" unless output.blank?
|
54
|
+
return !output.blank? ? JSON.parse(output) : nil
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
class DokkuBackend
|
2
|
+
def initialize(dokku_host:, app_name:)
|
3
|
+
@dokku_host = dokku_host
|
4
|
+
@dokku_app_name = app_name.gsub("_", "-")
|
5
|
+
end
|
6
|
+
|
7
|
+
def create
|
8
|
+
remote_command "dokku apps:create #{@dokku_app_name}"
|
9
|
+
remote_command "dokku postgres:create #{@dokku_app_name}"
|
10
|
+
remote_command "dokku postgres:link #{@dokku_app_name} #{@dokku_app_name}"
|
11
|
+
remote_command "dokku domains:enable #{@dokku_app_name}"
|
12
|
+
remote_command "dokku letsencrypt #{@dokku_app_name}"
|
13
|
+
|
14
|
+
local_command "git remote add dokku dokku@#{@dokku_host}:#{@dokku_app_name}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def configure_activestorage
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
def deploy
|
22
|
+
local_command "git push dokku master"
|
23
|
+
end
|
24
|
+
|
25
|
+
def sync_dotenv
|
26
|
+
env = File.read(".env").split.join(" ")
|
27
|
+
puts "Setting env: #{env}"
|
28
|
+
local_command "dokku config:set #{env}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def destroy
|
32
|
+
remote_command "dokku apps:destroy #{@dokku_app_name}"
|
33
|
+
end
|
34
|
+
|
35
|
+
def dokku_app_host
|
36
|
+
remote_command "dokku url #{@dokku_app_name}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def notifications_endpoint
|
40
|
+
"https://#{dokku_app_host}/notifications"
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
def remote_command(command)
|
45
|
+
command = "ssh -t ubuntu@#{@dokku_host} '#{command}'"
|
46
|
+
local_command(command)
|
47
|
+
end
|
48
|
+
|
49
|
+
def local_command(command)
|
50
|
+
puts "Running: #{command}"
|
51
|
+
output = `#{command}`
|
52
|
+
puts "Output: #{output}" unless output.blank?
|
53
|
+
return output
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class HerokuBackend
|
2
|
+
def initialize(app_name:)
|
3
|
+
@heroku_app_name = app_name.gsub("_", "-")
|
4
|
+
end
|
5
|
+
|
6
|
+
def create
|
7
|
+
heroku_command "heroku create #{@heroku_app_name}"
|
8
|
+
heroku_command "git push --set-upstream heroku master"
|
9
|
+
end
|
10
|
+
|
11
|
+
def configure_activestorage
|
12
|
+
heroku_command "heroku buildpacks:add -i 1 https://github.com/heroku/heroku-buildpack-activestorage-preview --app #{@heroku_app_name}"
|
13
|
+
heroku_command "heroku labs:enable runtime-dyno-metadata --app #{@heroku_app_name}" # Gives access to heroku variables which can be used to construct URLs
|
14
|
+
|
15
|
+
# Force recompile after buildpacks change
|
16
|
+
heroku_command "git commit --allow-empty -m 'empty commit'"
|
17
|
+
deploy
|
18
|
+
end
|
19
|
+
|
20
|
+
def deploy
|
21
|
+
heroku_command "git push"
|
22
|
+
end
|
23
|
+
|
24
|
+
def sync_dotenv
|
25
|
+
env = File.read(".env").split.join(" ")
|
26
|
+
puts "Setting env: #{env}"
|
27
|
+
heroku_command "heroku config:set #{env} --app #{@heroku_app_name}"
|
28
|
+
end
|
29
|
+
|
30
|
+
def destroy
|
31
|
+
heroku_command "heroku destroy #{@heroku_app_name} --confirm #{@heroku_app_name}"
|
32
|
+
end
|
33
|
+
|
34
|
+
def notifications_endpoint
|
35
|
+
"https://#{@heroku_app_name}.herokuapp.com/notifications"
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
def heroku_command(command)
|
40
|
+
puts "Running: #{command}"
|
41
|
+
output = `#{command}`
|
42
|
+
puts "Output: #{output}" unless output.blank?
|
43
|
+
return output
|
44
|
+
end
|
45
|
+
end
|
data/mobile_workflow_cli.gemspec
CHANGED
@@ -14,6 +14,8 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.metadata["homepage_uri"] = s.homepage
|
15
15
|
s.metadata["source_code_uri"] = s.homepage
|
16
16
|
|
17
|
+
s.executables = ['mwf']
|
18
|
+
|
17
19
|
s.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
18
20
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|s|features)/}) }
|
19
21
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
3
|
+
|
4
|
+
ruby '2.6.6'
|
5
|
+
|
6
|
+
# Core Gems
|
7
|
+
gem 'rails', '~> 6.0.2', '>= 6.0.2.2'
|
8
|
+
|
9
|
+
gem 'puma', '~> 4.1'
|
10
|
+
gem 'sass-rails', '>= 6'
|
11
|
+
gem 'webpacker', '~> 4.0'
|
12
|
+
gem 'turbolinks', '~> 5'
|
13
|
+
gem 'bootsnap', '>= 1.4.2', require: false
|
14
|
+
|
15
|
+
# Authorisation / Authentication
|
16
|
+
gem 'cancancan', '~> 3.1'
|
17
|
+
|
18
|
+
# Admin console
|
19
|
+
gem 'administrate', '~> 0.13.0'
|
20
|
+
gem 'administrate-field-active_storage'
|
21
|
+
gem 'administrate-field-enum'
|
22
|
+
|
23
|
+
# Backend storage for S3
|
24
|
+
gem "image_processing"
|
25
|
+
gem 'aws-sdk-s3', '~> 1.60', '>= 1.60.1'
|
26
|
+
gem 'aws-sdk-sns', '~> 1.23'
|
27
|
+
|
28
|
+
# Mobile Workflow
|
29
|
+
gem 'mobile_workflow', '~> 0.1.0'
|
30
|
+
|
31
|
+
group :development do
|
32
|
+
gem 'web-console', '>= 3.3.0'
|
33
|
+
gem 'listen', '>= 3.0.5', '< 3.2'
|
34
|
+
gem 'spring'
|
35
|
+
gem 'spring-watcher-listen', '~> 2.0.0'
|
36
|
+
end
|
37
|
+
|
38
|
+
group :development, :test do
|
39
|
+
gem 'sqlite3'
|
40
|
+
gem 'rspec-rails', '~> 4.0.0'
|
41
|
+
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
|
42
|
+
gem 'dotenv-rails'
|
43
|
+
end
|
44
|
+
|
45
|
+
group :production do
|
46
|
+
gem 'pg', '>= 0.18', '< 2.0'
|
47
|
+
end
|
data/templates/Procfile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
web: bundle exec rackup config.ru -p $PORT
|
@@ -0,0 +1,14 @@
|
|
1
|
+
test:
|
2
|
+
service: Disk
|
3
|
+
root: <%= Rails.root.join("tmp/storage") %>
|
4
|
+
|
5
|
+
local:
|
6
|
+
service: Disk
|
7
|
+
root: <%= Rails.root.join("storage") %>
|
8
|
+
|
9
|
+
amazon:
|
10
|
+
service: S3
|
11
|
+
access_key_id: <%= ENV['AWS_ACCESS_ID'] %>
|
12
|
+
secret_access_key: <%= ENV['AWS_SECRET_KEY'] %>
|
13
|
+
region: <%= ENV['AWS_REGION'] %>
|
14
|
+
bucket: <%= ENV['AWS_BUCKET_NAME'] %>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mobile_workflow_cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Brooke-Smith
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-06-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: administrate
|
@@ -55,7 +55,8 @@ dependencies:
|
|
55
55
|
description:
|
56
56
|
email:
|
57
57
|
- matt@futureworkshops.com
|
58
|
-
executables:
|
58
|
+
executables:
|
59
|
+
- mwf
|
59
60
|
extensions: []
|
60
61
|
extra_rdoc_files: []
|
61
62
|
files:
|
@@ -70,15 +71,25 @@ files:
|
|
70
71
|
- Rakefile
|
71
72
|
- USAGE
|
72
73
|
- bin/mwf
|
74
|
+
- bin/mwf-delete
|
73
75
|
- bin/setup
|
74
76
|
- lib/mobile_workflow_cli.rb
|
75
77
|
- lib/mobile_workflow_cli/app_builder.rb
|
78
|
+
- lib/mobile_workflow_cli/app_cleaner.rb
|
76
79
|
- lib/mobile_workflow_cli/app_generator.rb
|
80
|
+
- lib/mobile_workflow_cli/aws_backend.rb
|
81
|
+
- lib/mobile_workflow_cli/dokku_backend.rb
|
82
|
+
- lib/mobile_workflow_cli/heroku_backend.rb
|
77
83
|
- lib/mobile_workflow_cli/version.rb
|
78
84
|
- mobile_workflow_cli.gemspec
|
79
85
|
- spec/mobile_workflow_cli_spec.rb
|
80
86
|
- spec/spec_helper.rb
|
87
|
+
- templates/Gemfile.erb
|
88
|
+
- templates/Procfile
|
89
|
+
- templates/Procfile.dev
|
81
90
|
- templates/README.md.erb
|
91
|
+
- templates/ability.rb
|
92
|
+
- templates/storage.s3.yml
|
82
93
|
homepage: https://github.com/FutureWorkshops/MobileWorkflowCli
|
83
94
|
licenses:
|
84
95
|
- MIT
|