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,242 @@
|
|
|
1
|
+
import click
|
|
2
|
+
|
|
3
|
+
from cumulusci.core.dependencies.dependencies import (
|
|
4
|
+
PackageNamespaceVersionDependency,
|
|
5
|
+
PackageVersionIdDependency,
|
|
6
|
+
)
|
|
7
|
+
from cumulusci.core.dependencies.resolvers import get_resolver_stack
|
|
8
|
+
from cumulusci.core.exceptions import CumulusCIException, TaskOptionsError
|
|
9
|
+
from cumulusci.core.utils import process_bool_arg
|
|
10
|
+
from cumulusci.salesforce_api.package_install import (
|
|
11
|
+
DEFAULT_PACKAGE_RETRY_OPTIONS,
|
|
12
|
+
PACKAGE_INSTALL_TASK_OPTIONS,
|
|
13
|
+
PackageInstallOptions,
|
|
14
|
+
SecurityType,
|
|
15
|
+
)
|
|
16
|
+
from cumulusci.tasks.salesforce.BaseSalesforceApiTask import BaseSalesforceApiTask
|
|
17
|
+
from cumulusci.vcs.bootstrap import find_previous_release
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class InstallPackageVersion(BaseSalesforceApiTask):
|
|
21
|
+
task_options = {
|
|
22
|
+
"name": {
|
|
23
|
+
"description": "The name of the package to install. Defaults to project__package__name_managed",
|
|
24
|
+
"required": False,
|
|
25
|
+
},
|
|
26
|
+
"namespace": {
|
|
27
|
+
"description": "The namespace of the package to install. Defaults to project__package__namespace",
|
|
28
|
+
"required": True,
|
|
29
|
+
},
|
|
30
|
+
"version": {
|
|
31
|
+
"description": 'The version of the package to install. "latest" and "latest_beta" can be used to trigger lookup via Github Releases on the repository.',
|
|
32
|
+
"required": True,
|
|
33
|
+
},
|
|
34
|
+
"version_number": {
|
|
35
|
+
"description": "If installing a package using an 04t version Id, display this version "
|
|
36
|
+
"number to the user and in logs. Has no effect otherwise."
|
|
37
|
+
},
|
|
38
|
+
"activateRSS": {
|
|
39
|
+
"description": "Deprecated. Use activate_remote_site_settings instead."
|
|
40
|
+
},
|
|
41
|
+
"retries": {"description": "Number of retries (default=5)"},
|
|
42
|
+
"retry_interval": {
|
|
43
|
+
"description": "Number of seconds to wait before the next retry (default=5),"
|
|
44
|
+
},
|
|
45
|
+
"retry_interval_add": {
|
|
46
|
+
"description": "Number of seconds to add before each retry (default=30),"
|
|
47
|
+
},
|
|
48
|
+
"interactive": {
|
|
49
|
+
"description": "If True, stop after resolving the package version and output the package Id that will be installed. Defaults to False."
|
|
50
|
+
},
|
|
51
|
+
"base_package_url_format": {
|
|
52
|
+
"description": "If `interactive` is set to True, display package Ids using a format string ({} will be replaced with the package Id)."
|
|
53
|
+
},
|
|
54
|
+
**PACKAGE_INSTALL_TASK_OPTIONS,
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
def _init_options(self, kwargs):
|
|
58
|
+
super()._init_options(kwargs)
|
|
59
|
+
|
|
60
|
+
if "namespace" not in self.options:
|
|
61
|
+
self.options["namespace"] = self.project_config.project__package__namespace
|
|
62
|
+
version = self.options.get("version")
|
|
63
|
+
|
|
64
|
+
# `name` is shown in the logs and in MetaDeploy
|
|
65
|
+
# Populate a reasonable default. Note that if we're deploying a different package
|
|
66
|
+
# than our own, we should not show the name of this repo's package.
|
|
67
|
+
if "name" not in self.options:
|
|
68
|
+
if isinstance(version, str) and version.startswith("04t"):
|
|
69
|
+
self.options["name"] = "Package"
|
|
70
|
+
elif (
|
|
71
|
+
self.options["namespace"]
|
|
72
|
+
== self.project_config.project__package__namespace
|
|
73
|
+
):
|
|
74
|
+
self.options["name"] = (
|
|
75
|
+
self.project_config.project__package__name_managed
|
|
76
|
+
or self.project_config.project__package__name
|
|
77
|
+
or self.options["namespace"]
|
|
78
|
+
)
|
|
79
|
+
else:
|
|
80
|
+
self.options["name"] = self.options["namespace"]
|
|
81
|
+
|
|
82
|
+
self.retry_options = DEFAULT_PACKAGE_RETRY_OPTIONS.copy()
|
|
83
|
+
if "retries" in self.options:
|
|
84
|
+
self.retry_options["retries"] = self.options["retries"]
|
|
85
|
+
if "retry_interval" in self.options:
|
|
86
|
+
self.retry_options["retry_interval"] = self.options["retry_interval"]
|
|
87
|
+
if "retry_interval_add" in self.options:
|
|
88
|
+
self.retry_options["retry_interval_add"] = self.options[
|
|
89
|
+
"retry_interval_add"
|
|
90
|
+
]
|
|
91
|
+
|
|
92
|
+
dependency = None
|
|
93
|
+
|
|
94
|
+
if version in ["latest", "latest_beta"]:
|
|
95
|
+
strategy = "include_beta" if version == "latest_beta" else "production"
|
|
96
|
+
vcs_service = self.project_config.repo_service
|
|
97
|
+
repo = vcs_service.get_repository(options=self.options)
|
|
98
|
+
|
|
99
|
+
dependency = vcs_service.dynamic_dependency_class(url=repo.clone_url)
|
|
100
|
+
dependency.resolve(
|
|
101
|
+
self.project_config, get_resolver_stack(self.project_config, strategy)
|
|
102
|
+
)
|
|
103
|
+
elif version == "previous":
|
|
104
|
+
vcs_service = self.project_config.repo_service
|
|
105
|
+
repo = vcs_service.get_repository(options=self.options)
|
|
106
|
+
|
|
107
|
+
release = find_previous_release(
|
|
108
|
+
repo,
|
|
109
|
+
self.project_config.project__git__prefix_release,
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
vcs_service = self.project_config.repo_service
|
|
113
|
+
dependency = vcs_service.dynamic_dependency_class(
|
|
114
|
+
url=repo.clone_url, tag=release.tag_name
|
|
115
|
+
)
|
|
116
|
+
dependency.resolve(
|
|
117
|
+
self.project_config,
|
|
118
|
+
get_resolver_stack(self.project_config, "production"),
|
|
119
|
+
)
|
|
120
|
+
elif isinstance(version, (float, int)):
|
|
121
|
+
self.logger.warning(
|
|
122
|
+
f"The `version` option is specified as a number ({version}). "
|
|
123
|
+
"Please specify as a quoted string to avoid ambiguous results."
|
|
124
|
+
)
|
|
125
|
+
self.options["version"] = str(version)
|
|
126
|
+
|
|
127
|
+
if dependency:
|
|
128
|
+
if dependency.package_dependency:
|
|
129
|
+
# Handle 2GP and 1GP releases in a backwards-compatible way.
|
|
130
|
+
if isinstance(
|
|
131
|
+
dependency.package_dependency, PackageNamespaceVersionDependency
|
|
132
|
+
):
|
|
133
|
+
self.options["version"] = dependency.package_dependency.version
|
|
134
|
+
self.options[
|
|
135
|
+
"version_id"
|
|
136
|
+
] = dependency.package_dependency.version_id
|
|
137
|
+
elif isinstance(
|
|
138
|
+
dependency.package_dependency, PackageVersionIdDependency
|
|
139
|
+
):
|
|
140
|
+
self.options["version"] = dependency.package_dependency.version_id
|
|
141
|
+
self.options[
|
|
142
|
+
"version_number"
|
|
143
|
+
] = dependency.package_dependency.version_number
|
|
144
|
+
else:
|
|
145
|
+
raise CumulusCIException(
|
|
146
|
+
f"The release for {version} does not identify a package version."
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
if "activateRSS" in self.options:
|
|
150
|
+
self.logger.warning(
|
|
151
|
+
"The activateRSS option is deprecated. Please use activate_remote_site_settings."
|
|
152
|
+
)
|
|
153
|
+
self.options["activate_remote_site_settings"] = self.options["activateRSS"]
|
|
154
|
+
del self.options["activateRSS"]
|
|
155
|
+
|
|
156
|
+
self.install_options = PackageInstallOptions.from_task_options(self.options)
|
|
157
|
+
self._check_for_tooling()
|
|
158
|
+
|
|
159
|
+
# Interactivity options
|
|
160
|
+
self.options["interactive"] = process_bool_arg(
|
|
161
|
+
self.options.get("interactive") or False
|
|
162
|
+
)
|
|
163
|
+
self.options["base_package_url_format"] = (
|
|
164
|
+
self.options.get("base_package_url_format") or "{}"
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
def _run_task(self):
|
|
168
|
+
version = self.options["version"]
|
|
169
|
+
|
|
170
|
+
if version.startswith("04t"):
|
|
171
|
+
dep = PackageVersionIdDependency(
|
|
172
|
+
version_id=version, package_name=self.options["name"]
|
|
173
|
+
)
|
|
174
|
+
if "version_number" in self.options:
|
|
175
|
+
dep.version_number = self.options["version_number"]
|
|
176
|
+
else:
|
|
177
|
+
dep = PackageNamespaceVersionDependency(
|
|
178
|
+
namespace=self.options["namespace"],
|
|
179
|
+
version=version,
|
|
180
|
+
package_name=self.options["name"],
|
|
181
|
+
version_id=self.options.get("version_id"),
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
if self.options.get("interactive", False):
|
|
185
|
+
if dep.version_id:
|
|
186
|
+
package_desc = self.options["base_package_url_format"].format(
|
|
187
|
+
dep.version_id
|
|
188
|
+
)
|
|
189
|
+
else:
|
|
190
|
+
package_desc = str(dep)
|
|
191
|
+
self.logger.info("Package to install: {}".format(package_desc))
|
|
192
|
+
if not click.confirm("Continue to install dependencies?", default=True):
|
|
193
|
+
raise CumulusCIException("Dependency installation was canceled.")
|
|
194
|
+
|
|
195
|
+
dep.install(
|
|
196
|
+
self.project_config,
|
|
197
|
+
self.org_config,
|
|
198
|
+
self.install_options,
|
|
199
|
+
self.retry_options,
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
self.org_config.reset_installed_packages()
|
|
203
|
+
|
|
204
|
+
def freeze(self, step):
|
|
205
|
+
if self.options["interactive"]:
|
|
206
|
+
raise CumulusCIException(
|
|
207
|
+
"update_dependencies cannot be frozen when `interactive` is True."
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
options = self.options.copy()
|
|
211
|
+
options["version"] = str(options["version"])
|
|
212
|
+
if "version_id" in options:
|
|
213
|
+
# This is used only in interactive mode.
|
|
214
|
+
del options["version_id"]
|
|
215
|
+
name = options.pop("name")
|
|
216
|
+
task_config = {"options": options, "checks": self.task_config.checks or []}
|
|
217
|
+
ui_step = {
|
|
218
|
+
"name": f"Install {name} {options.get('version_number') or options['version']}",
|
|
219
|
+
"kind": "managed",
|
|
220
|
+
"is_required": True,
|
|
221
|
+
}
|
|
222
|
+
ui_step.update(step.task_config.get("ui_options", {}))
|
|
223
|
+
ui_step.update(
|
|
224
|
+
{
|
|
225
|
+
"path": step.path,
|
|
226
|
+
"step_num": str(step.step_num),
|
|
227
|
+
"task_class": self.task_config.class_path,
|
|
228
|
+
"task_config": task_config,
|
|
229
|
+
"source": step.project_config.source.frozenspec,
|
|
230
|
+
}
|
|
231
|
+
)
|
|
232
|
+
return [ui_step]
|
|
233
|
+
|
|
234
|
+
def _check_for_tooling(self):
|
|
235
|
+
version = str(self.options.get("version"))
|
|
236
|
+
if (
|
|
237
|
+
version.startswith("04t")
|
|
238
|
+
and self.install_options.security_type is SecurityType.PUSH
|
|
239
|
+
):
|
|
240
|
+
raise TaskOptionsError(
|
|
241
|
+
"Cannot use security type 'PUSH' when installing using a 04t package version ID due to Tooling API limitations."
|
|
242
|
+
)
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
from typing import List
|
|
2
|
+
|
|
3
|
+
from simple_salesforce import format_soql
|
|
4
|
+
|
|
5
|
+
from cumulusci.core.exceptions import CumulusCIException, SalesforceException
|
|
6
|
+
from cumulusci.core.utils import process_list_arg
|
|
7
|
+
from cumulusci.tasks.salesforce import BaseSalesforceApiTask
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class CreateNetworkMemberGroups(BaseSalesforceApiTask):
|
|
11
|
+
"""
|
|
12
|
+
Creates NetworkMemberGroup for a Network (Experience Site) for Profiles and Permission Sets
|
|
13
|
+
that don't already have a corresponding NetworkMemberGroup.
|
|
14
|
+
|
|
15
|
+
Raises exceptions if records cannot be found:
|
|
16
|
+
- Network with Name network_name
|
|
17
|
+
- Profiles with Names in profile_names
|
|
18
|
+
- Permission Sets with Names in permission_set_names
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
task_options = {
|
|
22
|
+
"network_name": {
|
|
23
|
+
"description": (
|
|
24
|
+
"Name of Network to add NetworkMemberGroup children records."
|
|
25
|
+
),
|
|
26
|
+
"required": True,
|
|
27
|
+
},
|
|
28
|
+
"profile_names": {
|
|
29
|
+
"description": (
|
|
30
|
+
"List of Profile Names to add as NetworkMemberGroups "
|
|
31
|
+
"for this Network."
|
|
32
|
+
),
|
|
33
|
+
"required": False,
|
|
34
|
+
},
|
|
35
|
+
"permission_set_names": {
|
|
36
|
+
"description": (
|
|
37
|
+
"List of PermissionSet Names to add as NetworkMemberGroups "
|
|
38
|
+
"for this Network."
|
|
39
|
+
),
|
|
40
|
+
"required": False,
|
|
41
|
+
},
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
def _get_network_id(self, network_name: str) -> str:
|
|
45
|
+
"""
|
|
46
|
+
Returns Id of Network record with Name network_name.
|
|
47
|
+
Raises a SalesforceException if no Network is found.
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
networks = self.sf.query_all(
|
|
51
|
+
format_soql(
|
|
52
|
+
"SELECT Id FROM Network WHERE Name = {network_name} LIMIT 1",
|
|
53
|
+
network_name=network_name,
|
|
54
|
+
)
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
if not networks["records"]:
|
|
58
|
+
raise SalesforceException(
|
|
59
|
+
f'No Network record found with Name "{network_name}"'
|
|
60
|
+
)
|
|
61
|
+
self.logger.info(
|
|
62
|
+
f"Creating NetworkMemberGroup records for {network_name} Network:"
|
|
63
|
+
)
|
|
64
|
+
return networks["records"][0]["Id"]
|
|
65
|
+
|
|
66
|
+
def _get_network_member_group_parent_ids(self, network_id) -> set:
|
|
67
|
+
"""
|
|
68
|
+
Collect existing NetworkMemberGroup Parent IDs (associated Profile or Permission Set ID).
|
|
69
|
+
An excpetion is thrown trying to create a NetworkMemberGroup for a parent who already has a
|
|
70
|
+
record.
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
network_member_group_parent_ids = set()
|
|
74
|
+
for record in self.sf.query_all(
|
|
75
|
+
f"SELECT ParentId FROM NetworkMemberGroup WHERE NetworkId = '{network_id}'" # noqa: E501
|
|
76
|
+
)["records"]:
|
|
77
|
+
network_member_group_parent_ids.add(record["ParentId"])
|
|
78
|
+
return network_member_group_parent_ids
|
|
79
|
+
|
|
80
|
+
def _get_parent_ids_by_name(self, sobject_type: str, record_names: List[str]):
|
|
81
|
+
"""
|
|
82
|
+
Returns a Dict: Name --> ID of records with Name in record_names for
|
|
83
|
+
sObject_type. Dict value are None for all record_names that do not
|
|
84
|
+
have corresponding records.
|
|
85
|
+
"""
|
|
86
|
+
parent_ids_by_name = dict((name, None) for name in record_names)
|
|
87
|
+
|
|
88
|
+
if sobject_type == "PermissionSet":
|
|
89
|
+
field_key = "Label"
|
|
90
|
+
else:
|
|
91
|
+
field_key = "Name"
|
|
92
|
+
|
|
93
|
+
for record in self.sf.query_all(
|
|
94
|
+
"SELECT Id, {} FROM {} WHERE {} IN ('{}')".format(
|
|
95
|
+
field_key,
|
|
96
|
+
sobject_type,
|
|
97
|
+
field_key,
|
|
98
|
+
"','".join(record_names),
|
|
99
|
+
)
|
|
100
|
+
)["records"]:
|
|
101
|
+
record_name = record[field_key]
|
|
102
|
+
parent_ids_by_name[record_name] = record["Id"]
|
|
103
|
+
|
|
104
|
+
return parent_ids_by_name
|
|
105
|
+
|
|
106
|
+
def _process_parent(self, sobject_type, record_names) -> None:
|
|
107
|
+
"""
|
|
108
|
+
For a specific sobject_type and record_names, queries all Salesforce IDs
|
|
109
|
+
corresponding to records of SObjectType sobject_type with Name in
|
|
110
|
+
record_names. Then, tries to create NetworkMemberGroup for each
|
|
111
|
+
parent in record_names.
|
|
112
|
+
"""
|
|
113
|
+
|
|
114
|
+
if not record_names:
|
|
115
|
+
return
|
|
116
|
+
|
|
117
|
+
self.logger.info(f" {sobject_type}:")
|
|
118
|
+
|
|
119
|
+
# Collect Parent IDs by Name.
|
|
120
|
+
parent_ids_by_name = self._get_parent_ids_by_name(sobject_type, record_names)
|
|
121
|
+
|
|
122
|
+
# Create NetworkMemberGroup records.
|
|
123
|
+
for parent_name, parent_id in parent_ids_by_name.items():
|
|
124
|
+
self._create_network_member_group(sobject_type, parent_name, parent_id)
|
|
125
|
+
|
|
126
|
+
def _create_network_member_group(
|
|
127
|
+
self, sobject_type, parent_name, parent_id
|
|
128
|
+
) -> None:
|
|
129
|
+
"""
|
|
130
|
+
Processes and logs creating a NetworkMemberGroup for a specific parent.
|
|
131
|
+
|
|
132
|
+
Outcomes:
|
|
133
|
+
- Raises a CumulusCIException if record_id is None meaning
|
|
134
|
+
no corresponding record was found in _get_parent_ids_by_name.
|
|
135
|
+
- Logs a warning that a NetworkMemberGroup already exists is parent_id
|
|
136
|
+
is in self._parent_ids.
|
|
137
|
+
- Creates a NetworkMemberGroup for parent_id and logs the result.
|
|
138
|
+
"""
|
|
139
|
+
|
|
140
|
+
# Assert a Parent was found for each Name.
|
|
141
|
+
if not parent_id:
|
|
142
|
+
raise CumulusCIException(
|
|
143
|
+
f'No {sobject_type} record found with Name "{parent_name}"'
|
|
144
|
+
)
|
|
145
|
+
# If the Profile/Permission set already exists for a NetworkMemberGroup -
|
|
146
|
+
if parent_id in self._parent_ids:
|
|
147
|
+
self.logger.warning(f' Already exists for "{parent_name}"')
|
|
148
|
+
else:
|
|
149
|
+
insert_response = self.sf.NetworkMemberGroup.create(
|
|
150
|
+
{"NetworkId": self._network_id, "ParentId": parent_id}
|
|
151
|
+
)
|
|
152
|
+
if insert_response.get("success") is True:
|
|
153
|
+
self.logger.info(f' "{parent_name}"')
|
|
154
|
+
else:
|
|
155
|
+
# It might be impossible to get to this state.
|
|
156
|
+
# If there's a query exception, it gets thrown before this is called.
|
|
157
|
+
raise SalesforceException(
|
|
158
|
+
f'Error creating NetworkMemberGroup for Network "{self._network_id}" for parent {sobject_type} "{parent_name}" {parent_id}. Errors: {", ".join(insert_response.get("errors") or [])}'
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
def _run_task(self):
|
|
162
|
+
"""
|
|
163
|
+
Gets required information then tries to create NetworkMemberGroups for
|
|
164
|
+
Profiles and Permission Sets cooresponding to profile_names and
|
|
165
|
+
permission_set_names respectively.
|
|
166
|
+
"""
|
|
167
|
+
|
|
168
|
+
self._network_id = self._get_network_id(self.options["network_name"])
|
|
169
|
+
self._parent_ids = self._get_network_member_group_parent_ids(self._network_id)
|
|
170
|
+
|
|
171
|
+
# Create NetworkMemberGroup records.
|
|
172
|
+
for sobject_type, record_names in {
|
|
173
|
+
"Profile": process_list_arg(self.options.get("profile_names") or []),
|
|
174
|
+
"PermissionSet": process_list_arg(
|
|
175
|
+
self.options.get("permission_set_names") or []
|
|
176
|
+
),
|
|
177
|
+
}.items():
|
|
178
|
+
self._process_parent(sobject_type, record_names)
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
import requests
|
|
5
|
+
|
|
6
|
+
from cumulusci.core.config import TaskConfig
|
|
7
|
+
from cumulusci.core.exceptions import CumulusCIException
|
|
8
|
+
from cumulusci.core.utils import process_list_arg
|
|
9
|
+
from cumulusci.salesforce_api.metadata import ApiListMetadata
|
|
10
|
+
from cumulusci.tasks.salesforce import (
|
|
11
|
+
BaseRetrieveMetadata,
|
|
12
|
+
BaseSalesforceApiTask,
|
|
13
|
+
DescribeMetadataTypes,
|
|
14
|
+
)
|
|
15
|
+
from cumulusci.tasks.salesforce.sourcetracking import ListChanges, retrieve_components
|
|
16
|
+
|
|
17
|
+
nl = "\n"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ListNonSourceTrackable(BaseSalesforceApiTask):
|
|
21
|
+
|
|
22
|
+
task_options = {
|
|
23
|
+
"api_version": {
|
|
24
|
+
"description": "Override the API version used to list metadatatypes",
|
|
25
|
+
},
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
def _init_task(self):
|
|
29
|
+
super()._init_task()
|
|
30
|
+
if "api_version" not in self.options:
|
|
31
|
+
self.options[
|
|
32
|
+
"api_version"
|
|
33
|
+
] = self.project_config.project__package__api_version
|
|
34
|
+
|
|
35
|
+
def get_types_details(self, api_version):
|
|
36
|
+
# The Metadata coverage report: https://developer.salesforce.com/docs/metadata-coverage/{version} is created from
|
|
37
|
+
# the below URL. (So the api versions are allowed based on those report ranges)
|
|
38
|
+
url = f"https://dx-extended-coverage.my.salesforce-sites.com/services/apexrest/report?version={api_version}"
|
|
39
|
+
response = requests.get(url)
|
|
40
|
+
if response.status_code == 200:
|
|
41
|
+
json_response = response.json()
|
|
42
|
+
return json_response
|
|
43
|
+
else:
|
|
44
|
+
raise CumulusCIException(
|
|
45
|
+
f"Failed to retrieve response with status code {response.status_code}"
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
def _run_task(self):
|
|
49
|
+
metadatatypes_details = self.get_types_details(self.options["api_version"])[
|
|
50
|
+
"types"
|
|
51
|
+
]
|
|
52
|
+
all_nonsource_types = []
|
|
53
|
+
for md_type, details in metadatatypes_details.items():
|
|
54
|
+
if not details["channels"]:
|
|
55
|
+
raise CumulusCIException(
|
|
56
|
+
f"Api version {self.options['api_version']} not supported"
|
|
57
|
+
)
|
|
58
|
+
if (
|
|
59
|
+
details["channels"]["sourceTracking"] is False
|
|
60
|
+
and details["channels"]["metadataApi"] is True
|
|
61
|
+
):
|
|
62
|
+
all_nonsource_types.append(md_type)
|
|
63
|
+
|
|
64
|
+
types_supported = DescribeMetadataTypes(
|
|
65
|
+
org_config=self.org_config,
|
|
66
|
+
project_config=self.project_config,
|
|
67
|
+
task_config=self.task_config,
|
|
68
|
+
)._run_task()
|
|
69
|
+
|
|
70
|
+
self.return_values = []
|
|
71
|
+
for md_type in all_nonsource_types:
|
|
72
|
+
if md_type in types_supported:
|
|
73
|
+
self.return_values.append(md_type)
|
|
74
|
+
|
|
75
|
+
if self.return_values:
|
|
76
|
+
self.return_values.sort()
|
|
77
|
+
|
|
78
|
+
self.logger.info(
|
|
79
|
+
f"Non source trackable Metadata types supported by org: \n{self.return_values}"
|
|
80
|
+
)
|
|
81
|
+
return self.return_values
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class ListComponents(BaseSalesforceApiTask):
|
|
85
|
+
api_class = ApiListMetadata
|
|
86
|
+
task_options = {
|
|
87
|
+
"api_version": {
|
|
88
|
+
"description": "Override the API version used to list metadatatypes",
|
|
89
|
+
},
|
|
90
|
+
"metadata_types": {"description": "A comma-separated list of metadata types."},
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
def _init_task(self):
|
|
94
|
+
super()._init_task()
|
|
95
|
+
|
|
96
|
+
def _init_options(self, kwargs):
|
|
97
|
+
super(ListComponents, self)._init_options(kwargs)
|
|
98
|
+
if "api_version" not in self.options:
|
|
99
|
+
self.options[
|
|
100
|
+
"api_version"
|
|
101
|
+
] = self.project_config.project__package__api_version
|
|
102
|
+
if "metadata_types" not in self.options:
|
|
103
|
+
self.options["metadata_types"] = ListNonSourceTrackable(
|
|
104
|
+
org_config=self.org_config,
|
|
105
|
+
project_config=self.project_config,
|
|
106
|
+
task_config=TaskConfig(
|
|
107
|
+
{"options": {"api_version": self.options["api_version"]}}
|
|
108
|
+
),
|
|
109
|
+
)._run_task()
|
|
110
|
+
else:
|
|
111
|
+
self.options["metadata_types"] = process_list_arg(
|
|
112
|
+
self.options.get("metadata_types")
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
def _get_components(self):
|
|
116
|
+
list_components = []
|
|
117
|
+
for md_type in self.options["metadata_types"]:
|
|
118
|
+
api_object = self.api_class(
|
|
119
|
+
self, metadata_type=md_type, as_of_version=self.options["api_version"]
|
|
120
|
+
)
|
|
121
|
+
components = api_object()
|
|
122
|
+
for temp in components[md_type]:
|
|
123
|
+
cmp = {
|
|
124
|
+
"MemberType": md_type,
|
|
125
|
+
"MemberName": temp["fullName"],
|
|
126
|
+
"lastModifiedByName": temp["lastModifiedByName"],
|
|
127
|
+
"lastModifiedDate": temp["lastModifiedDate"],
|
|
128
|
+
}
|
|
129
|
+
if cmp not in list_components:
|
|
130
|
+
list_components.append(cmp)
|
|
131
|
+
return list_components
|
|
132
|
+
|
|
133
|
+
def _run_task(self):
|
|
134
|
+
self.return_values = self._get_components()
|
|
135
|
+
self.logger.info(
|
|
136
|
+
f"Found {len(self.return_values)} non source trackable components in the org for the given types."
|
|
137
|
+
)
|
|
138
|
+
for change in self.return_values:
|
|
139
|
+
self.logger.info("{MemberType}: {MemberName}".format(**change))
|
|
140
|
+
return self.return_values
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
retrieve_components_task_options = ListComponents.task_options.copy()
|
|
144
|
+
retrieve_components_task_options["path"] = {
|
|
145
|
+
"description": "The path to write the retrieved metadata",
|
|
146
|
+
"required": False,
|
|
147
|
+
}
|
|
148
|
+
retrieve_components_task_options["include"] = {
|
|
149
|
+
"description": "Components will be included if one of these names"
|
|
150
|
+
"is part of either the metadata type or name. "
|
|
151
|
+
"Example: ``-o include CustomField,Admin`` matches both "
|
|
152
|
+
"``CustomField: Favorite_Color__c`` and ``Profile: Admin``"
|
|
153
|
+
}
|
|
154
|
+
retrieve_components_task_options["exclude"] = {
|
|
155
|
+
"description": "Exclude components matching this name."
|
|
156
|
+
}
|
|
157
|
+
retrieve_components_task_options[
|
|
158
|
+
"namespace_tokenize"
|
|
159
|
+
] = BaseRetrieveMetadata.task_options["namespace_tokenize"]
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
class RetrieveComponents(ListComponents, BaseSalesforceApiTask):
|
|
163
|
+
task_options = retrieve_components_task_options
|
|
164
|
+
|
|
165
|
+
def _init_options(self, kwargs):
|
|
166
|
+
super(RetrieveComponents, self)._init_options(kwargs)
|
|
167
|
+
self.options["include"] = process_list_arg(self.options.get("include", []))
|
|
168
|
+
self.options["exclude"] = process_list_arg(self.options.get("exclude", []))
|
|
169
|
+
self._include = self.options["include"]
|
|
170
|
+
self._exclude = self.options["exclude"]
|
|
171
|
+
self._exclude.extend(self.project_config.project__source__ignore or [])
|
|
172
|
+
|
|
173
|
+
package_directories = []
|
|
174
|
+
default_package_directory = None
|
|
175
|
+
if os.path.exists("sfdx-project.json"):
|
|
176
|
+
with open("sfdx-project.json", "r", encoding="utf-8") as f:
|
|
177
|
+
sfdx_project = json.load(f)
|
|
178
|
+
for package_directory in sfdx_project.get("packageDirectories", []):
|
|
179
|
+
package_directories.append(package_directory["path"])
|
|
180
|
+
if package_directory.get("default"):
|
|
181
|
+
default_package_directory = package_directory["path"]
|
|
182
|
+
|
|
183
|
+
path = self.options.get("path")
|
|
184
|
+
if path is None:
|
|
185
|
+
# set default path to src for mdapi format,
|
|
186
|
+
# or the default package directory from sfdx-project.json for dx format
|
|
187
|
+
if (
|
|
188
|
+
default_package_directory
|
|
189
|
+
and self.project_config.project__source_format == "sfdx"
|
|
190
|
+
):
|
|
191
|
+
path = default_package_directory
|
|
192
|
+
md_format = False
|
|
193
|
+
else:
|
|
194
|
+
path = "src"
|
|
195
|
+
md_format = True
|
|
196
|
+
else:
|
|
197
|
+
md_format = path not in package_directories
|
|
198
|
+
self.md_format = md_format
|
|
199
|
+
self.options["path"] = path
|
|
200
|
+
|
|
201
|
+
def _run_task(self):
|
|
202
|
+
components = self._get_components()
|
|
203
|
+
filtered, ignored = ListChanges._filter_changes(self, components)
|
|
204
|
+
if not filtered:
|
|
205
|
+
self.logger.info("No components to retrieve")
|
|
206
|
+
return
|
|
207
|
+
for cmp in filtered:
|
|
208
|
+
self.logger.info("{MemberType}: {MemberName}".format(**cmp))
|
|
209
|
+
|
|
210
|
+
target = os.path.realpath(self.options["path"])
|
|
211
|
+
package_xml_opts = {}
|
|
212
|
+
if self.options["path"] == "src":
|
|
213
|
+
package_xml_opts.update(
|
|
214
|
+
{
|
|
215
|
+
"package_name": self.project_config.project__package__name,
|
|
216
|
+
"install_class": self.project_config.project__package__install_class,
|
|
217
|
+
"uninstall_class": self.project_config.project__package__uninstall_class,
|
|
218
|
+
}
|
|
219
|
+
)
|
|
220
|
+
retrieve_components(
|
|
221
|
+
filtered,
|
|
222
|
+
self.org_config,
|
|
223
|
+
target,
|
|
224
|
+
md_format=self.md_format,
|
|
225
|
+
namespace_tokenize=self.options.get("namespace_tokenize"),
|
|
226
|
+
api_version=self.options["api_version"],
|
|
227
|
+
extra_package_xml_opts=package_xml_opts,
|
|
228
|
+
)
|