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,339 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from collections import defaultdict
|
|
3
|
+
|
|
4
|
+
from packaging import version
|
|
5
|
+
|
|
6
|
+
from cumulusci.core.exceptions import CumulusCIException, TaskOptionsError
|
|
7
|
+
from cumulusci.core.utils import process_bool_arg, process_list_arg
|
|
8
|
+
from cumulusci.tasks.metadata_etl import (
|
|
9
|
+
MetadataOperation,
|
|
10
|
+
MetadataSingleEntityTransformTask,
|
|
11
|
+
)
|
|
12
|
+
from cumulusci.tasks.salesforce import BaseSalesforceApiTask
|
|
13
|
+
from cumulusci.utils import CUMULUSCI_PATH
|
|
14
|
+
from cumulusci.utils.xml import metadata_tree
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class ProfileGrantAllAccess(MetadataSingleEntityTransformTask, BaseSalesforceApiTask):
|
|
18
|
+
name = "ProfileGrantAllAccess"
|
|
19
|
+
entity = "Profile"
|
|
20
|
+
|
|
21
|
+
task_options = {
|
|
22
|
+
"package_xml": {
|
|
23
|
+
"description": "Override the default package.xml file for retrieving the Admin.profile and all objects and classes "
|
|
24
|
+
"that need to be included by providing a path to your custom package.xml"
|
|
25
|
+
},
|
|
26
|
+
"record_types": {
|
|
27
|
+
"description": "A list of dictionaries containing the required key `record_type` with a value specifying "
|
|
28
|
+
"the record type in format <object>.<developer_name>. Record type names can use the token strings {managed} "
|
|
29
|
+
"and {namespaced_org} for namespace prefix injection as needed. By default, all listed record types will be set "
|
|
30
|
+
"to visible and not default. Use the additional keys `visible`, `default`, and `person_account_default` set to "
|
|
31
|
+
"true/false to override. "
|
|
32
|
+
"Page Layout Support: If you are using the Page Layouts feature, you can specify the `page_layout` key with the "
|
|
33
|
+
"layout name to use for the record type. If not specified, the default page layout will be used. "
|
|
34
|
+
"NOTE: Setting record_types is only supported in cumulusci.yml, command line override is not supported."
|
|
35
|
+
},
|
|
36
|
+
"managed": {
|
|
37
|
+
"description": "If True, uses the namespace prefix where appropriate. Use if running against an org with the managed package "
|
|
38
|
+
"installed. Defaults to False"
|
|
39
|
+
},
|
|
40
|
+
"namespaced_org": {
|
|
41
|
+
"description": "If True, attempts to prefix all unmanaged metadata references with the namespace prefix for deployment to the "
|
|
42
|
+
"packaging org or a namespaced scratch org. Defaults to False"
|
|
43
|
+
},
|
|
44
|
+
"namespace_inject": {
|
|
45
|
+
"description": "If set, the namespace tokens in files and filenames are replaced with the namespace's prefix. "
|
|
46
|
+
"Defaults to project__package__namespace"
|
|
47
|
+
},
|
|
48
|
+
"profile_name": {
|
|
49
|
+
"description": "Name of the Profile to target for updates (deprecated; use api_names to target multiple profiles).",
|
|
50
|
+
"default": "Admin",
|
|
51
|
+
},
|
|
52
|
+
"include_packaged_objects": {
|
|
53
|
+
"description": "Automatically include objects from all installed managed packages. "
|
|
54
|
+
"Defaults to True in projects that require CumulusCI 3.9.0 and greater that don't use a custom package.xml, otherwise False."
|
|
55
|
+
},
|
|
56
|
+
"api_names": {"description": "List of API names of Profiles to affect"},
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
def _init_options(self, kwargs):
|
|
60
|
+
super(ProfileGrantAllAccess, self)._init_options(kwargs)
|
|
61
|
+
|
|
62
|
+
self.options["namespace_inject"] = self.options.get(
|
|
63
|
+
"namespace_inject", self.project_config.project__package__namespace
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
# We enable new functionality to extend the package.xml to packaged objects
|
|
67
|
+
# by default only if we meet specific requirements: the project has to require
|
|
68
|
+
# CumulusCI >= 3.9.0 (i.e., creation date or opt-in after release), and it must
|
|
69
|
+
# not be using a custom `package.xml`
|
|
70
|
+
min_cci_version = self.project_config.minimum_cumulusci_version
|
|
71
|
+
if min_cci_version and "package_xml" not in self.options:
|
|
72
|
+
parsed_version = version.parse(min_cci_version)
|
|
73
|
+
default_packages_arg = parsed_version >= version.parse("3.9.0")
|
|
74
|
+
else:
|
|
75
|
+
default_packages_arg = False
|
|
76
|
+
|
|
77
|
+
self.options["include_packaged_objects"] = process_bool_arg(
|
|
78
|
+
self.options.get("include_packaged_objects", default_packages_arg)
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
# Build the api_names list, taking into account legacy behavior.
|
|
82
|
+
# If we're using a custom package.xml, we will union the api_names list with
|
|
83
|
+
# any Profiles specified there.
|
|
84
|
+
self.api_names = set(process_list_arg(self.options.get("api_names") or []))
|
|
85
|
+
if "profile_name" in self.options:
|
|
86
|
+
self.api_names.add(self.options["profile_name"])
|
|
87
|
+
if not self.api_names and "package_xml" not in self.options:
|
|
88
|
+
self.api_names.add(
|
|
89
|
+
"Admin"
|
|
90
|
+
) # Don't add a default if using custom package.xml
|
|
91
|
+
|
|
92
|
+
if "package_xml" in self.options:
|
|
93
|
+
self.package_xml_path = self.options["package_xml"]
|
|
94
|
+
else:
|
|
95
|
+
self.package_xml_path = os.path.join(
|
|
96
|
+
CUMULUSCI_PATH, "cumulusci", "files", "admin_profile.xml"
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
if self.org_config is not None:
|
|
100
|
+
# Set up namespace prefix strings.
|
|
101
|
+
# We can only do this if we actually have an org_config;
|
|
102
|
+
# i.e. not while freezing steps for metadeploy
|
|
103
|
+
namespace = self.options["namespace_inject"]
|
|
104
|
+
namespace_prefix = f"{namespace}__" if namespace else ""
|
|
105
|
+
self.namespace_prefixes = {
|
|
106
|
+
"managed": namespace_prefix if self.options["managed"] else "",
|
|
107
|
+
"namespaced_org": namespace_prefix
|
|
108
|
+
if self.options["namespaced_org"]
|
|
109
|
+
else "",
|
|
110
|
+
}
|
|
111
|
+
self.api_names = {self._inject_namespace(x) for x in self.api_names}
|
|
112
|
+
|
|
113
|
+
def freeze(self, step):
|
|
114
|
+
# Preserve behavior from when we subclassed Deploy.
|
|
115
|
+
|
|
116
|
+
steps = super().freeze(step)
|
|
117
|
+
for step in steps:
|
|
118
|
+
if step["kind"] == "other":
|
|
119
|
+
step["kind"] = "metadata"
|
|
120
|
+
return steps
|
|
121
|
+
|
|
122
|
+
def _generate_package_xml(self, operation):
|
|
123
|
+
if operation is MetadataOperation.RETRIEVE:
|
|
124
|
+
with open(self.package_xml_path, "r", encoding="utf-8") as f:
|
|
125
|
+
package_xml_content = f.read()
|
|
126
|
+
|
|
127
|
+
package_xml_content = package_xml_content.format(**self.namespace_prefixes)
|
|
128
|
+
|
|
129
|
+
# We need to rewrite the package.xml for one or two reasons.
|
|
130
|
+
# Either we are using packaged-object expansion, or we're using
|
|
131
|
+
# a package.xml and need to substitute in profile API names.
|
|
132
|
+
|
|
133
|
+
# Convert to bytes because stored `package.xml`s typically have an encoding declaration,
|
|
134
|
+
# which `fromstring()` doesn't like.
|
|
135
|
+
package_xml = metadata_tree.fromstring(package_xml_content.encode("utf-8"))
|
|
136
|
+
|
|
137
|
+
if self.options["include_packaged_objects"]:
|
|
138
|
+
self._expand_package_xml(package_xml)
|
|
139
|
+
|
|
140
|
+
self._expand_profile_members(package_xml)
|
|
141
|
+
|
|
142
|
+
package_xml_content = package_xml.tostring(xml_declaration=True)
|
|
143
|
+
|
|
144
|
+
return package_xml_content
|
|
145
|
+
else:
|
|
146
|
+
return super()._generate_package_xml(operation)
|
|
147
|
+
|
|
148
|
+
def _expand_profile_members(self, package_xml):
|
|
149
|
+
profile_names = package_xml.find("types", name="Profile")
|
|
150
|
+
if not profile_names:
|
|
151
|
+
profile_names = package_xml.append("types")
|
|
152
|
+
profile_names.append("name", "Profile")
|
|
153
|
+
|
|
154
|
+
listed_api_names = {p.text for p in profile_names.findall("members")}
|
|
155
|
+
|
|
156
|
+
for profile in self.api_names:
|
|
157
|
+
if profile not in listed_api_names:
|
|
158
|
+
profile_names.append("members", text=profile)
|
|
159
|
+
|
|
160
|
+
self.api_names.update(listed_api_names)
|
|
161
|
+
|
|
162
|
+
def _expand_package_xml(self, package_xml):
|
|
163
|
+
# Query the target org for all namespaced objects
|
|
164
|
+
# Add these entities to the package.xml
|
|
165
|
+
|
|
166
|
+
results = self.tooling.query_all(
|
|
167
|
+
"SELECT DeveloperName, NamespacePrefix FROM CustomObject WHERE ManageableState != 'unmanaged'"
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
custom_objects = package_xml.find("types", name="CustomObject")
|
|
171
|
+
if not custom_objects:
|
|
172
|
+
raise CumulusCIException(
|
|
173
|
+
"Unable to add packaged objects to package.xml because it does not contain a <types> tag of type CustomObject."
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
for record in results.get("records", []):
|
|
177
|
+
custom_objects.append(
|
|
178
|
+
"members",
|
|
179
|
+
text=f"{record['NamespacePrefix']}__{record['DeveloperName']}__c",
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
self._expand_package_xml_objects(package_xml)
|
|
183
|
+
|
|
184
|
+
def _expand_package_xml_objects(self, package_xml):
|
|
185
|
+
# Check for any record types specified in the options, but missing from the package.xml
|
|
186
|
+
# Add these entities to the package.xml
|
|
187
|
+
|
|
188
|
+
custom_objects = package_xml.find("types", name="CustomObject")
|
|
189
|
+
|
|
190
|
+
# Append custom objects if record types are present but missing from package.xml
|
|
191
|
+
record_types = self.options.get("record_types") or []
|
|
192
|
+
rt_objects = {rt["record_type"].split(".")[0] for rt in record_types}
|
|
193
|
+
listed_custom_objects = {c.text for c in custom_objects.findall("members")}
|
|
194
|
+
|
|
195
|
+
for rt in rt_objects:
|
|
196
|
+
if rt not in listed_custom_objects:
|
|
197
|
+
self.logger.info('Adding "{}" to package.xml'.format(rt))
|
|
198
|
+
custom_objects.append(
|
|
199
|
+
"members",
|
|
200
|
+
text=rt,
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
def _transform_entity(self, tree, api_name):
|
|
204
|
+
# Custom applications
|
|
205
|
+
self._set_elements_visible(tree, "applicationVisibilities", "visible")
|
|
206
|
+
# Apex classes
|
|
207
|
+
self._set_elements_visible(tree, "classAccesses", "enabled")
|
|
208
|
+
# Fields
|
|
209
|
+
self._set_elements_visible(tree, "fieldPermissions", "editable")
|
|
210
|
+
self._set_elements_visible(tree, "fieldPermissions", "readable")
|
|
211
|
+
# Visualforce pages
|
|
212
|
+
self._set_elements_visible(tree, "pageAccesses", "enabled")
|
|
213
|
+
# Custom tabs
|
|
214
|
+
self._set_elements_visible(
|
|
215
|
+
tree,
|
|
216
|
+
"tabVisibilities",
|
|
217
|
+
"visibility",
|
|
218
|
+
false_value="Hidden",
|
|
219
|
+
true_value="DefaultOn",
|
|
220
|
+
)
|
|
221
|
+
# Record Types
|
|
222
|
+
self._set_record_types(tree, api_name)
|
|
223
|
+
|
|
224
|
+
return tree
|
|
225
|
+
|
|
226
|
+
def _set_elements_visible(
|
|
227
|
+
self, tree, outer_tag, inner_tag, false_value="false", true_value="true"
|
|
228
|
+
):
|
|
229
|
+
for elem in tree.findall(outer_tag, **{inner_tag: false_value}):
|
|
230
|
+
elem.find(inner_tag).text = true_value
|
|
231
|
+
|
|
232
|
+
def _strip_namespace_from_record_type(self, record_type):
|
|
233
|
+
"""Strip namespace prefix from record type string.
|
|
234
|
+
|
|
235
|
+
Converts 'namespace__Object__c.namespace__RecordType' to 'Object__c.RecordType'
|
|
236
|
+
"""
|
|
237
|
+
if not self.options.get("namespace_inject"):
|
|
238
|
+
return record_type
|
|
239
|
+
|
|
240
|
+
namespace = self.options["namespace_inject"]
|
|
241
|
+
namespace_prefix = f"{namespace}__"
|
|
242
|
+
|
|
243
|
+
# Split on the dot to handle object and record type separately
|
|
244
|
+
parts = record_type.split(".", 1)
|
|
245
|
+
if len(parts) != 2:
|
|
246
|
+
return record_type
|
|
247
|
+
|
|
248
|
+
object_name, record_type_name = parts
|
|
249
|
+
|
|
250
|
+
# Strip namespace prefix from both object and record type if present
|
|
251
|
+
if object_name.startswith(namespace_prefix):
|
|
252
|
+
object_name = object_name[len(namespace_prefix):]
|
|
253
|
+
if record_type_name.startswith(namespace_prefix):
|
|
254
|
+
record_type_name = record_type_name[len(namespace_prefix):]
|
|
255
|
+
|
|
256
|
+
return f"{object_name}.{record_type_name}"
|
|
257
|
+
|
|
258
|
+
def _set_record_types(self, tree, api_name):
|
|
259
|
+
# Do namespace injection
|
|
260
|
+
record_types = self.options.get("record_types") or []
|
|
261
|
+
for rt in record_types:
|
|
262
|
+
rt["record_type"] = rt["record_type"].format(**self.namespace_prefixes)
|
|
263
|
+
|
|
264
|
+
# If defaults are specified, clear any pre-existing defaults
|
|
265
|
+
# that apply to the same object
|
|
266
|
+
defaults = {
|
|
267
|
+
"default": "default",
|
|
268
|
+
"person_account_default": "personAccountDefault",
|
|
269
|
+
}
|
|
270
|
+
objects_with_defaults = defaultdict(set)
|
|
271
|
+
|
|
272
|
+
for option, default_element in defaults.items():
|
|
273
|
+
for rt in record_types:
|
|
274
|
+
if option in rt:
|
|
275
|
+
objects_with_defaults[option].add(rt["record_type"].split(".")[0])
|
|
276
|
+
|
|
277
|
+
for elem in tree.findall("recordTypeVisibilities"):
|
|
278
|
+
if (
|
|
279
|
+
elem.find(default_element)
|
|
280
|
+
and elem.recordType.text.split(".")[0]
|
|
281
|
+
in objects_with_defaults[option]
|
|
282
|
+
):
|
|
283
|
+
elem.find(default_element).text = "false"
|
|
284
|
+
|
|
285
|
+
# Set recordTypeVisibilities
|
|
286
|
+
for rt in record_types:
|
|
287
|
+
# Look for the recordTypeVisibilities element
|
|
288
|
+
# First try with the original record type
|
|
289
|
+
elem = tree.find("recordTypeVisibilities", recordType=rt["record_type"])
|
|
290
|
+
|
|
291
|
+
# If not found and we're in a namespaced org, try with namespace stripped
|
|
292
|
+
# (since Salesforce may return without namespace in namespaced orgs)
|
|
293
|
+
if elem is None and self.options.get("namespaced_org"):
|
|
294
|
+
record_type_without_namespace = self._strip_namespace_from_record_type(rt["record_type"])
|
|
295
|
+
elem = tree.find("recordTypeVisibilities", recordType=record_type_without_namespace)
|
|
296
|
+
|
|
297
|
+
if elem is None:
|
|
298
|
+
raise TaskOptionsError(
|
|
299
|
+
f"Record Type {rt['record_type']} (or {record_type_without_namespace}) not found in retrieved {api_name}.profile"
|
|
300
|
+
)
|
|
301
|
+
elif elem is None:
|
|
302
|
+
raise TaskOptionsError(
|
|
303
|
+
f"Record Type {rt['record_type']} not found in retrieved {api_name}.profile"
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
# Set visible
|
|
307
|
+
elem.visible.text = str(rt.get("visible", "true")).lower()
|
|
308
|
+
|
|
309
|
+
# Set default
|
|
310
|
+
elem.default.text = str(rt.get("default", "false")).lower()
|
|
311
|
+
|
|
312
|
+
# Set person account default if element exists
|
|
313
|
+
pa_default = elem.find("personAccountDefault")
|
|
314
|
+
if pa_default is not None:
|
|
315
|
+
pa_default.text = str(rt.get("person_account_default", "false")).lower()
|
|
316
|
+
|
|
317
|
+
# Set page layout defaults for record types
|
|
318
|
+
for rt in record_types:
|
|
319
|
+
# We need it to look like this:
|
|
320
|
+
# <layoutAssignments>
|
|
321
|
+
# <layout>{page_layout}</layout>
|
|
322
|
+
# <recordType>{record_type}</recordType>
|
|
323
|
+
# </layoutAssignments>
|
|
324
|
+
layout_option = rt.get("page_layout", None)
|
|
325
|
+
if layout_option:
|
|
326
|
+
# Look for page layout definitions in the record type
|
|
327
|
+
found_layout = False
|
|
328
|
+
for elem in tree.findall("layoutAssignments"):
|
|
329
|
+
if elem.find("recordType").text == rt["record_type"]:
|
|
330
|
+
elem.layout.text = layout_option
|
|
331
|
+
found_layout = True
|
|
332
|
+
|
|
333
|
+
if not found_layout:
|
|
334
|
+
assignment = tree.append(tag="layoutAssignments")
|
|
335
|
+
assignment.append(tag="recordType", text=rt["record_type"])
|
|
336
|
+
assignment.append(tag="layout", text=layout_option)
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
UpdateAdminProfile = UpdateProfile = ProfileGrantAllAccess
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
3
|
+
from cumulusci.cli.ui import CliTable
|
|
4
|
+
from cumulusci.core.exceptions import CumulusCIException
|
|
5
|
+
from cumulusci.core.utils import process_list_arg
|
|
6
|
+
from cumulusci.tasks.salesforce import BaseSalesforceApiTask
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class AssignPermissionSets(BaseSalesforceApiTask):
|
|
10
|
+
task_docs = """
|
|
11
|
+
Assigns Permission Sets whose Names are in ``api_names`` to either the default org user or the user whose Alias is ``user_alias``. This task skips assigning Permission Sets that are already assigned.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
task_options = {
|
|
15
|
+
"api_names": {
|
|
16
|
+
"description": "API Names of desired Permission Sets, separated by commas.",
|
|
17
|
+
"required": True,
|
|
18
|
+
},
|
|
19
|
+
"user_alias": {
|
|
20
|
+
"description": "Target user aliases, separated by commas. Defaults to the current running user."
|
|
21
|
+
},
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
permission_name = "PermissionSet"
|
|
25
|
+
permission_name_field = "Name"
|
|
26
|
+
permission_label = "Permission Set"
|
|
27
|
+
assignment_name = "PermissionSetAssignment"
|
|
28
|
+
assignment_lookup = "PermissionSetId"
|
|
29
|
+
assignment_child_relationship = "PermissionSetAssignments"
|
|
30
|
+
|
|
31
|
+
def _init_options(self, kwargs):
|
|
32
|
+
super()._init_options(kwargs)
|
|
33
|
+
|
|
34
|
+
self.options["api_names"] = process_list_arg(self.options["api_names"])
|
|
35
|
+
self.options["user_alias"] = process_list_arg(
|
|
36
|
+
self.options.get("user_alias") or []
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
def _run_task(self):
|
|
40
|
+
users = self._query_existing_assignments()
|
|
41
|
+
users_assigned_perms = {
|
|
42
|
+
user["Id"]: self._get_assigned_perms(user) for user in users
|
|
43
|
+
}
|
|
44
|
+
perms_by_id = self._get_perm_ids()
|
|
45
|
+
|
|
46
|
+
records_to_insert = []
|
|
47
|
+
for user_id, assigned_perms in users_assigned_perms.items():
|
|
48
|
+
records_to_insert.extend(
|
|
49
|
+
self._get_assignments(user_id, assigned_perms, perms_by_id)
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
self._insert_assignments(records_to_insert)
|
|
53
|
+
|
|
54
|
+
def _query_existing_assignments(self):
|
|
55
|
+
if not self.options["user_alias"]:
|
|
56
|
+
query = (
|
|
57
|
+
f"SELECT Id,(SELECT {self.assignment_lookup} FROM {self.assignment_child_relationship}) "
|
|
58
|
+
"FROM User "
|
|
59
|
+
f"WHERE Username = '{self.org_config.username}'"
|
|
60
|
+
)
|
|
61
|
+
else:
|
|
62
|
+
aliases = "','".join(self.options["user_alias"])
|
|
63
|
+
query = (
|
|
64
|
+
f"SELECT Id,(SELECT {self.assignment_lookup} FROM {self.assignment_child_relationship}) "
|
|
65
|
+
"FROM User "
|
|
66
|
+
f"""WHERE Alias IN ('{aliases}')"""
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
result = self.sf.query(query)
|
|
70
|
+
if result["totalSize"] == 0:
|
|
71
|
+
raise CumulusCIException(
|
|
72
|
+
"No Users were found matching the specified aliases."
|
|
73
|
+
)
|
|
74
|
+
return result["records"]
|
|
75
|
+
|
|
76
|
+
def _get_assigned_perms(self, user):
|
|
77
|
+
assigned_perms = {}
|
|
78
|
+
# PermissionSetLicenseAssignments actually returns None if there are no assignments instead of an empty list of records. Wow.
|
|
79
|
+
if user[self.assignment_child_relationship]:
|
|
80
|
+
assigned_perms = {
|
|
81
|
+
r[self.assignment_lookup]
|
|
82
|
+
for r in user[self.assignment_child_relationship]["records"]
|
|
83
|
+
}
|
|
84
|
+
return assigned_perms
|
|
85
|
+
|
|
86
|
+
def _get_perm_ids(self):
|
|
87
|
+
api_names = "', '".join(self.options["api_names"])
|
|
88
|
+
perms = self.sf.query(
|
|
89
|
+
f"SELECT Id,{self.permission_name_field} FROM {self.permission_name} WHERE {self.permission_name_field} IN ('{api_names}')"
|
|
90
|
+
)
|
|
91
|
+
perms_by_ids = {
|
|
92
|
+
p["Id"]: p[self.permission_name_field] for p in perms["records"]
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
missing_perms = [
|
|
96
|
+
api_name
|
|
97
|
+
for api_name in self.options["api_names"]
|
|
98
|
+
if api_name not in perms_by_ids.values()
|
|
99
|
+
]
|
|
100
|
+
if missing_perms:
|
|
101
|
+
raise CumulusCIException(
|
|
102
|
+
f"The following {self.permission_label}s were not found: {', '.join(missing_perms)}."
|
|
103
|
+
)
|
|
104
|
+
return perms_by_ids
|
|
105
|
+
|
|
106
|
+
def _get_assignments(self, user_id, assigned_perms, perms_by_id):
|
|
107
|
+
assignments = []
|
|
108
|
+
for perm, perm_name in perms_by_id.items():
|
|
109
|
+
if perm not in assigned_perms:
|
|
110
|
+
self.logger.info(
|
|
111
|
+
f'Assigning {self.permission_label} "{perm_name}" to {user_id}.'
|
|
112
|
+
)
|
|
113
|
+
assignment = {
|
|
114
|
+
"attributes": {"type": self.assignment_name},
|
|
115
|
+
"AssigneeId": user_id,
|
|
116
|
+
self.assignment_lookup: perm,
|
|
117
|
+
}
|
|
118
|
+
assignments.append(assignment)
|
|
119
|
+
else:
|
|
120
|
+
self.logger.warning(
|
|
121
|
+
f'{self.permission_label} "{perm_name}" is already assigned to {user_id}.'
|
|
122
|
+
)
|
|
123
|
+
return assignments
|
|
124
|
+
|
|
125
|
+
def _insert_assignments(self, records_to_insert):
|
|
126
|
+
result_list = []
|
|
127
|
+
for i in range(0, len(records_to_insert), 200):
|
|
128
|
+
request_body = json.dumps(
|
|
129
|
+
{"allOrNone": False, "records": records_to_insert[i : i + 200]}
|
|
130
|
+
)
|
|
131
|
+
result = self.sf.restful(
|
|
132
|
+
"composite/sobjects", method="POST", data=request_body
|
|
133
|
+
)
|
|
134
|
+
result_list.extend(result)
|
|
135
|
+
self._process_composite_results(result_list)
|
|
136
|
+
|
|
137
|
+
def _process_composite_results(self, api_results):
|
|
138
|
+
results_table_data = [["Success", "ID", "Message"]]
|
|
139
|
+
for result in api_results:
|
|
140
|
+
result_row = [result["success"], result.get("id", "-")]
|
|
141
|
+
if not result["success"] and result["errors"]:
|
|
142
|
+
result_row.append(result["errors"][0]["message"])
|
|
143
|
+
else:
|
|
144
|
+
result_row.append("-")
|
|
145
|
+
results_table_data.append(result_row)
|
|
146
|
+
|
|
147
|
+
table = CliTable(
|
|
148
|
+
results_table_data,
|
|
149
|
+
title="Results",
|
|
150
|
+
)
|
|
151
|
+
table.echo()
|
|
152
|
+
|
|
153
|
+
if not all([result["success"] for result in api_results]):
|
|
154
|
+
raise CumulusCIException(
|
|
155
|
+
f"Not all {self.assignment_child_relationship} were saved."
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class AssignPermissionSetLicenses(AssignPermissionSets):
|
|
160
|
+
task_docs = """
|
|
161
|
+
Assigns Permission Set Licenses whose Developer Names or PermissionSetLicenseKey are in ``api_names`` to either the default org user or the user whose Alias is ``user_alias``. This task skips assigning Permission Set Licenses that are already assigned.
|
|
162
|
+
|
|
163
|
+
Permission Set Licenses are usually associated with a Permission Set, and assigning the Permission Set usually assigns the associated Permission Set License automatically. However, in non-namespaced developer scratch orgs, assigning the associated Permission Set may not automatically assign the Permission Set License, and this task will ensure the Permission Set Licenses are assigned.
|
|
164
|
+
"""
|
|
165
|
+
|
|
166
|
+
task_options = {
|
|
167
|
+
"api_names": {
|
|
168
|
+
"description": "API Developer Names of desired Permission Set Licenses, separated by commas.",
|
|
169
|
+
"required": True,
|
|
170
|
+
},
|
|
171
|
+
"user_alias": {
|
|
172
|
+
"description": "Alias of target user (if not the current running user, the default)."
|
|
173
|
+
},
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
permission_name = "PermissionSetLicense"
|
|
177
|
+
permission_name_field = ["DeveloperName", "PermissionSetLicenseKey"]
|
|
178
|
+
permission_label = "Permission Set License"
|
|
179
|
+
assignment_name = "PermissionSetLicenseAssign"
|
|
180
|
+
assignment_lookup = "PermissionSetLicenseId"
|
|
181
|
+
assignment_child_relationship = "PermissionSetLicenseAssignments"
|
|
182
|
+
|
|
183
|
+
def _get_perm_ids(self):
|
|
184
|
+
perms_by_ids = {}
|
|
185
|
+
api_names = "', '".join(self.options["api_names"])
|
|
186
|
+
perms = self.sf.query(
|
|
187
|
+
f"SELECT Id,{self.permission_name_field[0]},{self.permission_name_field[1]} FROM {self.permission_name} WHERE {self.permission_name_field[0]} IN ('{api_names}') OR {self.permission_name_field[1]} IN ('{api_names}')"
|
|
188
|
+
)
|
|
189
|
+
for p in perms["records"]:
|
|
190
|
+
if p[self.permission_name_field[0]] in self.options["api_names"]:
|
|
191
|
+
perms_by_ids[p["Id"]] = p[self.permission_name_field[0]]
|
|
192
|
+
else:
|
|
193
|
+
perms_by_ids[p["Id"]] = p[self.permission_name_field[1]]
|
|
194
|
+
|
|
195
|
+
missing_perms = [
|
|
196
|
+
api_name
|
|
197
|
+
for api_name in self.options["api_names"]
|
|
198
|
+
if api_name not in perms_by_ids.values()
|
|
199
|
+
]
|
|
200
|
+
if missing_perms:
|
|
201
|
+
raise CumulusCIException(
|
|
202
|
+
f"The following {self.permission_label}s were not found: {', '.join(missing_perms)}."
|
|
203
|
+
)
|
|
204
|
+
return perms_by_ids
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
class AssignPermissionSetGroups(AssignPermissionSets):
|
|
208
|
+
task_docs = """
|
|
209
|
+
Assigns Permission Set Groups whose Developer Names are in ``api_names`` to either the default org user or the user whose Alias is ``user_alias``. This task skips assigning Permission Set Groups that are already assigned.
|
|
210
|
+
"""
|
|
211
|
+
|
|
212
|
+
task_options = {
|
|
213
|
+
"api_names": {
|
|
214
|
+
"description": "API Developer Names of desired Permission Set Groups, separated by commas.",
|
|
215
|
+
"required": True,
|
|
216
|
+
},
|
|
217
|
+
"user_alias": {
|
|
218
|
+
"description": "Alias of target user (if not the current running user, the default)."
|
|
219
|
+
},
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
permission_name = "PermissionSetGroup"
|
|
223
|
+
permission_name_field = "DeveloperName"
|
|
224
|
+
permission_label = "Permission Set Group"
|
|
225
|
+
assignment_name = "PermissionSetAssignment"
|
|
226
|
+
assignment_lookup = "PermissionSetGroupId"
|
|
227
|
+
assignment_child_relationship = "PermissionSetAssignments"
|