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.
Files changed (48) hide show
  1. {baucli-1.0.78 → baucli-1.0.80}/PKG-INFO +1 -1
  2. {baucli-1.0.78 → baucli-1.0.80}/baucli/__init__.py +1 -1
  3. {baucli-1.0.78 → baucli-1.0.80}/baucli/cli.py +80 -11
  4. {baucli-1.0.78 → baucli-1.0.80}/baucli.egg-info/PKG-INFO +1 -1
  5. {baucli-1.0.78 → baucli-1.0.80}/setup.py +1 -1
  6. {baucli-1.0.78 → baucli-1.0.80}/MANIFEST.in +0 -0
  7. {baucli-1.0.78 → baucli-1.0.80}/README.md +0 -0
  8. {baucli-1.0.78 → baucli-1.0.80}/baucli/apex_rebuild.py +0 -0
  9. {baucli-1.0.78 → baucli-1.0.80}/baucli/apexlang.py +0 -0
  10. {baucli-1.0.78 → baucli-1.0.80}/baucli/api.py +0 -0
  11. {baucli-1.0.78 → baucli-1.0.80}/baucli/canon.py +0 -0
  12. {baucli-1.0.78 → baucli-1.0.80}/baucli/config.py +0 -0
  13. {baucli-1.0.78 → baucli-1.0.80}/baucli/db/__init__.py +0 -0
  14. {baucli-1.0.78 → baucli-1.0.80}/baucli/db/mssql.py +0 -0
  15. {baucli-1.0.78 → baucli-1.0.80}/baucli/db/mysql.py +0 -0
  16. {baucli-1.0.78 → baucli-1.0.80}/baucli/db/oracle.py +0 -0
  17. {baucli-1.0.78 → baucli-1.0.80}/baucli/db/postgresql.py +0 -0
  18. {baucli-1.0.78 → baucli-1.0.80}/baucli/democrm.py +0 -0
  19. {baucli-1.0.78 → baucli-1.0.80}/baucli/democrm_sql/mssql/crm_data_mssql.sql +0 -0
  20. {baucli-1.0.78 → baucli-1.0.80}/baucli/democrm_sql/mssql/crm_demo_mssql.sql +0 -0
  21. {baucli-1.0.78 → baucli-1.0.80}/baucli/democrm_sql/mysql/crm_data_mysql.sql +0 -0
  22. {baucli-1.0.78 → baucli-1.0.80}/baucli/democrm_sql/mysql/crm_demo_mysql.sql +0 -0
  23. {baucli-1.0.78 → baucli-1.0.80}/baucli/democrm_sql/oracle/crm_demo_oracle.sql +0 -0
  24. {baucli-1.0.78 → baucli-1.0.80}/baucli/democrm_sql/postgresql/crm_data_postgresql.sql +0 -0
  25. {baucli-1.0.78 → baucli-1.0.80}/baucli/democrm_sql/postgresql/crm_demo_postgresql.sql +0 -0
  26. {baucli-1.0.78 → baucli-1.0.80}/baucli/diffenvs.py +0 -0
  27. {baucli-1.0.78 → baucli-1.0.80}/baucli/docmig.py +0 -0
  28. {baucli-1.0.78 → baucli-1.0.80}/baucli/git.py +0 -0
  29. {baucli-1.0.78 → baucli-1.0.80}/baucli/legacy/__init__.py +0 -0
  30. {baucli-1.0.78 → baucli-1.0.80}/baucli/legacy/delphi.py +0 -0
  31. {baucli-1.0.78 → baucli-1.0.80}/baucli/legacy/magic.py +0 -0
  32. {baucli-1.0.78 → baucli-1.0.80}/baucli/mcp_server.py +0 -0
  33. {baucli-1.0.78 → baucli-1.0.80}/baucli/project.py +0 -0
  34. {baucli-1.0.78 → baucli-1.0.80}/baucli/rag_embed.py +0 -0
  35. {baucli-1.0.78 → baucli-1.0.80}/baucli/sample_scan.py +0 -0
  36. {baucli-1.0.78 → baucli-1.0.80}/baucli/scope_scan.py +0 -0
  37. {baucli-1.0.78 → baucli-1.0.80}/baucli/screenshot.py +0 -0
  38. {baucli-1.0.78 → baucli-1.0.80}/baucli/seed_check.py +0 -0
  39. {baucli-1.0.78 → baucli-1.0.80}/baucli/skills.py +0 -0
  40. {baucli-1.0.78 → baucli-1.0.80}/baucli/stress.py +0 -0
  41. {baucli-1.0.78 → baucli-1.0.80}/baucli/sync.py +0 -0
  42. {baucli-1.0.78 → baucli-1.0.80}/baucli.egg-info/SOURCES.txt +0 -0
  43. {baucli-1.0.78 → baucli-1.0.80}/baucli.egg-info/dependency_links.txt +0 -0
  44. {baucli-1.0.78 → baucli-1.0.80}/baucli.egg-info/entry_points.txt +0 -0
  45. {baucli-1.0.78 → baucli-1.0.80}/baucli.egg-info/requires.txt +0 -0
  46. {baucli-1.0.78 → baucli-1.0.80}/baucli.egg-info/top_level.txt +0 -0
  47. {baucli-1.0.78 → baucli-1.0.80}/setup.cfg +0 -0
  48. {baucli-1.0.78 → baucli-1.0.80}/tests/test_canon_multiengine.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: baucli
3
- Version: 1.0.78
3
+ Version: 1.0.80
4
4
  Summary: Extracts verified business-logic and schema context from Oracle, PostgreSQL, MySQL and SQL Server
5
5
  Home-page: https://www.begcloud.com
6
6
  Author: BEG Support
@@ -3,6 +3,6 @@
3
3
  import warnings
4
4
  warnings.filterwarnings("ignore", message="urllib3 v2 only supports OpenSSL")
5
5
 
6
- __version__ = "1.0.78"
6
+ __version__ = "1.0.80"
7
7
  __product__ = "BAUCLI"
8
8
  __author__ = "BEG Support"
@@ -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(" Rode [cyan]baucli sync[/cyan] + re-documente, ou "
3052
- "[cyan]--force[/cyan] para sobrescrever.")
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
- def _print_conflict_block(ref: str, d: dict, live_ddl, doc_ddl):
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
- "Rode [cyan]baucli sync[/cyan] (re-captura o fonte atual), re-documente/aprove "
3490
- "e gere um novo header — ou reaplique com [cyan]--force[/cyan] se tiver certeza.")
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
- "Rode [cyan]baucli sync[/cyan] + re-documente, ou use "
3845
- "[cyan]--force[/cyan].")
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):")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: baucli
3
- Version: 1.0.78
3
+ Version: 1.0.80
4
4
  Summary: Extracts verified business-logic and schema context from Oracle, PostgreSQL, MySQL and SQL Server
5
5
  Home-page: https://www.begcloud.com
6
6
  Author: BEG Support
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="baucli",
5
- version="1.0.78",
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