safer_rails_console 0.1.4 → 0.5.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: cdf260deb3867b5bed0d92646aa88de6f64afd03
4
- data.tar.gz: 3cbaac5740f226b7a0364168f4ab137d080fe1ec
2
+ SHA256:
3
+ metadata.gz: cafff060a5348f7dbabb75a906b6ec0fe610cbf994308be6273aa67fd02e72aa
4
+ data.tar.gz: b13364f0f4eaf4ece0d3eab4ed49e5d50bd9803ca8159f964456cb8c99211694
5
5
  SHA512:
6
- metadata.gz: 470e4da18f0fe1ad4e10df31ae6189f66c7ee58f66389bc8bc3c6d0224f6f8c816dec8d7b94001b22911778bc595a6da7e0de0e3a360c348e29b56de64f7638f
7
- data.tar.gz: a3afb5cc08b8a001879271c7f86b4c78dc5b6cb13d97f2a7602f4ab3ebe96437cc9fb0d22c33ef872fbf9d9daa85e5bd7cc44c43b2e679d2baab112be7c8ef5d
6
+ metadata.gz: 4a7443a5523a213e3728c956100fd988288c32e60b86445504d5d42a3d002042dccfcc8fd8c9fd9faeefa25d45e025b810259d6cd5824d4a23a25266cb27a26f
7
+ data.tar.gz: 3da4c68ff49a4e9f59bd86c8f84e281378dc0d93db3cf31dce6239476d74b67769b6be94602cfa2ebf9d61378a2ab1e986bacfa054bf5a9290096b61614f2679
@@ -0,0 +1,79 @@
1
+ version: 2.1
2
+ jobs:
3
+ lint:
4
+ docker:
5
+ - image: salsify/ruby_ci:2.5.8
6
+ working_directory: ~/safer_rails_console
7
+ steps:
8
+ - checkout
9
+ - restore_cache:
10
+ keys:
11
+ - v2-gems-ruby-2.5.8-{{ checksum "safer_rails_console.gemspec" }}-{{ checksum "Gemfile" }}
12
+ - v2-gems-ruby-2.5.8-
13
+ - run:
14
+ name: Install Gems
15
+ command: |
16
+ if ! bundle check --path=vendor/bundle; then
17
+ bundle install --path=vendor/bundle --jobs=4 --retry=3
18
+ bundle clean
19
+ fi
20
+ - save_cache:
21
+ key: v2-gems-ruby-2.5.8-{{ checksum "safer_rails_console.gemspec" }}-{{ checksum "Gemfile" }}
22
+ paths:
23
+ - "vendor/bundle"
24
+ - "gemfiles/vendor/bundle"
25
+ - run:
26
+ name: Run Rubocop
27
+ command: bundle exec rubocop
28
+ test:
29
+ parameters:
30
+ gemfile:
31
+ type: string
32
+ docker:
33
+ - image: salsify/ruby_ci:2.5.8
34
+ environment:
35
+ CIRCLE_TEST_REPORTS: "test-results"
36
+ BUNDLE_GEMFILE: "/home/circleci/safer_rails_console/<< parameters.gemfile >>"
37
+ - image: circleci/postgres:9.6
38
+ environment:
39
+ POSTGRES_USER: "circleci"
40
+ POSTGRES_DB: "safer_rails_console_test"
41
+ POSTGRES_HOST_AUTH_METHOD: "trust"
42
+ working_directory: ~/safer_rails_console
43
+ steps:
44
+ - checkout
45
+ - restore_cache:
46
+ keys:
47
+ - v2-gems-ruby-2.5.8-{{ checksum "safer_rails_console.gemspec" }}-{{ checksum "<< parameters.gemfile >>" }}
48
+ - v2-gems-ruby-2.5.8-
49
+ - run:
50
+ name: Install Gems
51
+ command: |
52
+ if ! bundle check --path=vendor/bundle; then
53
+ bundle install --path=vendor/bundle --jobs=4 --retry=3
54
+ bundle clean
55
+ fi
56
+ - save_cache:
57
+ key: v2-gems-ruby-2.5.8-{{ checksum "safer_rails_console.gemspec" }}-{{ checksum "<< parameters.gemfile >>" }}
58
+ paths:
59
+ - "vendor/bundle"
60
+ - "gemfiles/vendor/bundle"
61
+ - run:
62
+ name: Run Tests
63
+ command: |
64
+ bundle exec rspec --format RspecJunitFormatter --out $CIRCLE_TEST_REPORTS/rspec/junit.xml --format progress spec
65
+ - store_test_results:
66
+ path: "test-results"
67
+ workflows:
68
+ build:
69
+ jobs:
70
+ - lint
71
+ - test:
72
+ matrix:
73
+ parameters:
74
+ gemfile:
75
+ - "gemfiles/5.0.gemfile"
76
+ - "gemfiles/5.1.gemfile"
77
+ - "gemfiles/5.2.gemfile"
78
+ - "gemfiles/6.0.gemfile"
79
+ - "gemfiles/6.1.gemfile"
data/.gitignore CHANGED
@@ -13,3 +13,5 @@
13
13
 
14
14
  # Appraisal gemfile.lock
