Skip to content

Commit 3e626f3

Browse files
ssantoluSalvador Santoluctio
andauthored
Users/ssantolu/refactor (#26)
* refactor config settings flow * update version * ran lint tools * replace INI with PY * update version * removing unnecessary file * removed old files --------- Co-authored-by: Salvador Santoluctio <salvador.santolucito@ni.com>
1 parent fa3e822 commit 3e626f3

28 files changed

Lines changed: 718 additions & 897 deletions

README.md

Lines changed: 127 additions & 199 deletions
Large diffs are not rendered by default.

labview_fpga_hdl_tools/__main__.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def cli(ctx):
4141

4242

4343
@cli.command("migrate-clip", help="Migrate CLIP files for FlexRIO custom devices")
44-
@click.option("--config", default=None, help="Path to nihdlcommandconfig.py")
44+
@click.option("--config", default=None, help="Path to nihdlsettings.py")
4545
@click.pass_context
4646
def migrate_clip_cmd(ctx, config):
4747
"""Migrate CLIP files for FlexRIO custom devices."""
@@ -58,7 +58,7 @@ def migrate_clip_cmd(ctx, config):
5858

5959

6060
@cli.command("install-target", help="Install LabVIEW FPGA target support files")
61-
@click.option("--config", default=None, help="Path to nihdlcommandconfig.py")
61+
@click.option("--config", default=None, help="Path to nihdlsettings.py")
6262
@click.pass_context
6363
def install_target_cmd(ctx, config):
6464
"""Install LabVIEW FPGA target support files."""
@@ -75,7 +75,7 @@ def install_target_cmd(ctx, config):
7575

7676

7777
@cli.command("get-window", help="Extract window netlist from Vivado project")
78-
@click.option("--config", default=None, help="Path to nihdlcommandconfig.py")
78+
@click.option("--config", default=None, help="Path to nihdlsettings.py")
7979
@click.pass_context
8080
def get_window_cmd(ctx, config):
8181
"""Extract window netlist from Vivado project."""
@@ -92,7 +92,7 @@ def get_window_cmd(ctx, config):
9292

9393

9494
@cli.command("gen-target", help="Generate LabVIEW FPGA target support files")
95-
@click.option("--config", default=None, help="Path to nihdlcommandconfig.py")
95+
@click.option("--config", default=None, help="Path to nihdlsettings.py")
9696
@click.pass_context
9797
def gen_target_cmd(ctx, config):
9898
"""Generate LabVIEW FPGA target support files."""
@@ -109,7 +109,7 @@ def gen_target_cmd(ctx, config):
109109

110110

111111
@cli.command("gen-hdl", help="Generate Window VHDL files from CSV/templates")
112-
@click.option("--config", default=None, help="Path to nihdlcommandconfig.py")
112+
@click.option("--config", default=None, help="Path to nihdlsettings.py")
113113
@click.pass_context
114114
def gen_hdl_cmd(ctx, config):
115115
"""Generate Window VHDL files only."""
@@ -126,7 +126,7 @@ def gen_hdl_cmd(ctx, config):
126126

127127

128128
@cli.command("gen-xdc", help="Generate XDC constraint files from templates")
129-
@click.option("--config", default=None, help="Path to nihdlcommandconfig.py")
129+
@click.option("--config", default=None, help="Path to nihdlsettings.py")
130130
@click.pass_context
131131
def gen_xdc_cmd(ctx, config):
132132
"""Generate XDC constraint files from templates."""
@@ -145,7 +145,7 @@ def gen_xdc_cmd(ctx, config):
145145
@cli.command("create-project", help="Create or update Vivado project")
146146
@click.option("--overwrite", "-o", is_flag=True, help="Overwrite and create a new project")
147147
@click.option("--update", "-u", is_flag=True, help="Update files in the existing project")
148-
@click.option("--config", default=None, help="Path to nihdlcommandconfig.py")
148+
@click.option("--config", default=None, help="Path to nihdlsettings.py")
149149
@click.pass_context
150150
def create_project_cmd(ctx, overwrite, update, config):
151151
"""Create or update Vivado project."""
@@ -164,7 +164,7 @@ def create_project_cmd(ctx, overwrite, update, config):
164164

165165

166166
@cli.command("check-syntax", help="Check Vivado RTL syntax and hierarchy quickly")
167-
@click.option("--config", default=None, help="Path to nihdlcommandconfig.py")
167+
@click.option("--config", default=None, help="Path to nihdlsettings.py")
168168
@click.pass_context
169169
def check_syntax_cmd(ctx, config):
170170
"""Check Vivado RTL syntax and hierarchy using RTL elaboration."""
@@ -181,7 +181,7 @@ def check_syntax_cmd(ctx, config):
181181

182182

183183
@cli.command("compile-project", help="Compile Vivado project and generate a LabVIEW FPGA bitfile")
184-
@click.option("--config", default=None, help="Path to nihdlcommandconfig.py")
184+
@click.option("--config", default=None, help="Path to nihdlsettings.py")
185185
@click.pass_context
186186
def compile_project_cmd(ctx, config):
187187
"""Compile Vivado project and generate a LabVIEW FPGA bitfile."""
@@ -198,7 +198,7 @@ def compile_project_cmd(ctx, config):
198198

199199

200200
@cli.command("launch-vivado", help="Launch Vivado with the current project")
201-
@click.option("--config", default=None, help="Path to nihdlcommandconfig.py")
201+
@click.option("--config", default=None, help="Path to nihdlsettings.py")
202202
@click.pass_context
203203
def launch_vivado_cmd(ctx, config):
204204
"""Launch Vivado with the current project."""
@@ -218,7 +218,7 @@ def launch_vivado_cmd(ctx, config):
218218
@click.option("--delete", is_flag=True, help="Automatically delete and re-clone without prompting")
219219
@click.option("--pre", is_flag=True, help="Include pre-release versions when resolving versions")
220220
@click.option("--latest", is_flag=True, help="Use latest version for all dependencies")
221-
@click.option("--config", default=None, help="Path to nihdlcommandconfig.py")
221+
@click.option("--config", default=None, help="Path to nihdlsettings.py")
222222
@click.pass_context
223223
def install_deps_cmd(ctx, delete, pre, latest, config):
224224
"""Install GitHub dependencies from dependencies.toml."""
@@ -239,7 +239,7 @@ def install_deps_cmd(ctx, delete, pre, latest, config):
239239

240240
@cli.command("create-modelsim", help="Create a ModelSim project for simulation")
241241
@click.option("--overwrite", "-o", is_flag=True, help="Overwrite existing ModelSim project")
242-
@click.option("--config", default=None, help="Path to nihdlcommandconfig.py")
242+
@click.option("--config", default=None, help="Path to nihdlsettings.py")
243243
@click.pass_context
244244
def create_modelsim_cmd(ctx, overwrite, config):
245245
"""Create a ModelSim project for HDL simulation."""
@@ -258,7 +258,7 @@ def create_modelsim_cmd(ctx, overwrite, config):
258258

259259
@cli.command("launch-modelsim", help="Launch ModelSim with the current project")
260260
@click.option("--batch", is_flag=True, help="Run simulation in batch mode (no GUI)")
261-
@click.option("--config", default=None, help="Path to nihdlcommandconfig.py")
261+
@click.option("--config", default=None, help="Path to nihdlsettings.py")
262262
@click.pass_context
263263
def launch_modelsim_cmd(ctx, batch, config):
264264
"""Launch ModelSim with the current project."""
@@ -277,7 +277,7 @@ def launch_modelsim_cmd(ctx, batch, config):
277277

278278
@cli.command("sim-modelsim", help="Run ModelSim simulation in batch mode")
279279
@click.option("--do-file", default=None, help="Custom .do file to run instead of default")
280-
@click.option("--config", default=None, help="Path to nihdlcommandconfig.py")
280+
@click.option("--config", default=None, help="Path to nihdlsettings.py")
281281
@click.pass_context
282282
def sim_modelsim_cmd(ctx, do_file, config):
283283
"""Run ModelSim simulation in batch mode and report results."""
@@ -295,7 +295,7 @@ def sim_modelsim_cmd(ctx, do_file, config):
295295

296296

297297
@cli.command("create-lvbitx", help="Create LabVIEW FPGA bitfile from Vivado output")
298-
@click.option("--config", default=None, help="Path to nihdlcommandconfig.py")
298+
@click.option("--config", default=None, help="Path to nihdlsettings.py")
299299
@click.pass_context
300300
def create_lvbitx_cmd(ctx, config):
301301
"""Create LabVIEW FPGA bitfile from Vivado output."""
@@ -312,15 +312,15 @@ def create_lvbitx_cmd(ctx, config):
312312

313313

314314
@cli.command("gen-guid", help="Generate a new GUID for LabVIEW FPGA target plugins")
315-
@click.option("--config", default=None, help="Path to nihdlcommandconfig.py")
315+
@click.option("--config", default=None, help="Path to nihdlsettings.py")
316316
@click.pass_context
317317
def gen_guid_cmd(ctx, config):
318318
"""Generate a new GUID for LabVIEW FPGA target plugins."""
319319

320320
def _gen_guid(**kwargs):
321321
guid = common.generate_guid()
322322
print("Generated GUID:", guid)
323-
print("Copy and paste this GUID into LVTargetGUID in the projectsettings.ini file.")
323+
print("Copy and paste this GUID into your nihdlsettings.py file.")
324324
return 0
325325

326326
try:

labview_fpga_hdl_tools/check_syntax.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ def _run_check_syntax(config, generated_tcl_path):
116116
if not os.path.exists(vivado_abs):
117117
raise FileNotFoundError(
118118
f"Vivado executable not found at: {vivado_abs}\n"
119-
f"Please check your --vivado argument or VivadoToolsPath setting in projectsettings.ini"
119+
f"Please check your --vivado argument or VivadoToolsPath setting in nihdlsettings.py"
120120
)
121121

122122
vivado_project_path = os.path.join(os.getcwd(), "VivadoProject")
@@ -184,7 +184,7 @@ def check_syntax(config=None):
184184
int: 0 for success, 1 for error
185185
"""
186186
if config is None:
187-
config = common.load_config()
187+
config = common.FileConfiguration()
188188

189189
try:
190190
_validate_ini(config)

labview_fpga_hdl_tools/command_hooks.py

Lines changed: 64 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Command hook system for nihdl CLI.
22
3-
Loads a user-provided nihdlcommandconfig.py file that can define pre/post hooks
3+
Loads a user-provided nihdlsettings.py file that can define pre/post hooks
44
for each CLI command, enabling customization and extension of the tool behavior.
55
66
The hook execution order for each command is:
@@ -23,10 +23,13 @@ class CommandContext:
2323
"""Shared context passed to all hook functions for a command invocation.
2424
2525
Attributes:
26-
config: FileConfiguration loaded from projectsettings.ini (set by pre_all).
26+
config: FileConfiguration loaded from nihdlsettings.py (set by pre_all).
2727
command_name: Name of the command being executed (e.g. "create_project").
2828
command_kwargs: Dict of keyword arguments that will be passed to the command.
2929
result: Return value from the command function (available in post hooks).
30+
invocation_dir: The working directory from which the nihdl command was
31+
invoked. Useful in wrapper settings files that need to load another
32+
nihdlsettings.py from the original target directory.
3033
"""
3134

3235
def __init__(self, command_name, command_kwargs):
@@ -35,10 +38,11 @@ def __init__(self, command_name, command_kwargs):
3538
self.command_name = command_name
3639
self.command_kwargs = dict(command_kwargs)
3740
self.result = None
41+
self.invocation_dir = os.getcwd()
3842

3943

4044
def _load_config_module(command_config_path):
41-
"""Dynamically load a nihdlcommandconfig.py module.
45+
"""Dynamically load a nihdlsettings.py module.
4246
4347
Args:
4448
command_config_path: Absolute path to the Python config file.
@@ -47,10 +51,10 @@ def _load_config_module(command_config_path):
4751
The loaded module object.
4852
"""
4953
if not os.path.exists(command_config_path):
50-
print(f"Error: Command config file not found: {command_config_path}", file=sys.stderr)
54+
print(f"Error: Settings file not found: {command_config_path}", file=sys.stderr)
5155
sys.exit(1)
5256

53-
spec = importlib.util.spec_from_file_location("nihdlcommandconfig", command_config_path)
57+
spec = importlib.util.spec_from_file_location("nihdlsettings", command_config_path)
5458
if spec is None or spec.loader is None:
5559
print(f"Error: Could not load module spec from: {command_config_path}", file=sys.stderr)
5660
sys.exit(1)
@@ -63,7 +67,7 @@ def _call_hook(module, hook_name, context):
6367
"""Call a hook function on the module if it exists.
6468
6569
Args:
66-
module: The loaded nihdlcommandconfig module.
70+
module: The loaded nihdlsettings module.
6771
hook_name: Name of the hook function (e.g. "pre_all", "post_create_project").
6872
context: CommandContext instance to pass to the hook.
6973
"""
@@ -72,33 +76,80 @@ def _call_hook(module, hook_name, context):
7276
hook(context)
7377

7478

79+
def load_settings(settings_path, context):
80+
"""Load another nihdlsettings.py file and run its pre_all hook.
81+
82+
Use this from a wrapper nihdlsettings.py to compose settings — for example,
83+
a pipeline config that loads each target's own nihdlsettings.py and then
84+
overrides specific values::
85+
86+
from labview_fpga_hdl_tools.command_hooks import load_settings
87+
88+
def pre_all(context):
89+
# Load the target's settings from the original invocation directory
90+
target_settings = os.path.join(context.invocation_dir, "nihdlsettings.py")
91+
load_settings(target_settings, context)
92+
# Override Vivado path from environment
93+
xilinx = os.environ.get("XILINX")
94+
if xilinx:
95+
context.config.set_vivado_tools_path(xilinx)
96+
97+
Relative paths are resolved from the loaded file's directory, matching the
98+
normal nihdlsettings.py behavior.
99+
100+
Args:
101+
settings_path: Path to the nihdlsettings.py file to load. Relative
102+
paths are resolved from the current working directory.
103+
context: The CommandContext whose config will be updated.
104+
"""
105+
abs_path = os.path.abspath(settings_path)
106+
module = _load_config_module(abs_path)
107+
settings_dir = os.path.dirname(abs_path)
108+
original_dir = os.getcwd()
109+
os.chdir(settings_dir)
110+
try:
111+
_call_hook(module, "pre_all", context)
112+
finally:
113+
os.chdir(original_dir)
114+
115+
75116
def run_with_hooks(command_name, command_func, command_config_path=None, **command_kwargs):
76-
"""Execute a command wrapped with pre/post hooks from nihdlcommandconfig.py.
117+
"""Execute a command wrapped with pre/post hooks from nihdlsettings.py.
77118
78-
If no command_config_path is given, looks for nihdlcommandconfig.py in cwd.
119+
If no command_config_path is given, looks for nihdlsettings.py in cwd.
120+
Pre hooks run with the working directory set to the settings file's
121+
directory so that relative paths in setter calls resolve correctly.
122+
The command and post hooks run from the original working directory.
79123
80124
Args:
81125
command_name: Underscore-separated command name (e.g. "create_project").
82126
command_func: The callable command function to execute.
83-
command_config_path: Optional path to nihdlcommandconfig.py.
127+
command_config_path: Optional path to nihdlsettings.py.
84128
**command_kwargs: Keyword arguments to pass to the command function.
85129
86130
Returns:
87131
The return value of the command function.
88132
"""
89133
# Resolve the config module path
90134
if command_config_path is None:
91-
command_config_path = os.path.join(os.getcwd(), "nihdlcommandconfig.py")
135+
command_config_path = os.path.join(os.getcwd(), "nihdlsettings.py")
92136

93137
# Load the config module
94138
module = _load_config_module(command_config_path)
95139

96140
# Build context
97141
context = CommandContext(command_name, command_kwargs)
98142

99-
# Pre hooks
100-
_call_hook(module, "pre_all", context)
101-
_call_hook(module, f"pre_{command_name}", context)
143+
# Pre hooks run from the settings file's directory so relative paths
144+
# passed to setters resolve correctly (same as the old INI chdir behavior).
145+
config_dir = os.path.dirname(os.path.abspath(command_config_path))
146+
original_dir = os.getcwd()
147+
os.chdir(config_dir)
148+
try:
149+
_call_hook(module, "pre_all", context)
150+
_call_hook(module, f"pre_{command_name}", context)
151+
finally:
152+
os.chdir(original_dir)
102153

103154
# Inject pre-loaded config into command kwargs
104155
command_kwargs["config"] = context.config

0 commit comments

Comments
 (0)