mobile_workflow_cli 0.1.1 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 14eadecdf65029000c8a7fee3e1a5ac7d2f94c0f855fd6f20a163a5f98376647
4
- data.tar.gz: 18aa7a950972b919664664e6e9fcceff25930ec769f95eda5aa5956b8f07c996
3
+ metadata.gz: ab76f2f5530aaa6f596be739b7f688cb78c537c28b5929c9477f548ea7e4cbbe
4
+ data.tar.gz: a03772c1bc45a38e5b8d3ba60cbb4f035c7ad3fb70a7c3aa50e9c591eda5641e
5
5
  SHA512:
6
- metadata.gz: d3da9a2036e2e6a15fb39d8b829e86609876cd43f75e27cadf58f9fc072dc81e85dbef35e9e3507073979edd08061d0eacfe3d4f82a152e2c542352664762060
7
- data.tar.gz: 78a427c0e21f31f9c8fbb15cf7cc749184634e7691e379a8bd47566a7019d4bd1bd96b2f3767105910028e5cc758a35c82578869f1a7925be30b881e2a618e74
6
+ metadata.gz: cccff8aaebd38f37c8a162c3b6eb8bf76e32ddc3f52b8f782330b36e144f120e69a1a439549ecdd245ffa01c9d8159f535fb50de5389e4d19db86852d4831cda
7
+ data.tar.gz: 7487c091c91a052bdf962b3785afcc54f45d237138378b8c009706a250763dc10c0a570ae1a719d474689dbda06bef8940d1a6ee08bc333facb73266c41e2eb0
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
- ```ruby
14
- gem 'mobile_workflow_cli'
15
- ```
19
+ `gem 'mobile_workflow_cli'`
16
20
 
17
21
  ## Usage
18
22
 
19
- ```mwf new <path to open api spec json> [options]```
20
-
23
+ `mwf --help`
21
24
 
22
25
  ## License
23
26
 
data/USAGE CHANGED
@@ -2,8 +2,10 @@ Description:
2
2
  Mobile Workflow CLI creates a Rails template project for your Mobile Workflow App.
3
3
 
4
4
  Example:
5
- mwf todo_server ~/Downloads/todo_oai_spec.json -H
5
+ mwf todo_server ~/Downloads/todo_oai_spec.json --heroku
6
6
 
7
7
  Generate a Rails installation from the downloaded todo_oai_spec.json in the todo_server
8
8
  folder relative to the current directory. Then create an new Heroku app and deploy the code.
9
9
 
10
+
11
+
data/bin/mwf CHANGED
@@ -1,6 +1,11 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'pathname'
3
- require 'byebug'
3
+
4
+ # Byebug for dev
5
+ begin
6
+ require 'byebug'
7
+ rescue LoadError
8
+ end
4
9
 
5
10
  source_path = (Pathname.new(__FILE__).dirname + '../lib').expand_path
6
11
  $LOAD_PATH << source_path
@@ -0,0 +1,27 @@
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 "See --help for more info"
17
+ exit 0
18
+ elsif ['-v', '--version'].include? ARGV[0]
19
+ puts MobileWorkflowCli::VERSION
20
+ exit 0
21
+ end
22
+
23
+ # Add the default task
24
+ ARGV.unshift(MobileWorkflowCli::AppCleaner.default_task) unless ARGV[0] == '--help'
25
+
26
+ # Run the cleaner
27
+ MobileWorkflowCli::AppCleaner.start(ARGV)
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative "../lib/mobile_workflow_cli/aws_backend"
3
+ require_relative "../lib/mobile_workflow_cli/heroku_backend"
4
+
5
+ # Byebug for dev
6
+ begin
7
+ require 'byebug'
8
+ rescue LoadError
9
+ end
10
+
11
+ if ARGV.count < 2 || ['-h', '--help'].include?(ARGV[0])
12
+ puts "USAGE: mwf_s3 <create|destroy|> <App name>"
13
+ exit 0
14
+ elsif ARGV.count == 2
15
+ app_name = ARGV[1]
16
+ aws = AwsBackend.new(app_name: app_name, region: 'us-east-1')
17
+
18
+ if ARGV[0] == 'create'
19
+ aws.create
20
+ heroku = HerokuBackend.new(app_name: app_name)
21
+ heroku.configure_activestorage
22
+ aws.create_topic_subscription(heroku.notifications_endpoint)
23
+ aws.put_env
24
+ elsif ARGV[0] == 'destroy'
25
+ aws.destroy
26
+ end
27
+ exit 0
28
+ end
@@ -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,80 @@ module MobileWorkflowCli
5
5
  end
