@@ -9,15 +9,21 @@ _SHELL_CONTENT = """\
99
1010set -eu
1111
12- {shellcheck} {args}
12+ " {shellcheck}" {args}{post }
1313"""
1414
1515_BATCH_CONTENT = """\
1616 @ECHO OFF
1717
18- {shellcheck} {args}
18+ " {shellcheck}" {args}{post }
1919"""
2020
21+ def _quote_for_shell (value ):
22+ return "\" {}\" " .format (value .replace ("\" " , "\\ \" " ))
23+
24+ def _quote_for_batch (value ):
25+ return "\" {}\" " .format (value .replace ("\" " , "\" \" " ))
26+
2127def shellcheck_test_impl (ctx , expect_fail = False ):
2228 """The implementation of the `shellcheck_test` rule.
2329
@@ -48,21 +54,27 @@ def shellcheck_test_impl(ctx, expect_fail = False):
4854 shellcheck_rc = toolchain .shellcheckrc .short_path
4955 srcs = [f .short_path for f in ctx .files .data ]
5056 if is_windows :
51- shellcheck_path .replace ("/" , "\\ " )
52- shellcheck_rc .replace ("/" , "\\ " )
57+ shellcheck_path = shellcheck_path .replace ("/" , "\\ " )
58+ shellcheck_rc = shellcheck_rc .replace ("/" , "\\ " )
5359 srcs = [src .replace ("/" , "\\ " ) for src in srcs ]
5460
55- cmd .append ("--rcfile={}" .format (shellcheck_rc ))
56- cmd .extend (srcs )
61+ if is_windows :
62+ cmd .append ("--rcfile={}" .format (_quote_for_batch (shellcheck_rc )))
63+ cmd .extend ([_quote_for_batch (src ) for src in srcs ])
64+ else :
65+ cmd .append ("--rcfile={}" .format (_quote_for_shell (shellcheck_rc )))
66+ cmd .extend ([_quote_for_shell (src ) for src in srcs ])
5767
68+ post = ""
5869 if expect_fail :
59- cmd . append ( " || exit 0; exit 1" )
70+ post = " && exit /b 1 || exit /b 0" if is_windows else " || exit 0 \n exit 1"
6071
6172 ctx .actions .write (
6273 output = executable ,
6374 content = (_BATCH_CONTENT if is_windows else _SHELL_CONTENT ).format (
6475 shellcheck = shellcheck_path ,
6576 args = " " .join (cmd ),
77+ post = post ,
6678 ),
6779 is_executable = True ,
6880 )
@@ -148,6 +160,12 @@ _shellcheck_srcs_aspect = aspect(
148160 implementation = _shellcheck_srcs_aspect_impl ,
149161)
150162
163+ def _unix_path_arg (value ):
164+ return value .path
165+
166+ def _windows_path_arg (value ):
167+ return value .path .replace ("/" , "\\ " )
168+
151169def _shellcheck_aspect_impl (target , ctx ):
152170 if target .label .workspace_root .startswith ("external" ):
153171 return []
@@ -177,6 +195,9 @@ def _shellcheck_aspect_impl(target, ctx):
177195 return []
178196
179197 toolchain = ctx .toolchains [TOOLCHAIN_TYPE ]
198+ is_windows = ctx .target_platform_has_constraint (
199+ ctx .attr ._windows_constraint [platform_common .ConstraintValueInfo ],
200+ )
180201
181202 inputs_direct = [toolchain .shellcheckrc ] + getattr (ctx .rule .files , "data" , [])
182203 inputs_transitive = [src_info .srcs , src_info .transitive_srcs ]
@@ -188,15 +209,21 @@ def _shellcheck_aspect_impl(target, ctx):
188209 ])
189210
190211 format = ctx .attr ._format [BuildSettingInfo ].value
191- severity = ctx .attr ._format [BuildSettingInfo ].value
212+ severity = ctx .attr ._severity [BuildSettingInfo ].value
192213
193214 output = ctx .actions .declare_file ("{}.shellcheck.ok" .format (target .label .name ))
194215
195216 tools = depset ([toolchain .shellcheck ], transitive = [toolchain .all_files ])
196217
218+ shellcheck_path = toolchain .shellcheck .path
219+ shellcheck_rc_path = toolchain .shellcheckrc .path
220+ if is_windows :
221+ shellcheck_path = shellcheck_path .replace ("/" , "\\ " )
222+ shellcheck_rc_path = shellcheck_rc_path .replace ("/" , "\\ " )
223+
197224 args = ctx .actions .args ()
198- args .add (toolchain . shellcheck )
199- args .add (toolchain . shellcheckrc , format = "--rcfile=%s" )
225+ args .add (shellcheck_path )
226+ args .add (shellcheck_rc_path , format = "--rcfile=%s" )
200227 args .add_all (src_info .source_paths , format_each = "--source-path=%s" )
201228
202229 if format :
@@ -205,7 +232,7 @@ def _shellcheck_aspect_impl(target, ctx):
205232 if severity :
206233 args .add (severity , format = "--severity=%s" )
207234
208- args .add_all (srcs )
235+ args .add_all (srcs , map_each = _windows_path_arg if is_windows else _unix_path_arg )
209236
210237 ctx .actions .run (
211238 mnemonic = "Shellcheck" ,
@@ -240,6 +267,9 @@ shellcheck_aspect = aspect(
240267 "_severity" : attr .label (
241268 default = Label ("//shellcheck/settings:severity" ),
242269 ),
270+ "_windows_constraint" : attr .label (
271+ default = Label ("@platforms//os:windows" ),
272+ ),
243273 },
244274 toolchains = [TOOLCHAIN_TYPE ],
245275 requires = [_shellcheck_srcs_aspect ],
0 commit comments