mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-09-30 14:05:53 +03:00
feat(v8-xsd-fetch): загрузка XSD-схем платформы в .v8-xsd
Схемы формата выгрузки по версиям формата из yellow-hammer/namespace-forest раскладываются в .v8-xsd/<версия>/ (или по xsdPath из .v8-project.json) — основа проверки выгрузки по XSD без базы (#101). Сами схемы — собственность 1С-Софт, в репозиторий не входят: в .gitignore, в каталоге только README. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018dc2yLQfw6wppbopM1Y4Ps
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
c9a551b815
commit
c47879098e
@@ -80,6 +80,7 @@ allowed-tools:
|
||||
| `newObjectPosition` | `"end"` / `"byName"` | Куда попадает новый объект в составе конфигурации: в конец своего вида (по умолчанию) или на место по имени. Переопределяется в `databases[]` |
|
||||
| `extensionApplyCheck` | bool | Проверять ли применимость расширения после загрузки в базу (по умолчанию `true`). Разово отключается ключом `-NoApplyCheck` |
|
||||
| `externalCheck` | bool | Проверять ли исходники внешней обработки/отчёта платформой перед сборкой (по умолчанию `true`). Разово отключается ключом `-Checks off` |
|
||||
| `xsdPath` | string | Каталог XSD-схем платформы для проверки выгрузок по версиям формата; по умолчанию `.v8-xsd` рядом с этим файлом. Наполняется `/v8-xsd-fetch` |
|
||||
| `databases` | array | Массив баз данных |
|
||||
| `default` | string | id базы по умолчанию |
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
---
|
||||
name: v8-xsd-fetch
|
||||
description: Загрузка XSD-схем формата XML-выгрузки 1С по версиям формата в каталог проекта. Используй когда нужно скачать или обновить схемы платформы для проверки выгрузки по XSD, или узнать, какие версии схем доступны
|
||||
argument-hint: "[-Versions 2.20,2.21] [-List]"
|
||||
allowed-tools:
|
||||
- Bash
|
||||
- Read
|
||||
---
|
||||
|
||||
# /v8-xsd-fetch — XSD-схемы платформы
|
||||
|
||||
Скачивает XSD-схемы формата выгрузки из репозитория
|
||||
[yellow-hammer/namespace-forest](https://github.com/yellow-hammer/namespace-forest)
|
||||
и раскладывает по версиям формата: `.v8-xsd/<версия>/*.xsd`. По этим схемам навыки
|
||||
проверяют выгрузку без базы; нет схем — нет проверки.
|
||||
|
||||
## Команда
|
||||
|
||||
```powershell
|
||||
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/v8-xsd-fetch.ps1" [-Versions "2.20,2.21"] [-List]
|
||||
```
|
||||
|
||||
| Параметр | Описание |
|
||||
|----------|----------|
|
||||
| `-Versions "<список>"` | Версии формата через запятую. Без него — все доступные (около 600 КБ на версию) |
|
||||
| `-List` | Показать доступные версии и какие уже есть локально, ничего не скачивая |
|
||||
| `-OutPath <путь>` | Каталог схем, если нужен не тот, что в проекте |
|
||||
| `-Force` | Перекачать файлы, которые уже есть |
|
||||
| `-Ref <ветка/коммит>` | Состояние репозитория-источника, по умолчанию `main` |
|
||||
|
||||
## Куда кладёт
|
||||
|
||||
`-OutPath` → `xsdPath` из `.v8-project.json` (относительно файла) → `.v8-xsd` рядом с
|
||||
`.v8-project.json` → `.v8-xsd` в текущем каталоге.
|
||||
|
||||
Рядом со схемами — `README.md` (что это и откуда) и `source.json` (репозиторий, коммит, дата).
|
||||
Схемы — собственность ООО «1С-Софт»: каталог в Git не добавлять, его место в `.gitignore`.
|
||||
|
||||
## Какую версию брать
|
||||
|
||||
Версия формата — атрибут `version` корня `Configuration.xml` выгрузки (например, `2.20`),
|
||||
а не номер релиза платформы. Достаточно версий тех выгрузок, с которыми работает проект.
|
||||
|
||||
Без сети: скопировать каталоги `schemas/designer/<версия>/` из репозитория-источника вручную.
|
||||
@@ -0,0 +1,175 @@
|
||||
# v8-xsd-fetch v1.0 — Download 1C platform XSD schemas (dump format) into .v8-xsd
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Загрузка XSD-схем формата выгрузки 1С по версиям формата
|
||||
|
||||
.DESCRIPTION
|
||||
Скачивает schemas/designer/<версия>/*.xsd из репозитория yellow-hammer/namespace-forest
|
||||
в каталог схем проекта: -OutPath, иначе xsdPath из .v8-project.json, иначе .v8-xsd
|
||||
рядом с .v8-project.json (нет его — в текущем каталоге).
|
||||
|
||||
.EXAMPLE
|
||||
.\v8-xsd-fetch.ps1 -Versions "2.20,2.21"
|
||||
|
||||
.EXAMPLE
|
||||
.\v8-xsd-fetch.ps1 -List
|
||||
#>
|
||||
|
||||
[CmdletBinding(PositionalBinding=$false)]
|
||||
param(
|
||||
# Списком одной строкой: powershell -File не связывает массивы
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string]$Versions,
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string]$OutPath,
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string]$Ref = "main",
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[switch]$Force,
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[switch]$List
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
||||
|
||||
$repo = "yellow-hammer/namespace-forest"
|
||||
$repoUrl = "https://github.com/$repo"
|
||||
|
||||
# Текст README — в templates/ навыка, одна копия на оба порта
|
||||
$readmeTemplate = Join-Path $PSScriptRoot "../templates/README.md"
|
||||
|
||||
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 Fail([string]$msg) {
|
||||
Write-Host "Error: $msg" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
# --- Версии: проверяем до сети ---
|
||||
$wanted = @()
|
||||
if ($Versions) {
|
||||
foreach ($v in ($Versions -split '[,;\s]+')) {
|
||||
if (-not $v) { continue }
|
||||
if ($v -notmatch '^\d+\.\d+$') { Fail "неверная версия формата '$v' (ожидается вида 2.20)" }
|
||||
if ($wanted -notcontains $v) { $wanted += $v }
|
||||
}
|
||||
}
|
||||
|
||||
# --- Каталог схем ---
|
||||
$cwd = (Get-Location).Path
|
||||
$pj = Find-V8Project $cwd
|
||||
$target = $null
|
||||
if ($OutPath) {
|
||||
$target = if ([System.IO.Path]::IsPathRooted($OutPath)) { $OutPath } else { Join-Path $cwd $OutPath }
|
||||
} elseif ($pj) {
|
||||
$pjDir = [System.IO.Path]::GetDirectoryName($pj)
|
||||
try { $cfg = Get-Content -LiteralPath $pj -Raw -Encoding UTF8 | ConvertFrom-Json } catch { $cfg = $null }
|
||||
if ($cfg -and $cfg.xsdPath) {
|
||||
$target = if ([System.IO.Path]::IsPathRooted($cfg.xsdPath)) { $cfg.xsdPath } else { Join-Path $pjDir $cfg.xsdPath }
|
||||
} else {
|
||||
$target = Join-Path $pjDir ".v8-xsd"
|
||||
}
|
||||
} else {
|
||||
$target = Join-Path $cwd ".v8-xsd"
|
||||
}
|
||||
$target = [System.IO.Path]::GetFullPath($target)
|
||||
if (Test-Path -LiteralPath $target -PathType Leaf) { Fail "каталог схем '$target' — это файл" }
|
||||
|
||||
# --- Состав репозитория ---
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
$wc = New-Object System.Net.WebClient
|
||||
$wc.Headers.Add("User-Agent", "v8-xsd-fetch")
|
||||
$wc.Encoding = [System.Text.Encoding]::UTF8
|
||||
try {
|
||||
$tree = $wc.DownloadString("https://api.github.com/repos/$repo/git/trees/$([uri]::EscapeDataString($Ref))?recursive=1") | ConvertFrom-Json
|
||||
} catch {
|
||||
Fail "не удалось получить состав $repo@${Ref}: $($_.Exception.Message)`nСкачайте вручную каталоги schemas/designer/<версия> из $repoUrl в '$target'"
|
||||
}
|
||||
$commit = $tree.sha
|
||||
|
||||
$byVersion = @{}
|
||||
foreach ($node in $tree.tree) {
|
||||
if ($node.type -ne 'blob') { continue }
|
||||
$m = [regex]::Match($node.path, '^schemas/designer/(\d+\.\d+)/([^/]+\.xsd)$')
|
||||
if (-not $m.Success) { continue }
|
||||
$v = $m.Groups[1].Value
|
||||
if (-not $byVersion.ContainsKey($v)) { $byVersion[$v] = New-Object System.Collections.ArrayList }
|
||||
[void]$byVersion[$v].Add(@{ path = $node.path; name = $m.Groups[2].Value })
|
||||
}
|
||||
$available = @($byVersion.Keys | Sort-Object { [version]$_ })
|
||||
if ($available.Count -eq 0) { Fail "в $repo@$Ref нет каталогов schemas/designer/<версия>" }
|
||||
|
||||
if ($List) {
|
||||
Write-Host "Версии формата в $repo@${Ref}:"
|
||||
foreach ($v in $available) {
|
||||
$mark = if (Test-Path -LiteralPath (Join-Path $target $v) -PathType Container) { " (есть локально)" } else { "" }
|
||||
Write-Host " $v — $($byVersion[$v].Count) схем$mark"
|
||||
}
|
||||
Write-Host "Каталог схем: $target"
|
||||
exit 0
|
||||
}
|
||||
|
||||
if ($wanted.Count -eq 0) { $wanted = $available }
|
||||
$missing = @($wanted | Where-Object { $available -notcontains $_ })
|
||||
if ($missing.Count -gt 0) {
|
||||
Fail "версии $($missing -join ', ') нет в $repo@$Ref (есть: $($available -join ', '))"
|
||||
}
|
||||
|
||||
# --- Загрузка ---
|
||||
if (-not (Test-Path -LiteralPath $target)) { New-Item -ItemType Directory -Path $target -Force | Out-Null }
|
||||
$totalNew = 0
|
||||
foreach ($v in ($wanted | Sort-Object { [version]$_ })) {
|
||||
$dir = Join-Path $target $v
|
||||
if (-not (Test-Path -LiteralPath $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null }
|
||||
$got = 0; $kept = 0
|
||||
foreach ($f in $byVersion[$v]) {
|
||||
$dest = Join-Path $dir $f.name
|
||||
if ((Test-Path -LiteralPath $dest) -and -not $Force) { $kept++; continue }
|
||||
# Файлы берём по коммиту, а не по ветке: весь набор — из одного состояния репозитория
|
||||
$url = "https://raw.githubusercontent.com/$repo/$commit/$($f.path)"
|
||||
try {
|
||||
$bytes = $wc.DownloadData($url)
|
||||
} catch {
|
||||
Fail "не удалось скачать $($f.path): $($_.Exception.Message)"
|
||||
}
|
||||
[System.IO.File]::WriteAllBytes($dest, $bytes)
|
||||
$got++
|
||||
}
|
||||
$totalNew += $got
|
||||
$line = " ${v}: скачано $got"
|
||||
if ($kept -gt 0) { $line += ", уже было $kept" }
|
||||
Write-Host $line
|
||||
}
|
||||
|
||||
# --- README и source.json ---
|
||||
$readmePath = Join-Path $target "README.md"
|
||||
if (-not (Test-Path -LiteralPath $readmePath) -and (Test-Path -LiteralPath $readmeTemplate)) {
|
||||
Copy-Item -LiteralPath $readmeTemplate -Destination $readmePath
|
||||
}
|
||||
$localVersions = @(Get-ChildItem -LiteralPath $target -Directory |
|
||||
Where-Object { $_.Name -match '^\d+\.\d+$' } |
|
||||
ForEach-Object { $_.Name } | Sort-Object { [version]$_ })
|
||||
# Руками, а не ConvertTo-Json: форматирование PS 5.1 не совпало бы с py-портом
|
||||
$fetched = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
|
||||
$verJson = ($localVersions | ForEach-Object { "`"$_`"" }) -join ", "
|
||||
$srcJson = "{`n `"repository`": `"$repoUrl`",`n `"ref`": `"$($Ref -replace '\\','\\' -replace '"','\"')`",`n `"commit`": `"$commit`",`n `"fetched`": `"$fetched`",`n `"versions`": [$verJson]`n}`n"
|
||||
$enc = New-Object System.Text.UTF8Encoding($false)
|
||||
[System.IO.File]::WriteAllText((Join-Path $target "source.json"), $srcJson, $enc)
|
||||
|
||||
Write-Host "Схемы: $target (скачано файлов: $totalNew)"
|
||||
@@ -0,0 +1,207 @@
|
||||
#!/usr/bin/env python3
|
||||
# v8-xsd-fetch v1.0 — Download 1C platform XSD schemas (dump format) into .v8-xsd
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
"""Загрузка XSD-схем формата выгрузки 1С по версиям формата.
|
||||
|
||||
Скачивает schemas/designer/<версия>/*.xsd из репозитория yellow-hammer/namespace-forest
|
||||
в каталог схем проекта: -OutPath, иначе xsdPath из .v8-project.json, иначе .v8-xsd
|
||||
рядом с .v8-project.json (нет его — в текущем каталоге).
|
||||
"""
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
from datetime import datetime, timezone
|
||||
|
||||
sys.stdout.reconfigure(encoding="utf-8")
|
||||
sys.stderr.reconfigure(encoding="utf-8")
|
||||
|
||||
REPO = "yellow-hammer/namespace-forest"
|
||||
REPO_URL = "https://github.com/" + REPO
|
||||
TIMEOUT = 60
|
||||
|
||||
# Текст README — в templates/ навыка, одна копия на оба порта
|
||||
README_TEMPLATE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "templates", "README.md")
|
||||
|
||||
|
||||
def ci_parse_args(parser, argv=None):
|
||||
"""parse_args по правилам PS: имена параметров и значения choices регистронезависимы."""
|
||||
argv = list(sys.argv[1:] if argv is None else argv)
|
||||
names = {s.lower(): s for a in parser._actions for s in a.option_strings}
|
||||
for i, tok in enumerate(argv):
|
||||
if tok.startswith('-') and tok.lower() in names:
|
||||
argv[i] = names[tok.lower()]
|
||||
# choices — зеркало [ValidateSet]; канонизируем ДО разбора, иначе argparse отвергнет регистр
|
||||
choice_map = {}
|
||||
for a in parser._actions:
|
||||
if a.choices:
|
||||
for s in a.option_strings:
|
||||
choice_map[s] = {str(c).lower(): c for c in a.choices}
|
||||
for i in range(len(argv) - 1):
|
||||
m = choice_map.get(argv[i])
|
||||
if m and argv[i + 1].lower() in m:
|
||||
argv[i + 1] = m[argv[i + 1].lower()]
|
||||
return parser.parse_args(argv)
|
||||
|
||||
|
||||
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 fail(msg):
|
||||
print("Error: " + msg)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def version_key(v):
|
||||
return tuple(int(x) for x in v.split("."))
|
||||
|
||||
|
||||
def http_get(url):
|
||||
req = urllib.request.Request(url, headers={"User-Agent": "v8-xsd-fetch"})
|
||||
with urllib.request.urlopen(req, timeout=TIMEOUT) as resp:
|
||||
return resp.read()
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Download 1C platform XSD schemas into .v8-xsd", allow_abbrev=False)
|
||||
# Списком одной строкой — паритет с PS: powershell -File не связывает массивы
|
||||
parser.add_argument("-Versions", default="")
|
||||
parser.add_argument("-OutPath", default="")
|
||||
parser.add_argument("-Ref", default="main")
|
||||
parser.add_argument("-Force", action="store_true")
|
||||
parser.add_argument("-List", action="store_true")
|
||||
args = ci_parse_args(parser)
|
||||
ref = args.Ref
|
||||
|
||||
# --- Версии: проверяем до сети ---
|
||||
wanted = []
|
||||
if args.Versions:
|
||||
for v in re.split(r"[,;\s]+", args.Versions):
|
||||
if not v:
|
||||
continue
|
||||
if not re.match(r"^\d+\.\d+$", v):
|
||||
fail("неверная версия формата '%s' (ожидается вида 2.20)" % v)
|
||||
if v not in wanted:
|
||||
wanted.append(v)
|
||||
|
||||
# --- Каталог схем ---
|
||||
cwd = os.getcwd()
|
||||
pj = _sg_find_v8project(cwd)
|
||||
if args.OutPath:
|
||||
target = args.OutPath if os.path.isabs(args.OutPath) else os.path.join(cwd, args.OutPath)
|
||||
elif pj:
|
||||
pj_dir = os.path.dirname(pj)
|
||||
try:
|
||||
with open(pj, encoding="utf-8-sig") as f:
|
||||
cfg = json.load(f)
|
||||
except Exception:
|
||||
cfg = None
|
||||
xsd_path = cfg.get("xsdPath") if isinstance(cfg, dict) else None
|
||||
if xsd_path:
|
||||
target = xsd_path if os.path.isabs(xsd_path) else os.path.join(pj_dir, xsd_path)
|
||||
else:
|
||||
target = os.path.join(pj_dir, ".v8-xsd")
|
||||
else:
|
||||
target = os.path.join(cwd, ".v8-xsd")
|
||||
target = os.path.abspath(target)
|
||||
if os.path.isfile(target):
|
||||
fail("каталог схем '%s' — это файл" % target)
|
||||
|
||||
# --- Состав репозитория ---
|
||||
try:
|
||||
tree = json.loads(http_get("https://api.github.com/repos/%s/git/trees/%s?recursive=1"
|
||||
% (REPO, urllib.parse.quote(ref, safe=""))).decode("utf-8"))
|
||||
except Exception as e:
|
||||
fail("не удалось получить состав %s@%s: %s\nСкачайте вручную каталоги schemas/designer/<версия> из %s в '%s'"
|
||||
% (REPO, ref, e, REPO_URL, target))
|
||||
commit = tree.get("sha", "")
|
||||
|
||||
by_version = {}
|
||||
for node in tree.get("tree", []):
|
||||
if node.get("type") != "blob":
|
||||
continue
|
||||
m = re.match(r"^schemas/designer/(\d+\.\d+)/([^/]+\.xsd)$", node.get("path", ""))
|
||||
if not m:
|
||||
continue
|
||||
by_version.setdefault(m.group(1), []).append({"path": node["path"], "name": m.group(2)})
|
||||
available = sorted(by_version.keys(), key=version_key)
|
||||
if not available:
|
||||
fail("в %s@%s нет каталогов schemas/designer/<версия>" % (REPO, ref))
|
||||
|
||||
if args.List:
|
||||
print("Версии формата в %s@%s:" % (REPO, ref))
|
||||
for v in available:
|
||||
mark = " (есть локально)" if os.path.isdir(os.path.join(target, v)) else ""
|
||||
print(" %s — %d схем%s" % (v, len(by_version[v]), mark))
|
||||
print("Каталог схем: " + target)
|
||||
sys.exit(0)
|
||||
|
||||
if not wanted:
|
||||
wanted = list(available)
|
||||
missing = [v for v in wanted if v not in available]
|
||||
if missing:
|
||||
fail("версии %s нет в %s@%s (есть: %s)" % (", ".join(missing), REPO, ref, ", ".join(available)))
|
||||
|
||||
# --- Загрузка ---
|
||||
os.makedirs(target, exist_ok=True)
|
||||
total_new = 0
|
||||
for v in sorted(wanted, key=version_key):
|
||||
vdir = os.path.join(target, v)
|
||||
os.makedirs(vdir, exist_ok=True)
|
||||
got = kept = 0
|
||||
for f in by_version[v]:
|
||||
dest = os.path.join(vdir, f["name"])
|
||||
if os.path.exists(dest) and not args.Force:
|
||||
kept += 1
|
||||
continue
|
||||
# Файлы берём по коммиту, а не по ветке: весь набор — из одного состояния репозитория
|
||||
url = "https://raw.githubusercontent.com/%s/%s/%s" % (REPO, commit, f["path"])
|
||||
try:
|
||||
data = http_get(url)
|
||||
except Exception as e:
|
||||
fail("не удалось скачать %s: %s" % (f["path"], e))
|
||||
with open(dest, "wb") as out:
|
||||
out.write(data)
|
||||
got += 1
|
||||
total_new += got
|
||||
line = " %s: скачано %d" % (v, got)
|
||||
if kept > 0:
|
||||
line += ", уже было %d" % kept
|
||||
print(line)
|
||||
|
||||
# --- README и source.json ---
|
||||
readme_path = os.path.join(target, "README.md")
|
||||
if not os.path.exists(readme_path) and os.path.isfile(README_TEMPLATE):
|
||||
shutil.copyfile(README_TEMPLATE, readme_path)
|
||||
local_versions = sorted((d for d in os.listdir(target)
|
||||
if re.match(r"^\d+\.\d+$", d) and os.path.isdir(os.path.join(target, d))),
|
||||
key=version_key)
|
||||
fetched = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||
ver_json = ", ".join('"%s"' % v for v in local_versions)
|
||||
ref_json = ref.replace("\\", "\\\\").replace('"', '\\"')
|
||||
src_json = ('{\n "repository": "%s",\n "ref": "%s",\n "commit": "%s",\n "fetched": "%s",\n "versions": [%s]\n}\n'
|
||||
% (REPO_URL, ref_json, commit, fetched, ver_json))
|
||||
with open(os.path.join(target, "source.json"), "w", encoding="utf-8", newline="\n") as out:
|
||||
out.write(src_json)
|
||||
|
||||
print("Схемы: %s (скачано файлов: %d)" % (target, total_new))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,39 @@
|
||||
# .v8-xsd — XSD-схемы платформы 1С:Предприятие 8
|
||||
|
||||
Каталог для XSD-схем формата XML-выгрузки конфигурации. По ним навыки проверяют выгрузку
|
||||
без базы: порядок элементов, типы значений, допустимые значения перечислений.
|
||||
|
||||
Схем нет — проверки нет, остальное работает как обычно.
|
||||
|
||||
## Раскладка
|
||||
|
||||
```
|
||||
.v8-xsd/
|
||||
├── 2.20/ схемы версии формата 2.20 (атрибут version корня MetaDataObject)
|
||||
│ └── *.xsd
|
||||
├── 2.21/
|
||||
└── source.json откуда и когда загружено
|
||||
```
|
||||
|
||||
Имена файлов значения не имеют: схема находится по `targetNamespace`. Подойдут и схемы,
|
||||
выгруженные из своей платформы (`ФабрикаXDTO.ЭкспортСхемыXML`).
|
||||
|
||||
## Как наполнить
|
||||
|
||||
Навыком `/v8-xsd-fetch` — он скачивает схемы из репозитория
|
||||
[yellow-hammer/namespace-forest](https://github.com/yellow-hammer/namespace-forest)
|
||||
(каталог `schemas/designer/<версия формата>/`).
|
||||
|
||||
Или вручную: скопировать нужные каталоги версий из `schemas/designer/` того же репозитория.
|
||||
|
||||
Другой каталог задаётся ключом `xsdPath` в `.v8-project.json`.
|
||||
|
||||
## Лицензия
|
||||
|
||||
Схемы (`*.xsd`) — часть продукта «1С:Предприятие 8», правообладатель ООО «1С-Софт».
|
||||
Использование регулируется лицензионным соглашением 1С. В репозиторий их не включаем.
|
||||
|
||||
## Благодарность
|
||||
|
||||
Спасибо Ivan Karlo за [namespace-forest](https://github.com/yellow-hammer/namespace-forest) —
|
||||
собранные и разложенные по версиям формата схемы, обновляемые автоматически.
|
||||
@@ -31,6 +31,10 @@ __pycache__/
|
||||
# на чистом клоне не сойдётся с результатом прогона.
|
||||
!tests/skills/cases/**/.v8-project.json
|
||||
|
||||
# XSD-схемы платформы (/v8-xsd-fetch) — собственность 1С, не распространяем
|
||||
.v8-xsd/*
|
||||
!.v8-xsd/README.md
|
||||
|
||||
# web-test: Node.js зависимости и runtime-артефакты
|
||||
.claude/skills/web-test/scripts/node_modules/
|
||||
.claude/skills/web-test/.browser-session.json
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
# .v8-xsd — XSD-схемы платформы 1С:Предприятие 8
|
||||
|
||||
Каталог для XSD-схем формата XML-выгрузки конфигурации. По ним навыки проверяют выгрузку
|
||||
без базы: порядок элементов, типы значений, допустимые значения перечислений.
|
||||
|
||||
Схем нет — проверки нет, остальное работает как обычно.
|
||||
|
||||
## Раскладка
|
||||
|
||||
```
|
||||
.v8-xsd/
|
||||
├── 2.20/ схемы версии формата 2.20 (атрибут version корня MetaDataObject)
|
||||
│ └── *.xsd
|
||||
├── 2.21/
|
||||
└── source.json откуда и когда загружено
|
||||
```
|
||||
|
||||
Имена файлов значения не имеют: схема находится по `targetNamespace`. Подойдут и схемы,
|
||||
выгруженные из своей платформы (`ФабрикаXDTO.ЭкспортСхемыXML`).
|
||||
|
||||
## Как наполнить
|
||||
|
||||
Навыком `/v8-xsd-fetch` — он скачивает схемы из репозитория
|
||||
[yellow-hammer/namespace-forest](https://github.com/yellow-hammer/namespace-forest)
|
||||
(каталог `schemas/designer/<версия формата>/`).
|
||||
|
||||
Или вручную: скопировать нужные каталоги версий из `schemas/designer/` того же репозитория.
|
||||
|
||||
Другой каталог задаётся ключом `xsdPath` в `.v8-project.json`.
|
||||
|
||||
## Лицензия
|
||||
|
||||
Схемы (`*.xsd`) — часть продукта «1С:Предприятие 8», правообладатель ООО «1С-Софт».
|
||||
Использование регулируется лицензионным соглашением 1С. В репозиторий их не включаем.
|
||||
|
||||
## Благодарность
|
||||
|
||||
Спасибо Ivan Karlo за [namespace-forest](https://github.com/yellow-hammer/namespace-forest) —
|
||||
собранные и разложенные по версиям формата схемы, обновляемые автоматически.
|
||||
@@ -76,7 +76,7 @@ python tools/cc-1c-skills/scripts/switch.py
|
||||
| Тестирование (Web) | `/web-test` | Взаимодействие с веб-клиентом 1С — навигация, формы, таблицы, отчёты, тестирование | [Подробнее](docs/web-test-guide.md) |
|
||||
| Запись видео (Web) | `/web-test` | Запись видеоинструкций с субтитрами, подсветкой и TTS-озвучкой | [Подробнее](docs/web-test-recording-guide.md) |
|
||||
| Регресс прикладного решения (Web) | `/web-test` | Автоматический регресс конфигурации: тесты, проверки, отчёты, прогон после правок | [Подробнее](docs/web-test-regression-guide.md) |
|
||||
| Утилиты | `/img-grid` | Наложение сетки на изображение для определения пропорций колонок | — |
|
||||
| Утилиты | `/img-grid`, `/v8-xsd-fetch` | Сетка на изображении для определения пропорций колонок; загрузка XSD-схем платформы для проверки выгрузок | [Подробнее](docs/v8-project-guide.md#xsdpath--xsd-схемы-платформы) |
|
||||
|
||||
## Требования
|
||||
|
||||
@@ -246,7 +246,8 @@ python scripts/switch.py --runtime powershell # вернуть на PowerShell
|
||||
├── web-stop/ # Остановка Apache
|
||||
├── web-unpublish/ # Удаление публикации
|
||||
├── web-test/ # Тестирование через веб-клиент 1С
|
||||
└── img-grid/ # Сетка для анализа изображений
|
||||
├── img-grid/ # Сетка для анализа изображений
|
||||
└── v8-xsd-fetch/ # Загрузка XSD-схем платформы (.v8-xsd)
|
||||
scripts/
|
||||
└── switch.py # Переключение платформы и рантайма (13 платформ)
|
||||
docs/
|
||||
|
||||
@@ -88,6 +88,7 @@
|
||||
| `webPath` | string | нет | `tools/apache24` | Каталог Apache HTTP Server | Руками |
|
||||
| `ffmpegPath` | string | нет | `tools/ffmpeg/bin/ffmpeg.exe` | Путь к ffmpeg | Руками |
|
||||
| `tts` | object | нет | Edge TTS, DmitryNeural | Настройки озвучки видео | Руками |
|
||||
| `xsdPath` | string | нет | `.v8-xsd` | Каталог XSD-схем платформы по версиям формата (см. ниже) | Руками |
|
||||
|
||||
## Базы данных (`databases[]`)
|
||||
|
||||
@@ -257,6 +258,16 @@
|
||||
|
||||
Подробнее о выборе провайдера и голосов — в [гайде по записи видео](web-test-recording-guide.md#доступные-голоса-и-провайдеры).
|
||||
|
||||
### `xsdPath` — XSD-схемы платформы
|
||||
|
||||
Каталог XSD-схем формата выгрузки, разложенных по версиям формата: `<xsdPath>/<версия>/*.xsd`.
|
||||
По ним проверяется выгрузка без базы — порядок элементов, типы, допустимые значения.
|
||||
|
||||
Если не задан — `.v8-xsd` рядом с `.v8-project.json`. Путь считается от каталога `.v8-project.json`.
|
||||
Наполняется навыком `/v8-xsd-fetch` из репозитория
|
||||
[yellow-hammer/namespace-forest](https://github.com/yellow-hammer/namespace-forest). Схемы —
|
||||
собственность ООО «1С-Софт», в Git их не добавляют. Нет схем — нет проверки.
|
||||
|
||||
### `webUrl` — URL веб-клиента (per-database)
|
||||
|
||||
URL для открытия базы в браузере через `/web-test`. Задаётся в записи конкретной базы.
|
||||
@@ -275,6 +286,7 @@ src/
|
||||
cfe/<ИмяРасширения>/ # исходники расширения (CFE)
|
||||
epf/<ИмяОбработки>/ # исходники внешней обработки (EPF)
|
||||
erf/<ИмяОтчёта>/ # исходники внешнего отчёта (ERF)
|
||||
.v8-xsd/ # XSD-схемы платформы по версиям формата (/v8-xsd-fetch; в .gitignore)
|
||||
```
|
||||
|
||||
В `.v8-project.json` напрямую участвует только `cf` — через поле `configSrc` базы (`"src\\cf"`).
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"script": "v8-xsd-fetch/scripts/v8-xsd-fetch",
|
||||
"setup": "none",
|
||||
"args": []
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "версия не вида N.N — отказ до обращения к сети",
|
||||
"args_extra": ["-Versions", "2.20,2.x"],
|
||||
"expectError": true,
|
||||
"expect": {
|
||||
"stdoutContains": "неверная версия формата '2.x'"
|
||||
},
|
||||
"noSnapshot": "негативный кейс — навык отказывает до загрузки"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "каталог схем указывает на файл — отказ до обращения к сети",
|
||||
"preRun": [{ "writeFile": { "path": "schemas", "content": "x" } }],
|
||||
"args_extra": ["-OutPath", "{workDir}/schemas", "-Versions", "2.20"],
|
||||
"expectError": true,
|
||||
"expect": {
|
||||
"stdoutContains": "это файл"
|
||||
},
|
||||
"noSnapshot": "негативный кейс — навык отказывает до загрузки"
|
||||
}
|
||||
@@ -93,7 +93,7 @@ const FAMILIES = [
|
||||
{ id: 'full', authority: 'cf-edit',
|
||||
consumers: ['cfe-borrow', 'db-cfe-admin', 'db-create', 'db-dump-cf', 'db-dump-dt', 'db-dump-xml',
|
||||
'db-load-cf', 'db-load-dt', 'db-load-git', 'db-load-xml', 'db-repo', 'db-run', 'db-update',
|
||||
'epf-build', 'epf-dump', 'web-publish',
|
||||
'epf-build', 'epf-dump', 'web-publish', 'v8-xsd-fetch',
|
||||
'form-add', 'form-compile', 'form-edit', 'help-add', 'interface-edit', 'meta-compile',
|
||||
'meta-edit', 'meta-remove', 'mxl-compile', 'role-compile', 'role-edit', 'skd-compile', 'skd-edit',
|
||||
'subsystem-compile', 'subsystem-edit', 'template-add', 'xdto-compile', 'xdto-edit'] },
|
||||
@@ -543,7 +543,7 @@ const FAMILIES = [
|
||||
'skd-info', 'skd-validate', 'subsystem-compile', 'subsystem-edit', 'subsystem-info',
|
||||
'subsystem-validate', 'support-edit', 'template-add', 'template-remove', 'web-info',
|
||||
'web-publish', 'web-stop', 'web-unpublish', 'xdto-compile', 'xdto-decompile', 'xdto-edit',
|
||||
'xdto-info', 'xdto-validate'] },
|
||||
'xdto-info', 'xdto-validate', 'v8-xsd-fetch'] },
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user