6
6
 
7
7
  def gemfile
8
- super
9
- # Thoughtbot administrate for admin console
10
- gem "administrate"
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
+ gen_opts = ""
33
+ gen_opts += "--doorkeeper_oauth" if options[:doorkeeper_oauth]
34
+ generate "mobile_workflow:install #{gen_opts}"
35
+
36
+ # Copy user migrations if needed
37
+ rails_command 'mobile_workflow:install:migrations' if options[:doorkeeper_oauth]
38
+ end
39
+
40
+ def s3_backend(region)
41
+ @region = region
42
+ aws_backend.create
43
+ aws_backend.write_env
44
+
45
+ if options[:heroku]
46
+ heroku_backend.sync_dotenv
47
+ sleep 10 # Wait for the server to restart
48
+ aws_backend.create_topic_subscription(heroku_backend.notifications_endpoint)
49
+ elsif options[:dokku]
50
+ dokku_backend.sync_dotenv
51
+ aws_backend.create_topic_subscription(dokku_backend.notifications_endpoint)
52
+ end
11
53
 
12
- # Dotenv for development / test
13
- gem 'dotenv-rails', groups: [:development, :test]
54
+ end
55
+
56
+ def heroku
57
+ heroku_backend.create
58
+ heroku_backend.configure_activestorage if options[:s3_storage]
59
+ heroku_backend.deploy
60
+ heroku_backend.sync_dotenv
61
+ end
62
+
63
+ def dokku(dokku_host)
64
+ @dokku_host = dokku_host
65
+ dokku_backend.create
66
+ dokku_backend.configure_activestorage if options[:s3_storage]
67
+ dokku_backend.deploy
68
+ dokku_backend.sync_dotenv
69
+ end
70
+
71
+ private
72
+ def aws_backend
73
+ @aws_backend ||= AwsBackend.new(app_name: app_name, region: @region)
74
+ end
75
+
76
+ def dokku_backend
77
+ @dokku_backend ||= DokkuBackend.new(app_name: app_name, dokku_host: @dokku_host)
78
+ end
79
+
80
+ def heroku_backend
81
+ @heroku_backend ||= HerokuBackend.new(app_name: app_name)
14
82
  end
15
83
  end
16
84
  end
@@ -0,0 +1,26 @@
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 :heroku, type: :boolean, default: false, desc: "Clean Heroku app"
12
+ class_option :s3_storage, type: :boolean, default: false, desc: "Clean an s3 backend for attachment 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
+ default_task :clean
16
+
17
+ desc "APP_NAME", "clean the app"
18
+ def clean(app_name)
19
+ `rm -rf #{app_name}`
20
+ AwsBackend.new(app_name: app_name, region: options[:aws_region]).destroy if options[:s3_storage]
21
+ HerokuBackend.new(app_name: app_name).destroy if options[:heroku]
22
+ end
23
+
24
+
25
+ end
26
+ end
@@ -5,37 +5,46 @@ 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"
11
+ class_option :skip_webpack_install, type: :boolean, default: true, desc: "Skip webpacker installation"
13
12
 
14
13
  class_option :version, type: :boolean, aliases: "-v", desc: "Show version number and quit"
15
14
  class_option :help, type: :boolean, aliases: '-h', desc: "Show this help message and quit"
16
15
 
17
- class_option :heroku, type: :boolean, aliases: "-H", default: false, desc: "Create Heroku app"
16
+ class_option :heroku, type: :boolean, default: false, desc: "Create Heroku app"
17
+
18
+ class_option :dokku, type: :boolean, default: false, desc: "Create Dokku app"
19
+ class_option :dokku_host, type: :string, desc: "Specify the Dokku host machine e.g. 18.131.127.164"
20
+
21
+ class_option :s3_storage, type: :boolean, default: false, desc: "Create an s3 backend for attachment upload and storage"
22
+ class_option :aws_region, type: :string, default: 'us-east-1', desc: "Specify a region to create AWS resources in"
23
+
24
+ class_option :doorkeeper_oauth, type: :boolean, default: false, desc: "Use Doorkeeper gem for OAuth login"
18
25
 
