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}')
128 repoRoot=os.path.abspath(repoRoot)
129 timestamp=timestamp
or datetime.now().strftime(
'%Y%m%d-%H%M%S')
131 runsRoot=os.path.join(repoRoot,
'PCARTRuns',
'runs')
132 os.makedirs(runsRoot, exist_ok=
True)
133 runId,runRoot=_nextRunId(runsRoot,projectSlug,timestamp)
135 workspaceRoot=os.path.join(runRoot,commandId)
136 os.mkdir(workspaceRoot)
137 copyRoot=os.path.join(workspaceRoot,
'Copy')
138 dynamicRoot=os.path.join(workspaceRoot,
'Dynamic')
139 dataDir=os.path.join(workspaceRoot,
'data')
140 tempDir=os.path.join(workspaceRoot,
'temp')
141 internalReportDir=os.path.join(workspaceRoot,
'Report')
142 reportRoot=os.path.join(repoRoot,
'Report',
'runs',runId,commandId)
143 metadataPath=os.path.join(workspaceRoot,
'metadata.json')
152 os.path.join(reportRoot,
'patches'),
153 os.path.join(reportRoot,
'fixed_project'),
155 os.makedirs(path,exist_ok=
True)
157 workspace=
RunWorkspace(repo_root=repoRoot,run_id=runId,command_id=commandId,run_root=runRoot,workspace_root=workspaceRoot,copy_root=copyRoot,dynamic_root=dynamicRoot,data_dir=dataDir,temp_dir=tempDir,internal_report_dir=internalReportDir,report_root=reportRoot,metadata_path=metadataPath)
161 'project_slug': projectSlug,
162 'project_path': projPath,
163 'run_command': runCommand,
164 'run_file_path': runPath,
166 'current_version': currentVersion,
167 'target_version': targetVersion,
168 'current_env': currentEnv,
169 'target_env': targetEnv,
170 'write_patch': writePatch,
183 content=asdict(workspace)
184 content.update(metadata)
185 with open(workspace.metadata_path,
'w',encoding=
'utf-8')
as fw:
186 json.dump(content,fw,ensure_ascii=
False,indent=2)
199 'workspace_root': workspace.workspace_root,
200 'copy_root': workspace.copy_root,
201 'dynamic_root': workspace.dynamic_root,
202 'data_dir': workspace.data_dir,
203 'temp_dir': workspace.temp_dir,
204 'report_dir': workspace.internal_report_dir,
230 os.makedirs(workspace.report_root, exist_ok=
True)
231 os.makedirs(os.path.join(workspace.report_root,
'patches'),exist_ok=
True)
232 os.makedirs(os.path.join(workspace.report_root,
'fixed_project'),exist_ok=
True)
233 if not os.path.isdir(workspace.internal_report_dir):
235 for name
in os.listdir(workspace.internal_report_dir):
236 source=os.path.join(workspace.internal_report_dir,name)
237 target=os.path.join(workspace.report_root,name)
238 if os.path.isdir(source):
239 if os.path.exists(target):
240 shutil.rmtree(target)
241 shutil.copytree(source,target)
243 shutil.copy2(source,target)
255 runsRoot=os.path.realpath(os.path.join(workspace.repo_root,
'PCARTRuns',
'runs'))
256 runRoot=os.path.realpath(workspace.run_root)
257 normalizedRunsRoot=os.path.normcase(os.path.normpath(runsRoot))
258 normalizedParent=os.path.normcase(os.path.normpath(os.path.dirname(runRoot)))
260 if normalizedParent!=normalizedRunsRoot:
261 raise ValueError(f
'Refuse to remove workspace outside PCARTRuns/runs: {runRoot}')
263 if os.path.isdir(runRoot):
264 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, writePatch=False)
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 写入运行工作区元数据