mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-09-20 17:25:52 +03:00
feat(db-*,epf-*,erf-*,web-publish): v8path на уровне записи базы
В одном проекте базы могут жить на разных версиях платформы, а версию формата
XML-выгрузки задаёт та платформа, которая выгружает: без выбора платформы по базе
срабатывает автопоиск и берёт самую старшую установленную — то есть самый новый
формат, который коллега на младшей платформе уже не загрузит.
Теперь порядок такой: явный -V8Path -> v8path записи базы -> корневой v8path ->
автопоиск. Запись базы ищет сам скрипт тем же матчем, которым добывал реквизиты
хранилища (Find-ProjectDatabase): файловую по path, серверную по server + ref.
- в 9 навыков, где матча не было, скопирован блок из авторитета db-repo;
- списки потребителей трёх семей в check-inline-drift расширены; заведена семья
platform: resolve_v8path — обёртка меняла сигнатуру, а под гардом не была;
- раннер подставляет {workDir}/{fakePlatform} и в содержимое preRun.writeFile,
иначе кейс про выбор платформы нельзя написать кроссплатформенно;
- в SKILL.md платформа теперь берётся ПОСЛЕ разрешения базы, строка про
автоопределение через Program Files убрана как деталь реализации.
Живой прогон: две базы в одном проекте при корневом v8path = 8.5 дали формат
2.17 (8.3.24) и 2.20 (8.3.27), оба порта.
Closes #93
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
303db4e9f9
commit
874ae650ca
@@ -1,4 +1,4 @@
|
||||
# epf-dump v1.15 — Dump external data processor or report (EPF/ERF) to XML sources
|
||||
# epf-dump v1.16 — Dump external data processor or report (EPF/ERF) to XML sources
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
# NB: *nix-раскладку платформы (/opt/1cv8/<ver>/1cv8, без .exe) знает только .py-порт — PS на *nix не исполняется.
|
||||
<#
|
||||
@@ -267,8 +267,52 @@ function Assert-InfoBaseExists {
|
||||
|
||||
Assert-InfoBaseExists $InfoBasePath
|
||||
|
||||
# --- Запись базы в .v8-project.json ---
|
||||
# Модель не передаёт ни путь к платформе конкретной базы, ни реквизиты хранилища: скрипт
|
||||
# сопоставляет параметры соединения с записью в databases[] и берёт их оттуда. Тот же приём,
|
||||
# что в cf-edit.ps1 (сопоставление по configSrc).
|
||||
function Find-V8Project([string]$startDir) {
|
||||
$d = $startDir
|
||||
for ($i = 0; $i -lt 20 -and $d; $i++) {
|
||||
$pj = Join-Path $d ".v8-project.json"
|
||||
if (Test-Path $pj) { return $pj }
|
||||
$parent = [System.IO.Path]::GetDirectoryName($d)
|
||||
if ($parent -eq $d) { break }
|
||||
$d = $parent
|
||||
}
|
||||
return $null
|
||||
}
|
||||
function Test-SamePath {
|
||||
param([string]$A, [string]$B)
|
||||
if (-not $A -or -not $B) { return $false }
|
||||
try {
|
||||
$na = [System.IO.Path]::GetFullPath($A).TrimEnd('\', '/')
|
||||
$nb = [System.IO.Path]::GetFullPath($B).TrimEnd('\', '/')
|
||||
return $na.Equals($nb, [System.StringComparison]::OrdinalIgnoreCase)
|
||||
} catch { return $false }
|
||||
}
|
||||
function Find-ProjectDatabase {
|
||||
# Запись базы в реестре, соответствующая переданному соединению. $null, если не найдена.
|
||||
$pf = Find-V8Project (Get-Location).Path
|
||||
if (-not $pf) { return $null }
|
||||
try { $proj = Get-Content $pf -Raw -Encoding UTF8 | ConvertFrom-Json } catch { return $null }
|
||||
if (-not $proj.databases) { return $null }
|
||||
foreach ($db in $proj.databases) {
|
||||
if ($InfoBasePath -and $db.path -and (Test-SamePath $db.path $InfoBasePath)) { return $db }
|
||||
if ($InfoBaseServer -and $InfoBaseRef -and $db.server -and $db.ref) {
|
||||
if ($db.server.Equals($InfoBaseServer, [System.StringComparison]::OrdinalIgnoreCase) -and
|
||||
$db.ref.Equals($InfoBaseRef, [System.StringComparison]::OrdinalIgnoreCase)) { return $db }
|
||||
}
|
||||
}
|
||||
return $null
|
||||
}
|
||||
|
||||
# --- Resolve V8Path ---
|
||||
function Find-ProjectV8Path {
|
||||
# v8path записи базы сильнее корневого: в одном проекте базы живут на разных версиях
|
||||
# платформы, а версию формата выгрузки задаёт та платформа, которая выгружает.
|
||||
$dbRec = Find-ProjectDatabase
|
||||
if ($dbRec -and $dbRec.v8path) { return [string]$dbRec.v8path }
|
||||
$dir = (Get-Location).Path
|
||||
while ($dir) {
|
||||
$pf = Join-Path $dir ".v8-project.json"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# epf-dump v1.15 — Dump external data processor or report (EPF/ERF) to XML sources
|
||||
# epf-dump v1.16 — Dump external data processor or report (EPF/ERF) to XML sources
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
@@ -37,8 +37,62 @@ def ci_parse_args(parser, argv=None):
|
||||
|
||||
|
||||
|
||||
def _find_project_v8path():
|
||||
"""Walk up from CWD to find .v8-project.json and read its v8path."""
|
||||
# --- Запись базы в .v8-project.json ---
|
||||
# Модель не передаёт ни путь к платформе конкретной базы, ни реквизиты хранилища: скрипт
|
||||
# сопоставляет параметры соединения с записью в databases[] и берёт их оттуда. Тот же приём,
|
||||
# что в cf-edit.py (сопоставление по configSrc).
|
||||
def _sg_find_v8project(start_dir):
|
||||
d = start_dir
|
||||
for _ in range(20):
|
||||
if not d:
|
||||
break
|
||||
pj = os.path.join(d, ".v8-project.json")
|
||||
if os.path.isfile(pj):
|
||||
return pj
|
||||
parent = os.path.dirname(d)
|
||||
if parent == d:
|
||||
break
|
||||
d = parent
|
||||
return None
|
||||
|
||||
def same_path(a, b):
|
||||
if not a or not b:
|
||||
return False
|
||||
try:
|
||||
return os.path.abspath(a).rstrip("\\/").lower() == os.path.abspath(b).rstrip("\\/").lower()
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
def find_project_database(args):
|
||||
"""Запись базы в реестре, соответствующая переданному соединению. None, если не найдена."""
|
||||
pf = _sg_find_v8project(os.getcwd())
|
||||
if not pf:
|
||||
return None
|
||||
try:
|
||||
with open(pf, encoding="utf-8-sig") as f:
|
||||
proj = json.load(f)
|
||||
except Exception:
|
||||
return None
|
||||
for db in proj.get("databases") or []:
|
||||
if args.InfoBasePath and db.get("path") and same_path(db["path"], args.InfoBasePath):
|
||||
return db
|
||||
if args.InfoBaseServer and args.InfoBaseRef and db.get("server") and db.get("ref"):
|
||||
if (db["server"].lower() == args.InfoBaseServer.lower()
|
||||
and db["ref"].lower() == args.InfoBaseRef.lower()):
|
||||
return db
|
||||
return None
|
||||
|
||||
|
||||
def _find_project_v8path(args):
|
||||
"""Walk up from CWD to find .v8-project.json and read its v8path.
|
||||
|
||||
v8path записи базы сильнее корневого: в одном проекте базы живут на разных версиях
|
||||
платформы, а версию формата выгрузки задаёт та платформа, которая выгружает.
|
||||
"""
|
||||
db = find_project_database(args)
|
||||
if db and db.get("v8path"):
|
||||
return db["v8path"]
|
||||
d = os.getcwd()
|
||||
while True:
|
||||
pf = os.path.join(d, ".v8-project.json")
|
||||
@@ -243,10 +297,10 @@ def _version_key(p):
|
||||
return [int(x) for x in re.findall(r"\d+", _version_dir(p))]
|
||||
|
||||
|
||||
def resolve_v8path(v8path):
|
||||
def resolve_v8path(v8path, args):
|
||||
"""Resolve path to a 1C executable (1cv8; ibcmd only when given explicitly)."""
|
||||
if not v8path:
|
||||
v8path = _find_project_v8path()
|
||||
v8path = _find_project_v8path(args)
|
||||
if not v8path:
|
||||
if os.name == "nt":
|
||||
candidates = (
|
||||
@@ -446,7 +500,7 @@ def main():
|
||||
args.OutputDir = clean_path(args.OutputDir, "-OutputDir")
|
||||
|
||||
# --- Resolve V8Path ---
|
||||
v8path = resolve_v8path(args.V8Path)
|
||||
v8path = resolve_v8path(args.V8Path, args)
|
||||
engine = "ibcmd" if os.path.basename(v8path).lower().startswith("ibcmd") else "1cv8"
|
||||
|
||||
# --- Resolve additional arguments for the selected engine ---
|
||||
|
||||
Reference in New Issue
Block a user