19
26
  def self.banner
20
27
  "mwf <directory> <OpenAPI Spec file path> [options]"
21
28
  end
22
29
 
23
30
  def finish_template
24
- run "spring stop"
25
- open_api_spec = read_openapi_spec
26
- generate_models(open_api_spec)
27
- setup_db
28
- generate_base_api_controller(open_api_spec)
29
- generate_controllers_and_routes(open_api_spec)
30
- generate_procfile
31
- admin_user = 'admin'
32
- admin_password = SecureRandom.base64(12)
33
- generate_dot_env(admin_user, admin_password)
34
31
  super
35
32
  after_bundle do
33
+ run "spring stop"
34
+ build :procfiles
35
+ build :rspec_generator
36
+ build :ability_generator
37
+ build :active_storage if options[:s3_storage]
38
+ build :mobile_workflow_generator, ARGV[1]
39
+ setup_db
36
40
  generate_administrate
41
+
42
+ generate_dot_env
37
43
  initial_git_commit
38
- deploy_heroku(admin_user, admin_password) if options[:heroku]
44
+
45
+ build :heroku if options[:heroku]
46
+ build :dokku, options[:dokku_host] if options[:dokku]
47
+ build :s3_backend, options[:aws_region] if options[:s3_storage]
39
48
  end
40
49
  end
41
50
 
@@ -48,71 +57,21 @@ module MobileWorkflowCli
48
57
  # Todo: MBS - move these methods to the builder class
49
58
  # Ideally override RailsBuilder methods
50
59
  private
51
- def read_openapi_spec
52
- openapi_spec_path = ARGV[1]
53
- say "Loading model from OpenAPI Spec: #{openapi_spec_path}"
54
- return JSON.parse(File.read(openapi_spec_path)).with_indifferent_access
55
- end
56
-
57
60
  def generate_administrate
58
61
  generate 'administrate:install'
59
62
  file 'app/assets/config/manifest.js', <<-CODE
60
- //= link administrate/application.css
61
- //= link administrate/application.js
63
+ //= link administrate/application.css
64
+ //= link administrate/application.js
62
65
  CODE
63
66
 
64
67
  file 'app/controllers/admin/application_controller.rb', <<-CODE
65
- module Admin
66
- class ApplicationController < Administrate::ApplicationController
67
- before_action :authenticate_admin
68
-
69
- def authenticate_admin
70
- self.class.http_basic_authenticate_with(name: ENV["ADMIN_USER"], password: ENV["ADMIN_PASSWORD"])
71
- end
72
- end
73
- end
74
- CODE
75
- end
76
-
77
- def generate_models(openapi_spec)
78
- say "Generating models"
79
- openapi_spec[:components][:schemas].each_pair do |name, schema|
80
- properties_args = schema['properties'].keys.reject{|key| key == 'id'}.collect{|key| "#{key}:#{schema['properties'][key]['type']}" }.join(' ')
81
- generate(:model, "#{name.underscore} #{properties_args}")
82
- end
83
- end
84
-
85
- def generate_base_api_controller(openapi_spec)
86
- file 'app/controllers/api_controller.rb', <<-CODE
87
- class ApiController < ActionController::API
88
- end
89
- CODE
90
- end
91
-
92
- def generate_controllers_and_routes(openapi_spec)
93
- say "Generating controllers"
94
- controller_names = []
95
- openapi_spec[:paths].each_pair do |url_path, path|
96
- controller_name = url_path.split('/').last.pluralize
97
- model = path[:get][:responses]["200"][:content]['application/json'][:schema][:items]['$ref'].split('/').last
98
- file "app/controllers/#{controller_name}_controller.rb", <<-CODE
99
- class #{controller_name.titleize}Controller < ApiController
100
- def index
101
- render json: #{model}.where(filter_params)
102
- end
103
-
104
- private
105
- def filter_params
106
- params.permit() # Add any filter properties here
107
- end
108
- end
109
- CODE
110
- controller_names << controller_name
111
- end
112
- controller_names.each {|n| route "resources :#{n}, only: :index" }
113
-
114
- # Root route
115
- route "root to: 'admin/#{controller_names.first}#index'"
68
+ module Admin
69
+ class ApplicationController < Administrate::ApplicationController
70
+ http_basic_authenticate_with(name: ENV["ADMIN_USER"], password: ENV["ADMIN_PASSWORD"])
71
+ end
72
+ end
73
+ CODE
74
+ generate 'administrate:routes'
116
75
  end
