cumulusci-plus 5.0.0__py3-none-any.whl
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.
Potentially problematic release.
This version of cumulusci-plus might be problematic. Click here for more details.
- cumulusci/__about__.py +1 -0
- cumulusci/__init__.py +22 -0
- cumulusci/__main__.py +3 -0
- cumulusci/cli/__init__.py +0 -0
- cumulusci/cli/cci.py +244 -0
- cumulusci/cli/error.py +125 -0
- cumulusci/cli/flow.py +185 -0
- cumulusci/cli/logger.py +72 -0
- cumulusci/cli/org.py +692 -0
- cumulusci/cli/plan.py +181 -0
- cumulusci/cli/project.py +391 -0
- cumulusci/cli/robot.py +116 -0
- cumulusci/cli/runtime.py +190 -0
- cumulusci/cli/service.py +521 -0
- cumulusci/cli/task.py +295 -0
- cumulusci/cli/tests/__init__.py +0 -0
- cumulusci/cli/tests/test_cci.py +545 -0
- cumulusci/cli/tests/test_error.py +170 -0
- cumulusci/cli/tests/test_flow.py +276 -0
- cumulusci/cli/tests/test_logger.py +25 -0
- cumulusci/cli/tests/test_org.py +1438 -0
- cumulusci/cli/tests/test_plan.py +245 -0
- cumulusci/cli/tests/test_project.py +235 -0
- cumulusci/cli/tests/test_robot.py +177 -0
- cumulusci/cli/tests/test_runtime.py +197 -0
- cumulusci/cli/tests/test_service.py +853 -0
- cumulusci/cli/tests/test_task.py +266 -0
- cumulusci/cli/tests/test_ui.py +310 -0
- cumulusci/cli/tests/test_utils.py +122 -0
- cumulusci/cli/tests/utils.py +52 -0
- cumulusci/cli/ui.py +234 -0
- cumulusci/cli/utils.py +150 -0
- cumulusci/conftest.py +181 -0
- cumulusci/core/__init__.py +0 -0
- cumulusci/core/config/BaseConfig.py +5 -0
- cumulusci/core/config/BaseTaskFlowConfig.py +5 -0
- cumulusci/core/config/OrgConfig.py +5 -0
- cumulusci/core/config/ScratchOrgConfig.py +5 -0
- cumulusci/core/config/__init__.py +125 -0
- cumulusci/core/config/base_config.py +111 -0
- cumulusci/core/config/base_task_flow_config.py +82 -0
- cumulusci/core/config/marketing_cloud_service_config.py +83 -0
- cumulusci/core/config/oauth2_service_config.py +17 -0
- cumulusci/core/config/org_config.py +604 -0
- cumulusci/core/config/project_config.py +782 -0
- cumulusci/core/config/scratch_org_config.py +251 -0
- cumulusci/core/config/sfdx_org_config.py +220 -0
- cumulusci/core/config/tests/_test_config_backwards_compatibility.py +33 -0
- cumulusci/core/config/tests/test_config.py +1895 -0
- cumulusci/core/config/tests/test_config_expensive.py +839 -0
- cumulusci/core/config/tests/test_config_util.py +91 -0
- cumulusci/core/config/universal_config.py +88 -0
- cumulusci/core/config/util.py +18 -0
- cumulusci/core/datasets.py +303 -0
- cumulusci/core/debug.py +33 -0
- cumulusci/core/dependencies/__init__.py +55 -0
- cumulusci/core/dependencies/base.py +561 -0
- cumulusci/core/dependencies/dependencies.py +273 -0
- cumulusci/core/dependencies/github.py +177 -0
- cumulusci/core/dependencies/github_resolvers.py +244 -0
- cumulusci/core/dependencies/resolvers.py +580 -0
- cumulusci/core/dependencies/tests/__init__.py +0 -0
- cumulusci/core/dependencies/tests/conftest.py +385 -0
- cumulusci/core/dependencies/tests/test_dependencies.py +950 -0
- cumulusci/core/dependencies/tests/test_github.py +83 -0
- cumulusci/core/dependencies/tests/test_resolvers.py +1027 -0
- cumulusci/core/dependencies/utils.py +13 -0
- cumulusci/core/enums.py +11 -0
- cumulusci/core/exceptions.py +311 -0
- cumulusci/core/flowrunner.py +888 -0
- cumulusci/core/github.py +665 -0
- cumulusci/core/keychain/__init__.py +24 -0
- cumulusci/core/keychain/base_project_keychain.py +441 -0
- cumulusci/core/keychain/encrypted_file_project_keychain.py +945 -0
- cumulusci/core/keychain/environment_project_keychain.py +7 -0
- cumulusci/core/keychain/serialization.py +152 -0
- cumulusci/core/keychain/subprocess_keychain.py +24 -0
- cumulusci/core/keychain/tests/conftest.py +50 -0
- cumulusci/core/keychain/tests/test_base_project_keychain.py +299 -0
- cumulusci/core/keychain/tests/test_encrypted_file_project_keychain.py +1228 -0
- cumulusci/core/metadeploy/__init__.py +0 -0
- cumulusci/core/metadeploy/api.py +88 -0
- cumulusci/core/metadeploy/plans.py +25 -0
- cumulusci/core/metadeploy/tests/test_api.py +276 -0
- cumulusci/core/runtime.py +115 -0
- cumulusci/core/sfdx.py +162 -0
- cumulusci/core/source/__init__.py +16 -0
- cumulusci/core/source/github.py +50 -0
- cumulusci/core/source/local_folder.py +35 -0
- cumulusci/core/source_transforms/__init__.py +0 -0
- cumulusci/core/source_transforms/tests/test_transforms.py +1091 -0
- cumulusci/core/source_transforms/transforms.py +532 -0
- cumulusci/core/tasks.py +404 -0
- cumulusci/core/template_utils.py +59 -0
- cumulusci/core/tests/__init__.py +0 -0
- cumulusci/core/tests/cassettes/TestDatasetsE2E.test_datasets_e2e.yaml +215 -0
- cumulusci/core/tests/cassettes/TestDatasetsE2E.test_datasets_extract_standard_objects.yaml +199 -0
- cumulusci/core/tests/cassettes/TestDatasetsE2E.test_datasets_read_explicit_extract_declaration.yaml +3 -0
- cumulusci/core/tests/fake_remote_repo/cumulusci.yml +32 -0
- cumulusci/core/tests/fake_remote_repo/tasks/directory/example_2.py +6 -0
- cumulusci/core/tests/fake_remote_repo/tasks/example.py +43 -0
- cumulusci/core/tests/fake_remote_repo_2/cumulusci.yml +11 -0
- cumulusci/core/tests/fake_remote_repo_2/tasks/example_3.py +6 -0
- cumulusci/core/tests/test_datasets_e2e.py +386 -0
- cumulusci/core/tests/test_exceptions.py +11 -0
- cumulusci/core/tests/test_flowrunner.py +836 -0
- cumulusci/core/tests/test_github.py +942 -0
- cumulusci/core/tests/test_sfdx.py +138 -0
- cumulusci/core/tests/test_source.py +678 -0
- cumulusci/core/tests/test_tasks.py +262 -0
- cumulusci/core/tests/test_utils.py +141 -0
- cumulusci/core/tests/test_utils_merge_config.py +276 -0
- cumulusci/core/tests/test_versions.py +76 -0
- cumulusci/core/tests/untrusted_repo_child/cumulusci.yml +7 -0
- cumulusci/core/tests/untrusted_repo_child/tasks/untrusted_child.py +6 -0
- cumulusci/core/tests/untrusted_repo_parent/cumulusci.yml +26 -0
- cumulusci/core/tests/untrusted_repo_parent/tasks/untrusted_parent.py +6 -0
- cumulusci/core/tests/utils.py +116 -0
- cumulusci/core/tests/yaml/global.yaml +0 -0
- cumulusci/core/utils.py +402 -0
- cumulusci/core/versions.py +149 -0
- cumulusci/cumulusci.yml +1621 -0
- cumulusci/files/admin_profile.xml +20 -0
- cumulusci/files/delete_excludes.txt +424 -0
- cumulusci/files/templates/project/README.md +12 -0
- cumulusci/files/templates/project/cumulusci.yml +63 -0
- cumulusci/files/templates/project/dot-gitignore +60 -0
- cumulusci/files/templates/project/mapping.yml +45 -0
- cumulusci/files/templates/project/scratch_def.json +25 -0
- cumulusci/oauth/__init__.py +0 -0
- cumulusci/oauth/client.py +400 -0
- cumulusci/oauth/exceptions.py +9 -0
- cumulusci/oauth/salesforce.py +95 -0
- cumulusci/oauth/tests/__init__.py +0 -0
- cumulusci/oauth/tests/cassettes/test_get_device_code.yaml +22 -0
- cumulusci/oauth/tests/cassettes/test_get_device_oauth_token.yaml +74 -0
- cumulusci/oauth/tests/test_client.py +308 -0
- cumulusci/oauth/tests/test_salesforce.py +46 -0
- cumulusci/plugins/__init__.py +3 -0
- cumulusci/plugins/plugin_base.py +93 -0
- cumulusci/plugins/plugin_loader.py +59 -0
- cumulusci/robotframework/CumulusCI.py +340 -0
- cumulusci/robotframework/CumulusCI.robot +7 -0
- cumulusci/robotframework/Performance.py +165 -0
- cumulusci/robotframework/Salesforce.py +936 -0
- cumulusci/robotframework/Salesforce.robot +192 -0
- cumulusci/robotframework/SalesforceAPI.py +416 -0
- cumulusci/robotframework/SalesforcePlaywright.py +220 -0
- cumulusci/robotframework/SalesforcePlaywright.robot +40 -0
- cumulusci/robotframework/__init__.py +2 -0
- cumulusci/robotframework/base_library.py +39 -0
- cumulusci/robotframework/faker_mixin.py +89 -0
- cumulusci/robotframework/form_handlers.py +222 -0
- cumulusci/robotframework/javascript/cci_init.js +34 -0
- cumulusci/robotframework/javascript/cumulusci.js +4 -0
- cumulusci/robotframework/locator_manager.py +197 -0
- cumulusci/robotframework/locators_56.py +88 -0
- cumulusci/robotframework/locators_57.py +5 -0
- cumulusci/robotframework/pageobjects/BasePageObjects.py +433 -0
- cumulusci/robotframework/pageobjects/ObjectManagerPageObject.py +246 -0
- cumulusci/robotframework/pageobjects/PageObjectLibrary.py +45 -0
- cumulusci/robotframework/pageobjects/PageObjects.py +351 -0
- cumulusci/robotframework/pageobjects/__init__.py +12 -0
- cumulusci/robotframework/pageobjects/baseobjects.py +120 -0
- cumulusci/robotframework/perftests/short/collection_perf.robot +105 -0
- cumulusci/robotframework/tests/CustomObjectTestPage.py +10 -0
- cumulusci/robotframework/tests/FooTestPage.py +8 -0
- cumulusci/robotframework/tests/cumulusci/base.robot +40 -0
- cumulusci/robotframework/tests/cumulusci/bulkdata.robot +38 -0
- cumulusci/robotframework/tests/cumulusci/communities.robot +57 -0
- cumulusci/robotframework/tests/cumulusci/datagen.robot +84 -0
- cumulusci/robotframework/tests/salesforce/TestLibraryA.py +24 -0
- cumulusci/robotframework/tests/salesforce/TestLibraryB.py +20 -0
- cumulusci/robotframework/tests/salesforce/TestListener.py +93 -0
- cumulusci/robotframework/tests/salesforce/api.robot +178 -0
- cumulusci/robotframework/tests/salesforce/browsers.robot +143 -0
- cumulusci/robotframework/tests/salesforce/classic.robot +51 -0
- cumulusci/robotframework/tests/salesforce/create_contact.robot +59 -0
- cumulusci/robotframework/tests/salesforce/faker.robot +68 -0
- cumulusci/robotframework/tests/salesforce/forms.robot +172 -0
- cumulusci/robotframework/tests/salesforce/label_locator.robot +244 -0
- cumulusci/robotframework/tests/salesforce/labels.html +33 -0
- cumulusci/robotframework/tests/salesforce/locators.robot +149 -0
- cumulusci/robotframework/tests/salesforce/pageobjects/base_pageobjects.robot +100 -0
- cumulusci/robotframework/tests/salesforce/pageobjects/example_page_object.py +25 -0
- cumulusci/robotframework/tests/salesforce/pageobjects/listing_page.robot +115 -0
- cumulusci/robotframework/tests/salesforce/pageobjects/objectmanager.robot +74 -0
- cumulusci/robotframework/tests/salesforce/pageobjects/pageobjects.robot +171 -0
- cumulusci/robotframework/tests/salesforce/performance.robot +109 -0
- cumulusci/robotframework/tests/salesforce/playwright/javascript_keywords.robot +33 -0
- cumulusci/robotframework/tests/salesforce/playwright/open_test_browser.robot +48 -0
- cumulusci/robotframework/tests/salesforce/playwright/playwright.robot +24 -0
- cumulusci/robotframework/tests/salesforce/playwright/ui.robot +32 -0
- cumulusci/robotframework/tests/salesforce/populate.robot +89 -0
- cumulusci/robotframework/tests/salesforce/test_testlistener.py +37 -0
- cumulusci/robotframework/tests/salesforce/ui.robot +361 -0
- cumulusci/robotframework/tests/test_cumulusci_library.py +304 -0
- cumulusci/robotframework/tests/test_locator_manager.py +158 -0
- cumulusci/robotframework/tests/test_pageobjects.py +291 -0
- cumulusci/robotframework/tests/test_performance.py +38 -0
- cumulusci/robotframework/tests/test_salesforce.py +79 -0
- cumulusci/robotframework/tests/test_salesforce_locators.py +73 -0
- cumulusci/robotframework/tests/test_template_util.py +53 -0
- cumulusci/robotframework/tests/test_utils.py +106 -0
- cumulusci/robotframework/utils.py +283 -0
- cumulusci/salesforce_api/__init__.py +0 -0
- cumulusci/salesforce_api/exceptions.py +23 -0
- cumulusci/salesforce_api/filterable_objects.py +96 -0
- cumulusci/salesforce_api/mc_soap_envelopes.py +89 -0
- cumulusci/salesforce_api/metadata.py +721 -0
- cumulusci/salesforce_api/org_schema.py +571 -0
- cumulusci/salesforce_api/org_schema_models.py +226 -0
- cumulusci/salesforce_api/package_install.py +265 -0
- cumulusci/salesforce_api/package_zip.py +301 -0
- cumulusci/salesforce_api/rest_deploy.py +148 -0
- cumulusci/salesforce_api/retrieve_profile_api.py +301 -0
- cumulusci/salesforce_api/soap_envelopes.py +177 -0
- cumulusci/salesforce_api/tests/__init__.py +0 -0
- cumulusci/salesforce_api/tests/metadata_test_strings.py +24 -0
- cumulusci/salesforce_api/tests/test_metadata.py +1015 -0
- cumulusci/salesforce_api/tests/test_package_install.py +219 -0
- cumulusci/salesforce_api/tests/test_package_zip.py +380 -0
- cumulusci/salesforce_api/tests/test_rest_deploy.py +264 -0
- cumulusci/salesforce_api/tests/test_retrieve_profile_api.py +337 -0
- cumulusci/salesforce_api/tests/test_utils.py +124 -0
- cumulusci/salesforce_api/utils.py +51 -0
- cumulusci/schema/cumulusci.jsonschema.json +782 -0
- cumulusci/tasks/__init__.py +0 -0
- cumulusci/tasks/apex/__init__.py +0 -0
- cumulusci/tasks/apex/anon.py +157 -0
- cumulusci/tasks/apex/batch.py +180 -0
- cumulusci/tasks/apex/testrunner.py +835 -0
- cumulusci/tasks/apex/tests/cassettes/ManualEditTestApexIntegrationTests.test_run_tests__integration_test.yaml +703 -0
- cumulusci/tasks/apex/tests/test_apex_tasks.py +1558 -0
- cumulusci/tasks/base_source_control_task.py +17 -0
- cumulusci/tasks/bulkdata/__init__.py +15 -0
- cumulusci/tasks/bulkdata/base_generate_data_task.py +96 -0
- cumulusci/tasks/bulkdata/dates.py +97 -0
- cumulusci/tasks/bulkdata/delete.py +156 -0
- cumulusci/tasks/bulkdata/extract.py +441 -0
- cumulusci/tasks/bulkdata/extract_dataset_utils/calculate_dependencies.py +117 -0
- cumulusci/tasks/bulkdata/extract_dataset_utils/extract_yml.py +123 -0
- cumulusci/tasks/bulkdata/extract_dataset_utils/hardcoded_default_declarations.py +49 -0
- cumulusci/tasks/bulkdata/extract_dataset_utils/synthesize_extract_declarations.py +283 -0
- cumulusci/tasks/bulkdata/extract_dataset_utils/tests/test_extract_yml.py +142 -0
- cumulusci/tasks/bulkdata/extract_dataset_utils/tests/test_synthesize_extract_declarations.py +575 -0
- cumulusci/tasks/bulkdata/factory_utils.py +134 -0
- cumulusci/tasks/bulkdata/generate.py +4 -0
- cumulusci/tasks/bulkdata/generate_and_load_data.py +232 -0
- cumulusci/tasks/bulkdata/generate_and_load_data_from_yaml.py +19 -0
- cumulusci/tasks/bulkdata/generate_from_yaml.py +183 -0
- cumulusci/tasks/bulkdata/generate_mapping.py +434 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/dependency_map.py +169 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/extract_mapping_file_generator.py +45 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/generate_mapping_from_declarations.py +121 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/load_mapping_file_generator.py +127 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/mapping_generator_post_processes.py +53 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/mapping_transforms.py +139 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/tests/test_generate_extract_mapping_from_declarations.py +135 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/tests/test_generate_load_mapping_from_declarations.py +330 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/tests/test_mapping_generator_post_processes.py +60 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/tests/test_mapping_transforms.py +188 -0
- cumulusci/tasks/bulkdata/load.py +1196 -0
- cumulusci/tasks/bulkdata/mapping_parser.py +811 -0
- cumulusci/tasks/bulkdata/query_transformers.py +264 -0
- cumulusci/tasks/bulkdata/select_utils.py +792 -0
- cumulusci/tasks/bulkdata/snowfakery.py +753 -0
- cumulusci/tasks/bulkdata/snowfakery_utils/queue_manager.py +478 -0
- cumulusci/tasks/bulkdata/snowfakery_utils/snowfakery_run_until.py +141 -0
- cumulusci/tasks/bulkdata/snowfakery_utils/snowfakery_working_directory.py +53 -0
- cumulusci/tasks/bulkdata/snowfakery_utils/subtask_configurator.py +64 -0
- cumulusci/tasks/bulkdata/step.py +1242 -0
- cumulusci/tasks/bulkdata/tests/__init__.py +0 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_random_strategy.yaml +147 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_similarity_annoy_strategy.yaml +123 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_similarity_select_and_insert_strategy.yaml +313 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_similarity_select_and_insert_strategy_bulk.yaml +550 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_similarity_strategy.yaml +175 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_standard_strategy.yaml +147 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSnowfakery.test_run_until_records_in_org__multiple_needed.yaml +69 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSnowfakery.test_run_until_records_in_org__none_needed.yaml +22 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSnowfakery.test_run_until_records_in_org__one_needed.yaml +24 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSnowfakery.test_snowfakery_query_salesforce.yaml +25 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestUpdatesIntegrationTests.test_updates_task.yaml +80 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestUpsert.test_simple_upsert__rest.yaml +270 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestUpsert.test_upsert__rest.yaml +267 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestUpsert.test_upsert_complex_external_id_field__rest.yaml +369 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestUpsert.test_upsert_complex_external_id_field_rest__duplicate_error.yaml +204 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestUpsert.test_upsert_complex_fields__bulk.yaml +675 -0
- cumulusci/tasks/bulkdata/tests/dummy_data_factory.py +36 -0
- cumulusci/tasks/bulkdata/tests/integration_test_utils.py +49 -0
- cumulusci/tasks/bulkdata/tests/mapping-oid.yml +87 -0
- cumulusci/tasks/bulkdata/tests/mapping_after.yml +38 -0
- cumulusci/tasks/bulkdata/tests/mapping_poly.yml +34 -0
- cumulusci/tasks/bulkdata/tests/mapping_poly_incomplete.yml +20 -0
- cumulusci/tasks/bulkdata/tests/mapping_poly_wrong.yml +21 -0
- cumulusci/tasks/bulkdata/tests/mapping_select.yml +20 -0
- cumulusci/tasks/bulkdata/tests/mapping_select_invalid_strategy.yml +20 -0
- cumulusci/tasks/bulkdata/tests/mapping_select_invalid_threshold__invalid_number.yml +21 -0
- cumulusci/tasks/bulkdata/tests/mapping_select_invalid_threshold__invalid_strategy.yml +21 -0
- cumulusci/tasks/bulkdata/tests/mapping_select_invalid_threshold__non_float.yml +21 -0
- cumulusci/tasks/bulkdata/tests/mapping_select_missing_priority_fields.yml +22 -0
- cumulusci/tasks/bulkdata/tests/mapping_select_no_priority_fields.yml +18 -0
- cumulusci/tasks/bulkdata/tests/mapping_simple.yml +27 -0
- cumulusci/tasks/bulkdata/tests/mapping_v1.yml +28 -0
- cumulusci/tasks/bulkdata/tests/mapping_v2.yml +21 -0
- cumulusci/tasks/bulkdata/tests/mapping_v3.yml +32 -0
- cumulusci/tasks/bulkdata/tests/mapping_vanilla_sf.yml +69 -0
- cumulusci/tasks/bulkdata/tests/mock_data_factory_without_mapping.py +12 -0
- cumulusci/tasks/bulkdata/tests/person_accounts.yml +23 -0
- cumulusci/tasks/bulkdata/tests/person_accounts_minimal.yml +15 -0
- cumulusci/tasks/bulkdata/tests/recordtypes.yml +8 -0
- cumulusci/tasks/bulkdata/tests/recordtypes_2.yml +6 -0
- cumulusci/tasks/bulkdata/tests/recordtypes_with_ispersontype.yml +8 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/child/child2.yml +3 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/child.yml +4 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/gen_npsp_standard_objects.recipe.yml +89 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/include_parent.yml +3 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/npsp_standard_objects_macros.yml +34 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/options.recipe.yml +6 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/query_snowfakery.recipe.yml +16 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/sf_standard_object_macros.yml +83 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery.load.yml +2 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery.recipe.yml +13 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery_2.load.yml +5 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery_channels.load.yml +13 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery_channels.recipe.yml +12 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery_channels_2.load.yml +13 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/unique_values.recipe.yml +4 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/upsert.recipe.yml +23 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/upsert_2.recipe.yml +29 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/upsert_before.yml +10 -0
- cumulusci/tasks/bulkdata/tests/test_base_generate_data_tasks.py +61 -0
- cumulusci/tasks/bulkdata/tests/test_dates.py +99 -0
- cumulusci/tasks/bulkdata/tests/test_delete.py +404 -0
- cumulusci/tasks/bulkdata/tests/test_extract.py +1311 -0
- cumulusci/tasks/bulkdata/tests/test_factory_utils.py +55 -0
- cumulusci/tasks/bulkdata/tests/test_generate_and_load.py +252 -0
- cumulusci/tasks/bulkdata/tests/test_generate_from_snowfakery_task.py +343 -0
- cumulusci/tasks/bulkdata/tests/test_generatemapping.py +1039 -0
- cumulusci/tasks/bulkdata/tests/test_load.py +3175 -0
- cumulusci/tasks/bulkdata/tests/test_mapping_parser.py +1658 -0
- cumulusci/tasks/bulkdata/tests/test_query_db__joins_self_lookups.yml +12 -0
- cumulusci/tasks/bulkdata/tests/test_query_db_joins_lookups.yml +26 -0
- cumulusci/tasks/bulkdata/tests/test_query_db_joins_lookups_select.yml +48 -0
- cumulusci/tasks/bulkdata/tests/test_select.py +171 -0
- cumulusci/tasks/bulkdata/tests/test_select_utils.py +1057 -0
- cumulusci/tasks/bulkdata/tests/test_snowfakery.py +1153 -0
- cumulusci/tasks/bulkdata/tests/test_step.py +3957 -0
- cumulusci/tasks/bulkdata/tests/test_updates.py +513 -0
- cumulusci/tasks/bulkdata/tests/test_upsert.py +1015 -0
- cumulusci/tasks/bulkdata/tests/test_utils.py +158 -0
- cumulusci/tasks/bulkdata/tests/testdata.db +0 -0
- cumulusci/tasks/bulkdata/tests/update_describe.py +50 -0
- cumulusci/tasks/bulkdata/tests/update_person_accounts.yml +23 -0
- cumulusci/tasks/bulkdata/tests/utils.py +114 -0
- cumulusci/tasks/bulkdata/update_data.py +260 -0
- cumulusci/tasks/bulkdata/upsert_utils.py +130 -0
- cumulusci/tasks/bulkdata/utils.py +249 -0
- cumulusci/tasks/command.py +178 -0
- cumulusci/tasks/connectedapp.py +186 -0
- cumulusci/tasks/create_package_version.py +778 -0
- cumulusci/tasks/datadictionary.py +745 -0
- cumulusci/tasks/dx_convert_from.py +26 -0
- cumulusci/tasks/github/__init__.py +17 -0
- cumulusci/tasks/github/base.py +16 -0
- cumulusci/tasks/github/commit_status.py +13 -0
- cumulusci/tasks/github/merge.py +11 -0
- cumulusci/tasks/github/publish.py +11 -0
- cumulusci/tasks/github/pull_request.py +11 -0
- cumulusci/tasks/github/release.py +11 -0
- cumulusci/tasks/github/release_report.py +11 -0
- cumulusci/tasks/github/tag.py +11 -0
- cumulusci/tasks/github/tests/__init__.py +0 -0
- cumulusci/tasks/github/tests/test_util.py +202 -0
- cumulusci/tasks/github/tests/test_vcs_migration.py +44 -0
- cumulusci/tasks/github/tests/util_github_api.py +666 -0
- cumulusci/tasks/github/util.py +252 -0
- cumulusci/tasks/marketing_cloud/__init__.py +0 -0
- cumulusci/tasks/marketing_cloud/api.py +188 -0
- cumulusci/tasks/marketing_cloud/base.py +38 -0
- cumulusci/tasks/marketing_cloud/deploy.py +345 -0
- cumulusci/tasks/marketing_cloud/get_user_info.py +40 -0
- cumulusci/tasks/marketing_cloud/mc_constants.py +1 -0
- cumulusci/tasks/marketing_cloud/tests/__init__.py +0 -0
- cumulusci/tasks/marketing_cloud/tests/conftest.py +46 -0
- cumulusci/tasks/marketing_cloud/tests/expected-payload.json +110 -0
- cumulusci/tasks/marketing_cloud/tests/test_api.py +97 -0
- cumulusci/tasks/marketing_cloud/tests/test_api_soap_envelopes.py +145 -0
- cumulusci/tasks/marketing_cloud/tests/test_base.py +14 -0
- cumulusci/tasks/marketing_cloud/tests/test_deploy.py +400 -0
- cumulusci/tasks/marketing_cloud/tests/test_get_user_info.py +141 -0
- cumulusci/tasks/marketing_cloud/tests/validation-response.json +39 -0
- cumulusci/tasks/metadata/__init__.py +0 -0
- cumulusci/tasks/metadata/ee_src.py +94 -0
- cumulusci/tasks/metadata/managed_src.py +100 -0
- cumulusci/tasks/metadata/metadata_map.yml +868 -0
- cumulusci/tasks/metadata/modify.py +99 -0
- cumulusci/tasks/metadata/package.py +684 -0
- cumulusci/tasks/metadata/tests/__init__.py +0 -0
- cumulusci/tasks/metadata/tests/package_metadata/namespaced_report_folder/.hidden/.keep +0 -0
- cumulusci/tasks/metadata/tests/package_metadata/namespaced_report_folder/destructiveChanges.xml +9 -0
- cumulusci/tasks/metadata/tests/package_metadata/namespaced_report_folder/package.xml +9 -0
- cumulusci/tasks/metadata/tests/package_metadata/namespaced_report_folder/package_install_uninstall.xml +11 -0
- cumulusci/tasks/metadata/tests/package_metadata/namespaced_report_folder/reports/namespace__TestFolder/TestReport.report +3 -0
- cumulusci/tasks/metadata/tests/sample_package.xml +9 -0
- cumulusci/tasks/metadata/tests/test_ee_src.py +112 -0
- cumulusci/tasks/metadata/tests/test_managed_src.py +111 -0
- cumulusci/tasks/metadata/tests/test_modify.py +123 -0
- cumulusci/tasks/metadata/tests/test_package.py +476 -0
- cumulusci/tasks/metadata_etl/__init__.py +29 -0
- cumulusci/tasks/metadata_etl/base.py +436 -0
- cumulusci/tasks/metadata_etl/duplicate_rules.py +24 -0
- cumulusci/tasks/metadata_etl/field_sets.py +70 -0
- cumulusci/tasks/metadata_etl/help_text.py +92 -0
- cumulusci/tasks/metadata_etl/layouts.py +550 -0
- cumulusci/tasks/metadata_etl/objects.py +68 -0
- cumulusci/tasks/metadata_etl/permissions.py +167 -0
- cumulusci/tasks/metadata_etl/picklists.py +221 -0
- cumulusci/tasks/metadata_etl/remote_site_settings.py +99 -0
- cumulusci/tasks/metadata_etl/sharing.py +138 -0
- cumulusci/tasks/metadata_etl/tests/test_base.py +512 -0
- cumulusci/tasks/metadata_etl/tests/test_duplicate_rules.py +22 -0
- cumulusci/tasks/metadata_etl/tests/test_field_sets.py +156 -0
- cumulusci/tasks/metadata_etl/tests/test_help_text.py +387 -0
- cumulusci/tasks/metadata_etl/tests/test_ip_ranges.py +85 -0
- cumulusci/tasks/metadata_etl/tests/test_layouts.py +858 -0
- cumulusci/tasks/metadata_etl/tests/test_objects.py +236 -0
- cumulusci/tasks/metadata_etl/tests/test_permissions.py +223 -0
- cumulusci/tasks/metadata_etl/tests/test_picklists.py +547 -0
- cumulusci/tasks/metadata_etl/tests/test_remote_site_settings.py +46 -0
- cumulusci/tasks/metadata_etl/tests/test_sharing.py +333 -0
- cumulusci/tasks/metadata_etl/tests/test_value_sets.py +298 -0
- cumulusci/tasks/metadata_etl/value_sets.py +106 -0
- cumulusci/tasks/metadeploy.py +393 -0
- cumulusci/tasks/metaxml.py +88 -0
- cumulusci/tasks/preflight/__init__.py +0 -0
- cumulusci/tasks/preflight/dataset_load.py +49 -0
- cumulusci/tasks/preflight/licenses.py +86 -0
- cumulusci/tasks/preflight/packages.py +14 -0
- cumulusci/tasks/preflight/permsets.py +23 -0
- cumulusci/tasks/preflight/recordtypes.py +16 -0
- cumulusci/tasks/preflight/retrieve_tasks.py +30 -0
- cumulusci/tasks/preflight/settings.py +77 -0
- cumulusci/tasks/preflight/sobjects.py +202 -0
- cumulusci/tasks/preflight/tests/test_dataset_load.py +85 -0
- cumulusci/tasks/preflight/tests/test_licenses.py +174 -0
- cumulusci/tasks/preflight/tests/test_packages.py +14 -0
- cumulusci/tasks/preflight/tests/test_permset_preflights.py +51 -0
- cumulusci/tasks/preflight/tests/test_recordtypes.py +30 -0
- cumulusci/tasks/preflight/tests/test_retrieve_tasks.py +62 -0
- cumulusci/tasks/preflight/tests/test_settings.py +130 -0
- cumulusci/tasks/preflight/tests/test_sobjects.py +231 -0
- cumulusci/tasks/push/README.md +59 -0
- cumulusci/tasks/push/__init__.py +0 -0
- cumulusci/tasks/push/push_api.py +659 -0
- cumulusci/tasks/push/pushfails.py +136 -0
- cumulusci/tasks/push/tasks.py +476 -0
- cumulusci/tasks/push/tests/conftest.py +263 -0
- cumulusci/tasks/push/tests/test_push_api.py +951 -0
- cumulusci/tasks/push/tests/test_push_tasks.py +659 -0
- cumulusci/tasks/release_notes/README.md +63 -0
- cumulusci/tasks/release_notes/__init__.py +0 -0
- cumulusci/tasks/release_notes/exceptions.py +5 -0
- cumulusci/tasks/release_notes/generator.py +137 -0
- cumulusci/tasks/release_notes/parser.py +232 -0
- cumulusci/tasks/release_notes/provider.py +44 -0
- cumulusci/tasks/release_notes/task.py +300 -0
- cumulusci/tasks/release_notes/tests/__init__.py +0 -0
- cumulusci/tasks/release_notes/tests/change_notes/full/example1.md +17 -0
- cumulusci/tasks/release_notes/tests/change_notes/multi/1.txt +1 -0
- cumulusci/tasks/release_notes/tests/change_notes/multi/2.txt +1 -0
- cumulusci/tasks/release_notes/tests/change_notes/multi/3.txt +1 -0
- cumulusci/tasks/release_notes/tests/change_notes/single/1.txt +1 -0
- cumulusci/tasks/release_notes/tests/test_generator.py +582 -0
- cumulusci/tasks/release_notes/tests/test_parser.py +867 -0
- cumulusci/tasks/release_notes/tests/test_provider.py +512 -0
- cumulusci/tasks/release_notes/tests/test_task.py +461 -0
- cumulusci/tasks/release_notes/tests/utils.py +153 -0
- cumulusci/tasks/robotframework/__init__.py +3 -0
- cumulusci/tasks/robotframework/debugger/DebugListener.py +100 -0
- cumulusci/tasks/robotframework/debugger/__init__.py +10 -0
- cumulusci/tasks/robotframework/debugger/model.py +87 -0
- cumulusci/tasks/robotframework/debugger/ui.py +259 -0
- cumulusci/tasks/robotframework/libdoc.py +269 -0
- cumulusci/tasks/robotframework/robotframework.py +392 -0
- cumulusci/tasks/robotframework/stylesheet.css +130 -0
- cumulusci/tasks/robotframework/template.html +109 -0
- cumulusci/tasks/robotframework/tests/TestLibrary.py +18 -0
- cumulusci/tasks/robotframework/tests/TestPageObjects.py +31 -0
- cumulusci/tasks/robotframework/tests/TestResource.robot +8 -0
- cumulusci/tasks/robotframework/tests/failing_tests.robot +16 -0
- cumulusci/tasks/robotframework/tests/performance.robot +23 -0
- cumulusci/tasks/robotframework/tests/test_browser_proxies.py +137 -0
- cumulusci/tasks/robotframework/tests/test_debugger.py +360 -0
- cumulusci/tasks/robotframework/tests/test_robot_parallel.py +141 -0
- cumulusci/tasks/robotframework/tests/test_robotframework.py +860 -0
- cumulusci/tasks/salesforce/BaseRetrieveMetadata.py +58 -0
- cumulusci/tasks/salesforce/BaseSalesforceApiTask.py +45 -0
- cumulusci/tasks/salesforce/BaseSalesforceMetadataApiTask.py +18 -0
- cumulusci/tasks/salesforce/BaseSalesforceTask.py +4 -0
- cumulusci/tasks/salesforce/BaseUninstallMetadata.py +41 -0
- cumulusci/tasks/salesforce/CreateCommunity.py +124 -0
- cumulusci/tasks/salesforce/CreatePackage.py +29 -0
- cumulusci/tasks/salesforce/Deploy.py +240 -0
- cumulusci/tasks/salesforce/DeployBundles.py +88 -0
- cumulusci/tasks/salesforce/DescribeMetadataTypes.py +26 -0
- cumulusci/tasks/salesforce/EnsureRecordTypes.py +202 -0
- cumulusci/tasks/salesforce/GetInstalledPackages.py +8 -0
- cumulusci/tasks/salesforce/ListCommunities.py +40 -0
- cumulusci/tasks/salesforce/ListCommunityTemplates.py +19 -0
- cumulusci/tasks/salesforce/PublishCommunity.py +62 -0
- cumulusci/tasks/salesforce/RetrievePackaged.py +41 -0
- cumulusci/tasks/salesforce/RetrieveReportsAndDashboards.py +82 -0
- cumulusci/tasks/salesforce/RetrieveUnpackaged.py +36 -0
- cumulusci/tasks/salesforce/SOQLQuery.py +39 -0
- cumulusci/tasks/salesforce/UninstallLocal.py +15 -0
- cumulusci/tasks/salesforce/UninstallLocalBundles.py +28 -0
- cumulusci/tasks/salesforce/UninstallLocalNamespacedBundles.py +58 -0
- cumulusci/tasks/salesforce/UninstallPackage.py +32 -0
- cumulusci/tasks/salesforce/UninstallPackaged.py +56 -0
- cumulusci/tasks/salesforce/UpdateAdminProfile.py +8 -0
- cumulusci/tasks/salesforce/__init__.py +79 -0
- cumulusci/tasks/salesforce/activate_flow.py +74 -0
- cumulusci/tasks/salesforce/check_components.py +324 -0
- cumulusci/tasks/salesforce/composite.py +142 -0
- cumulusci/tasks/salesforce/create_permission_sets.py +35 -0
- cumulusci/tasks/salesforce/custom_settings.py +134 -0
- cumulusci/tasks/salesforce/custom_settings_wait.py +132 -0
- cumulusci/tasks/salesforce/enable_prediction.py +107 -0
- cumulusci/tasks/salesforce/insert_record.py +40 -0
- cumulusci/tasks/salesforce/install_package_version.py +242 -0
- cumulusci/tasks/salesforce/license_preflights.py +8 -0
- cumulusci/tasks/salesforce/network_member_group.py +178 -0
- cumulusci/tasks/salesforce/nonsourcetracking.py +228 -0
- cumulusci/tasks/salesforce/org_settings.py +193 -0
- cumulusci/tasks/salesforce/package_upload.py +328 -0
- cumulusci/tasks/salesforce/profiles.py +74 -0
- cumulusci/tasks/salesforce/promote_package_version.py +376 -0
- cumulusci/tasks/salesforce/retrieve_profile.py +195 -0
- cumulusci/tasks/salesforce/salesforce_files.py +244 -0
- cumulusci/tasks/salesforce/sourcetracking.py +507 -0
- cumulusci/tasks/salesforce/tests/__init__.py +3 -0
- cumulusci/tasks/salesforce/tests/test_CreateCommunity.py +278 -0
- cumulusci/tasks/salesforce/tests/test_CreatePackage.py +22 -0
- cumulusci/tasks/salesforce/tests/test_Deploy.py +470 -0
- cumulusci/tasks/salesforce/tests/test_DeployBundles.py +76 -0
- cumulusci/tasks/salesforce/tests/test_EnsureRecordTypes.py +345 -0
- cumulusci/tasks/salesforce/tests/test_ListCommunities.py +84 -0
- cumulusci/tasks/salesforce/tests/test_ListCommunityTemplates.py +49 -0
- cumulusci/tasks/salesforce/tests/test_PackageUpload.py +547 -0
- cumulusci/tasks/salesforce/tests/test_ProfileGrantAllAccess.py +699 -0
- cumulusci/tasks/salesforce/tests/test_PublishCommunity.py +181 -0
- cumulusci/tasks/salesforce/tests/test_RetrievePackaged.py +24 -0
- cumulusci/tasks/salesforce/tests/test_RetrieveReportsAndDashboards.py +56 -0
- cumulusci/tasks/salesforce/tests/test_RetrieveUnpackaged.py +21 -0
- cumulusci/tasks/salesforce/tests/test_SOQLQuery.py +30 -0
- cumulusci/tasks/salesforce/tests/test_UninstallLocal.py +15 -0
- cumulusci/tasks/salesforce/tests/test_UninstallLocalBundles.py +19 -0
- cumulusci/tasks/salesforce/tests/test_UninstallLocalNamespacedBundles.py +22 -0
- cumulusci/tasks/salesforce/tests/test_UninstallPackage.py +19 -0
- cumulusci/tasks/salesforce/tests/test_UninstallPackaged.py +66 -0
- cumulusci/tasks/salesforce/tests/test_UninstallPackagedIncremental.py +127 -0
- cumulusci/tasks/salesforce/tests/test_activate_flow.py +132 -0
- cumulusci/tasks/salesforce/tests/test_base_tasks.py +110 -0
- cumulusci/tasks/salesforce/tests/test_check_components.py +445 -0
- cumulusci/tasks/salesforce/tests/test_composite.py +250 -0
- cumulusci/tasks/salesforce/tests/test_create_permission_sets.py +41 -0
- cumulusci/tasks/salesforce/tests/test_custom_settings.py +227 -0
- cumulusci/tasks/salesforce/tests/test_custom_settings_wait.py +174 -0
- cumulusci/tasks/salesforce/tests/test_describemetadatatypes.py +18 -0
- cumulusci/tasks/salesforce/tests/test_enable_prediction.py +240 -0
- cumulusci/tasks/salesforce/tests/test_insert_record.py +110 -0
- cumulusci/tasks/salesforce/tests/test_install_package_version.py +464 -0
- cumulusci/tasks/salesforce/tests/test_network_member_group.py +444 -0
- cumulusci/tasks/salesforce/tests/test_nonsourcetracking.py +235 -0
- cumulusci/tasks/salesforce/tests/test_org_settings.py +407 -0
- cumulusci/tasks/salesforce/tests/test_profiles.py +202 -0
- cumulusci/tasks/salesforce/tests/test_retrieve_profile.py +287 -0
- cumulusci/tasks/salesforce/tests/test_salesforce_files.py +228 -0
- cumulusci/tasks/salesforce/tests/test_sourcetracking.py +350 -0
- cumulusci/tasks/salesforce/tests/test_trigger_handlers.py +300 -0
- cumulusci/tasks/salesforce/tests/test_update_dependencies.py +509 -0
- cumulusci/tasks/salesforce/tests/util.py +79 -0
- cumulusci/tasks/salesforce/trigger_handlers.py +119 -0
- cumulusci/tasks/salesforce/uninstall_packaged_incremental.py +136 -0
- cumulusci/tasks/salesforce/update_dependencies.py +290 -0
- cumulusci/tasks/salesforce/update_profile.py +339 -0
- cumulusci/tasks/salesforce/users/permsets.py +227 -0
- cumulusci/tasks/salesforce/users/photos.py +162 -0
- cumulusci/tasks/salesforce/users/tests/photo.mock.txt +1 -0
- cumulusci/tasks/salesforce/users/tests/test_permsets.py +950 -0
- cumulusci/tasks/salesforce/users/tests/test_photos.py +373 -0
- cumulusci/tasks/sample_data/capture_sample_data.py +77 -0
- cumulusci/tasks/sample_data/load_sample_data.py +85 -0
- cumulusci/tasks/sample_data/test_capture_sample_data.py +117 -0
- cumulusci/tasks/sample_data/test_load_sample_data.py +121 -0
- cumulusci/tasks/sfdx.py +83 -0
- cumulusci/tasks/tests/__init__.py +1 -0
- cumulusci/tasks/tests/conftest.py +30 -0
- cumulusci/tasks/tests/test_command.py +129 -0
- cumulusci/tasks/tests/test_connectedapp.py +236 -0
- cumulusci/tasks/tests/test_create_package_version.py +847 -0
- cumulusci/tasks/tests/test_datadictionary.py +1575 -0
- cumulusci/tasks/tests/test_dx_convert_from.py +60 -0
- cumulusci/tasks/tests/test_metadeploy.py +624 -0
- cumulusci/tasks/tests/test_metaxml.py +99 -0
- cumulusci/tasks/tests/test_promote_package_version.py +488 -0
- cumulusci/tasks/tests/test_pushfails.py +96 -0
- cumulusci/tasks/tests/test_salesforce.py +72 -0
- cumulusci/tasks/tests/test_sfdx.py +105 -0
- cumulusci/tasks/tests/test_util.py +207 -0
- cumulusci/tasks/util.py +261 -0
- cumulusci/tasks/vcs/__init__.py +19 -0
- cumulusci/tasks/vcs/commit_status.py +58 -0
- cumulusci/tasks/vcs/create_commit_status.py +37 -0
- cumulusci/tasks/vcs/download_extract.py +199 -0
- cumulusci/tasks/vcs/merge.py +298 -0
- cumulusci/tasks/vcs/publish.py +207 -0
- cumulusci/tasks/vcs/pull_request.py +9 -0
- cumulusci/tasks/vcs/release.py +134 -0
- cumulusci/tasks/vcs/release_report.py +105 -0
- cumulusci/tasks/vcs/tag.py +31 -0
- cumulusci/tasks/vcs/tests/github/test_commit_status.py +196 -0
- cumulusci/tasks/vcs/tests/github/test_download_extract.py +896 -0
- cumulusci/tasks/vcs/tests/github/test_merge.py +1118 -0
- cumulusci/tasks/vcs/tests/github/test_publish.py +823 -0
- cumulusci/tasks/vcs/tests/github/test_pull_request.py +29 -0
- cumulusci/tasks/vcs/tests/github/test_release.py +390 -0
- cumulusci/tasks/vcs/tests/github/test_release_report.py +109 -0
- cumulusci/tasks/vcs/tests/github/test_tag.py +90 -0
- cumulusci/tasks/vlocity/exceptions.py +2 -0
- cumulusci/tasks/vlocity/tests/test_vlocity.py +283 -0
- cumulusci/tasks/vlocity/vlocity.py +342 -0
- cumulusci/tests/__init__.py +1 -0
- cumulusci/tests/cassettes/GET_sobjects_Account_PersonAccount_describe.yaml +18 -0
- cumulusci/tests/cassettes/TestIntegrationInfrastructure.test_integration_tests.yaml +19 -0
- cumulusci/tests/pytest_plugins/pytest_sf_orgconnect.py +307 -0
- cumulusci/tests/pytest_plugins/pytest_sf_vcr.py +275 -0
- cumulusci/tests/pytest_plugins/pytest_sf_vcr_serializer.py +160 -0
- cumulusci/tests/pytest_plugins/pytest_typeguard.py +5 -0
- cumulusci/tests/pytest_plugins/test_vcr_string_compressor.py +49 -0
- cumulusci/tests/pytest_plugins/vcr_string_compressor.py +97 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Account_describe.yaml +18 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Case_describe.yaml +18 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Contact_describe.yaml +4838 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Custom__c_describe.yaml +242 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Event_describe.yaml +19 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Global_describe.yaml +1338 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Lead_describe.yaml +18 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_OpportunityContactRole_describe.yaml +34 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Opportunity_describe.yaml +1261 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Organization.yaml +49 -0
- cumulusci/tests/shared_cassettes/vcr_string_templates/batchInfoList_xml.tpl +15 -0
- cumulusci/tests/shared_cassettes/vcr_string_templates/batchInfo_xml.tpl +13 -0
- cumulusci/tests/shared_cassettes/vcr_string_templates/jobInfo_insert_xml.tpl +24 -0
- cumulusci/tests/shared_cassettes/vcr_string_templates/jobInfo_upsert_xml.tpl +25 -0
- cumulusci/tests/test_entry_points.py +20 -0
- cumulusci/tests/test_integration_infrastructure.py +131 -0
- cumulusci/tests/test_main.py +9 -0
- cumulusci/tests/test_schema.py +32 -0
- cumulusci/tests/test_utils.py +657 -0
- cumulusci/tests/test_vcr_serializer.py +134 -0
- cumulusci/tests/uncompressed_cassette.yaml +83 -0
- cumulusci/tests/util.py +344 -0
- cumulusci/utils/__init__.py +731 -0
- cumulusci/utils/classutils.py +9 -0
- cumulusci/utils/collections.py +32 -0
- cumulusci/utils/deprecation.py +11 -0
- cumulusci/utils/encryption.py +31 -0
- cumulusci/utils/fileutils.py +295 -0
- cumulusci/utils/git.py +142 -0
- cumulusci/utils/http/multi_request.py +214 -0
- cumulusci/utils/http/requests_utils.py +103 -0
- cumulusci/utils/http/tests/cassettes/ManualEditTestCompositeParallelSalesforce.test_http_headers.yaml +32 -0
- cumulusci/utils/http/tests/cassettes/TestCompositeParallelSalesforce.test_composite_parallel_salesforce.yaml +65 -0
- cumulusci/utils/http/tests/cassettes/TestCompositeParallelSalesforce.test_errors.yaml +24 -0
- cumulusci/utils/http/tests/cassettes/TestCompositeParallelSalesforce.test_reference_ids.yaml +49 -0
- cumulusci/utils/http/tests/test_multi_request.py +255 -0
- cumulusci/utils/iterators.py +21 -0
- cumulusci/utils/logging.py +128 -0
- cumulusci/utils/metaprogramming.py +10 -0
- cumulusci/utils/options.py +138 -0
- cumulusci/utils/parallel/queries_in_parallel/run_queries_in_parallel.py +29 -0
- cumulusci/utils/parallel/queries_in_parallel/tests/test_run_queries_in_parallel.py +50 -0
- cumulusci/utils/parallel/task_worker_queues/parallel_worker.py +238 -0
- cumulusci/utils/parallel/task_worker_queues/parallel_worker_queue.py +243 -0
- cumulusci/utils/parallel/task_worker_queues/tests/test_parallel_worker.py +353 -0
- cumulusci/utils/salesforce/count_sobjects.py +46 -0
- cumulusci/utils/salesforce/soql.py +17 -0
- cumulusci/utils/salesforce/tests/cassettes/ManualEdit_TestCountSObjects.test_count_sobjects__network_errors.yaml +23 -0
- cumulusci/utils/salesforce/tests/cassettes/TestCountSObjects.test_count_sobjects__errors.yaml +33 -0
- cumulusci/utils/salesforce/tests/cassettes/TestCountSObjects.test_count_sobjects_simple.yaml +29 -0
- cumulusci/utils/salesforce/tests/test_count_sobjects.py +29 -0
- cumulusci/utils/salesforce/tests/test_soql.py +30 -0
- cumulusci/utils/tests/cassettes/ManualEditTestDescribeOrg.test_minimal_schema.yaml +36 -0
- cumulusci/utils/tests/cassettes/ManualEdit_test_describe_to_sql.yaml +191 -0
- cumulusci/utils/tests/test_fileutils.py +284 -0
- cumulusci/utils/tests/test_git.py +85 -0
- cumulusci/utils/tests/test_logging.py +70 -0
- cumulusci/utils/tests/test_option_parsing.py +188 -0
- cumulusci/utils/tests/test_org_schema.py +691 -0
- cumulusci/utils/tests/test_org_schema_models.py +79 -0
- cumulusci/utils/tests/test_waiting.py +25 -0
- cumulusci/utils/version_strings.py +391 -0
- cumulusci/utils/waiting.py +42 -0
- cumulusci/utils/xml/__init__.py +91 -0
- cumulusci/utils/xml/metadata_tree.py +299 -0
- cumulusci/utils/xml/robot_xml.py +114 -0
- cumulusci/utils/xml/salesforce_encoding.py +100 -0
- cumulusci/utils/xml/test/test_metadata_tree.py +251 -0
- cumulusci/utils/xml/test/test_salesforce_encoding.py +173 -0
- cumulusci/utils/yaml/cumulusci_yml.py +401 -0
- cumulusci/utils/yaml/model_parser.py +156 -0
- cumulusci/utils/yaml/safer_loader.py +74 -0
- cumulusci/utils/yaml/tests/bad_cci.yml +5 -0
- cumulusci/utils/yaml/tests/cassettes/TestCumulusciYml.test_validate_url__with_errors.yaml +20 -0
- cumulusci/utils/yaml/tests/test_cumulusci_yml.py +286 -0
- cumulusci/utils/yaml/tests/test_model_parser.py +175 -0
- cumulusci/utils/yaml/tests/test_safer_loader.py +88 -0
- cumulusci/utils/ziputils.py +61 -0
- cumulusci/vcs/base.py +143 -0
- cumulusci/vcs/bootstrap.py +272 -0
- cumulusci/vcs/github/__init__.py +24 -0
- cumulusci/vcs/github/adapter.py +689 -0
- cumulusci/vcs/github/release_notes/generator.py +219 -0
- cumulusci/vcs/github/release_notes/parser.py +151 -0
- cumulusci/vcs/github/release_notes/provider.py +143 -0
- cumulusci/vcs/github/service.py +569 -0
- cumulusci/vcs/github/tests/test_adapter.py +138 -0
- cumulusci/vcs/github/tests/test_service.py +408 -0
- cumulusci/vcs/models.py +586 -0
- cumulusci/vcs/tests/conftest.py +41 -0
- cumulusci/vcs/tests/dummy_service.py +241 -0
- cumulusci/vcs/tests/test_vcs_base.py +687 -0
- cumulusci/vcs/tests/test_vcs_bootstrap.py +727 -0
- cumulusci/vcs/utils/__init__.py +31 -0
- cumulusci/vcs/vcs_source.py +287 -0
- cumulusci_plus-5.0.0.dist-info/METADATA +145 -0
- cumulusci_plus-5.0.0.dist-info/RECORD +744 -0
- cumulusci_plus-5.0.0.dist-info/WHEEL +4 -0
- cumulusci_plus-5.0.0.dist-info/entry_points.txt +3 -0
- cumulusci_plus-5.0.0.dist-info/licenses/AUTHORS.rst +41 -0
- cumulusci_plus-5.0.0.dist-info/licenses/LICENSE +30 -0
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
import contextlib
|
|
2
|
+
from abc import ABC, abstractmethod
|
|
3
|
+
from typing import List, Optional, Type
|
|
4
|
+
from zipfile import ZipFile
|
|
5
|
+
|
|
6
|
+
from pydantic import AnyUrl, PrivateAttr, root_validator, validator
|
|
7
|
+
|
|
8
|
+
from cumulusci.core.config import OrgConfig
|
|
9
|
+
from cumulusci.core.config.project_config import BaseProjectConfig
|
|
10
|
+
from cumulusci.core.dependencies.utils import TaskContext
|
|
11
|
+
from cumulusci.core.exceptions import DependencyResolutionError, VcsNotFoundError
|
|
12
|
+
from cumulusci.core.sfdx import (
|
|
13
|
+
SourceFormat,
|
|
14
|
+
convert_sfdx_source,
|
|
15
|
+
get_source_format_for_zipfile,
|
|
16
|
+
)
|
|
17
|
+
from cumulusci.salesforce_api.metadata import ApiDeploy
|
|
18
|
+
from cumulusci.salesforce_api.package_zip import MetadataPackageZipBuilder
|
|
19
|
+
from cumulusci.utils import download_extract_vcs_from_repo, temporary_dir
|
|
20
|
+
from cumulusci.utils.yaml.model_parser import HashableBaseModel
|
|
21
|
+
from cumulusci.utils.ziputils import zip_subfolder
|
|
22
|
+
from cumulusci.vcs.models import AbstractRepo
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class DependencyPin(HashableBaseModel, ABC):
|
|
26
|
+
@abstractmethod
|
|
27
|
+
def can_pin(self, d: "DynamicDependency") -> bool:
|
|
28
|
+
raise NotImplementedError("Subclasses must implement can_pin.")
|
|
29
|
+
|
|
30
|
+
@abstractmethod
|
|
31
|
+
def pin(self, d: "DynamicDependency", context: BaseProjectConfig):
|
|
32
|
+
raise NotImplementedError("Subclasses must implement pin.")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
DependencyPin.update_forward_refs()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class VcsDependencyPin(DependencyPin):
|
|
39
|
+
url: Optional[AnyUrl] = None
|
|
40
|
+
tag: str
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
@abstractmethod
|
|
44
|
+
def vcsTagResolver(self): # -> Type["AbstractTagResolver"]:
|
|
45
|
+
raise NotImplementedError("Subclasses must implement vcsTagResolver.")
|
|
46
|
+
|
|
47
|
+
@root_validator(pre=True)
|
|
48
|
+
@abstractmethod
|
|
49
|
+
def sync_vcs_and_url(cls, values):
|
|
50
|
+
"""Defined vcs should be assigned to url"""
|
|
51
|
+
raise NotImplementedError("Subclasses must implement sync_vcs_and_url.")
|
|
52
|
+
|
|
53
|
+
def can_pin(self, d: "DynamicDependency") -> bool:
|
|
54
|
+
return isinstance(d, BaseVcsDynamicDependency) and d.url == self.url
|
|
55
|
+
|
|
56
|
+
def pin(self, d: "BaseVcsDynamicDependency", context: BaseProjectConfig):
|
|
57
|
+
if d.tag and d.tag != self.tag:
|
|
58
|
+
raise DependencyResolutionError(
|
|
59
|
+
f"A pin is specified for {self.url}, but the dependency already has a tag specified."
|
|
60
|
+
)
|
|
61
|
+
d.tag = self.tag
|
|
62
|
+
d.ref, d.package_dependency = self.vcsTagResolver().resolve(d, context)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class Dependency(HashableBaseModel, ABC):
|
|
66
|
+
"""Abstract base class for models representing dependencies
|
|
67
|
+
|
|
68
|
+
Dependencies can be _resolved_ to an immutable version, or not.
|
|
69
|
+
They can also be _flattened_ (turned into a list including their own transitive dependencies) or not.
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
@property
|
|
73
|
+
@abstractmethod
|
|
74
|
+
def name(self):
|
|
75
|
+
pass
|
|
76
|
+
|
|
77
|
+
@property
|
|
78
|
+
def description(self):
|
|
79
|
+
return self.name
|
|
80
|
+
|
|
81
|
+
@property
|
|
82
|
+
@abstractmethod
|
|
83
|
+
def is_resolved(self):
|
|
84
|
+
return False
|
|
85
|
+
|
|
86
|
+
@property
|
|
87
|
+
@abstractmethod
|
|
88
|
+
def is_flattened(self):
|
|
89
|
+
return False
|
|
90
|
+
|
|
91
|
+
def flatten(self, context: BaseProjectConfig) -> List["Dependency"]:
|
|
92
|
+
"""Get a list including this dependency as well as its transitive dependencies."""
|
|
93
|
+
return [self]
|
|
94
|
+
|
|
95
|
+
def __str__(self):
|
|
96
|
+
return self.description
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
Dependency.update_forward_refs()
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class StaticDependency(Dependency, ABC):
|
|
103
|
+
"""Abstract base class for dependencies that we know how to install (i.e., they
|
|
104
|
+
are already both resolved and flattened)."""
|
|
105
|
+
|
|
106
|
+
@abstractmethod
|
|
107
|
+
def install(self, org_config: OrgConfig, retry_options: Optional[dict] = None):
|
|
108
|
+
pass
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def is_resolved(self):
|
|
112
|
+
return True
|
|
113
|
+
|
|
114
|
+
@property
|
|
115
|
+
def is_flattened(self):
|
|
116
|
+
return True
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
class DynamicDependency(Dependency, ABC):
|
|
120
|
+
"""Abstract base class for dependencies with dynamic references, like GitHub.
|
|
121
|
+
These dependencies must be resolved and flattened before they can be installed."""
|
|
122
|
+
|
|
123
|
+
url: Optional[AnyUrl] = None
|
|
124
|
+
package_dependency: Optional[StaticDependency] = None
|
|
125
|
+
password_env_name: Optional[str] = None
|
|
126
|
+
|
|
127
|
+
@property
|
|
128
|
+
def is_flattened(self):
|
|
129
|
+
return False
|
|
130
|
+
|
|
131
|
+
@root_validator(pre=True)
|
|
132
|
+
@abstractmethod
|
|
133
|
+
def sync_vcs_and_url(cls, values):
|
|
134
|
+
"""Defined vcs should be assigned to url"""
|
|
135
|
+
raise NotImplementedError("Subclasses must implement sync_vcs_and_url.")
|
|
136
|
+
|
|
137
|
+
def resolve(
|
|
138
|
+
self,
|
|
139
|
+
context: BaseProjectConfig,
|
|
140
|
+
strategies: List, # List[DependencyResolutionStrategy], but circular import
|
|
141
|
+
pins: Optional[List[DependencyPin]] = None,
|
|
142
|
+
):
|
|
143
|
+
"""Resolve a DynamicDependency that is not pinned to a specific version into one that is."""
|
|
144
|
+
# avoid import cycle
|
|
145
|
+
from .resolvers import resolve_dependency
|
|
146
|
+
|
|
147
|
+
for pin in pins or []:
|
|
148
|
+
if pin.can_pin(self):
|
|
149
|
+
context.logger.info(f"Pinning dependency {self} to {pin}")
|
|
150
|
+
pin.pin(self, context)
|
|
151
|
+
return
|
|
152
|
+
|
|
153
|
+
resolve_dependency(self, context, strategies)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
class UnmanagedDependency(StaticDependency, ABC):
|
|
157
|
+
"""Abstract base class for static, unmanaged dependencies."""
|
|
158
|
+
|
|
159
|
+
unmanaged: Optional[bool] = None
|
|
160
|
+
subfolder: Optional[str] = None
|
|
161
|
+
namespace_inject: Optional[str] = None
|
|
162
|
+
namespace_strip: Optional[str] = None
|
|
163
|
+
collision_check: Optional[bool] = None
|
|
164
|
+
|
|
165
|
+
def _get_unmanaged(self, org: OrgConfig):
|
|
166
|
+
if self.unmanaged is None:
|
|
167
|
+
if self.namespace_inject:
|
|
168
|
+
return self.namespace_inject not in org.installed_packages
|
|
169
|
+
else:
|
|
170
|
+
return True
|
|
171
|
+
|
|
172
|
+
return self.unmanaged
|
|
173
|
+
|
|
174
|
+
@abstractmethod
|
|
175
|
+
def _get_zip_src(self, context: BaseProjectConfig) -> ZipFile:
|
|
176
|
+
pass
|
|
177
|
+
|
|
178
|
+
def get_metadata_package_zip_builder(
|
|
179
|
+
self, project_config: BaseProjectConfig, org: OrgConfig
|
|
180
|
+
) -> MetadataPackageZipBuilder:
|
|
181
|
+
zip_src = self._get_zip_src(project_config)
|
|
182
|
+
# Determine whether to inject namespace prefixes or not
|
|
183
|
+
# If and only if we have no explicit configuration.
|
|
184
|
+
|
|
185
|
+
options = {
|
|
186
|
+
"unmanaged": self._get_unmanaged(org),
|
|
187
|
+
"namespace_inject": self.namespace_inject,
|
|
188
|
+
"namespace_strip": self.namespace_strip,
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
# We have a zip file. Now, determine how to handle
|
|
192
|
+
# MDAPI/SFDX format, with or without a subfolder specified.
|
|
193
|
+
|
|
194
|
+
# In only two cases do we need to do a zip subset.
|
|
195
|
+
# Either we have a repo root in MDAPI format and need to get `src`,
|
|
196
|
+
# or we're deploying a subfolder that is in MDAPI format.
|
|
197
|
+
zip_extract_subfolder = None
|
|
198
|
+
if (
|
|
199
|
+
not self.subfolder
|
|
200
|
+
and get_source_format_for_zipfile(zip_src, "src") is SourceFormat.MDAPI
|
|
201
|
+
):
|
|
202
|
+
zip_extract_subfolder = "src"
|
|
203
|
+
elif (
|
|
204
|
+
self.subfolder
|
|
205
|
+
and get_source_format_for_zipfile(zip_src, self.subfolder)
|
|
206
|
+
is SourceFormat.MDAPI
|
|
207
|
+
):
|
|
208
|
+
zip_extract_subfolder = self.subfolder
|
|
209
|
+
|
|
210
|
+
if zip_extract_subfolder:
|
|
211
|
+
zip_src = zip_subfolder(zip_src, zip_extract_subfolder)
|
|
212
|
+
|
|
213
|
+
source_format = get_source_format_for_zipfile(
|
|
214
|
+
zip_src, self.subfolder if not zip_extract_subfolder else None
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
real_path = None
|
|
218
|
+
package_zip = None
|
|
219
|
+
with contextlib.ExitStack() as stack:
|
|
220
|
+
if source_format is SourceFormat.SFDX:
|
|
221
|
+
# Convert source first.
|
|
222
|
+
stack.enter_context(temporary_dir(chdir=True))
|
|
223
|
+
zip_src.extractall()
|
|
224
|
+
real_path = stack.enter_context(
|
|
225
|
+
convert_sfdx_source(self.subfolder, None, project_config.logger)
|
|
226
|
+
)
|
|
227
|
+
zip_src = None # Don't use the zipfile if we converted source.
|
|
228
|
+
|
|
229
|
+
context = TaskContext(org, project_config, project_config.logger)
|
|
230
|
+
# We now know what to send to MetadataPackageZipBuilder
|
|
231
|
+
# Note that subfolder logic is applied either by subsetting the zip
|
|
232
|
+
# (for MDAPI) or by the conversion (for SFDX format)
|
|
233
|
+
|
|
234
|
+
package_zip = MetadataPackageZipBuilder.from_zipfile(
|
|
235
|
+
zip_src,
|
|
236
|
+
path=real_path,
|
|
237
|
+
options=options,
|
|
238
|
+
context=context,
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
return package_zip
|
|
242
|
+
|
|
243
|
+
def install(self, context: BaseProjectConfig, org: OrgConfig):
|
|
244
|
+
|
|
245
|
+
context.logger.info(f"Deploying unmanaged metadata from {self.description}")
|
|
246
|
+
|
|
247
|
+
package_zip_builder = self.get_metadata_package_zip_builder(context, org)
|
|
248
|
+
task = TaskContext(
|
|
249
|
+
org_config=org, project_config=context, logger=context.logger
|
|
250
|
+
)
|
|
251
|
+
api = ApiDeploy(task, package_zip_builder.as_base64())
|
|
252
|
+
|
|
253
|
+
return api()
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
class BaseVcsDynamicDependency(DynamicDependency, ABC):
|
|
257
|
+
"""Abstract base class for dynamic dependencies that are stored in a VCS."""
|
|
258
|
+
|
|
259
|
+
tag: Optional[str] = None
|
|
260
|
+
ref: Optional[str] = None
|
|
261
|
+
|
|
262
|
+
vcs: str = "" # Need to validate presence of this pydantic field in subclasses
|
|
263
|
+
_repo: Optional[AbstractRepo] = PrivateAttr(default=None)
|
|
264
|
+
|
|
265
|
+
@property
|
|
266
|
+
@abstractmethod
|
|
267
|
+
def is_unmanaged(self):
|
|
268
|
+
pass
|
|
269
|
+
|
|
270
|
+
@property
|
|
271
|
+
def is_resolved(self):
|
|
272
|
+
return bool(self.ref)
|
|
273
|
+
|
|
274
|
+
@property
|
|
275
|
+
def repo(self):
|
|
276
|
+
# if not self._repo:
|
|
277
|
+
# raise ValueError("VCS DynamicDependency has no repo set")
|
|
278
|
+
return self._repo
|
|
279
|
+
|
|
280
|
+
def set_repo(self, value: AbstractRepo):
|
|
281
|
+
self._repo = value
|
|
282
|
+
|
|
283
|
+
@root_validator
|
|
284
|
+
def check_complete(cls, values):
|
|
285
|
+
|
|
286
|
+
assert values["ref"] is None, "Must not specify `ref` at creation."
|
|
287
|
+
return values
|
|
288
|
+
|
|
289
|
+
@property
|
|
290
|
+
def name(self):
|
|
291
|
+
return f"Dependency: {self.url}"
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
class VcsDynamicSubfolderDependency(BaseVcsDynamicDependency, ABC):
|
|
295
|
+
"""A dependency expressed by a reference to a subfolder of a ADO repo, which needs
|
|
296
|
+
to be resolved to a specific ref. This is always an unmanaged dependency."""
|
|
297
|
+
|
|
298
|
+
subfolder: str
|
|
299
|
+
namespace_inject: Optional[str] = None
|
|
300
|
+
namespace_strip: Optional[str] = None
|
|
301
|
+
|
|
302
|
+
@property
|
|
303
|
+
def is_unmanaged(self):
|
|
304
|
+
return True
|
|
305
|
+
|
|
306
|
+
@property
|
|
307
|
+
def name(self) -> str:
|
|
308
|
+
return f"Dependency: {self.url}/{self.subfolder}"
|
|
309
|
+
|
|
310
|
+
@property
|
|
311
|
+
def description(self) -> str:
|
|
312
|
+
loc = f" @{self.tag or self.ref}" if self.ref or self.tag else ""
|
|
313
|
+
return f"{self.url}/{self.subfolder}{loc}"
|
|
314
|
+
|
|
315
|
+
@property
|
|
316
|
+
@abstractmethod
|
|
317
|
+
def unmanagedVcsDependency(self) -> Type[UnmanagedDependency]:
|
|
318
|
+
raise NotImplementedError("Subclasses must implement unmanagedVcsDependency.")
|
|
319
|
+
|
|
320
|
+
def flatten(self, context: BaseProjectConfig) -> List[Dependency]:
|
|
321
|
+
"""Convert to a static dependency after resolution"""
|
|
322
|
+
|
|
323
|
+
if not self.is_resolved:
|
|
324
|
+
raise DependencyResolutionError(
|
|
325
|
+
f"Dependency {self} is not resolved and cannot be flattened."
|
|
326
|
+
)
|
|
327
|
+
|
|
328
|
+
return [
|
|
329
|
+
self.unmanagedVcsDependency(
|
|
330
|
+
url=self.url,
|
|
331
|
+
ref=self.ref or "",
|
|
332
|
+
subfolder=self.subfolder,
|
|
333
|
+
namespace_inject=self.namespace_inject,
|
|
334
|
+
namespace_strip=self.namespace_strip,
|
|
335
|
+
)
|
|
336
|
+
]
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
class VcsDynamicDependency(BaseVcsDynamicDependency, ABC):
|
|
340
|
+
"""A dependency expressed by a reference to a ADO repo, which needs
|
|
341
|
+
to be resolved to a specific ref and/or package version."""
|
|
342
|
+
|
|
343
|
+
unmanaged: bool = False
|
|
344
|
+
namespace_inject: Optional[str] = None
|
|
345
|
+
namespace_strip: Optional[str] = None
|
|
346
|
+
password_env_name: Optional[str] = None
|
|
347
|
+
|
|
348
|
+
skip: List[str] = []
|
|
349
|
+
|
|
350
|
+
@property
|
|
351
|
+
def is_unmanaged(self):
|
|
352
|
+
return self.unmanaged
|
|
353
|
+
|
|
354
|
+
@property
|
|
355
|
+
@abstractmethod
|
|
356
|
+
def unmanagedVcsDependency(self) -> Type[UnmanagedDependency]:
|
|
357
|
+
raise NotImplementedError("Subclasses must implement unmanagedVcsDependency.")
|
|
358
|
+
|
|
359
|
+
@abstractmethod
|
|
360
|
+
def get_repo(self, context, url) -> AbstractRepo:
|
|
361
|
+
raise NotImplementedError("Subclasses must implement get_repo.")
|
|
362
|
+
|
|
363
|
+
@validator("skip", pre=True)
|
|
364
|
+
def listify_skip(cls, v):
|
|
365
|
+
if v and not isinstance(v, list):
|
|
366
|
+
v = [v]
|
|
367
|
+
return v
|
|
368
|
+
|
|
369
|
+
@root_validator
|
|
370
|
+
def check_unmanaged_values(cls, values):
|
|
371
|
+
|
|
372
|
+
if not values.get("unmanaged") and (
|
|
373
|
+
values.get("namespace_inject") or values.get("namespace_strip")
|
|
374
|
+
):
|
|
375
|
+
raise ValueError(
|
|
376
|
+
"The namespace_strip and namespace_inject fields require unmanaged = True"
|
|
377
|
+
)
|
|
378
|
+
|
|
379
|
+
return values
|
|
380
|
+
|
|
381
|
+
def _flatten_unpackaged(
|
|
382
|
+
self,
|
|
383
|
+
repo: AbstractRepo,
|
|
384
|
+
subfolder: str,
|
|
385
|
+
skip: List[str],
|
|
386
|
+
managed: bool,
|
|
387
|
+
namespace: Optional[str],
|
|
388
|
+
) -> List[StaticDependency]:
|
|
389
|
+
"""Locate unmanaged dependencies from a repository subfolder (such as unpackaged/pre or unpackaged/post)"""
|
|
390
|
+
unpackaged = []
|
|
391
|
+
try:
|
|
392
|
+
contents = repo.directory_contents(subfolder, return_as=dict, ref=self.ref)
|
|
393
|
+
except VcsNotFoundError:
|
|
394
|
+
contents = None
|
|
395
|
+
|
|
396
|
+
if contents:
|
|
397
|
+
for dirname in sorted(contents.keys()):
|
|
398
|
+
this_subfolder = f"{subfolder}/{dirname}"
|
|
399
|
+
if this_subfolder in skip:
|
|
400
|
+
continue
|
|
401
|
+
|
|
402
|
+
unpackaged.append(
|
|
403
|
+
self.unmanagedVcsDependency(
|
|
404
|
+
url=self.url,
|
|
405
|
+
ref=self.ref,
|
|
406
|
+
subfolder=this_subfolder,
|
|
407
|
+
unmanaged=not managed,
|
|
408
|
+
namespace_inject=namespace if namespace and managed else None,
|
|
409
|
+
namespace_strip=namespace
|
|
410
|
+
if namespace and not managed
|
|
411
|
+
else None,
|
|
412
|
+
)
|
|
413
|
+
)
|
|
414
|
+
|
|
415
|
+
return unpackaged
|
|
416
|
+
|
|
417
|
+
def flatten(self, context: BaseProjectConfig) -> List[Dependency]:
|
|
418
|
+
"""Find more dependencies based on repository contents.
|
|
419
|
+
|
|
420
|
+
Includes:
|
|
421
|
+
- dependencies from cumulusci.yml
|
|
422
|
+
- subfolders of unpackaged/pre
|
|
423
|
+
- the contents of src, if this is not a managed package
|
|
424
|
+
- subfolders of unpackaged/post
|
|
425
|
+
"""
|
|
426
|
+
from cumulusci.core.dependencies.dependencies import parse_dependency
|
|
427
|
+
from cumulusci.core.dependencies.resolvers import get_package_data
|
|
428
|
+
from cumulusci.vcs.bootstrap import get_remote_project_config
|
|
429
|
+
|
|
430
|
+
if not self.is_resolved:
|
|
431
|
+
raise DependencyResolutionError(
|
|
432
|
+
f"Dependency {self} is not resolved and cannot be flattened."
|
|
433
|
+
)
|
|
434
|
+
|
|
435
|
+
deps = []
|
|
436
|
+
|
|
437
|
+
context.logger.info(f"Collecting dependencies from {self.vcs} repo {self.url}")
|
|
438
|
+
repo = self.get_repo(context, self.url)
|
|
439
|
+
|
|
440
|
+
package_config = get_remote_project_config(repo, self.ref)
|
|
441
|
+
_, namespace = get_package_data(package_config)
|
|
442
|
+
|
|
443
|
+
# Parse upstream dependencies from the repo's cumulusci.yml
|
|
444
|
+
# These may be unresolved or unflattened; if so, `get_static_dependencies()`
|
|
445
|
+
# will manage them.
|
|
446
|
+
dependencies = package_config.project__dependencies
|
|
447
|
+
if dependencies:
|
|
448
|
+
deps.extend([parse_dependency(d) for d in dependencies])
|
|
449
|
+
if None in deps:
|
|
450
|
+
raise DependencyResolutionError(
|
|
451
|
+
f"Unable to flatten dependency {self} because a transitive dependency could not be parsed."
|
|
452
|
+
)
|
|
453
|
+
|
|
454
|
+
# Check for unmanaged flag on a namespaced package
|
|
455
|
+
managed = bool(namespace and not self.unmanaged)
|
|
456
|
+
|
|
457
|
+
# Look for subfolders under unpackaged/pre
|
|
458
|
+
# unpackaged/pre is always deployed unmanaged, no namespace manipulation.
|
|
459
|
+
deps.extend(
|
|
460
|
+
self._flatten_unpackaged(
|
|
461
|
+
repo, "unpackaged/pre", self.skip, managed=False, namespace=None
|
|
462
|
+
)
|
|
463
|
+
)
|
|
464
|
+
|
|
465
|
+
if not self.package_dependency:
|
|
466
|
+
if managed:
|
|
467
|
+
# We had an expectation of finding a package version and did not.
|
|
468
|
+
raise DependencyResolutionError(
|
|
469
|
+
f"Could not find latest release for {self}"
|
|
470
|
+
)
|
|
471
|
+
|
|
472
|
+
# Deploy the project, if unmanaged.
|
|
473
|
+
deps.append(
|
|
474
|
+
self.unmanagedVcsDependency(
|
|
475
|
+
url=self.url,
|
|
476
|
+
ref=self.ref,
|
|
477
|
+
unmanaged=self.unmanaged,
|
|
478
|
+
namespace_inject=self.namespace_inject,
|
|
479
|
+
namespace_strip=self.namespace_strip,
|
|
480
|
+
)
|
|
481
|
+
)
|
|
482
|
+
else:
|
|
483
|
+
deps.append(self.package_dependency)
|
|
484
|
+
|
|
485
|
+
# We always inject the project's namespace into unpackaged/post metadata if managed
|
|
486
|
+
deps.extend(
|
|
487
|
+
self._flatten_unpackaged(
|
|
488
|
+
repo,
|
|
489
|
+
"unpackaged/post",
|
|
490
|
+
self.skip,
|
|
491
|
+
managed=managed,
|
|
492
|
+
namespace=namespace,
|
|
493
|
+
)
|
|
494
|
+
)
|
|
495
|
+
|
|
496
|
+
return deps
|
|
497
|
+
|
|
498
|
+
@property
|
|
499
|
+
def description(self):
|
|
500
|
+
unmanaged = " (unmanaged)" if self.unmanaged else ""
|
|
501
|
+
loc = f" @{self.tag or self.ref}" if self.ref or self.tag else ""
|
|
502
|
+
return f"{self.url}{unmanaged}{loc}"
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
class UnmanagedVcsDependency(UnmanagedDependency, ABC):
|
|
506
|
+
url: Optional[AnyUrl] = None
|
|
507
|
+
ref: str
|
|
508
|
+
|
|
509
|
+
# for backwards compatibility only; currently unused
|
|
510
|
+
filename_token: Optional[str] = None
|
|
511
|
+
namespace_token: Optional[str] = None
|
|
512
|
+
|
|
513
|
+
# Add these fields to support subfolder and namespace manipulation
|
|
514
|
+
subfolder: Optional[str] = None
|
|
515
|
+
namespace_inject: Optional[str] = None
|
|
516
|
+
namespace_strip: Optional[str] = None
|
|
517
|
+
|
|
518
|
+
@root_validator(pre=True)
|
|
519
|
+
@abstractmethod
|
|
520
|
+
def sync_vcs_and_url(cls, values):
|
|
521
|
+
"""Defined vcs should be assigned to url"""
|
|
522
|
+
raise NotImplementedError("Subclasses must implement sync_vcs_and_url.")
|
|
523
|
+
|
|
524
|
+
@abstractmethod
|
|
525
|
+
def get_repo(self, url, context) -> AbstractRepo:
|
|
526
|
+
raise NotImplementedError("Subclasses must implement get_repo.")
|
|
527
|
+
|
|
528
|
+
@property
|
|
529
|
+
@abstractmethod
|
|
530
|
+
def package_name(self) -> str:
|
|
531
|
+
"""A human-readable name of the dependency."""
|
|
532
|
+
raise NotImplementedError("Subclasses must implement package_name.")
|
|
533
|
+
|
|
534
|
+
def _get_zip_src(self, context):
|
|
535
|
+
repo = self.get_repo(context, self.url)
|
|
536
|
+
|
|
537
|
+
# We don't pass `subfolder` to download_extract_vcs_from_repo()
|
|
538
|
+
# because we need to get the whole ref in order to
|
|
539
|
+
# correctly handle any permutation of MDAPI/SFDX format,
|
|
540
|
+
# with or without a subfolder specified.
|
|
541
|
+
|
|
542
|
+
# install() will take care of that for us.
|
|
543
|
+
return download_extract_vcs_from_repo(
|
|
544
|
+
repo,
|
|
545
|
+
ref=self.ref,
|
|
546
|
+
)
|
|
547
|
+
|
|
548
|
+
@property
|
|
549
|
+
def name(self):
|
|
550
|
+
subfolder = (
|
|
551
|
+
f"/{self.subfolder}" if self.subfolder and self.subfolder != "src" else ""
|
|
552
|
+
)
|
|
553
|
+
return f"Deploy {self.url}{subfolder}"
|
|
554
|
+
|
|
555
|
+
@property
|
|
556
|
+
def description(self):
|
|
557
|
+
subfolder = (
|
|
558
|
+
f"/{self.subfolder}" if self.subfolder and self.subfolder != "src" else ""
|
|
559
|
+
)
|
|
560
|
+
|
|
561
|
+
return f"{self.url}{subfolder} @{self.ref}"
|