baucli 1.0.78__tar.gz → 1.0.80__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {baucli-1.0.78 → baucli-1.0.80}/PKG-INFO +1 -1
- {baucli-1.0.78 → baucli-1.0.80}/baucli/__init__.py +1 -1
- {baucli-1.0.78 → baucli-1.0.80}/baucli/cli.py +80 -11
- {baucli-1.0.78 → baucli-1.0.80}/baucli.egg-info/PKG-INFO +1 -1
- {baucli-1.0.78 → baucli-1.0.80}/setup.py +1 -1
- {baucli-1.0.78 → baucli-1.0.80}/MANIFEST.in +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/README.md +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/apex_rebuild.py +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/apexlang.py +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/api.py +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/canon.py +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/config.py +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/db/__init__.py +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/db/mssql.py +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/db/mysql.py +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/db/oracle.py +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/db/postgresql.py +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/democrm.py +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/democrm_sql/mssql/crm_data_mssql.sql +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/democrm_sql/mssql/crm_demo_mssql.sql +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/democrm_sql/mysql/crm_data_mysql.sql +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/democrm_sql/mysql/crm_demo_mysql.sql +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/democrm_sql/oracle/crm_demo_oracle.sql +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/democrm_sql/postgresql/crm_data_postgresql.sql +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/democrm_sql/postgresql/crm_demo_postgresql.sql +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/diffenvs.py +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/docmig.py +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/git.py +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/legacy/__init__.py +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/legacy/delphi.py +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/legacy/magic.py +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/mcp_server.py +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/project.py +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/rag_embed.py +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/sample_scan.py +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/scope_scan.py +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/screenshot.py +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/seed_check.py +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/skills.py +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/stress.py +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli/sync.py +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli.egg-info/SOURCES.txt +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli.egg-info/dependency_links.txt +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli.egg-info/entry_points.txt +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli.egg-info/requires.txt +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/baucli.egg-info/top_level.txt +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/setup.cfg +0 -0
- {baucli-1.0.78 → baucli-1.0.80}/tests/test_canon_multiengine.py +0 -0
|
@@ -926,6 +926,12 @@ def _guard_db_tenant(cfg, db_name, acao="sincronizar"):
|
|
|
926
926
|
@click.option("--scope", "scope_code", default=None,
|
|
927
927
|
help="Sincroniza só os objetos do scope set (BAU_SCOPE_SETS) deste código. "
|
|
928
928
|
"Default: [project].scope do bau.toml.")
|
|
929
|
+
@click.option("--conflicts", "conflicts_only", is_flag=True, default=False,
|
|
930
|
+
help="Sincroniza APENAS os objetos cujo deploy está em CONFLITO no "
|
|
931
|
+
"BAU (fonte mudou no banco depois de documentado). Busca a fila, "
|
|
932
|
+
"re-captura o fonte vivo desses objetos (lote escopado, --full) "
|
|
933
|
+
"e combina com --object/--table (união). Depois re-documente/"
|
|
934
|
+
"aprove para gerar novos deploys.")
|
|
929
935
|
@click.option("--no-rowcount", "no_rowcount", is_flag=True, default=False,
|
|
930
936
|
help="Não capturar a contagem de linhas (num_rows) das tabelas no "
|
|
931
937
|
"fim do sync. Por padrão o sync traz esse baseline (origem DEV).")
|
|
@@ -947,7 +953,7 @@ def _guard_db_tenant(cfg, db_name, acao="sincronizar"):
|
|
|
947
953
|
def sync(db_name: str, sync_all_dbs: bool, full: bool, days: int,
|
|
948
954
|
objects_only: bool, tables_only: bool, object_name: str, table_name: str,
|
|
949
955
|
parallel: bool, batch_size: int, overwrite_undocumented: bool,
|
|
950
|
-
dry_run: bool, scope_code: str,
|
|
956
|
+
dry_run: bool, scope_code: str, conflicts_only: bool,
|
|
951
957
|
no_rowcount: bool, yes: bool, select: bool, include_bau: bool, verbose: bool):
|
|
952
958
|
"""Sync database objects to BAU Server.
|
|
953
959
|
|
|
@@ -961,6 +967,7 @@ def sync(db_name: str, sync_all_dbs: bool, full: bool, days: int,
|
|
|
961
967
|
baucli sync --object PKG_X Sync just one PL/SQL object (FULL)
|
|
962
968
|
baucli sync --table MEDICOS Sync just one table/view (FULL)
|
|
963
969
|
baucli sync --table T1 --object P1 --object P2 Uniao (repetivel, FULL)
|
|
970
|
+
baucli sync --conflicts So os objetos com deploy em CONFLITO
|
|
964
971
|
baucli sync --parallel Force parallel extraction
|
|
965
972
|
baucli sync --no-parallel Force sequential extraction
|
|
966
973
|
baucli sync --full -O Re-seed comments on undocumented rows
|
|
@@ -1016,6 +1023,32 @@ def sync(db_name: str, sync_all_dbs: bool, full: bool, days: int,
|
|
|
1016
1023
|
|
|
1017
1024
|
api = get_api(cfg)
|
|
1018
1025
|
|
|
1026
|
+
# --conflicts: busca na fila DOCPL os deploys em CONFLITO (fonte mudou no
|
|
1027
|
+
# banco depois de documentado) e vira sync dirigido por --object (união com
|
|
1028
|
+
# os passados na linha de comando). Lote escopado: não avança o watermark.
|
|
1029
|
+
if conflicts_only:
|
|
1030
|
+
if sync_all_dbs:
|
|
1031
|
+
console.print("[red]--conflicts não combina com --all (rode por --db).[/red]")
|
|
1032
|
+
raise SystemExit(1)
|
|
1033
|
+
from baucli.api import BauApiError as _CfErr
|
|
1034
|
+
try:
|
|
1035
|
+
_cf = api.deploys_pending(status="CONFLICT", limit=500) or {}
|
|
1036
|
+
except _CfErr as e:
|
|
1037
|
+
console.print(f"[red]API /deploys/pending?status=CONFLICT: {e}[/red]")
|
|
1038
|
+
raise SystemExit(1)
|
|
1039
|
+
_cf_items = _cf.get("deploys", []) or []
|
|
1040
|
+
_cf_names = sorted({(d.get("name") or "").upper()
|
|
1041
|
+
for d in _cf_items if d.get("name")})
|
|
1042
|
+
if not _cf_names:
|
|
1043
|
+
console.print("[green]Nenhum deploy em CONFLITO no BAU — nada a sincronizar.[/green]")
|
|
1044
|
+
raise SystemExit(0)
|
|
1045
|
+
console.print(f"[yellow]{len(_cf_names)} objeto(s) com deploy em CONFLITO:[/yellow] "
|
|
1046
|
+
+ ", ".join(_cf_names))
|
|
1047
|
+
object_name = sorted(set(object_name or []) | set(_cf_names))
|
|
1048
|
+
full = True
|
|
1049
|
+
if not table_name:
|
|
1050
|
+
objects_only = True
|
|
1051
|
+
|
|
1019
1052
|
# Resolve scope set (CLI > bau.toml [project].scope) and fetch its object
|
|
1020
1053
|
# lists once. Filtering happens client-side in sync_database.
|
|
1021
1054
|
scope_names = None
|
|
@@ -3021,7 +3054,7 @@ def deploy_apply(deploy_ref: str, db_name: str, out_file: str, mark_applied: boo
|
|
|
3021
3054
|
_idx = _build_live_ddl_index(extractor, [_meta.get("schema", "")])
|
|
3022
3055
|
_blocked, _live, _doc = _deploy_ddl_conflict(_meta, _idx)
|
|
3023
3056
|
if _blocked:
|
|
3024
|
-
_print_conflict_block(deploy_ref.upper(), _meta, _live, _doc)
|
|
3057
|
+
_print_conflict_block(deploy_ref.upper(), _meta, _live, _doc, db_name=name)
|
|
3025
3058
|
_report_deploy_outcome(api, cfg, _meta, "BLOCKED_LOSTUPDATE", "BLOCKED",
|
|
3026
3059
|
db_name=name, engine=db_config.get("engine"),
|
|
3027
3060
|
error="LAST_DDL vivo mais novo que o documentado",
|
|
@@ -3048,8 +3081,11 @@ def deploy_apply(deploy_ref: str, db_name: str, out_file: str, mark_applied: boo
|
|
|
3048
3081
|
extractor._conn, script, (db_config.get("engine") or None))
|
|
3049
3082
|
if _drift:
|
|
3050
3083
|
console.print(f" [yellow]BLOQUEADO (drift de código)[/yellow]: {_ddetail}")
|
|
3051
|
-
console.print(
|
|
3052
|
-
|
|
3084
|
+
console.print(
|
|
3085
|
+
" Re-capture, re-documente e gere novo header — ou "
|
|
3086
|
+
"[cyan]--force[/cyan] para sobrescrever:")
|
|
3087
|
+
console.print(
|
|
3088
|
+
f" [cyan]{_sync_cmd_for(name, [('--object', _obj_name or '')])}[/cyan]")
|
|
3053
3089
|
_rd = dict(_meta or {}); _rd.setdefault("id", deploy_id)
|
|
3054
3090
|
_rd.setdefault("_kind", kind); _rd.setdefault("name", _obj_name)
|
|
3055
3091
|
_report_deploy_outcome(api, cfg, _rd, "BLOCKED_DRIFT", "BLOCKED",
|
|
@@ -3477,17 +3513,41 @@ def _deploy_ddl_conflict(d: dict, live_idx: dict):
|
|
|
3477
3513
|
return (cur_min > doc_min, live, doc)
|
|
3478
3514
|
|
|
3479
3515
|
|
|
3480
|
-
|
|
3516
|
+
|
|
3517
|
+
|
|
3518
|
+
def _sync_cmd_for(db_name=None, items=None) -> str:
|
|
3519
|
+
"""Ready-to-run directed-sync command for blocked deploys.
|
|
3520
|
+
|
|
3521
|
+
items: list of ("--object"|"--table", NAME). Flags are repeatable and
|
|
3522
|
+
combinable (1.0.75+); dedupes preserving order. db_name optional.
|
|
3523
|
+
"""
|
|
3524
|
+
seen, parts = set(), []
|
|
3525
|
+
for flag, nm in (items or []):
|
|
3526
|
+
key = (flag, (nm or "").upper())
|
|
3527
|
+
if not nm or key in seen:
|
|
3528
|
+
continue
|
|
3529
|
+
seen.add(key)
|
|
3530
|
+
parts.append(f"{flag} {nm.upper()}")
|
|
3531
|
+
cmd = "baucli sync"
|
|
3532
|
+
if db_name:
|
|
3533
|
+
cmd += f" --db {db_name}"
|
|
3534
|
+
return cmd + (" " + " ".join(parts) if parts else "")
|
|
3535
|
+
|
|
3536
|
+
def _print_conflict_block(ref: str, d: dict, live_ddl, doc_ddl, db_name: str = None):
|
|
3481
3537
|
"""Uniform message when a deploy is blocked to protect in-progress work."""
|
|
3482
3538
|
console.print(
|
|
3483
3539
|
f" [red]BLOQUEADO[/red] — {d.get('schema','')}.{d.get('name','')} "
|
|
3484
3540
|
f"({d.get('type','')}) mudou no banco depois de documentado.")
|
|
3485
3541
|
console.print(
|
|
3486
3542
|
f" [dim]DDL vivo: {live_ddl or '?'} > documentado: {doc_ddl or '?'}[/dim]")
|
|
3543
|
+
_flag = "--table" if (d.get("type") or "").upper() in (
|
|
3544
|
+
"TABLE", "VIEW", "MATERIALIZED VIEW") else "--object"
|
|
3487
3545
|
console.print(
|
|
3488
3546
|
" [yellow]Não aplicado para não sobrescrever trabalho em andamento.[/yellow] "
|
|
3489
|
-
"
|
|
3490
|
-
"
|
|
3547
|
+
"Re-capture o fonte atual, re-documente/aprove e gere um novo header — "
|
|
3548
|
+
"ou reaplique com [cyan]--force[/cyan] se tiver certeza:")
|
|
3549
|
+
console.print(
|
|
3550
|
+
f" [cyan]{_sync_cmd_for(db_name, [(_flag, d.get('name') or '')])}[/cyan]")
|
|
3491
3551
|
|
|
3492
3552
|
|
|
3493
3553
|
@deploy.command("apply-all")
|
|
@@ -3741,6 +3801,7 @@ def deploy_apply_all(db_name: str, schema: str, kind: str, status: str,
|
|
|
3741
3801
|
live_idx = _build_live_ddl_index(extractor, _docpl_schemas)
|
|
3742
3802
|
|
|
3743
3803
|
applied_objs: list[str] = [] # DOCPL aplicados -> baseline pós-apply
|
|
3804
|
+
blocked_syncs: list[tuple] = [] # (--object|--table, NOME) p/ comando de sync no resumo
|
|
3744
3805
|
import uuid as _uuid
|
|
3745
3806
|
_batch_id = "aa-" + _uuid.uuid4().hex[:14] # agrupa este apply-all na trilha de suporte
|
|
3746
3807
|
|
|
@@ -3755,8 +3816,9 @@ def deploy_apply_all(db_name: str, schema: str, kind: str, status: str,
|
|
|
3755
3816
|
if not force:
|
|
3756
3817
|
_blk, _live, _doc = _deploy_ddl_conflict(d, live_idx)
|
|
3757
3818
|
if _blk:
|
|
3758
|
-
_print_conflict_block(ref, d, _live, _doc)
|
|
3819
|
+
_print_conflict_block(ref, d, _live, _doc, db_name=name)
|
|
3759
3820
|
blocked_refs.append(ref)
|
|
3821
|
+
blocked_syncs.append(("--table" if dkind == "doctab" else "--object", obj))
|
|
3760
3822
|
_report_deploy_outcome(api, cfg, d, "BLOCKED_LOSTUPDATE", "BLOCKED",
|
|
3761
3823
|
db_name=name, engine=db_config.get("engine"),
|
|
3762
3824
|
error="LAST_DDL vivo mais novo que o documentado",
|
|
@@ -3789,6 +3851,7 @@ def deploy_apply_all(db_name: str, schema: str, kind: str, status: str,
|
|
|
3789
3851
|
if _drift:
|
|
3790
3852
|
console.print(f" [yellow]BLOQUEADO (drift de código)[/yellow]: {_ddetail}")
|
|
3791
3853
|
blocked_refs.append(ref)
|
|
3854
|
+
blocked_syncs.append(("--object", obj))
|
|
3792
3855
|
_report_deploy_outcome(api, cfg, d, "BLOCKED_DRIFT", "BLOCKED",
|
|
3793
3856
|
db_name=name, engine=db_config.get("engine"), error=_ddetail,
|
|
3794
3857
|
deploy_mode="APPLY_ALL", batch_id=_batch_id)
|
|
@@ -3840,9 +3903,15 @@ def deploy_apply_all(db_name: str, schema: str, kind: str, status: str,
|
|
|
3840
3903
|
_post_apply_context(no_context)
|
|
3841
3904
|
if blocked_refs:
|
|
3842
3905
|
console.print(f"[yellow]{len(blocked_refs)} bloqueado(s)[/yellow] "
|
|
3843
|
-
f"(mudaram no banco desde a documentação): {', '.join(blocked_refs)}.
|
|
3844
|
-
|
|
3845
|
-
|
|
3906
|
+
f"(mudaram no banco desde a documentação): {', '.join(blocked_refs)}.")
|
|
3907
|
+
console.print(
|
|
3908
|
+
" Sincronize os bloqueados (re-captura o fonte atual), re-documente/aprove "
|
|
3909
|
+
"e gere novos headers — ou reaplique com [cyan]--force[/cyan]:")
|
|
3910
|
+
console.print(f" [cyan]{_sync_cmd_for(name, blocked_syncs)}[/cyan]")
|
|
3911
|
+
console.print(
|
|
3912
|
+
" [dim]Esse sync marca os deploys como CONFLITO na fila; dali em diante,[/dim] "
|
|
3913
|
+
f"[cyan]baucli sync --db {name} --conflicts[/cyan] [dim]re-sincroniza o que "
|
|
3914
|
+
"estiver em conflito, sem listar objeto a objeto.[/dim]")
|
|
3846
3915
|
if failed_refs:
|
|
3847
3916
|
console.print(f"[red]{len(failed_refs)} failed[/red] "
|
|
3848
3917
|
"(marcados FAILED na fila + registrados em BAU_DEPLOY_LOG):")
|
|
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
|
|
2
2
|
|
|
3
3
|
setup(
|
|
4
4
|
name="baucli",
|
|
5
|
-
version="1.0.
|
|
5
|
+
version="1.0.80",
|
|
6
6
|
description="Extracts verified business-logic and schema context from Oracle, PostgreSQL, MySQL and SQL Server",
|
|
7
7
|
long_description=open("README.md").read(),
|
|
8
8
|
long_description_content_type="text/markdown",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|