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.
Files changed (272) hide show
  1. periplus/__init__.py +70 -0
  2. periplus/checkmap.py +80 -0
  3. periplus/cli.py +658 -0
  4. periplus/contract/schema/map.schema.json +138 -0
  5. periplus/contract/schema/navigation.schema.json +200 -0
  6. periplus/contract/schema/pack-file.schema.json +1405 -0
  7. periplus/contract/schema/pack-manifest.schema.json +245 -0
  8. periplus/contract/schema/project-settings.schema.json +85 -0
  9. periplus/contract/spec/engine.md +151 -0
  10. periplus/contract/spec/rules.md +352 -0
  11. periplus/detect.py +228 -0
  12. periplus/engine/__init__.py +5 -0
  13. periplus/engine/check.py +481 -0
  14. periplus/engine/emit.py +368 -0
  15. periplus/engine/packload.py +2321 -0
  16. periplus/engine/pattern.py +27 -0
  17. periplus/engine/rules.py +1946 -0
  18. periplus/engine/select.py +491 -0
  19. periplus/engine/source.py +172 -0
  20. periplus/engine/tree.py +424 -0
  21. periplus/errors.py +332 -0
  22. periplus/init.py +358 -0
  23. periplus/layout.py +28 -0
  24. periplus/manifest.py +498 -0
  25. periplus/map.py +364 -0
  26. periplus/navigate/__init__.py +1 -0
  27. periplus/navigate/find.py +143 -0
  28. periplus/navigate/ids.py +30 -0
  29. periplus/navigate/listing.py +42 -0
  30. periplus/navigate/mapfile.py +189 -0
  31. periplus/navigate/path.py +175 -0
  32. periplus/navigate/show.py +175 -0
  33. periplus/navigate/types.py +83 -0
  34. periplus/navigate/walk.py +138 -0
  35. periplus/packs/advancedqueue_basic@0.0.1/pack.yaml +14 -0
  36. periplus/packs/advancedqueue_basic@0.0.1/queue_job_type/queue_job_type.yaml +9 -0
  37. periplus/packs/advancedqueue_basic@0.0.1/queue_job_type/queue_job_type_annotation.yaml +43 -0
  38. periplus/packs/advancedqueue_basic@0.0.1/queue_job_type/queue_job_type_attribute.yaml +43 -0
  39. periplus/packs/ai_basic@0.0.1/ai_agent/ai_agent.yaml +8 -0
  40. periplus/packs/ai_basic@0.0.1/ai_agent/ai_agent_attribute.yaml +43 -0
  41. periplus/packs/ai_basic@0.0.1/ai_function_call/ai_function_call.yaml +8 -0
  42. periplus/packs/ai_basic@0.0.1/ai_function_call/ai_function_call_attribute.yaml +43 -0
  43. periplus/packs/ai_basic@0.0.1/pack.yaml +15 -0
  44. periplus/packs/config_pages_basic@0.0.1/bundle/config_pages_bundle_config.yaml +54 -0
  45. periplus/packs/config_pages_basic@0.0.1/pack.yaml +11 -0
  46. periplus/packs/crop_basic@0.0.1/bundle/crop_bundle_config.yaml +54 -0
  47. periplus/packs/crop_basic@0.0.1/pack.yaml +11 -0
  48. periplus/packs/drupal@0.1.0/block/block_placement.yaml +25 -0
  49. periplus/packs/drupal@0.1.0/block/block_placement_code.yaml +58 -0
  50. periplus/packs/drupal@0.1.0/block/block_placement_config.yaml +53 -0
  51. periplus/packs/drupal@0.1.0/block/block_plugin.yaml +52 -0
  52. periplus/packs/drupal@0.1.0/block/block_plugin_altered.yaml +61 -0
  53. periplus/packs/drupal@0.1.0/block/block_plugin_annotation.yaml +69 -0
  54. periplus/packs/drupal@0.1.0/block/block_plugin_attribute.yaml +56 -0
  55. periplus/packs/drupal@0.1.0/block/block_plugin_content.yaml +46 -0
  56. periplus/packs/drupal@0.1.0/block/block_plugin_derived.yaml +110 -0
  57. periplus/packs/drupal@0.1.0/block/block_plugin_deriver.yaml +30 -0
  58. periplus/packs/drupal@0.1.0/block/block_type.yaml +14 -0
  59. periplus/packs/drupal@0.1.0/block/block_type_code.yaml +43 -0
  60. periplus/packs/drupal@0.1.0/block/block_type_config.yaml +45 -0
  61. periplus/packs/drupal@0.1.0/cache/cache.yaml +18 -0
  62. periplus/packs/drupal@0.1.0/cache/cache_backend.yaml +31 -0
  63. periplus/packs/drupal@0.1.0/component/sdc.yaml +19 -0
  64. periplus/packs/drupal@0.1.0/component/sdc_definition.yaml +25 -0
  65. periplus/packs/drupal@0.1.0/component/sdc_use.yaml +25 -0
  66. periplus/packs/drupal@0.1.0/config/config_object.yaml +65 -0
  67. periplus/packs/drupal@0.1.0/display/display.yaml +32 -0
  68. periplus/packs/drupal@0.1.0/display/display_code.yaml +53 -0
  69. periplus/packs/drupal@0.1.0/display/display_config.yaml +95 -0
  70. periplus/packs/drupal@0.1.0/entity/entity.yaml +33 -0
  71. periplus/packs/drupal@0.1.0/entity/entity_class.yaml +60 -0
  72. periplus/packs/drupal@0.1.0/entity/entity_save.yaml +27 -0
  73. periplus/packs/drupal@0.1.0/entity/entity_type_annotation.yaml +85 -0
  74. periplus/packs/drupal@0.1.0/entity/entity_type_attribute.yaml +76 -0
  75. periplus/packs/drupal@0.1.0/field/field_instance_code.yaml +40 -0
  76. periplus/packs/drupal@0.1.0/field/field_instance_config.yaml +58 -0
  77. periplus/packs/drupal@0.1.0/field/field_storage.yaml +37 -0
  78. periplus/packs/drupal@0.1.0/field/field_storage_code.yaml +39 -0
  79. periplus/packs/drupal@0.1.0/field/field_storage_config.yaml +24 -0
  80. periplus/packs/drupal@0.1.0/form/form.yaml +48 -0
  81. periplus/packs/drupal@0.1.0/form/form_class.yaml +50 -0
  82. periplus/packs/drupal@0.1.0/form/form_id.yaml +48 -0
  83. periplus/packs/drupal@0.1.0/form/form_methods.yaml +39 -0
  84. periplus/packs/drupal@0.1.0/hook/hook.yaml +8 -0
  85. periplus/packs/drupal@0.1.0/hook/hook_attribute.yaml +28 -0
  86. periplus/packs/drupal@0.1.0/module/module.yaml +8 -0
  87. periplus/packs/drupal@0.1.0/module/module_info.yaml +50 -0
  88. periplus/packs/drupal@0.1.0/pack.yaml +184 -0
  89. periplus/packs/drupal@0.1.0/plugin/plugin.yaml +17 -0
  90. periplus/packs/drupal@0.1.0/plugin/plugin_annotation.yaml +120 -0
  91. periplus/packs/drupal@0.1.0/recommendations/recommendations.yaml +14 -0
  92. periplus/packs/drupal@0.1.0/service/service.yaml +19 -0
  93. periplus/packs/drupal@0.1.0/service/service_autowire.yaml +28 -0
  94. periplus/packs/drupal@0.1.0/service/service_definition.yaml +24 -0
  95. periplus/packs/drupal@0.1.0/service/service_use.yaml +43 -0
  96. periplus/packs/drupal_basic@0.3.0/action/action.yaml +9 -0
  97. periplus/packs/drupal_basic@0.3.0/action/action_annotation.yaml +43 -0
  98. periplus/packs/drupal_basic@0.3.0/action/action_attribute.yaml +43 -0
  99. periplus/packs/drupal_basic@0.3.0/block/block_placement.yaml +16 -0
  100. periplus/packs/drupal_basic@0.3.0/block/block_placement_config.yaml +51 -0
  101. periplus/packs/drupal_basic@0.3.0/block_plugin/block_plugin.yaml +14 -0
  102. periplus/packs/drupal_basic@0.3.0/block_plugin/block_plugin_annotation.yaml +47 -0
  103. periplus/packs/drupal_basic@0.3.0/block_plugin/block_plugin_attribute.yaml +43 -0
  104. periplus/packs/drupal_basic@0.3.0/block_type/block_type.yaml +8 -0
  105. periplus/packs/drupal_basic@0.3.0/block_type/block_type_config.yaml +54 -0
  106. periplus/packs/drupal_basic@0.3.0/boundary/boundary_types.yaml +19 -0
  107. periplus/packs/drupal_basic@0.3.0/bundle/bundle.yaml +20 -0
  108. periplus/packs/drupal_basic@0.3.0/bundle/bundle_config.yaml +393 -0
  109. periplus/packs/drupal_basic@0.3.0/call/call.yaml +349 -0
  110. periplus/packs/drupal_basic@0.3.0/component/component.yaml +30 -0
  111. periplus/packs/drupal_basic@0.3.0/config/config_object.yaml +119 -0
  112. periplus/packs/drupal_basic@0.3.0/constraint/constraint.yaml +8 -0
  113. periplus/packs/drupal_basic@0.3.0/constraint/constraint_annotation.yaml +43 -0
  114. periplus/packs/drupal_basic@0.3.0/constraint/constraint_attribute.yaml +43 -0
  115. periplus/packs/drupal_basic@0.3.0/display/display.yaml +30 -0
  116. periplus/packs/drupal_basic@0.3.0/display/display_config.yaml +203 -0
  117. periplus/packs/drupal_basic@0.3.0/display/display_mode_config.yaml +60 -0
  118. periplus/packs/drupal_basic@0.3.0/entity_type/config_entity_type_annotation.yaml +46 -0
  119. periplus/packs/drupal_basic@0.3.0/entity_type/config_entity_type_attribute.yaml +43 -0
  120. periplus/packs/drupal_basic@0.3.0/entity_type/content_entity_type_annotation.yaml +46 -0
  121. periplus/packs/drupal_basic@0.3.0/entity_type/content_entity_type_attribute.yaml +43 -0
  122. periplus/packs/drupal_basic@0.3.0/entity_type/entity_type.yaml +16 -0
  123. periplus/packs/drupal_basic@0.3.0/field/field_instance_config.yaml +116 -0
  124. periplus/packs/drupal_basic@0.3.0/field/field_storage.yaml +21 -0
  125. periplus/packs/drupal_basic@0.3.0/field/field_storage_config.yaml +45 -0
  126. periplus/packs/drupal_basic@0.3.0/field_formatter/field_formatter.yaml +8 -0
  127. periplus/packs/drupal_basic@0.3.0/field_formatter/field_formatter_annotation.yaml +46 -0
  128. periplus/packs/drupal_basic@0.3.0/field_formatter/field_formatter_attribute.yaml +43 -0
  129. periplus/packs/drupal_basic@0.3.0/field_type/field_type_annotation.yaml +46 -0
  130. periplus/packs/drupal_basic@0.3.0/field_type/field_type_attribute.yaml +50 -0
  131. periplus/packs/drupal_basic@0.3.0/field_widget/field_widget_annotation.yaml +46 -0
  132. periplus/packs/drupal_basic@0.3.0/field_widget/field_widget_attribute.yaml +50 -0
  133. periplus/packs/drupal_basic@0.3.0/form/form_id.yaml +80 -0
  134. periplus/packs/drupal_basic@0.3.0/hook/hook.yaml +100 -0
  135. periplus/packs/drupal_basic@0.3.0/hook/hook_attribute.yaml +64 -0
  136. periplus/packs/drupal_basic@0.3.0/hook/hook_theme_include.yaml +34 -0
  137. periplus/packs/drupal_basic@0.3.0/library/library.yaml +12 -0
  138. periplus/packs/drupal_basic@0.3.0/library/library_definition.yaml +58 -0
  139. periplus/packs/drupal_basic@0.3.0/local_action/local_action.yaml +12 -0
  140. periplus/packs/drupal_basic@0.3.0/local_action/local_action_definition.yaml +49 -0
  141. periplus/packs/drupal_basic@0.3.0/mail/mail.yaml +8 -0
  142. periplus/packs/drupal_basic@0.3.0/mail/mail_attribute.yaml +43 -0
  143. periplus/packs/drupal_basic@0.3.0/media_source/media_source.yaml +8 -0
  144. periplus/packs/drupal_basic@0.3.0/media_source/media_source_annotation.yaml +43 -0
  145. periplus/packs/drupal_basic@0.3.0/media_source/media_source_attribute.yaml +79 -0
  146. periplus/packs/drupal_basic@0.3.0/menu_link/menu_link.yaml +18 -0
  147. periplus/packs/drupal_basic@0.3.0/menu_link/menu_link_definition.yaml +48 -0
  148. periplus/packs/drupal_basic@0.3.0/module/module.yaml +7 -0
  149. periplus/packs/drupal_basic@0.3.0/module/module_info.yaml +58 -0
  150. periplus/packs/drupal_basic@0.3.0/pack.yaml +528 -0
  151. periplus/packs/drupal_basic@0.3.0/permission/permission.yaml +7 -0
  152. periplus/packs/drupal_basic@0.3.0/permission/permission_definition.yaml +27 -0
  153. periplus/packs/drupal_basic@0.3.0/queue_worker/queue_worker.yaml +9 -0
  154. periplus/packs/drupal_basic@0.3.0/queue_worker/queue_worker_annotation.yaml +43 -0
  155. periplus/packs/drupal_basic@0.3.0/queue_worker/queue_worker_attribute.yaml +43 -0
  156. periplus/packs/drupal_basic@0.3.0/rest_resource/rest_resource.yaml +8 -0
  157. periplus/packs/drupal_basic@0.3.0/rest_resource/rest_resource_annotation.yaml +43 -0
  158. periplus/packs/drupal_basic@0.3.0/rest_resource/rest_resource_attribute.yaml +43 -0
  159. periplus/packs/drupal_basic@0.3.0/role/role.yaml +14 -0
  160. periplus/packs/drupal_basic@0.3.0/role/role_config.yaml +44 -0
  161. periplus/packs/drupal_basic@0.3.0/route/route.yaml +42 -0
  162. periplus/packs/drupal_basic@0.3.0/route/route_definition.yaml +113 -0
  163. periplus/packs/drupal_basic@0.3.0/route/route_options.yaml +55 -0
  164. periplus/packs/drupal_basic@0.3.0/route/route_requirements.yaml +108 -0
  165. periplus/packs/drupal_basic@0.3.0/service/service.yaml +56 -0
  166. periplus/packs/drupal_basic@0.3.0/service/service_definition.yaml +181 -0
  167. periplus/packs/drupal_basic@0.3.0/template/template.yaml +86 -0
  168. periplus/packs/drupal_basic@0.3.0/template/template_route_link.yaml +30 -0
  169. periplus/packs/drupal_basic@0.3.0/theme/theme.yaml +15 -0
  170. periplus/packs/drupal_basic@0.3.0/theme/theme_info.yaml +61 -0
  171. periplus/packs/drupal_basic@0.3.0/theme_hook/template_suggestion.yaml +29 -0
  172. periplus/packs/drupal_basic@0.3.0/theme_hook/theme_hook.yaml +87 -0
  173. periplus/packs/drupal_basic@0.3.0/theme_hook/theme_hook_render.yaml +20 -0
  174. periplus/packs/drupal_basic@0.3.0/url/url.yaml +88 -0
  175. periplus/packs/drupal_basic@0.3.0/views_plugin/views_field_attribute.yaml +80 -0
  176. periplus/packs/drupal_basic@0.3.0/views_plugin/views_filter_attribute.yaml +80 -0
  177. periplus/packs/drupal_basic@0.3.0/views_plugin/views_plugin.yaml +15 -0
  178. periplus/packs/drupal_basic@0.3.0/views_plugin/views_style_attribute.yaml +80 -0
  179. periplus/packs/drupal_js_basic@0.0.1/attachment/attachment.yaml +12 -0
  180. periplus/packs/drupal_js_basic@0.0.1/attachment/attachment_in_php.yaml +15 -0
  181. periplus/packs/drupal_js_basic@0.0.1/attachment/attachment_in_php_array.yaml +52 -0
  182. periplus/packs/drupal_js_basic@0.0.1/attachment/attachment_in_twig.yaml +26 -0
  183. periplus/packs/drupal_js_basic@0.0.1/attachment/php_function_holder.yaml +13 -0
  184. periplus/packs/drupal_js_basic@0.0.1/behavior/behavior.yaml +198 -0
  185. periplus/packs/drupal_js_basic@0.0.1/pack.yaml +153 -0
  186. periplus/packs/drupal_js_basic@0.0.1/setting/setting.yaml +13 -0
  187. periplus/packs/drupal_js_basic@0.0.1/setting/setting_in_js.yaml +15 -0
  188. periplus/packs/drupal_js_basic@0.0.1/setting/setting_in_php.yaml +92 -0
  189. periplus/packs/drush_basic@0.0.1/command/command.yaml +15 -0
  190. periplus/packs/drush_basic@0.0.1/command/command_annotation.yaml +60 -0
  191. periplus/packs/drush_basic@0.0.1/command/command_attribute.yaml +88 -0
  192. periplus/packs/drush_basic@0.0.1/pack.yaml +29 -0
  193. periplus/packs/eck_basic@0.0.1/bundle/eck_bundle_config.yaml +56 -0
  194. periplus/packs/eck_basic@0.0.1/entity_type/eck_entity_type_config.yaml +26 -0
  195. periplus/packs/eck_basic@0.0.1/pack.yaml +28 -0
  196. periplus/packs/go@0.0.2/interfaces/satisfies.yaml +47 -0
  197. periplus/packs/go@0.0.2/pack.yaml +51 -0
  198. periplus/packs/go@0.0.2/types/find_declarations.yaml +137 -0
  199. periplus/packs/go@0.0.2/types/node_types.yaml +36 -0
  200. periplus/packs/go_basic@0.0.3/pack.yaml +104 -0
  201. periplus/packs/go_basic@0.0.3/rules/calls.yaml +25 -0
  202. periplus/packs/go_basic@0.0.3/rules/declarations.yaml +40 -0
  203. periplus/packs/go_basic@0.0.3/rules/imports.yaml +16 -0
  204. periplus/packs/go_basic@0.0.3/types/node_types.yaml +15 -0
  205. periplus/packs/js_basic@0.0.1/function/function.yaml +68 -0
  206. periplus/packs/js_basic@0.0.1/pack.yaml +50 -0
  207. periplus/packs/laravel_basic@0.0.5/pack.yaml +313 -0
  208. periplus/packs/laravel_basic@0.0.5/rules/classes.yaml +42 -0
  209. periplus/packs/laravel_basic@0.0.5/rules/config.yaml +229 -0
  210. periplus/packs/laravel_basic@0.0.5/rules/routes.yaml +210 -0
  211. periplus/packs/laravel_basic@0.0.5/rules/types.yaml +50 -0
  212. periplus/packs/laravel_basic@0.0.5/rules/views.yaml +100 -0
  213. periplus/packs/paragraphs_basic@0.0.1/bundle/paragraph_bundle_config.yaml +54 -0
  214. periplus/packs/paragraphs_basic@0.0.1/pack.yaml +12 -0
  215. periplus/packs/php@0.1.0/edges/edge_kinds.yaml +64 -0
  216. periplus/packs/php@0.1.0/edges/find_calls.yaml +34 -0
  217. periplus/packs/php@0.1.0/edges/find_imports.yaml +18 -0
  218. periplus/packs/php@0.1.0/edges/find_member_access.yaml +22 -0
  219. periplus/packs/php@0.1.0/edges/find_structure.yaml +38 -0
  220. periplus/packs/php@0.1.0/embedded/embedded_regions.yaml +19 -0
  221. periplus/packs/php@0.1.0/imports/imports.yaml +20 -0
  222. periplus/packs/php@0.1.0/pack.yaml +117 -0
  223. periplus/packs/php@0.1.0/resolution/excluded_tokens.yaml +23 -0
  224. periplus/packs/php@0.1.0/resolution/resolution.yaml +35 -0
  225. periplus/packs/php@0.1.0/types/find_declarations.yaml +102 -0
  226. periplus/packs/php@0.1.0/types/node_types.yaml +55 -0
  227. periplus/packs/php_basic@0.2.0/edges/edge_kinds.yaml +48 -0
  228. periplus/packs/php_basic@0.2.0/edges/find_structure.yaml +750 -0
  229. periplus/packs/php_basic@0.2.0/imports/imports.yaml +19 -0
  230. periplus/packs/php_basic@0.2.0/pack.yaml +94 -0
  231. periplus/packs/php_basic@0.2.0/types/find_declarations.yaml +267 -0
  232. periplus/packs/php_basic@0.2.0/types/node_types.yaml +55 -0
  233. periplus/packs/profile_basic@0.0.1/bundle/profile_bundle_config.yaml +54 -0
  234. periplus/packs/profile_basic@0.0.1/pack.yaml +12 -0
  235. periplus/packs/salesforce_basic@0.0.1/event/salesforce_event.yaml +36 -0
  236. periplus/packs/salesforce_basic@0.0.1/pack.yaml +31 -0
  237. periplus/packs/salesforce_basic@0.0.1/salesforce_mapping/salesforce_mapping.yaml +19 -0
  238. periplus/packs/salesforce_basic@0.0.1/salesforce_mapping/salesforce_mapping_config.yaml +83 -0
  239. periplus/packs/salesforce_basic@0.0.1/salesforce_mapping_field/salesforce_mapping_field.yaml +8 -0
  240. periplus/packs/salesforce_basic@0.0.1/salesforce_mapping_field/salesforce_mapping_field_annotation.yaml +43 -0
  241. periplus/packs/twig@0.0.1/pack.yaml +26 -0
  242. periplus/packs/twig@0.0.1/types/template.yaml +57 -0
  243. periplus/packs/twig_basic@0.1.0/pack.yaml +11 -0
  244. periplus/packs/twig_tweak_basic@0.0.1/pack.yaml +27 -0
  245. periplus/packs/twig_tweak_basic@0.0.1/rules/block.yaml +20 -0
  246. periplus/packs/twig_tweak_basic@0.0.1/rules/entity.yaml +35 -0
  247. periplus/packs/twig_tweak_basic@0.0.1/rules/field.yaml +21 -0
  248. periplus/packs/twig_tweak_basic@0.0.1/rules/menu.yaml +21 -0
  249. periplus/packs/webform_basic@0.0.1/bundle/webform_submission_bundle_config.yaml +54 -0
  250. periplus/packs/webform_basic@0.0.1/pack.yaml +20 -0
  251. periplus/packs/webform_basic@0.0.1/webform_handler/webform_handler.yaml +8 -0
  252. periplus/packs/webform_basic@0.0.1/webform_handler/webform_handler_annotation.yaml +43 -0
  253. periplus/packs/yaml@0.0.1/pack.yaml +72 -0
  254. periplus/packs/yaml@0.0.1/types/find_mapping_entry.yaml +21 -0
  255. periplus/packs/yaml@0.0.1/types/yaml_types.yaml +44 -0
  256. periplus/packs/yaml_basic@0.1.0/pack.yaml +10 -0
  257. periplus/packs.py +447 -0
  258. periplus/preflight.py +102 -0
  259. periplus/py.typed +0 -0
  260. periplus/report.py +596 -0
  261. periplus/resolution.py +355 -0
  262. periplus/settings.py +617 -0
  263. periplus/settings.stub.yml +99 -0
  264. periplus/spec.py +774 -0
  265. periplus/update.py +197 -0
  266. periplus/validate.py +655 -0
  267. periplus_map-0.2.1.dist-info/METADATA +566 -0
  268. periplus_map-0.2.1.dist-info/RECORD +272 -0
  269. periplus_map-0.2.1.dist-info/WHEEL +4 -0
  270. periplus_map-0.2.1.dist-info/entry_points.txt +2 -0
  271. periplus_map-0.2.1.dist-info/licenses/LICENSE +202 -0
  272. periplus_map-0.2.1.dist-info/licenses/NOTICE +2 -0
