wslave 0.2.2
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 +7 -0
- data/base/.gitignore +5 -0
- data/base/Capfile +24 -0
- data/base/Gemfile +3 -0
- data/base/Rakefile +81 -0
- data/base/config/deploy-tools/gen-nginx-vhost.rb +11 -0
- data/base/config/deploy-tools/gen-salts.rb +21 -0
- data/base/config/deploy-tools/gen-wp-config.rb +18 -0
- data/base/config/deploy-tools/nginx.vhost.erb +51 -0
- data/base/config/deploy-tools/wp-config.php.erb +97 -0
- data/base/config/deploy-tools/wp-config.php.local +96 -0
- data/base/config/deploy.rb +17 -0
- data/base/config/deploy/.production.rb.swp +0 -0
- data/base/config/deploy/.staging.rb.swp +0 -0
- data/base/config/deploy/production.rb +288 -0
- data/base/config/deploy/staging.rb +288 -0
- data/base/docker-compose.yml +33 -0
- data/base/docker/apache/Dockerfile +16 -0
- data/base/docker/nginx/Dockerfile +24 -0
- data/base/docker/nginx/nginx.vhost +48 -0
- data/base/docker/nginx/supervisord.conf +23 -0
- data/base/public/.htaccess +27 -0
- data/base/public/wp-config.php +96 -0
- data/bin/wslave +123 -0
- data/lib/wslave_docker.rb +75 -0
- data/lib/wslave_new.rb +82 -0
- data/lib/wslave_sage.rb +76 -0
- data/lib/wslave_tools.rb +80 -0
- data/lib/wslave_update.rb +38 -0
- data/templates/config/database.yml +16 -0
- data/templates/config/definitions.yml +22 -0
- data/wslave.gemspec +32 -0
- metadata +211 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 61e948f1644206ed6520ad69e43583dbafe1200208eb007d7dab044e09d1c84f
|
4
|
+
data.tar.gz: 351b554954d11957292a027a440f7add6ee8156b7b5eeaa9d97fc7cbb9772fb9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b67317839d90324f73bdd34c998832be78d367174fe2c88737d615a9811b9c5c531ea0bed198461425307b2b7e6742e330a9258abe7a10b99f7af9b1630a4756
|
7
|
+
data.tar.gz: 2513942d0a62658f8a4b72bc0f2afcc3f933ad94c6f5507ad6f9a94c02571cdcfaa0b625049c9e2cf9f55d8789b3223f748c6eee3157a2b96dc0c986001d1d51
|
data/base/Capfile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'capistrano/setup'
|
2
|
+
require 'capistrano/deploy'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
opts = YAML.load_file('config/definitions.yml')
|
6
|
+
|
7
|
+
deploy_method = 'git-with-submodules'
|
8
|
+
deploy_method = opts['options']['deploy_method'] if (opts.has_key?('options') &&
|
9
|
+
opts['options'].has_key?('deploy_method'))
|
10
|
+
|
11
|
+
case deploy_method
|
12
|
+
when 'scp'
|
13
|
+
require 'capistrano/copy'
|
14
|
+
when 'git'
|
15
|
+
require 'capistrano/scm/git'
|
16
|
+
install_plugin Capistrano::SCM::Git
|
17
|
+
else
|
18
|
+
require 'capistrano/scm/git'
|
19
|
+
install_plugin Capistrano::SCM::Git
|
20
|
+
require 'capistrano/scm/git-with-submodules'
|
21
|
+
install_plugin Capistrano::SCM::Git::WithSubmodules
|
22
|
+
end
|
23
|
+
|
24
|
+
Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }
|
data/base/Gemfile
ADDED
data/base/Rakefile
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
@opts = YAML.load_file('config/definitions.yml')
|
5
|
+
|
6
|
+
def rm_dbfile(profile)
|
7
|
+
puts "Deleting db/#{profile}/wordpress.sql"
|
8
|
+
FileUtils.rm("db/#{profile}/wordpress.sql") if File.exist?("db/#{profile}/wordpress.sql")
|
9
|
+
end
|
10
|
+
|
11
|
+
namespace :db do
|
12
|
+
namespace :dev do
|
13
|
+
desc 'Backup development container database to db/dev (container must be running)'
|
14
|
+
task :backup do
|
15
|
+
rm_dbfile('dev')
|
16
|
+
puts 'Creating backup of development database...'
|
17
|
+
sh 'docker-compose exec db sh -c "exec mysqldump --single-transaction -hlocalhost -uroot -pwordpress wordpress > /db/wordpress.sql"'
|
18
|
+
sh 'docker-compose exec db sh -c "chown :www-data /db/wordpress.sql"'
|
19
|
+
sh 'docker-compose exec db sh -c "chmod 664 /db/wordpress.sql"'
|
20
|
+
end
|
21
|
+
|
22
|
+
desc 'Set the development container database image to the active image'
|
23
|
+
task :activate do
|
24
|
+
rm_dbfile('active')
|
25
|
+
FileUtils.cp('db/dev/wordpress.sql', 'db/active/wordpress.sql')
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
desc 'Backup and activate the development container database (container must be running)'
|
30
|
+
task :dev do
|
31
|
+
Rake::Task['db:dev:backup'].invoke
|
32
|
+
Rake::Task['db:dev:activate'].invoke
|
33
|
+
end
|
34
|
+
|
35
|
+
namespace :staging do
|
36
|
+
desc 'Set the staging database backup to the active database'
|
37
|
+
task :activate do
|
38
|
+
rm_dbfile('active')
|
39
|
+
FileUtils.cp('db/staging/wordpress.sql', 'db/active/wordpress.sql')
|
40
|
+
_replace_active_urls
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
namespace :production do
|
45
|
+
desc 'Set the production database backup to the active database'
|
46
|
+
task :activate do
|
47
|
+
rm_dbfile('active')
|
48
|
+
FileUtils.cp('db/production/wordpress.sql', 'db/active/wordpress.sql')
|
49
|
+
_replace_active_urls
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Converts staging and production URL entries in DB backup with localhost:8000
|
54
|
+
def _replace_active_urls()
|
55
|
+
puts 'Replacing Production and Staging URLs for local development/re-deployment...'
|
56
|
+
db_data = File.read('db/active/wordpress.sql')
|
57
|
+
|
58
|
+
if @opts['deployer']['fqdn']['staging'] != ''
|
59
|
+
db_data = db_data.gsub(/#{@opts['deployer']['fqdn']['staging']}/, 'localhost:8000')
|
60
|
+
end
|
61
|
+
if @opts['deployer']['fqdn']['production'] != ''
|
62
|
+
db_data = db_data.gsub(/#{@opts['deployer']['fqdn']['production']}/, 'localhost:8000')
|
63
|
+
end
|
64
|
+
|
65
|
+
File.open('db/active/wordpress.sql', "w") {|file| file.puts db_data }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
namespace :staging do
|
70
|
+
desc 'Open an SSH session to the staging host in the staging directory'
|
71
|
+
task :ssh do
|
72
|
+
exec("ssh #{@opts['deployer']['user']}@#{@opts['deployer']['host']['staging']} -t \"cd #{@opts['deployer']['root']}/#{@opts['deployer']['fqdn']['staging']}; exec \$SHELL -l\"")
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
namespace :production do
|
77
|
+
desc 'Open an SSH session to the staging host in the production directory'
|
78
|
+
task :ssh do
|
79
|
+
exec("ssh #{@opts['deployer']['user']}@#{@opts['deployer']['host']['production']} -t \"cd #{@opts['deployer']['root']}/#{@opts['deployer']['fqdn']['production']}; exec \$SHELL -l\"")
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'yaml'
|
3
|
+
require 'ostruct'
|
4
|
+
|
5
|
+
def GenerateNginxConfig(profile = 'production', out_path= './')
|
6
|
+
config_path = File.dirname(File.expand_path(File.dirname(__FILE__)))
|
7
|
+
server = {}
|
8
|
+
#server[:name] =
|
9
|
+
#server[:root] =
|
10
|
+
#server[:php_sock_path] =
|
11
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
config_path = File.dirname(File.expand_path(File.dirname(__FILE__)))
|
5
|
+
|
6
|
+
if File.exist?("#{config_path}/salts.yml")
|
7
|
+
puts "Salts already generated! Refusing to overwrite them!"
|
8
|
+
else
|
9
|
+
salts = {
|
10
|
+
AUTH_KEY: SecureRandom.base64(24),
|
11
|
+
SECURE_AUTH_KEY: SecureRandom.base64(24),
|
12
|
+
LOGGED_IN_KEY: SecureRandom.base64(24),
|
13
|
+
NONCE_KEY: SecureRandom.base64(24),
|
14
|
+
AUTH_SALT: SecureRandom.base64(24),
|
15
|
+
SECURE_AUTH_SALT: SecureRandom.base64(24),
|
16
|
+
LOGGED_IN_SALT: SecureRandom.base64(24),
|
17
|
+
NONCE_SALT: SecureRandom.base64(24)
|
18
|
+
}
|
19
|
+
|
20
|
+
File.open("#{config_path}/salts.yml", 'w') {|f| f.write salts.to_yaml }
|
21
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'yaml'
|
3
|
+
require 'ostruct'
|
4
|
+
|
5
|
+
def GenerateWPConfig(profile = 'production', out_path = './')
|
6
|
+
require_relative 'gen-salts' # Generate salts if necessary
|
7
|
+
|
8
|
+
config_path = File.dirname(File.expand_path(File.dirname(__FILE__)))
|
9
|
+
vars = {}
|
10
|
+
vars[:profile] = profile.to_sym
|
11
|
+
vars[:db_info] = YAML.load_file("#{config_path}/database.yml")
|
12
|
+
vars[:salt] = YAML.load_file("#{config_path}/salts.yml")
|
13
|
+
|
14
|
+
erb_source = File.read("#{config_path}/deploy-tools/wp-config.php.erb")
|
15
|
+
rend = ERB.new(erb_source)
|
16
|
+
res = rend.result(OpenStruct.new(vars).instance_eval { binding })
|
17
|
+
File.write("#{out_path}/wp-config.php", res)
|
18
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
server {
|
2
|
+
listen 80;
|
3
|
+
listen [::]:80;
|
4
|
+
|
5
|
+
server_name <%= server[:name] %>;
|
6
|
+
|
7
|
+
root <%= server[:root] %>;
|
8
|
+
|
9
|
+
access_log <%= server[:root] %>/access.log;
|
10
|
+
error_log <%= server[:root] %>/error.log;
|
11
|
+
|
12
|
+
index index.php;
|
13
|
+
|
14
|
+
location / {
|
15
|
+
rewrite ^/(wp-(admin|includes).*) /wordpress/$1 last;
|
16
|
+
|
17
|
+
rewrite ^/$ /wordpress/index.php last;
|
18
|
+
|
19
|
+
location ~ \.php {
|
20
|
+
if ($request_uri !~* "/wp-config.php") {
|
21
|
+
rewrite ^/wp-(.*)\.php$ /wordpress/wp-$1.php last;
|
22
|
+
}
|
23
|
+
rewrite ^/index\.php$ /wordpress/index.php last;
|
24
|
+
rewrite ^/wp-login\.php$ /hello.php last;
|
25
|
+
include snippets/fastcgi-php.conf;
|
26
|
+
fastcgi_pass unix:<%= server[:php_sock_path] %>;
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
location ~ /\. {
|
31
|
+
deny all;
|
32
|
+
access_log off;
|
33
|
+
log_not_found off;
|
34
|
+
}
|
35
|
+
|
36
|
+
location ~- \.(blade\.php)$ {
|
37
|
+
deny all;
|
38
|
+
}
|
39
|
+
|
40
|
+
location ~- composer\.(json|lock)$ {
|
41
|
+
deny all;
|
42
|
+
}
|
43
|
+
|
44
|
+
location ~- package(-lock)?\.json$ {
|
45
|
+
deny all;
|
46
|
+
}
|
47
|
+
|
48
|
+
location ~- yarn\.lock$ {
|
49
|
+
deny all;
|
50
|
+
}
|
51
|
+
}
|
@@ -0,0 +1,97 @@
|
|
1
|
+
<?php
|
2
|
+
/**
|
3
|
+
* The base configuration for WordPress
|
4
|
+
*
|
5
|
+
* The wp-config.php creation script uses this file during the
|
6
|
+
* installation. You don't have to use the web site, you can
|
7
|
+
* copy this file to "wp-config.php" and fill in the values.
|
8
|
+
*
|
9
|
+
* This file contains the following configurations:
|
10
|
+
*
|
11
|
+
* * MySQL settings
|
12
|
+
* * Secret keys
|
13
|
+
* * Database table prefix
|
14
|
+
* * ABSPATH
|
15
|
+
*
|
16
|
+
* @link https://codex.wordpress.org/Editing_wp-config.php
|
17
|
+
*
|
18
|
+
* @package WordPress
|
19
|
+
*/
|
20
|
+
|
21
|
+
// ** MySQL settings - You can get this info from your web host ** //
|
22
|
+
/** The name of the database for WordPress */
|
23
|
+
define('DB_NAME', '<%= db_info[profile]["database"] %>');
|
24
|
+
|
25
|
+
/** MySQL database username */
|
26
|
+
define('DB_USER', '<%= db_info[profile]["username"] %>');
|
27
|
+
|
28
|
+
/** MySQL database password */
|
29
|
+
define('DB_PASSWORD', '<%= db_info[profile]["password"] %>');
|
30
|
+
|
31
|
+
/** MySQL hostname */
|
32
|
+
define('DB_HOST', '<%= db_info[profile]["host"] %>');
|
33
|
+
|
34
|
+
/** Database Charset to use in creating database tables. */
|
35
|
+
define('DB_CHARSET', 'utf8');
|
36
|
+
|
37
|
+
/** The Database Collate type. Don't change this if in doubt. */
|
38
|
+
define('DB_COLLATE', '');
|
39
|
+
|
40
|
+
/**#@+
|
41
|
+
* Authentication Unique Keys and Salts.
|
42
|
+
*
|
43
|
+
* Change these to different unique phrases!
|
44
|
+
* You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}
|
45
|
+
* You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again.
|
46
|
+
*
|
47
|
+
* @since 2.6.0
|
48
|
+
*/
|
49
|
+
define('AUTH_KEY', '<%= salt[:AUTH_KEY] %>');
|
50
|
+
define('SECURE_AUTH_KEY', '<%= salt[:SECURE_AUTH_KEY] %>');
|
51
|
+
define('LOGGED_IN_KEY', '<%= salt[:LOGGED_IN_KEY] %>');
|
52
|
+
define('NONCE_KEY', '<%= salt[:NONCE_KEY] %>');
|
53
|
+
define('AUTH_SALT', '<%= salt[:AUTH_SALT] %>');
|
54
|
+
define('SECURE_AUTH_SALT', '<%= salt[:SECURE_AUTH_SALT] %>');
|
55
|
+
define('LOGGED_IN_SALT', '<%= salt[:LOGGED_IN_SALT] %>');
|
56
|
+
define('NONCE_SALT', '<%= salt[:NONCE_SALT] %>');
|
57
|
+
|
58
|
+
/**#@-*/
|
59
|
+
|
60
|
+
/**
|
61
|
+
* WordPress Database Table prefix.
|
62
|
+
*
|
63
|
+
* You can have multiple installations in one database if you give each
|
64
|
+
* a unique prefix. Only numbers, letters, and underscores please!
|
65
|
+
*/
|
66
|
+
$table_prefix = 'wp_';
|
67
|
+
|
68
|
+
/**
|
69
|
+
* For developers: WordPress debugging mode.
|
70
|
+
*
|
71
|
+
* Change this to true to enable the display of notices during development.
|
72
|
+
* It is strongly recommended that plugin and theme developers use WP_DEBUG
|
73
|
+
* in their development environments.
|
74
|
+
*
|
75
|
+
* For information on other constants that can be used for debugging,
|
76
|
+
* visit the Codex.
|
77
|
+
*
|
78
|
+
* @link https://codex.wordpress.org/Debugging_in_WordPress
|
79
|
+
*/
|
80
|
+
define('WP_DEBUG', false);
|
81
|
+
|
82
|
+
/* That's all, stop editing! Happy blogging. */
|
83
|
+
|
84
|
+
/** Absolute path to the WordPress directory. */
|
85
|
+
if ( !defined('ABSPATH') )
|
86
|
+
define('ABSPATH', dirname(__FILE__) . '/wordpress/');
|
87
|
+
|
88
|
+
define('WP_HOME', 'http://' . $_SERVER['HTTP_HOST']);
|
89
|
+
define('WP_SITEURL', 'http://' . $_SERVER['HTTP_HOST'] . '/wordpress');
|
90
|
+
define('WP_CONTENT_DIR', realpath(ABSPATH . '../../../current/public/wp-content/'));
|
91
|
+
define('WP_CONTENT_URL', WP_HOME . '/wp-content');
|
92
|
+
define('WP_TEMP_DIR', realpath(ABSPATH . '../../tmp/'));
|
93
|
+
define('FS_METHOD', 'direct');
|
94
|
+
|
95
|
+
/** Sets up WordPress vars and included files. */
|
96
|
+
require_once(ABSPATH . 'wp-settings.php');
|
97
|
+
add_filter('auto_update_theme', '__return_false');
|
@@ -0,0 +1,96 @@
|
|
1
|
+
<?php
|
2
|
+
/**
|
3
|
+
* The base configuration for WordPress
|
4
|
+
*
|
5
|
+
* The wp-config.php creation script uses this file during the
|
6
|
+
* installation. You don't have to use the web site, you can
|
7
|
+
* copy this file to "wp-config.php" and fill in the values.
|
8
|
+
*
|
9
|
+
* This file contains the following configurations:
|
10
|
+
*
|
11
|
+
* * MySQL settings
|
12
|
+
* * Secret keys
|
13
|
+
* * Database table prefix
|
14
|
+
* * ABSPATH
|
15
|
+
*
|
16
|
+
* @link https://codex.wordpress.org/Editing_wp-config.php
|
17
|
+
*
|
18
|
+
* @package WordPress
|
19
|
+
*/
|
20
|
+
|
21
|
+
// ** MySQL settings - You can get this info from your web host ** //
|
22
|
+
/** The name of the database for WordPress */
|
23
|
+
define('DB_NAME', 'wordpress');
|
24
|
+
|
25
|
+
/** MySQL database username */
|
26
|
+
define('DB_USER', 'wordpress');
|
27
|
+
|
28
|
+
/** MySQL database password */
|
29
|
+
define('DB_PASSWORD', 'wordpress');
|
30
|
+
|
31
|
+
/** MySQL hostname */
|
32
|
+
define('DB_HOST', 'localhost');
|
33
|
+
|
34
|
+
/** Database Charset to use in creating database tables. */
|
35
|
+
define('DB_CHARSET', 'utf8');
|
36
|
+
|
37
|
+
/** The Database Collate type. Don't change this if in doubt. */
|
38
|
+
define('DB_COLLATE', '');
|
39
|
+
|
40
|
+
/**#@+
|
41
|
+
* Authentication Unique Keys and Salts.
|
42
|
+
*
|
43
|
+
* Change these to different unique phrases!
|
44
|
+
* You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}
|
45
|
+
* You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again.
|
46
|
+
*
|
47
|
+
* @since 2.6.0
|
48
|
+
*/
|
49
|
+
define('AUTH_KEY', 'put your unique phrase here');
|
50
|
+
define('SECURE_AUTH_KEY', 'put your unique phrase here');
|
51
|
+
define('LOGGED_IN_KEY', 'put your unique phrase here');
|
52
|
+
define('NONCE_KEY', 'put your unique phrase here');
|
53
|
+
define('AUTH_SALT', 'put your unique phrase here');
|
54
|
+
define('SECURE_AUTH_SALT', 'put your unique phrase here');
|
55
|
+
define('LOGGED_IN_SALT', 'put your unique phrase here');
|
56
|
+
define('NONCE_SALT', 'put your unique phrase here');
|
57
|
+
|
58
|
+
/**#@-*/
|
59
|
+
|
60
|
+
/**
|
61
|
+
* WordPress Database Table prefix.
|
62
|
+
*
|
63
|
+
* You can have multiple installations in one database if you give each
|
64
|
+
* a unique prefix. Only numbers, letters, and underscores please!
|
65
|
+
*/
|
66
|
+
$table_prefix = 'wp_';
|
67
|
+
|
68
|
+
/**
|
69
|
+
* For developers: WordPress debugging mode.
|
70
|
+
*
|
71
|
+
* Change this to true to enable the display of notices during development.
|
72
|
+
* It is strongly recommended that plugin and theme developers use WP_DEBUG
|
73
|
+
* in their development environments.
|
74
|
+
*
|
75
|
+
* For information on other constants that can be used for debugging,
|
76
|
+
* visit the Codex.
|
77
|
+
*
|
78
|
+
* @link https://codex.wordpress.org/Debugging_in_WordPress
|
79
|
+
*/
|
80
|
+
define('WP_DEBUG', false);
|
81
|
+
|
82
|
+
/* That's all, stop editing! Happy blogging. */
|
83
|
+
|
84
|
+
/** Absolute path to the WordPress directory. */
|
85
|
+
if ( !defined('ABSPATH') )
|
86
|
+
define('ABSPATH', dirname(__FILE__) . '/wordpress/');
|
87
|
+
|
88
|
+
define('WP_HOME', 'http://' . $_SERVER['HTTP_HOST']);
|
89
|
+
define('WP_SITEURL', 'http://' . $_SERVER['HTTP_HOST'] . '/wordpress');
|
90
|
+
define('WP_CONTENT_DIR', realpath(ABSPATH . '../wp-content/'));
|
91
|
+
define('WP_CONTENT_URL', WP_HOME . '/wp-content');
|
92
|
+
//define('WP_TEMP_DIR', realpath(ABSPATH . '../../tmp/'));
|
93
|
+
define('FS_METHOD', 'direct');
|
94
|
+
|
95
|
+
/** Sets up WordPress vars and included files. */
|
96
|
+
require_once(ABSPATH . 'wp-settings.php');
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# config valid only for current version of Capistrano
|
2
|
+
lock "3.14.1"
|
3
|
+
|
4
|
+
require 'yaml'
|
5
|
+
opts = YAML.load_file('config/definitions.yml')
|
6
|
+
|
7
|
+
set :application, opts['app']['name']
|
8
|
+
set :repo_url, opts['app']['repo']
|
9
|
+
|
10
|
+
deploy_method = opts['options']['deploy_method'] if opts.has_key?('options') &&
|
11
|
+
opts['options'].has_key?('deploy_method')
|
12
|
+
|
13
|
+
case deploy_method
|
14
|
+
when 'scp'
|
15
|
+
set :scm, :copy
|
16
|
+
else
|
17
|
+
end
|