117
76
 
118
77
  def setup_db
@@ -121,30 +80,19 @@ module MobileWorkflowCli
121
80
  rails_command "db:migrate"
122
81
  end
123
82
 
124
- def generate_procfile
125
- file 'Procfile', <<-CODE
126
- web: bundle exec rackup config.ru -p $PORT
127
- release: bundle exec rake db:migrate
128
- CODE
129
- end
130
-
131
83
  def initial_git_commit
132
84
  git add: "."
133
85
  git commit: %Q{ -m 'Initial commit' }
134
86
  end
135
87
 
136
- def generate_dot_env(admin_user, admin_password)
88
+ def generate_dot_env
89
+ admin_user = 'admin'
90
+ admin_password = SecureRandom.base64(12)
91
+
137
92
  file '.env', <<-CODE
138
- ADMIN_USER=#{admin_user}
139
- ADMIN_PASSWORD=#{admin_password}
140
- CODE
141
- end
142
-
143
- def deploy_heroku(admin_user, admin_password)
144
- heroku_output = `heroku create`
145
- `git push heroku master`
146
- `heroku config:set ADMIN_USER=#{admin_user} ADMIN_PASSWORD=#{admin_password}`
147
- say "Server created: #{heroku_output}"
93
+ ADMIN_USER=#{admin_user}
94
+ ADMIN_PASSWORD=#{admin_password}
95
+ CODE
148
96
  end
149
97
  end
150
98
  end
@@ -0,0 +1,78 @@
1
+ require 'json'
2
+
3
+ class AwsBackend
4
+
5
+ attr_accessor :access_id, :secret_key, :region, :bucket_name
6
+
7
+ def initialize(app_name:, region:)
8
+ @app_name = app_name
9
+ @aws_name = @app_name.gsub("_", "-")
10
+ @region = region
11
+ end
12
+
13
+ def bucket_name
14
+ @aws_name
15
+ end
16
+
17
+ def create
18
+ bucket_configuration = ''
19
+ bucket_configuration += "--create-bucket-configuration LocationConstraint=#{@region}" unless @region.eql? 'us-east-1'
20
+ aws_command "aws s3api create-bucket --bucket #{@aws_name} --acl private --region #{@region} #{bucket_configuration}"
21
+ @topic_arn = aws_command("aws sns create-topic --name #{@aws_name} --region #{@region}")["TopicArn"]
22
+ aws_command "aws iam create-user --user-name #{@aws_name}"
23
+ 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}\"}]}'"
24
+ 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}\"]}]}'"
25
+ 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}\"}}}]}'"
26
+ aws_command "aws s3api put-bucket-notification-configuration --bucket #{@aws_name} --notification-configuration '{\"TopicConfigurations\": [{\"TopicArn\": \"#{@topic_arn}\", \"Events\": [\"s3:ObjectCreated:*\"]}]}'"
27
+ aws_credentials_json = aws_command("aws iam create-access-key --user-name #{@aws_name}")["AccessKey"]
28
+ @access_id, @secret_key = aws_credentials_json["AccessKeyId"], aws_credentials_json["SecretAccessKey"]
29
+ return @access_id, @secret_key
30
+ end
31
+
32
+ def put_env
33
+ puts "AWS_ACCESS_ID=#{access_id}"
34
+ puts "AWS_SECRET_KEY=#{secret_key}"
35
+ puts "AWS_REGION=#{region}"
36
+ puts "AWS_BUCKET_NAME=#{bucket_name}"
37
+ end
38
+
39
+ def write_env
40
+ open('.env', 'a') { |f|
41
+ f.puts "AWS_ACCESS_ID=#{access_id}"
42
+ f.puts "AWS_SECRET_KEY=#{secret_key}"
43
+ f.puts "AWS_REGION=#{region}"
44
+ f.puts "AWS_BUCKET_NAME=#{bucket_name}"
45
+ }
46
+ end
47
+
48
+ def create_topic_subscription(endpoint)
49
+ aws_command "aws sns subscribe --topic-arn #{@topic_arn} --region #{@region} --protocol https --notification-endpoint #{endpoint}"
50
+ end
51
+
52
+ def destroy
53
+ aws_command "aws s3api delete-bucket --bucket #{@aws_name} --region #{@region}"
54
+
55
+ aws_command("aws sns list-topics")["Topics"].each do |topic|
56
+ topic_arn = topic["TopicArn"]
57
+ aws_command "aws sns delete-topic --topic-arn '#{topic_arn}'" if topic_arn.end_with?(@aws_name)
58
+ end
59
+
60
+ aws_command "aws iam delete-user-policy --user-name #{@aws_name} --policy-name s3"
61
+ aws_command "aws iam delete-user-policy --user-name #{@aws_name} --policy-name sns"
62
+ aws_command("aws iam list-access-keys --user-name #{@aws_name}")["AccessKeyMetadata"].each do |accessKeyMetadata|
63
+ aws_command "aws iam delete-access-key --user-name #{@aws_name} --access-key #{accessKeyMetadata["AccessKeyId"]}"
64
+ end
65
+ aws_command "aws iam delete-user --user-name #{@aws_name}"
66
+ end
67
+
68
+ private
69
+ def aws_command(command)
70
+ puts "Running: #{command}"
71
+ output = `#{command}`
72
+ return nil if output == nil || output.strip == ""
73
+
74
+ puts "Output: #{output}"
75
+ JSON.parse(output)
76
+ end
77
+
78
+ 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}/sns_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/sns_notifications"
36
+ end
37
+
38
+ private
39
+ def heroku_command(command)
40
+ puts "Running: #{command}"
41
+ output = `#{command}`
42
+ puts "Output: #{output}"
43
+ return output
44
+ end
45
+ end
@@ -1,5 +1,5 @@
1
1
  module MobileWorkflowCli
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.7"
3
3
  RUBY_VERSION = '2.5.5'
