From 84e908304e554651656b8b292e24c7c2c41faace Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sun, 23 Aug 2026 15:45:51 +0300 Subject: [PATCH] =?UTF-8?q?fix(db-*):=20=D0=BD=D0=B0=20POSIX=20=D1=81?= =?UTF-8?q?=D0=BD=D0=B8=D0=BC=D0=B0=D1=82=D1=8C=20=D0=B8=20=D0=BA=D0=B0?= =?UTF-8?q?=D0=B2=D1=8B=D1=87=D0=BA=D0=B8=20=D1=81=D0=BA=D0=BB=D0=B5=D0=B5?= =?UTF-8?q?=D0=BD=D0=BD=D1=8B=D1=85=20=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Проверка прямым вызовом платформы на darwin: /ConfigurationRepositoryF"путь с пробелом" отвергается, тот же ключ без кавычек проходит. Значит на POSIX лишние и обрамляющие кавычки значений, и кавычки внутри склеенных ключей — они нужны только для склейки команды на Windows. File="…" не трогаем: там кавычки часть синтаксиса строки соединения, и с ними на POSIX всё работает (проверено db-create). Co-Authored-By: Claude Opus 5 --- .claude/skills/db-create/scripts/db-create.py | 19 +++++++++++++++---- .../skills/db-dump-cf/scripts/db-dump-cf.py | 19 +++++++++++++++---- .../skills/db-dump-dt/scripts/db-dump-dt.py | 19 +++++++++++++++---- .../skills/db-dump-xml/scripts/db-dump-xml.py | 19 +++++++++++++++---- .../skills/db-load-cf/scripts/db-load-cf.py | 19 +++++++++++++++---- .../skills/db-load-dt/scripts/db-load-dt.py | 19 +++++++++++++++---- .../skills/db-load-git/scripts/db-load-git.py | 19 +++++++++++++++---- .../skills/db-load-xml/scripts/db-load-xml.py | 19 +++++++++++++++---- .claude/skills/db-repo/scripts/db-repo.py | 19 +++++++++++++++---- .claude/skills/db-update/scripts/db-update.py | 19 +++++++++++++++---- .claude/skills/epf-build/scripts/epf-build.py | 19 +++++++++++++++---- .claude/skills/epf-dump/scripts/epf-dump.py | 19 +++++++++++++++---- 12 files changed, 180 insertions(+), 48 deletions(-) diff --git a/.claude/skills/db-create/scripts/db-create.py b/.claude/skills/db-create/scripts/db-create.py index 7919f68b9..58abe9d61 100644 --- a/.claude/skills/db-create/scripts/db-create.py +++ b/.claude/skills/db-create/scripts/db-create.py @@ -342,10 +342,21 @@ def run_v8(v8path, arguments): if os.name == "nt": cmd = '"' + v8path + '" ' + " ".join(arguments) else: - cmd = [v8path] + [ - a[1:-1] if len(a) > 1 and a[0] == '"' and a[-1] == '"' else a - for a in arguments - ] + def strip_framing_quotes(a): + # Кавычки, которыми мы обрамляем значения ради склейки на Windows, на POSIX + # становятся ЧАСТЬЮ значения. Проверено на darwin: путь с пробелом отдельным + # токеном даёт «Неопределена информационная база», а склеенный + # /ConfigurationRepositoryF"путь с пробелом" — «завершилось с ошибкой»; + # без кавычек обе формы работают. + if len(a) > 1 and a[0] == '"' and a[-1] == '"': + return a[1:-1] # "значение" отдельным токеном + if a[0:1] == "/" and a[-1:] == '"' and '"' in a[:-1]: + i = a.index('"') + return a[:i] + a[i + 1:-1] # /N"имя" -> /Nимя + return a # File="…" не трогаем: там кавычки — + # часть синтаксиса строки соединения, + # и с ними на POSIX всё работает + cmd = [v8path] + [strip_framing_quotes(a) for a in arguments] r = subprocess.run(cmd, input=b"", capture_output=True) r.stdout = decode_platform_bytes(r.stdout) r.stderr = decode_platform_bytes(r.stderr) diff --git a/.claude/skills/db-dump-cf/scripts/db-dump-cf.py b/.claude/skills/db-dump-cf/scripts/db-dump-cf.py index 287b79ee1..a5300c9ef 100644 --- a/.claude/skills/db-dump-cf/scripts/db-dump-cf.py +++ b/.claude/skills/db-dump-cf/scripts/db-dump-cf.py @@ -329,10 +329,21 @@ def run_v8(v8path, arguments): if os.name == "nt": cmd = '"' + v8path + '" ' + " ".join(arguments) else: - cmd = [v8path] + [ - a[1:-1] if len(a) > 1 and a[0] == '"' and a[-1] == '"' else a - for a in arguments - ] + def strip_framing_quotes(a): + # Кавычки, которыми мы обрамляем значения ради склейки на Windows, на POSIX + # становятся ЧАСТЬЮ значения. Проверено на darwin: путь с пробелом отдельным + # токеном даёт «Неопределена информационная база», а склеенный + # /ConfigurationRepositoryF"путь с пробелом" — «завершилось с ошибкой»; + # без кавычек обе формы работают. + if len(a) > 1 and a[0] == '"' and a[-1] == '"': + return a[1:-1] # "значение" отдельным токеном + if a[0:1] == "/" and a[-1:] == '"' and '"' in a[:-1]: + i = a.index('"') + return a[:i] + a[i + 1:-1] # /N"имя" -> /Nимя + return a # File="…" не трогаем: там кавычки — + # часть синтаксиса строки соединения, + # и с ними на POSIX всё работает + cmd = [v8path] + [strip_framing_quotes(a) for a in arguments] r = subprocess.run(cmd, input=b"", capture_output=True) r.stdout = decode_platform_bytes(r.stdout) r.stderr = decode_platform_bytes(r.stderr) diff --git a/.claude/skills/db-dump-dt/scripts/db-dump-dt.py b/.claude/skills/db-dump-dt/scripts/db-dump-dt.py index 30690f502..ffae3d34e 100644 --- a/.claude/skills/db-dump-dt/scripts/db-dump-dt.py +++ b/.claude/skills/db-dump-dt/scripts/db-dump-dt.py @@ -329,10 +329,21 @@ def run_v8(v8path, arguments): if os.name == "nt": cmd = '"' + v8path + '" ' + " ".join(arguments) else: - cmd = [v8path] + [ - a[1:-1] if len(a) > 1 and a[0] == '"' and a[-1] == '"' else a - for a in arguments - ] + def strip_framing_quotes(a): + # Кавычки, которыми мы обрамляем значения ради склейки на Windows, на POSIX + # становятся ЧАСТЬЮ значения. Проверено на darwin: путь с пробелом отдельным + # токеном даёт «Неопределена информационная база», а склеенный + # /ConfigurationRepositoryF"путь с пробелом" — «завершилось с ошибкой»; + # без кавычек обе формы работают. + if len(a) > 1 and a[0] == '"' and a[-1] == '"': + return a[1:-1] # "значение" отдельным токеном + if a[0:1] == "/" and a[-1:] == '"' and '"' in a[:-1]: + i = a.index('"') + return a[:i] + a[i + 1:-1] # /N"имя" -> /Nимя + return a # File="…" не трогаем: там кавычки — + # часть синтаксиса строки соединения, + # и с ними на POSIX всё работает + cmd = [v8path] + [strip_framing_quotes(a) for a in arguments] r = subprocess.run(cmd, input=b"", capture_output=True) r.stdout = decode_platform_bytes(r.stdout) r.stderr = decode_platform_bytes(r.stderr) diff --git a/.claude/skills/db-dump-xml/scripts/db-dump-xml.py b/.claude/skills/db-dump-xml/scripts/db-dump-xml.py index a5a506c28..b31e67467 100644 --- a/.claude/skills/db-dump-xml/scripts/db-dump-xml.py +++ b/.claude/skills/db-dump-xml/scripts/db-dump-xml.py @@ -414,10 +414,21 @@ def run_v8(v8path, arguments): if os.name == "nt": cmd = '"' + v8path + '" ' + " ".join(arguments) else: - cmd = [v8path] + [ - a[1:-1] if len(a) > 1 and a[0] == '"' and a[-1] == '"' else a - for a in arguments - ] + def strip_framing_quotes(a): + # Кавычки, которыми мы обрамляем значения ради склейки на Windows, на POSIX + # становятся ЧАСТЬЮ значения. Проверено на darwin: путь с пробелом отдельным + # токеном даёт «Неопределена информационная база», а склеенный + # /ConfigurationRepositoryF"путь с пробелом" — «завершилось с ошибкой»; + # без кавычек обе формы работают. + if len(a) > 1 and a[0] == '"' and a[-1] == '"': + return a[1:-1] # "значение" отдельным токеном + if a[0:1] == "/" and a[-1:] == '"' and '"' in a[:-1]: + i = a.index('"') + return a[:i] + a[i + 1:-1] # /N"имя" -> /Nимя + return a # File="…" не трогаем: там кавычки — + # часть синтаксиса строки соединения, + # и с ними на POSIX всё работает + cmd = [v8path] + [strip_framing_quotes(a) for a in arguments] r = subprocess.run(cmd, input=b"", capture_output=True) r.stdout = decode_platform_bytes(r.stdout) r.stderr = decode_platform_bytes(r.stderr) diff --git a/.claude/skills/db-load-cf/scripts/db-load-cf.py b/.claude/skills/db-load-cf/scripts/db-load-cf.py index 05c77dd96..e4c1f9861 100644 --- a/.claude/skills/db-load-cf/scripts/db-load-cf.py +++ b/.claude/skills/db-load-cf/scripts/db-load-cf.py @@ -329,10 +329,21 @@ def run_v8(v8path, arguments): if os.name == "nt": cmd = '"' + v8path + '" ' + " ".join(arguments) else: - cmd = [v8path] + [ - a[1:-1] if len(a) > 1 and a[0] == '"' and a[-1] == '"' else a - for a in arguments - ] + def strip_framing_quotes(a): + # Кавычки, которыми мы обрамляем значения ради склейки на Windows, на POSIX + # становятся ЧАСТЬЮ значения. Проверено на darwin: путь с пробелом отдельным + # токеном даёт «Неопределена информационная база», а склеенный + # /ConfigurationRepositoryF"путь с пробелом" — «завершилось с ошибкой»; + # без кавычек обе формы работают. + if len(a) > 1 and a[0] == '"' and a[-1] == '"': + return a[1:-1] # "значение" отдельным токеном + if a[0:1] == "/" and a[-1:] == '"' and '"' in a[:-1]: + i = a.index('"') + return a[:i] + a[i + 1:-1] # /N"имя" -> /Nимя + return a # File="…" не трогаем: там кавычки — + # часть синтаксиса строки соединения, + # и с ними на POSIX всё работает + cmd = [v8path] + [strip_framing_quotes(a) for a in arguments] r = subprocess.run(cmd, input=b"", capture_output=True) r.stdout = decode_platform_bytes(r.stdout) r.stderr = decode_platform_bytes(r.stderr) diff --git a/.claude/skills/db-load-dt/scripts/db-load-dt.py b/.claude/skills/db-load-dt/scripts/db-load-dt.py index 413cafbcf..3233ea36c 100644 --- a/.claude/skills/db-load-dt/scripts/db-load-dt.py +++ b/.claude/skills/db-load-dt/scripts/db-load-dt.py @@ -329,10 +329,21 @@ def run_v8(v8path, arguments): if os.name == "nt": cmd = '"' + v8path + '" ' + " ".join(arguments) else: - cmd = [v8path] + [ - a[1:-1] if len(a) > 1 and a[0] == '"' and a[-1] == '"' else a - for a in arguments - ] + def strip_framing_quotes(a): + # Кавычки, которыми мы обрамляем значения ради склейки на Windows, на POSIX + # становятся ЧАСТЬЮ значения. Проверено на darwin: путь с пробелом отдельным + # токеном даёт «Неопределена информационная база», а склеенный + # /ConfigurationRepositoryF"путь с пробелом" — «завершилось с ошибкой»; + # без кавычек обе формы работают. + if len(a) > 1 and a[0] == '"' and a[-1] == '"': + return a[1:-1] # "значение" отдельным токеном + if a[0:1] == "/" and a[-1:] == '"' and '"' in a[:-1]: + i = a.index('"') + return a[:i] + a[i + 1:-1] # /N"имя" -> /Nимя + return a # File="…" не трогаем: там кавычки — + # часть синтаксиса строки соединения, + # и с ними на POSIX всё работает + cmd = [v8path] + [strip_framing_quotes(a) for a in arguments] r = subprocess.run(cmd, input=b"", capture_output=True) r.stdout = decode_platform_bytes(r.stdout) r.stderr = decode_platform_bytes(r.stderr) diff --git a/.claude/skills/db-load-git/scripts/db-load-git.py b/.claude/skills/db-load-git/scripts/db-load-git.py index d8ec0530b..499cd6fdd 100644 --- a/.claude/skills/db-load-git/scripts/db-load-git.py +++ b/.claude/skills/db-load-git/scripts/db-load-git.py @@ -435,10 +435,21 @@ def run_v8(v8path, arguments): if os.name == "nt": cmd = '"' + v8path + '" ' + " ".join(arguments) else: - cmd = [v8path] + [ - a[1:-1] if len(a) > 1 and a[0] == '"' and a[-1] == '"' else a - for a in arguments - ] + def strip_framing_quotes(a): + # Кавычки, которыми мы обрамляем значения ради склейки на Windows, на POSIX + # становятся ЧАСТЬЮ значения. Проверено на darwin: путь с пробелом отдельным + # токеном даёт «Неопределена информационная база», а склеенный + # /ConfigurationRepositoryF"путь с пробелом" — «завершилось с ошибкой»; + # без кавычек обе формы работают. + if len(a) > 1 and a[0] == '"' and a[-1] == '"': + return a[1:-1] # "значение" отдельным токеном + if a[0:1] == "/" and a[-1:] == '"' and '"' in a[:-1]: + i = a.index('"') + return a[:i] + a[i + 1:-1] # /N"имя" -> /Nимя + return a # File="…" не трогаем: там кавычки — + # часть синтаксиса строки соединения, + # и с ними на POSIX всё работает + cmd = [v8path] + [strip_framing_quotes(a) for a in arguments] r = subprocess.run(cmd, input=b"", capture_output=True) r.stdout = decode_platform_bytes(r.stdout) r.stderr = decode_platform_bytes(r.stderr) diff --git a/.claude/skills/db-load-xml/scripts/db-load-xml.py b/.claude/skills/db-load-xml/scripts/db-load-xml.py index d0a73f1a2..71939965f 100644 --- a/.claude/skills/db-load-xml/scripts/db-load-xml.py +++ b/.claude/skills/db-load-xml/scripts/db-load-xml.py @@ -435,10 +435,21 @@ def run_v8(v8path, arguments): if os.name == "nt": cmd = '"' + v8path + '" ' + " ".join(arguments) else: - cmd = [v8path] + [ - a[1:-1] if len(a) > 1 and a[0] == '"' and a[-1] == '"' else a - for a in arguments - ] + def strip_framing_quotes(a): + # Кавычки, которыми мы обрамляем значения ради склейки на Windows, на POSIX + # становятся ЧАСТЬЮ значения. Проверено на darwin: путь с пробелом отдельным + # токеном даёт «Неопределена информационная база», а склеенный + # /ConfigurationRepositoryF"путь с пробелом" — «завершилось с ошибкой»; + # без кавычек обе формы работают. + if len(a) > 1 and a[0] == '"' and a[-1] == '"': + return a[1:-1] # "значение" отдельным токеном + if a[0:1] == "/" and a[-1:] == '"' and '"' in a[:-1]: + i = a.index('"') + return a[:i] + a[i + 1:-1] # /N"имя" -> /Nимя + return a # File="…" не трогаем: там кавычки — + # часть синтаксиса строки соединения, + # и с ними на POSIX всё работает + cmd = [v8path] + [strip_framing_quotes(a) for a in arguments] r = subprocess.run(cmd, input=b"", capture_output=True) r.stdout = decode_platform_bytes(r.stdout) r.stderr = decode_platform_bytes(r.stderr) diff --git a/.claude/skills/db-repo/scripts/db-repo.py b/.claude/skills/db-repo/scripts/db-repo.py index a3429d81d..a11a645ad 100644 --- a/.claude/skills/db-repo/scripts/db-repo.py +++ b/.claude/skills/db-repo/scripts/db-repo.py @@ -300,10 +300,21 @@ def run_v8(v8path, arguments): if os.name == "nt": cmd = '"' + v8path + '" ' + " ".join(arguments) else: - cmd = [v8path] + [ - a[1:-1] if len(a) > 1 and a[0] == '"' and a[-1] == '"' else a - for a in arguments - ] + def strip_framing_quotes(a): + # Кавычки, которыми мы обрамляем значения ради склейки на Windows, на POSIX + # становятся ЧАСТЬЮ значения. Проверено на darwin: путь с пробелом отдельным + # токеном даёт «Неопределена информационная база», а склеенный + # /ConfigurationRepositoryF"путь с пробелом" — «завершилось с ошибкой»; + # без кавычек обе формы работают. + if len(a) > 1 and a[0] == '"' and a[-1] == '"': + return a[1:-1] # "значение" отдельным токеном + if a[0:1] == "/" and a[-1:] == '"' and '"' in a[:-1]: + i = a.index('"') + return a[:i] + a[i + 1:-1] # /N"имя" -> /Nимя + return a # File="…" не трогаем: там кавычки — + # часть синтаксиса строки соединения, + # и с ними на POSIX всё работает + cmd = [v8path] + [strip_framing_quotes(a) for a in arguments] r = subprocess.run(cmd, input=b"", capture_output=True) r.stdout = decode_platform_bytes(r.stdout) r.stderr = decode_platform_bytes(r.stderr) diff --git a/.claude/skills/db-update/scripts/db-update.py b/.claude/skills/db-update/scripts/db-update.py index d3ab13c5b..2a04fe1b0 100644 --- a/.claude/skills/db-update/scripts/db-update.py +++ b/.claude/skills/db-update/scripts/db-update.py @@ -414,10 +414,21 @@ def run_v8(v8path, arguments): if os.name == "nt": cmd = '"' + v8path + '" ' + " ".join(arguments) else: - cmd = [v8path] + [ - a[1:-1] if len(a) > 1 and a[0] == '"' and a[-1] == '"' else a - for a in arguments - ] + def strip_framing_quotes(a): + # Кавычки, которыми мы обрамляем значения ради склейки на Windows, на POSIX + # становятся ЧАСТЬЮ значения. Проверено на darwin: путь с пробелом отдельным + # токеном даёт «Неопределена информационная база», а склеенный + # /ConfigurationRepositoryF"путь с пробелом" — «завершилось с ошибкой»; + # без кавычек обе формы работают. + if len(a) > 1 and a[0] == '"' and a[-1] == '"': + return a[1:-1] # "значение" отдельным токеном + if a[0:1] == "/" and a[-1:] == '"' and '"' in a[:-1]: + i = a.index('"') + return a[:i] + a[i + 1:-1] # /N"имя" -> /Nимя + return a # File="…" не трогаем: там кавычки — + # часть синтаксиса строки соединения, + # и с ними на POSIX всё работает + cmd = [v8path] + [strip_framing_quotes(a) for a in arguments] r = subprocess.run(cmd, input=b"", capture_output=True) r.stdout = decode_platform_bytes(r.stdout) r.stderr = decode_platform_bytes(r.stderr) diff --git a/.claude/skills/epf-build/scripts/epf-build.py b/.claude/skills/epf-build/scripts/epf-build.py index 7dd5423e8..bc79ba01a 100644 --- a/.claude/skills/epf-build/scripts/epf-build.py +++ b/.claude/skills/epf-build/scripts/epf-build.py @@ -329,10 +329,21 @@ def run_v8(v8path, arguments): if os.name == "nt": cmd = '"' + v8path + '" ' + " ".join(arguments) else: - cmd = [v8path] + [ - a[1:-1] if len(a) > 1 and a[0] == '"' and a[-1] == '"' else a - for a in arguments - ] + def strip_framing_quotes(a): + # Кавычки, которыми мы обрамляем значения ради склейки на Windows, на POSIX + # становятся ЧАСТЬЮ значения. Проверено на darwin: путь с пробелом отдельным + # токеном даёт «Неопределена информационная база», а склеенный + # /ConfigurationRepositoryF"путь с пробелом" — «завершилось с ошибкой»; + # без кавычек обе формы работают. + if len(a) > 1 and a[0] == '"' and a[-1] == '"': + return a[1:-1] # "значение" отдельным токеном + if a[0:1] == "/" and a[-1:] == '"' and '"' in a[:-1]: + i = a.index('"') + return a[:i] + a[i + 1:-1] # /N"имя" -> /Nимя + return a # File="…" не трогаем: там кавычки — + # часть синтаксиса строки соединения, + # и с ними на POSIX всё работает + cmd = [v8path] + [strip_framing_quotes(a) for a in arguments] r = subprocess.run(cmd, input=b"", capture_output=True) r.stdout = decode_platform_bytes(r.stdout) r.stderr = decode_platform_bytes(r.stderr) diff --git a/.claude/skills/epf-dump/scripts/epf-dump.py b/.claude/skills/epf-dump/scripts/epf-dump.py index 2b13e38b8..308475230 100644 --- a/.claude/skills/epf-dump/scripts/epf-dump.py +++ b/.claude/skills/epf-dump/scripts/epf-dump.py @@ -329,10 +329,21 @@ def run_v8(v8path, arguments): if os.name == "nt": cmd = '"' + v8path + '" ' + " ".join(arguments) else: - cmd = [v8path] + [ - a[1:-1] if len(a) > 1 and a[0] == '"' and a[-1] == '"' else a - for a in arguments - ] + def strip_framing_quotes(a): + # Кавычки, которыми мы обрамляем значения ради склейки на Windows, на POSIX + # становятся ЧАСТЬЮ значения. Проверено на darwin: путь с пробелом отдельным + # токеном даёт «Неопределена информационная база», а склеенный + # /ConfigurationRepositoryF"путь с пробелом" — «завершилось с ошибкой»; + # без кавычек обе формы работают. + if len(a) > 1 and a[0] == '"' and a[-1] == '"': + return a[1:-1] # "значение" отдельным токеном + if a[0:1] == "/" and a[-1:] == '"' and '"' in a[:-1]: + i = a.index('"') + return a[:i] + a[i + 1:-1] # /N"имя" -> /Nимя + return a # File="…" не трогаем: там кавычки — + # часть синтаксиса строки соединения, + # и с ними на POSIX всё работает + cmd = [v8path] + [strip_framing_quotes(a) for a in arguments] r = subprocess.run(cmd, input=b"", capture_output=True) r.stdout = decode_platform_bytes(r.stdout) r.stderr = decode_platform_bytes(r.stderr)