@@ -0,0 +1,15 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-file.schema.json"
2
+
3
+ rules:
4
+ # $x['#attached']['library'][] = 'module/library' in a method: the class attaches the library.
5
+ - rule: library_attached_in_class
6
+ reads: file
7
+ in: [source]
8
+ match:
9
+ declaration: assignment_expression
10
+ name_child: right
11
+ filetype: php
12
+ where: [{name_matches: {child: left, pattern: '(?s).*\[\s*[''"]#attached[''"]\s*\]\s*\[\s*[''"]library[''"]\s*\]\s*\[\s*\]'}}]
13
+ id: {from: declared_name, pattern: '^[''"](?<library>[^''"]+)[''"]$', template: '{library}'}
14
+ emits: [{edge: {kind: attaches_library, from: enclosing_class, to: this_node}}]
15
+ confidence: declared
@@ -0,0 +1,52 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-file.schema.json"
2
+
3
+ rules:
4
+ # '#attached' => ['library' => ['module/library', ...]] in a class file under src: each text in
5
+ # the list is a library the class attaches. The id names both spans, so a text outside either
6
+ # one makes nothing.
7
+ - rule: library_attached_in_array
8
+ reads: file
9
+ in: [source]
10
+ match:
11
+ file: '**'
12
+ filetype: drupal_php_text
13
+ text: '[\[,\s][''"](?<library>[A-Za-z0-9_]+/[\w.-]+)[''"]\s*[,\]]'
14
+ values:
15
+ in_attached: {from: {enclosing: attached, capture: mark}}
16
+ in_library: {from: {enclosing: library_list, capture: mark}}
17
+ id:
18
+ template: '{in_attached}|{in_library}|{library}'
19
+ normalize:
20
+ - {replace: '^.*\|', with: ''}
21
+ line: {capture: library}
22
+ emits:
23
+ - edge:
24
+ kind: attaches_library
25
+ from: {template: '{psr4_class}', types: [php.class]}
26
+ to: this_node
27
+ confidence: inferred
28
+ # The same list in a function of a procedural file, such as a hook in a .module file: the
29
+ # function attaches the library. Its node is the one php_basic makes for the function.
30
+ - rule: library_attached_in_array_in_function
31
+ reads: file
32
+ in: [source]
33
+ match:
34
+ file: '**'
35
+ filetype: drupal_php_text
36
+ ending: [module, theme, inc, install, profile]
37
+ text: '[\[,\s][''"](?<library>[A-Za-z0-9_]+/[\w.-]+)[''"]\s*[,\]]'
38
+ values:
39
+ in_attached: {from: {enclosing: attached, capture: mark}}
40
+ in_library: {from: {enclosing: library_list, capture: mark}}
41
+ fn: {from: {enclosing: function_body, capture: name}}
42
+ id:
43
+ template: '{in_attached}|{in_library}|{library}'
44
+ normalize:
45
+ - {replace: '^.*\|', with: ''}
46
+ line: {capture: library}
47
+ emits:
48
+ - edge:
49
+ kind: attaches_library
50
+ from: {template: '{fn}', types: [php.function]}
51
+ to: this_node
52
+ confidence: inferred
@@ -0,0 +1,26 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-file.schema.json"
2
+
3
+ rules:
4
+ # {{ attach_library('module/library') }}: the template attaches the library.
5
+ - rule: library_attached_in_template
6
+ reads: file
7
+ in: [module_root, theme_root]
8
+ match:
9
+ file: '*.html'
10
+ filetype: drupal_template_text
11
+ text: 'attach_library\(\s*[''"](?<library>[^''"\s]+)[''"]\s*\)'
12
+ id: {template: '{template_name}'}
13
+ emits: [{edge: {kind: template_attaches_library, from: this_node, to: {from: {capture: library}}}}]
14
+ confidence: declared
15
+ # {{ attach_library('module/library') }} in a component's <name>.twig: the component attaches the
16
+ # library. A file with no component_name, such as a <name>.html.twig template, makes nothing.
17
+ - rule: library_attached_in_component
18
+ reads: file
19
+ in: [module_root, theme_root]
20
+ match:
21
+ file: '*'
22
+ filetype: drupal_template_text
23
+ text: 'attach_library\(\s*[''"](?<library>[^''"\s]+)[''"]\s*\)'
24
+ id: {template: '{component_name}'}
25
+ emits: [{edge: {kind: component_attaches_library, from: this_node, to: {from: {capture: library}}}}]
26
+ confidence: declared
@@ -0,0 +1,13 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-file.schema.json"
2
+
3
+ rules:
4
+ # A PHP function holds what its body holds, as a class does. So an attachment written in a
5
+ # function, such as a hook in a .module file, starts its edge at that function. The node is the
6
+ # one php_basic already makes for the function.
7
+ - rule: php_function_holds_body
8
+ reads: file
9
+ in: [source]
10
+ match: {declaration: function_definition, name_child: name, body_child: body, filetype: php}
11
+ id: {from: qualified_name}
12
+ emits: [{node: {type: php.function}}]
13
+ confidence: declared
@@ -0,0 +1,198 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-file.schema.json"
2
+
3
+ node_types:
4
+ - name: drupal.js_behavior
5
+ id_namespace: drupal.js_behavior
6
+ - name: css.file
7
+ id_namespace: css.file
8
+
9
+ edge_kinds:
10
+ - kind: attaches_behavior
11
+ from: drupal.js_behavior
12
+ to: drupal.js_behavior
13
+ - kind: library_includes_script
14
+ from: drupal.library
15
+ to: js.file
16
+ - kind: library_includes_stylesheet
17
+ from: drupal.library
18
+ to: css.file
19
+ - kind: script_declares_behavior
20
+ from: js.file
21
+ to: drupal.js_behavior
22
+ # drupal_basic's links_to_path cannot start at a script: drupal_basic does not depend on js_basic.
23
+ - kind: script_links_to_path
24
+ from: js.file
25
+ to: drupal.url_path
26
+
27
+ rules:
28
+ # Drupal.behaviors.name = {...}: the behavior name. An arrow function or a function expression on
29
+ # the right is read by the rules below; any other value, such as a variable, makes nothing.
30
+ - rule: behavior_from_assignment
31
+ reads: file
32
+ in: [js_source]
33
+ match: {declaration: assignment_expression, name_child: left, body_child: object, filetype: javascript, where: [{has_child: object}]}
34
+ id: {from: declared_name, pattern: '^Drupal\.behaviors\.(?<behavior>[A-Za-z_$][\w$]*)$', template: '{behavior}'}
35
+ emits: [{node: {type: drupal.js_behavior}}]
36
+ confidence: declared
37
+ - rule: behavior_from_assignment_in_file
38
+ reads: file
39
+ in: [js_source]
40
+ match: {declaration: assignment_expression, name_child: left, body_child: object, filetype: javascript, where: [{has_child: object}]}
41
+ id: {from: declared_name, pattern: '^Drupal\.behaviors\.(?<behavior>[A-Za-z_$][\w$]*)$', template: '{behavior}'}
42
+ emits: [{edge: {kind: script_declares_behavior, from: enclosing_file, to: this_node}}]
43
+ confidence: declared
44
+ # Drupal.behaviors.name = (context) => {...}: the behavior name, as for an object.
45
+ # body_child is object, not the function: a function body would end the enclosing-behavior walk
46
+ # at every attach: function () {} or attach: () => {} pair, losing the edges inside it.
47
+ - rule: behavior_from_arrow
48
+ reads: file
49
+ in: [js_source]
50
+ match: {declaration: assignment_expression, name_child: left, body_child: object, filetype: javascript, where: [{has_child: arrow_function}]}
51
+ id: {from: declared_name, pattern: '^Drupal\.behaviors\.(?<behavior>[A-Za-z_$][\w$]*)$', template: '{behavior}'}
52
+ emits: [{node: {type: drupal.js_behavior}}]
53
+ confidence: declared
54
+ - rule: behavior_from_arrow_in_file
55
+ reads: file
56
+ in: [js_source]
57
+ match: {declaration: assignment_expression, name_child: left, body_child: object, filetype: javascript, where: [{has_child: arrow_function}]}
58
+ id: {from: declared_name, pattern: '^Drupal\.behaviors\.(?<behavior>[A-Za-z_$][\w$]*)$', template: '{behavior}'}
59
+ emits: [{edge: {kind: script_declares_behavior, from: enclosing_file, to: this_node}}]
60
+ confidence: declared
61
+ # Drupal.behaviors.name = function (context) {...}: the behavior name, as for an object.
62
+ - rule: behavior_from_function
63
+ reads: file
64
+ in: [js_source]
65
+ match: {declaration: assignment_expression, name_child: left, body_child: object, filetype: javascript, where: [{has_child: function_expression}]}
66
+ id: {from: declared_name, pattern: '^Drupal\.behaviors\.(?<behavior>[A-Za-z_$][\w$]*)$', template: '{behavior}'}
67
+ emits: [{node: {type: drupal.js_behavior}}]
68
+ confidence: declared
69
+ - rule: behavior_from_function_in_file
70
+ reads: file
71
+ in: [js_source]
72
+ match: {declaration: assignment_expression, name_child: left, body_child: object, filetype: javascript, where: [{has_child: function_expression}]}
73
+ id: {from: declared_name, pattern: '^Drupal\.behaviors\.(?<behavior>[A-Za-z_$][\w$]*)$', template: '{behavior}'}
74
+ emits: [{edge: {kind: script_declares_behavior, from: enclosing_file, to: this_node}}]
75
+ confidence: declared
76
+ # Drupal.behaviors.other.attach(...) inside a behavior object: that behavior runs the other one.
77
+ - rule: behavior_attach_call
78
+ reads: file
79
+ in: [js_source]
80
+ match: {declaration: call_expression, name_child: function, filetype: javascript}
81
+ id: {from: declared_name, pattern: '^Drupal\.behaviors\.(?<behavior>[A-Za-z_$][\w$]*)\.attach$', template: '{behavior}'}
82
+ emits: [{edge: {kind: attaches_behavior, from: enclosing_class, to: this_node}}]
83
+ confidence: declared
84
+ # A local script a library lists under js:. The key is the script's path from the libraries file's
85
+ # folder, so that folder joined with the key is the script's path from the project folder. A key
86
+ # that starts with one /, such as /core/misc/drupal.js, is joined to the Drupal root instead, by a
87
+ # second edge in this rule, so a library with no such key leaves no skipped row. A file outside the
88
+ # mapped folders gets a referenced node. A URL, //host/x, makes nothing.
89
+ - rule: library_script
90
+ reads: file
91
+ in:
92
+ - module_root
93
+ - theme_root
94
+ match:
95
+ file: '*.libraries'
96
+ filetype: yml
97
+ each: '*'
98
+ id:
99
+ from:
100
+ - file_stem
101
+ - key
102
+ template: '{file_stem}/{key}'
103
+ normalize:
104
+ - replace: \.libraries/
105
+ with: /
106
+ emits:
107
+ - edge:
108
+ kind: library_includes_script
109
+ from: this_node
110
+ to:
111
+ from:
112
+ - each: js.*
113
+ template: '{libraries_dir}/{key}'
114
+ where:
115
+ - not_matches: /*
116
+ - not_matches: http:*
117
+ - not_matches: https:*
118
+ - edge:
119
+ kind: library_includes_script
120
+ from: this_node
121
+ to:
122
+ from:
123
+ - each: js.*
124
+ template: '{drupal_root}{key}'
125
+ where:
126
+ - matches: /*
127
+ - not_matches: //*
128
+ confidence: declared
129
+ # A local stylesheet a library lists under css:, in any group (base, layout, component, state,
130
+ # theme). Read the same way as library_script; the id is the file's path from the project folder.
131
+ - rule: library_stylesheet
132
+ reads: file
133
+ in:
134
+ - module_root
135
+ - theme_root
136
+ match:
137
+ file: '*.libraries'
138
+ filetype: yml
139
+ each: '*'
140
+ id:
141
+ from:
142
+ - file_stem
143
+ - key
144
+ template: '{file_stem}/{key}'
145
+ normalize:
146
+ - replace: \.libraries/
147
+ with: /
148
+ emits:
149
+ - edge:
150
+ kind: library_includes_stylesheet
151
+ from: this_node
152
+ to:
153
+ from:
154
+ - each: css.*.*
155
+ template: '{libraries_dir}/{key}'
156
+ where:
157
+ - not_matches: /*
158
+ - not_matches: http:*
159
+ - not_matches: https:*
160
+ - edge:
161
+ kind: library_includes_stylesheet
162
+ from: this_node
163
+ to:
164
+ from:
165
+ - each: css.*.*
166
+ template: '{drupal_root}{key}'
167
+ where:
168
+ - matches: /*
169
+ - not_matches: //*
170
+ confidence: declared
171
+ # Each .css file in a module or theme, named by its path from the project folder: the id a
172
+ # library's css: entry builds, so a listed file that exists is a mapped node.
173
+ - rule: stylesheet_file
174
+ reads: file
175
+ in:
176
+ - module_root
177
+ - theme_root
178
+ match: {file: '*', filetype: css_text}
179
+ id: {template: '{stylesheet}'}
180
+ emits: [{node: {type: css.file}}]
181
+ confidence: declared
182
+ # A path a script writes whole as a string, such as let endpoint = "/my/path" or fetch('/my/path'):
183
+ # an edge to the drupal.url_path node route_serves_path meets (drupal_basic url/url.yaml). Read as
184
+ # the type js_text. The string follows a space, (, [, comma, =, : or ?, starts with one / and holds
185
+ # no space, quote, brace or $. So "/", "//cdn.example.com/x" and "/a b" make nothing, and
186
+ # "/my/" + id or base + "/my/path", a URL joined by + on either side, makes nothing. The + before a
187
+ # string, or before a ( that opens it, is refused at any distance, across a line break too. A string
188
+ # inside a comment or a template literal makes nothing.
189
+ - rule: path_in_script_string
190
+ reads: file
191
+ in: [js_source]
192
+ match:
193
+ file: '*'
194
+ filetype: js_text
195
+ text: '(?:(?<![+\s])\s*[(\[,=:?]\s*|(?<![+\s])\s+)["''](?<path>/[^/\s"''`{}$][^\s"''`{}$]*)["''](?!\s*\+)'
196
+ id: {template: '{script}'}
197
+ emits: [{edge: {kind: script_links_to_path, from: this_node, to: {from: {capture: path}}}}]
198
+ confidence: declared
@@ -0,0 +1,153 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-manifest.schema.json"
2
+
3
+ # Known gaps. This pack maps the Drupal side of a project's JavaScript and what joins it to
4
+ # Drupal. Each line below was seen on real code or on a planted file.
5
+ #
6
+ # Behaviors. Drupal.behaviors.name = {...} is a node named by its name, and
7
+ # Drupal.behaviors.other.attach(...) inside a behavior object is an edge to the other behavior.
8
+ # - Any object assigned to Drupal.behaviors.name is a behavior, with or without an attach
9
+ # member: Drupal.behaviors.empty = {} gives a node.
10
+ # - Drupal.behaviors['name'] = {...} and window.Drupal.behaviors.name = {...}: no node.
11
+ # - An arrow function or a function expression gives the node, Drupal.behaviors.trapFocus =
12
+ # (element) => {...}; a value of any other kind, such as a variable, gives none.
13
+ # - Two scripts that declare one behavior name give one node holding both locations. Drupal
14
+ # keeps only the one loaded last on a page.
15
+ # - Drupal.behaviors.other.detach(...): no edge.
16
+ # - once(), Drupal.t() and an Ajax call: no rule reads them.
17
+ #
18
+ # Settings. $build['#attached']['drupalSettings']['key'] = ... in PHP is a setting node named by
19
+ # that first key, and drupalSettings.key inside a behavior object is an edge to it. A key that
20
+ # no mapped PHP file attaches is a referenced node.
21
+ # - Only the first name after drupalSettings is the key. drupalSettings.a.b reads the key a.
22
+ # - drupalSettings['key'], and a read through the second parameter of attach,
23
+ # attach(context, settings) { settings.key }: no edge.
24
+ #
25
+ # The two text file types this pack reads, drupal_template_text and drupal_php_text, are declared
26
+ # by drupal_basic, so every Drupal pack reads them the same way.
27
+ #
28
+ # Library attachments. In PHP, $build['#attached']['library'][] = 'module/library' is an edge
29
+ # from the class or the function around it. The array form,
30
+ # '#attached' => ['library' => ['module/library', ...]], is an edge from the class of its file,
31
+ # one for each text in the list. In Twig, attach_library('module/library') in a
32
+ # <name>.html.twig file is an edge from the template.
33
+ # - The array form is read as text. Its class is named from the file's path, by Drupal's PSR-4
34
+ # layout: <module>/src/A/B.php is Drupal\<module>\A\B. So the rule is inferred, and a file
35
+ # whose class is named otherwise gets an edge from a class that does not exist. In a .module,
36
+ # .theme, .inc, .install or .profile file the edge starts at the function around the list.
37
+ # - The array form with something between => and the array makes nothing:
38
+ # '#attached' => $flag ? ['library' => [...]] : [].
39
+ # - A library named by a constant, a variable or a joined text: no edge.
40
+ # - '#attached' => ['drupalSettings' => ['key' => ...]] is read as text the same way: a setting
41
+ # node for each first-level key, from the class or the function. A key named by a variable, or
42
+ # below the first level, makes nothing.
43
+ # - A component's components/<name>/<name>.twig is an edge from drupal.component::<name>. Any
44
+ # other Twig file not named .html.twig: no edge.
45
+ # - A call inside a Twig comment makes nothing. A call inside a quoted text or a verbatim block
46
+ # still gives an edge.
47
+ # - A script a library lists under js: is an edge from the library to the script's js.file node.
48
+ # The script's path is the libraries file's folder joined with the key. A key that is a URL
49
+ # (http:, https: or //) makes no edge and no node. A key that starts with /, such as
50
+ # /core/misc/drupal.js, is read from the Drupal root, the folder above the first modules, themes
51
+ # or profiles folder; a file outside the mapped folders gets a referenced node. In a project
52
+ # whose top folder is the Drupal root itself, such a key makes no edge.
53
+ # Chain: library -> script -> behavior. A script is linked to each behavior object it assigns,
54
+ # by a script_declares_behavior edge from its js.file node.
55
+ # - A stylesheet a library lists under css:, in any group, is an edge from the library to a
56
+ # css.file node named by the same joined path, with the same URL filter. Each .css file in a
57
+ # module or theme is a css.file node named by its path, so a listed file that does not exist
58
+ # gets a referenced node. A key that starts with / is read from the Drupal root, as for a script.
59
+ # - A second pack that claims libraries files, by a file type of its own for the ending yml, is
60
+ # refused (exit 19: the ending yml is claimed by different file types), because libraries
61
+ # files are read through this pack's type yml and drupal_basic's library rules. A pack that
62
+ # declares the type yml again in full, under the same name and with a path value of its own,
63
+ # merges with it and keeps the library edges. Two themes or modules that keep a script at one
64
+ # path meet at one js.file node.
65
+ #
66
+ # An edge that starts at what is around a match needs a behavior object in JavaScript, and a
67
+ # class or a function in PHP. A behavior call or a settings read outside a behavior object makes
68
+ # no edge and is listed under skipped: no value for enclosing_class. In PHP an attachment in a
69
+ # function, such as a hook in a .module file, starts at the function, and one in a method starts
70
+ # at the class, not at the method. An attachment outside both makes no edge and is listed the
71
+ # same way; its setting node is still made.
72
+ pack: drupal_js_basic
73
+ version: 0.0.1
74
+ depends: [js_basic, drupal_basic]
75
+ files:
76
+ types:
77
+ # yaml_basic's type yml, read as data, given the path value libraries_dir: the folder the file
78
+ # sits in, which a libraries file's js: keys are written from.
79
+ yml:
80
+ endings: [yml]
81
+ reader: data
82
+ format: yaml
83
+ path_values:
84
+ libraries_dir:
85
+ pattern: '^(?<dir>.+)/[^/]+$'
86
+ template: '{dir}'
87
+ # The folder above the first modules, themes or profiles folder: the Drupal root, which a
88
+ # js: or css: key that starts with / is written from. A file with no folder above it has
89
+ # no value.
90
+ drupal_root:
91
+ pattern: '^(?<root>.*?)/(?:modules|themes|profiles)/'
92
+ template: '{root}'
93
+ # drupal_basic's type drupal_template_text, given the path value component_name: the name of a
94
+ # single-directory component whose folder components/<name>/ holds the file <name>.twig.
95
+ drupal_template_text:
96
+ endings: [twig]
97
+ reader: text
98
+ path_values:
99
+ component_name:
100
+ pattern: '^(?:.*/)?components/(?<name>[^/]+)/(?P=name)\.twig$'
101
+ template: '{name}'
102
+ # drupal_basic's type drupal_php_text, given one more span: the array after each quoted,
103
+ # constant or variable key and =>, to any depth. The array-form setting rules read the keys
104
+ # around a match from it.
105
+ drupal_php_text:
106
+ endings: [php, module, theme, inc, install, profile]
107
+ reader: text
108
+ spans:
109
+ - name: keyed_array
110
+ open: '[\[,]\s*(?<key>[''"][\w.-]+[''"]|[^\s\[\](),''"=>|]+(?:\[[^\[\]]*\])*)\s*=>\s*(?=\[)'
111
+ balance: ['[', ']']
112
+ # The same name for an array that is not the whole value after =>, such as one inside a
113
+ # ternary, a call's argument or a list, and for old array( ). Its key is the character before
114
+ # the bracket, or the word array, so a key inside it is below the first level.
115
+ - name: keyed_array
116
+ open: '(?<key>[^\s\w$\]])(?<!=>)\s*(?=\[)'
117
+ balance: ['[', ']']
118
+ - name: keyed_array
119
+ open: '\b(?<key>array)\s*(?=\()'
120
+ balance: ['(', ')']
121
+ # A stylesheet, read as text only to be named by its path from the project folder.
122
+ css_text:
123
+ endings: [css]
124
+ reader: text
125
+ path_values:
126
+ stylesheet:
127
+ pattern: '^(?<file>.+)$'
128
+ template: '{file}'
129
+ # A script read as text, to find a path written whole in a string (behavior/behavior.yaml). Named
130
+ # by its path from the project folder, as js_basic names its js.file node.
131
+ js_text:
132
+ endings: [js]
133
+ reader: text
134
+ path_values:
135
+ script:
136
+ pattern: '^(?<file>.+)$'
137
+ template: '{file}'
138
+ sections:
139
+ - name: block_comment
140
+ open: '/\*'
141
+ close: '\*/'
142
+ - name: line_comment
143
+ open: '//'
144
+ close: '\n'
145
+ - name: string
146
+ open: ''''
147
+ close: '(?:[^''\\\n]|\\.)*'''
148
+ - name: string
149
+ open: '"'
150
+ close: '(?:[^"\\\n]|\\.)*"'
151
+ - name: template_string
152
+ open: '`'
153
+ close: '(?:[^`\\]|\\(?s:.))*`'
@@ -0,0 +1,13 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-file.schema.json"
2
+
3
+ node_types:
4
+ - name: drupal.js_setting
5
+ id_namespace: drupal.js_setting
6
+
7
+ edge_kinds:
8
+ - kind: provides_setting
9
+ from: [php.class, php.function]
10
+ to: drupal.js_setting
11
+ - kind: reads_setting
12
+ from: drupal.js_behavior
13
+ to: drupal.js_setting
@@ -0,0 +1,15 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-file.schema.json"
2
+
3
+ rules:
4
+ # drupalSettings.key inside a behavior object: the behavior reads the setting.
5
+ - rule: setting_read_in_behavior
6
+ reads: file
7
+ in: [js_source]
8
+ match:
9
+ declaration: member_expression
10
+ name_child: property
11
+ filetype: javascript
12
+ where: [{name_matches: {child: object, pattern: 'drupalSettings'}}]
13
+ id: {from: declared_name}
14
+ emits: [{edge: {kind: reads_setting, from: enclosing_class, to: this_node}}]
15
+ confidence: declared
@@ -0,0 +1,92 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-file.schema.json"
2
+
3
+ rules:
4
+ # $x['#attached']['drupalSettings']['key'] = ..., with or without more keys after it: the
5
+ # setting key the page gets.
6
+ - rule: setting_attached
7
+ reads: file
8
+ in: [source]
9
+ match: {declaration: assignment_expression, name_child: left, filetype: php}
10
+ id: {from: declared_name, pattern: '\[\s*[''"]#attached[''"]\s*\]\s*\[\s*[''"]drupalSettings[''"]\s*\]\s*\[\s*[''"](?<key>[\w.-]+)[''"]\s*\]', template: '{key}'}
11
+ emits: [{node: {type: drupal.js_setting}}]
12
+ confidence: declared
13
+ # The same assignment in a method: the class provides the setting.
14
+ - rule: setting_attached_in_class
15
+ reads: file
16
+ in: [source]
17
+ match: {declaration: assignment_expression, name_child: left, filetype: php}
18
+ id: {from: declared_name, pattern: '\[\s*[''"]#attached[''"]\s*\]\s*\[\s*[''"]drupalSettings[''"]\s*\]\s*\[\s*[''"](?<key>[\w.-]+)[''"]\s*\]', template: '{key}'}
19
+ emits: [{edge: {kind: provides_setting, from: enclosing_class, to: this_node}}]
20
+ confidence: declared
21
+ # '#attached' => ['drupalSettings' => ['key' => ...]]: each first-level key is a setting. level is
22
+ # first only when the innermost keyed_array around the key is drupalSettings, or is the key's own
23
+ # array value just inside it, so a key below the first level, at any depth, makes nothing.
24
+ - rule: setting_attached_in_array
25
+ reads: file
26
+ in: [source]
27
+ match:
28
+ file: '**'
29
+ filetype: drupal_php_text
30
+ text: '[\[,]\s*[''"](?<key>(?!drupalSettings[''"])[\w.-]+)[''"]\s*=>(?=\s*(?<arr>\[?))'
31
+ values:
32
+ in_attached: {from: {enclosing: attached, capture: mark}}
33
+ in_settings: {from: {enclosing: settings_list, capture: mark}}
34
+ chain: {from: {enclosing: keyed_array, capture: key}, join: '|'}
35
+ level: {template: '{chain}#{arr}', normalize: [{replace: '^(?:.*\|)?[''"]drupalSettings[''"](?:\|[^|]+#\[|#)$', with: first}, {replace: '^(?!first$).*', with: ''}]}
36
+ id:
37
+ template: '{in_attached}|{in_settings}|{level}|{key}'
38
+ normalize:
39
+ - {replace: '^.*\|', with: ''}
40
+ line: {capture: key}
41
+ emits: [{node: {type: drupal.js_setting}}]
42
+ confidence: declared
43
+ # The same key in a class file under src: the class of its file provides the setting.
44
+ - rule: setting_attached_in_array_in_class
45
+ reads: file
46
+ in: [source]
47
+ match:
48
+ file: '**'
49
+ filetype: drupal_php_text
50
+ text: '[\[,]\s*[''"](?<key>(?!drupalSettings[''"])[\w.-]+)[''"]\s*=>(?=\s*(?<arr>\[?))'
51
+ values:
52
+ in_attached: {from: {enclosing: attached, capture: mark}}
53
+ in_settings: {from: {enclosing: settings_list, capture: mark}}
54
+ chain: {from: {enclosing: keyed_array, capture: key}, join: '|'}
55
+ level: {template: '{chain}#{arr}', normalize: [{replace: '^(?:.*\|)?[''"]drupalSettings[''"](?:\|[^|]+#\[|#)$', with: first}, {replace: '^(?!first$).*', with: ''}]}
56
+ id:
57
+ template: '{in_attached}|{in_settings}|{level}|{key}'
58
+ normalize:
59
+ - {replace: '^.*\|', with: ''}
60
+ line: {capture: key}
61
+ emits:
62
+ - edge:
63
+ kind: provides_setting
64
+ from: {template: '{psr4_class}', types: [php.class]}
65
+ to: this_node
66
+ confidence: inferred
67
+ # The same key in a function of a procedural file: the function provides the setting.
68
+ - rule: setting_attached_in_array_in_function
69
+ reads: file
70
+ in: [source]
71
+ match:
72
+ file: '**'
73
+ filetype: drupal_php_text
74
+ ending: [module, theme, inc, install, profile]
75
+ text: '[\[,]\s*[''"](?<key>(?!drupalSettings[''"])[\w.-]+)[''"]\s*=>(?=\s*(?<arr>\[?))'
76
+ values:
77
+ in_attached: {from: {enclosing: attached, capture: mark}}
78
+ in_settings: {from: {enclosing: settings_list, capture: mark}}
79
+ chain: {from: {enclosing: keyed_array, capture: key}, join: '|'}
80
+ level: {template: '{chain}#{arr}', normalize: [{replace: '^(?:.*\|)?[''"]drupalSettings[''"](?:\|[^|]+#\[|#)$', with: first}, {replace: '^(?!first$).*', with: ''}]}
81
+ fn: {from: {enclosing: function_body, capture: name}}
82
+ id:
83
+ template: '{in_attached}|{in_settings}|{level}|{key}'
84
+ normalize:
85
+ - {replace: '^.*\|', with: ''}
86
+ line: {capture: key}
87
+ emits:
88
+ - edge:
89
+ kind: provides_setting
90
+ from: {template: '{fn}', types: [php.function]}
91
+ to: this_node
92
+ confidence: inferred
@@ -0,0 +1,15 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-file.schema.json"
2
+
3
+ # A Drush command, named by its name, and the method and class that run it.
4
+
5
+ node_types:
6
+ - name: drush.command
7
+ id_namespace: drush.command
8
+
9
+ edge_kinds:
10
+ - kind: command_method
11
+ from: drush.command
12
+ to: php.method
13
+ - kind: command_class
14
+ from: drush.command
15
+ to: php.class
@@ -0,0 +1,60 @@
1
+ $schema: "https://periplus.dev/schema/0/pack-file.schema.json"
2
+
3
+ # A Drush command declared by the @command tag in a method's docblock, read as text. The pattern
4
+ # runs from the tag to the docblock's end, never past it, then past one-line attributes and
5
+ # modifiers to the function's name. The node rule is declared; the edge rules name the class from
6
+ # the file's path, so they are inferred.
7
+
8
+ rules:
9
+ - rule: command_from_annotation
10
+ reads: file
11
+ in:
12
+ - source
13
+ match:
14
+ file: '**'
15
+ filetype: drupal_php_text
16
+ reads_sections: [block_comment]
17
+ text: '(?m)^[ \t]*\*[ \t]*@command[ \t]+(?<name>[\w:.-]+)'
18
+ id:
19
+ template: '{name}'
20
+ line: {capture: name}
21
+ emits:
22
+ - node:
23
+ type: drush.command
24
+ confidence: declared
25
+ - rule: command_method_from_annotation
26
+ reads: file
27
+ in:
28
+ - source
29
+ match:
30
+ file: '**'
31
+ filetype: drupal_php_text
32
+ reads_sections: [block_comment]
33
+ text: '(?m)^[ \t]*\*[ \t]*@command[ \t]+(?<name>[\w:.-]+)(?:[^*]|\*[^/])*\*/\s*(?:#\[[^\n]*\]\s*)*(?:(?:public|protected|private|static|final)\s+)*function\s+(?<method>\w+)'
34
+ id:
35
+ template: '{name}'
36
+ line: {capture: name}
37
+ emits:
38
+ - edge:
39
+ kind: command_method
40
+ from: this_node
41
+ to: {template: '{psr4_class}::{method}', types: [php.method], on_miss: unresolved}
42
+ confidence: inferred
43
+ - rule: command_class_from_annotation
44
+ reads: file
45
+ in:
46
+ - source
47
+ match:
48
+ file: '**'
49
+ filetype: drupal_php_text
50
+ reads_sections: [block_comment]
51
+ text: '(?m)^[ \t]*\*[ \t]*@command[ \t]+(?<name>[\w:.-]+)'
52
+ id:
53
+ template: '{name}'
54
+ line: {capture: name}
55
+ emits:
56
+ - edge:
57
+ kind: command_class
58
+ from: this_node
59
+ to: {template: '{psr4_class}', types: [php.class], on_miss: unresolved}
60
+ confidence: inferred