4
4
  RAILS_VERSION = '6.0.0'
5
5
  end
@@ -0,0 +1,53 @@
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
+ gem 'puma', '~> 4.1'
9
+ gem 'sass-rails', '>= 6'
10
+ gem 'turbolinks', '~> 5'
11
+ gem 'bootsnap', '>= 1.4.2', require: false
12
+
13
+ # Mobile Workflow
14
+ #gem 'mobile_workflow', path: '../mobile_workflow'
15
+ gem 'mobile_workflow', github: 'FutureWorkshops/mobile_workflow'
16
+
17
+ # Authorisation / Authentication
18
+ <%- if options[:doorkeeper_oauth] %>
19
+ gem 'doorkeeper'
20
+ gem 'bcrypt-ruby'
21
+ <%- end %>
22
+ gem 'cancancan', '~> 3.1'
23
+
24
+ # Admin console
25
+ gem 'administrate', '~> 0.13.0'
26
+ gem 'administrate-field-active_storage'
27
+ gem 'administrate-field-enum'
28
+
29
+ <%- if options[:s3_storage] %>
30
+ # Backend storage for S3
31
+ gem "image_processing"
32
+ gem 'aws-sdk-s3', '~> 1.60', '>= 1.60.1'
33
+ gem 'aws-sdk-sns', '~> 1.23'
34
+ <%- end %>
35
+
36
+ group :development do
37
+ gem 'web-console', '>= 3.3.0'
38
+ gem 'listen', '>= 3.0.5', '< 3.2'
39
+ gem 'spring'
40
+ gem 'spring-watcher-listen', '~> 2.0.0'
41
+ end
42
+
43
+ group :development, :test do
44
+ gem 'sqlite3'
45
+ gem 'rspec-rails', '~> 4.0.0'
46
+ gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
47
+ gem 'dotenv-rails'
48
+ gem 'factory_bot_rails'
49
+ end
50
+
51
+ group :production do
52
+ gem 'pg', '>= 0.18', '< 2.0'
53
+ end
@@ -0,0 +1,2 @@
1
+ web: bundle exec rackup config.ru -p $PORT
2
+ release: bundle exec rake db:migrate
@@ -0,0 +1 @@
1
+ web: bundle exec rackup config.ru -p $PORT
@@ -0,0 +1,7 @@
1
+ class Ability
2
+ include CanCan::Ability
3
+
4
+ def initialize(user)
5
+ can :manage, :all
6
+ end
7
+ end
@@ -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.1
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Brooke-Smith
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-14 00:00:00.000000000 Z
11
+ date: 2020-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: administrate
@@ -52,40 +52,44 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
- description:
55
+ description:
56
56
  email:
