Skip to content

Commit efc0153

Browse files
committed
- Add ability to choose a different formatter (internal, none, shfmt)
1 parent 406a86a commit efc0153

File tree

9 files changed

+92
-12
lines changed

9 files changed

+92
-12
lines changed

lib/bashly.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ module Bashly
2222
module Script
2323
autoloads 'bashly/script', %i[
2424
Argument Base CatchAll Command Dependency EnvironmentVariable Flag
25-
Variable Wrapper
25+
Formatter Variable Wrapper
2626
]
2727

2828
module Introspection

lib/bashly/exceptions.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ class Interrupt < Interrupt; end
33
class Error < StandardError; end
44
class InitError < Error; end
55
class ConfigurationError < Error; end
6+
class DependencyError < Error; end
67
end

lib/bashly/extensions/string.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ def wrap(length = 80)
4444
end * "\n"
4545
end
4646

47-
def lint
48-
gsub(/\s+\n/m, "\n\n").lines.grep_v(/^\s*##/).join
47+
def remove_private_comments
48+
lines.grep_v(/^\s*##/).join
4949
end
5050

5151
def remove_front_matter

lib/bashly/libraries/settings/settings.yml

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,22 @@ partials_extension: sh
4141
#-------------------------------------------------------------------------------
4242

4343
# Configure the bash options that will be added to the initialize function:
44-
# strict: true Bash strict mode (set -euo pipefail)
45-
# strict: false Only exit on errors (set -e)
46-
# strict: '' Do not add any 'set' directive
47-
# strict: <string> Add any other custom 'set' directive
44+
# strict: true # Bash strict mode (set -euo pipefail)
45+
# strict: false # Only exit on errors (set -e)
46+
# strict: '' # Do not add any 'set' directive
47+
# strict: <string> # Add any other custom 'set' directive
4848
strict: false
4949

5050
# When true, the generated script will use tab indentation instead of spaces
5151
# (every 2 leading spaces will be converted to a tab character)
5252
tab_indent: false
5353

54+
# Choose a post-processor for the generated script:
55+
# formatter: internal # Use Bashly's internal formatter (compacts newlines)
56+
# formatter: none # Disable all post-processing
57+
# formatter: shfmt # Use shfmt if installed
58+
formatter: internal
59+
5460

5561
#-------------------------------------------------------------------------------
5662
# INTERFACE OPTIONS
@@ -100,10 +106,10 @@ env: development
100106

101107
# Tweak the script output by enabling or disabling some script output.
102108
# These options accept one of the following strings:
103-
# - production render this feature only when env == production
104-
# - development render this feature only when env == development
105-
# - always render this feature in any environment
106-
# - never do not render this feature
109+
# - production # render this feature only when env == production
110+
# - development # render this feature only when env == development
111+
# - always # render this feature in any environment
112+
# - never # do not render this feature
107113
enable_header_comment: always
108114
enable_bash3_bouncer: always
109115
enable_view_markers: development

lib/bashly/script/formatter.rb

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
require 'open3'
2+
3+
module Bashly
4+
module Script
5+
class Formatter
6+
MODES = %i[internal none shfmt]
7+
8+
attr_reader :script, :mode
9+
10+
def initialize(script, mode: nil)
11+
@script = script
12+
@mode = MODES.include?(mode&.to_sym) ? mode.to_sym : MODES.first
13+
end
14+
15+
def formatted_script
16+
case mode
17+
when :internal then script.gsub(/\s+\n/m, "\n\n")
18+
when :shfmt then shfmt_result
19+
else script
20+
end
21+
end
22+
23+
private
24+
25+
def shfmt_result
26+
unless system 'command -v shfmt > /dev/null 2>&1'
27+
raise DependencyError,
28+
'Cannot find g`shfmt`.\nEither install it or change to the g`internal` formatter.'
29+
end
30+
31+
output, error, status =
32+
Open3.capture3 %w[shfmt --case-indent --indent 2], stdin_data: script
33+
34+
raise DependencyError, "Failed running g`shfmt`:\n\n#{error}" unless status.success?
35+
36+
output
37+
end
38+
end
39+
end
40+
end

lib/bashly/script/wrapper.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,13 @@ def base_code
2323
[header, body]
2424
end
2525

26-
result.join("\n").lint
26+
clean_code result.join("\n")
27+
end
28+
29+
def clean_code(script)
30+
script.remove_private_comments
31+
formatter = Formatter.new script, mode: Settings.formatter
32+
formatter.formatted_script
2733
end
2834

2935
def header

lib/bashly/settings.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class << self
1515
:enable_inspect_args,
1616
:enable_sourcing,
1717
:enable_view_markers,
18+
:formatter,
1819
:function_names,
1920
:lib_dir,
2021
:partials_extension,
@@ -86,6 +87,10 @@ def env=(value)
8687
@env = value&.to_sym
8788
end
8889

90+
def formatter
91+
@formatter ||= get :formatter
92+
end
93+
8994
def full_lib_dir
9095
"#{source_dir}/#{lib_dir}"
9196
end

schemas/settings.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,17 @@
213213
],
214214
"default": "development"
215215
},
216+
"formatter": {
217+
"title": "formatter",
218+
"description": "Choose how to post-process the generated script\nhttps://bashly.dev/usage/settings/#formatter",
219+
"type": "string",
220+
"enum": [
221+
"internal",
222+
"none",
223+
"shfmt"
224+
],
225+
"default": "internal"
226+
},
216227
"partials_extension": {
217228
"title": "partials extension",
218229
"description": "The extension to use when reading/writing partial script snippets\nhttps://bashly.dev/usage/settings/#partials_extension",

support/schema/settings.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,17 @@ properties:
181181
type: string
182182
enum: *feature_toggles
183183
default: development
184+
formatter:
185+
title: formatter
186+
description: |-
187+
Choose how to post-process the generated script
188+
https://bashly.dev/usage/settings/#formatter
189+
type: string
190+
enum:
191+
- internal
192+
- none
193+
- shfmt
194+
default: internal
184195
partials_extension:
185196
title: partials extension
186197
description: |-

0 commit comments

Comments
 (0)