periplus-map 0.2.1__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.
- periplus/__init__.py +70 -0
- periplus/checkmap.py +80 -0
- periplus/cli.py +658 -0
- periplus/contract/schema/map.schema.json +138 -0
- periplus/contract/schema/navigation.schema.json +200 -0
- periplus/contract/schema/pack-file.schema.json +1405 -0
- periplus/contract/schema/pack-manifest.schema.json +245 -0
- periplus/contract/schema/project-settings.schema.json +85 -0
- periplus/contract/spec/engine.md +151 -0
- periplus/contract/spec/rules.md +352 -0
- periplus/detect.py +228 -0
- periplus/engine/__init__.py +5 -0
- periplus/engine/check.py +481 -0
- periplus/engine/emit.py +368 -0
- periplus/engine/packload.py +2321 -0
- periplus/engine/pattern.py +27 -0
- periplus/engine/rules.py +1946 -0
- periplus/engine/select.py +491 -0
- periplus/engine/source.py +172 -0
- periplus/engine/tree.py +424 -0
- periplus/errors.py +332 -0
- periplus/init.py +358 -0
- periplus/layout.py +28 -0
- periplus/manifest.py +498 -0
- periplus/map.py +364 -0
- periplus/navigate/__init__.py +1 -0
- periplus/navigate/find.py +143 -0
- periplus/navigate/ids.py +30 -0
- periplus/navigate/listing.py +42 -0
- periplus/navigate/mapfile.py +189 -0
- periplus/navigate/path.py +175 -0
- periplus/navigate/show.py +175 -0
- periplus/navigate/types.py +83 -0
- periplus/navigate/walk.py +138 -0
- periplus/packs/advancedqueue_basic@0.0.1/pack.yaml +14 -0
- periplus/packs/advancedqueue_basic@0.0.1/queue_job_type/queue_job_type.yaml +9 -0
- periplus/packs/advancedqueue_basic@0.0.1/queue_job_type/queue_job_type_annotation.yaml +43 -0
- periplus/packs/advancedqueue_basic@0.0.1/queue_job_type/queue_job_type_attribute.yaml +43 -0
- periplus/packs/ai_basic@0.0.1/ai_agent/ai_agent.yaml +8 -0
- periplus/packs/ai_basic@0.0.1/ai_agent/ai_agent_attribute.yaml +43 -0
- periplus/packs/ai_basic@0.0.1/ai_function_call/ai_function_call.yaml +8 -0
- periplus/packs/ai_basic@0.0.1/ai_function_call/ai_function_call_attribute.yaml +43 -0
- periplus/packs/ai_basic@0.0.1/pack.yaml +15 -0
- periplus/packs/config_pages_basic@0.0.1/bundle/config_pages_bundle_config.yaml +54 -0
- periplus/packs/config_pages_basic@0.0.1/pack.yaml +11 -0
- periplus/packs/crop_basic@0.0.1/bundle/crop_bundle_config.yaml +54 -0
- periplus/packs/crop_basic@0.0.1/pack.yaml +11 -0
- periplus/packs/drupal@0.1.0/block/block_placement.yaml +25 -0
- periplus/packs/drupal@0.1.0/block/block_placement_code.yaml +58 -0
- periplus/packs/drupal@0.1.0/block/block_placement_config.yaml +53 -0
- periplus/packs/drupal@0.1.0/block/block_plugin.yaml +52 -0
- periplus/packs/drupal@0.1.0/block/block_plugin_altered.yaml +61 -0
- periplus/packs/drupal@0.1.0/block/block_plugin_annotation.yaml +69 -0
- periplus/packs/drupal@0.1.0/block/block_plugin_attribute.yaml +56 -0
- periplus/packs/drupal@0.1.0/block/block_plugin_content.yaml +46 -0
- periplus/packs/drupal@0.1.0/block/block_plugin_derived.yaml +110 -0
- periplus/packs/drupal@0.1.0/block/block_plugin_deriver.yaml +30 -0
- periplus/packs/drupal@0.1.0/block/block_type.yaml +14 -0
- periplus/packs/drupal@0.1.0/block/block_type_code.yaml +43 -0
- periplus/packs/drupal@0.1.0/block/block_type_config.yaml +45 -0
- periplus/packs/drupal@0.1.0/cache/cache.yaml +18 -0
- periplus/packs/drupal@0.1.0/cache/cache_backend.yaml +31 -0
- periplus/packs/drupal@0.1.0/component/sdc.yaml +19 -0
- periplus/packs/drupal@0.1.0/component/sdc_definition.yaml +25 -0
- periplus/packs/drupal@0.1.0/component/sdc_use.yaml +25 -0
- periplus/packs/drupal@0.1.0/config/config_object.yaml +65 -0
- periplus/packs/drupal@0.1.0/display/display.yaml +32 -0
- periplus/packs/drupal@0.1.0/display/display_code.yaml +53 -0
- periplus/packs/drupal@0.1.0/display/display_config.yaml +95 -0
- periplus/packs/drupal@0.1.0/entity/entity.yaml +33 -0
- periplus/packs/drupal@0.1.0/entity/entity_class.yaml +60 -0
- periplus/packs/drupal@0.1.0/entity/entity_save.yaml +27 -0
- periplus/packs/drupal@0.1.0/entity/entity_type_annotation.yaml +85 -0
- periplus/packs/drupal@0.1.0/entity/entity_type_attribute.yaml +76 -0
- periplus/packs/drupal@0.1.0/field/field_instance_code.yaml +40 -0
- periplus/packs/drupal@0.1.0/field/field_instance_config.yaml +58 -0
- periplus/packs/drupal@0.1.0/field/field_storage.yaml +37 -0
- periplus/packs/drupal@0.1.0/field/field_storage_code.yaml +39 -0
- periplus/packs/drupal@0.1.0/field/field_storage_config.yaml +24 -0
- periplus/packs/drupal@0.1.0/form/form.yaml +48 -0
- periplus/packs/drupal@0.1.0/form/form_class.yaml +50 -0
- periplus/packs/drupal@0.1.0/form/form_id.yaml +48 -0
- periplus/packs/drupal@0.1.0/form/form_methods.yaml +39 -0
- periplus/packs/drupal@0.1.0/hook/hook.yaml +8 -0
- periplus/packs/drupal@0.1.0/hook/hook_attribute.yaml +28 -0
- periplus/packs/drupal@0.1.0/module/module.yaml +8 -0
- periplus/packs/drupal@0.1.0/module/module_info.yaml +50 -0
- periplus/packs/drupal@0.1.0/pack.yaml +184 -0
- periplus/packs/drupal@0.1.0/plugin/plugin.yaml +17 -0
- periplus/packs/drupal@0.1.0/plugin/plugin_annotation.yaml +120 -0
- periplus/packs/drupal@0.1.0/recommendations/recommendations.yaml +14 -0
- periplus/packs/drupal@0.1.0/service/service.yaml +19 -0
- periplus/packs/drupal@0.1.0/service/service_autowire.yaml +28 -0
- periplus/packs/drupal@0.1.0/service/service_definition.yaml +24 -0
- periplus/packs/drupal@0.1.0/service/service_use.yaml +43 -0
- periplus/packs/drupal_basic@0.3.0/action/action.yaml +9 -0
- periplus/packs/drupal_basic@0.3.0/action/action_annotation.yaml +43 -0
- periplus/packs/drupal_basic@0.3.0/action/action_attribute.yaml +43 -0
- periplus/packs/drupal_basic@0.3.0/block/block_placement.yaml +16 -0
- periplus/packs/drupal_basic@0.3.0/block/block_placement_config.yaml +51 -0
- periplus/packs/drupal_basic@0.3.0/block_plugin/block_plugin.yaml +14 -0
- periplus/packs/drupal_basic@0.3.0/block_plugin/block_plugin_annotation.yaml +47 -0
- periplus/packs/drupal_basic@0.3.0/block_plugin/block_plugin_attribute.yaml +43 -0
- periplus/packs/drupal_basic@0.3.0/block_type/block_type.yaml +8 -0
- periplus/packs/drupal_basic@0.3.0/block_type/block_type_config.yaml +54 -0
- periplus/packs/drupal_basic@0.3.0/boundary/boundary_types.yaml +19 -0
- periplus/packs/drupal_basic@0.3.0/bundle/bundle.yaml +20 -0
- periplus/packs/drupal_basic@0.3.0/bundle/bundle_config.yaml +393 -0
- periplus/packs/drupal_basic@0.3.0/call/call.yaml +349 -0
- periplus/packs/drupal_basic@0.3.0/component/component.yaml +30 -0
- periplus/packs/drupal_basic@0.3.0/config/config_object.yaml +119 -0
- periplus/packs/drupal_basic@0.3.0/constraint/constraint.yaml +8 -0
- periplus/packs/drupal_basic@0.3.0/constraint/constraint_annotation.yaml +43 -0
- periplus/packs/drupal_basic@0.3.0/constraint/constraint_attribute.yaml +43 -0
- periplus/packs/drupal_basic@0.3.0/display/display.yaml +30 -0
- periplus/packs/drupal_basic@0.3.0/display/display_config.yaml +203 -0
- periplus/packs/drupal_basic@0.3.0/display/display_mode_config.yaml +60 -0
- periplus/packs/drupal_basic@0.3.0/entity_type/config_entity_type_annotation.yaml +46 -0
- periplus/packs/drupal_basic@0.3.0/entity_type/config_entity_type_attribute.yaml +43 -0
- periplus/packs/drupal_basic@0.3.0/entity_type/content_entity_type_annotation.yaml +46 -0
- periplus/packs/drupal_basic@0.3.0/entity_type/content_entity_type_attribute.yaml +43 -0
- periplus/packs/drupal_basic@0.3.0/entity_type/entity_type.yaml +16 -0
- periplus/packs/drupal_basic@0.3.0/field/field_instance_config.yaml +116 -0
- periplus/packs/drupal_basic@0.3.0/field/field_storage.yaml +21 -0
- periplus/packs/drupal_basic@0.3.0/field/field_storage_config.yaml +45 -0
- periplus/packs/drupal_basic@0.3.0/field_formatter/field_formatter.yaml +8 -0
- periplus/packs/drupal_basic@0.3.0/field_formatter/field_formatter_annotation.yaml +46 -0
- periplus/packs/drupal_basic@0.3.0/field_formatter/field_formatter_attribute.yaml +43 -0
- periplus/packs/drupal_basic@0.3.0/field_type/field_type_annotation.yaml +46 -0
- periplus/packs/drupal_basic@0.3.0/field_type/field_type_attribute.yaml +50 -0
- periplus/packs/drupal_basic@0.3.0/field_widget/field_widget_annotation.yaml +46 -0
- periplus/packs/drupal_basic@0.3.0/field_widget/field_widget_attribute.yaml +50 -0
- periplus/packs/drupal_basic@0.3.0/form/form_id.yaml +80 -0
- periplus/packs/drupal_basic@0.3.0/hook/hook.yaml +100 -0
- periplus/packs/drupal_basic@0.3.0/hook/hook_attribute.yaml +64 -0
- periplus/packs/drupal_basic@0.3.0/hook/hook_theme_include.yaml +34 -0
- periplus/packs/drupal_basic@0.3.0/library/library.yaml +12 -0
- periplus/packs/drupal_basic@0.3.0/library/library_definition.yaml +58 -0
- periplus/packs/drupal_basic@0.3.0/local_action/local_action.yaml +12 -0
- periplus/packs/drupal_basic@0.3.0/local_action/local_action_definition.yaml +49 -0
- periplus/packs/drupal_basic@0.3.0/mail/mail.yaml +8 -0
- periplus/packs/drupal_basic@0.3.0/mail/mail_attribute.yaml +43 -0
- periplus/packs/drupal_basic@0.3.0/media_source/media_source.yaml +8 -0
- periplus/packs/drupal_basic@0.3.0/media_source/media_source_annotation.yaml +43 -0
- periplus/packs/drupal_basic@0.3.0/media_source/media_source_attribute.yaml +79 -0
- periplus/packs/drupal_basic@0.3.0/menu_link/menu_link.yaml +18 -0
- periplus/packs/drupal_basic@0.3.0/menu_link/menu_link_definition.yaml +48 -0
- periplus/packs/drupal_basic@0.3.0/module/module.yaml +7 -0
- periplus/packs/drupal_basic@0.3.0/module/module_info.yaml +58 -0
- periplus/packs/drupal_basic@0.3.0/pack.yaml +528 -0
- periplus/packs/drupal_basic@0.3.0/permission/permission.yaml +7 -0
- periplus/packs/drupal_basic@0.3.0/permission/permission_definition.yaml +27 -0
- periplus/packs/drupal_basic@0.3.0/queue_worker/queue_worker.yaml +9 -0
- periplus/packs/drupal_basic@0.3.0/queue_worker/queue_worker_annotation.yaml +43 -0
- periplus/packs/drupal_basic@0.3.0/queue_worker/queue_worker_attribute.yaml +43 -0
- periplus/packs/drupal_basic@0.3.0/rest_resource/rest_resource.yaml +8 -0
- periplus/packs/drupal_basic@0.3.0/rest_resource/rest_resource_annotation.yaml +43 -0
- periplus/packs/drupal_basic@0.3.0/rest_resource/rest_resource_attribute.yaml +43 -0
- periplus/packs/drupal_basic@0.3.0/role/role.yaml +14 -0
- periplus/packs/drupal_basic@0.3.0/role/role_config.yaml +44 -0
- periplus/packs/drupal_basic@0.3.0/route/route.yaml +42 -0
- periplus/packs/drupal_basic@0.3.0/route/route_definition.yaml +113 -0
- periplus/packs/drupal_basic@0.3.0/route/route_options.yaml +55 -0
- periplus/packs/drupal_basic@0.3.0/route/route_requirements.yaml +108 -0
- periplus/packs/drupal_basic@0.3.0/service/service.yaml +56 -0
- periplus/packs/drupal_basic@0.3.0/service/service_definition.yaml +181 -0
- periplus/packs/drupal_basic@0.3.0/template/template.yaml +86 -0
- periplus/packs/drupal_basic@0.3.0/template/template_route_link.yaml +30 -0
- periplus/packs/drupal_basic@0.3.0/theme/theme.yaml +15 -0
- periplus/packs/drupal_basic@0.3.0/theme/theme_info.yaml +61 -0
- periplus/packs/drupal_basic@0.3.0/theme_hook/template_suggestion.yaml +29 -0
- periplus/packs/drupal_basic@0.3.0/theme_hook/theme_hook.yaml +87 -0
- periplus/packs/drupal_basic@0.3.0/theme_hook/theme_hook_render.yaml +20 -0
- periplus/packs/drupal_basic@0.3.0/url/url.yaml +88 -0
- periplus/packs/drupal_basic@0.3.0/views_plugin/views_field_attribute.yaml +80 -0
- periplus/packs/drupal_basic@0.3.0/views_plugin/views_filter_attribute.yaml +80 -0
- periplus/packs/drupal_basic@0.3.0/views_plugin/views_plugin.yaml +15 -0
- periplus/packs/drupal_basic@0.3.0/views_plugin/views_style_attribute.yaml +80 -0
- periplus/packs/drupal_js_basic@0.0.1/attachment/attachment.yaml +12 -0
- periplus/packs/drupal_js_basic@0.0.1/attachment/attachment_in_php.yaml +15 -0
- periplus/packs/drupal_js_basic@0.0.1/attachment/attachment_in_php_array.yaml +52 -0
- periplus/packs/drupal_js_basic@0.0.1/attachment/attachment_in_twig.yaml +26 -0
- periplus/packs/drupal_js_basic@0.0.1/attachment/php_function_holder.yaml +13 -0
- periplus/packs/drupal_js_basic@0.0.1/behavior/behavior.yaml +198 -0
- periplus/packs/drupal_js_basic@0.0.1/pack.yaml +153 -0
- periplus/packs/drupal_js_basic@0.0.1/setting/setting.yaml +13 -0
- periplus/packs/drupal_js_basic@0.0.1/setting/setting_in_js.yaml +15 -0
- periplus/packs/drupal_js_basic@0.0.1/setting/setting_in_php.yaml +92 -0
- periplus/packs/drush_basic@0.0.1/command/command.yaml +15 -0
- periplus/packs/drush_basic@0.0.1/command/command_annotation.yaml +60 -0
- periplus/packs/drush_basic@0.0.1/command/command_attribute.yaml +88 -0
- periplus/packs/drush_basic@0.0.1/pack.yaml +29 -0
- periplus/packs/eck_basic@0.0.1/bundle/eck_bundle_config.yaml +56 -0
- periplus/packs/eck_basic@0.0.1/entity_type/eck_entity_type_config.yaml +26 -0
- periplus/packs/eck_basic@0.0.1/pack.yaml +28 -0
- periplus/packs/go@0.0.2/interfaces/satisfies.yaml +47 -0
- periplus/packs/go@0.0.2/pack.yaml +51 -0
- periplus/packs/go@0.0.2/types/find_declarations.yaml +137 -0
- periplus/packs/go@0.0.2/types/node_types.yaml +36 -0
- periplus/packs/go_basic@0.0.3/pack.yaml +104 -0
- periplus/packs/go_basic@0.0.3/rules/calls.yaml +25 -0
- periplus/packs/go_basic@0.0.3/rules/declarations.yaml +40 -0
- periplus/packs/go_basic@0.0.3/rules/imports.yaml +16 -0
- periplus/packs/go_basic@0.0.3/types/node_types.yaml +15 -0
- periplus/packs/js_basic@0.0.1/function/function.yaml +68 -0
- periplus/packs/js_basic@0.0.1/pack.yaml +50 -0
- periplus/packs/laravel_basic@0.0.5/pack.yaml +313 -0
- periplus/packs/laravel_basic@0.0.5/rules/classes.yaml +42 -0
- periplus/packs/laravel_basic@0.0.5/rules/config.yaml +229 -0
- periplus/packs/laravel_basic@0.0.5/rules/routes.yaml +210 -0
- periplus/packs/laravel_basic@0.0.5/rules/types.yaml +50 -0
- periplus/packs/laravel_basic@0.0.5/rules/views.yaml +100 -0
- periplus/packs/paragraphs_basic@0.0.1/bundle/paragraph_bundle_config.yaml +54 -0
- periplus/packs/paragraphs_basic@0.0.1/pack.yaml +12 -0
- periplus/packs/php@0.1.0/edges/edge_kinds.yaml +64 -0
- periplus/packs/php@0.1.0/edges/find_calls.yaml +34 -0
- periplus/packs/php@0.1.0/edges/find_imports.yaml +18 -0
- periplus/packs/php@0.1.0/edges/find_member_access.yaml +22 -0
- periplus/packs/php@0.1.0/edges/find_structure.yaml +38 -0
- periplus/packs/php@0.1.0/embedded/embedded_regions.yaml +19 -0
- periplus/packs/php@0.1.0/imports/imports.yaml +20 -0
- periplus/packs/php@0.1.0/pack.yaml +117 -0
- periplus/packs/php@0.1.0/resolution/excluded_tokens.yaml +23 -0
- periplus/packs/php@0.1.0/resolution/resolution.yaml +35 -0
- periplus/packs/php@0.1.0/types/find_declarations.yaml +102 -0
- periplus/packs/php@0.1.0/types/node_types.yaml +55 -0
- periplus/packs/php_basic@0.2.0/edges/edge_kinds.yaml +48 -0
- periplus/packs/php_basic@0.2.0/edges/find_structure.yaml +750 -0
- periplus/packs/php_basic@0.2.0/imports/imports.yaml +19 -0
- periplus/packs/php_basic@0.2.0/pack.yaml +94 -0
- periplus/packs/php_basic@0.2.0/types/find_declarations.yaml +267 -0
- periplus/packs/php_basic@0.2.0/types/node_types.yaml +55 -0
- periplus/packs/profile_basic@0.0.1/bundle/profile_bundle_config.yaml +54 -0
- periplus/packs/profile_basic@0.0.1/pack.yaml +12 -0
- periplus/packs/salesforce_basic@0.0.1/event/salesforce_event.yaml +36 -0
- periplus/packs/salesforce_basic@0.0.1/pack.yaml +31 -0
- periplus/packs/salesforce_basic@0.0.1/salesforce_mapping/salesforce_mapping.yaml +19 -0
- periplus/packs/salesforce_basic@0.0.1/salesforce_mapping/salesforce_mapping_config.yaml +83 -0
- periplus/packs/salesforce_basic@0.0.1/salesforce_mapping_field/salesforce_mapping_field.yaml +8 -0
- periplus/packs/salesforce_basic@0.0.1/salesforce_mapping_field/salesforce_mapping_field_annotation.yaml +43 -0
- periplus/packs/twig@0.0.1/pack.yaml +26 -0
- periplus/packs/twig@0.0.1/types/template.yaml +57 -0
- periplus/packs/twig_basic@0.1.0/pack.yaml +11 -0
- periplus/packs/twig_tweak_basic@0.0.1/pack.yaml +27 -0
- periplus/packs/twig_tweak_basic@0.0.1/rules/block.yaml +20 -0
- periplus/packs/twig_tweak_basic@0.0.1/rules/entity.yaml +35 -0
- periplus/packs/twig_tweak_basic@0.0.1/rules/field.yaml +21 -0
- periplus/packs/twig_tweak_basic@0.0.1/rules/menu.yaml +21 -0
- periplus/packs/webform_basic@0.0.1/bundle/webform_submission_bundle_config.yaml +54 -0
- periplus/packs/webform_basic@0.0.1/pack.yaml +20 -0
- periplus/packs/webform_basic@0.0.1/webform_handler/webform_handler.yaml +8 -0
- periplus/packs/webform_basic@0.0.1/webform_handler/webform_handler_annotation.yaml +43 -0
- periplus/packs/yaml@0.0.1/pack.yaml +72 -0
- periplus/packs/yaml@0.0.1/types/find_mapping_entry.yaml +21 -0
- periplus/packs/yaml@0.0.1/types/yaml_types.yaml +44 -0
- periplus/packs/yaml_basic@0.1.0/pack.yaml +10 -0
- periplus/packs.py +447 -0
- periplus/preflight.py +102 -0
- periplus/py.typed +0 -0
- periplus/report.py +596 -0
- periplus/resolution.py +355 -0
- periplus/settings.py +617 -0
- periplus/settings.stub.yml +99 -0
- periplus/spec.py +774 -0
- periplus/update.py +197 -0
- periplus/validate.py +655 -0
- periplus_map-0.2.1.dist-info/METADATA +566 -0
- periplus_map-0.2.1.dist-info/RECORD +272 -0
- periplus_map-0.2.1.dist-info/WHEEL +4 -0
- periplus_map-0.2.1.dist-info/entry_points.txt +2 -0
- periplus_map-0.2.1.dist-info/licenses/LICENSE +202 -0
- periplus_map-0.2.1.dist-info/licenses/NOTICE +2 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
$schema: "https://periplus.dev/schema/0/pack-file.schema.json"
|
|
2
|
+
|
|
3
|
+
# drupal pack — field storage created by PHP. One rule.
|
|
4
|
+
|
|
5
|
+
needs:
|
|
6
|
+
types:
|
|
7
|
+
- drupal.field_storage
|
|
8
|
+
rules:
|
|
9
|
+
- rule: field_storage_from_code
|
|
10
|
+
reads: file
|
|
11
|
+
in:
|
|
12
|
+
- custom_module
|
|
13
|
+
match:
|
|
14
|
+
static_call: Drupal\field\Entity\FieldStorageConfig::create
|
|
15
|
+
argument: 0
|
|
16
|
+
id: &id001
|
|
17
|
+
from:
|
|
18
|
+
- argument_key: entity_type
|
|
19
|
+
- argument_key: field_name
|
|
20
|
+
template: field.storage.{entity_type}.{field_name}
|
|
21
|
+
on_miss: unresolved
|
|
22
|
+
emits:
|
|
23
|
+
- node:
|
|
24
|
+
type: drupal.field_storage
|
|
25
|
+
confidence: declared
|
|
26
|
+
- rule: field_storage_from_code_edges
|
|
27
|
+
reads: file
|
|
28
|
+
in:
|
|
29
|
+
- custom_module
|
|
30
|
+
match:
|
|
31
|
+
static_call: Drupal\field\Entity\FieldStorageConfig::create
|
|
32
|
+
argument: 0
|
|
33
|
+
emits:
|
|
34
|
+
- edge:
|
|
35
|
+
kind: declares
|
|
36
|
+
from: enclosing_callable
|
|
37
|
+
to: this_node
|
|
38
|
+
confidence: declared
|
|
39
|
+
id: *id001
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
$schema: "https://periplus.dev/schema/0/pack-file.schema.json"
|
|
2
|
+
|
|
3
|
+
# drupal pack — field storage from a config file. One rule.
|
|
4
|
+
|
|
5
|
+
needs:
|
|
6
|
+
types: [drupal.field_storage]
|
|
7
|
+
|
|
8
|
+
rules:
|
|
9
|
+
|
|
10
|
+
- rule: field_storage_from_config
|
|
11
|
+
reads: file
|
|
12
|
+
in: [config, module_config]
|
|
13
|
+
match:
|
|
14
|
+
file: "field.storage.*"
|
|
15
|
+
filetype: yaml
|
|
16
|
+
id:
|
|
17
|
+
from: file_stem
|
|
18
|
+
emits:
|
|
19
|
+
- node: {type: drupal.field_storage}
|
|
20
|
+
- attribute: {name: field_type, from: {key: type}}
|
|
21
|
+
- attribute: {name: cardinality, from: {key: cardinality}}
|
|
22
|
+
confidence: declared
|
|
23
|
+
# Verified: field.storage.block_content.body.yml, and the six the test modules ship as
|
|
24
|
+
# field.storage.block_content.field_tw_*.yml.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
$schema: "https://periplus.dev/schema/0/pack-file.schema.json"
|
|
2
|
+
|
|
3
|
+
# drupal pack — declares the Form API types and edges. Finds nothing.
|
|
4
|
+
#
|
|
5
|
+
# Under php alone every class here is php.class and every method is php.method. Adding this
|
|
6
|
+
# pack keeps every id and refines every type to a descendant. That is the monotonic layering
|
|
7
|
+
# check, and it is testable by running twice and diffing.
|
|
8
|
+
#
|
|
9
|
+
# Verified by grep over core lib and modules: no class implements both an entity interface
|
|
10
|
+
# and a form interface. The two families are disjoint, so a class can never match both — a
|
|
11
|
+
# form that edits a node is not a node.
|
|
12
|
+
#
|
|
13
|
+
# The collision that IS real sits inside the form family. EntityForm satisfies both
|
|
14
|
+
# "reaches FormInterface" and "reaches EntityFormInterface", so both rules fire. The parent
|
|
15
|
+
# declarations below make the most specific match win, and reserve refusal for genuine
|
|
16
|
+
# ambiguity.
|
|
17
|
+
|
|
18
|
+
node_types:
|
|
19
|
+
|
|
20
|
+
- name: drupal.form
|
|
21
|
+
parent: php.class
|
|
22
|
+
|
|
23
|
+
- name: drupal.entity_form
|
|
24
|
+
parent: drupal.form
|
|
25
|
+
|
|
26
|
+
- name: drupal.content_entity_form
|
|
27
|
+
parent: drupal.entity_form
|
|
28
|
+
|
|
29
|
+
- name: drupal.form_save
|
|
30
|
+
parent: php.method
|
|
31
|
+
|
|
32
|
+
- name: drupal.form_build
|
|
33
|
+
parent: php.method
|
|
34
|
+
|
|
35
|
+
- name: drupal.form_validate
|
|
36
|
+
parent: php.method
|
|
37
|
+
|
|
38
|
+
- name: drupal.form_submit
|
|
39
|
+
parent: php.method
|
|
40
|
+
|
|
41
|
+
edge_kinds:
|
|
42
|
+
|
|
43
|
+
- kind: edits_entity
|
|
44
|
+
from: drupal.entity_form
|
|
45
|
+
to: drupal.entity_type
|
|
46
|
+
# The endpoint is the entity TYPE, not the entity CLASS: an entity form
|
|
47
|
+
# edits an entity TYPE, which is its own node. Routing makes the binding at
|
|
48
|
+
# runtime, so the rule that fills this in is inferred, and it is not written yet.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
$schema: "https://periplus.dev/schema/0/pack-file.schema.json"
|
|
2
|
+
|
|
3
|
+
# drupal pack — classifies a class as a form. Three rules, all reading the map.
|
|
4
|
+
#
|
|
5
|
+
# Same reason as entity_class.yaml: a class becomes a form because of what it extends, and
|
|
6
|
+
# the chain can pass through first-party base classes. Transitive classification is always a
|
|
7
|
+
# map rule.
|
|
8
|
+
#
|
|
9
|
+
# About 258 classes in core modules reach drupal.form by extending FormBase, ConfirmFormBase,
|
|
10
|
+
# EntityForm, ContentEntityForm, EntityDeleteForm or ConfigFormBase. Not one of them says
|
|
11
|
+
# `implements FormInterface` at its own declaration site, so a rule matching the written
|
|
12
|
+
# clause would match nothing real.
|
|
13
|
+
|
|
14
|
+
needs:
|
|
15
|
+
types: [drupal.form, drupal.entity_form, drupal.content_entity_form]
|
|
16
|
+
|
|
17
|
+
rules:
|
|
18
|
+
|
|
19
|
+
- rule: form_class
|
|
20
|
+
reads: map
|
|
21
|
+
match:
|
|
22
|
+
node_type: php.class
|
|
23
|
+
where:
|
|
24
|
+
- ancestor_reaches: "Drupal\\Core\\Form\\FormInterface"
|
|
25
|
+
emits:
|
|
26
|
+
- type: drupal.form
|
|
27
|
+
confidence: declared
|
|
28
|
+
|
|
29
|
+
- rule: entity_form_class
|
|
30
|
+
reads: map
|
|
31
|
+
match:
|
|
32
|
+
node_type: php.class
|
|
33
|
+
where:
|
|
34
|
+
- ancestor_reaches: "Drupal\\Core\\Entity\\EntityFormInterface"
|
|
35
|
+
emits:
|
|
36
|
+
- type: drupal.entity_form
|
|
37
|
+
confidence: declared
|
|
38
|
+
|
|
39
|
+
- rule: content_entity_form_class
|
|
40
|
+
reads: map
|
|
41
|
+
match:
|
|
42
|
+
node_type: php.class
|
|
43
|
+
where:
|
|
44
|
+
- ancestor_reaches: "Drupal\\Core\\Entity\\ContentEntityFormInterface"
|
|
45
|
+
emits:
|
|
46
|
+
- type: drupal.content_entity_form
|
|
47
|
+
confidence: declared
|
|
48
|
+
# Verified in a private Drupal site: 1 class extends ContentEntityForm, 1 extends
|
|
49
|
+
# ConfigFormBase. Small, and the rule that finds them is the same one that would find
|
|
50
|
+
# 258 in core.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
$schema: "https://periplus.dev/schema/0/pack-file.schema.json"
|
|
2
|
+
|
|
3
|
+
# drupal pack — the form's own id, from getFormId. One rule, reading the map.
|
|
4
|
+
#
|
|
5
|
+
# An entity type's id is a literal in an attribute or annotation, so it resolves every time.
|
|
6
|
+
# A form's id comes from a method return, and usually that is also a literal — but not
|
|
7
|
+
# always, and the exceptions are permanent rather than a pack needing improvement.
|
|
8
|
+
#
|
|
9
|
+
# Counted in core lib and modules: 274 getFormId() bodies return something. 266 return a
|
|
10
|
+
# plain string literal. 8 compute it:
|
|
11
|
+
# RevisionRevertForm.php:106 $this->revision->getEntityTypeId() . '_revision_revert'
|
|
12
|
+
# RevisionDeleteForm.php:101 $this->revision->getEntityTypeId() . '_revision_delete'
|
|
13
|
+
# FileUploadForm.php:119 $this->getBaseFormId() . '_upload'
|
|
14
|
+
# OEmbedForm.php:76 $this->getBaseFormId() . '_oembed'
|
|
15
|
+
# JSInteractionTestForm.php:20 __CLASS__
|
|
16
|
+
# StubForm.php:48 $this->formId
|
|
17
|
+
#
|
|
18
|
+
# 97% resolvable is the useful number. Gaps being the exception is what makes an unresolved
|
|
19
|
+
# count worth reading at all.
|
|
20
|
+
|
|
21
|
+
needs:
|
|
22
|
+
types: [drupal.form]
|
|
23
|
+
|
|
24
|
+
rules:
|
|
25
|
+
|
|
26
|
+
- rule: form_id_from_method_return
|
|
27
|
+
reads: map
|
|
28
|
+
match:
|
|
29
|
+
node_type: php.method
|
|
30
|
+
where:
|
|
31
|
+
- name: getFormId
|
|
32
|
+
- contained_by_type: drupal.form
|
|
33
|
+
id:
|
|
34
|
+
from: method_return_literal
|
|
35
|
+
must_be: string_literal
|
|
36
|
+
on_miss: unresolved
|
|
37
|
+
emits:
|
|
38
|
+
- attribute: {name: form_id, target: containing_node}
|
|
39
|
+
confidence: declared
|
|
40
|
+
# `reads: map` because the class has to be known to be a form first, and that is a map
|
|
41
|
+
# rule's output. Deciding literal-versus-not is a check, not a judgment, so no model is
|
|
42
|
+
# involved.
|
|
43
|
+
#
|
|
44
|
+
# It emits an ATTRIBUTE on the class, not a node. The form id is a second name for a
|
|
45
|
+
# thing already in the map, unlike an entity type id, which is referenced by config that
|
|
46
|
+
# never names the class. Nothing in a Drupal codebase references a form by its form id
|
|
47
|
+
# from another file — the id is used at runtime by hook_form_FORM_ID_alter, which is a
|
|
48
|
+
# function NAME, not a reference. That is a claim worth checking before it is relied on.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
$schema: "https://periplus.dev/schema/0/pack-file.schema.json"
|
|
2
|
+
|
|
3
|
+
# drupal pack — the form lifecycle methods. Four rules, all reading the map.
|
|
4
|
+
#
|
|
5
|
+
# Each is a method name that means something only inside a form. The containing class's type
|
|
6
|
+
# is what decides it, and that type is itself assigned by a map rule, so these run a pass
|
|
7
|
+
# later again.
|
|
8
|
+
|
|
9
|
+
needs:
|
|
10
|
+
types: [drupal.form, drupal.entity_form]
|
|
11
|
+
|
|
12
|
+
rules:
|
|
13
|
+
|
|
14
|
+
- rule: form_build
|
|
15
|
+
reads: map
|
|
16
|
+
match: {node_type: php.method, where: [{name: buildForm}, {contained_by_type: drupal.form}]}
|
|
17
|
+
emits: [{type: drupal.form_build}]
|
|
18
|
+
confidence: declared
|
|
19
|
+
|
|
20
|
+
- rule: form_validate
|
|
21
|
+
reads: map
|
|
22
|
+
match: {node_type: php.method, where: [{name: validateForm}, {contained_by_type: drupal.form}]}
|
|
23
|
+
emits: [{type: drupal.form_validate}]
|
|
24
|
+
confidence: declared
|
|
25
|
+
|
|
26
|
+
- rule: form_submit
|
|
27
|
+
reads: map
|
|
28
|
+
match: {node_type: php.method, where: [{name: submitForm}, {contained_by_type: drupal.form}]}
|
|
29
|
+
emits: [{type: drupal.form_submit}]
|
|
30
|
+
confidence: declared
|
|
31
|
+
|
|
32
|
+
- rule: form_save
|
|
33
|
+
reads: map
|
|
34
|
+
match: {node_type: php.method, where: [{name: save}, {contained_by_type: drupal.entity_form}]}
|
|
35
|
+
emits: [{type: drupal.form_save}]
|
|
36
|
+
confidence: declared
|
|
37
|
+
# The pair that makes the point. EntityBase.php:368 and EntityForm.php:293 are both
|
|
38
|
+
# called `save`. One becomes drupal.entity_save, the other drupal.form_save, and the
|
|
39
|
+
# only thing separating them is the containing class's type.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
$schema: "https://periplus.dev/schema/0/pack-file.schema.json"
|
|
2
|
+
|
|
3
|
+
# drupal pack — hook implementations declared by the Hook attribute. One rule.
|
|
4
|
+
|
|
5
|
+
needs:
|
|
6
|
+
types: [drupal.hook_implementation]
|
|
7
|
+
|
|
8
|
+
rules:
|
|
9
|
+
|
|
10
|
+
- rule: hook_from_attribute
|
|
11
|
+
reads: file
|
|
12
|
+
in: [custom_module, custom_theme]
|
|
13
|
+
match:
|
|
14
|
+
attribute: "Drupal\\Core\\Hook\\Attribute\\Hook"
|
|
15
|
+
where:
|
|
16
|
+
- applies_to: method_declaration
|
|
17
|
+
emits:
|
|
18
|
+
- type: drupal.hook_implementation
|
|
19
|
+
- attribute: {name: hook, from: {attribute_argument: 0}}
|
|
20
|
+
confidence: declared
|
|
21
|
+
# BlockWaysHooks.php:25-26. A type refinement of php.method, so the id does not change
|
|
22
|
+
# and every edge the php pack emitted still lands.
|
|
23
|
+
#
|
|
24
|
+
# The hook being implemented is an attribute, not a node, and that is unsettled. Nothing
|
|
25
|
+
# first-party ever declares a hook — core does, in documentation — so a hook node would
|
|
26
|
+
# exist only because something referenced it, which is exactly when the boundary rule
|
|
27
|
+
# says a boundary node should be emitted. So this is probably wrong as written, and one
|
|
28
|
+
# hook implementation is not enough evidence to design against.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
$schema: "https://periplus.dev/schema/0/pack-file.schema.json"
|
|
2
|
+
|
|
3
|
+
# drupal pack — the module, from its info file. One rule.
|
|
4
|
+
|
|
5
|
+
needs:
|
|
6
|
+
types:
|
|
7
|
+
- drupal.module
|
|
8
|
+
rules:
|
|
9
|
+
- rule: module_from_info_file
|
|
10
|
+
reads: file
|
|
11
|
+
in:
|
|
12
|
+
- custom_module
|
|
13
|
+
match:
|
|
14
|
+
file: '*.info'
|
|
15
|
+
filetype: yaml
|
|
16
|
+
where:
|
|
17
|
+
- key:
|
|
18
|
+
name: type
|
|
19
|
+
equals: module
|
|
20
|
+
id: &id001
|
|
21
|
+
from: file_stem
|
|
22
|
+
emits:
|
|
23
|
+
- node:
|
|
24
|
+
type: drupal.module
|
|
25
|
+
- attribute:
|
|
26
|
+
name: name
|
|
27
|
+
from:
|
|
28
|
+
key: name
|
|
29
|
+
confidence: declared
|
|
30
|
+
- rule: module_from_info_file_edges
|
|
31
|
+
reads: file
|
|
32
|
+
in:
|
|
33
|
+
- custom_module
|
|
34
|
+
match:
|
|
35
|
+
file: '*.info'
|
|
36
|
+
filetype: yaml
|
|
37
|
+
where:
|
|
38
|
+
- key:
|
|
39
|
+
name: type
|
|
40
|
+
equals: module
|
|
41
|
+
emits:
|
|
42
|
+
- edge:
|
|
43
|
+
kind: depends_on_module
|
|
44
|
+
from: this_node
|
|
45
|
+
to:
|
|
46
|
+
from:
|
|
47
|
+
key: dependencies
|
|
48
|
+
each: true
|
|
49
|
+
confidence: declared
|
|
50
|
+
id: *id001
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
$schema: "https://periplus.dev/schema/0/pack-manifest.schema.json"
|
|
2
|
+
|
|
3
|
+
# Drupal pack — fragment
|
|
4
|
+
#
|
|
5
|
+
# Not a Drupal pack. A companion to the php pack that exercises what a dependent pack has
|
|
6
|
+
# to do, using three of Drupal's APIs as the case, and deliberately leaving a fourth dark.
|
|
7
|
+
#
|
|
8
|
+
# configured: Entity API, Form API, Cache API
|
|
9
|
+
# dark: Event Subscriber API
|
|
10
|
+
#
|
|
11
|
+
# The dark one is not an oversight. It is the test for what happens when first-party code
|
|
12
|
+
# leans on something no pack describes, which is the ordinary state of any real codebase.
|
|
13
|
+
#
|
|
14
|
+
# Every Drupal claim below was read from drupal-cms on 2026-08-28 and carries its file and
|
|
15
|
+
# line. Nothing here is recalled.
|
|
16
|
+
|
|
17
|
+
pack: drupal
|
|
18
|
+
version: 0.1.0
|
|
19
|
+
depends: [php, yaml]
|
|
20
|
+
# Same mechanism as javascript -> react -> nextjs. Nothing marks this as a "framework
|
|
21
|
+
# pack"; it is a pack that depends on another pack.
|
|
22
|
+
#
|
|
23
|
+
# Two languages rather than a layer on one, as transcribing the
|
|
24
|
+
# block_ways map showed. A Drupal codebase is PHP and YAML in roughly equal measure, and with php
|
|
25
|
+
# alone this pack declared config rules it could never run: `files` claimed no .yml, so no
|
|
26
|
+
# .yml was ever opened and every config rule matched nothing without erroring.
|
|
27
|
+
#
|
|
28
|
+
# The alternative was a second `grammar:` block on this pack, which is wrong. A domain pack
|
|
29
|
+
# that owns a language means every domain pack touching YAML re-declares the same grammar
|
|
30
|
+
# and they drift. Instead the grammar follows the file extension, and the extension belongs
|
|
31
|
+
# to whichever pack claimed it — so a `find` rule naming config/install/*.yml needs no
|
|
32
|
+
# grammar field at all.
|
|
33
|
+
|
|
34
|
+
# ======================================================================================
|
|
35
|
+
# NAMED FOLDERS
|
|
36
|
+
#
|
|
37
|
+
# A rule says `in: [config]`. It never writes a path. The path lives here, once, and the
|
|
38
|
+
# project settings file overrides it for one repository without touching a rule.
|
|
39
|
+
#
|
|
40
|
+
# Proved necessary: the default below is wrong for the codebase we tested
|
|
41
|
+
# against, where settings.php:882 puts exported config at ./config/default. Under a rule
|
|
42
|
+
# with the path baked in, that is a pack edit. Under a name, it is one line of settings.
|
|
43
|
+
# ======================================================================================
|
|
44
|
+
folders:
|
|
45
|
+
config: ./config/sync # exported configuration
|
|
46
|
+
custom_module: ./web/modules/custom
|
|
47
|
+
custom_theme: ./web/themes/custom
|
|
48
|
+
|
|
49
|
+
# Relative to another folder, not to the root. A module ships its own config, and the
|
|
50
|
+
# path only means anything inside whatever custom_module resolves to.
|
|
51
|
+
module_config: "{custom_module}/*/config/install"
|
|
52
|
+
|
|
53
|
+
files:
|
|
54
|
+
extends: [php, yaml]
|
|
55
|
+
add_extensions: [module, inc, install, theme, profile, engine]
|
|
56
|
+
# None of these say "PHP" by convention. A mapper that cannot be told they are PHP maps
|
|
57
|
+
# almost nothing in a Drupal codebase.
|
|
58
|
+
|
|
59
|
+
add_excludes:
|
|
60
|
+
# Every path here is PHP by extension, so the PHP pack would open it. None of it is
|
|
61
|
+
# code anyone wrote to be read. Excluded rather than bounded: nothing in these files
|
|
62
|
+
# should ever be a node, not even the target of a reference.
|
|
63
|
+
#
|
|
64
|
+
# Verified present in drupal-cms on 2026-08-28.
|
|
65
|
+
- "web/sites/*/settings.php" # web/sites/default/settings.php
|
|
66
|
+
- "web/sites/*/settings.*.php" # web/sites/default/settings.ddev.php
|
|
67
|
+
- "web/sites/*/default.settings.php" # the template shipped by core
|
|
68
|
+
- "web/sites/*/services.yml"
|
|
69
|
+
- "web/sites/*/default.services.yml"
|
|
70
|
+
# Per-environment configuration, and the first two hold database credentials and the
|
|
71
|
+
# hash salt. The map is committed and diffed in a pull request, so this is the one
|
|
72
|
+
# exclusion that is a security rule and not a tidiness rule.
|
|
73
|
+
|
|
74
|
+
- "web/sites/*/files/**"
|
|
75
|
+
# The public files directory. User uploads, generated assets, and on some sites
|
|
76
|
+
# compiled Twig. Nothing here is authored.
|
|
77
|
+
|
|
78
|
+
- "web/sites/simpletest/**"
|
|
79
|
+
# Test-run scratch space, created and destroyed by the test runner.
|
|
80
|
+
|
|
81
|
+
# ======================================================================================
|
|
82
|
+
# BOUNDARY
|
|
83
|
+
#
|
|
84
|
+
# Entity API is not "a boundary". Every class listed below is the boundary. What separates
|
|
85
|
+
# Entity API from Event Subscriber API is only that this pack ships knowledge about one of them.
|
|
86
|
+
# Two mechanisms, kept apart, which is what lets the dark case degrade instead of fail.
|
|
87
|
+
# ======================================================================================
|
|
88
|
+
boundary:
|
|
89
|
+
# A boundary node enters the map because first-party code refers to it, never because a
|
|
90
|
+
# pack knows about it. An edge end that lands on a listed name becomes a declared node this
|
|
91
|
+
# pack drew; a listed name nothing reaches stays out of the map, so the map stays about this
|
|
92
|
+
# repository.
|
|
93
|
+
framework:
|
|
94
|
+
type: php.class_like
|
|
95
|
+
ancestry: [inherits, implements]
|
|
96
|
+
|
|
97
|
+
# ------------------------------------------------------------------------------------
|
|
98
|
+
# The hierarchy the ancestry kinds walk toward a listed name.
|
|
99
|
+
#
|
|
100
|
+
# This is why "not mapped" and "not read" are different operations. A custom entity
|
|
101
|
+
# almost never writes `implements EntityInterface`; it writes `extends
|
|
102
|
+
# ContentEntityBase`, and the interface is two hops up inside core. A rule matching the
|
|
103
|
+
# written clause would match nothing real.
|
|
104
|
+
#
|
|
105
|
+
# Both families are diamonds. Verified:
|
|
106
|
+
#
|
|
107
|
+
# ContentEntityForm extends EntityForm implements ContentEntityFormInterface
|
|
108
|
+
# ContentEntityForm.php:16 / ContentEntityFormInterface.php:11
|
|
109
|
+
# EntityForm extends FormBase implements EntityFormInterface EntityForm.php:18
|
|
110
|
+
# ConfirmFormBase extends FormBase implements ConfirmFormInterface
|
|
111
|
+
# ConfirmFormBase.php:8
|
|
112
|
+
# FormBase implements FormInterface, ContainerInjectionInterface FormBase.php:45
|
|
113
|
+
# EntityFormInterface extends BaseFormIdInterface EntityFormInterface.php:14
|
|
114
|
+
# BaseFormIdInterface extends FormInterface BaseFormIdInterface.php:11
|
|
115
|
+
# => EntityForm reaches FormInterface twice: via FormBase, and via
|
|
116
|
+
# EntityFormInterface -> BaseFormIdInterface. Resolution must dedupe.
|
|
117
|
+
#
|
|
118
|
+
# ContentEntityBase extends EntityBase implements ContentEntityInterface, ...
|
|
119
|
+
# ContentEntityBase.php:20
|
|
120
|
+
# EntityBase implements EntityInterface EntityBase.php:21
|
|
121
|
+
# ContentEntityInterface extends FieldableEntityInterface, ...
|
|
122
|
+
# ContentEntityInterface.php:24
|
|
123
|
+
# FieldableEntityInterface extends EntityInterface FieldableEntityInterface.php:23
|
|
124
|
+
# ConfigEntityInterface extends EntityInterface, ... ConfigEntityInterface.php:14
|
|
125
|
+
# ConfigEntityBase extends EntityBase implements ConfigEntityInterface
|
|
126
|
+
# ConfigEntityBase.php:26
|
|
127
|
+
# => same diamond on the entity side.
|
|
128
|
+
# ------------------------------------------------------------------------------------
|
|
129
|
+
# Each name below is a boundary with no classification (~).
|
|
130
|
+
names:
|
|
131
|
+
# Form API
|
|
132
|
+
"Drupal\\Core\\Form\\FormInterface": ~
|
|
133
|
+
"Drupal\\Core\\Form\\FormBase": ~
|
|
134
|
+
"Drupal\\Core\\Form\\ConfirmFormInterface": ~
|
|
135
|
+
"Drupal\\Core\\Form\\ConfirmFormBase": ~
|
|
136
|
+
"Drupal\\Core\\Form\\BaseFormIdInterface": ~
|
|
137
|
+
"Drupal\\Core\\Entity\\EntityFormInterface": ~
|
|
138
|
+
"Drupal\\Core\\Entity\\EntityForm": ~
|
|
139
|
+
"Drupal\\Core\\Entity\\ContentEntityFormInterface": ~
|
|
140
|
+
"Drupal\\Core\\Entity\\ContentEntityForm": ~
|
|
141
|
+
|
|
142
|
+
# Entity API
|
|
143
|
+
"Drupal\\Core\\Entity\\EntityInterface": ~
|
|
144
|
+
"Drupal\\Core\\Entity\\EntityBase": ~
|
|
145
|
+
"Drupal\\Core\\Entity\\FieldableEntityInterface": ~
|
|
146
|
+
"Drupal\\Core\\Entity\\ContentEntityInterface": ~
|
|
147
|
+
"Drupal\\Core\\Entity\\ContentEntityBase": ~
|
|
148
|
+
"Drupal\\Core\\Config\\Entity\\ConfigEntityInterface": ~
|
|
149
|
+
"Drupal\\Core\\Config\\Entity\\ConfigEntityBase": ~
|
|
150
|
+
|
|
151
|
+
# Cache API. Both are standalone: neither extends another interface.
|
|
152
|
+
# CacheBackendInterface.php:16 / CacheTagsInvalidatorInterface.php:14
|
|
153
|
+
"Drupal\\Core\\Cache\\CacheBackendInterface": ~
|
|
154
|
+
"Drupal\\Core\\Cache\\CacheTagsInvalidatorInterface": ~
|
|
155
|
+
|
|
156
|
+
# ------------------------------------------------------------------------------------
|
|
157
|
+
# Deliberately NOT shipped, so the unknown path is exercised by real code.
|
|
158
|
+
#
|
|
159
|
+
# Nothing below appears in names. Each is referenced by first-party code in the
|
|
160
|
+
# worked example, so each becomes a boundary node whose state is `referenced` rather
|
|
161
|
+
# than `declared`: the edge kind is known, because `implements` is written at the site,
|
|
162
|
+
# but nothing describes what the target is.
|
|
163
|
+
#
|
|
164
|
+
# Symfony\Component\EventDispatcher\EventSubscriberInterface
|
|
165
|
+
# vendor/symfony/event-dispatcher/EventSubscriberInterface.php
|
|
166
|
+
# 11 first-party files implement it across the three example modules.
|
|
167
|
+
#
|
|
168
|
+
# Drupal\Core\Entity\EntityTypeListenerInterface
|
|
169
|
+
# core/lib/Drupal/Core/Entity/EntityTypeListenerInterface.php:8
|
|
170
|
+
#
|
|
171
|
+
# Drupal\Core\Form\WorkspaceDynamicSafeFormInterface
|
|
172
|
+
# core/lib/Drupal/Core/Form/WorkspaceDynamicSafeFormInterface.php:15
|
|
173
|
+
#
|
|
174
|
+
# Drupal\Core\Entity\EntityPublishedInterface
|
|
175
|
+
# core/lib/Drupal/Core/Entity/EntityPublishedInterface.php:10
|
|
176
|
+
# Note this one extends EntityInterface. Leaving it out costs nothing, because
|
|
177
|
+
# Redirect still types correctly as a content entity through ContentEntityBase.
|
|
178
|
+
# That is graceful degradation demonstrated rather than claimed.
|
|
179
|
+
#
|
|
180
|
+
# The Plugin API is also dark, incidentally rather than by design: ControllerBase,
|
|
181
|
+
# PluginBase, QueueWorkerBase, DeriverBase, ActionBase, FieldItemBase and
|
|
182
|
+
# ContainerFactoryPluginInterface all appear in the example modules and none is
|
|
183
|
+
# described here. That is what a real first pack looks like.
|
|
184
|
+
# ------------------------------------------------------------------------------------
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
$schema: "https://periplus.dev/schema/0/pack-file.schema.json"
|
|
2
|
+
|
|
3
|
+
# drupal pack — declares the field plugin types.
|
|
4
|
+
|
|
5
|
+
node_types:
|
|
6
|
+
|
|
7
|
+
- name: drupal.field_type
|
|
8
|
+
parent: drupal.plugin
|
|
9
|
+
id_namespace: drupal.plugin.field_type
|
|
10
|
+
|
|
11
|
+
- name: drupal.field_widget
|
|
12
|
+
parent: drupal.plugin
|
|
13
|
+
id_namespace: drupal.plugin.field_widget
|
|
14
|
+
|
|
15
|
+
- name: drupal.field_formatter
|
|
16
|
+
parent: drupal.plugin
|
|
17
|
+
id_namespace: drupal.plugin.field_formatter
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
$schema: "https://periplus.dev/schema/0/pack-file.schema.json"
|
|
2
|
+
|
|
3
|
+
# drupal pack — plugins declared by a docblock annotation. One rule per plugin type, and
|
|
4
|
+
# they differ only in two values.
|
|
5
|
+
#
|
|
6
|
+
# Written to test whether twelve annotation classes need twelve mechanisms. They do not.
|
|
7
|
+
# Every one is @Name(key = "value") in a docblock, so one grammar reads all of them, and a
|
|
8
|
+
# rule differs from its neighbour by the annotation name and the type it emits.
|
|
9
|
+
|
|
10
|
+
needs:
|
|
11
|
+
types:
|
|
12
|
+
- drupal.field_type
|
|
13
|
+
- drupal.field_widget
|
|
14
|
+
- drupal.field_formatter
|
|
15
|
+
rules:
|
|
16
|
+
- rule: field_type_from_annotation
|
|
17
|
+
reads: file
|
|
18
|
+
in:
|
|
19
|
+
- custom_module
|
|
20
|
+
match:
|
|
21
|
+
annotation: FieldType
|
|
22
|
+
grammar: doctrine-annotation
|
|
23
|
+
where:
|
|
24
|
+
- applies_to: class_declaration
|
|
25
|
+
id: &id001
|
|
26
|
+
from:
|
|
27
|
+
annotation_key: id
|
|
28
|
+
must_be: string_literal
|
|
29
|
+
template: drupal.plugin.field_type::{id}
|
|
30
|
+
on_miss: unresolved
|
|
31
|
+
emits:
|
|
32
|
+
- node:
|
|
33
|
+
type: drupal.field_type
|
|
34
|
+
confidence: declared
|
|
35
|
+
- rule: field_widget_from_annotation
|
|
36
|
+
reads: file
|
|
37
|
+
in:
|
|
38
|
+
- custom_module
|
|
39
|
+
match:
|
|
40
|
+
annotation: FieldWidget
|
|
41
|
+
grammar: doctrine-annotation
|
|
42
|
+
where:
|
|
43
|
+
- applies_to: class_declaration
|
|
44
|
+
id: &id002
|
|
45
|
+
from:
|
|
46
|
+
annotation_key: id
|
|
47
|
+
must_be: string_literal
|
|
48
|
+
template: drupal.plugin.field_widget::{id}
|
|
49
|
+
on_miss: unresolved
|
|
50
|
+
emits:
|
|
51
|
+
- node:
|
|
52
|
+
type: drupal.field_widget
|
|
53
|
+
confidence: declared
|
|
54
|
+
- rule: field_formatter_from_annotation
|
|
55
|
+
reads: file
|
|
56
|
+
in:
|
|
57
|
+
- custom_module
|
|
58
|
+
match:
|
|
59
|
+
annotation: FieldFormatter
|
|
60
|
+
grammar: doctrine-annotation
|
|
61
|
+
where:
|
|
62
|
+
- applies_to: class_declaration
|
|
63
|
+
id: &id003
|
|
64
|
+
from:
|
|
65
|
+
annotation_key: id
|
|
66
|
+
must_be: string_literal
|
|
67
|
+
template: drupal.plugin.field_formatter::{id}
|
|
68
|
+
on_miss: unresolved
|
|
69
|
+
emits:
|
|
70
|
+
- node:
|
|
71
|
+
type: drupal.field_formatter
|
|
72
|
+
confidence: declared
|
|
73
|
+
- rule: field_type_from_annotation_edges
|
|
74
|
+
reads: file
|
|
75
|
+
in:
|
|
76
|
+
- custom_module
|
|
77
|
+
match:
|
|
78
|
+
annotation: FieldType
|
|
79
|
+
grammar: doctrine-annotation
|
|
80
|
+
where:
|
|
81
|
+
- applies_to: class_declaration
|
|
82
|
+
emits:
|
|
83
|
+
- edge:
|
|
84
|
+
kind: plugin_class
|
|
85
|
+
from: this_node
|
|
86
|
+
to: enclosing_class
|
|
87
|
+
confidence: declared
|
|
88
|
+
id: *id001
|
|
89
|
+
- rule: field_widget_from_annotation_edges
|
|
90
|
+
reads: file
|
|
91
|
+
in:
|
|
92
|
+
- custom_module
|
|
93
|
+
match:
|
|
94
|
+
annotation: FieldWidget
|
|
95
|
+
grammar: doctrine-annotation
|
|
96
|
+
where:
|
|
97
|
+
- applies_to: class_declaration
|
|
98
|
+
emits:
|
|
99
|
+
- edge:
|
|
100
|
+
kind: plugin_class
|
|
101
|
+
from: this_node
|
|
102
|
+
to: enclosing_class
|
|
103
|
+
confidence: declared
|
|
104
|
+
id: *id002
|
|
105
|
+
- rule: field_formatter_from_annotation_edges
|
|
106
|
+
reads: file
|
|
107
|
+
in:
|
|
108
|
+
- custom_module
|
|
109
|
+
match:
|
|
110
|
+
annotation: FieldFormatter
|
|
111
|
+
grammar: doctrine-annotation
|
|
112
|
+
where:
|
|
113
|
+
- applies_to: class_declaration
|
|
114
|
+
emits:
|
|
115
|
+
- edge:
|
|
116
|
+
kind: plugin_class
|
|
117
|
+
from: this_node
|
|
118
|
+
to: enclosing_class
|
|
119
|
+
confidence: declared
|
|
120
|
+
id: *id003
|