57
57
  - matt@futureworkshops.com
58
- executables: []
58
+ executables:
59
+ - mwf
60
+ - mwf-delete
61
+ - mwf_s3
59
62
  extensions: []
60
63
  extra_rdoc_files: []
61
64
  files:
62
- - ".byebug_history"
63
- - ".gitignore"
64
- - ".rspec"
65
- - ".travis.yml"
66
- - Gemfile
67
- - Gemfile.lock
68
- - LICENSE.txt
69
65
  - README.md
70
66
  - Rakefile
71
67
  - USAGE
72
68
  - bin/mwf
69
+ - bin/mwf-delete
70
+ - bin/mwf_s3
73
71
  - bin/setup
74
72
  - lib/mobile_workflow_cli.rb
75
73
  - lib/mobile_workflow_cli/app_builder.rb
74
+ - lib/mobile_workflow_cli/app_cleaner.rb
76
75
  - lib/mobile_workflow_cli/app_generator.rb
76
+ - lib/mobile_workflow_cli/aws_backend.rb
77
+ - lib/mobile_workflow_cli/dokku_backend.rb
78
+ - lib/mobile_workflow_cli/heroku_backend.rb
77
79
  - lib/mobile_workflow_cli/version.rb
78
- - mobile_workflow_cli.gemspec
79
- - spec/mobile_workflow_cli_spec.rb
80
- - spec/spec_helper.rb
80
+ - templates/Gemfile.erb
81
+ - templates/Procfile
82
+ - templates/Procfile.dev
81
83
  - templates/README.md.erb
84
+ - templates/ability.rb
85
+ - templates/storage.s3.yml
82
86
  homepage: https://github.com/FutureWorkshops/MobileWorkflowCli
83
87
  licenses:
84
88
  - MIT
85
89
  metadata:
86
90
  homepage_uri: https://github.com/FutureWorkshops/MobileWorkflowCli
87
91
  source_code_uri: https://github.com/FutureWorkshops/MobileWorkflowCli
88
- post_install_message:
92
+ post_install_message:
89
93
  rdoc_options: []
90
94
  require_paths:
91
95
  - lib
@@ -101,7 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
101
105
  version: '0'
102
106
  requirements: []
103
107
  rubygems_version: 3.0.8
104
- signing_key:
108
+ signing_key:
105
109
  specification_version: 4
106
110
  summary: CLI tool for Mobile Workflow
107
111
  test_files: []
