rails_template_18f 0.3.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -0
- data/Gemfile +0 -2
- data/Gemfile.lock +4 -4
- data/exe/rails_template_18f +31 -0
- data/lib/generators/rails_template18f/active_storage/active_storage_generator.rb +141 -0
- data/lib/generators/rails_template18f/active_storage/templates/app/jobs/file_scan_job.rb +33 -0
- data/lib/generators/rails_template18f/active_storage/templates/app/models/file_upload.rb +25 -0
- data/lib/generators/rails_template18f/active_storage/templates/doc/adr/clamav.md.tt +30 -0
- data/lib/generators/rails_template18f/active_storage/templates/spec/jobs/file_scan_job_spec.rb +35 -0
- data/lib/generators/rails_template18f/active_storage/templates/spec/models/file_upload_spec.rb +38 -0
- data/lib/generators/rails_template18f/circleci/circleci_generator.rb +4 -1
- data/lib/generators/rails_template18f/cloud_gov_config/cloud_gov_config_generator.rb +29 -0
- data/lib/generators/rails_template18f/cloud_gov_config/templates/app/models/cloud_gov_config.rb +15 -0
- data/lib/generators/rails_template18f/cloud_gov_config/templates/spec/models/cloud_gov_config_spec.rb +44 -0
- data/lib/generators/rails_template18f/i18n/i18n_generator.rb +8 -9
- data/lib/generators/rails_template18f/i18n_js/i18n_js_generator.rb +59 -0
- data/lib/generators/rails_template18f/i18n_js/templates/lib/tasks/i18n.rake +9 -0
- data/lib/generators/rails_template18f/newrelic/newrelic_generator.rb +2 -0
- data/lib/generators/rails_template18f/sidekiq/sidekiq_generator.rb +81 -0
- data/lib/generators/rails_template18f/sidekiq/templates/config/initializers/redis.rb +14 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/README.md.tt +1 -1
- data/lib/generators/rails_template18f/terraform/templates/terraform/production/main.tf.tt +37 -5
- data/lib/generators/rails_template18f/terraform/templates/terraform/shared/clamav/main.tf.tt +50 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/shared/clamav/providers.tf +16 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/shared/clamav/variables.tf +47 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/shared/redis/main.tf.tt +23 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/shared/redis/providers.tf +16 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/shared/redis/variables.tf +42 -0
- data/lib/generators/rails_template18f/terraform/templates/terraform/staging/main.tf.tt +37 -5
- data/lib/generators/rails_template18f/terraform/terraform_generator.rb +10 -12
- data/lib/rails_template18f/app_updater.rb +19 -0
- data/lib/rails_template18f/generators/base.rb +37 -5
- data/lib/rails_template18f/generators/cloud_gov_options.rb +0 -4
- data/lib/rails_template18f/version.rb +1 -1
- data/rails-template-18f.gemspec +1 -0
- data/template.rb +29 -1
- data/templates/Brewfile +14 -0
- data/templates/README.md.tt +9 -10
- data/templates/app/views/application/_header.html.erb +0 -1
- data/templates/app/views/application/_usa_banner.html.erb +2 -0
- data/templates/bin/with-server +1 -2
- data/templates/config/deployment/staging.yml +1 -1
- data/templates/config/environments/ci.rb +0 -1
- data/templates/doc/compliance/apps/application.boundary.md.tt +0 -7
- data/templates/env +1 -1
- metadata +37 -2
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails/generators"
|
4
|
+
|
5
|
+
module RailsTemplate18f
|
6
|
+
module Generators
|
7
|
+
class SidekiqGenerator < ::Rails::Generators::Base
|
8
|
+
include Base
|
9
|
+
|
10
|
+
desc <<~DESC
|
11
|
+
Description:
|
12
|
+
Install Sidekiq and configure it as the ActiveJob backend
|
13
|
+
DESC
|
14
|
+
|
15
|
+
def install_gem
|
16
|
+
return if gem_installed?("sidekiq")
|
17
|
+
gem "sidekiq", "~> 6.4"
|
18
|
+
bundle_install
|
19
|
+
end
|
20
|
+
|
21
|
+
def install_redis
|
22
|
+
append_to_file "Brewfile", <<~EOB
|
23
|
+
|
24
|
+
# queue for sidekiq jobs
|
25
|
+
brew "redis"
|
26
|
+
EOB
|
27
|
+
insert_into_file "README.md", indent("* [redis]()\n"), after: /\* Install homebrew dependencies: `brew bundle`\n/
|
28
|
+
end
|
29
|
+
|
30
|
+
def configure_server_runner
|
31
|
+
append_to_file "Procfile.dev", "worker: bundle exec sidekiq\n"
|
32
|
+
insert_into_file "manifest.yml", indent(<<~EOYAML), after: /processes:$\n/
|
33
|
+
- type: worker
|
34
|
+
instances: ((worker_instances))
|
35
|
+
memory: ((worker_memory))
|
36
|
+
command: bundle exec sidekiq
|
37
|
+
EOYAML
|
38
|
+
insert_into_file "manifest.yml", "\n - #{app_name}-redis-((env))", after: "services:"
|
39
|
+
inside "config/deployment" do
|
40
|
+
append_to_file "staging.yml", <<~EOYAML
|
41
|
+
worker_instances: 1
|
42
|
+
worker_memory: 256M
|
43
|
+
EOYAML
|
44
|
+
append_to_file "production.yml", <<~EOYAML
|
45
|
+
worker_instances: 1
|
46
|
+
worker_memory: 512M
|
47
|
+
EOYAML
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def configure_active_job
|
52
|
+
generate "rails_template18f:cloud_gov_config", inline: true
|
53
|
+
copy_file "config/initializers/redis.rb"
|
54
|
+
application "config.active_job.queue_adapter = :sidekiq"
|
55
|
+
end
|
56
|
+
|
57
|
+
def configure_sidekiq_ui
|
58
|
+
prepend_to_file "config/routes.rb", "require \"sidekiq/web\"\n\n"
|
59
|
+
route <<~EOR
|
60
|
+
if Rails.env.development?
|
61
|
+
mount Sidekiq::Web => "/sidekiq"
|
62
|
+
end
|
63
|
+
EOR
|
64
|
+
end
|
65
|
+
|
66
|
+
def update_boundary_diagram
|
67
|
+
boundary_filename = "doc/compliance/apps/application.boundary.md"
|
68
|
+
|
69
|
+
insert_into_file boundary_filename, indent(<<~EOB, 16), after: /ContainerDb\(app_db.*$\n/
|
70
|
+
Container(worker, "<&layers> Sidekiq workers", "Ruby #{ruby_version}, Sidekiq", "Perform background work and data processing")
|
71
|
+
ContainerDb(redis, "Redis Database", "AWS ElastiCache (Redis)", "Background job queue")
|
72
|
+
EOB
|
73
|
+
insert_into_file boundary_filename, <<~EOB, before: "@enduml"
|
74
|
+
Rel(app, redis, "enqueue job parameters", "redis")
|
75
|
+
Rel(worker, redis, "dequeues job parameters", "redis")
|
76
|
+
Rel(worker, app_db, "reads/writes primary data", "psql (5432)")
|
77
|
+
EOB
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Rails.application.config.to_prepare do
|
4
|
+
redis_url = CloudGovConfig.dig "aws-elasticache-redis", "credentials", "uri"
|
5
|
+
if redis_url.present?
|
6
|
+
Sidekiq.configure_server do |config|
|
7
|
+
config.redis = {url: redis_url, ssl: true}
|
8
|
+
end
|
9
|
+
|
10
|
+
Sidekiq.configure_client do |config|
|
11
|
+
config.redis = {url: redis_url, ssl: true}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
This directory holds the terraform modules for maintaining your complete persistent infrastructure.
|
4
4
|
|
5
|
-
Prerequisite: install the `jq` JSON processor: `brew install jq`
|
5
|
+
Prerequisite: install the `jq` JSON processor: `brew bundle` or `brew install jq`
|
6
6
|
|
7
7
|
## Initial setup
|
8
8
|
|
@@ -16,17 +16,49 @@ module "database" {
|
|
16
16
|
recursive_delete = local.recursive_delete
|
17
17
|
rds_plan_name = "TKTK-production-rds-plan"
|
18
18
|
}
|
19
|
+
<% if has_active_job? %>
|
20
|
+
module "redis" {
|
21
|
+
source = "../shared/redis"
|
19
22
|
|
23
|
+
cf_user = var.cf_user
|
24
|
+
cf_password = var.cf_password
|
25
|
+
cf_org_name = local.cf_org_name
|
26
|
+
cf_space_name = local.cf_space_name
|
27
|
+
env = local.env
|
28
|
+
recursive_delete = local.recursive_delete
|
29
|
+
redis_plan_name = "TKTK-production-redis-plan"
|
30
|
+
}
|
31
|
+
<% end %>
|
20
32
|
<% if has_active_storage? %>
|
21
33
|
module "s3" {
|
22
34
|
source = "../shared/s3"
|
23
35
|
|
24
|
-
cf_user
|
25
|
-
cf_password
|
26
|
-
cf_org_name
|
27
|
-
cf_space_name
|
28
|
-
|
36
|
+
cf_user = var.cf_user
|
37
|
+
cf_password = var.cf_password
|
38
|
+
cf_org_name = local.cf_org_name
|
39
|
+
cf_space_name = local.cf_space_name
|
40
|
+
recursive_delete = local.recursive_delete
|
41
|
+
s3_service_name = "<%= app_name %>-s3-${local.env}"<% if cloud_gov_organization == "sandbox-gsa" %>
|
42
|
+
s3_plan_name = "basic-sandbox"<% end %>
|
29
43
|
}
|
44
|
+
|
45
|
+
###########################################################################
|
46
|
+
# The following lines need to be commented out for the initial `terraform apply`
|
47
|
+
# It can be re-enabled after:
|
48
|
+
# 1) the app has first been deployed
|
49
|
+
# 2) Your organization has sufficient memory. Each clamav app requires 3GB
|
50
|
+
###########################################################################
|
51
|
+
# module "clamav" {
|
52
|
+
# source = "../shared/clamav"
|
53
|
+
#
|
54
|
+
# cf_user = var.cf_user
|
55
|
+
# cf_password = var.cf_password
|
56
|
+
# cf_org_name = local.cf_org_name
|
57
|
+
# cf_space_name = local.cf_space_name
|
58
|
+
# env = local.env
|
59
|
+
# clamav_image = "ajilaag/clamav-rest:20211229"
|
60
|
+
# max_file_size = "30M"
|
61
|
+
# }
|
30
62
|
<% end %>
|
31
63
|
|
32
64
|
###########################################################################
|
@@ -0,0 +1,50 @@
|
|
1
|
+
###
|
2
|
+
# Target space/org
|
3
|
+
###
|
4
|
+
|
5
|
+
data "cloudfoundry_space" "space" {
|
6
|
+
org_name = var.cf_org_name
|
7
|
+
name = var.cf_space_name
|
8
|
+
}
|
9
|
+
|
10
|
+
data "cloudfoundry_domain" "internal" {
|
11
|
+
name = "apps.internal"
|
12
|
+
}
|
13
|
+
|
14
|
+
data "cloudfoundry_app" "app" {
|
15
|
+
name_or_id = "<%= app_name %>-${var.env}"
|
16
|
+
space = data.cloudfoundry_space.space.id
|
17
|
+
}
|
18
|
+
|
19
|
+
###
|
20
|
+
# ClamAV API app
|
21
|
+
###
|
22
|
+
|
23
|
+
resource "cloudfoundry_route" "clamav_route" {
|
24
|
+
space = data.cloudfoundry_space.space.id
|
25
|
+
domain = data.cloudfoundry_domain.internal.id
|
26
|
+
hostname = "<%= app_name %>-clamapi-${var.env}"
|
27
|
+
}
|
28
|
+
|
29
|
+
resource "cloudfoundry_app" "clamav_api" {
|
30
|
+
name = "<%= app_name %>-clamav-api-${var.env}"
|
31
|
+
space = data.cloudfoundry_space.space.id
|
32
|
+
memory = var.clamav_memory
|
33
|
+
disk_quota = 2048
|
34
|
+
timeout = 600
|
35
|
+
docker_image = var.clamav_image
|
36
|
+
routes {
|
37
|
+
route = cloudfoundry_route.clamav_route.id
|
38
|
+
}
|
39
|
+
environment = {
|
40
|
+
MAX_FILE_SIZE = var.max_file_size
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
resource "cloudfoundry_network_policy" "clamav_routing" {
|
45
|
+
policy {
|
46
|
+
source_app = data.cloudfoundry_app.app.id
|
47
|
+
destination_app = cloudfoundry_app.clamav_api.id
|
48
|
+
port = "9443"
|
49
|
+
}
|
50
|
+
}
|
data/lib/generators/rails_template18f/terraform/templates/terraform/shared/clamav/providers.tf
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
terraform {
|
2
|
+
required_version = "~> 1.0"
|
3
|
+
required_providers {
|
4
|
+
cloudfoundry = {
|
5
|
+
source = "cloudfoundry-community/cloudfoundry"
|
6
|
+
version = "0.15.0"
|
7
|
+
}
|
8
|
+
}
|
9
|
+
}
|
10
|
+
|
11
|
+
provider "cloudfoundry" {
|
12
|
+
api_url = var.cf_api_url
|
13
|
+
user = var.cf_user
|
14
|
+
password = var.cf_password
|
15
|
+
app_logs_max = 30
|
16
|
+
}
|
data/lib/generators/rails_template18f/terraform/templates/terraform/shared/clamav/variables.tf
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
variable "cf_api_url" {
|
2
|
+
type = string
|
3
|
+
description = "cloud.gov api url"
|
4
|
+
default = "https://api.fr.cloud.gov"
|
5
|
+
}
|
6
|
+
|
7
|
+
variable "cf_user" {
|
8
|
+
type = string
|
9
|
+
description = "cloud.gov deployer account user"
|
10
|
+
}
|
11
|
+
|
12
|
+
variable "cf_password" {
|
13
|
+
type = string
|
14
|
+
description = "secret; cloud.gov deployer account password"
|
15
|
+
sensitive = true
|
16
|
+
}
|
17
|
+
|
18
|
+
variable "cf_org_name" {
|
19
|
+
type = string
|
20
|
+
description = "cloud.gov organization name"
|
21
|
+
}
|
22
|
+
|
23
|
+
variable "cf_space_name" {
|
24
|
+
type = string
|
25
|
+
description = "cloud.gov space name (staging or prod)"
|
26
|
+
}
|
27
|
+
|
28
|
+
variable "env" {
|
29
|
+
type = string
|
30
|
+
description = "deployment environment (staging, production)"
|
31
|
+
}
|
32
|
+
|
33
|
+
variable "clamav_image" {
|
34
|
+
type = string
|
35
|
+
description = "Docker image to deploy the clamav api app"
|
36
|
+
}
|
37
|
+
|
38
|
+
variable "clamav_memory" {
|
39
|
+
type = number
|
40
|
+
description = "Memory in MB to allocate to clamav app"
|
41
|
+
default = 3072
|
42
|
+
}
|
43
|
+
|
44
|
+
variable "max_file_size" {
|
45
|
+
type = string
|
46
|
+
description = "Maximum file size the API will accept for scanning"
|
47
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
###
|
2
|
+
# Target space/org
|
3
|
+
###
|
4
|
+
|
5
|
+
data "cloudfoundry_space" "space" {
|
6
|
+
org_name = var.cf_org_name
|
7
|
+
name = var.cf_space_name
|
8
|
+
}
|
9
|
+
|
10
|
+
###
|
11
|
+
# RDS instance
|
12
|
+
###
|
13
|
+
|
14
|
+
data "cloudfoundry_service" "redis" {
|
15
|
+
name = "aws-elasticache-redis"
|
16
|
+
}
|
17
|
+
|
18
|
+
resource "cloudfoundry_service_instance" "redis" {
|
19
|
+
name = "<%= app_name %>-redis-${var.env}"
|
20
|
+
space = data.cloudfoundry_space.space.id
|
21
|
+
service_plan = data.cloudfoundry_service.redis.service_plans[var.redis_plan_name]
|
22
|
+
recursive_delete = var.recursive_delete
|
23
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
terraform {
|
2
|
+
required_version = "~> 1.0"
|
3
|
+
required_providers {
|
4
|
+
cloudfoundry = {
|
5
|
+
source = "cloudfoundry-community/cloudfoundry"
|
6
|
+
version = "0.15.0"
|
7
|
+
}
|
8
|
+
}
|
9
|
+
}
|
10
|
+
|
11
|
+
provider "cloudfoundry" {
|
12
|
+
api_url = var.cf_api_url
|
13
|
+
user = var.cf_user
|
14
|
+
password = var.cf_password
|
15
|
+
app_logs_max = 30
|
16
|
+
}
|
@@ -0,0 +1,42 @@
|
|
1
|
+
variable "cf_api_url" {
|
2
|
+
type = string
|
3
|
+
description = "cloud.gov api url"
|
4
|
+
default = "https://api.fr.cloud.gov"
|
5
|
+
}
|
6
|
+
|
7
|
+
variable "cf_user" {
|
8
|
+
type = string
|
9
|
+
description = "cloud.gov deployer account user"
|
10
|
+
}
|
11
|
+
|
12
|
+
variable "cf_password" {
|
13
|
+
type = string
|
14
|
+
description = "secret; cloud.gov deployer account password"
|
15
|
+
sensitive = true
|
16
|
+
}
|
17
|
+
|
18
|
+
variable "cf_org_name" {
|
19
|
+
type = string
|
20
|
+
description = "cloud.gov organization name"
|
21
|
+
}
|
22
|
+
|
23
|
+
variable "cf_space_name" {
|
24
|
+
type = string
|
25
|
+
description = "cloud.gov space name (staging or prod)"
|
26
|
+
}
|
27
|
+
|
28
|
+
variable "env" {
|
29
|
+
type = string
|
30
|
+
description = "deployment environment (staging, production)"
|
31
|
+
}
|
32
|
+
|
33
|
+
variable "recursive_delete" {
|
34
|
+
type = bool
|
35
|
+
description = "when true, deletes service bindings attached to the resource (not recommended for production)"
|
36
|
+
default = false
|
37
|
+
}
|
38
|
+
|
39
|
+
variable "redis_plan_name" {
|
40
|
+
type = string
|
41
|
+
description = "name of the service plan name to create"
|
42
|
+
}
|
@@ -16,15 +16,47 @@ module "database" {
|
|
16
16
|
recursive_delete = local.recursive_delete
|
17
17
|
rds_plan_name = "micro-psql"
|
18
18
|
}
|
19
|
+
<% if has_active_job? %>
|
20
|
+
module "redis" {
|
21
|
+
source = "../shared/redis"
|
19
22
|
|
23
|
+
cf_user = var.cf_user
|
24
|
+
cf_password = var.cf_password
|
25
|
+
cf_org_name = local.cf_org_name
|
26
|
+
cf_space_name = local.cf_space_name
|
27
|
+
env = local.env
|
28
|
+
recursive_delete = local.recursive_delete
|
29
|
+
redis_plan_name = "redis-dev"
|
30
|
+
}
|
31
|
+
<% end %>
|
20
32
|
<% if has_active_storage? %>
|
21
33
|
module "s3" {
|
22
34
|
source = "../shared/s3"
|
23
35
|
|
24
|
-
cf_user
|
25
|
-
cf_password
|
26
|
-
cf_org_name
|
27
|
-
cf_space_name
|
28
|
-
|
36
|
+
cf_user = var.cf_user
|
37
|
+
cf_password = var.cf_password
|
38
|
+
cf_org_name = local.cf_org_name
|
39
|
+
cf_space_name = local.cf_space_name
|
40
|
+
recursive_delete = local.recursive_delete
|
41
|
+
s3_service_name = "<%= app_name %>-s3-${local.env}"<% if cloud_gov_organization == "sandbox-gsa" %>
|
42
|
+
s3_plan_name = "basic-sandbox"<% end %>
|
29
43
|
}
|
44
|
+
|
45
|
+
###########################################################################
|
46
|
+
# The following lines need to be commented out for the initial `terraform apply`
|
47
|
+
# It can be re-enabled after:
|
48
|
+
# 1) the app has first been deployed
|
49
|
+
# 2) Your organization has sufficient memory. Each clamav app requires 3GB
|
50
|
+
###########################################################################
|
51
|
+
# module "clamav" {
|
52
|
+
# source = "../shared/clamav"
|
53
|
+
#
|
54
|
+
# cf_user = var.cf_user
|
55
|
+
# cf_password = var.cf_password
|
56
|
+
# cf_org_name = local.cf_org_name
|
57
|
+
# cf_space_name = local.cf_space_name
|
58
|
+
# env = local.env
|
59
|
+
# clamav_image = "ajilaag/clamav-rest:20211229"
|
60
|
+
# max_file_size = "30M"
|
61
|
+
# }
|
30
62
|
<% end %>
|
@@ -19,6 +19,15 @@ module RailsTemplate18f
|
|
19
19
|
chmod "terraform/bootstrap/teardown_creds.sh", 0o755
|
20
20
|
end
|
21
21
|
|
22
|
+
def install_jq
|
23
|
+
append_to_file "Brewfile", <<~EOB
|
24
|
+
|
25
|
+
# used in terraform/create_space_deployer.sh
|
26
|
+
brew "jq"
|
27
|
+
EOB
|
28
|
+
insert_into_file "README.md", indent("* [jq](https://stedolan.github.io/jq/)\n"), after: /\* Install homebrew dependencies: `brew bundle`\n/
|
29
|
+
end
|
30
|
+
|
22
31
|
def ignore_files
|
23
32
|
unless skip_git?
|
24
33
|
append_to_file ".gitignore", <<~EOM
|
@@ -34,7 +43,7 @@ module RailsTemplate18f
|
|
34
43
|
end
|
35
44
|
|
36
45
|
def update_readme
|
37
|
-
gsub_file "README.md", /^(### Automatic linting)
|
46
|
+
gsub_file "README.md", /^(### Automatic linting)\s*$/, '\1 and terraform formatting'
|
38
47
|
gsub_file "README.md", /(ruby linting) (on every)/, '\1 and terraform formatting \2'
|
39
48
|
gsub_file "README.md", /^Before the first deploy only.*$/, "Follow the instructions in `terraform/README.md` to create the supporting services."
|
40
49
|
end
|
@@ -79,17 +88,6 @@ module RailsTemplate18f
|
|
79
88
|
EOM
|
80
89
|
end
|
81
90
|
end
|
82
|
-
|
83
|
-
private
|
84
|
-
|
85
|
-
def terraform_dir_exists?
|
86
|
-
# prevents cloud_gov_* helpers from trying to read non-existant .tf files
|
87
|
-
false
|
88
|
-
end
|
89
|
-
|
90
|
-
def has_active_storage?
|
91
|
-
defined?(::ActiveStorage)
|
92
|
-
end
|
93
91
|
end
|
94
92
|
end
|
95
93
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require "rails/app_updater"
|
2
|
+
|
3
|
+
module AppUpdaterOptions
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
class_methods do
|
7
|
+
def generator_options
|
8
|
+
options = super
|
9
|
+
# These options all end up hardcoded to true in the default `rails app:update`
|
10
|
+
options[:skip_active_job] = !defined?(ActiveJob::Railtie)
|
11
|
+
options[:skip_action_mailbox] = !defined?(ActionMailbox::Engine)
|
12
|
+
options[:skip_action_text] = !defined?(ActionText::Engine)
|
13
|
+
options[:skip_test] = !defined?(Rails::TestUnitRailtie)
|
14
|
+
options
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
Rails::AppUpdater.prepend(AppUpdaterOptions)
|
@@ -1,15 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "bundler"
|
4
|
+
|
3
5
|
module RailsTemplate18f
|
4
6
|
module Generators
|
5
7
|
module Base
|
6
8
|
extend ActiveSupport::Concern
|
7
9
|
include ::Rails::Generators::AppName
|
8
10
|
|
9
|
-
included do
|
10
|
-
self.source_path = RailsTemplate18f::Generators.const_source_location(name).first
|
11
|
-
end
|
12
|
-
|
13
11
|
class_methods do
|
14
12
|
attr_accessor :source_path
|
15
13
|
|
@@ -18,19 +16,53 @@ module RailsTemplate18f
|
|
18
16
|
end
|
19
17
|
end
|
20
18
|
|
19
|
+
included do
|
20
|
+
self.source_path = RailsTemplate18f::Generators.const_source_location(name).first
|
21
|
+
end
|
22
|
+
|
21
23
|
private
|
22
24
|
|
25
|
+
def bundle_install
|
26
|
+
Bundler.with_original_env do
|
27
|
+
in_root do
|
28
|
+
run "bundle install"
|
29
|
+
yield if block_given?
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def gem_installed?(gem_name)
|
35
|
+
file_content("Gemfile").match?(/gem "#{gem_name}"/)
|
36
|
+
end
|
37
|
+
|
23
38
|
def file_content(filename)
|
24
|
-
File.
|
39
|
+
file_path = File.expand_path(filename, destination_root)
|
40
|
+
if File.exist? file_path
|
41
|
+
File.read(file_path)
|
42
|
+
else
|
43
|
+
""
|
44
|
+
end
|
25
45
|
end
|
26
46
|
|
27
47
|
def ruby_version
|
28
48
|
RUBY_VERSION
|
29
49
|
end
|
30
50
|
|
51
|
+
def terraform_dir_exists?
|
52
|
+
Dir.exist? File.expand_path("terraform", destination_root)
|
53
|
+
end
|
54
|
+
|
31
55
|
def skip_git?
|
32
56
|
!Dir.exist?(File.expand_path(".git", destination_root))
|
33
57
|
end
|
58
|
+
|
59
|
+
def has_active_job?
|
60
|
+
defined?(::ActiveJob)
|
61
|
+
end
|
62
|
+
|
63
|
+
def has_active_storage?
|
64
|
+
defined?(::ActiveStorage)
|
65
|
+
end
|
34
66
|
end
|
35
67
|
end
|
36
68
|
end
|
data/rails-template-18f.gemspec
CHANGED
@@ -34,6 +34,7 @@ Gem::Specification.new do |spec|
|
|
34
34
|
spec.add_dependency "railties", "~> 7.0.0"
|
35
35
|
spec.add_dependency "activesupport", "~> 7.0.0"
|
36
36
|
spec.add_dependency "thor", "~> 1.0"
|
37
|
+
spec.add_dependency "colorize", "~> 0.8"
|
37
38
|
|
38
39
|
spec.add_development_dependency "rspec", "~> 3.11"
|
39
40
|
spec.add_development_dependency "ammeter", "~> 1.1"
|
data/template.rb
CHANGED
@@ -10,6 +10,10 @@ def skip_git?
|
|
10
10
|
!!options[:skip_git]
|
11
11
|
end
|
12
12
|
|
13
|
+
def skip_active_job?
|
14
|
+
!!options[:skip_active_job]
|
15
|
+
end
|
16
|
+
|
13
17
|
def webpack?
|
14
18
|
adjusted_javascript_option == "webpack"
|
15
19
|
end
|
@@ -83,6 +87,13 @@ register_announcement("Documentation", <<~EOM)
|
|
83
87
|
* Review any TBD sections of the README and update where appropriate.
|
84
88
|
EOM
|
85
89
|
|
90
|
+
# ensure dependencies are installed
|
91
|
+
copy_file "Brewfile"
|
92
|
+
insert_into_file "bin/setup", <<EOSETUP, after: /Add necessary setup steps to this file.\n/
|
93
|
+
puts "== Installing homebrew dependencies =="
|
94
|
+
system("brew bundle --no-lock")
|
95
|
+
EOSETUP
|
96
|
+
|
86
97
|
# setup nvmrc
|
87
98
|
file ".nvmrc", @node_version
|
88
99
|
|
@@ -187,9 +198,14 @@ copy_file "env", ".env"
|
|
187
198
|
copy_file "githooks/pre-commit", ".githooks/pre-commit", mode: :preserve
|
188
199
|
|
189
200
|
unless skip_git?
|
190
|
-
|
201
|
+
after_bundle do
|
202
|
+
rails_command "credentials:diff --enroll"
|
203
|
+
end
|
191
204
|
append_to_file ".gitignore", <<~EOM
|
192
205
|
|
206
|
+
# Ignore Brewfile debug info
|
207
|
+
Brewfile.lock.json
|
208
|
+
|
193
209
|
# Ignore local dotenv overrides
|
194
210
|
.env*.local
|
195
211
|
|
@@ -339,6 +355,18 @@ if terraform
|
|
339
355
|
register_announcement("Terraform", "Run the bootstrap script and update the appropriate CI/CD environment variables defined in the Deployment section of the README")
|
340
356
|
end
|
341
357
|
|
358
|
+
if !skip_active_job?
|
359
|
+
after_bundle do
|
360
|
+
generate "rails_template18f:sidekiq"
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
if !skip_active_storage?
|
365
|
+
after_bundle do
|
366
|
+
generate "rails_template18f:active_storage"
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
342
370
|
if @github_actions
|
343
371
|
after_bundle do
|
344
372
|
generator_arguments = [
|
data/templates/Brewfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# Brewfile
|
2
|
+
# add any dependencies that must be installed from homebrew here
|
3
|
+
|
4
|
+
# cloud.gov RDS is on postgres 12
|
5
|
+
brew "postgresql@12", link: true
|
6
|
+
|
7
|
+
# used in bin/with-server script
|
8
|
+
brew "dockerize"
|
9
|
+
|
10
|
+
# helper scripts for creating new ADRs
|
11
|
+
brew "adr-tools"
|
12
|
+
|
13
|
+
# chromedriver for integration tests
|
14
|
+
cask "chromedriver"
|