@shundoo-ai/dsh-cosmic 1.0.21 → 1.0.22
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.
- package/package.json +1 -1
- package/skills/cosmic-build/LOCAL-PATCHES.md +43 -14
- package/skills/cosmic-build/SKILL.md +24 -9
- package/skills/cosmic-build/examples/java-rules/CosmicReportAggregation.java +26 -17
- package/skills/cosmic-build/examples/java-rules/CosmicReportFilters.java +96 -2
- package/skills/cosmic-build/knowledge/cosmic/arch/security/security_standard.md +4 -4
- package/skills/cosmic-build/knowledge/cosmic/platform/allimport.md +2 -1
- package/skills/cosmic-build/knowledge/cosmic/platform/core/dynamic-object-collection.md +6 -4
- package/skills/cosmic-build/knowledge/cosmic/platform/core/model.md +9 -9
- package/skills/cosmic-build/knowledge/cosmic/platform/core/view.md +5 -5
- package/skills/cosmic-build/knowledge/cosmic/platform/form-plugin.md +8 -4
- package/skills/cosmic-build/knowledge/cosmic/platform/list-plugin.md +5 -3
- package/skills/cosmic-build/knowledge/cosmic/platform/print-plugin-guide.md +1 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/report-plugin.md +269 -57
- package/skills/cosmic-build/knowledge/cosmic/platform/reportlistdata-plugin.md +130 -23
- package/skills/cosmic-build/knowledge/cosmic/platform/reporttreedata-plugin.md +48 -28
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/_index.md +12 -3
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/common/attachment-name-process.md +17 -13
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/common/dynamic-update-field.md +4 -4
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/control/filter-grid/filter-grid-set-value.md +1 -1
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/control/list/filter-basedatafield.md +2 -3
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/control/list/filter-container-init.md +0 -1
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/control/list/filter-popup.md +0 -1
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/control/list/filter-value-parse.md +5 -6
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/control/list/list-show-form.md +1 -1
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/control/list/query-field-dynamic.md +0 -7
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/data-access/business-data/delete-service.md +24 -29
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/data-access/ksql/db-batch.md +4 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/data-access/ksql/db-direct-access.md +4 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/data-access/qfilter/entity-object-access.md +8 -3
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/data-access/qfilter/qfilter-compose.md +6 -5
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/event/after-bind-data-set-visible.md +5 -1
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/event/click-return-data.md +2 -2
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/event/closed-call-back-set-value.md +2 -2
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/event/register-listener.md +1 -1
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/event/set-filter-tab-org.md +3 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/infra/dispatch-service/microservice-dev.md +18 -11
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/infra/dist-lock/dist-lock-basic.md +3 -6
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/infra/mq/mq-subscribe.md +5 -1
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/infra/thread-pool/async-operation.md +10 -6
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/infra/thread-pool/big-task-async.md +4 -2
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/infra/thread-pool/schedule-task.md +9 -7
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/operation/operation-interactive.md +33 -34
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/operation/operation-plugin-events.md +30 -22
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-async-query.md +133 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-batch-query.md +26 -22
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-chart.md +112 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-dataset-assembly.md +200 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-head-filter.md +177 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-hyperlink-drill.md +216 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-list-data-query.md +12 -12
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-merge-column.md +44 -6
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-print-data.md +163 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-row-data-toolbar.md +188 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-subtotal-total.md +139 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-tree-data-query.md +108 -12
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/report/report-tree-list.md +181 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/system-service/report-plugin-interface.md +3 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/tree/tree-basedata-cascade-confirm.md +14 -11
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/tree/tree-list-before-item-validate.md +1 -1
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/tree/tree-list-build-filter.md +1 -1
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/tree/tree-list-multi-level-filter.md +11 -11
- package/skills/cosmic-build/knowledge/cosmic/platform/scenes/tree/tree-list-refresh-node.md +22 -15
- package/skills/cosmic-build/knowledge/cosmic/platform/sdk/sdk-algo.md +2 -2
- package/skills/cosmic-build/knowledge/cosmic/platform/sdk/sdk-entity-model.md +3 -4
- package/skills/cosmic-build/knowledge/cosmic/platform/sdk/sdk-exception.md +9 -5
- package/skills/cosmic-build/knowledge/cosmic/platform/sdk/sdk-orm-access.md +4 -0
- package/skills/cosmic-build/knowledge/cosmic/platform/sdk/sdk-request-context.md +7 -3
- package/skills/cosmic-build/knowledge/cosmic/platform/standards.md +28 -3
- package/skills/cosmic-build/references/compile-guide.md +36 -1
- package/skills/cosmic-build/references/dcs-code-rules.md +180 -0
- package/skills/cosmic-build/references/delivery.md +16 -2
- package/skills/cosmic-build/references/execution-contract.md +15 -3
- package/skills/cosmic-build/references/java-plugin-delivery.md +21 -11
- package/skills/cosmic-build/references/plugin-handoff-input.md +82 -24
- package/skills/cosmic-build/references/plugin-runtime-routing.md +23 -6
- package/skills/cosmic-build/references/report-filter-contract.md +53 -15
- package/skills/cosmic-build/references/sdk-inspection.md +4 -1
- package/skills/cosmic-build/references/type-registry.json +26 -17
- package/skills/cosmic-build/schemas/data-model-authoring.schema.json +1 -1
- package/skills/cosmic-build/scripts/_http_client.py +3 -0
- package/skills/cosmic-build/scripts/compile_plugin_source.py +251 -42
- package/skills/cosmic-build/scripts/configure_list.py +112 -0
- package/skills/cosmic-build/scripts/dcs-rule-catalog.json +799 -0
- package/skills/cosmic-build/scripts/dcs_code_gate.py +1976 -0
- package/skills/cosmic-build/scripts/execution_binding.py +25 -0
- package/skills/cosmic-build/scripts/platform_api_contract.py +352 -7
- package/skills/cosmic-build/scripts/plugin_source_gate.py +9 -1
- package/skills/cosmic-build/scripts/plugin_target_sdk.py +12 -8
- package/skills/cosmic-build/scripts/prepare_plugin_handoff.py +488 -88
- package/skills/cosmic-build/scripts/query_plugin_handoff.py +207 -20
- package/skills/cosmic-build/scripts/register_plugins.py +27 -10
- package/skills/cosmic-build/scripts/render_output_cards.py +57 -20
- package/skills/cosmic-build/scripts/resolve_output_path.py +60 -26
- package/skills/cosmic-build/scripts/run_java_tests.py +162 -0
- package/skills/cosmic-build/scripts/sync_generated_locale_assets.py +28 -0
- package/skills/cosmic-build/scripts/test/fixtures/ReportSdkCheck.java +1 -22
- package/skills/cosmic-build/scripts/test/fixtures/list_column_property_declarations.json +887 -0
- package/skills/cosmic-build/scripts/test/fixtures/operation-entry-field-prepare.java +78 -0
- package/skills/cosmic-build/scripts/test/test_add_field_required_contract.py +12 -0
- package/skills/cosmic-build/scripts/test/test_batch5_drift_governance.py +23 -2
- package/skills/cosmic-build/scripts/test/test_compile_plugin_source.py +287 -4
- package/skills/cosmic-build/scripts/test/test_configure_list_delivery.py +132 -0
- package/skills/cosmic-build/scripts/test/test_cosmic_sdk_examples.py +58 -1
- package/skills/cosmic-build/scripts/test/test_data_model_contract.py +19 -0
- package/skills/cosmic-build/scripts/test/test_dcs_code_gate.py +901 -0
- package/skills/cosmic-build/scripts/test/test_delivery_stage_boundary.py +1 -1
- package/skills/cosmic-build/scripts/test/test_direct_cli_architecture.py +2 -0
- package/skills/cosmic-build/scripts/test/test_http_client.py +6 -0
- package/skills/cosmic-build/scripts/test/test_java_toolchain_feedback.py +206 -0
- package/skills/cosmic-build/scripts/test/test_kd_api.py +21 -0
- package/skills/cosmic-build/scripts/test/test_list_configuration_closure.py +184 -0
- package/skills/cosmic-build/scripts/test/test_mcp_cli.py +139 -2
- package/skills/cosmic-build/scripts/test/test_menu_creation_closure.py +16 -0
- package/skills/cosmic-build/scripts/test/test_modeling_input_recovery.py +55 -1
- package/skills/cosmic-build/scripts/test/test_open_world_cli_catalog.py +1 -1
- package/skills/cosmic-build/scripts/test/test_operation_field_preparation.py +84 -0
- package/skills/cosmic-build/scripts/test/test_platform_api_contract.py +322 -1
- package/skills/cosmic-build/scripts/test/test_plugin_handoff.py +951 -4
- package/skills/cosmic-build/scripts/test/test_plugin_source_gate.py +30 -2
- package/skills/cosmic-build/scripts/test/test_plugin_target_sdk.py +21 -0
- package/skills/cosmic-build/scripts/test/test_property_reroute.py +165 -0
- package/skills/cosmic-build/scripts/test/test_property_schema_first.py +35 -0
- package/skills/cosmic-build/scripts/test/test_query_plugin_handoff.py +221 -0
- package/skills/cosmic-build/scripts/test/test_register_plugins.py +76 -4
- package/skills/cosmic-build/scripts/test/test_render_output_cards.py +75 -3
- package/skills/cosmic-build/scripts/test/test_report_business_contract.py +27 -5
- package/skills/cosmic-build/scripts/test/test_report_doc_contract_sync.py +103 -11
- package/skills/cosmic-build/scripts/test/test_report_plugin_source_gate.py +46 -16
- package/skills/cosmic-build/scripts/test/test_report_properties.py +74 -15
- package/skills/cosmic-build/scripts/test/test_report_query_data_source.py +3 -1
- package/skills/cosmic-build/scripts/test/test_report_sdk_optimization.py +1 -2
- package/skills/cosmic-build/scripts/test/test_test_environment.py +76 -1
- package/skills/cosmic-build/scripts/test_environment.py +67 -1
- package/skills/cosmic-build/skills/cosmic-coding-impl/SKILL.md +52 -10
- package/skills/cosmic-build/skills/cosmic-meta-api/apis/ai_meta.md +16 -3
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/report-write-contracts.json +59 -26
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/cli/rule-domain.json +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/contracts/schema/report-write.schema.json +75 -18
- package/skills/cosmic-build/skills/cosmic-meta-api/modules/pdm/scripts/pdm_auto.py +39 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/modules/pdm/scripts/pdm_client.py +97 -10
- package/skills/cosmic-build/skills/cosmic-meta-api/modules/verify/SKILL.md +10 -12
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_apps.py +3 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_formactions.py +38 -29
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_listui.py +400 -233
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_metaops.py +87 -45
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_properties.py +42 -15
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/cmd_rules.py +135 -5
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/config.py +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/execution_errors.py +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/formatters.py +17 -11
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/property_reroute.py +15 -5
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/report_ops.py +1429 -238
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/_core/validators.py +56 -28
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/cosmic_api.py +380 -134
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/field_decorator.py +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/meta_export.py +12 -11
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/meta_verifier.py +42 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_add_field_placement_closure.py +8 -8
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_build_configuration_readback.py +94 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_build_receipt_resume.py +47 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_metadata_unchanged_fail_closed.py +87 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_dym_evidence.py +23 -23
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_entity_integrity.py +279 -4
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_field_guard.py +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_plugin_contract.py +509 -32
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_readback_derivation.py +178 -1
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_recreate_plan.py +125 -10
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_serve_contract.py +208 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_report_typed_filters.py +259 -50
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_rule_inventory_perf.py +29 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_rule_write_closure.py +20 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_run_batch_post_build_recovery.py +18 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_run_batch_verification_evidence.py +35 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_run_identity_guard.py +25 -0
- package/skills/cosmic-build/skills/cosmic-meta-api/scripts/test/test_time_range_rule.py +98 -0
- package/skills/cosmic-build/skills/cosmic-meta-knowledge/domain-model/report-model.md +20 -9
- package/skills/cosmic-build/skills/cosmic-meta-knowledge/generation/report-modeling-guide.md +55 -25
- package/skills/cosmic-build/skills/cosmic-meta-knowledge/property-guides/report-column-properties.md +15 -39
- package/skills/cosmic-build/skills/cosmic-meta-modeling/SKILL.md +19 -17
- package/skills/cosmic-build/skills/cosmic-meta-modeling/modules/report/SKILL.md +82 -38
- package/skills/cosmic-build/skills/cosmic-meta-modeling/modules/report/examples/golden-example-report-batch.md +64 -19
- package/skills/cosmic-build/skills/cosmic-meta-modeling/modules/report/examples/golden-example-report-plugin.md +32 -20
- package/skills/cosmic-build/skills/cosmic-meta-modeling/modules/report/examples/golden-example-report-tree.md +78 -31
- package/skills/cosmic-build/skills/cosmic-meta-modeling/modules/report/report-artifact-schema.json +2 -1
- package/skills/cosmic-build/skills/cosmic-meta-modeling/references/authoring-companion-fields.md +3 -0
- package/skills/cosmic-build/skills/cosmic-meta-modeling/references/authoring-list-configuration.md +2 -0
- package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/data_model_contract.py +3 -1
- package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/data_model_emit.py +27 -4
- package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/report_validator.py +99 -44
- package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/test_report_examples.py +31 -4
- package/skills/cosmic-build/skills/cosmic-meta-modeling/scripts/test_report_validator.py +129 -29
- package/skills/cosmic-build/skills/cosmic-meta-modifier/SKILL.md +6 -2
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/operation/validation.md +2 -0
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/property/SKILL.md +1 -1
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/report-op/SKILL.md +104 -25
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/rule/SKILL.md +9 -0
- package/skills/cosmic-build/skills/cosmic-meta-modifier/modules/verify/usage-guide.md +2 -2
- package/skills/cosmic-build/skills/cosmic-meta-modifier/references/list-filter-modification.md +39 -12
- package/skills/cosmic-build/skills/mcp-server/SKILL.md +39 -24
- package/skills/cosmic-build/skills/mcp-server/scripts/mcp_cli.py +20 -6
- package/skills/cosmic-dev-best-practices/SKILL.md +1 -1
- package/skills/cosmic-dev-best-practices/references/README.md +2 -2
- package/skills/cosmic-dev-best-practices/references/basedata-dev-convention.md +2 -2
- package/skills/cosmic-dev-best-practices/references/bill-dev-convention.md +4 -4
- package/skills/cosmic-dev-best-practices/references/design-document-convention.md +2 -2
- package/skills/cosmic-dev-best-practices/references/design-examples/basedata-design-example.md +4 -4
- package/skills/cosmic-dev-best-practices/references/design-examples/bill-design-example.md +13 -13
- package/skills/cosmic-dev-best-practices/references/elements/CustomerField.md +1 -1
- package/skills/cosmic-dev-best-practices/references/elements/README.md +1 -1
- package/skills/cosmic-dev-best-practices/references/elements/SupplierField.md +1 -1
- package/skills/cosmic-dev-best-practices/references/elements/common-field-property-conventions.md +109 -13
- package/skills/cosmic-dev-best-practices/references/layout-control-convention.md +1 -1
- package/skills/erp-analysis/references/delivery-contract.md +2 -1
- package/skills/erp-analysis/templates/AGENTS.template.md +3 -1
- package/skills/cosmic-build/assets/platform-report-filters/TypedReportFilterFields.java +0 -169
- package/skills/cosmic-build/assets/platform-report-filters/platform.patch +0 -98
- package/skills/cosmic-build/scripts/apply_report_filter_extension.py +0 -39
|
@@ -34,7 +34,11 @@ def _app_context(app_root: str) -> dict:
|
|
|
34
34
|
root = Path(app_root)
|
|
35
35
|
context = _read_json(root / "_runtime" / "context.json")
|
|
36
36
|
archive = _read_json(root / "archive.json")
|
|
37
|
-
app_code = str(
|
|
37
|
+
app_code = str(
|
|
38
|
+
context.get("appCode")
|
|
39
|
+
or archive.get("appCode")
|
|
40
|
+
or root.name
|
|
41
|
+
).strip()
|
|
38
42
|
configured_package = ""
|
|
39
43
|
for source in (context, archive):
|
|
40
44
|
for key in CONTEXT_PACKAGE_KEYS:
|
|
@@ -51,14 +55,21 @@ def _is_java_project(path: str | Path) -> bool:
|
|
|
51
55
|
return root.is_dir() and (root / "src" / "main" / "java").is_dir()
|
|
52
56
|
|
|
53
57
|
|
|
54
|
-
def _project_result(candidate: str, source: str, app_code: str) -> dict:
|
|
58
|
+
def _project_result(candidate: str, source: str, app_code: str, prepare_source: bool = False) -> dict:
|
|
55
59
|
root = Path(candidate).expanduser()
|
|
60
|
+
if prepare_source and inspect_config().get("status") == "disabled":
|
|
61
|
+
try:
|
|
62
|
+
(root / "src" / "main" / "java").mkdir(parents=True, exist_ok=True)
|
|
63
|
+
except OSError:
|
|
64
|
+
return {"projectRoot": None, "projectRootSource": source, "appCode": app_code,
|
|
65
|
+
"errorCode": "PLUGIN_WORKSPACE_UNWRITABLE",
|
|
66
|
+
"error": f"Cannot prepare source-only workspace at {root}; select a writable --java-project-root"}
|
|
56
67
|
if not _is_java_project(root):
|
|
57
68
|
return {
|
|
58
69
|
"projectRoot": None,
|
|
59
70
|
"projectRootSource": source,
|
|
60
71
|
"errorCode": "PLUGIN_WORKSPACE_UNRESOLVED",
|
|
61
|
-
"error": f"{source}
|
|
72
|
+
"error": f"{source} has no src/main/java: {root}",
|
|
62
73
|
"appCode": app_code,
|
|
63
74
|
}
|
|
64
75
|
return {
|
|
@@ -70,13 +81,15 @@ def _project_result(candidate: str, source: str, app_code: str) -> dict:
|
|
|
70
81
|
|
|
71
82
|
|
|
72
83
|
def _preset_app_local_java_workspace(app_root: str) -> bool:
|
|
73
|
-
"""
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
84
|
+
"""Create the deterministic in-app Java module when compilation is disabled.
|
|
85
|
+
|
|
86
|
+
A metadata-only workspace used to fail closed here and hand the directory
|
|
87
|
+
decision to a user question — a first report delivery asked where to put its
|
|
88
|
+
class. With compile=false the delivery completes as `source_ready (compile
|
|
89
|
+
skipped by config)` without touching Gradle, so the appRoot is a sound fixed
|
|
90
|
+
home: per-app, and picked up by rank 5 on every later run once created.
|
|
91
|
+
While compilation is enabled or undecided the preset stays off: a real
|
|
92
|
+
Gradle module must resolve.
|
|
80
93
|
"""
|
|
81
94
|
if inspect_config().get("status") != "disabled":
|
|
82
95
|
return False
|
|
@@ -90,20 +103,22 @@ def _preset_app_local_java_workspace(app_root: str) -> bool:
|
|
|
90
103
|
return True
|
|
91
104
|
|
|
92
105
|
|
|
93
|
-
def _resolve_project_root(app_root: str, cli_project_root: str | None = None) -> dict:
|
|
106
|
+
def _resolve_project_root(app_root: str, cli_project_root: str | None = None, prepare_source: bool = False) -> dict:
|
|
94
107
|
context = _read_json(Path(app_root) / "_runtime" / "context.json")
|
|
95
108
|
app_code = _app_context(app_root)["appCode"]
|
|
96
109
|
if cli_project_root:
|
|
97
|
-
return _project_result(cli_project_root, "
|
|
110
|
+
return _project_result(cli_project_root, "explicit javaProjectRoot", app_code, prepare_source)
|
|
98
111
|
for key in CONTEXT_PROJECT_KEYS:
|
|
99
112
|
candidate = str(context.get(key) or "").strip()
|
|
100
113
|
if candidate:
|
|
101
114
|
return _project_result(candidate, f"context.{key}", app_code)
|
|
102
|
-
#
|
|
103
|
-
#
|
|
104
|
-
# --save-plugin-project
|
|
105
|
-
#
|
|
106
|
-
#
|
|
115
|
+
# The bound project outranks appconfig. appconfig.json is machine level and its pluginProjects
|
|
116
|
+
# map is keyed by appCode alone, so one appCode opened from two project directories shares one
|
|
117
|
+
# mapping: a --save-plugin-project run in another checkout kept sending later plugins there
|
|
118
|
+
# even when the bound project root was itself a Java module, which is how a generated report
|
|
119
|
+
# plugin landed outside the project the user was working in. appconfig is specified for the
|
|
120
|
+
# case where the metadata workspace is not the Java module, so it is reached only when the
|
|
121
|
+
# bound root is absent or is not one.
|
|
107
122
|
metadata_project = str(context.get("projectRoot") or "").strip()
|
|
108
123
|
if metadata_project and _is_java_project(metadata_project):
|
|
109
124
|
return _project_result(metadata_project, "context.projectRoot", app_code)
|
|
@@ -123,10 +138,10 @@ def _resolve_project_root(app_root: str, cli_project_root: str | None = None) ->
|
|
|
123
138
|
"projectRootSource": "unresolved",
|
|
124
139
|
"errorCode": "PLUGIN_WORKSPACE_UNRESOLVED",
|
|
125
140
|
"error": (
|
|
126
|
-
f"
|
|
127
|
-
"
|
|
141
|
+
f"No Java plugin project is configured for appCode={app_code}, and the app-local "
|
|
142
|
+
"preset applies only while compile=false in appconfig. Configure one with "
|
|
128
143
|
"appconfig_load.py --save-plugin-project "
|
|
129
|
-
f"{app_code} --plugin-project-root <moduleRoot
|
|
144
|
+
f"{app_code} --plugin-project-root <moduleRoot>."
|
|
130
145
|
),
|
|
131
146
|
"appCode": app_code,
|
|
132
147
|
}
|
|
@@ -202,8 +217,13 @@ def _registry_type(root_dir: str, task_type: str) -> dict:
|
|
|
202
217
|
return {}
|
|
203
218
|
|
|
204
219
|
|
|
205
|
-
def resolve_output_path(app_root: str, task_type: str, project_root: str | None = None
|
|
206
|
-
|
|
220
|
+
def resolve_output_path(app_root: str, task_type: str, project_root: str | None = None,
|
|
221
|
+
prepare_source: bool = False, source_directory: str | None = None) -> dict:
|
|
222
|
+
registry_type = _registry_type(_find_root_dir(), task_type)
|
|
223
|
+
if not registry_type.get("outputDir"):
|
|
224
|
+
return {"projectRoot": None, "packagePath": None, "outputDir": None, "classSuffix": None,
|
|
225
|
+
"errorCode": "PLUGIN_TYPE_UNSUPPORTED", "error": f"Unknown plugin type: {task_type}"}
|
|
226
|
+
project_resolution = _resolve_project_root(app_root, cli_project_root=project_root, prepare_source=prepare_source)
|
|
207
227
|
resolved_project = project_resolution.get("projectRoot")
|
|
208
228
|
if not resolved_project:
|
|
209
229
|
return {
|
|
@@ -212,17 +232,31 @@ def resolve_output_path(app_root: str, task_type: str, project_root: str | None
|
|
|
212
232
|
"outputDir": None,
|
|
213
233
|
"classSuffix": None,
|
|
214
234
|
}
|
|
215
|
-
base_path = _resolve_base_package_path(resolved_project, app_root=app_root)
|
|
216
|
-
registry_type = _registry_type(_find_root_dir(), task_type)
|
|
217
235
|
type_dir = str(registry_type.get("outputDir") or "").strip("/")
|
|
218
|
-
|
|
236
|
+
if source_directory:
|
|
237
|
+
java_root = (Path(resolved_project) / "src" / "main" / "java").resolve()
|
|
238
|
+
directory = Path(source_directory).expanduser().resolve()
|
|
239
|
+
try:
|
|
240
|
+
relative = directory.relative_to(java_root)
|
|
241
|
+
except ValueError:
|
|
242
|
+
return {"projectRoot": None, "packagePath": None, "outputDir": None, "classSuffix": None,
|
|
243
|
+
"errorCode": "PLUGIN_WORKSPACE_UNRESOLVED", "error": "Source directory must be inside the selected module src/main/java"}
|
|
244
|
+
if any(not re.fullmatch(r"[A-Za-z_$][A-Za-z0-9_$]*", part) for part in relative.parts):
|
|
245
|
+
return {"projectRoot": None, "packagePath": None, "outputDir": None, "classSuffix": None,
|
|
246
|
+
"errorCode": "PLUGIN_PACKAGE_UNRESOLVED", "error": "Source directory must identify a valid Java package"}
|
|
247
|
+
base_path = _convention_package_root(_app_context(app_root)["appCode"])
|
|
248
|
+
package_path = "/".join(relative.parts) if relative.parts else "/".join((base_path, type_dir)) if base_path and type_dir else None
|
|
249
|
+
else:
|
|
250
|
+
base_path = _resolve_base_package_path(resolved_project, app_root=app_root)
|
|
251
|
+
package_path = "/".join((base_path, type_dir)) if base_path and type_dir else None
|
|
219
252
|
result = {
|
|
220
253
|
"projectRoot": resolved_project,
|
|
221
254
|
"projectRootSource": project_resolution.get("projectRootSource"),
|
|
222
255
|
"errorCode": "0",
|
|
223
256
|
"packagePath": package_path,
|
|
224
257
|
"outputDir": f"src/main/java/{package_path}" if package_path else None,
|
|
225
|
-
#
|
|
258
|
+
# The suffix the coding step appends when no className is supplied, so a caller can look
|
|
259
|
+
# for the class that convention would have created.
|
|
226
260
|
"classSuffix": str(registry_type.get("classSuffix") or "").strip() or None,
|
|
227
261
|
}
|
|
228
262
|
if not type_dir:
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Run the bound Gradle Java test task and report observed tests, without archiving plugins."""
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import hashlib
|
|
7
|
+
import json
|
|
8
|
+
import os
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
import subprocess
|
|
11
|
+
import sys
|
|
12
|
+
import tempfile
|
|
13
|
+
|
|
14
|
+
from compile_plugin_source import compile_handoff, inspect_compile_environment, parse_compiler_errors
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# The observer lives only for this invocation. Project build files and test assertions are unchanged.
|
|
18
|
+
OBSERVER = r'''
|
|
19
|
+
import groovy.json.JsonOutput
|
|
20
|
+
import org.gradle.api.tasks.testing.Test
|
|
21
|
+
import org.gradle.api.tasks.testing.TestResult
|
|
22
|
+
|
|
23
|
+
def receipt = new File(System.getenv('APP_BUILD_TEST_RECEIPT'))
|
|
24
|
+
def observed = [available: false]
|
|
25
|
+
def persist = { receipt.text = JsonOutput.toJson(observed) }
|
|
26
|
+
gradle.projectsEvaluated {
|
|
27
|
+
def owner = gradle.rootProject.allprojects.find {
|
|
28
|
+
it.projectDir.canonicalPath == new File(System.getenv('APP_BUILD_TEST_PROJECT')).canonicalPath
|
|
29
|
+
}
|
|
30
|
+
def task = owner?.tasks?.findByName('test')
|
|
31
|
+
if (!(task instanceof Test)) {
|
|
32
|
+
observed.reason = 'The bound module has no Gradle Test task named test'
|
|
33
|
+
persist()
|
|
34
|
+
throw new GradleException(observed.reason)
|
|
35
|
+
}
|
|
36
|
+
observed.available = true
|
|
37
|
+
observed.task = task.path
|
|
38
|
+
observed.reportsDirectory = task.reports.junitXml.outputLocation.get().asFile.absolutePath
|
|
39
|
+
observed.counts = [total: 0, passed: 0, failed: 0, skipped: 0]
|
|
40
|
+
observed.failures = []
|
|
41
|
+
persist()
|
|
42
|
+
if (System.getenv('APP_BUILD_RERUN_TESTS') == '1') {
|
|
43
|
+
task.outputs.upToDateWhen { false }
|
|
44
|
+
task.outputs.doNotCacheIf('Explicit app-build test rerun') { true }
|
|
45
|
+
}
|
|
46
|
+
task.afterTest { descriptor, result ->
|
|
47
|
+
if (result.resultType == TestResult.ResultType.FAILURE) {
|
|
48
|
+
observed.failureCount = (observed.failureCount ?: 0) + 1
|
|
49
|
+
if (observed.failures.size() < 20) {
|
|
50
|
+
observed.failures.add([className: descriptor.className, name: descriptor.name,
|
|
51
|
+
exceptions: result.exceptions.take(5).collect { exception ->
|
|
52
|
+
def trace = new StringWriter()
|
|
53
|
+
exception.printStackTrace(new PrintWriter(trace))
|
|
54
|
+
def text = trace.toString()
|
|
55
|
+
[type: exception.class.name, message: exception.message?.take(4000),
|
|
56
|
+
stackTrace: text.take(8000), truncated: text.length() > 8000]
|
|
57
|
+
}])
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
task.afterSuite { descriptor, result ->
|
|
62
|
+
if (descriptor.parent == null) {
|
|
63
|
+
observed.counts = [total: result.testCount, passed: result.successfulTestCount,
|
|
64
|
+
failed: result.failedTestCount, skipped: result.skippedTestCount]
|
|
65
|
+
persist()
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
gradle.taskGraph.afterTask { current, state ->
|
|
69
|
+
if (current.path == task.path) {
|
|
70
|
+
observed.state = [skipped: state.skipped, skipMessage: state.skipMessage,
|
|
71
|
+
upToDate: state.upToDate, noSource: state.noSource,
|
|
72
|
+
failure: state.failure?.toString()]
|
|
73
|
+
persist()
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
'''
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def run_tests(project_root: str, *, tests: list[str] | None = None, timeout_sec: int = 300,
|
|
81
|
+
rerun: bool = False) -> dict:
|
|
82
|
+
environment = inspect_compile_environment(project_root)
|
|
83
|
+
if environment.get('status') != 'ready':
|
|
84
|
+
return {'status': False, 'outcome': 'environment-unavailable', 'errorCode': 'JAVA_TEST_ENVIRONMENT_UNAVAILABLE',
|
|
85
|
+
'buildEnvironment': environment}
|
|
86
|
+
project = Path(project_root).resolve()
|
|
87
|
+
task = f"{environment['module']}:test" if environment['module'] else ':test'
|
|
88
|
+
command = [environment['wrapperPath'], task, '--console=plain']
|
|
89
|
+
for pattern in tests or []:
|
|
90
|
+
if not pattern.strip() or any(character in pattern for character in '\r\n\0'):
|
|
91
|
+
return {'status': False, 'outcome': 'invalid-input', 'errorCode': 'JAVA_TEST_SELECTOR_INVALID'}
|
|
92
|
+
command += ['--tests', pattern]
|
|
93
|
+
env = {**os.environ, 'JAVA_HOME': environment['javaHome'], 'APP_BUILD_TEST_PROJECT': str(project),
|
|
94
|
+
'APP_BUILD_RERUN_TESTS': '1' if rerun else '0'}
|
|
95
|
+
with tempfile.TemporaryDirectory(prefix='app-build-java-tests-') as temporary:
|
|
96
|
+
directory = Path(temporary)
|
|
97
|
+
observer = directory / 'observe.gradle'
|
|
98
|
+
receipt = directory / 'result.json'
|
|
99
|
+
observer.write_text(OBSERVER, encoding='utf-8')
|
|
100
|
+
env['APP_BUILD_TEST_RECEIPT'] = str(receipt)
|
|
101
|
+
try:
|
|
102
|
+
completed = subprocess.run([*command, '--init-script', str(observer)], cwd=environment['gradleRoot'],
|
|
103
|
+
env=env, capture_output=True, text=True, timeout=max(1, timeout_sec), check=False)
|
|
104
|
+
output = completed.stdout + completed.stderr
|
|
105
|
+
exit_code = completed.returncode
|
|
106
|
+
except subprocess.TimeoutExpired as error:
|
|
107
|
+
output = ''.join(value.decode('utf-8', 'replace') if isinstance(value, bytes) else value or ''
|
|
108
|
+
for value in (error.stdout, error.stderr))
|
|
109
|
+
exit_code = None
|
|
110
|
+
observed = json.loads(receipt.read_text(encoding='utf-8')) if receipt.is_file() else {}
|
|
111
|
+
log = project / '.temp' / 'plugin-tests' / (hashlib.sha256(output.encode()).hexdigest() + '.log')
|
|
112
|
+
log.parent.mkdir(parents=True, exist_ok=True)
|
|
113
|
+
log.write_text(output, encoding='utf-8')
|
|
114
|
+
counts = observed.get('counts', {'total': 0, 'passed': 0, 'failed': 0, 'skipped': 0})
|
|
115
|
+
state = observed.get('state', {})
|
|
116
|
+
outcome = ('timed-out' if exit_code is None else
|
|
117
|
+
'task-unavailable' if observed.get('available') is False else
|
|
118
|
+
'test-failed' if counts['failed'] or observed.get('failureCount') else
|
|
119
|
+
'build-failed' if exit_code != 0 or state.get('failure') else
|
|
120
|
+
'up-to-date' if state.get('upToDate') else
|
|
121
|
+
'no-tests' if state.get('noSource') else
|
|
122
|
+
'skipped' if state.get('skipped') else
|
|
123
|
+
'no-tests' if not counts['total'] else
|
|
124
|
+
'skipped' if counts['skipped'] == counts['total'] else 'passed')
|
|
125
|
+
result = {'status': outcome == 'passed', 'outcome': outcome,
|
|
126
|
+
'errorCode': '0' if outcome == 'passed' else 'JAVA_TEST_' + outcome.upper().replace('-', '_'),
|
|
127
|
+
'projectRoot': str(project), 'gradleRoot': environment['gradleRoot'], 'javaHome': environment['javaHome'],
|
|
128
|
+
'task': task, 'command': command, 'exitCode': exit_code, 'selectors': tests or [],
|
|
129
|
+
'rerunTests': rerun, 'counts': counts, 'taskState': state,
|
|
130
|
+
'failures': observed.get('failures', []), 'failureCount': observed.get('failureCount', 0),
|
|
131
|
+
'reportsDirectory': observed.get('reportsDirectory'), 'logPath': str(log),
|
|
132
|
+
'diagnostics': parse_compiler_errors(output),
|
|
133
|
+
'evidenceScope': 'Observed target Gradle test events only; no plugin registration, runtime activation or business coverage beyond the executed tests is established'}
|
|
134
|
+
if observed.get('reason'):
|
|
135
|
+
result['message'] = observed['reason']
|
|
136
|
+
if result['failureCount'] > len(result['failures']):
|
|
137
|
+
result['failuresTruncated'] = True
|
|
138
|
+
return result
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def main() -> int:
|
|
142
|
+
parser = argparse.ArgumentParser(description=__doc__)
|
|
143
|
+
target = parser.add_mutually_exclusive_group(required=True)
|
|
144
|
+
target.add_argument('--project-root', help='Existing bound Java module root')
|
|
145
|
+
target.add_argument('--handoff', help='Reuse the verified Java module from a prepared handoff')
|
|
146
|
+
parser.add_argument('--tests', action='append', help='Gradle test class/method filter; repeat for multiple selectors')
|
|
147
|
+
parser.add_argument('--rerun-tests', action='store_true', help='Execute the selected test task again; keep compilation incremental')
|
|
148
|
+
parser.add_argument('--timeout-sec', type=int, default=300)
|
|
149
|
+
args = parser.parse_args()
|
|
150
|
+
try:
|
|
151
|
+
result = run_tests(compile_handoff(args.handoff)['projectRoot'] if args.handoff else args.project_root,
|
|
152
|
+
tests=args.tests, timeout_sec=args.timeout_sec, rerun=args.rerun_tests)
|
|
153
|
+
except (ValueError, OSError) as error:
|
|
154
|
+
result = {'status': False, 'outcome': 'environment-unavailable',
|
|
155
|
+
'errorCode': getattr(error, 'code', 'JAVA_TEST_ENVIRONMENT_UNAVAILABLE'),
|
|
156
|
+
'message': str(error), **getattr(error, 'details', {})}
|
|
157
|
+
print(json.dumps(result, ensure_ascii=False))
|
|
158
|
+
return 0 if result.get('status') is True else 2
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
if __name__ == '__main__':
|
|
162
|
+
raise SystemExit(main())
|
|
@@ -24,6 +24,23 @@ ZH_ROOT = APP_BUILD_ROOT / ".locales" / "zh"
|
|
|
24
24
|
# unit: schema -> direct CLI normalizer/readback -> artifact validator. The two
|
|
25
25
|
# report SKILL.md files are deliberately absent because their prose is localized.
|
|
26
26
|
GENERATED_FAMILIES: dict[str, tuple[str, ...]] = {
|
|
27
|
+
# 报表修复仅同步共用示例、改道实现和测试。cmd_apps.py、validators.py
|
|
28
|
+
# 保留人工中文提示,修复须精准移植并在各自入口运行同一套行为回归。
|
|
29
|
+
"report-repair-v1": (
|
|
30
|
+
"examples/java-rules/CosmicReportFilters.java",
|
|
31
|
+
"skills/cosmic-meta-api/scripts/_core/cmd_metaops.py",
|
|
32
|
+
"skills/cosmic-meta-api/scripts/_core/property_reroute.py",
|
|
33
|
+
"scripts/test/test_cosmic_sdk_examples.py",
|
|
34
|
+
"scripts/test/test_menu_creation_closure.py",
|
|
35
|
+
"scripts/test/test_property_reroute.py",
|
|
36
|
+
# 新 API 逐项回执与 no_op 的执行回归必须跟随两侧 cmd_metaops 同步。
|
|
37
|
+
"skills/cosmic-meta-api/scripts/test/test_metadata_unchanged_fail_closed.py",
|
|
38
|
+
),
|
|
39
|
+
# The localized executable had drifted behind canonical list property support.
|
|
40
|
+
"list-execution-v1": (
|
|
41
|
+
"scripts/configure_list.py",
|
|
42
|
+
"skills/cosmic-meta-api/scripts/_core/cmd_listui.py",
|
|
43
|
+
),
|
|
27
44
|
# Batch recovery must not differ between the canonical and zh entry.
|
|
28
45
|
# These files publish machine results and use the same locale-aware runtime.
|
|
29
46
|
"execution-recovery-v1": (
|
|
@@ -40,6 +57,9 @@ GENERATED_FAMILIES: dict[str, tuple[str, ...]] = {
|
|
|
40
57
|
"skills/cosmic-meta-api/scripts/_core/cmd_rules.py",
|
|
41
58
|
"skills/cosmic-meta-api/scripts/_core/formatters.py",
|
|
42
59
|
"skills/cosmic-meta-api/scripts/test/test_build_receipt_resume.py",
|
|
60
|
+
"skills/cosmic-meta-api/scripts/test/test_run_batch_verification_evidence.py",
|
|
61
|
+
"skills/cosmic-meta-api/scripts/test/test_run_batch_post_build_recovery.py",
|
|
62
|
+
"skills/cosmic-meta-api/scripts/test/test_build_configuration_readback.py",
|
|
43
63
|
"skills/cosmic-meta-api/scripts/test/test_creation_identity_boundary.py",
|
|
44
64
|
"scripts/test/test_rule_batch_evidence.py",
|
|
45
65
|
),
|
|
@@ -192,6 +212,11 @@ GENERATED_FAMILIES: dict[str, tuple[str, ...]] = {
|
|
|
192
212
|
"scripts/prepare_plugin_handoff.py",
|
|
193
213
|
"scripts/java_source.py",
|
|
194
214
|
"scripts/compile_plugin_source.py",
|
|
215
|
+
"scripts/run_java_tests.py",
|
|
216
|
+
"scripts/test/test_java_toolchain_feedback.py",
|
|
217
|
+
"scripts/dcs_code_gate.py",
|
|
218
|
+
# 门禁按脚本所在目录读取规则目录,两侧必须带同一依赖资产。
|
|
219
|
+
"scripts/dcs-rule-catalog.json",
|
|
195
220
|
"scripts/plugin_source_gate.py",
|
|
196
221
|
"scripts/java_write_guard.js",
|
|
197
222
|
"scripts/platform_api_contract.py",
|
|
@@ -202,6 +227,8 @@ GENERATED_FAMILIES: dict[str, tuple[str, ...]] = {
|
|
|
202
227
|
# JSON pointer queries are read-only and language-neutral. Mirror the single implementation
|
|
203
228
|
# and its CLI regression to the zh skill so either locale can inspect the same native handoff.
|
|
204
229
|
"plugin-handoff-query-v1": (
|
|
230
|
+
"scripts/test_environment.py",
|
|
231
|
+
"scripts/test/test_test_environment.py",
|
|
205
232
|
"scripts/query_plugin_handoff.py",
|
|
206
233
|
"scripts/test/test_query_plugin_handoff.py",
|
|
207
234
|
),
|
|
@@ -229,6 +256,7 @@ GENERATED_FAMILIES: dict[str, tuple[str, ...]] = {
|
|
|
229
256
|
"scripts/test/fixtures/java_context_booking_native.json",
|
|
230
257
|
"scripts/test/test_guide_skeleton_contract.py",
|
|
231
258
|
"scripts/test/test_compile_plugin_source.py",
|
|
259
|
+
"scripts/test/test_dcs_code_gate.py",
|
|
232
260
|
"scripts/test/test_plugin_source_gate.py",
|
|
233
261
|
"scripts/test/test_platform_api_contract.py",
|
|
234
262
|
"scripts/test/test_java_source.py",
|
|
@@ -1,36 +1,16 @@
|
|
|
1
1
|
import kd.bos.algo.*;
|
|
2
|
-
import kd.bos.designer.property.setting.TypedReportFilterFields;
|
|
3
|
-
import kd.bos.metadata.entity.commonfield.ComboField;
|
|
4
|
-
import kd.bos.metadata.entity.commonfield.ComboItem;
|
|
5
|
-
import kd.bos.metadata.entity.commonfield.DateField;
|
|
6
|
-
import kd.bos.metadata.entity.commonfield.DateRangeField;
|
|
7
|
-
import kd.bos.metadata.entity.businessfield.BasedataField;
|
|
8
|
-
import kd.bos.dataentity.entity.LocaleString;
|
|
9
2
|
import java.util.*;
|
|
10
3
|
import java.math.BigDecimal;
|
|
11
4
|
import java.util.concurrent.*;
|
|
12
5
|
|
|
13
6
|
public class ReportSdkCheck {
|
|
14
|
-
// Isolate logging only. All
|
|
7
|
+
// Isolate logging only. All DataSet joins and aggregates are actual SDK objects.
|
|
15
8
|
public static class TestLogFactory extends kd.bos.logging.LogFactory {
|
|
16
9
|
protected kd.bos.logging.Log _getLog(String name) {
|
|
17
10
|
return (kd.bos.logging.Log) java.lang.reflect.Proxy.newProxyInstance(kd.bos.logging.Log.class.getClassLoader(),
|
|
18
11
|
new Class[]{kd.bos.logging.Log.class}, (proxy, method, args) -> method.getReturnType() == boolean.class ? false : null);
|
|
19
12
|
}
|
|
20
13
|
}
|
|
21
|
-
static void fields() {
|
|
22
|
-
BasedataField source = new BasedataField(); source.setKey("supplier");source.setBaseEntityId("bd_supplier");source.setDisplayProp("name");
|
|
23
|
-
kd.bos.metadata.entity.commonfield.Field<?> copied = TypedReportFilterFields.create(source,"67");
|
|
24
|
-
if (copied == source || !"bd_supplier".equals(((BasedataField)copied).getBaseEntityId())) throw new AssertionError("reference");
|
|
25
|
-
ComboField combo = new ComboField();combo.setItems(Arrays.asList(new ComboItem(0,new LocaleString("zero"),"0")));
|
|
26
|
-
ComboField cloned = (ComboField)TypedReportFilterFields.create(combo,"67");
|
|
27
|
-
if (cloned.getItems()==combo.getItems() || !"0".equals(cloned.getItems().get(0).getValue())) throw new AssertionError("enum");
|
|
28
|
-
if (!(TypedReportFilterFields.create(new DateField(),"13") instanceof DateRangeField)) throw new AssertionError("range");
|
|
29
|
-
if (!(TypedReportFilterFields.create(new DateField(),"105") instanceof DateField)) throw new AssertionError("date");
|
|
30
|
-
source.setOrgFieldId("source-org-id");
|
|
31
|
-
try { TypedReportFilterFields.create(source,"67");throw new AssertionError("organization dependency silently lost"); }
|
|
32
|
-
catch(IllegalArgumentException expected) { }
|
|
33
|
-
}
|
|
34
14
|
static RowMeta headersMeta() {
|
|
35
15
|
return new RowMeta(new Field("id",DataType.LongType),new Field("supplier",DataType.StringType),
|
|
36
16
|
new Field("bill_date",DataType.DateType),new Field("base_amount",DataType.createBigDecimalType(18,2)));
|
|
@@ -53,7 +33,6 @@ public class ReportSdkCheck {
|
|
|
53
33
|
if(count!=2) throw new AssertionError("supplier membership");result.close();
|
|
54
34
|
}
|
|
55
35
|
public static void main(String[] args) throws Exception {
|
|
56
|
-
fields();
|
|
57
36
|
ExecutorService executor=kd.bos.threads.ThreadPools.newExecutorService("report-check",1);
|
|
58
37
|
java.util.concurrent.atomic.AtomicBoolean completed=new java.util.concurrent.atomic.AtomicBoolean();
|
|
59
38
|
try { executor.submit(() -> { try(AlgoContext context=Algo.newContext()) { amounts();completed.set(true); } }).get(20,TimeUnit.SECONDS); } catch(Exception error) { error.printStackTrace();System.exit(2); }
|