Skip to content

Commit 0a32305

Browse files
committed
add project+version handling
1 parent 6e3ece7 commit 0a32305

5 files changed

Lines changed: 209 additions & 1 deletion

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ sdist/
2121
output/
2222
docs/source/_autosummary/
2323
var/
24+
pylab_ml/scripts/*.yaml
2425
wheels/
2526
pip-wheel-metadata/
2627
share/python-wheels/

pylab_ml/misc/project_info.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/usr/bin/env python3
2+
"""
3+
get project infos from the harness/project_info.yaml file
4+
and set the environment variable.
5+
6+
7+
"""
8+
import os
9+
from pathlib import Path
10+
import yaml
11+
12+
13+
class Project_Info:
14+
15+
def __init__(self, filename):
16+
"""
17+
Get project infos from the harness/project_info.yaml file.
18+
19+
and set the environment variable.
20+
"""
21+
22+
project_file = os.path.join(str(Path(filename).parent.parent.parent.parent), "harness", "project_info.yaml")
23+
24+
if os.path.isfile(project_file):
25+
with open(project_file, 'r', encoding='utf-8') as file:
26+
project_info = yaml.safe_load(file)
27+
for name in project_info:
28+
value = project_info[name]
29+
if type(value) is dict and 'VERSION' in project_info and project_info['VERSION'] in value:
30+
value = value[project_info['VERSION']]
31+
if value is not None:
32+
os.environ[name] = value
33+
setattr(self, name, value)

pylab_ml/misc/registermaster.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1412,6 +1412,7 @@ def set_bank(self, adr):
14121412
return adr
14131413

14141414
def _call_from_string(self, adr, callstr):
1415+
result = []
14151416
regs = self._register_to_list()
14161417
call = ast.parse(callstr, mode='eval').body
14171418
args = [ast.literal_eval(a) for a in call.args]
@@ -1429,6 +1430,7 @@ def _call_from_string(self, adr, callstr):
14291430
result += resu
14301431
else:
14311432
result.append(resu)
1433+
result.append(function(*args, **kwargs))
14321434
index += 1
14331435
return result
14341436

@@ -1442,6 +1444,8 @@ def readreg(self, adr, bank=None, compare=None, onlycheck=True, tolerance=0, mas
14421444
else:
14431445
return self._call_from_string(adr, f"read({compare}, {onlycheck}, {tolerance}, {mask})")
14441446
if type(adr) is list:
1447+
return self._call_from_string(adr, f"read({compare}, {onlycheck}, {tolerance}, {mask})")
1448+
elif type(adr) is list:
14451449
result = [] if compare is None else 0
14461450
index = 0
14471451
for a in adr:
@@ -1511,6 +1515,8 @@ def writereg(self, adr, dat, bank=None):
15111515
else:
15121516
return self._call_from_string(adr, f"write({dat})")
15131517
if type(adr) is list:
1518+
return self._call_from_string(adr, f"write({dat})")
1519+
elif type(adr) is list:
15141520
index = 0
15151521
for a in adr:
15161522
d = dat[index] if type(dat) is list else dat
@@ -1625,6 +1631,7 @@ def apply_configuration(self, data):
16251631
None.
16261632
16271633
"""
1634+
breakpoint()
16281635
_setattr = object.__setattr__.__get__(self, self.__class__)
16291636
config = environment.replaceEnvs(data)
16301637
filename = config["filename"] if "filename" in config and config["filename"] != "" else self.filename

pylab_ml/scripts/enter_semiate.py

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
#!/usr/bin/env python3
2+
"""
3+
semi-ate
4+
5+
Usage:
6+
semi-ate project version [-w name]
7+
8+
"""
9+
import shlex
10+
from pathlib import Path
11+
import yaml
12+
import argparse
13+
import os
14+
import subprocess
15+
import sys
16+
import platform
17+
from typing import Optional
18+
19+
20+
class SemiAte:
21+
def __init__(self, args):
22+
optionfile = str(Path(__file__).with_suffix('')) + '.yaml'
23+
if not os.path.isfile(optionfile) or args.edit: # search for the optionfile, if not found, create it
24+
while True:
25+
path = input('no path to projects defined, please enter the path: ')
26+
if path != "" and os.path.isdir(path):
27+
break
28+
print(f"path {path} not valid")
29+
with open(optionfile, 'w', encoding='utf-8') as file:
30+
yaml.safe_dump(path, file, sort_keys=False, allow_unicode=True)
31+
else:
32+
with open(optionfile, 'r', encoding='utf-8') as file:
33+
path = yaml.safe_load(file)
34+
35+
self._validate_version(args.version)
36+
37+
if not os.path.isdir(os.path.join(path, args.project)):
38+
print(f'project {args.project} not found')
39+
return
40+
path = os.path.join(path, args.project)
41+
if not os.path.isdir(os.path.join(path, "harness")):
42+
os.makedirs(os.path.join(path, "harness"))
43+
project_file = os.path.join(path, "harness", "project_info.yaml")
44+
45+
if os.path.isfile(project_file):
46+
with open(project_file, 'r', encoding='utf-8') as file:
47+
project_info = yaml.safe_load(file)
48+
else:
49+
project_info = {"PROJECT": args.project,
50+
"VERSION": args.version,
51+
"USER": args.who}
52+
53+
project_info["PROJECT"] = args.project
54+
project_info["VERSION"] = args.version
55+
project_info["USER"] = args.who
56+
57+
with open(project_file, 'w', encoding='utf-8') as file:
58+
yaml.safe_dump(project_info, file, sort_keys=False, allow_unicode=True)
59+
60+
print(project_info)
61+
62+
# self.start_spyder_in_env("", args.project.upper(), args.version.upper(), args.who)
63+
64+
65+
def _validate_version(self, v: str) -> str:
66+
if len(v) != 4 or not v.isdigit():
67+
print("The version must be a 4-digit number, e.g. 0001")
68+
exit()
69+
return v
70+
71+
72+
def start_spyder_in_env(self, env_name: str, project: str, version: str, user: Optional[str] = None) -> int:
73+
"""
74+
Start Spyder in the given conda env. Return exit code.
75+
Cross-platform:
76+
- On Windows: use `conda run -n <env> spyder` (and pass env vars via env)
77+
- On Unix: try to source conda.sh and `conda activate`, export vars and exec spyder.
78+
if that fails, fallback to `conda run`.
79+
"""
80+
env = os.environ.copy()
81+
env["PROJECT"] = project
82+
env["VERSION"] = version
83+
if user:
84+
env["USER"] = user
85+
86+
system = platform.system().lower()
87+
# Try to find conda base
88+
conda_base = None
89+
try:
90+
p = subprocess.run(["conda", "info", "--base"], capture_output=True, text=True, check=True, env=env)
91+
conda_base = p.stdout.strip()
92+
except Exception:
93+
conda_base = None
94+
95+
# Windows: use conda run (works with modern conda)
96+
if system.startswith("win"):
97+
try:
98+
cmd = ["conda", "run", "-n", env_name, "--no-capture-output", "spyder"]
99+
return subprocess.call(cmd, env=env)
100+
except FileNotFoundError:
101+
print("Fehler: 'conda' nicht gefunden. Stelle sicher, dass Anaconda/Miniconda installiert und in PATH ist.", file=sys.stderr)
102+
return 3
103+
except Exception as e:
104+
print(f"Fehler beim Starten von Spyder (Windows): {e}", file=sys.stderr)
105+
return 4
106+
107+
# Unix-like
108+
if conda_base:
109+
conda_sh = os.path.join(conda_base, "etc", "profile.d", "conda.sh")
110+
if os.path.exists(conda_sh):
111+
# Build a bash command that sources conda.sh, activates env, exports vars, and exec spyder
112+
parts = [
113+
f". {conda_sh}",
114+
f"conda activate {env_name}",
115+
f"export PROJECT='{project}'",
116+
f"export VERSION='{version}'",
117+
]
118+
if user:
119+
parts.append(f"export USER='{user}'")
120+
parts.append("exec spyder")
121+
bash_cmd = " && ".join(parts)
122+
try:
123+
return subprocess.call(["bash", "-lc", bash_cmd], env=env)
124+
except Exception as e:
125+
print(f"Fehler beim Starten von Spyder über conda activate: {e}", file=sys.stderr)
126+
# fall through to fallback
127+
# Fallback: conda run
128+
try:
129+
cmd = ["conda", "run", "-n", env_name, "--no-capture-output", "spyder"]
130+
return subprocess.call(cmd, env=env)
131+
except FileNotFoundError:
132+
print("Fehler: 'conda' nicht gefunden. Stelle sicher, dass Anaconda/Miniconda installiert und in PATH ist.", file=sys.stderr)
133+
return 3
134+
except Exception as e:
135+
print(f"Fehler beim Starten von Spyder: {e}", file=sys.stderr)
136+
return 4
137+
138+
139+
def main():
140+
parser = argparse.ArgumentParser(prog="semi-ate", description="Wähle conda-env basierend auf project+version und starte Spyder.")
141+
parser.add_argument("project", nargs="?", help="Projektname (oder leer, wenn -e/-m benutzt wird)")
142+
parser.add_argument("version", nargs="?", help="Version als 4-stellige Zahl, z.B. 0001 (oder leer, wenn -e/-m benutzt wird)")
143+
parser.add_argument("-w", "--who", metavar="name", help="optional: USER=name setzen")
144+
parser.add_argument("-e", "--edit", action="store_true", help="optional: edit path to Projects")
145+
args = parser.parse_args()
146+
147+
# Normaler Start: require project+version
148+
if not args.project or not args.version:
149+
parser.print_usage()
150+
print("\nError: project and version are required.", file=sys.stderr)
151+
sys.exit(1)
152+
153+
sa = SemiAte(args)
154+
155+
if args.who:
156+
print(f"USER set to: {args.who}")
157+
158+
#rc = sa.start_spyder_in_env(env_name, args.project, args.version, args.who)
159+
# sys.exit(rc)
160+
161+
162+
if __name__ == "__main__":
163+
main()

pyproject.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ dependencies = [
5959
"pyvisa-py",
6060
"regex",
6161
"semi-ate-common",
62+
"yaml",
6263
]
6364

6465
[project.optional-dependencies]
@@ -79,4 +80,7 @@ test = [
7980
]
8081

8182
[project.entry-points."ate.org"]
82-
pylabml = "pylab_ml.plugins.pylabml.instruments:Plugin"
83+
pylabml = "pylab_ml.plugins.pylabml.instruments:Plugin"
84+
85+
[project.scripts]
86+
enter_semiate = "pylab_ml.scripts.enter_semiate:main"

0 commit comments

Comments
 (0)