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,604 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import re
|
|
3
|
+
from collections import defaultdict, namedtuple
|
|
4
|
+
from contextlib import contextmanager
|
|
5
|
+
from datetime import date, datetime
|
|
6
|
+
from typing import Optional
|
|
7
|
+
from urllib.parse import urlparse
|
|
8
|
+
|
|
9
|
+
import requests
|
|
10
|
+
from simple_salesforce import Salesforce
|
|
11
|
+
from simple_salesforce.exceptions import SalesforceError, SalesforceResourceNotFound
|
|
12
|
+
|
|
13
|
+
from cumulusci.core.config import BaseConfig
|
|
14
|
+
from cumulusci.core.exceptions import (
|
|
15
|
+
CumulusCIException,
|
|
16
|
+
DependencyResolutionError,
|
|
17
|
+
ServiceNotConfigured,
|
|
18
|
+
)
|
|
19
|
+
from cumulusci.oauth.client import OAuth2Client, OAuth2ClientConfig
|
|
20
|
+
from cumulusci.oauth.salesforce import SANDBOX_LOGIN_URL, jwt_session
|
|
21
|
+
from cumulusci.utils import parse_api_datetime
|
|
22
|
+
from cumulusci.utils.fileutils import open_fs_resource
|
|
23
|
+
from cumulusci.utils.http.requests_utils import safe_json_from_response
|
|
24
|
+
from cumulusci.utils.version_strings import StrictVersion
|
|
25
|
+
|
|
26
|
+
SKIP_REFRESH = os.environ.get("CUMULUSCI_DISABLE_REFRESH")
|
|
27
|
+
SANDBOX_MYDOMAIN_RE = re.compile(r"\.cs\d+\.my\.(.*)salesforce\.com")
|
|
28
|
+
MYDOMAIN_RE = re.compile(r"\.my\.(.*)salesforce\.com")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
VersionInfo = namedtuple("VersionInfo", ["id", "number"])
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class OrgConfig(BaseConfig):
|
|
35
|
+
"""Salesforce org configuration (i.e. org credentials)"""
|
|
36
|
+
|
|
37
|
+
access_token: str
|
|
38
|
+
config_file: str
|
|
39
|
+
config_name: str
|
|
40
|
+
created: bool
|
|
41
|
+
date_created: (datetime, date) # type: ignore
|
|
42
|
+
days: int
|
|
43
|
+
email_address: str
|
|
44
|
+
instance_name: str
|
|
45
|
+
instance_url: str
|
|
46
|
+
expires: str # TODO: note that ScratchOrgConfig has a bool method of same name
|
|
47
|
+
expired: bool # ditto
|
|
48
|
+
is_sandbox: bool
|
|
49
|
+
namespace: str
|
|
50
|
+
namespaced: bool
|
|
51
|
+
org_type: str
|
|
52
|
+
password: str
|
|
53
|
+
scratch: bool
|
|
54
|
+
scratch_org_type: str
|
|
55
|
+
set_password: bool
|
|
56
|
+
sfdx_alias: str
|
|
57
|
+
userinfo: str
|
|
58
|
+
id: str
|
|
59
|
+
active: bool
|
|
60
|
+
default: bool
|
|
61
|
+
client_id: str
|
|
62
|
+
refresh_token: str
|
|
63
|
+
client_secret: str
|
|
64
|
+
connected_app: str
|
|
65
|
+
serialization_format: str
|
|
66
|
+
|
|
67
|
+
createable: Optional[bool] = None
|
|
68
|
+
|
|
69
|
+
# make sure it can be mocked for tests
|
|
70
|
+
OAuth2Client = OAuth2Client
|
|
71
|
+
|
|
72
|
+
def __init__(self, config: dict, name: str, keychain=None, global_org=False):
|
|
73
|
+
self.keychain = keychain
|
|
74
|
+
self.global_org = global_org
|
|
75
|
+
|
|
76
|
+
self.name = name
|
|
77
|
+
self.force_sandbox = config.get("sandbox", False) if config else False
|
|
78
|
+
self._community_info_cache = {}
|
|
79
|
+
self._latest_api_version = None
|
|
80
|
+
self._installed_packages = None
|
|
81
|
+
self._is_person_accounts_enabled = None
|
|
82
|
+
self._multiple_currencies_is_enabled = False
|
|
83
|
+
|
|
84
|
+
super().__init__(config)
|
|
85
|
+
|
|
86
|
+
def refresh_oauth_token(self, keychain, connected_app=None, is_sandbox=False):
|
|
87
|
+
"""Get a fresh access token and store it in the org config.
|
|
88
|
+
|
|
89
|
+
If the SFDX_CLIENT_ID and SFDX_HUB_KEY environment variables are set,
|
|
90
|
+
this is done using the Oauth2 JWT flow.
|
|
91
|
+
|
|
92
|
+
Otherwise it is done using the Oauth2 Refresh Token flow using the connected app
|
|
93
|
+
configured in the keychain's connected_app service.
|
|
94
|
+
|
|
95
|
+
Also refreshes user and org info that is cached in the org config.
|
|
96
|
+
"""
|
|
97
|
+
if not SKIP_REFRESH:
|
|
98
|
+
SFDX_CLIENT_ID = os.environ.get("SFDX_CLIENT_ID")
|
|
99
|
+
SFDX_HUB_KEY = os.environ.get("SFDX_HUB_KEY")
|
|
100
|
+
if SFDX_CLIENT_ID and SFDX_HUB_KEY:
|
|
101
|
+
auth_url = SANDBOX_LOGIN_URL if self.force_sandbox else self.id
|
|
102
|
+
info = jwt_session(
|
|
103
|
+
SFDX_CLIENT_ID,
|
|
104
|
+
SFDX_HUB_KEY,
|
|
105
|
+
self.username,
|
|
106
|
+
self.instance_url,
|
|
107
|
+
auth_url=auth_url,
|
|
108
|
+
is_sandbox=is_sandbox,
|
|
109
|
+
)
|
|
110
|
+
else:
|
|
111
|
+
info = self._refresh_token(keychain, connected_app)
|
|
112
|
+
if info != self.config:
|
|
113
|
+
self.config.update(info)
|
|
114
|
+
self._load_userinfo()
|
|
115
|
+
self._load_orginfo()
|
|
116
|
+
|
|
117
|
+
@contextmanager
|
|
118
|
+
def save_if_changed(self):
|
|
119
|
+
orig_config = self.config.copy()
|
|
120
|
+
yield
|
|
121
|
+
if self.config != orig_config:
|
|
122
|
+
self.logger.info("Org info updated, writing to keychain")
|
|
123
|
+
self.save()
|
|
124
|
+
|
|
125
|
+
def _refresh_token(self, keychain, connected_app):
|
|
126
|
+
if keychain: # it might be none'd and caller adds connected_app
|
|
127
|
+
try:
|
|
128
|
+
connected_app = keychain.get_service(
|
|
129
|
+
"connected_app", self.connected_app
|
|
130
|
+
)
|
|
131
|
+
except ServiceNotConfigured:
|
|
132
|
+
raise ServiceNotConfigured(
|
|
133
|
+
f"This org was connected using the {self.connected_app} connected_app service, which is no longer configured."
|
|
134
|
+
)
|
|
135
|
+
if connected_app is None:
|
|
136
|
+
raise AttributeError(
|
|
137
|
+
"No connected app or keychain was passed to refresh_oauth_token."
|
|
138
|
+
)
|
|
139
|
+
client_id = self.client_id
|
|
140
|
+
client_secret = self.client_secret
|
|
141
|
+
if not client_id:
|
|
142
|
+
client_id = connected_app.client_id
|
|
143
|
+
client_secret = connected_app.client_secret
|
|
144
|
+
|
|
145
|
+
sf_oauth_config = OAuth2ClientConfig(
|
|
146
|
+
client_id=client_id,
|
|
147
|
+
client_secret=client_secret,
|
|
148
|
+
auth_uri=f"{self.instance_url}/services/oauth2/authorize",
|
|
149
|
+
token_uri=f"{self.instance_url}/services/oauth2/token",
|
|
150
|
+
scope="web full refresh_token",
|
|
151
|
+
)
|
|
152
|
+
sf_oauth = self.OAuth2Client(sf_oauth_config)
|
|
153
|
+
return sf_oauth.refresh_token(self.refresh_token)
|
|
154
|
+
|
|
155
|
+
@property
|
|
156
|
+
def lightning_base_url(self):
|
|
157
|
+
instance_url = self.instance_url.rstrip("/")
|
|
158
|
+
if SANDBOX_MYDOMAIN_RE.search(instance_url):
|
|
159
|
+
return SANDBOX_MYDOMAIN_RE.sub(r".lightning.\1force.com", instance_url)
|
|
160
|
+
elif MYDOMAIN_RE.search(instance_url):
|
|
161
|
+
return MYDOMAIN_RE.sub(r".lightning.\1force.com", instance_url)
|
|
162
|
+
else:
|
|
163
|
+
return self.instance_url.split(".")[0] + ".lightning.force.com"
|
|
164
|
+
|
|
165
|
+
@property
|
|
166
|
+
def salesforce_client(self):
|
|
167
|
+
"""Return a simple_salesforce.Salesforce instance authorized to this org.
|
|
168
|
+
Does not perform a token refresh."""
|
|
169
|
+
return Salesforce(
|
|
170
|
+
instance=self.instance_url.replace("https://", ""),
|
|
171
|
+
session_id=self.access_token,
|
|
172
|
+
version=self.latest_api_version,
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
@property
|
|
176
|
+
def latest_api_version(self):
|
|
177
|
+
if not self._latest_api_version:
|
|
178
|
+
headers = {"Authorization": "Bearer " + self.access_token}
|
|
179
|
+
response = requests.get(
|
|
180
|
+
self.instance_url + "/services/data", headers=headers
|
|
181
|
+
)
|
|
182
|
+
try:
|
|
183
|
+
version = safe_json_from_response(response)[-1]["version"]
|
|
184
|
+
except (KeyError, IndexError, TypeError):
|
|
185
|
+
raise CumulusCIException(
|
|
186
|
+
f"Cannot decode API Version `{response.text[0:100]}``"
|
|
187
|
+
)
|
|
188
|
+
self._latest_api_version = str(version)
|
|
189
|
+
|
|
190
|
+
return self._latest_api_version
|
|
191
|
+
|
|
192
|
+
@property
|
|
193
|
+
def start_url(self):
|
|
194
|
+
"""The frontdoor URL that results in an instant login"""
|
|
195
|
+
start_url = "%s/secur/frontdoor.jsp?sid=%s" % (
|
|
196
|
+
self.instance_url,
|
|
197
|
+
self.access_token,
|
|
198
|
+
)
|
|
199
|
+
return start_url
|
|
200
|
+
|
|
201
|
+
@property
|
|
202
|
+
def user_id(self):
|
|
203
|
+
return self.id.split("/")[-1]
|
|
204
|
+
|
|
205
|
+
@property
|
|
206
|
+
def org_id(self):
|
|
207
|
+
try:
|
|
208
|
+
if org_id := self.config.get("org_id"):
|
|
209
|
+
return org_id
|
|
210
|
+
elif hasattr(self, "id") and self.id:
|
|
211
|
+
return self.id.split("/")[-2]
|
|
212
|
+
else:
|
|
213
|
+
return None
|
|
214
|
+
except Exception as e: # pragma: no cover
|
|
215
|
+
assert e is None, e
|
|
216
|
+
|
|
217
|
+
@property
|
|
218
|
+
def username(self):
|
|
219
|
+
"""Username for the org connection."""
|
|
220
|
+
username = self.config.get("username")
|
|
221
|
+
if not username:
|
|
222
|
+
username = self.userinfo__preferred_username
|
|
223
|
+
return username
|
|
224
|
+
|
|
225
|
+
def load_userinfo(self):
|
|
226
|
+
self._load_userinfo()
|
|
227
|
+
|
|
228
|
+
def _load_userinfo(self):
|
|
229
|
+
headers = {"Authorization": "Bearer " + self.access_token}
|
|
230
|
+
response = requests.get(
|
|
231
|
+
self.instance_url + "/services/oauth2/userinfo", headers=headers
|
|
232
|
+
)
|
|
233
|
+
if response != self.config.get("userinfo", {}):
|
|
234
|
+
config_data = safe_json_from_response(response)
|
|
235
|
+
self.config.update({"userinfo": config_data})
|
|
236
|
+
|
|
237
|
+
def can_delete(self):
|
|
238
|
+
return False
|
|
239
|
+
|
|
240
|
+
def _load_orginfo(self):
|
|
241
|
+
"""Query the Organization sObject and populate local config values from the result."""
|
|
242
|
+
self._org_sobject = self.salesforce_client.Organization.get(self.org_id)
|
|
243
|
+
|
|
244
|
+
result = {
|
|
245
|
+
"org_type": self._org_sobject["OrganizationType"],
|
|
246
|
+
"is_sandbox": self._org_sobject["IsSandbox"],
|
|
247
|
+
"instance_name": self._org_sobject["InstanceName"],
|
|
248
|
+
"namespace": self._org_sobject["NamespacePrefix"],
|
|
249
|
+
}
|
|
250
|
+
self.config.update(result)
|
|
251
|
+
|
|
252
|
+
def populate_expiration_date(self):
|
|
253
|
+
if not self.organization_sobject:
|
|
254
|
+
self._load_orginfo()
|
|
255
|
+
if self.organization_sobject["TrialExpirationDate"] is None:
|
|
256
|
+
self.config["expires"] = "Persistent"
|
|
257
|
+
else:
|
|
258
|
+
self.config["expires"] = parse_api_datetime(
|
|
259
|
+
self.organization_sobject["TrialExpirationDate"]
|
|
260
|
+
).date()
|
|
261
|
+
|
|
262
|
+
@property
|
|
263
|
+
def organization_sobject(self):
|
|
264
|
+
"""Cached copy of Organization sObject. Does not perform API call."""
|
|
265
|
+
return getattr(self, "_org_sobject", None)
|
|
266
|
+
|
|
267
|
+
def _fetch_community_info(self):
|
|
268
|
+
"""Use the API to re-fetch information about communities"""
|
|
269
|
+
response = self.salesforce_client.restful("connect/communities")
|
|
270
|
+
|
|
271
|
+
# Since community names must be unique, we'll return a dictionary
|
|
272
|
+
# with the community names as keys
|
|
273
|
+
result = {community["name"]: community for community in response["communities"]}
|
|
274
|
+
return result
|
|
275
|
+
|
|
276
|
+
def get_community_info(self, community_name, force_refresh=False):
|
|
277
|
+
"""Return the community information for the given community
|
|
278
|
+
|
|
279
|
+
An API call will be made the first time this function is used,
|
|
280
|
+
and the return values will be cached. Subsequent calls will
|
|
281
|
+
not call the API unless the requested community name is not in
|
|
282
|
+
the cached results, or unless the force_refresh parameter is
|
|
283
|
+
set to True.
|
|
284
|
+
|
|
285
|
+
"""
|
|
286
|
+
|
|
287
|
+
if force_refresh or community_name not in self._community_info_cache:
|
|
288
|
+
self._community_info_cache = self._fetch_community_info()
|
|
289
|
+
|
|
290
|
+
if community_name not in self._community_info_cache:
|
|
291
|
+
raise Exception(
|
|
292
|
+
f"Unable to find community information for '{community_name}'"
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
return self._community_info_cache[community_name]
|
|
296
|
+
|
|
297
|
+
def has_minimum_package_version(self, package_identifier, version_identifier):
|
|
298
|
+
"""Return True if the org has a version of the specified package that is
|
|
299
|
+
equal to or newer than the supplied version identifier.
|
|
300
|
+
|
|
301
|
+
The package identifier may be either a namespace or a 033 package Id.
|
|
302
|
+
The version identifier should be in "1.2.3" or "1.2.3b4" format.
|
|
303
|
+
|
|
304
|
+
A CumulusCIException will be thrown if you request to check a namespace
|
|
305
|
+
and multiple second-generation packages sharing that namespace are installed.
|
|
306
|
+
Use a package Id to handle this circumstance."""
|
|
307
|
+
installed_version = self.installed_packages.get(package_identifier)
|
|
308
|
+
|
|
309
|
+
if not installed_version:
|
|
310
|
+
return False
|
|
311
|
+
elif len(installed_version) > 1:
|
|
312
|
+
raise CumulusCIException(
|
|
313
|
+
f"Cannot check installed version of {package_identifier}, because multiple "
|
|
314
|
+
f"packages are installed that match this identifier."
|
|
315
|
+
)
|
|
316
|
+
|
|
317
|
+
return installed_version[0].number >= version_identifier
|
|
318
|
+
|
|
319
|
+
@property
|
|
320
|
+
def installed_packages(self):
|
|
321
|
+
"""installed_packages is a dict mapping a namespace, package name, or package Id (033*) to the installed package
|
|
322
|
+
version(s) matching that identifier. All values are lists, because multiple second-generation
|
|
323
|
+
packages may be installed with the same namespace.
|
|
324
|
+
|
|
325
|
+
Keys include:
|
|
326
|
+
- namespace: "mycompany"
|
|
327
|
+
- package name: "My Package Name"
|
|
328
|
+
- namespace@version: "mycompany@1.2.3"
|
|
329
|
+
- package ID: "033ABCDEF123456"
|
|
330
|
+
|
|
331
|
+
To check if a required package is present, call `has_minimum_package_version()` with either the
|
|
332
|
+
namespace or 033 Id of the desired package and its version, in 1.2.3 format.
|
|
333
|
+
|
|
334
|
+
Beta version of a package are represented as "1.2.3b5", where 5 is the build number.
|
|
335
|
+
"""
|
|
336
|
+
if self._installed_packages is None:
|
|
337
|
+
isp_result = self.salesforce_client.restful(
|
|
338
|
+
"tooling/query/?q=SELECT SubscriberPackage.Id, SubscriberPackage.Name, SubscriberPackage.NamespacePrefix, "
|
|
339
|
+
"SubscriberPackageVersionId FROM InstalledSubscriberPackage"
|
|
340
|
+
)
|
|
341
|
+
_installed_packages = defaultdict(list)
|
|
342
|
+
for isp in isp_result["records"]:
|
|
343
|
+
sp = isp["SubscriberPackage"]
|
|
344
|
+
try:
|
|
345
|
+
spv_result = self.salesforce_client.restful(
|
|
346
|
+
"tooling/query/?q=SELECT Id, MajorVersion, MinorVersion, PatchVersion, BuildNumber, "
|
|
347
|
+
f"IsBeta FROM SubscriberPackageVersion WHERE Id='{isp['SubscriberPackageVersionId']}'"
|
|
348
|
+
)
|
|
349
|
+
except SalesforceError as err:
|
|
350
|
+
self.logger.warning(
|
|
351
|
+
f"Ignoring error while trying to check installed package {isp['SubscriberPackageVersionId']}: {err.content}"
|
|
352
|
+
)
|
|
353
|
+
continue
|
|
354
|
+
if not spv_result["records"]:
|
|
355
|
+
# This _shouldn't_ happen, but it is possible in customer orgs.
|
|
356
|
+
continue
|
|
357
|
+
spv = spv_result["records"][0]
|
|
358
|
+
|
|
359
|
+
version = f"{spv['MajorVersion']}.{spv['MinorVersion']}"
|
|
360
|
+
if spv["PatchVersion"]:
|
|
361
|
+
version += f".{spv['PatchVersion']}"
|
|
362
|
+
if spv["IsBeta"]:
|
|
363
|
+
version += f"b{spv['BuildNumber']}"
|
|
364
|
+
version_info = VersionInfo(spv["Id"], StrictVersion(version))
|
|
365
|
+
namespace = sp["NamespacePrefix"]
|
|
366
|
+
package_name = sp.get("Name", None)
|
|
367
|
+
_installed_packages[namespace].append(version_info)
|
|
368
|
+
namespace_version = f"{namespace}@{version}"
|
|
369
|
+
_installed_packages[namespace_version].append(version_info)
|
|
370
|
+
_installed_packages[sp["Id"]].append(version_info)
|
|
371
|
+
# Add package name as a key for specific package detection
|
|
372
|
+
if package_name:
|
|
373
|
+
_installed_packages[package_name].append(version_info)
|
|
374
|
+
|
|
375
|
+
self._installed_packages = _installed_packages
|
|
376
|
+
return self._installed_packages
|
|
377
|
+
|
|
378
|
+
def reset_installed_packages(self):
|
|
379
|
+
self._installed_packages = None
|
|
380
|
+
|
|
381
|
+
def save(self):
|
|
382
|
+
assert self.keychain, "Keychain was not set on OrgConfig"
|
|
383
|
+
self.keychain.set_org(self, self.global_org)
|
|
384
|
+
|
|
385
|
+
def get_domain(self):
|
|
386
|
+
instance_url = self.config.get("instance_url", "")
|
|
387
|
+
return urlparse(instance_url).hostname or ""
|
|
388
|
+
|
|
389
|
+
def get_orginfo_cache_dir(self, cachename):
|
|
390
|
+
"Returns a context managed FSResource object"
|
|
391
|
+
assert self.keychain, "Keychain should be set"
|
|
392
|
+
if self.global_org:
|
|
393
|
+
cache_dir = self.keychain.global_config_dir
|
|
394
|
+
else:
|
|
395
|
+
cache_dir = self.keychain.cache_dir
|
|
396
|
+
assert self.get_domain()
|
|
397
|
+
assert self.username
|
|
398
|
+
uniqifier = self.get_domain() + "__" + str(self.username).replace("@", "__")
|
|
399
|
+
cache_dir = cache_dir / "orginfo" / uniqifier / cachename
|
|
400
|
+
|
|
401
|
+
cache_dir.mkdir(parents=True, exist_ok=True)
|
|
402
|
+
return open_fs_resource(cache_dir)
|
|
403
|
+
|
|
404
|
+
@property
|
|
405
|
+
def is_person_accounts_enabled(self):
|
|
406
|
+
"""
|
|
407
|
+
Returns if the org has person accounts enabled, i.e. if Account has an ``IsPersonAccount`` field.
|
|
408
|
+
|
|
409
|
+
**Example**
|
|
410
|
+
|
|
411
|
+
Selectively run a task in a flow only if Person Accounts is or is not enabled.
|
|
412
|
+
|
|
413
|
+
.. code-block:: yaml
|
|
414
|
+
|
|
415
|
+
flows:
|
|
416
|
+
load_storytelling_data:
|
|
417
|
+
steps:
|
|
418
|
+
1:
|
|
419
|
+
task: load_dataset
|
|
420
|
+
options:
|
|
421
|
+
mapping: datasets/with_person_accounts/mapping.yml
|
|
422
|
+
sql_path: datasets/with_person_accounts/data.sql
|
|
423
|
+
when: org_config.is_person_accounts_enabled
|
|
424
|
+
2:
|
|
425
|
+
task: load_dataset
|
|
426
|
+
options:
|
|
427
|
+
mapping: datasets/without_person_accounts/mapping.yml
|
|
428
|
+
sql_path: datasets/without_person_accounts/data.sql
|
|
429
|
+
when: not org_config.is_person_accounts_enabled
|
|
430
|
+
|
|
431
|
+
"""
|
|
432
|
+
if self._is_person_accounts_enabled is None:
|
|
433
|
+
self._is_person_accounts_enabled = any(
|
|
434
|
+
field["name"] == "IsPersonAccount"
|
|
435
|
+
for field in self.salesforce_client.Account.describe()["fields"]
|
|
436
|
+
)
|
|
437
|
+
return self._is_person_accounts_enabled
|
|
438
|
+
|
|
439
|
+
@property
|
|
440
|
+
def is_multiple_currencies_enabled(self):
|
|
441
|
+
"""
|
|
442
|
+
Returns if the org has `Multiple Currencies <https://help.salesforce.com/articleView?id=admin_enable_multicurrency.htm>`_ enabled by checking if the `CurrencyType <https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_objects_currencytype.htm>`_ Sobject is exposed.
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
**Notes**
|
|
446
|
+
|
|
447
|
+
- Multiple Currencies cannot be disabled once enabled.
|
|
448
|
+
- Enabling `Multiple Currencies <https://help.salesforce.com/articleView?id=admin_enable_multicurrency.htm>`_ exposes both the `CurrencyType <https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_objects_currencytype.htm>`_ and the `DatedConversionRate <https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_objects_datedconversionrate.htm>`_ Sobjects.
|
|
449
|
+
|
|
450
|
+
**Enable Multiple Currencies programatically**
|
|
451
|
+
|
|
452
|
+
`Multiple Currencies <https://help.salesforce.com/articleView?id=admin_enable_multicurrency.htm>`_ can be enabled with Metadata API by updating the org's `CurrencySettings <https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_currencysettings.htm>`_ as the following:
|
|
453
|
+
|
|
454
|
+
.. code-block:: xml
|
|
455
|
+
|
|
456
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
457
|
+
<CurrencySettings xmlns="http://soap.sforce.com/2006/04/metadata">
|
|
458
|
+
<!-- Enables Multiple Currencies -->
|
|
459
|
+
<enableMultiCurrency>true</enableMultiCurrency>
|
|
460
|
+
</CurrencySettings>
|
|
461
|
+
|
|
462
|
+
**Example**
|
|
463
|
+
|
|
464
|
+
Selectively run a task in a flow only if Multiple Currencies <https://help.salesforce.com/articleView?id=admin_enable_multicurrency.htm>`_ is or is not enabled.
|
|
465
|
+
|
|
466
|
+
.. code-block:: yaml
|
|
467
|
+
|
|
468
|
+
flows:
|
|
469
|
+
load_storytelling_data:
|
|
470
|
+
steps:
|
|
471
|
+
1:
|
|
472
|
+
task: load_dataset
|
|
473
|
+
options:
|
|
474
|
+
mapping: datasets/with_multiple_currencies/mapping.yml
|
|
475
|
+
sql_path: datasets/with_multiple_currencies/data.sql
|
|
476
|
+
when: org_config.is_multiple_currencies_enabled
|
|
477
|
+
2:
|
|
478
|
+
task: load_dataset
|
|
479
|
+
options:
|
|
480
|
+
mapping: datasets/without_multple_currencies/mapping.yml
|
|
481
|
+
sql_path: datasets/without_multple_currencies/data.sql
|
|
482
|
+
when: not org_config.is_multiple_currencies_enabled
|
|
483
|
+
|
|
484
|
+
"""
|
|
485
|
+
# When Multiple Currencies is enabled, the CurrencyType Sobject is exposed.
|
|
486
|
+
# If Mutiple Currencies is not enabled:
|
|
487
|
+
# - CurrencyType Sobject is not exposed.
|
|
488
|
+
# - simple_salesforce raises a SalesforceResourceNotFound exception when trying to describe CurrencyType.
|
|
489
|
+
# NOTE: Multiple Currencies can be enabled through Metadata API by setting CurrencySettings.enableMultiCurrency as "true". Therefore, we should try to dynamically check if Multiple Currencies is enabled.
|
|
490
|
+
# NOTE: Once enabled, Multiple Currenies cannot be disabled.
|
|
491
|
+
if not self._multiple_currencies_is_enabled:
|
|
492
|
+
try:
|
|
493
|
+
# Multiple Currencies is enabled if CurrencyType can be described (implying the Sobject is exposed).
|
|
494
|
+
self.salesforce_client.CurrencyType.describe()
|
|
495
|
+
self._multiple_currencies_is_enabled = True
|
|
496
|
+
except SalesforceResourceNotFound:
|
|
497
|
+
# CurrencyType Sobject is not exposed meaning Multiple Currencies is not enabled.
|
|
498
|
+
# Keep self._multiple_currencies_is_enabled False.
|
|
499
|
+
pass
|
|
500
|
+
return self._multiple_currencies_is_enabled
|
|
501
|
+
|
|
502
|
+
@property
|
|
503
|
+
def is_advanced_currency_management_enabled(self):
|
|
504
|
+
"""
|
|
505
|
+
Returns if the org has `Advanced Currency Management (ACM) <https://help.salesforce.com/articleView?id=administration_enable_advanced_currency_management.htm>`_ enabled by checking if both:
|
|
506
|
+
|
|
507
|
+
- `Multiple Currencies <https://help.salesforce.com/articleView?id=admin_enable_multicurrency.htm>`_ is enabled (which exposes the ``DatedConversionRate`` Sobject).
|
|
508
|
+
- ``DatedConversionRate`` is createable.
|
|
509
|
+
|
|
510
|
+
**Notes**
|
|
511
|
+
|
|
512
|
+
- If Advanced Currency Management (ACM) is disabled, ``DatedConversionRate`` is no longer createable.
|
|
513
|
+
- Multiple Currencies cannot be disabled once enabled.
|
|
514
|
+
|
|
515
|
+
**Enable Advanced Currency Managment (ACM) programatically**
|
|
516
|
+
|
|
517
|
+
`Advanced Currency Management (ACM) <https://help.salesforce.com/articleView?id=administration_enable_advanced_currency_management.htm>`_ can be enabled with Metadata API by updating the org's `CurrencySettings <https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_currencysettings.htm>`_ as the following:
|
|
518
|
+
|
|
519
|
+
.. code-block:: xml
|
|
520
|
+
|
|
521
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
522
|
+
<CurrencySettings xmlns="http://soap.sforce.com/2006/04/metadata">
|
|
523
|
+
<!-- Enables Multiple Currencies -->
|
|
524
|
+
<enableMultiCurrency>true</enableMultiCurrency>
|
|
525
|
+
|
|
526
|
+
<!-- Enables Advanced Currency Management (ACM) -->
|
|
527
|
+
<enableCurrencyEffectiveDates>true</enableCurrencyEffectiveDates>
|
|
528
|
+
</CurrencySettings>
|
|
529
|
+
|
|
530
|
+
**Example**
|
|
531
|
+
|
|
532
|
+
Selectively run a task in a flow only if `Advanced Currency Management (ACM) <https://help.salesforce.com/articleView?id=administration_enable_advanced_currency_management.htm>`_ is or is not enabled.
|
|
533
|
+
|
|
534
|
+
.. code-block:: yaml
|
|
535
|
+
|
|
536
|
+
flows:
|
|
537
|
+
load_storytelling_data:
|
|
538
|
+
steps:
|
|
539
|
+
1:
|
|
540
|
+
task: load_dataset
|
|
541
|
+
options:
|
|
542
|
+
mapping: datasets/with_acm/mapping.yml
|
|
543
|
+
sql_path: datasets/with_acm/data.sql
|
|
544
|
+
when: org_config.is_advanced_currency_management_enabled
|
|
545
|
+
2:
|
|
546
|
+
task: load_dataset
|
|
547
|
+
options:
|
|
548
|
+
mapping: datasets/without_acm/mapping.yml
|
|
549
|
+
sql_path: datasets/without_acm/data.sql
|
|
550
|
+
when: not org_config.is_advanced_currency_management_enabled
|
|
551
|
+
|
|
552
|
+
"""
|
|
553
|
+
# NOTE: Advanced Currency Management (ACM) can be enabled via Metadata API by setting:
|
|
554
|
+
# - CurrencySettings.enableMultiCurrency as "true" to enable Multiple Currencies.
|
|
555
|
+
# - CurrencySettings.enableCurrencyEffectiveDates as "true" to enable Advanced Currency Management (ACM).
|
|
556
|
+
# NOTE: Once enabled, Multiple Currenies cannot be disabled.
|
|
557
|
+
# Avdanced Currency Management (ACM) is enabled if:
|
|
558
|
+
# - Multiple Currencies is enabled (which exposes the DatedConversionRate Sobject)
|
|
559
|
+
# - DatedConversionRate Sobject is createable.
|
|
560
|
+
# Advanced Currency Management (ACM) can be disabled, and if so, DatedConversionRate Sobject will no longer be createable.
|
|
561
|
+
try:
|
|
562
|
+
# Always check the describe since ACM can be disabled.
|
|
563
|
+
return self.salesforce_client.DatedConversionRate.describe()["createable"]
|
|
564
|
+
except SalesforceResourceNotFound:
|
|
565
|
+
# DatedConversionRate Sobject is not exposed meaning Multiple Currencies is not enabled.
|
|
566
|
+
return False
|
|
567
|
+
|
|
568
|
+
@property
|
|
569
|
+
def is_survey_advanced_features_enabled(self) -> bool:
|
|
570
|
+
return any(
|
|
571
|
+
f["name"] == "PermissionsAllowSurveyAdvancedFeatures"
|
|
572
|
+
for f in self.salesforce_client.PermissionSet.describe()["fields"]
|
|
573
|
+
)
|
|
574
|
+
|
|
575
|
+
def resolve_04t_dependencies(self, dependencies):
|
|
576
|
+
"""Look up 04t SubscriberPackageVersion ids for 1GP project dependencies"""
|
|
577
|
+
from cumulusci.core.dependencies.dependencies import (
|
|
578
|
+
PackageNamespaceVersionDependency,
|
|
579
|
+
PackageVersionIdDependency,
|
|
580
|
+
)
|
|
581
|
+
|
|
582
|
+
# Circular dependency.
|
|
583
|
+
|
|
584
|
+
new_dependencies = []
|
|
585
|
+
for dependency in dependencies:
|
|
586
|
+
if isinstance(dependency, PackageNamespaceVersionDependency):
|
|
587
|
+
# get the SubscriberPackageVersion id
|
|
588
|
+
key = f"{dependency.namespace}@{dependency.version}"
|
|
589
|
+
version_info = self.installed_packages.get(key)
|
|
590
|
+
if version_info:
|
|
591
|
+
new_dependencies.append(
|
|
592
|
+
PackageVersionIdDependency(
|
|
593
|
+
version_id=version_info[0].id,
|
|
594
|
+
package_name=dependency.package_name,
|
|
595
|
+
)
|
|
596
|
+
)
|
|
597
|
+
else:
|
|
598
|
+
raise DependencyResolutionError(
|
|
599
|
+
f"Could not find 04t id for package {key} in org {self.name}"
|
|
600
|
+
)
|
|
601
|
+
else:
|
|
602
|
+
new_dependencies.append(dependency)
|
|
603
|
+
|
|
604
|
+
return new_dependencies
|