@@ -74,87 +74,87 @@ def install
7474 # 3. Minimal copying - only what needs to be writable
7575 # 4. Resolves input file paths before changing directories
7676 ( bin /"mfc" ) . write <<~EOS
77- #!/bin/bash
78- set -euo pipefail
79-
80- # Unset VIRTUAL_ENV to ensure mfc.sh uses our configured venv
81- unset VIRTUAL_ENV || true
82-
83- # Save original working directory
84- ORIG_DIR="$(pwd)"
85-
86- # Process arguments and convert relative paths to absolute paths
87- ARGS=()
88- for arg in "$@"; do
89- # If argument looks like a file path and exists as relative path
90- if [[ "$arg" =~ \\ .(py|txt|json|yaml|yml)$ ]] && [ -e "${ORIG_DIR}/${arg}" ]; then
91- ARGS+=("${ORIG_DIR}/${arg}")
77+ #!/bin/bash
78+ set -euo pipefail
79+
80+ # Unset VIRTUAL_ENV to ensure mfc.sh uses our configured venv
81+ unset VIRTUAL_ENV || true
82+
83+ # Save original working directory
84+ ORIG_DIR="$(pwd)"
85+
86+ # Process arguments and convert relative paths to absolute paths
87+ ARGS=()
88+ for arg in "$@"; do
89+ # If argument looks like a file path and exists as relative path
90+ if [[ "$arg" =~ \\ .(py|txt|json|yaml|yml)$ ]] && [ -e "${ORIG_DIR}/${arg}" ]; then
91+ ARGS+=("${ORIG_DIR}/${arg}")
92+ else
93+ ARGS+=("$arg")
94+ fi
95+ done
96+
97+ # Create a temporary working directory (Cellar is read-only)
98+ TMPDIR="$(mktemp -d)"
99+ trap 'rm -rf "${TMPDIR}"' EXIT
100+ cd "${TMPDIR}"
101+
102+ # Copy only mfc.sh (small, fast)
103+ cp "#{ libexec } /mfc.sh" .
104+
105+ # Create a minimal CMakeLists.txt to prevent the cat error
106+ # mfc.sh reads this to get version info
107+ cat > CMakeLists.txt << 'CMAKE_EOF'
108+ cmake_minimum_required(VERSION 3.18)
109+ project(MFC VERSION #{ version } )
110+ CMAKE_EOF
111+
112+ # Symlink toolchain (read-only is fine, no copy needed)
113+ ln -s "#{ prefix } /toolchain" toolchain
114+
115+ # Symlink examples (read-only is fine)
116+ ln -s "#{ prefix } /examples" examples
117+
118+ # Create build directory structure
119+ mkdir -p build
120+
121+ # Symlink the persistent venv (no copy)
122+ ln -s "#{ var } /mfc/venv" build/venv
123+
124+ # Copy only pyproject.toml (tiny file, prevents reinstall checks)
125+ cp "#{ prefix } /toolchain/pyproject.toml" build/pyproject.toml
126+
127+ # Create a minimal patch file for build.py overrides
128+ mkdir -p .mfc_patch
129+ cat > .mfc_patch/build_patch.py << 'PATCH_EOF'
130+ import sys
131+ sys.path.insert(0, "#{ prefix } /toolchain")
132+ from mfc.build import MFCTarget
133+
134+ # Override get_install_binpath to use pre-installed binaries
135+ _original_get_install_binpath = MFCTarget.get_install_binpath
136+ def _homebrew_get_install_binpath(self, case):
137+ return "#{ bin } /" + self.name
138+ MFCTarget.get_install_binpath = _homebrew_get_install_binpath
139+
140+ # Override is_buildable to skip building main targets
141+ _original_is_buildable = MFCTarget.is_buildable
142+ def _homebrew_is_buildable(self):
143+ if self.name in ["pre_process", "simulation", "post_process", "syscheck"]:
144+ return False
145+ return _original_is_buildable(self)
146+ MFCTarget.is_buildable = _homebrew_is_buildable
147+ PATCH_EOF
148+
149+ # Set PYTHONPATH to load our patch before running mfc.sh
150+ export PYTHONPATH="${TMPDIR}/.mfc_patch:#{ prefix } /toolchain:${PYTHONPATH:-}"
151+
152+ # For 'mfc run', add --no-build flag to skip compilation
153+ if [ "${1-}" = "run" ]; then
154+ exec ./mfc.sh "${ARGS[@]}" --no-build
92155 else
93- ARGS+=("$arg")
156+ exec ./mfc.sh "${ARGS[@]}"
94157 fi
95- done
96-
97- # Create a temporary working directory (Cellar is read-only)
98- TMPDIR="$(mktemp -d)"
99- trap 'rm -rf "${TMPDIR}"' EXIT
100- cd "${TMPDIR}"
101-
102- # Copy only mfc.sh (small, fast)
103- cp "#{ libexec } /mfc.sh" .
104-
105- # Create a minimal CMakeLists.txt to prevent the cat error
106- # mfc.sh reads this to get version info
107- cat > CMakeLists.txt << 'CMAKE_EOF'
108- cmake_minimum_required(VERSION 3.18)
109- project(MFC VERSION #{ version } )
110- CMAKE_EOF
111-
112- # Symlink toolchain (read-only is fine, no copy needed)
113- ln -s "#{ prefix } /toolchain" toolchain
114-
115- # Symlink examples (read-only is fine)
116- ln -s "#{ prefix } /examples" examples
117-
118- # Create build directory structure
119- mkdir -p build
120-
121- # Symlink the persistent venv (no copy)
122- ln -s "#{ var } /mfc/venv" build/venv
123-
124- # Copy only pyproject.toml (tiny file, prevents reinstall checks)
125- cp "#{ prefix } /toolchain/pyproject.toml" build/pyproject.toml
126-
127- # Create a minimal patch file for build.py overrides
128- mkdir -p .mfc_patch
129- cat > .mfc_patch/build_patch.py << 'PATCH_EOF'
130- import sys
131- sys.path.insert(0, "#{ prefix } /toolchain")
132- from mfc.build import MFCTarget
133-
134- # Override get_install_binpath to use pre-installed binaries
135- _original_get_install_binpath = MFCTarget.get_install_binpath
136- def _homebrew_get_install_binpath(self, case):
137- return "#{ bin } /" + self.name
138- MFCTarget.get_install_binpath = _homebrew_get_install_binpath
139-
140- # Override is_buildable to skip building main targets
141- _original_is_buildable = MFCTarget.is_buildable
142- def _homebrew_is_buildable(self):
143- if self.name in ["pre_process", "simulation", "post_process", "syscheck"]:
144- return False
145- return _original_is_buildable(self)
146- MFCTarget.is_buildable = _homebrew_is_buildable
147- PATCH_EOF
148-
149- # Set PYTHONPATH to load our patch before running mfc.sh
150- export PYTHONPATH="${TMPDIR}/.mfc_patch:#{ prefix } /toolchain:${PYTHONPATH:-}"
151-
152- # For 'mfc run', add --no-build flag to skip compilation
153- if [ "${1-}" = "run" ]; then
154- exec ./mfc.sh "${ARGS[@]}" --no-build
155- else
156- exec ./mfc.sh "${ARGS[@]}"
157- fi
158158 EOS
159159 ( bin /"mfc" ) . chmod 0755
160160 end
@@ -204,5 +204,23 @@ def caveats
204204
205205 # Test that mfc wrapper works
206206 system bin /"mfc" , "--help"
207+
208+ # Test running a simple 1D Sod shock tube case from a separate directory
209+ # This ensures the wrapper script correctly handles relative paths
210+ testpath_case = testpath /"test_run"
211+ testpath_case . mkpath
212+
213+ # Copy case.py from examples to an independent test directory
214+ cp prefix /"examples/1D_sodshocktube/case.py" , testpath_case /"case.py"
215+
216+ # Run the case from the test directory (this will execute pre_process and simulation)
217+ # Limit to 1 processor and reduce runtime for testing
218+ cd testpath_case do
219+ system bin /"mfc" , "run" , "case.py" , "-j" , "1"
220+ end
221+
222+ # Verify output files were created in the test directory
223+ assert_path_exists testpath_case /"silo_hdf5"
224+ assert_predicate testpath_case /"silo_hdf5" , :directory?
207225 end
208226end
0 commit comments