@@ -147,127 +147,91 @@ def prepare_workspace_action(ctx, config):
147147 # Create workspace output directory
148148 workspace_dir = ctx .actions .declare_directory (config ["work_dir" ])
149149
150- # HERMETIC APPROACH: Use a simple script that only uses POSIX commands available everywhere
151- # Create a minimal shell script that doesn't depend on system Python
152- workspace_script = ctx . actions . declare_file ( ctx . label . name + "_workspace_setup.sh" )
150+ # Get the hermetic file operations tool from toolchain
151+ file_ops_toolchain = ctx . toolchains [ "@rules_wasm_component//toolchains:file_ops_toolchain_type" ]
152+ file_ops_tool = file_ops_toolchain . file_ops_component
153153
154- # Collect all input files and their destinations
154+ # Collect all input files and build operations list
155155 all_inputs = []
156- file_mappings = []
156+ operations = []
157157
158158 # Process source files
159159 for source_info in config .get ("sources" , []):
160160 src_file = source_info ["source" ]
161161 dest_name = source_info .get ("destination" ) or src_file .basename
162162 all_inputs .append (src_file )
163- file_mappings .append ((src_file , dest_name ))
163+ operations .append ({
164+ "type" : "copy_file" ,
165+ "src_path" : src_file .path ,
166+ "dest_path" : dest_name ,
167+ })
164168
165169 # Process header files
166170 for header_info in config .get ("headers" , []):
167171 hdr_file = header_info ["source" ]
168172 dest_name = header_info .get ("destination" ) or hdr_file .basename
169173 all_inputs .append (hdr_file )
170- file_mappings .append ((hdr_file , dest_name ))
174+ operations .append ({
175+ "type" : "copy_file" ,
176+ "src_path" : hdr_file .path ,
177+ "dest_path" : dest_name ,
178+ })
171179
172180 # Process dependency files
173181 for dep_info in config .get ("dependencies" , []):
174182 dep_file = dep_info ["source" ]
175183 dest_name = dep_info .get ("destination" ) or dep_file .basename
176184 all_inputs .append (dep_file )
177185
178- # Include the full dep_info for directory handling
179- file_mappings .append ((dep_file , dest_name , dep_info ))
180-
181- script_lines = [
182- "#!/bin/sh" ,
183- "set -e" ,
184- "" ,
185- "WORKSPACE_DIR=\" $1\" " ,
186- "mkdir -p \" $WORKSPACE_DIR\" " ,
187- "" ,
188- ]
189-
190- # Add file operations using basic POSIX commands
191- for mapping in file_mappings :
192- if len (mapping ) == 3 :
193- src_file , dest_name , dep_info = mapping
194- is_directory = dep_info .get ("is_directory" , False )
195- else :
196- src_file , dest_name = mapping
197- is_directory = False
198-
199- # Ensure parent directory exists for nested paths
200- if "/" in dest_name :
201- parent_dir = "/" .join (dest_name .split ("/" )[:- 1 ])
202- script_lines .append ("mkdir -p \" $WORKSPACE_DIR/{}\" " .format (parent_dir ))
203-
204- # Use cp -r for directories, cp for files
186+ is_directory = dep_info .get ("is_directory" , False )
205187 if is_directory :
206- # For directories, copy contents not the directory itself
207- script_lines .append ("mkdir -p \" $WORKSPACE_DIR/{}\" " .format (dest_name ))
208- script_lines .append ("cp -r \" {}\" /* \" $WORKSPACE_DIR/{}\" " .format (src_file .path , dest_name ))
188+ operations .append ({
189+ "type" : "copy_directory_contents" ,
190+ "src_path" : dep_file .path ,
191+ "dest_path" : dest_name ,
192+ })
209193 else :
210- script_lines .append ("cp \" {}\" \" $WORKSPACE_DIR/{}\" " .format (src_file .path , dest_name ))
194+ operations .append ({
195+ "type" : "copy_file" ,
196+ "src_path" : dep_file .path ,
197+ "dest_path" : dest_name ,
198+ })
211199
212200 # Add Go module dependency resolution if go_binary provided
213201 go_binary = config .get ("go_binary" )
214202 if go_binary and config .get ("workspace_type" ) == "go" :
215- # Note: go_binary.path might be relative, ensure it's resolved correctly
216- go_binary_path = go_binary .path
217- script_lines .extend ([
218- "" ,
219- "# Go module dependency resolution" ,
220- "echo \" Resolving Go module dependencies...\" " ,
221- "cd \" $WORKSPACE_DIR\" " ,
222- "export GOCACHE=\" $WORKSPACE_DIR/.gocache\" " ,
223- "export GOPATH=\" $WORKSPACE_DIR/.gopath\" " ,
224- "mkdir -p \" $GOCACHE\" \" $GOPATH\" " ,
225- "" ,
226- "# Find the Go binary in execution root" ,
227- "if [ -f \" $EXECROOT/{}\" ]; then" .format (go_binary_path ),
228- " GO_BIN=\" $EXECROOT/{}\" " .format (go_binary_path ),
229- "elif [ -f \" {}\" ]; then" .format (go_binary_path ),
230- " GO_BIN=\" {}\" " .format (go_binary_path ),
231- "else" ,
232- " echo \" Warning: Go binary not found, skipping dependency resolution\" " ,
233- " GO_BIN=\" \" " ,
234- "fi" ,
235- "" ,
236- "if [ -n \" $GO_BIN\" ]; then" ,
237- " \" $GO_BIN\" mod download || echo \" Note: Go mod download failed or not needed\" " ,
238- " echo \" Go dependencies resolved\" " ,
239- "fi" ,
240- "" ,
203+ # Note: go mod download is not needed here as TinyGo handles dependencies
204+ # Just create the cache directories for potential future use
205+ operations .extend ([
206+ {"type" : "mkdir" , "path" : ".gocache" },
207+ {"type" : "mkdir" , "path" : ".gopath" },
241208 ])
242209
243- script_lines . extend ([
244- "" ,
245- "# Create completion marker" ,
246- "echo \" Workspace prepared with {} files \" > \" $WORKSPACE_DIR/.workspace_ready \" " . format ( len ( file_mappings )) ,
247- ])
210+ # Build JSON config for file operations tool
211+ file_ops_config = {
212+ "workspace_dir" : workspace_dir . path ,
213+ "operations" : operations ,
214+ }
248215
216+ # Write config to a JSON file
217+ config_file = ctx .actions .declare_file (ctx .label .name + "_file_ops_config.json" )
249218 ctx .actions .write (
250- output = workspace_script ,
251- content = "\n " .join (script_lines ),
252- is_executable = True ,
219+ output = config_file ,
220+ content = json .encode (file_ops_config ),
253221 )
254222
255- # Add go_binary to inputs if provided
256- action_inputs = all_inputs + [workspace_script ]
257- if go_binary :
258- action_inputs .append (go_binary )
259-
260- # Execute the workspace setup using only basic POSIX shell
223+ # Execute the hermetic file operations tool
261224 ctx .actions .run (
262- executable = workspace_script ,
263- arguments = [workspace_dir .path ],
264- inputs = action_inputs ,
225+ executable = file_ops_tool ,
226+ arguments = [config_file .path ],
227+ inputs = all_inputs + [ config_file ] ,
265228 outputs = [workspace_dir ],
266229 mnemonic = "PrepareWorkspaceHermetic" ,
267230 progress_message = "Preparing {} workspace for {} (hermetic)" .format (
268231 config .get ("workspace_type" , "generic" ),
269232 ctx .label ,
270233 ),
234+ tools = [file_ops_tool ],
271235 )
272236
273237 return workspace_dir
@@ -440,69 +404,61 @@ def setup_js_workspace_action(ctx, sources, package_json = None, npm_deps = None
440404 # Create workspace directory
441405 workspace_dir = ctx .actions .declare_directory (ctx .label .name + "_jswork" )
442406
443- # Prepare inputs
444- all_inputs = list (sources )
445- if package_json :
446- all_inputs .append (package_json )
447- if npm_deps :
448- all_inputs .append (npm_deps )
407+ # Get the hermetic file operations tool from toolchain
408+ file_ops_toolchain = ctx .toolchains ["@rules_wasm_component//toolchains:file_ops_toolchain_type" ]
409+ file_ops_tool = file_ops_toolchain .file_ops_component
449410
450- # Create a shell script that properly copies files (not symlinks)
451- setup_script = ctx .actions .declare_file (ctx .label .name + "_setup_workspace.sh" )
452-
453- script_lines = [
454- "#!/bin/bash" ,
455- "set -euo pipefail" ,
456- "" ,
457- "WORKSPACE_DIR=\" $1\" " ,
458- "shift" ,
459- "" ,
460- "# Create workspace directory" ,
461- "mkdir -p \" $WORKSPACE_DIR\" " ,
462- "echo \" Setting up JavaScript workspace: $WORKSPACE_DIR\" " ,
463- "" ,
464- ]
411+ # Build operations list
412+ all_inputs = []
413+ operations = []
465414
466415 # Copy source files to workspace root (flatten structure)
467416 for src in sources :
468- script_lines .extend ([
469- "echo \" Copying {} to $WORKSPACE_DIR/{}\" " .format (src .path , src .basename ),
470- "cp \" {}\" \" $WORKSPACE_DIR/{}\" " .format (src .path , src .basename ),
471- ])
417+ all_inputs .append (src )
418+ operations .append ({
419+ "type" : "copy_file" ,
420+ "src_path" : src .path ,
421+ "dest_path" : src .basename ,
422+ })
472423
473424 if package_json :
474- script_lines .extend ([
475- "echo \" Copying package.json\" " ,
476- "cp \" {}\" \" $WORKSPACE_DIR/package.json\" " .format (package_json .path ),
477- ])
425+ all_inputs .append (package_json )
426+ operations .append ({
427+ "type" : "copy_file" ,
428+ "src_path" : package_json .path ,
429+ "dest_path" : "package.json" ,
430+ })
478431
479432 if npm_deps :
480- script_lines .extend ([
481- "echo \" Copying npm dependencies\" " ,
482- "cp -r \" {}\" \" $WORKSPACE_DIR/node_modules\" " .format (npm_deps .path ),
483- ])
433+ all_inputs .append (npm_deps )
434+ operations .append ({
435+ "type" : "copy_directory_contents" ,
436+ "src_path" : npm_deps .path ,
437+ "dest_path" : "node_modules" ,
438+ })
484439
485- script_lines .extend ([
486- "" ,
487- "echo \" JavaScript workspace setup complete\" " ,
488- "echo \" Files in workspace:\" " ,
489- "ls -la \" $WORKSPACE_DIR\" " ,
490- ])
440+ # Build JSON config for file operations tool
441+ file_ops_config = {
442+ "workspace_dir" : workspace_dir .path ,
443+ "operations" : operations ,
444+ }
491445
446+ # Write config to a JSON file
447+ config_file = ctx .actions .declare_file (ctx .label .name + "_file_ops_config.json" )
492448 ctx .actions .write (
493- output = setup_script ,
494- content = "\n " .join (script_lines ),
495- is_executable = True ,
449+ output = config_file ,
450+ content = json .encode (file_ops_config ),
496451 )
497452
498- # Run the setup script
453+ # Execute the hermetic file operations tool
499454 ctx .actions .run (
500- executable = setup_script ,
501- arguments = [workspace_dir .path ],
502- inputs = all_inputs ,
455+ executable = file_ops_tool ,
456+ arguments = [config_file .path ],
457+ inputs = all_inputs + [ config_file ] ,
503458 outputs = [workspace_dir ],
504459 mnemonic = "SetupJSWorkspace" ,
505460 progress_message = "Setting up JavaScript workspace for %s" % ctx .label ,
461+ tools = [file_ops_tool ],
506462 )
507463
508464 return workspace_dir
0 commit comments