mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-09-02 00:10:50 +03:00
fix(cfe-patch-method): -Check ловит расхождение списка параметров
-Check сравнивал только тело и сигнатуру не смотрел вовсе. Если поставщик добавил методу параметр, а тело не изменил (новый параметр часто ещё не используется), платформа перехватчик отвергает — «Список параметров метода "X" не соответствует методу "Y"» — а -Check говорил АКТУАЛЕН, и починка не запускалась. Замер на стенде (8.3.24, /CheckCanApplyConfigurationExtensions + рантайм): платформа сверяет только ЧИСЛО параметров. Имена, значения по умолчанию и лишний Экспорт не сравнивает; дефолты копии вдобавок не действуют — берутся из оригинала. Поэтому сверяем количество и ничего сверх того, иначе получили бы ложный дрейф там, где платформа молчит. Число параметров считается существующим Split-TopLevel по ParamsText обеих сторон; при расхождении метод идёт обычной веткой дрейфа со статусом ДРЕЙФ и причиной «список параметров: в оригинале N, в перехватчике M». -Actualize починку уже умел: он собирает строку сигнатуры заново из оригинала — не запускался только потому, что -Check не звал. Кейсы: расхождение числа (ДРЕЙФ), переименованные параметры с другим дефолтом (АКТУАЛЕН, как у платформы) и -Actualize, переписывающий список параметров. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QoAJmoNbgWKobA7JGgN5S3
This commit is contained in:
co-authored by
Claude Opus 5
parent
533dd0ded4
commit
d4832ce363
@@ -1,4 +1,4 @@
|
||||
# cfe-patch-method v2.10 — Source-aware method interceptor for 1C extension (CFE)
|
||||
# cfe-patch-method v2.11 — Source-aware method interceptor for 1C extension (CFE)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
[CmdletBinding(PositionalBinding=$false)]
|
||||
param(
|
||||
@@ -370,6 +370,14 @@ function Get-ControlKey {
|
||||
return (@($lines | ForEach-Object { $_.Trim() } | Where-Object { $_ -ne '' }) -join "`n")
|
||||
}
|
||||
|
||||
# Parameter count of a signature params text. The platform compares only the number of
|
||||
# parameters of a &ИзменениеИКонтроль copy (names and default values it ignores).
|
||||
function Get-ParamCount {
|
||||
param([string]$paramsText)
|
||||
if ([string]::IsNullOrWhiteSpace($paramsText)) { return 0 }
|
||||
return @(Split-TopLevel $paramsText | Where-Object { $_.Trim() -ne '' }).Count
|
||||
}
|
||||
|
||||
# Reconstruct v1 body and edit ops from a marked body
|
||||
function Parse-MarkedBody {
|
||||
param($bodyLines)
|
||||
@@ -659,7 +667,14 @@ function Invoke-Resync {
|
||||
$v1norm = @($v1 | ForEach-Object { Get-Normalized $_ })
|
||||
$v2norm = @($v2 | ForEach-Object { Get-Normalized $_ })
|
||||
|
||||
if ([string]::Equals((Get-ControlKey $v1), (Get-ControlKey $v2), 'Ordinal')) {
|
||||
# Signature: the platform rejects the interceptor when the parameter COUNT differs, so a
|
||||
# body-only comparison would miss a vendor-added parameter. Names/defaults it ignores.
|
||||
$extParamCount = Get-ParamCount $sig.ParamsText
|
||||
$srcParamCount = Get-ParamCount $method.ParamsText
|
||||
$paramsDrift = ($extParamCount -ne $srcParamCount)
|
||||
$paramsReason = if ($paramsDrift) { "список параметров: в оригинале $srcParamCount, в перехватчике $extParamCount" } else { '' }
|
||||
|
||||
if (-not $paramsDrift -and [string]::Equals((Get-ControlKey $v1), (Get-ControlKey $v2), 'Ordinal')) {
|
||||
return @{ Id = $methodId; Status = 'АКТУАЛЕН'; ExtBsl = $extBsl }
|
||||
}
|
||||
|
||||
@@ -709,7 +724,9 @@ function Invoke-Resync {
|
||||
|
||||
if ($ReportOnly) {
|
||||
$st = if ($disputed.Count -gt 0) { 'КОНФЛИКТ' } elseif ($transferred.Count -eq 0 -and $absorbed.Count -gt 0) { 'ПЕРЕНЕСЕНО В ОСНОВНУЮ' } else { 'ДРЕЙФ' }
|
||||
if ($paramsDrift -and $st -eq 'ПЕРЕНЕСЕНО В ОСНОВНУЮ') { $st = 'ДРЕЙФ' }
|
||||
$rsn = if ($disputed.Count -gt 0) { Get-ResyncConflictReason $disputed } elseif ($st -eq 'ПЕРЕНЕСЕНО В ОСНОВНУЮ') { 'все правки уже в основной конфигурации' } else { '' }
|
||||
if ($paramsDrift) { $rsn = if ($rsn) { "$paramsReason; $rsn" } else { $paramsReason } }
|
||||
return @{ Id = $methodId; Status = $st; ExtBsl = $extBsl; Transferred = $transferred.Count; Absorbed = $absorbed.Count; Disputed = $disputed.Count; Reason = $rsn; AbsorbedNotes = $absorbedNotes }
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# cfe-patch-method v2.10 — Source-aware method interceptor for 1C extension (CFE)
|
||||
# cfe-patch-method v2.11 — Source-aware method interceptor for 1C extension (CFE)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
@@ -498,6 +498,14 @@ def control_key(lines):
|
||||
return "\n".join([k for k in (x.strip() for x in lines) if k != ""])
|
||||
|
||||
|
||||
# Parameter count of a signature params text. The platform compares only the number of
|
||||
# parameters of a &ИзменениеИКонтроль copy (names and default values it ignores).
|
||||
def param_count(params_text):
|
||||
if not params_text or not params_text.strip():
|
||||
return 0
|
||||
return len([p for p in split_top_level(params_text) if p.strip()])
|
||||
|
||||
|
||||
def parse_marked_body(body_lines):
|
||||
v1 = []
|
||||
ops = []
|
||||
@@ -1136,7 +1144,7 @@ def resync_one(ext_bsl, ext_lines, dup, method, logical_module, conflict_folder,
|
||||
sig = read_signature(ext_lines, sig_line_idx)
|
||||
if not sig:
|
||||
return {"id": method_id, "status": "ОШИБКА", "ext_bsl": ext_bsl, "reason": "не разобрать сигнатуру"}
|
||||
_params, sig_end = sig
|
||||
ext_params_text, sig_end = sig
|
||||
is_func = bool(re.match(r'^\s*(?:Асинх\s+)?Функция\b', ext_lines[sig_line_idx], re.IGNORECASE))
|
||||
end_re = re.compile(r'^\s*КонецФункции\b' if is_func else r'^\s*КонецПроцедуры\b', re.IGNORECASE)
|
||||
block_end = -1
|
||||
@@ -1153,7 +1161,15 @@ def resync_one(ext_bsl, ext_lines, dup, method, logical_module, conflict_folder,
|
||||
v1norm = [normalize(x) for x in v1]
|
||||
v2norm = [normalize(x) for x in v2]
|
||||
|
||||
if control_key(v1) == control_key(v2):
|
||||
# Signature: the platform rejects the interceptor when the parameter COUNT differs, so a
|
||||
# body-only comparison would miss a vendor-added parameter. Names/defaults it ignores.
|
||||
ext_param_count = param_count(ext_params_text)
|
||||
src_param_count = param_count(method["params_text"])
|
||||
params_drift = ext_param_count != src_param_count
|
||||
params_reason = ("список параметров: в оригинале %d, в перехватчике %d"
|
||||
% (src_param_count, ext_param_count)) if params_drift else ""
|
||||
|
||||
if not params_drift and control_key(v1) == control_key(v2):
|
||||
return {"id": method_id, "status": "АКТУАЛЕН", "ext_bsl": ext_bsl}
|
||||
|
||||
insert_top = []; insert_after = {}; del_start = set(); del_end = set(); disputed = []; transferred = 0; absorbed = 0; absorbed_notes = []
|
||||
@@ -1215,7 +1231,11 @@ def resync_one(ext_bsl, ext_lines, dup, method, logical_module, conflict_folder,
|
||||
st = "ПЕРЕНЕСЕНО В ОСНОВНУЮ"
|
||||
else:
|
||||
st = "ДРЕЙФ"
|
||||
if params_drift and st == "ПЕРЕНЕСЕНО В ОСНОВНУЮ":
|
||||
st = "ДРЕЙФ"
|
||||
rsn = conflict_reason(disputed) if disputed else ("все правки уже в основной конфигурации" if st == "ПЕРЕНЕСЕНО В ОСНОВНУЮ" else "")
|
||||
if params_drift:
|
||||
rsn = ("%s; %s" % (params_reason, rsn)) if rsn else params_reason
|
||||
return {"id": method_id, "status": st, "ext_bsl": ext_bsl, "transferred": transferred,
|
||||
"absorbed": absorbed, "disputed": len(disputed), "reason": rsn, "absorbed_notes": absorbed_notes}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user