@@ -1,2 +0,0 @@
1
- exit
2
- bt
data/.gitignore DELETED
@@ -1,11 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
- /coverage/
5
- /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
9
-
10
- # rspec failure tracking
11
- .rspec_status
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --format documentation
2
- --color
3
- --require spec_helper
@@ -1,6 +0,0 @@
1
- ---
2
- language: ruby
3
- cache: bundler
4
- rvm:
5
- - 2.6.6
6
- before_install: gem install bundler -v 2.1.4
data/Gemfile DELETED
@@ -1,7 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- # Specify your gem's dependencies in mobile_workflow_cli.gemspec
4
- gemspec
5
-
6
- gem "rake", "~> 12.0"
7
- gem "rspec", "~> 3.0"
@@ -1,205 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- mobile_workflow_cli (0.1.1)
5
- administrate
6
- rails (>= 6.0.0)
7
-
8
- GEM
9
- remote: https://rubygems.org/
10
- specs:
11
- actioncable (6.0.3)
12
- actionpack (= 6.0.3)
13
- nio4r (~> 2.0)
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)
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)
26
- mail (~> 2.5, >= 2.5.4)
27
- rails-dom-testing (~> 2.0)
28
- actionpack (6.0.3)
29
- actionview (= 6.0.3)
30
- activesupport (= 6.0.3)
31
- rack (~> 2.0, >= 2.0.8)
32
- rack-test (>= 0.6.3)
33
- rails-dom-testing (~> 2.0)
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)
40
- nokogiri (>= 1.8.5)
41
- actionview (6.0.3)
42
- activesupport (= 6.0.3)
43
- builder (~> 3.1)
44
- erubi (~> 1.4)
45
- rails-dom-testing (~> 2.0)
46
- rails-html-sanitizer (~> 1.1, >= 1.2.0)
47
- activejob (6.0.3)
48
- activesupport (= 6.0.3)
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)
59
- marcel (~> 0.3.1)
60
- activesupport (6.0.3)
61
- concurrent-ruby (~> 1.0, >= 1.0.2)
62
- i18n (>= 0.7, < 2)
63
- minitest (~> 5.1)
64
- tzinfo (~> 1.1)
65
- zeitwerk (~> 2.2, >= 2.2.2)
66
- administrate (0.13.0)
67
- actionpack (>= 4.2)
68
- actionview (>= 4.2)
69
- activerecord (>= 4.2)
70
- autoprefixer-rails (>= 6.0)
71
- datetime_picker_rails (~> 0.0.7)
72
- jquery-rails (>= 4.0)
73
- kaminari (>= 1.0)
74
- momentjs-rails (~> 2.8)
75
- sassc-rails (~> 2.1)
76
- selectize-rails (~> 0.6)
77
- autoprefixer-rails (9.7.6)
78
- execjs
79
- builder (3.2.4)
80
- byebug (11.1.3)
81
- concurrent-ruby (1.1.6)
82
- crass (1.0.6)
83
- datetime_picker_rails (0.0.7)
84
- momentjs-rails (>= 2.8.1)
85
- diff-lcs (1.3)
86
- erubi (1.9.0)
87
- execjs (2.7.0)
88
- ffi (1.12.2)
89
- globalid (0.4.2)
90
- activesupport (>= 4.2.0)
91
- i18n (1.8.2)
92
- concurrent-ruby (~> 1.0)
93
- jquery-rails (4.4.0)
94
- rails-dom-testing (>= 1, < 3)
95
- railties (>= 4.2.0)
96
- thor (>= 0.14, < 2.0)
97
- kaminari (1.2.0)
98
- activesupport (>= 4.1.0)
99
- kaminari-actionview (= 1.2.0)
100
- kaminari-activerecord (= 1.2.0)
101
- kaminari-core (= 1.2.0)
102
- kaminari-actionview (1.2.0)
103
- actionview
104
- kaminari-core (= 1.2.0)
105
- kaminari-activerecord (1.2.0)
106
- activerecord
107
- kaminari-core (= 1.2.0)
108
- kaminari-core (1.2.0)
109
- loofah (2.5.0)
110
- crass (~> 1.0.2)
111
- nokogiri (>= 1.5.9)
112
- mail (2.7.1)
113
- mini_mime (>= 0.1.1)
114
- marcel (0.3.3)
115
- mimemagic (~> 0.3.2)
116
- method_source (1.0.0)
117
- mimemagic (0.3.5)
118
- mini_mime (1.0.2)
119
- mini_portile2 (2.4.0)
120
- minitest (5.14.0)
121
- momentjs-rails (2.20.1)
122
- railties (>= 3.1)
123
- nio4r (2.5.2)
124
- nokogiri (1.10.9)
125
- mini_portile2 (~> 2.4.0)
126
- rack (2.2.2)
127
- rack-test (1.1.0)
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)
141
- bundler (>= 1.3.0)
142
- railties (= 6.0.3)
143
- sprockets-rails (>= 2.0.0)
144
- rails-dom-testing (2.0.3)
145
- activesupport (>= 4.2.0)
146
- nokogiri (>= 1.6)
147
- rails-html-sanitizer (1.3.0)
148
- loofah (~> 2.3)
149
- railties (6.0.3)
150
- actionpack (= 6.0.3)
151
- activesupport (= 6.0.3)
152
- method_source
153
- rake (>= 0.8.7)
154
- thor (>= 0.20.3, < 2.0)
155
- rake (12.3.3)
156
- rspec (3.9.0)
157
- rspec-core (~> 3.9.0)
158
- rspec-expectations (~> 3.9.0)
159
- rspec-mocks (~> 3.9.0)
160
- rspec-core (3.9.2)
161
- rspec-support (~> 3.9.3)
162
- rspec-expectations (3.9.2)
163
- diff-lcs (>= 1.2.0, < 2.0)
164
- rspec-support (~> 3.9.0)
165
- rspec-mocks (3.9.1)
166
- diff-lcs (>= 1.2.0, < 2.0)
167
- rspec-support (~> 3.9.0)
168
- rspec-support (3.9.3)
169
- sassc (2.3.0)
170
- ffi (~> 1.9)
171
- sassc-rails (2.1.2)
172
- railties (>= 4.0.0)
173
- sassc (>= 2.0)
174
- sprockets (> 3.0)
175
- sprockets-rails
176
- tilt
177
- selectize-rails (0.12.6)
178
- sprockets (4.0.0)
179
- concurrent-ruby (~> 1.0)
180
- rack (> 1, < 3)
181
- sprockets-rails (3.2.1)
182
- actionpack (>= 4.0)
183
- activesupport (>= 4.0)
184
- sprockets (>= 3.0.0)
185
- thor (1.0.1)
186
- thread_safe (0.3.6)
187
- tilt (2.0.10)
188
- tzinfo (1.2.7)
189
- thread_safe (~> 0.1)
190
- websocket-driver (0.7.1)
191
- websocket-extensions (>= 0.1.0)
192
- websocket-extensions (0.1.4)
193
- zeitwerk (2.3.0)
194
-
195
- PLATFORMS
196
- ruby
197
-
198
- DEPENDENCIES
199
- byebug
200
- mobile_workflow_cli!
201
- rake (~> 12.0)
202
- rspec (~> 3.0)
203
-
204
- BUNDLED WITH
205
- 2.1.4
@@ -1,21 +0,0 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2020 Matt Brooke-Smith
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
@@ -1,27 +0,0 @@
1
- require_relative 'lib/mobile_workflow_cli/version'
2
-
3
- Gem::Specification.new do |s|
4
- s.name = "mobile_workflow_cli"
5
- s.version = MobileWorkflowCli::VERSION
6
- s.authors = ["Matt Brooke-Smith"]
7
- s.email = ["matt@futureworkshops.com"]
8
-
9
- s.summary = "CLI tool for Mobile Workflow"
10
- s.homepage = "https://github.com/FutureWorkshops/MobileWorkflowCli"
11
- s.license = "MIT"
12
- s.required_ruby_version = ">= #{MobileWorkflowCli::RUBY_VERSION}"
13
-
14
- s.metadata["homepage_uri"] = s.homepage
15
- s.metadata["source_code_uri"] = s.homepage
16
-
17
- s.files = Dir.chdir(File.expand_path('..', __FILE__)) do
18
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|s|features)/}) }
19
- end
20
- s.test_files = `git ls-files -- {spec}/*`.split("\n")
21
- s.require_paths = ["lib"]
22
-
23
- s.add_dependency 'administrate'
24
- s.add_dependency 'rails', ">= #{MobileWorkflowCli::RAILS_VERSION}"
25
-
26
- s.add_development_dependency 'byebug'
27
- end
@@ -1,9 +0,0 @@
1
- RSpec.describe MobileWorkflowCli do
2
- it "has a version number" do
3
- expect(MobileWorkflowCli::VERSION).not_to be nil
4
- end
5
-
6
- it "does something useful" do
7
- expect(false).to eq(true)
8
- end
9
- end
@@ -1,14 +0,0 @@
1
- require "bundler/setup"
2
- require "mobile_workflow_cli"
3
-
4
- RSpec.configure do |config|
5
- # Enable flags like --only-failures and --next-failure
6
- config.example_status_persistence_file_path = ".rspec_status"
7
-
8
- # Disable RSpec exposing methods globally on `Module` and `main`
9
- config.disable_monkey_patching!
10
-
11
- config.expect_with :rspec do |c|
12
- c.syntax = :expect
13
- end
14
- end