21 from contextlib
import contextmanager
22 from dataclasses
import asdict,dataclass
23 from datetime
import datetime
43 internal_report_dir: str
53 return os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
62 normalized=str(projPath).strip().rstrip(
'/\\')
65 name=re.split(
r'[\\/]+',normalized)[-1]
66 slug=re.sub(
r'[^A-Za-z0-9._-]+',
'-',name).strip(
'.-_')
67 return slug
or 'project'
81 def _nextRunId(runsRoot,projectSlug,timestamp):
82 prefix=f
'{projectSlug}__{timestamp}'
83 for index
in range(1, 1000):
84 runId=f
'{prefix}-{index:03d}'
85 runRoot=os.path.join(runsRoot,runId)
89 except FileExistsError:
91 raise RuntimeError(f
'Cannot allocate run id for {prefix}')
126 repoRoot=os.path.abspath(repoRoot)
127 timestamp=timestamp
or datetime.now().strftime(
'%Y%m%d-%H%M%S')
129 runsRoot=os.path.join(repoRoot,
'PCARTRuns',
'runs')
130 os.makedirs(runsRoot, exist_ok=
True)
131 runId,runRoot=_nextRunId(runsRoot,projectSlug,timestamp)
133 workspaceRoot=os.path.join(runRoot,commandId)
134 os.mkdir(workspaceRoot)
135 copyRoot=os.path.join(workspaceRoot,
'Copy')
136 dynamicRoot=os.path.join(workspaceRoot,
'Dynamic')
137 dataDir=os.path.join(workspaceRoot,
'data')
138 tempDir=os.path.join(workspaceRoot,
'temp')
139 internalReportDir=os.path.join(workspaceRoot,
'Report')
140 reportRoot=os.path.join(repoRoot,
'Report',
'runs',runId,commandId)
141 metadataPath=os.path.join(workspaceRoot,
'metadata.json')
150 os.path.join(reportRoot,
'patches'),
151 os.path.join(reportRoot,
'fixed_project'),
153 os.makedirs(path,exist_ok=
True)
158 command_id=commandId,
160 workspace_root=workspaceRoot,
162 dynamic_root=dynamicRoot,
165 internal_report_dir=internalReportDir,
166 report_root=reportRoot,
167 metadata_path=metadataPath,
172 'project_slug': projectSlug,
173 'project_path': projPath,
174 'run_command': runCommand,
175 'run_file_path': runPath,
177 'current_version': currentVersion,
178 'target_version': targetVersion,
179 'current_env': currentEnv,
180 'target_env': targetEnv,
193 content=asdict(workspace)
194 content.update(metadata)
195 with open(workspace.metadata_path,
'w',encoding=
'utf-8')
as fw:
196 json.dump(content,fw,ensure_ascii=
False,indent=2)
209 'workspace_root': workspace.workspace_root,
210 'copy_root': workspace.copy_root,
211 'dynamic_root': workspace.dynamic_root,
212 'data_dir': workspace.data_dir,
213 'temp_dir': workspace.temp_dir,
214 'report_dir': workspace.internal_report_dir,
240 os.makedirs(workspace.report_root, exist_ok=
True)
241 os.makedirs(os.path.join(workspace.report_root,
'patches'),exist_ok=
True)
242 os.makedirs(os.path.join(workspace.report_root,
'fixed_project'),exist_ok=
True)
243 if not os.path.isdir(workspace.internal_report_dir):
245 for name
in os.listdir(workspace.internal_report_dir):
246 source=os.path.join(workspace.internal_report_dir,name)
247 target=os.path.join(workspace.report_root,name)
248 if os.path.isdir(source):
249 if os.path.exists(target):
250 shutil.rmtree(target)
251 shutil.copytree(source,target)
253 shutil.copy2(source,target)
265 runsRoot=os.path.realpath(
266 os.path.join(workspace.repo_root,
'PCARTRuns',
'runs')
268 runRoot=os.path.realpath(workspace.run_root)
269 normalizedRunsRoot=os.path.normcase(os.path.normpath(runsRoot))
270 normalizedParent=os.path.normcase(
271 os.path.normpath(os.path.dirname(runRoot))
274 if normalizedParent!=normalizedRunsRoot:
276 f
'Refuse to remove workspace outside PCARTRuns/runs: {runRoot}'
279 if os.path.isdir(runRoot):
280 shutil.rmtree(runRoot)
Run workspace path object PCART单次运行的工作区路径对象
def getRepoRoot()
Get PCART repository root path 获取PCART仓库根目录路径
def cleanupRunWorkspace(workspace)
Remove one completed PCART run workspace 删除一次已完成的PCART运行工作区
def exportRunReport(workspace)
Export internal report files to user-visible report directory 将工作区内部报告导出到用户可见报告目录
def slugifyProjectName(projPath)
Convert project path/name to a filesystem-safe slug 将项目路径或项目名转换为可作为目录名使用的slug.
def createRunWorkspace(repoRoot, projPath, runCommand, runPath, libName, currentVersion, targetVersion, currentEnv, targetEnv, commandId='cmd-001', timestamp=None)
Create an isolated workspace for one PCART run command 为一次PCART运行命令创建隔离工作区
def getRuntimePaths(workspace)
Return runtime artifact paths for the current execution 返回当前执行使用的运行产物路径
def writeMetadata(workspace, metadata)
Write workspace metadata 写入运行工作区元数据