mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-09-30 05:55:53 +03:00
fix(template-add,help-add): закрыть находки ревью по коду языка и странице
help-add терял текст справки. Отказ смотрит только на Help.xml, а страница может пережить его (удалённый дескриптор, частичная выгрузка, справка, сделанная руками): тогда запись шла безусловно и стирала содержимое с кодом 0 и рапортом [OK]. Теперь существующая страница сохраняется, создаётся только дескриптор — та же защита, что уже стоит в template-add. Прежняя оценка «в help-add потери данных нет» была неверной: она опиралась на чтение кода, а не на замер. Код языка: регулярка пропускала имена устройств Windows. При -Lang nul py-порт молча писал <Page>nul</Page> и пустой каталог с кодом 0 (страница уходила в NUL), а PS падал исключением — то есть порты ещё и расходились. Якоря \A…\z вместо ^…$: последние в обоих языках допускают перевод строки в конце. Проверка вынесена в Test-LangCode / is_valid_lang и внесена в реестр check-inline-drift: inline-блок гард не видел, а копий у него две. Плюс мелочи оттуда же: мёртвый дизъюнкт в $pageExists убран; полумигрированное дерево (дескриптор есть, старый Ext/Template.html остался рядом) теперь получает предупреждение, а не молчание; существование страницы в py сверяется без учёта регистра — иначе на Linux -Lang RU писал бы вторую страницу мимо дескриптора. Четыре кейса на каждый сценарий. Существующие эталоны не сдвинулись. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
c619da4a0a
commit
dc470a3803
@@ -1,4 +1,4 @@
|
|||||||
# help-add v1.21 — Add built-in help to 1C object (+write_xml_file/write_utf8_bom: общий эталон записи)
|
# help-add v1.22 — Add built-in help to 1C object (+write_xml_file/write_utf8_bom: общий эталон записи)
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory)]
|
[Parameter(Mandatory)]
|
||||||
@@ -185,13 +185,22 @@ if (-not (Test-Path $extDir)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Код языка идёт и в текст XML, и в имя файла страницы, поэтому проверяем его до записи:
|
# Код языка идёт и в текст XML, и в имя файла страницы, поэтому проверяем его до записи:
|
||||||
# пустое значение дало бы файл «.html» и пустой <Page></Page>, а разделитель пути —
|
# пустое значение дало бы файл «.html» и пустой <Page></Page>, разделитель пути — запись мимо
|
||||||
# запись мимо каталога Ext/Help. Оба отказа платформы были бы тихими.
|
# каталога страниц, а зарезервированное имя устройства (nul, con, prn, aux, com1…, lpt1…) на
|
||||||
|
# Windows уводит запись в само устройство. Все отказы платформы были бы тихими.
|
||||||
#
|
#
|
||||||
# Копия этой проверки есть в template-add (навыки автономны, формат «дескриптор +
|
# Якоря `\A…\z`, а не `^…$`: последние в обоих языках допускают перевод строки в конце.
|
||||||
# страница» у них общий). Держать копии одинаковыми — сознательно.
|
#
|
||||||
if ($Lang -notmatch '^[A-Za-z0-9_-]+$') {
|
# Копия этой функции есть в template-add (навыки автономны, формат «дескриптор + страница»
|
||||||
Write-Error "Недопустимый код языка: '$Lang'`nОжидается код вида ru, en (буквы, цифры, дефис, подчёркивание)"
|
# у них общий). Держать копии одинаковыми — сознательно; за дрейфом следит check-inline-drift.
|
||||||
|
function Test-LangCode([string]$code) {
|
||||||
|
if ($code -notmatch '\A[A-Za-z0-9_-]+\z') { return $false }
|
||||||
|
if ($code -match '\A(?i)(con|prn|aux|nul|com[1-9]|lpt[1-9])\z') { return $false }
|
||||||
|
return $true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not (Test-LangCode $Lang)) {
|
||||||
|
Write-Error "Недопустимый код языка: '$Lang'`nОжидается код вида ru, en (буквы, цифры, дефис, подчёркивание; имена устройств Windows недопустимы)"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,7 +259,14 @@ $helpHtml = @"
|
|||||||
</html>
|
</html>
|
||||||
"@
|
"@
|
||||||
|
|
||||||
[System.IO.File]::WriteAllText($helpHtmlPath, $helpHtml, $encBom)
|
# Файл страницы НЕ перезаписываем: отказ выше смотрит только на Help.xml, а страница может
|
||||||
|
# пережить его (удалённый дескриптор, частичная выгрузка, справка, сделанная руками) — и тогда
|
||||||
|
# безусловная запись молча стирала бы текст справки с кодом 0.
|
||||||
|
if (Test-Path $helpHtmlPath) {
|
||||||
|
Write-Host "[WARN] Страница $Lang.html уже лежала на диске — содержимое сохранено, создан только дескриптор."
|
||||||
|
} else {
|
||||||
|
[System.IO.File]::WriteAllText($helpHtmlPath, $helpHtml, $encBom)
|
||||||
|
}
|
||||||
|
|
||||||
# --- 3. Проверка IncludeHelpInContents в метаданных форм ---
|
# --- 3. Проверка IncludeHelpInContents в метаданных форм ---
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# help-add v1.21 — Add built-in help to 1C object (+write_xml_file/write_utf8_bom: общий эталон записи)
|
# help-add v1.22 — Add built-in help to 1C object (+write_xml_file/write_utf8_bom: общий эталон записи)
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
@@ -293,6 +293,26 @@ def write_utf8_bom(path, content):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def is_valid_lang(code):
|
||||||
|
"""Код языка идёт и в текст XML, и в имя файла страницы.
|
||||||
|
|
||||||
|
Пустое значение дало бы файл «.html» и пустой <Page></Page>, разделитель пути — запись
|
||||||
|
мимо каталога страниц, а зарезервированное имя устройства (nul, con, prn, aux, com1…, lpt1…)
|
||||||
|
на Windows уводит запись в само устройство: при -Lang nul этот порт молча писал
|
||||||
|
<Page>nul</Page> и пустой каталог с кодом 0. Все отказы платформы были бы тихими.
|
||||||
|
|
||||||
|
fullmatch, а не match: последний с `$` допускает перевод строки в конце.
|
||||||
|
|
||||||
|
Копия этой функции есть в template-add (навыки автономны, формат «дескриптор + страница»
|
||||||
|
у них общий). Держать копии одинаковыми — сознательно; за дрейфом следит check-inline-drift.
|
||||||
|
"""
|
||||||
|
if not re.fullmatch(r"[A-Za-z0-9_-]+", code):
|
||||||
|
return False
|
||||||
|
if re.fullmatch(r"(?i)(con|prn|aux|nul|com[1-9]|lpt[1-9])", code):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def write_xml_file(path, content):
|
def write_xml_file(path, content):
|
||||||
"""XML в каноне выгрузки Конфигуратора: CRLF в разделителях, без перевода в конце.
|
"""XML в каноне выгрузки Конфигуратора: CRLF в разделителях, без перевода в конце.
|
||||||
|
|
||||||
@@ -329,15 +349,9 @@ def main():
|
|||||||
print(f"Каталог объекта не найден: {ext_dir}. Проверьте путь ObjectName (например Catalogs/МойСправочник).", file=sys.stderr)
|
print(f"Каталог объекта не найден: {ext_dir}. Проверьте путь ObjectName (например Catalogs/МойСправочник).", file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# Код языка идёт и в текст XML, и в имя файла страницы, поэтому проверяем его до записи:
|
if not is_valid_lang(lang):
|
||||||
# пустое значение дало бы файл «.html» и пустой <Page></Page>, а разделитель пути —
|
|
||||||
# запись мимо каталога Ext/Help. Оба отказа платформы были бы тихими.
|
|
||||||
#
|
|
||||||
# Копия этой проверки есть в template-add (навыки автономны, формат «дескриптор +
|
|
||||||
# страница» у них общий). Держать копии одинаковыми — сознательно.
|
|
||||||
if not re.match(r"^[A-Za-z0-9_-]+$", lang):
|
|
||||||
print(f"Недопустимый код языка: '{lang}'", file=sys.stderr)
|
print(f"Недопустимый код языка: '{lang}'", file=sys.stderr)
|
||||||
print("Ожидается код вида ru, en (буквы, цифры, дефис, подчёркивание)", file=sys.stderr)
|
print("Ожидается код вида ru, en (буквы, цифры, дефис, подчёркивание; имена устройств Windows недопустимы)", file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
help_xml_path = os.path.join(ext_dir, "Help.xml")
|
help_xml_path = os.path.join(ext_dir, "Help.xml")
|
||||||
@@ -382,7 +396,13 @@ def main():
|
|||||||
'</html>'
|
'</html>'
|
||||||
)
|
)
|
||||||
|
|
||||||
write_utf8_bom(help_html_path, help_html)
|
# Файл страницы НЕ перезаписываем: отказ выше смотрит только на Help.xml, а страница может
|
||||||
|
# пережить его (удалённый дескриптор, частичная выгрузка, справка, сделанная руками) — и тогда
|
||||||
|
# безусловная запись молча стирала бы текст справки с кодом 0.
|
||||||
|
if os.path.exists(help_html_path):
|
||||||
|
print(f"[WARN] Страница {lang}.html уже лежала на диске — содержимое сохранено, создан только дескриптор.")
|
||||||
|
else:
|
||||||
|
write_utf8_bom(help_html_path, help_html)
|
||||||
|
|
||||||
# --- 3. Check IncludeHelpInContents in form metadata ---
|
# --- 3. Check IncludeHelpInContents in form metadata ---
|
||||||
|
|
||||||
|
|||||||
@@ -202,10 +202,23 @@ $templatesDir = Join-Path $processorDir "Templates"
|
|||||||
$templateMetaPath = Join-Path $templatesDir "$TemplateName.xml"
|
$templateMetaPath = Join-Path $templatesDir "$TemplateName.xml"
|
||||||
|
|
||||||
# Код языка идёт и в текст XML, и в имя файла страницы, поэтому проверяем его до записи:
|
# Код языка идёт и в текст XML, и в имя файла страницы, поэтому проверяем его до записи:
|
||||||
# пустое значение дало бы файл «.html» и пустой <Page></Page>, а разделитель пути —
|
# пустое значение дало бы файл «.html» и пустой <Page></Page>, разделитель пути — запись мимо
|
||||||
# запись мимо каталога Ext/Template. Оба отказа платформы были бы тихими.
|
# каталога страниц, а зарезервированное имя устройства (nul, con, prn, aux, com1…, lpt1…) на
|
||||||
if ($Lang -notmatch '^[A-Za-z0-9_-]+$') {
|
# Windows уводит запись в само устройство: py-порт при -Lang nul молча писал <Page>nul</Page>
|
||||||
Write-Error "Недопустимый код языка: '$Lang'`nОжидается код вида ru, en (буквы, цифры, дефис, подчёркивание)"
|
# и пустой каталог с кодом 0. Все отказы платформы были бы тихими.
|
||||||
|
#
|
||||||
|
# Якоря `\A…\z`, а не `^…$`: последние в обоих языках допускают перевод строки в конце.
|
||||||
|
#
|
||||||
|
# Копия этой функции есть в help-add (навыки автономны, формат «дескриптор + страница» у них
|
||||||
|
# общий). Держать копии одинаковыми — сознательно; за дрейфом следит check-inline-drift.
|
||||||
|
function Test-LangCode([string]$code) {
|
||||||
|
if ($code -notmatch '\A[A-Za-z0-9_-]+\z') { return $false }
|
||||||
|
if ($code -match '\A(?i)(con|prn|aux|nul|com[1-9]|lpt[1-9])\z') { return $false }
|
||||||
|
return $true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not (Test-LangCode $Lang)) {
|
||||||
|
Write-Error "Недопустимый код языка: '$Lang'`nОжидается код вида ru, en (буквы, цифры, дефис, подчёркивание; имена устройств Windows недопустимы)"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -358,6 +371,12 @@ if ($addLangMode) {
|
|||||||
# Версию берём из самого дескриптора: правка чужой выгрузки не должна менять формат.
|
# Версию берём из самого дескриптора: правка чужой выгрузки не должна менять формат.
|
||||||
if ($descText -match '<Help[^>]+version="(\d+\.\d+)"') { $descVersion = $Matches[1] }
|
if ($descText -match '<Help[^>]+version="(\d+\.\d+)"') { $descVersion = $Matches[1] }
|
||||||
$langs = @([regex]::Matches($descText, '<Page>([^<]+)</Page>') | ForEach-Object { $_.Groups[1].Value })
|
$langs = @([regex]::Matches($descText, '<Page>([^<]+)</Page>') | ForEach-Object { $_.Groups[1].Value })
|
||||||
|
# Полумигрированное дерево: дескриптор уже есть, а старый Ext/Template.html остался рядом.
|
||||||
|
# Платформа его игнорирует, поэтому текст в нём пропадёт незаметно — говорим вслух.
|
||||||
|
if (Test-Path $legacyPagePath) {
|
||||||
|
Write-Host "[WARN] Рядом лежит старый Ext/Template.html — платформа его игнорирует."
|
||||||
|
Write-Host " Перенесите нужное в Template/<язык>.html и удалите его."
|
||||||
|
}
|
||||||
} elseif (Test-Path $legacyPagePath) {
|
} elseif (Test-Path $legacyPagePath) {
|
||||||
# Раскладка до v1.24 — одиночный Ext/Template.html, который платформа молча игнорирует.
|
# Раскладка до v1.24 — одиночный Ext/Template.html, который платформа молча игнорирует.
|
||||||
# Языка у него нет, но создать его могла только версия навыка без параметра -Lang,
|
# Языка у него нет, но создать его могла только версия навыка без параметра -Lang,
|
||||||
@@ -372,8 +391,8 @@ if ($addLangMode) {
|
|||||||
|
|
||||||
# Файл страницы НИКОГДА не перезаписываем: в нём может лежать текст макета.
|
# Файл страницы НИКОГДА не перезаписываем: в нём может лежать текст макета.
|
||||||
# Ошибка — только когда добавлять нечего: язык уже в дескрипторе И страница на диске.
|
# Ошибка — только когда добавлять нечего: язык уже в дескрипторе И страница на диске.
|
||||||
$pageExists = (Test-Path $pagePath) -or ($legacyPending -and $Lang -eq "ru")
|
# При миграции проверять нечего: langs там задан нами же, а страница появится переносом.
|
||||||
if (($langs -contains $Lang) -and $pageExists -and -not $legacyPending) {
|
if (($langs -contains $Lang) -and (Test-Path $pagePath) -and -not $legacyPending) {
|
||||||
Write-Error "Страница макета на языке '$Lang' уже существует: $pagePath"
|
Write-Error "Страница макета на языке '$Lang' уже существует: $pagePath"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# template-add v1.26 — Add template to 1C object (+write_xml_file/write_utf8_bom: общий эталон записи)
|
# template-add v1.27 — Add template to 1C object (+write_xml_file/write_utf8_bom: общий эталон записи)
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
@@ -276,6 +276,26 @@ def write_utf8_bom(path, content):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def is_valid_lang(code):
|
||||||
|
"""Код языка идёт и в текст XML, и в имя файла страницы.
|
||||||
|
|
||||||
|
Пустое значение дало бы файл «.html» и пустой <Page></Page>, разделитель пути — запись
|
||||||
|
мимо каталога страниц, а зарезервированное имя устройства (nul, con, prn, aux, com1…, lpt1…)
|
||||||
|
на Windows уводит запись в само устройство: при -Lang nul этот порт молча писал
|
||||||
|
<Page>nul</Page> и пустой каталог с кодом 0. Все отказы платформы были бы тихими.
|
||||||
|
|
||||||
|
fullmatch, а не match: последний с `$` допускает перевод строки в конце.
|
||||||
|
|
||||||
|
Копия этой функции есть в help-add (навыки автономны, формат «дескриптор + страница»
|
||||||
|
у них общий). Держать копии одинаковыми — сознательно; за дрейфом следит check-inline-drift.
|
||||||
|
"""
|
||||||
|
if not re.fullmatch(r"[A-Za-z0-9_-]+", code):
|
||||||
|
return False
|
||||||
|
if re.fullmatch(r"(?i)(con|prn|aux|nul|com[1-9]|lpt[1-9])", code):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def write_xml_file(path, content):
|
def write_xml_file(path, content):
|
||||||
"""XML в каноне выгрузки Конфигуратора: CRLF в разделителях, без перевода в конце.
|
"""XML в каноне выгрузки Конфигуратора: CRLF в разделителях, без перевода в конце.
|
||||||
|
|
||||||
@@ -379,12 +399,9 @@ def main():
|
|||||||
templates_dir = os.path.join(processor_dir, "Templates")
|
templates_dir = os.path.join(processor_dir, "Templates")
|
||||||
template_meta_path = os.path.join(templates_dir, f"{template_name}.xml")
|
template_meta_path = os.path.join(templates_dir, f"{template_name}.xml")
|
||||||
|
|
||||||
# Код языка идёт и в текст XML, и в имя файла страницы, поэтому проверяем его до записи:
|
if not is_valid_lang(lang):
|
||||||
# пустое значение дало бы файл «.html» и пустой <Page></Page>, а разделитель пути —
|
|
||||||
# запись мимо каталога Ext/Template. Оба отказа платформы были бы тихими.
|
|
||||||
if not re.match(r"^[A-Za-z0-9_-]+$", lang):
|
|
||||||
print(f"Недопустимый код языка: '{lang}'", file=sys.stderr)
|
print(f"Недопустимый код языка: '{lang}'", file=sys.stderr)
|
||||||
print("Ожидается код вида ru, en (буквы, цифры, дефис, подчёркивание)", file=sys.stderr)
|
print("Ожидается код вида ru, en (буквы, цифры, дефис, подчёркивание; имена устройств Windows недопустимы)", file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# Существующий HTML-макет — не всегда повод отказать: в один макет платформа кладёт
|
# Существующий HTML-макет — не всегда повод отказать: в один макет платформа кладёт
|
||||||
@@ -491,6 +508,11 @@ def main():
|
|||||||
if m_dv:
|
if m_dv:
|
||||||
desc_version = m_dv.group(1)
|
desc_version = m_dv.group(1)
|
||||||
langs = re.findall(r"<Page>([^<]+)</Page>", desc_text)
|
langs = re.findall(r"<Page>([^<]+)</Page>", desc_text)
|
||||||
|
# Полумигрированное дерево: дескриптор уже есть, а старый Ext/Template.html остался рядом.
|
||||||
|
# Платформа его игнорирует, поэтому текст в нём пропадёт незаметно — говорим вслух.
|
||||||
|
if os.path.exists(legacy_page_path):
|
||||||
|
print("[WARN] Рядом лежит старый Ext/Template.html — платформа его игнорирует.")
|
||||||
|
print(" Перенесите нужное в Template/<язык>.html и удалите его.")
|
||||||
elif os.path.exists(legacy_page_path):
|
elif os.path.exists(legacy_page_path):
|
||||||
# Раскладка до v1.24 — одиночный Ext/Template.html, который платформа молча игнорирует.
|
# Раскладка до v1.24 — одиночный Ext/Template.html, который платформа молча игнорирует.
|
||||||
# Языка у него нет, но создать его могла только версия навыка без параметра -Lang,
|
# Языка у него нет, но создать его могла только версия навыка без параметра -Lang,
|
||||||
@@ -506,7 +528,13 @@ def main():
|
|||||||
# Ошибка — только когда добавлять нечего: язык уже в дескрипторе И страница на диске.
|
# Ошибка — только когда добавлять нечего: язык уже в дескрипторе И страница на диске.
|
||||||
# Сравнение без учёта регистра — зеркало -contains в PS, который регистр не различает.
|
# Сравнение без учёта регистра — зеркало -contains в PS, который регистр не различает.
|
||||||
lang_known = lang.lower() in [x.lower() for x in langs]
|
lang_known = lang.lower() in [x.lower() for x in langs]
|
||||||
page_exists = os.path.exists(page_path) or (legacy_pending and lang.lower() == "ru")
|
# Существование страницы — тоже без учёта регистра: os.path.exists на Linux различает
|
||||||
|
# регистр, а PS -contains и Test-Path на Windows — нет, и порты разошлись бы на -Lang RU.
|
||||||
|
page_exists = False
|
||||||
|
if os.path.isdir(page_dir):
|
||||||
|
want = f"{lang}.html".lower()
|
||||||
|
page_exists = any(f.lower() == want for f in os.listdir(page_dir))
|
||||||
|
# При миграции проверять нечего: langs там задан нами же, а страница появится переносом.
|
||||||
if lang_known and page_exists and not legacy_pending:
|
if lang_known and page_exists and not legacy_pending:
|
||||||
print(f"Страница макета на языке '{lang}' уже существует: {page_path}", file=sys.stderr)
|
print(f"Страница макета на языке '{lang}' уже существует: {page_path}", file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"name": "Зарезервированное имя устройства как код языка отвергается",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"script": "epf-init/scripts/init",
|
||||||
|
"args": {
|
||||||
|
"-Name": "МояОбработка",
|
||||||
|
"-SrcDir": "{workDir}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"params": {
|
||||||
|
"objectName": "МояОбработка"
|
||||||
|
},
|
||||||
|
"args_extra": [
|
||||||
|
"-Lang",
|
||||||
|
"con"
|
||||||
|
],
|
||||||
|
"expectError": "Недопустимый код языка"
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"name": "Страница справки без дескриптора: содержимое не затирается",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"script": "epf-init/scripts/init",
|
||||||
|
"args": {
|
||||||
|
"-Name": "МояОбработка",
|
||||||
|
"-SrcDir": "{workDir}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": "help-add/scripts/add-help",
|
||||||
|
"args": {
|
||||||
|
"-ObjectName": "МояОбработка",
|
||||||
|
"-SrcDir": "{workDir}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"deletePath": "МояОбработка/Ext/Help.xml"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "МояОбработка/Ext/Help/ru.html",
|
||||||
|
"content": "ЖИВОЙ_ТЕКСТ_СПРАВКИ"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"params": {
|
||||||
|
"objectName": "МояОбработка"
|
||||||
|
},
|
||||||
|
"expect": {
|
||||||
|
"stdoutContains": [
|
||||||
|
"[WARN]",
|
||||||
|
"содержимое сохранено"
|
||||||
|
],
|
||||||
|
"fileContains": {
|
||||||
|
"file": "МояОбработка/Ext/Help/ru.html",
|
||||||
|
"text": "ЖИВОЙ_ТЕКСТ_СПРАВКИ"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xen="http://v8.1c.ru/8.3/xcf/enums" xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.17">
|
||||||
|
<ExternalDataProcessor uuid="UUID-001">
|
||||||
|
<InternalInfo>
|
||||||
|
<xr:ContainedObject>
|
||||||
|
<xr:ClassId>UUID-002</xr:ClassId>
|
||||||
|
<xr:ObjectId>UUID-003</xr:ObjectId>
|
||||||
|
</xr:ContainedObject>
|
||||||
|
<xr:GeneratedType name="ExternalDataProcessorObject.МояОбработка" category="Object">
|
||||||
|
<xr:TypeId>UUID-004</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-005</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
</InternalInfo>
|
||||||
|
<Properties>
|
||||||
|
<Name>МояОбработка</Name>
|
||||||
|
<Synonym>
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>МояОбработка</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</Synonym>
|
||||||
|
<Comment/>
|
||||||
|
<DefaultForm/>
|
||||||
|
<AuxiliaryForm/>
|
||||||
|
</Properties>
|
||||||
|
<ChildObjects/>
|
||||||
|
</ExternalDataProcessor>
|
||||||
|
</MetaDataObject>
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Help xmlns="http://v8.1c.ru/8.3/xcf/extrnprops" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.17">
|
||||||
|
<Page>ru</Page>
|
||||||
|
</Help>
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
ЖИВОЙ_ТЕКСТ_СПРАВКИ
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
#Область ОписаниеПеременных
|
||||||
|
|
||||||
|
#КонецОбласти
|
||||||
|
|
||||||
|
#Область ПрограммныйИнтерфейс
|
||||||
|
|
||||||
|
#КонецОбласти
|
||||||
|
|
||||||
|
#Область СлужебныеПроцедурыИФункции
|
||||||
|
|
||||||
|
#КонецОбласти
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"name": "Зарезервированное имя устройства как код языка отвергается",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"script": "epf-init/scripts/init",
|
||||||
|
"args": {
|
||||||
|
"-Name": "МояОбработка",
|
||||||
|
"-SrcDir": "{workDir}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"params": {
|
||||||
|
"objectName": "МояОбработка",
|
||||||
|
"templateName": "МакетHTML",
|
||||||
|
"templateType": "HTML"
|
||||||
|
},
|
||||||
|
"args_extra": [
|
||||||
|
"-Lang",
|
||||||
|
"nul"
|
||||||
|
],
|
||||||
|
"expectError": "Недопустимый код языка"
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "Дескриптор есть, старый Template.html остался рядом: предупреждение",
|
||||||
|
"preRun": [
|
||||||
|
{
|
||||||
|
"script": "epf-init/scripts/init",
|
||||||
|
"args": {
|
||||||
|
"-Name": "МояОбработка",
|
||||||
|
"-SrcDir": "{workDir}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": "template-add/scripts/add-template",
|
||||||
|
"args": {
|
||||||
|
"-ObjectName": "МояОбработка",
|
||||||
|
"-TemplateName": "МакетHTML",
|
||||||
|
"-TemplateType": "HTML",
|
||||||
|
"-SrcDir": "{workDir}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"writeFile": {
|
||||||
|
"path": "МояОбработка/Templates/МакетHTML/Ext/Template.html",
|
||||||
|
"content": "ЗАБЫТЫЙ_ФАЙЛ"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"params": {
|
||||||
|
"objectName": "МояОбработка",
|
||||||
|
"templateName": "МакетHTML",
|
||||||
|
"templateType": "HTML"
|
||||||
|
},
|
||||||
|
"args_extra": [
|
||||||
|
"-Lang",
|
||||||
|
"en"
|
||||||
|
],
|
||||||
|
"expect": {
|
||||||
|
"stdoutContains": [
|
||||||
|
"[WARN]",
|
||||||
|
"Рядом лежит старый"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xen="http://v8.1c.ru/8.3/xcf/enums" xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.17">
|
||||||
|
<ExternalDataProcessor uuid="UUID-001">
|
||||||
|
<InternalInfo>
|
||||||
|
<xr:ContainedObject>
|
||||||
|
<xr:ClassId>UUID-002</xr:ClassId>
|
||||||
|
<xr:ObjectId>UUID-003</xr:ObjectId>
|
||||||
|
</xr:ContainedObject>
|
||||||
|
<xr:GeneratedType name="ExternalDataProcessorObject.МояОбработка" category="Object">
|
||||||
|
<xr:TypeId>UUID-004</xr:TypeId>
|
||||||
|
<xr:ValueId>UUID-005</xr:ValueId>
|
||||||
|
</xr:GeneratedType>
|
||||||
|
</InternalInfo>
|
||||||
|
<Properties>
|
||||||
|
<Name>МояОбработка</Name>
|
||||||
|
<Synonym>
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>МояОбработка</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</Synonym>
|
||||||
|
<Comment/>
|
||||||
|
<DefaultForm/>
|
||||||
|
<AuxiliaryForm/>
|
||||||
|
</Properties>
|
||||||
|
<ChildObjects>
|
||||||
|
<Template>МакетHTML</Template>
|
||||||
|
</ChildObjects>
|
||||||
|
</ExternalDataProcessor>
|
||||||
|
</MetaDataObject>
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
#Область ОписаниеПеременных
|
||||||
|
|
||||||
|
#КонецОбласти
|
||||||
|
|
||||||
|
#Область ПрограммныйИнтерфейс
|
||||||
|
|
||||||
|
#КонецОбласти
|
||||||
|
|
||||||
|
#Область СлужебныеПроцедурыИФункции
|
||||||
|
|
||||||
|
#КонецОбласти
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xen="http://v8.1c.ru/8.3/xcf/enums" xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.17">
|
||||||
|
<Template uuid="UUID-001">
|
||||||
|
<Properties>
|
||||||
|
<Name>МакетHTML</Name>
|
||||||
|
<Synonym>
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>МакетHTML</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</Synonym>
|
||||||
|
<Comment/>
|
||||||
|
<TemplateType>HTMLDocument</TemplateType>
|
||||||
|
</Properties>
|
||||||
|
</Template>
|
||||||
|
</MetaDataObject>
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
ЗАБЫТЫЙ_ФАЙЛ
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Help xmlns="http://v8.1c.ru/8.3/xcf/extrnprops" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.17">
|
||||||
|
<Page>en</Page>
|
||||||
|
<Page>ru</Page>
|
||||||
|
</Help>
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta></head><body>
|
||||||
|
</body></html>
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta></head><body>
|
||||||
|
</body></html>
|
||||||
@@ -184,6 +184,15 @@ const FAMILIES = [
|
|||||||
consumersPy: ['cfe-borrow'] },
|
consumersPy: ['cfe-borrow'] },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
// ─── Код языка страницы ──────────────────────────────────────────────────
|
||||||
|
// Формат «дескриптор + страница» общий у справки объекта и HTML-макета, поэтому проверка
|
||||||
|
// кода языка обязана быть одна и та же: он идёт и в текст XML, и в имя файла.
|
||||||
|
{
|
||||||
|
name: 'is_valid_lang', py: 'is_valid_lang', ps1: 'Test-LangCode',
|
||||||
|
variants: [
|
||||||
|
{ id: 'base', authority: 'template-add', consumers: ['help-add'] },
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'write_utf8_bom', py: 'write_utf8_bom', ps1: null,
|
name: 'write_utf8_bom', py: 'write_utf8_bom', ps1: null,
|
||||||
variants: [
|
variants: [
|
||||||
|
|||||||
Reference in New Issue
Block a user