15
15
  /gemfiles/*.gemfile.lock
16
+ out
17
+ *.sqlite3
@@ -1,2 +1,11 @@
1
1
  inherit_gem:
2
2
  salsify_rubocop: conf/rubocop_rails.yml
3
+
4
+ AllCops:
5
+ TargetRubyVersion: 2.4
6
+ Exclude:
7
+ - 'vendor/**/*'
8
+ - 'gemfiles/vendor/**/*'
9
+
10
+ Style/FrozenStringLiteralComment:
11
+ Enabled: true
data/Appraisals CHANGED
@@ -1,10 +1,4 @@
1
- appraise '4.1' do
2
- gem 'rails', '~> 4.1.0'
3
- end
4
-
5
- appraise '4.2' do
6
- gem 'rails', '~> 4.2.0'
7
- end
1
+ # frozen_string_literal: true
8
2
 
9
3
  appraise '5.0' do
10
4
  gem 'rails', '~> 5.0.0'
@@ -13,3 +7,15 @@ end
13
7
  appraise '5.1' do
14
8
  gem 'rails', '~> 5.1.0'
15
9
  end
10
+
11
+ appraise '5.2' do
12
+ gem 'rails', '~> 5.2.0'
13
+ end
14
+
15
+ appraise '6.0' do
16
+ gem 'rails', '~> 6.0.0'
17
+ end
18
+
19
+ appraise '6.1' do
20
+ gem 'rails', '~> 6.1.0'
21
+ end
@@ -1,6 +1,59 @@
1
- # Change Log
1
+ # Changelog
2
+
3
+ ## [v0.4.1](https://github.com/salsify/safer_rails_console/tree/v0.4.1) (2020-10-13)
4
+
5
+ [Full Changelog](https://github.com/salsify/safer_rails_console/compare/v0.4.0...v0.4.1)
6
+
7
+ **Closed issues:**
8
+
9
+ - No default settings for rails 5.1 and 5.2 [\#29](https://github.com/salsify/safer_rails_console/issues/29)
10
+
11
+ **Merged pull requests:**
12
+
13
+ - Bump version v0.4.1 [\#33](https://github.com/salsify/safer_rails_console/pull/33) ([alexsalsify](https://github.com/alexsalsify))
14
+ - Add support for config values from ENV variables [\#32](https://github.com/salsify/safer_rails_console/pull/32) ([alexsalsify](https://github.com/alexsalsify))
15
+
16
+ ## [v0.4.0](https://github.com/salsify/safer_rails_console/tree/v0.4.0) (2019-09-19)
17
+
18
+ [Full Changelog](https://github.com/salsify/safer_rails_console/compare/v0.3.0...v0.4.0)
19
+
20
+ **Closed issues:**
21
+
22
+ - safer\_rails\_console breaks newrelic reporting [\#23](https://github.com/salsify/safer_rails_console/issues/23)
23
+
24
+ **Merged pull requests:**
25
+
26
+ - Rails 6.0 support [\#27](https://github.com/salsify/safer_rails_console/pull/27) ([jturkel](https://github.com/jturkel))
27
+ - Drop Rails 4.2 support [\#26](https://github.com/salsify/safer_rails_console/pull/26) ([jturkel](https://github.com/jturkel))
28
+ - Resolve sqlite3 dependency warning [\#11](https://github.com/salsify/safer_rails_console/pull/11) ([timothysu](https://github.com/timothysu))
29
+
30
+ ## [v0.3.0](https://github.com/salsify/safer_rails_console/tree/v0.3.0) (2018-04-16)
31
+
32
+ [Full Changelog](https://github.com/salsify/safer_rails_console/compare/v0.2.0...v0.3.0)
33
+
34
+ **Merged pull requests:**
35
+
36
+ - Add support for Rails 5.2; remove support for Rails 4.1 [\#24](https://github.com/salsify/safer_rails_console/pull/24) ([timothysu](https://github.com/timothysu))
37
+ - Patch PostgreSQLAdapter\#execute\_and\_clear instead of AbstractAdapter\#log for auto-rollback [\#15](https://github.com/salsify/safer_rails_console/pull/15) ([timothysu](https://github.com/timothysu))
38
+
39
+ ## [v0.2.0](https://github.com/salsify/safer_rails_console/tree/v0.2.0) (2017-09-07)
40
+
41
+ [Full Changelog](https://github.com/salsify/safer_rails_console/compare/v0.1.4...v0.2.0)
42
+
43
+ **Implemented enhancements:**
44
+
45
+ - Sandbox mode should make it clear that edits don't stick [\#19](https://github.com/salsify/safer_rails_console/issues/19)
46
+ - Writes made in sandbox mode take out DB locks [\#18](https://github.com/salsify/safer_rails_console/issues/18)
47
+ - Confusion over unsandboxed/sandboxed terminology in command prompt [\#17](https://github.com/salsify/safer_rails_console/issues/17)
48
+
49
+ **Merged pull requests:**
50
+
51
+ - Use Postgres for local development too [\#28](https://github.com/salsify/safer_rails_console/pull/28) ([jturkel](https://github.com/jturkel))
52
+ - Set DB transactions to read-only and provide messaging for non-read operations [\#21](https://github.com/salsify/safer_rails_console/pull/21) ([timothysu](https://github.com/timothysu))
53
+ - Change 'sandboxed' and 'unsandboxed' to 'read-only' and 'writable' and add respective flags [\#20](https://github.com/salsify/safer_rails_console/pull/20) ([timothysu](https://github.com/timothysu))
2
54
 
3
55
  ## [v0.1.4](https://github.com/salsify/safer_rails_console/tree/v0.1.4) (2017-08-15)
56
+
4
57
  [Full Changelog](https://github.com/salsify/safer_rails_console/compare/v0.1.3...v0.1.4)
5
58
 
6
59
  **Fixed bugs:**
@@ -8,11 +61,8 @@
8
61
  - Invalid cached and prepared statements do not trigger a automatic rollback with PostgreSQL [\#16](https://github.com/salsify/safer_rails_console/issues/16)
9
62
  - safer\_rails\_console doesn't work in alerts service rails console mode in sandbox mode [\#13](https://github.com/salsify/safer_rails_console/issues/13)
10
63
 
11
- **Merged pull requests:**
12
-
13
- - Patch PostgreSQLAdapter\#execute\_and\_clear instead of AbstractAdapter\#log for auto-rollback [\#15](https://github.com/salsify/safer_rails_console/pull/15) ([timothysu](https://github.com/timothysu))
14
-
15
64
  ## [v0.1.3](https://github.com/salsify/safer_rails_console/tree/v0.1.3) (2017-08-02)
65
+
16
66
  [Full Changelog](https://github.com/salsify/safer_rails_console/compare/v0.1.2...v0.1.3)
17
67
 
18
68
  **Fixed bugs:**
@@ -22,9 +72,9 @@
22
72
  **Merged pull requests:**
23
73
 
24
74
  - Default sandbox flag to nil in Rails 5.1 [\#12](https://github.com/salsify/safer_rails_console/pull/12) ([timothysu](https://github.com/timothysu))
25
- - Resolve sqlite3 dependency warning [\#11](https://github.com/salsify/safer_rails_console/pull/11) ([timothysu](https://github.com/timothysu))
26
75
 
27
76
  ## [v0.1.2](https://github.com/salsify/safer_rails_console/tree/v0.1.2) (2017-07-21)
77
+
28
78
  [Full Changelog](https://github.com/salsify/safer_rails_console/compare/v0.1.1...v0.1.2)
29
79
 
30
80
  **Merged pull requests:**
@@ -32,6 +82,7 @@
32
82
  - Dasherize the app name given CamelCase [\#10](https://github.com/salsify/safer_rails_console/pull/10) ([timothysu](https://github.com/timothysu))
33
83
 
34
84
  ## [v0.1.1](https://github.com/salsify/safer_rails_console/tree/v0.1.1) (2017-07-07)
85
+
35
86
  [Full Changelog](https://github.com/salsify/safer_rails_console/compare/v0.1.0...v0.1.1)
36
87
 
37
88
  **Fixed bugs:**
@@ -43,10 +94,13 @@
43
94
  - Add support for Spring [\#8](https://github.com/salsify/safer_rails_console/pull/8) ([timothysu](https://github.com/timothysu))
44
95
 
45
96
  ## [v0.1.0](https://github.com/salsify/safer_rails_console/tree/v0.1.0) (2017-06-26)
97
+
98
+ [Full Changelog](https://github.com/salsify/safer_rails_console/compare/baddba2bc069bc6d72e779d8c157e19d26b30fc1...v0.1.0)
99
+
46
100
  **Merged pull requests:**
47
101
 
48
102
  - Initial Implementation [\#2](https://github.com/salsify/safer_rails_console/pull/2) ([timothysu](https://github.com/timothysu))
49
103
 
50
104
 
51
105
 
52
- \* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
106
+ \* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in safer_rails_console.gemspec
data/README.md CHANGED
@@ -1,4 +1,7 @@
1
- # SaferRailsConsole [![Build Status](https://travis-ci.org/salsify/safer_rails_console.svg?branch=master)](https://travis-ci.org/salsify/safer_rails_console)
1
+ # SaferRailsConsole
2
+
3
+ [![Build Status](https://circleci.com/gh/salsify/safer_rails_console.svg?style=svg)](https://circleci.com/gh/salsify/safer_rails_console)
4
+ [![Gem Version](https://badge.fury.io/rb/safer_rails_console.svg)](https://badge.fury.io/rb/safer_rails_console)
2
5
 
3
6
  This gem makes Rails console sessions less dangerous in specified environments by warning, color-coding, auto-sandboxing, and allowing read-only external connections (disables job queueing, non-GET requests, etc.)
4
7
 
@@ -27,11 +30,14 @@ require 'safer_rails_console/patches/boot'
27
30
 
28
31
  The quickest way to demo this gem is to run `bundle exec rails console --sandbox`.
29
32
 
30
- A way to explicitly enable or disable the sandbox is added to Rails console as a flag with the last install step.
33
+ Several ways to explicitly enable or disable the sandbox are added to Rails console as flags with the last install step. The order of precedence is `-s`, `-r`, then `-w` if multiple sandbox related flags are specified.
31
34
  ```ruby
32
35
  bundle exec rails console --help
33
36
 
37
+ Usage: rails console [environment] [options]
34
38
  -s, --[no-]sandbox Explicitly enable/disable sandbox mode.
39
+ -w, --writable Alias for --no-sandbox.
40
+ -r, --read-only Alias for --sandbox.
35
41
  -e, --environment=name Specifies the environment to run this console under (test/development/production).
36
42
  Default: development
37
43
  --debugger Enable the debugger.
@@ -70,6 +76,24 @@ config.safer_rails_console.warn_text = "WARNING: YOU ARE USING RAILS CONSOLE IN
70
76
  'Make sure you know what you\'re doing.'
71
77
  ```
72
78
 
79
+ configuration settings can also be overridden using ENV variables. The following ENV vars can be used:
80
+ ```
81
+ # Set the color prompt to a new color. See colors.rb for a listing of supported colors.
82
+ SAFER_RAILS_CONSOLE_PROMPT_COLOR=red/yellow/green
83
+
84
+ # Set the short name for the rails console prompt
85
+ SAFER_RAILS_CONSOLE_ENVIRONMENT_NAME=short-name
86
+
87
+ # Set the warning text to be displayed when warning for the environments rails consoled is enabled
88
+ SAFER_RAILS_CONSOLE_WARN_TEXT=New warning prompt text
89
+
90
+ # Enable or disable sandboxing of the rails console
91
+ SAFER_RAILS_CONSOLE_SANDBOX_ENVIRONMENT=true/false
92
+
93
+ # Enable or disable warning prompt of the rails console
94
+ SAFER_RAILS_CONSOLE_WARN_ENVIRONMENT=true/false
95
+ ```
96
+
73
97
  ## Development
74
98
 
75
99
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `wwtd` to simulate the entire build matrix (ruby version / rails version) or `appraisal` to test against each supported rails version with your active ruby version. Run `rubocop` to check for style.
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/gem_tasks'
2
4
  require 'rspec/core/rake_task'
3
5
  require 'rails'
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require "bundler/setup"
4
- require "safer_rails_console"
4
+ require 'bundler/setup'
5
+ require 'safer_rails_console'
5
6
 
6
7
  # You can add fixtures and/or initialization code here to make experimenting
7
8
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +11,5 @@ require "safer_rails_console"
10
11
  # require "pry"
11
12
  # Pry.start
12
13
 
13
- require "irb"
14
+ require 'irb'
14
15
  IRB.start(__FILE__)
@@ -2,6 +2,6 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "rails", "~> 4.1.0"
5
+ gem "rails", "~> 5.2.0"
6
6
 
7
7
  gemspec path: "../"
@@ -2,6 +2,6 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "rails", "~> 4.2.0"
5
+ gem "rails", "~> 6.0.0"
6
6
 
7
7
  gemspec path: "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", "~> 6.1.0"
6
+
7
+ gemspec path: "../"
@@ -1,25 +1,52 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'safer_rails_console/version'
2
4
  require 'safer_rails_console/railtie'
3
5
  require 'safer_rails_console/colors'
4
6
  require 'safer_rails_console/rails_version'
5
7
  require 'safer_rails_console/console'
8
+ require 'active_model/type'
6
9
 
7
10
  module SaferRailsConsole
8
11
  class << self
9
12
  def environment_name
10
- config.environment_names.key?(::Rails.env.downcase) ? config.environment_names[::Rails.env.downcase] : 'unknown env'
13
+ if ENV.key?('SAFER_RAILS_CONSOLE_ENVIRONMENT_NAME')
14
+ ENV['SAFER_RAILS_CONSOLE_ENVIRONMENT_NAME']
15
+ else
16
+ config.environment_names.key?(::Rails.env.downcase) ? config.environment_names[::Rails.env.downcase] : 'unknown env'
17
+ end
11
18
  end
12
19
 
13
20
  def prompt_color
14
- config.environment_prompt_colors.key?(::Rails.env.downcase) ? config.environment_prompt_colors[::Rails.env.downcase] : SaferRailsConsole::Colors::NONE
21
+ if ENV.key?('SAFER_RAILS_CONSOLE_PROMPT_COLOR')
22
+ SaferRailsConsole::Colors.const_get(ENV['SAFER_RAILS_CONSOLE_PROMPT_COLOR'].upcase)
23
+ else
24
+ config.environment_prompt_colors.key?(::Rails.env.downcase) ? config.environment_prompt_colors[::Rails.env.downcase] : SaferRailsConsole::Colors::NONE
25
+ end
15
26
  end
16
27
 
17
28
  def sandbox_environment?
18
- config.sandbox_environments.include?(::Rails.env.downcase)
29
+ if ENV.key?('SAFER_RAILS_CONSOLE_SANDBOX_ENVIRONMENT')
30
+ ActiveModel::Type::Boolean.new.cast(ENV['SAFER_RAILS_CONSOLE_SANDBOX_ENVIRONMENT'])
31
+ else
32
+ config.sandbox_environments.include?(::Rails.env.downcase)
33
+ end
19
34
  end
20
35
 
21
36
  def warn_environment?
22
- config.warn_environments.include?(::Rails.env.downcase)
37
+ if ENV.key?('SAFER_RAILS_CONSOLE_WARN_ENVIRONMENT')
38
+ ActiveModel::Type::Boolean.new.cast(ENV['SAFER_RAILS_CONSOLE_WARN_ENVIRONMENT'])
39
+ else
40
+ config.warn_environments.include?(::Rails.env.downcase)
41
+ end
42
+ end
43
+
44
+ def warn_text
45
+ if ENV.key?('SAFER_RAILS_CONSOLE_WARN_TEXT')
46
+ ENV['SAFER_RAILS_CONSOLE_WARN_TEXT']
47
+ else
48
+ config.warn_text
49
+ end
23
50
  end
24
51
 
25
52
  def config
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SaferRailsConsole
2
4
  module Colors
3
5
  NONE = 0
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SaferRailsConsole
2
4
  module Console
3
5
  class << self
@@ -8,7 +10,7 @@ module SaferRailsConsole
8
10
  end
9
11
 
10
12
  def print_warning
11
- puts color_text(SaferRailsConsole.config.warn_text, SaferRailsConsole.prompt_color) # rubocop:disable Rails/Output
13
+ puts color_text(SaferRailsConsole.warn_text, SaferRailsConsole.prompt_color) # rubocop:disable Rails/Output
12
14
  end
13
15
 
14
16
  def load_config
@@ -1,8 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  include SaferRailsConsole::Colors
2
4
 
3
- app_name = ::Rails.application.class.parent.to_s.underscore.dasherize
5
+ app_name = if SaferRailsConsole::RailsVersion.six_or_above?
6
+ ::Rails.application.class.module_parent.to_s.underscore.dasherize
7
+ else
8
+ ::Rails.application.class.parent.to_s.underscore.dasherize
9
+ end
4
10
  env_name = SaferRailsConsole.environment_name
5
- status = ::Rails.application.sandbox ? 'sandboxed' : 'unsandboxed'
11
+ status = ::Rails.application.sandbox ? 'read-only' : 'writable'
6
12
  color = SaferRailsConsole.prompt_color
7
13
 
8
14
  prompt = "#{app_name}(#{env_name})(#{status}):%03n:%i"
@@ -12,7 +18,7 @@ IRB.conf[:PROMPT][:RAILS_ENV] = {
12
18
  PROMPT_N: color_text("#{prompt}> ", color),
13
19
  PROMPT_S: color_text("#{prompt}%l ", color),
14
20
  PROMPT_C: color_text("#{prompt}* ", color),
15
- RETURN: color_text('=> ', color).concat("%s\n")
21
+ RETURN: "#{color_text('=> ', color)}%s\n"
16
22
  }
17
23
 
18
24
  IRB.conf[:PROMPT_MODE] = :RAILS_ENV
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  Dir[File.join(__dir__, 'boot', '*.rb')].each { |file| require file }
@@ -1,45 +1,22 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'safer_rails_console/rails_version'
2
4
 
3
5
  module SaferRailsConsole
4
6
  module Patches
5
7
  module Boot
6
8
  module SandboxFlag
7
- module Rails
8
- module CommandsTasks4
9
- def console
10
- require_command!('console')
11
- ::Rails::Console.singleton_class.prepend(::SaferRailsConsole::Patches::Boot::SandboxFlag::Rails::Console4)
12
- super
13
- end
14
- end
15
-
16
- module Console4
17
- def parse_arguments(arguments)
18
- options = {}
19
-
20
- OptionParser.new do |opt|
21
- opt.banner = 'Usage: rails console [environment] [options]'
22
- opt.on('-s', '--[no-]sandbox', 'Explicitly enable/disable sandbox mode.') { |v| options[:sandbox] = v }
23
- opt.on('-e', '--environment=name', String,
24
- 'Specifies the environment to run this console under (test/development/production).',
25
- 'Default: development') { |v| options[:environment] = v.strip }
26
- opt.on('--debugger', 'Enable the debugger.') { |v| options[:debugger] = v }
27
- opt.parse!(arguments)
28
- end
29
-
30
- if arguments.first && arguments.first[0] != '-'
31
- env = arguments.first
32
- options[:environment] = if available_environments.include? env
33
- env
34
- else
35
- %w(production development test).detect { |e| e =~ /^#{env}/ } || env
36
- end
37
- end
38
-
39
- options
40
- end
41
- end
9
+ def self.console_options(opt, options = {})
10
+ opt.banner = 'Usage: rails console [environment] [options]'
11
+ opt.on('-s', '--[no-]sandbox', 'Explicitly enable/disable sandbox mode.') { |v| options[:sandbox] = v }
12
+ opt.on('-w', '--writable', 'Alias for --no-sandbox.') { |v| options[:writable] = v }
13
+ opt.on('-r', '--read-only', 'Alias for --sandbox.') { |v| options[:'read-only'] = v }
14
+ opt.on('-e', '--environment=name', String,
15
+ 'Specifies the environment to run this console under (test/development/production).',
16
+ 'Default: development') { |v| options[:environment] = v.strip }
17
+ end
42
18
 
19
+ module Rails
43
20
  module CommandsTasks50
44
21
  def console
45
22
  require_command!('console')
@@ -53,11 +30,7 @@ module SaferRailsConsole
53
30
  options = {}
54
31
 
55
32
  OptionParser.new do |opt|
56
- opt.banner = 'Usage: rails console [environment] [options]'
57
- opt.on('-s', '--[no-]sandbox', 'Explicitly enable/disable sandbox mode.') { |v| options[:sandbox] = v }
58
- opt.on('-e', '--environment=name', String,
59
- 'Specifies the environment to run this console under (test/development/production).',
60
- 'Default: development') { |v| options[:environment] = v.strip }
33
+ ::SaferRailsConsole::Patches::Boot::SandboxFlag.console_options(opt, options)
61
34
  opt.parse!(arguments)
62
35
  end
63
36
 
@@ -70,19 +43,18 @@ module SaferRailsConsole
70
43
  end
71
44
  end
72
45
 
73
- if SaferRailsConsole::RailsVersion.four_one? || SaferRailsConsole::RailsVersion.four_two?
74
- require 'rails/commands/commands_tasks'
75
- ::Rails::CommandsTasks.prepend(SaferRailsConsole::Patches::Boot::SandboxFlag::Rails::CommandsTasks4)
76
- elsif SaferRailsConsole::RailsVersion.five_zero?
46
+ if SaferRailsConsole::RailsVersion.five_zero?
77
47
  require 'rails/commands/commands_tasks'
78
48
  ::Rails::CommandsTasks.prepend(SaferRailsConsole::Patches::Boot::SandboxFlag::Rails::CommandsTasks50)
79
- elsif SaferRailsConsole::RailsVersion.five_one?
49
+ elsif SaferRailsConsole::RailsVersion.five_one_or_above?
80
50
  require 'rails/command'
81
51
  require 'rails/commands/console/console_command'
82
- # Rails 5.1 defaults `sandbox` to `false`, but we need it to NOT have a default value and be `nil` when it is not user-specified
52
+ # Rails 5.1 and 5.2 defaults `sandbox` to `false`, but we need it to NOT have a default value and be `nil` when it is not user-specified
83
53
  ::Rails::Command::ConsoleCommand.class_eval do
84
54
  remove_class_option :sandbox
85
55
  class_option :sandbox, aliases: '-s', type: :boolean, desc: 'Explicitly enable/disable sandbox mode.'
56
+ class_option :writable, aliases: '-w', type: :boolean, desc: 'Alias for --no-sandbox.'
57
+ class_option :'read-only', aliases: '-r', type: :boolean, desc: 'Alias for --sandbox.'
86
58
  end
87
59
  else
88
60
  unless SaferRailsConsole::RailsVersion.supported?
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  Dir[File.join(__dir__, 'railtie', '*.rb')].each { |file| require file }
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SaferRailsConsole
2
4
  module Patches
3
5
  module Sandbox
@@ -6,8 +8,15 @@ module SaferRailsConsole
6
8
  def start(*args)
7
9
  options = args.last
8
10
 
9
- options[:sandbox] = SaferRailsConsole.sandbox_environment? if options[:sandbox].nil?
10
- options[:sandbox] = SaferRailsConsole::Console.sandbox_user_prompt if SaferRailsConsole.sandbox_environment? && SaferRailsConsole.config.sandbox_prompt
11
+ if options[:sandbox].nil?
12
+ options[:sandbox] = if options[:'read-only']
13
+ true
14
+ elsif options[:writable]
15
+ false
16
+ else
17
+ SaferRailsConsole.sandbox_environment? && SaferRailsConsole.config.sandbox_prompt ? SaferRailsConsole::Console.sandbox_user_prompt : SaferRailsConsole.sandbox_environment?
18
+ end
19
+ end
11
20
 
12
21
  super *args
13
22
  end
@@ -18,7 +27,7 @@ module SaferRailsConsole
18
27
  end
19
28
 
20
29
  if SaferRailsConsole::RailsVersion.supported?
21
- if SaferRailsConsole::RailsVersion.five_one?
30
+ if SaferRailsConsole::RailsVersion.five_one_or_above?
22
31
  require 'rails/commands/console/console_command'
23
32
  else
24
33
  require 'rails/commands/console'
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  Dir[File.join(__dir__, 'sandbox', '*.rb')].each { |file| require file }
@@ -1,46 +1,34 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SaferRailsConsole
2
4
  module Patches
3
5
  module Sandbox
4
6
  module AutoRollback
7
+ extend SaferRailsConsole::Colors
8
+
5
9
  def self.rollback_and_begin_new_transaction
6
10
  connection = ::ActiveRecord::Base.connection
7
11
  connection.rollback_db_transaction
8
12
  connection.begin_db_transaction
9
13
  end
10
14
 
11
- module ActiveRecord
12
- module ConnectionAdapters
13
- module PostgreSQLAdapter41
14
- def exec_no_cache(sql, name, binds)
15
- super
16
- rescue => e
17
- SaferRailsConsole::Patches::Sandbox::AutoRollback.rollback_and_begin_new_transaction
18
- raise e
19
- end
20
-
21
- def exec_cache(sql, name, binds)
22
- super
23
- rescue => e
24
- SaferRailsConsole::Patches::Sandbox::AutoRollback.rollback_and_begin_new_transaction
25
- raise e
26
- end
27
- end
15
+ def self.handle_and_reraise_exception(e)
16
+ if e.message.include?('PG::ReadOnlySqlTransaction')
17
+ puts color_text('An operation could not be completed due to read-only mode.', RED) # rubocop:disable Rails/Output
18
+ else
19
+ rollback_and_begin_new_transaction
20
+ end
28
21
 
29
- module PostgreSQLAdapter42
30
- def execute_and_clear(sql, name, binds)
31
- super
32
- rescue => e
33
- SaferRailsConsole::Patches::Sandbox::AutoRollback.rollback_and_begin_new_transaction
34
- raise e
35
- end
36
- end
22
+ raise e
23
+ end
37
24
 
25
+ module ActiveRecord
26
+ module ConnectionAdapters
38
27
  module PostgreSQLAdapter5
39
28
  def execute_and_clear(sql, name, binds, prepare: false)
40
29
  super
41
30
  rescue => e
42
- SaferRailsConsole::Patches::Sandbox::AutoRollback.rollback_and_begin_new_transaction
43
- raise e
31
+ SaferRailsConsole::Patches::Sandbox::AutoRollback.handle_and_reraise_exception(e)
44
32
  end
45
33
  end
46
34
  end
@@ -51,11 +39,5 @@ module SaferRailsConsole
51
39
  end
52
40
 
53
41
  if defined?(::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
54
- if SaferRailsConsole::RailsVersion.four_one?
55
- ::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(SaferRailsConsole::Patches::Sandbox::AutoRollback::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter41)
56
- elsif SaferRailsConsole::RailsVersion.four_two?
57
- ::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(SaferRailsConsole::Patches::Sandbox::AutoRollback::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter42)
58
- else
59
- ::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(SaferRailsConsole::Patches::Sandbox::AutoRollback::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter5)
60
- end
42
+ ::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(SaferRailsConsole::Patches::Sandbox::AutoRollback::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter5)
61
43
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SaferRailsConsole
4
+ module Patches
5
+ module Sandbox
6
+ module TransactionReadOnly
7
+ module ActiveRecord
8
+ module ConnectionAdapters
9
+ module PostgreSQLAdapter
10
+ def begin_db_transaction
11
+ super
12
+ execute 'SET TRANSACTION READ ONLY'
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ if defined?(::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
23
+ ::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(SaferRailsConsole::Patches::Sandbox::TransactionReadOnly::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
24
+
25
+ # Ensure transaction is read-only if it was began before this patch was loaded
26
+ connection = ::ActiveRecord::Base.connection
27
+ connection.execute 'SET TRANSACTION READ ONLY' if connection.open_transactions > 0
28
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rails'
2
4
 
3
5
  module SaferRailsConsole
@@ -6,17 +8,7 @@ module SaferRailsConsole
6
8
 
7
9
  class << self
8
10
  def supported?
9
- four_one? || four_two? || five_zero? || five_one?
10
- end
11
-
12
- def four_one?
13
- @is_four_one = Gem::Requirement.new('~> 4.1.0').satisfied_by?(SaferRailsConsole::RailsVersion::RAILS_VERSION) if @is_four_one.nil?
14
- @is_four_one
15
- end
16
-
17
- def four_two?
18
- @is_four_two = Gem::Requirement.new('~> 4.2.0').satisfied_by?(SaferRailsConsole::RailsVersion::RAILS_VERSION) if @is_four_two.nil?
19
- @is_four_two
11
+ five_zero? || five_one? || five_two? || six_or_above?
20
12
  end
21
13
 
22
14
  def five_zero?
@@ -28,6 +20,26 @@ module SaferRailsConsole
28
20
  @is_five_one = Gem::Requirement.new('~> 5.1.0').satisfied_by?(SaferRailsConsole::RailsVersion::RAILS_VERSION) if @is_five_one.nil?
29
21
  @is_five_one
30
22
  end
23
+
24
+ def five_one_or_above?
25
+ @is_five_one_or_above = SaferRailsConsole::RailsVersion::RAILS_VERSION >= ::Gem::Version.new('5.1.0') if @is_five_one_or_above.nil?
26
+ @is_five_one_or_above
27
+ end
28
+
29
+ def five_two?
30
+ @is_five_two = Gem::Requirement.new('~> 5.2.0').satisfied_by?(SaferRailsConsole::RailsVersion::RAILS_VERSION) if @is_five_two.nil?
31
+ @is_five_two
32
+ end
33
+
34
+ def six_zero?
35
+ @is_six_zero = Gem::Requirement.new('~> 6.0.0').satisfied_by?(SaferRailsConsole::RailsVersion::RAILS_VERSION) if @is_six_zero.nil?
36
+ @is_six_zero
37
+ end
38
+
39
+ def six_or_above?
40
+ @is_six_or_above = SaferRailsConsole::RailsVersion::RAILS_VERSION >= ::Gem::Version.new('6.0.0') if @is_six_or_above.nil?
41
+ @is_six_or_above
42
+ end
31
43
  end
32
44
  end
33
45
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rails'
2
4
  require 'safer_rails_console'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SaferRailsConsole
2
- VERSION = '0.1.4'.freeze
4
+ VERSION = '0.5.0'
3
5
  end
@@ -1,4 +1,5 @@
1
1
  # coding: utf-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  lib = File.expand_path('../lib', __FILE__)
4
5
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
@@ -31,14 +32,15 @@ Gem::Specification.new do |spec|
31
32
  spec.require_paths = ['lib']
32
33
 
33
34
  spec.add_development_dependency 'appraisal', '~> 2.2'
34
- spec.add_development_dependency 'bundler', '~> 1.15'
35
+ spec.add_development_dependency 'bundler', '~> 2.0'
36
+ spec.add_development_dependency 'climate_control', '~> 0.2.0'
35
37
  spec.add_development_dependency 'mixlib-shellout', '~> 2.2'
36
38
  spec.add_development_dependency 'overcommit', '~> 0.39.0'
37
- spec.add_development_dependency 'pg', '~> 0.21'
39
+ spec.add_development_dependency 'pg', '~> 1.1'
38
40
  spec.add_development_dependency 'rake', '~> 12.0'
39
41
  spec.add_development_dependency 'rspec', '~> 3.6'
42
+ spec.add_development_dependency 'rspec_junit_formatter'
40
43
  spec.add_development_dependency 'salsify_rubocop', '~> 0.48.0'
41
- spec.add_development_dependency 'sqlite3', '~> 1.3'
42
- spec.add_development_dependency 'wwtd', '~> 1.3'
43
- spec.add_runtime_dependency 'rails', '>= 4.1', '< 5.2'
44
+
45
+ spec.add_runtime_dependency 'rails', '>= 5.0', '< 6.2'
44
46
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: safer_rails_console
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Salsify, Inc
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-08-15 00:00:00.000000000 Z
11
+ date: 2020-12-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: appraisal
@@ -30,14 +30,28 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.15'
33
+ version: '2.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.15'
40
+ version: '2.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: climate_control
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.2.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.2.0
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: mixlib-shellout
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -72,14 +86,14 @@ dependencies:
72
86
  requirements:
73
87
  - - "~>"
74
88
  - !ruby/object:Gem::Version
75
- version: '0.21'
89
+ version: '1.1'
76
90
  type: :development
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
94
  - - "~>"
81
95
  - !ruby/object:Gem::Version
82
- version: '0.21'
96
+ version: '1.1'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: rake
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -109,67 +123,53 @@ dependencies:
109
123
  - !ruby/object:Gem::Version
110
124
  version: '3.6'
111
125
  - !ruby/object:Gem::Dependency
112
- name: salsify_rubocop
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - "~>"
116
- - !ruby/object:Gem::Version
117
- version: 0.48.0
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - "~>"
123
- - !ruby/object:Gem::Version
124
- version: 0.48.0
125
- - !ruby/object:Gem::Dependency
126
- name: sqlite3
126
+ name: rspec_junit_formatter
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - "~>"
129
+ - - ">="
130
130
  - !ruby/object:Gem::Version
131
- version: '1.3'
131
+ version: '0'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
- - - "~>"
136
+ - - ">="
137
137
  - !ruby/object:Gem::Version
138
- version: '1.3'
138
+ version: '0'
139
139
  - !ruby/object:Gem::Dependency
140
- name: wwtd
140
+ name: salsify_rubocop
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - "~>"
144
144
  - !ruby/object:Gem::Version
145
- version: '1.3'
145
+ version: 0.48.0
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
- version: '1.3'
152
+ version: 0.48.0
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: rails
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
157
  - - ">="
158
158
  - !ruby/object:Gem::Version
159
- version: '4.1'
159
+ version: '5.0'
160
160
  - - "<"
161
161
  - !ruby/object:Gem::Version
162
- version: '5.2'
162
+ version: '6.2'
163
163
  type: :runtime
164
164
  prerelease: false
165
165
  version_requirements: !ruby/object:Gem::Requirement
166
166
  requirements:
167
167
  - - ">="
168
168
  - !ruby/object:Gem::Version
169
- version: '4.1'
169
+ version: '5.0'
170
170
  - - "<"
171
171
  - !ruby/object:Gem::Version
172
- version: '5.2'
172
+ version: '6.2'
173
173
  description: This gem makes Rails console sessions less dangerous in specified environments
174
174
  by warning, color-coding, auto-sandboxing, and allowing read-only external connections
175
175
  (disables job queueing, non-GET requests, etc.)
@@ -179,11 +179,11 @@ executables: []
179
179
  extensions: []
180
180
  extra_rdoc_files: []
181
181
  files:
182
+ - ".circleci/config.yml"
182
183
  - ".gitignore"
183
184
  - ".overcommit.yml"
184
185
  - ".rspec"
185
186
  - ".rubocop.yml"
186
- - ".travis.yml"
187
187
  - Appraisals
188
188
  - CHANGELOG.md
189
189
  - Gemfile
@@ -192,10 +192,11 @@ files:
192
192
  - Rakefile
193
193
  - bin/console
194
194
  - bin/setup
195
- - gemfiles/4.1.gemfile
196
- - gemfiles/4.2.gemfile
197
195
  - gemfiles/5.0.gemfile
198
196
  - gemfiles/5.1.gemfile
197
+ - gemfiles/5.2.gemfile
198
+ - gemfiles/6.0.gemfile
199
+ - gemfiles/6.1.gemfile
199
200
  - lib/safer_rails_console.rb
200
201
  - lib/safer_rails_console/colors.rb
201
202
  - lib/safer_rails_console/console.rb
@@ -206,6 +207,7 @@ files:
206
207
  - lib/safer_rails_console/patches/railtie/sandbox.rb
207
208
  - lib/safer_rails_console/patches/sandbox.rb
208
209
  - lib/safer_rails_console/patches/sandbox/auto_rollback.rb
210
+ - lib/safer_rails_console/patches/sandbox/transaction_read_only.rb
209
211
  - lib/safer_rails_console/rails_version.rb
210
212
  - lib/safer_rails_console/railtie.rb
211
213
  - lib/safer_rails_console/version.rb
@@ -215,7 +217,7 @@ licenses:
215
217
  - MIT
216
218
  metadata:
217
219
  allowed_push_host: https://rubygems.org
218
- post_install_message:
220
+ post_install_message:
219
221
  rdoc_options: []
220
222
  require_paths:
221
223
  - lib
@@ -230,9 +232,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
230
232
  - !ruby/object:Gem::Version
231
233
  version: '0'
232
234
  requirements: []
233
- rubyforge_project:
234
- rubygems_version: 2.6.12
235
- signing_key:
235
+ rubygems_version: 3.0.8
236
+ signing_key:
236
237
  specification_version: 4
237
238
  summary: Make rails console less dangerous!
238
239
  test_files: []
@@ -1,37 +0,0 @@
1
- language: ruby
2
- sudo: false
3
-
4
- services:
5
- - postgresql
6
-
7
- bundler_args: --without test --jobs 3 --retry 3
8
- before_install:
9
- - gem install bundler
10
-
11
- before_script:
12
- - cp spec/internal/database.yml.travis spec/internal/rails_4_1/config/database.yml
13
- - cp spec/internal/database.yml.travis spec/internal/rails_4_2/config/database.yml
14
- - cp spec/internal/database.yml.travis spec/internal/rails_5_0/config/database.yml
15
- - cp spec/internal/database.yml.travis spec/internal/rails_5_1/config/database.yml
16
-
17
- script:
18
- - bundle exec rubocop
19
- - bundle exec rspec
20
-
21
- rvm:
22
- - 2.2.7
23
- - 2.3.4
24
- - 2.4.1
25
-
26
- gemfile:
27
- - gemfiles/4.1.gemfile
28
- - gemfiles/4.2.gemfile
29
- - gemfiles/5.0.gemfile
30
- - gemfiles/5.1.gemfile
31
-
32
- matrix:
33
- allow_failures:
34
- - gemfile: gemfiles/4.1.gemfile
35
- rvm: 2.4.1
36
-
37
- fast_finish: true