@shortlink-org/portolan 0.1.0 → 0.2.1

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 (381) hide show
  1. package/README.md +69 -205
  2. package/cli/init.mjs +285 -0
  3. package/cli/init.test.mjs +158 -0
  4. package/cli/portolan.mjs +37 -73
  5. package/index.html +19 -0
  6. package/package.json +5 -10
  7. package/plugins/README.md +66 -27
  8. package/plugins/portolan-go.wasm +0 -0
  9. package/portolan.json +52 -73
  10. package/public/landing/cats/bug-hunter.webp +0 -0
  11. package/public/landing/cats/compass-nap.webp +0 -0
  12. package/public/landing/cats/diagrammer.webp +0 -0
  13. package/public/landing/cats/docs-reader.webp +0 -0
  14. package/public/landing/cats/laptop.webp +0 -0
  15. package/public/landing/cats/map-inspector.webp +0 -0
  16. package/public/landing/cats/server-break.webp +0 -0
  17. package/public/landing/cats/star-mapper.webp +0 -0
  18. package/public/landing/cats/system-builder.webp +0 -0
  19. package/public/landing/cats/thread-tangle.webp +0 -0
  20. package/public/og.png +0 -0
  21. package/public/readme-header.webp +0 -0
  22. package/schema/portolan.schema.json +180 -0
  23. package/scripts/builtin-plugins.mjs +14 -0
  24. package/scripts/delivery-presets.mjs +353 -0
  25. package/scripts/gen.mjs +37 -4
  26. package/scripts/history.mjs +126 -0
  27. package/scripts/history.test.mjs +110 -0
  28. package/scripts/host-plugins/fetch-bsr.mjs +351 -0
  29. package/{plugins/fetch-bsr/options.schema.json → scripts/host-plugins/fetch-bsr.options.json} +4 -0
  30. package/scripts/host-plugins/fetch-bsr.test.mjs +212 -0
  31. package/scripts/host-plugins/fetch-csr.mjs +386 -0
  32. package/scripts/host-plugins/fetch-csr.test.mjs +178 -0
  33. package/scripts/host-plugins/fetch-git.mjs +379 -0
  34. package/scripts/host-plugins/fetch-git.test.mjs +210 -0
  35. package/scripts/local-api.mjs +27 -10
  36. package/scripts/local-api.test.mjs +85 -2
  37. package/scripts/manifest.mjs +3 -2
  38. package/scripts/package-smoke.mjs +24 -3
  39. package/scripts/plugin-host.mjs +77 -18
  40. package/scripts/plugin-host.test.mjs +50 -1
  41. package/scripts/plugin-wasm-worker.mjs +6 -3
  42. package/scripts/run-builtin.mjs +6 -26
  43. package/scripts/schema.mjs +6 -1
  44. package/src/app/App.tsx +24 -429
  45. package/src/app/Breadcrumbs.test.ts +7 -0
  46. package/src/app/Breadcrumbs.tsx +15 -2
  47. package/src/app/CatalogApp.tsx +436 -0
  48. package/src/app/Sidebar.tsx +0 -1
  49. package/src/chat/ChatPanel.tsx +98 -41
  50. package/src/chat/Composer.tsx +4 -2
  51. package/src/chat/Conversation.tsx +79 -15
  52. package/src/chat/Header.tsx +43 -9
  53. package/src/chat/Starter.tsx +64 -3
  54. package/src/chat/Steps.tsx +1 -1
  55. package/src/chat/flags.test.ts +51 -14
  56. package/src/chat/flags.ts +8 -2
  57. package/src/chat/page-context.test.ts +51 -0
  58. package/src/chat/page-context.ts +128 -0
  59. package/src/chat/prompt.test.ts +49 -1
  60. package/src/chat/prompt.ts +42 -1
  61. package/src/chat/tools.ts +7 -2
  62. package/src/chat/transport.ts +16 -4
  63. package/src/components/ProblemRow.tsx +182 -0
  64. package/src/data.ts +20 -5
  65. package/src/er/ErCanvas.tsx +1 -1
  66. package/src/graph/DependencyGraph.tsx +10 -1
  67. package/src/graph/FocusedEventGraph.tsx +1 -1
  68. package/src/graph/GraphToolbar.tsx +2 -4
  69. package/src/index.css +220 -2
  70. package/src/landing/DraggableReveal.tsx +168 -0
  71. package/src/landing/EstateGraph.tsx +28 -0
  72. package/src/landing/FlowPlayback.tsx +282 -0
  73. package/src/landing/HeroMap.tsx +128 -0
  74. package/src/landing/LandingPage.tsx +757 -0
  75. package/src/landing/ProductFrame.tsx +68 -0
  76. package/src/landing/ProductTour.tsx +371 -0
  77. package/src/landing/catalog.ts +25 -0
  78. package/src/landing/motion.tsx +52 -0
  79. package/src/lib/all-problems.ts +28 -0
  80. package/src/lib/local-api.ts +35 -1
  81. package/src/lib/setup-info.test.ts +8 -0
  82. package/src/lib/setup-info.ts +3 -2
  83. package/src/lib/source-code.ts +2 -1
  84. package/src/likec4/C4View.tsx +5 -0
  85. package/src/likec4/InteractiveView.tsx +5 -1
  86. package/src/map/ContextMapGraph.tsx +47 -20
  87. package/src/pages/ContextMap.tsx +5 -1
  88. package/src/pages/FlowDetail.tsx +24 -7
  89. package/src/pages/Overview.tsx +68 -12
  90. package/src/pages/Problems.tsx +6 -193
  91. package/src/pages/Settings.tsx +133 -108
  92. package/src/pages/settings/DeliverySettings.tsx +229 -0
  93. package/src/pages/settings/PreferencesSettings.tsx +101 -0
  94. package/src/routes.test.ts +20 -0
  95. package/src/routes.ts +13 -1
  96. package/vite.config.ts +17 -9
  97. package/catalog/enum_test.go +0 -46
  98. package/catalog/model.go +0 -932
  99. package/catalog/roundtrip_test.go +0 -185
  100. package/catalog/via_test.go +0 -38
  101. package/go.mod +0 -14
  102. package/go.sum +0 -14
  103. package/internal/commands/cargo.go +0 -154
  104. package/internal/commands/commands.go +0 -143
  105. package/internal/commands/commands_test.go +0 -323
  106. package/internal/commands/gradle.go +0 -77
  107. package/internal/commands/justfile.go +0 -82
  108. package/internal/commands/makefile.go +0 -106
  109. package/internal/commands/maven.go +0 -93
  110. package/internal/commands/packagejson.go +0 -159
  111. package/internal/commands/pyproject.go +0 -169
  112. package/internal/commands/taskfile.go +0 -101
  113. package/internal/commands/testdata/estate/.cargo/config.toml +0 -7
  114. package/internal/commands/testdata/estate/Makefile +0 -33
  115. package/internal/commands/testdata/estate/Taskfile.yml +0 -21
  116. package/internal/commands/testdata/estate/build.gradle.kts +0 -21
  117. package/internal/commands/testdata/estate/justfile +0 -20
  118. package/internal/commands/testdata/estate/package.json +0 -13
  119. package/internal/commands/testdata/estate/pom.xml +0 -29
  120. package/internal/commands/testdata/estate/pyproject.toml +0 -27
  121. package/internal/commands/testdata/estate/xtask/src/main.rs +0 -27
  122. package/internal/commands/testdata/golden/commands.json +0 -305
  123. package/internal/gohttp/analyze.go +0 -2500
  124. package/internal/gohttp/endpoints.go +0 -1067
  125. package/internal/gohttp/roots.go +0 -320
  126. package/internal/gohttp/typed.go +0 -143
  127. package/internal/goscan/constants.go +0 -85
  128. package/internal/goscan/goscan_test.go +0 -227
  129. package/internal/goscan/names.go +0 -52
  130. package/internal/goscan/parse_test.go +0 -11
  131. package/internal/goscan/source.go +0 -36
  132. package/internal/goscan/tree.go +0 -155
  133. package/internal/goscan/types.go +0 -99
  134. package/internal/wsdl/ids.go +0 -127
  135. package/internal/wsdl/ids_test.go +0 -21
  136. package/internal/wsdl/model.go +0 -62
  137. package/internal/wsdl/parse.go +0 -920
  138. package/internal/wsdl/parse_test.go +0 -133
  139. package/plugin/describe.go +0 -107
  140. package/plugin/describe_test.go +0 -114
  141. package/plugin/protocol.go +0 -117
  142. package/plugin/schematest/schematest.go +0 -126
  143. package/plugins/extract-adr/describe.go +0 -19
  144. package/plugins/extract-adr/describe_test.go +0 -11
  145. package/plugins/extract-adr/extract.go +0 -153
  146. package/plugins/extract-adr/extract_test.go +0 -350
  147. package/plugins/extract-adr/history.go +0 -99
  148. package/plugins/extract-adr/main.go +0 -65
  149. package/plugins/extract-adr/parse.go +0 -642
  150. package/plugins/extract-adr/parse_test.go +0 -405
  151. package/plugins/extract-asyncapi/describe.go +0 -19
  152. package/plugins/extract-asyncapi/describe_test.go +0 -11
  153. package/plugins/extract-asyncapi/extract.go +0 -315
  154. package/plugins/extract-asyncapi/extract_test.go +0 -197
  155. package/plugins/extract-asyncapi/main.go +0 -48
  156. package/plugins/extract-asyncapi/spec.go +0 -151
  157. package/plugins/extract-commands/describe.go +0 -19
  158. package/plugins/extract-commands/describe_test.go +0 -11
  159. package/plugins/extract-commands/extract.go +0 -79
  160. package/plugins/extract-commands/extract_test.go +0 -92
  161. package/plugins/extract-commands/main.go +0 -55
  162. package/plugins/extract-csr/avro.go +0 -258
  163. package/plugins/extract-csr/describe.go +0 -19
  164. package/plugins/extract-csr/describe_test.go +0 -11
  165. package/plugins/extract-csr/extract.go +0 -338
  166. package/plugins/extract-csr/extract_test.go +0 -374
  167. package/plugins/extract-csr/jsonschema.go +0 -343
  168. package/plugins/extract-csr/lock.go +0 -25
  169. package/plugins/extract-csr/main.go +0 -84
  170. package/plugins/extract-csr/subject.go +0 -102
  171. package/plugins/extract-flows/describe.go +0 -19
  172. package/plugins/extract-flows/describe_test.go +0 -11
  173. package/plugins/extract-flows/extract.go +0 -91
  174. package/plugins/extract-flows/main.go +0 -45
  175. package/plugins/extract-flows/parse.go +0 -593
  176. package/plugins/extract-flows/parse_test.go +0 -204
  177. package/plugins/extract-glossary/describe.go +0 -19
  178. package/plugins/extract-glossary/describe_test.go +0 -11
  179. package/plugins/extract-glossary/extract.go +0 -115
  180. package/plugins/extract-glossary/extract_test.go +0 -220
  181. package/plugins/extract-glossary/main.go +0 -59
  182. package/plugins/extract-glossary/parse.go +0 -214
  183. package/plugins/extract-glossary/parse_test.go +0 -203
  184. package/plugins/extract-go/aggregate.go +0 -214
  185. package/plugins/extract-go/client.go +0 -409
  186. package/plugins/extract-go/client_test.go +0 -266
  187. package/plugins/extract-go/describe.go +0 -19
  188. package/plugins/extract-go/describe_test.go +0 -11
  189. package/plugins/extract-go/enum.go +0 -195
  190. package/plugins/extract-go/enum_test.go +0 -82
  191. package/plugins/extract-go/event.go +0 -99
  192. package/plugins/extract-go/extract.go +0 -191
  193. package/plugins/extract-go/extract_test.go +0 -261
  194. package/plugins/extract-go/flow.go +0 -1441
  195. package/plugins/extract-go/flow_test.go +0 -609
  196. package/plugins/extract-go/httpclient.go +0 -174
  197. package/plugins/extract-go/httpclient_test.go +0 -296
  198. package/plugins/extract-go/ids.go +0 -92
  199. package/plugins/extract-go/layout.go +0 -225
  200. package/plugins/extract-go/layout_test.go +0 -125
  201. package/plugins/extract-go/lifecycle.go +0 -324
  202. package/plugins/extract-go/lifecycle_test.go +0 -108
  203. package/plugins/extract-go/main.go +0 -79
  204. package/plugins/extract-go/operation.go +0 -157
  205. package/plugins/extract-go/source.go +0 -316
  206. package/plugins/extract-go/transport.go +0 -321
  207. package/plugins/extract-go/transport_test.go +0 -145
  208. package/plugins/extract-go/wiring.go +0 -434
  209. package/plugins/extract-go-nats/describe.go +0 -19
  210. package/plugins/extract-go-nats/describe_test.go +0 -11
  211. package/plugins/extract-go-nats/extract.go +0 -177
  212. package/plugins/extract-go-nats/extract_test.go +0 -389
  213. package/plugins/extract-go-nats/index.go +0 -379
  214. package/plugins/extract-go-nats/main.go +0 -42
  215. package/plugins/extract-go-nats/resolve.go +0 -161
  216. package/plugins/extract-go-nats/sites.go +0 -224
  217. package/plugins/extract-graphql/describe.go +0 -19
  218. package/plugins/extract-graphql/describe_test.go +0 -11
  219. package/plugins/extract-graphql/extract.go +0 -433
  220. package/plugins/extract-graphql/extract_test.go +0 -256
  221. package/plugins/extract-graphql/ids.go +0 -49
  222. package/plugins/extract-graphql/lex.go +0 -237
  223. package/plugins/extract-graphql/main.go +0 -51
  224. package/plugins/extract-graphql/parse.go +0 -621
  225. package/plugins/extract-graphql/parse_test.go +0 -122
  226. package/plugins/extract-http-clients/describe.go +0 -19
  227. package/plugins/extract-http-clients/describe_test.go +0 -11
  228. package/plugins/extract-http-clients/extract.go +0 -705
  229. package/plugins/extract-http-clients/extract_test.go +0 -1263
  230. package/plugins/extract-http-clients/main.go +0 -42
  231. package/plugins/extract-openapi/describe.go +0 -19
  232. package/plugins/extract-openapi/describe_test.go +0 -11
  233. package/plugins/extract-openapi/discover.go +0 -243
  234. package/plugins/extract-openapi/extract.go +0 -526
  235. package/plugins/extract-openapi/extract_test.go +0 -545
  236. package/plugins/extract-openapi/main.go +0 -75
  237. package/plugins/extract-openapi/spec.go +0 -350
  238. package/plugins/extract-project/describe.go +0 -19
  239. package/plugins/extract-project/describe_test.go +0 -11
  240. package/plugins/extract-project/extract.go +0 -221
  241. package/plugins/extract-project/extract_test.go +0 -109
  242. package/plugins/extract-project/main.go +0 -41
  243. package/plugins/extract-proto/ast.go +0 -125
  244. package/plugins/extract-proto/consumes.go +0 -77
  245. package/plugins/extract-proto/describe.go +0 -19
  246. package/plugins/extract-proto/extract.go +0 -293
  247. package/plugins/extract-proto/extract_test.go +0 -459
  248. package/plugins/extract-proto/ids.go +0 -89
  249. package/plugins/extract-proto/ids_test.go +0 -57
  250. package/plugins/extract-proto/lex.go +0 -285
  251. package/plugins/extract-proto/main.go +0 -100
  252. package/plugins/extract-proto/module.go +0 -120
  253. package/plugins/extract-proto/parse.go +0 -720
  254. package/plugins/extract-proto/parse_test.go +0 -307
  255. package/plugins/extract-proto/provides.go +0 -236
  256. package/plugins/extract-proto/resolve.go +0 -222
  257. package/plugins/extract-proto/resolve_test.go +0 -119
  258. package/plugins/extract-redis/describe.go +0 -19
  259. package/plugins/extract-redis/describe_test.go +0 -11
  260. package/plugins/extract-redis/extract.go +0 -183
  261. package/plugins/extract-redis/extract_test.go +0 -168
  262. package/plugins/extract-redis/keyspaces.go +0 -469
  263. package/plugins/extract-redis/main.go +0 -44
  264. package/plugins/extract-river/describe.go +0 -19
  265. package/plugins/extract-river/describe_test.go +0 -11
  266. package/plugins/extract-river/extract.go +0 -507
  267. package/plugins/extract-river/extract_test.go +0 -132
  268. package/plugins/extract-river/main.go +0 -42
  269. package/plugins/extract-sql/ddl.go +0 -893
  270. package/plugins/extract-sql/ddl_test.go +0 -401
  271. package/plugins/extract-sql/describe.go +0 -19
  272. package/plugins/extract-sql/describe_test.go +0 -11
  273. package/plugins/extract-sql/layout.go +0 -221
  274. package/plugins/extract-sql/layout_test.go +0 -55
  275. package/plugins/extract-sql/lineage.go +0 -107
  276. package/plugins/extract-sql/main.go +0 -141
  277. package/plugins/extract-sql/maps.go +0 -564
  278. package/plugins/extract-sql/maps_java.go +0 -117
  279. package/plugins/extract-sql/maps_rust.go +0 -333
  280. package/plugins/extract-sql/maps_rust_test.go +0 -70
  281. package/plugins/extract-sql/maps_test.go +0 -204
  282. package/plugins/extract-sql/maps_ts.go +0 -398
  283. package/plugins/extract-sql/maps_ts_test.go +0 -136
  284. package/plugins/extract-sql/projection.go +0 -70
  285. package/plugins/extract-sql/projection_test.go +0 -50
  286. package/plugins/extract-sql/store.go +0 -420
  287. package/plugins/extract-sql/store_test.go +0 -233
  288. package/plugins/extract-sql/view.go +0 -295
  289. package/plugins/extract-watermill/describe.go +0 -19
  290. package/plugins/extract-watermill/describe_test.go +0 -11
  291. package/plugins/extract-watermill/extract.go +0 -1228
  292. package/plugins/extract-watermill/extract_test.go +0 -234
  293. package/plugins/extract-watermill/main.go +0 -41
  294. package/plugins/extract-wsdl/describe.go +0 -19
  295. package/plugins/extract-wsdl/describe_test.go +0 -11
  296. package/plugins/extract-wsdl/extract.go +0 -148
  297. package/plugins/extract-wsdl/extract_test.go +0 -45
  298. package/plugins/extract-wsdl/main.go +0 -53
  299. package/plugins/fetch-bsr/auth.go +0 -114
  300. package/plugins/fetch-bsr/bsr.go +0 -240
  301. package/plugins/fetch-bsr/cache.go +0 -66
  302. package/plugins/fetch-bsr/describe.go +0 -19
  303. package/plugins/fetch-bsr/fetch.go +0 -192
  304. package/plugins/fetch-bsr/fetch_test.go +0 -465
  305. package/plugins/fetch-bsr/lock.go +0 -71
  306. package/plugins/fetch-bsr/main.go +0 -117
  307. package/plugins/fetch-csr/auth.go +0 -95
  308. package/plugins/fetch-csr/cache.go +0 -69
  309. package/plugins/fetch-csr/describe.go +0 -19
  310. package/plugins/fetch-csr/describe_test.go +0 -11
  311. package/plugins/fetch-csr/fetch.go +0 -254
  312. package/plugins/fetch-csr/fetch_test.go +0 -494
  313. package/plugins/fetch-csr/lock.go +0 -95
  314. package/plugins/fetch-csr/main.go +0 -122
  315. package/plugins/fetch-csr/registry.go +0 -209
  316. package/plugins/fetch-git/cache.go +0 -65
  317. package/plugins/fetch-git/describe.go +0 -19
  318. package/plugins/fetch-git/describe_test.go +0 -11
  319. package/plugins/fetch-git/fetch.go +0 -181
  320. package/plugins/fetch-git/fetch_test.go +0 -332
  321. package/plugins/fetch-git/git.go +0 -169
  322. package/plugins/fetch-git/lock.go +0 -72
  323. package/plugins/fetch-git/main.go +0 -127
  324. package/plugins/fetch-git/offline.go +0 -39
  325. package/plugins/fetch-git/pin.go +0 -90
  326. package/plugins/fetch-git/pin_test.go +0 -74
  327. package/plugins/gen-backstage/describe.go +0 -17
  328. package/plugins/gen-backstage/main.go +0 -22
  329. package/plugins/gen-backstage/plugin.go +0 -473
  330. package/plugins/gen-backstage/plugin_test.go +0 -145
  331. package/plugins/gen-backstage.wasm +0 -0
  332. package/plugins/gen-markdown/adr.go +0 -162
  333. package/plugins/gen-markdown/aggregate.go +0 -362
  334. package/plugins/gen-markdown/canonical.go +0 -93
  335. package/plugins/gen-markdown/context.go +0 -90
  336. package/plugins/gen-markdown/coverage_test.go +0 -89
  337. package/plugins/gen-markdown/describe.go +0 -19
  338. package/plugins/gen-markdown/describe_test.go +0 -11
  339. package/plugins/gen-markdown/external.go +0 -71
  340. package/plugins/gen-markdown/flow.go +0 -277
  341. package/plugins/gen-markdown/glossary.go +0 -76
  342. package/plugins/gen-markdown/glossary_test.go +0 -148
  343. package/plugins/gen-markdown/llms.go +0 -302
  344. package/plugins/gen-markdown/main.go +0 -22
  345. package/plugins/gen-markdown/markdown.go +0 -254
  346. package/plugins/gen-markdown/markdown_test.go +0 -100
  347. package/plugins/gen-markdown/module.go +0 -107
  348. package/plugins/gen-markdown/plugin.go +0 -39
  349. package/plugins/gen-markdown/quality_test.go +0 -176
  350. package/plugins/gen-markdown/redis_test.go +0 -38
  351. package/plugins/gen-markdown/render.go +0 -344
  352. package/plugins/gen-markdown/render_test.go +0 -186
  353. package/plugins/gen-markdown/service.go +0 -456
  354. package/plugins/gen-markdown/source.go +0 -177
  355. package/plugins/gen-markdown/store.go +0 -201
  356. package/plugins/gen-markdown.wasm +0 -0
  357. package/plugins/gen-mermaid/describe.go +0 -17
  358. package/plugins/gen-mermaid/main.go +0 -22
  359. package/plugins/gen-mermaid/plugin.go +0 -104
  360. package/plugins/gen-mermaid/plugin_test.go +0 -33
  361. package/plugins/gen-mermaid.wasm +0 -0
  362. package/plugins/openapi/ids.go +0 -261
  363. package/plugins/openapi/ids_test.go +0 -98
  364. package/plugins/verify-codeowners/describe.go +0 -19
  365. package/plugins/verify-codeowners/describe_test.go +0 -11
  366. package/plugins/verify-codeowners/main.go +0 -75
  367. package/plugins/verify-codeowners/match.go +0 -85
  368. package/plugins/verify-codeowners/match_test.go +0 -47
  369. package/plugins/verify-codeowners/owners.go +0 -164
  370. package/plugins/verify-codeowners/owners_test.go +0 -225
  371. package/plugins/verify-codeowners/parse.go +0 -90
  372. package/plugins/verify-codeowners/parse_test.go +0 -62
  373. package/plugins/verify-otel/describe.go +0 -19
  374. package/plugins/verify-otel/describe_test.go +0 -11
  375. package/plugins/verify-otel/main.go +0 -53
  376. package/plugins/verify-otel/match.go +0 -336
  377. package/plugins/verify-otel/otlp.go +0 -200
  378. package/plugins/verify-otel/verify.go +0 -734
  379. package/plugins/verify-otel/verify_test.go +0 -460
  380. /package/{plugins/fetch-csr/options.schema.json → scripts/host-plugins/fetch-csr.options.json} +0 -0
  381. /package/{plugins/fetch-git/options.schema.json → scripts/host-plugins/fetch-git.options.json} +0 -0
@@ -1,285 +0,0 @@
1
- package main
2
-
3
- // The tokens of a .proto file, and the comments attached to them.
4
- //
5
- // Comments are not thrown away. A proto's leading comments are the only
6
- // documentation it carries - a descriptor drops them unless SourceCodeInfo is
7
- // asked for and carried around - and `Field.doc` in the catalog would come back
8
- // empty without them. So the lexer keeps them, attaches each block to the token
9
- // it precedes, and files each trailing one under the line it sits on.
10
-
11
- import (
12
- "fmt"
13
- "strings"
14
- "unicode"
15
- "unicode/utf8"
16
- )
17
-
18
- type kind int
19
-
20
- const (
21
- tokEOF kind = iota
22
- tokIdent
23
- tokString
24
- tokNumber
25
- tokPunct
26
- )
27
-
28
- type token struct {
29
- kind kind
30
- text string
31
- line int
32
-
33
- // doc is the comment block directly above this token, already cleaned.
34
- // Empty unless this token opens a declaration that was commented.
35
- doc string
36
- }
37
-
38
- func (t token) is(text string) bool {
39
- return (t.kind == tokPunct || t.kind == tokIdent) && t.text == text
40
- }
41
-
42
- // lexed is a file's tokens plus the comments that did not lead a declaration.
43
- type lexed struct {
44
- tokens []token
45
-
46
- // trailing is the comment sitting at the end of a line, by line number.
47
- // A field documented to its right rather than above is common enough that
48
- // dropping it would lose real prose.
49
- trailing map[int]string
50
- }
51
-
52
- type lexer struct {
53
- src string
54
- pos int
55
- line int
56
-
57
- pending []string // comment block being accumulated
58
- lastEnd int // line the last accumulated comment ended on
59
- trailing map[int]string
60
- lastTok int // line of the last non-comment token, for trailing detection
61
- }
62
-
63
- func lex(src string) (lexed, error) {
64
- l := &lexer{src: src, line: 1, trailing: map[int]string{}, lastTok: -1}
65
- out := lexed{trailing: l.trailing}
66
-
67
- for {
68
- tok, err := l.next()
69
- if err != nil {
70
- return lexed{}, err
71
- }
72
- out.tokens = append(out.tokens, tok)
73
- if tok.kind == tokEOF {
74
- return out, nil
75
- }
76
- }
77
- }
78
-
79
- func (l *lexer) next() (token, error) {
80
- for {
81
- l.skipSpace()
82
- if l.pos >= len(l.src) {
83
- return token{kind: tokEOF, line: l.line}, nil
84
- }
85
-
86
- if l.src[l.pos] == '/' && l.pos+1 < len(l.src) {
87
- switch l.src[l.pos+1] {
88
- case '/':
89
- l.lineComment()
90
-
91
- continue
92
- case '*':
93
- if err := l.blockComment(); err != nil {
94
- return token{}, err
95
- }
96
-
97
- continue
98
- }
99
- }
100
-
101
- break
102
- }
103
-
104
- start := l.line
105
- c := l.src[l.pos]
106
-
107
- switch {
108
- case c == '"' || c == '\'':
109
- text, err := l.str()
110
- if err != nil {
111
- return token{}, err
112
- }
113
-
114
- return l.emit(token{kind: tokString, text: text, line: start}), nil
115
-
116
- case isIdentStart(c):
117
- begin := l.pos
118
- for l.pos < len(l.src) && isIdentPart(l.src[l.pos]) {
119
- l.pos++
120
- }
121
-
122
- return l.emit(token{kind: tokIdent, text: l.src[begin:l.pos], line: start}), nil
123
-
124
- case c >= '0' && c <= '9':
125
- begin := l.pos
126
- for l.pos < len(l.src) && isNumberPart(l.src[l.pos]) {
127
- l.pos++
128
- }
129
-
130
- return l.emit(token{kind: tokNumber, text: l.src[begin:l.pos], line: start}), nil
131
-
132
- default:
133
- l.pos++
134
-
135
- return l.emit(token{kind: tokPunct, text: string(c), line: start}), nil
136
- }
137
- }
138
-
139
- // emit hands the accumulated comment block to a token, but only when the block
140
- // ends on the line above it. A comment separated by a blank line was about
141
- // whatever came before, or about nothing, and attaching it would put a
142
- // paragraph on a declaration that never claimed it.
143
- func (l *lexer) emit(t token) token {
144
- if len(l.pending) > 0 {
145
- if l.lastEnd == t.line-1 {
146
- t.doc = strings.Join(l.pending, "\n")
147
- }
148
- l.pending = nil
149
- }
150
- l.lastTok = t.line
151
-
152
- return t
153
- }
154
-
155
- func (l *lexer) lineComment() {
156
- l.pos += 2
157
- begin := l.pos
158
- for l.pos < len(l.src) && l.src[l.pos] != '\n' {
159
- l.pos++
160
- }
161
- text := strings.TrimSpace(l.src[begin:l.pos])
162
-
163
- // A comment on the same line as the last token trails it rather than
164
- // leading whatever comes next.
165
- if l.line == l.lastTok {
166
- if prev, ok := l.trailing[l.line]; ok {
167
- l.trailing[l.line] = prev + " " + text
168
- } else {
169
- l.trailing[l.line] = text
170
- }
171
-
172
- return
173
- }
174
-
175
- if l.lastEnd != l.line-1 {
176
- l.pending = nil
177
- }
178
- l.pending = append(l.pending, text)
179
- l.lastEnd = l.line
180
- }
181
-
182
- func (l *lexer) blockComment() error {
183
- startLine := l.line
184
- l.pos += 2
185
- begin := l.pos
186
- for {
187
- if l.pos+1 >= len(l.src) {
188
- return fmt.Errorf("line %d: block comment is never closed", startLine)
189
- }
190
- if l.src[l.pos] == '*' && l.src[l.pos+1] == '/' {
191
- break
192
- }
193
- if l.src[l.pos] == '\n' {
194
- l.line++
195
- }
196
- l.pos++
197
- }
198
- body := l.src[begin:l.pos]
199
- l.pos += 2
200
-
201
- var lines []string
202
- for _, raw := range strings.Split(body, "\n") {
203
- line := strings.TrimSpace(raw)
204
- line = strings.TrimPrefix(line, "*")
205
- lines = append(lines, strings.TrimSpace(line))
206
- }
207
- for len(lines) > 0 && lines[0] == "" {
208
- lines = lines[1:]
209
- }
210
- for len(lines) > 0 && lines[len(lines)-1] == "" {
211
- lines = lines[:len(lines)-1]
212
- }
213
-
214
- if l.lastEnd != startLine-1 {
215
- l.pending = nil
216
- }
217
- l.pending = append(l.pending, lines...)
218
- l.lastEnd = l.line
219
-
220
- return nil
221
- }
222
-
223
- func (l *lexer) str() (string, error) {
224
- quote := l.src[l.pos]
225
- startLine := l.line
226
- l.pos++
227
- var b strings.Builder
228
- for {
229
- if l.pos >= len(l.src) {
230
- return "", fmt.Errorf("line %d: string is never closed", startLine)
231
- }
232
- c := l.src[l.pos]
233
- if c == quote {
234
- l.pos++
235
-
236
- return b.String(), nil
237
- }
238
- if c == '\n' {
239
- return "", fmt.Errorf("line %d: string is never closed", startLine)
240
- }
241
- if c == '\\' && l.pos+1 < len(l.src) {
242
- // The escape is kept as written. Nothing downstream interprets a
243
- // proto string literal; they are option values and default values,
244
- // and both are shown rather than evaluated.
245
- b.WriteByte(c)
246
- l.pos++
247
- b.WriteByte(l.src[l.pos])
248
- l.pos++
249
-
250
- continue
251
- }
252
- b.WriteByte(c)
253
- l.pos++
254
- }
255
- }
256
-
257
- func (l *lexer) skipSpace() {
258
- for l.pos < len(l.src) {
259
- c := l.src[l.pos]
260
- if c == '\n' {
261
- l.line++
262
- l.pos++
263
-
264
- continue
265
- }
266
- r, size := utf8.DecodeRuneInString(l.src[l.pos:])
267
- if !unicode.IsSpace(r) {
268
- return
269
- }
270
- l.pos += size
271
- }
272
- }
273
-
274
- func isIdentStart(c byte) bool {
275
- return c == '_' || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
276
- }
277
-
278
- func isIdentPart(c byte) bool {
279
- return isIdentStart(c) || (c >= '0' && c <= '9')
280
- }
281
-
282
- func isNumberPart(c byte) bool {
283
- return (c >= '0' && c <= '9') || c == '.' || c == 'x' || c == 'X' ||
284
- (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') || c == '-' || c == '+'
285
- }
@@ -1,100 +0,0 @@
1
- // Package main is portolan-extract-proto: .proto files in, a catalog fragment
2
- // out.
3
- //
4
- // It is a `process` plugin because it walks the input tree, and it would be a
5
- // wasm one the day the host preopens `Input.Root`. Nothing in it reads a clock,
6
- // opens a socket or looks at the environment, and nothing should: fetching a
7
- // module from a registry belongs to portolan-fetch-bsr, and keeping the two
8
- // apart is what lets this one be replayed byte-for-byte from a checkout.
9
- //
10
- // Wired into portolan.json for the order contract oms publishes; the shape of
11
- // a step, with a vendored copy as well:
12
- //
13
- // {
14
- // "plugins": [
15
- // { "name": "proto", "process": { "command": "go", "args": ["run", "./plugins/extract-proto"] } }
16
- // ],
17
- // "extract": [
18
- // {
19
- // "plugin": "proto",
20
- // "in": "examples/shop",
21
- // "out": "examples/shop/portolan",
22
- // "options": {
23
- // "context": "shop",
24
- // "service": "oms",
25
- // "paths": ["proto"],
26
- // "vendored": ["internal/infrastructure/pricing"],
27
- // "peers": { "shop.v1": "shop.pricing" },
28
- // "out": "proto.json"
29
- // }
30
- // }
31
- // ]
32
- // }
33
- //
34
- // Declared AFTER any fetch-bsr step that writes into the same tree: extract
35
- // steps run in list order, so a fetch declared first has already written its
36
- // protos and its lock by the time this reads them.
37
- package main
38
-
39
- import (
40
- "fmt"
41
- "io"
42
- "os"
43
-
44
- "github.com/shortlink-org/portolan/plugin"
45
- )
46
-
47
- // Options are what the manifest tells the extractor: the things a .proto does
48
- // not say about the estate it belongs to.
49
- type Options struct {
50
- Context string `json:"context"`
51
- Service string `json:"service"`
52
-
53
- // Paths are directories of protos this service PUBLISHES, relative to the
54
- // input root. They become what it provides.
55
- Paths []string `json:"paths,omitempty"`
56
-
57
- // Vendored are directories of client copies this service CONSUMES. They
58
- // become what it calls.
59
- //
60
- // An explicit list rather than a glob: which copies a service is allowed to
61
- // keep is an architectural boundary, and a boundary spelled out in the
62
- // manifest is one a reviewer can see change.
63
- Vendored []string `json:"vendored,omitempty"`
64
-
65
- // Peers maps a proto package to the service id that answers on it.
66
- //
67
- // The only way a consumer-side extractor can name a peer. Without an entry
68
- // the call keeps the raw package name, which is exactly what `RpcCall.peer`
69
- // documents - guessing a service id from a package would be inventing an
70
- // edge between two services.
71
- Peers map[string]string `json:"peers,omitempty"`
72
-
73
- // Modules maps a directory, relative to the input root, to the module id
74
- // its protos belong to. Only needed where there is no lock file to say.
75
- Modules map[string]string `json:"modules,omitempty"`
76
-
77
- // Defs is "shared" (the default) or "off". Shared promotes a message the
78
- // author put in another file to a catalog.defs entry, on the reasoning that
79
- // an import is their own signal the type is not local.
80
- Defs string `json:"defs,omitempty"`
81
-
82
- Out string `json:"out,omitempty"`
83
- }
84
-
85
- func main() {
86
- if err := run(os.Stdin, os.Stdout); err != nil {
87
- fmt.Fprintln(os.Stderr, "portolan-extract-proto:", err)
88
- os.Exit(1)
89
- }
90
- }
91
-
92
- func run(stdin io.Reader, stdout io.Writer) error {
93
- return plugin.Serve(stdin, stdout, descriptor(), func(req plugin.Request, opts Options) (plugin.Response, error) {
94
- if req.Input.Root == "" {
95
- return plugin.Response{}, fmt.Errorf("no input root: an extractor has nothing to read")
96
- }
97
-
98
- return extract(req.Input, opts)
99
- })
100
- }
@@ -1,120 +0,0 @@
1
- package main
2
-
3
- // Where a set of .proto files came from.
4
- //
5
- // Two answers are possible and both are honest. A directory written into by
6
- // `fetch-bsr` has a `bsr.lock.json` beside it saying which module and which
7
- // commit; a directory of protos the estate simply keeps has neither, and gets a
8
- // `local:` id so nobody mistakes the path for something they could go and
9
- // fetch.
10
-
11
- import (
12
- "encoding/json"
13
- "os"
14
- "path/filepath"
15
- "sort"
16
- "strings"
17
-
18
- "github.com/shortlink-org/portolan/catalog"
19
- )
20
-
21
- // lockFile is the shape fetch-bsr writes. Read here rather than shared, because
22
- // the two plugins are separate programs on purpose: one may run without the
23
- // other ever having existed.
24
- type lockFile struct {
25
- Modules []lockModule `json:"modules"`
26
- }
27
-
28
- type lockModule struct {
29
- Module string `json:"module"`
30
- Commit string `json:"commit"`
31
- Digest string `json:"digest"`
32
- Deps []string `json:"deps,omitempty"`
33
- Files []lockEntry `json:"files"`
34
- }
35
-
36
- type lockEntry struct {
37
- Path string `json:"path"`
38
- }
39
-
40
- const lockName = "bsr.lock.json"
41
-
42
- // readLock loads the lock beside a directory of protos, if there is one.
43
- func readLock(dir string) (*lockFile, error) {
44
- raw, err := os.ReadFile(filepath.Join(dir, lockName))
45
- if os.IsNotExist(err) {
46
- return nil, nil
47
- }
48
- if err != nil {
49
- return nil, err
50
- }
51
-
52
- var lock lockFile
53
- if err := json.Unmarshal(raw, &lock); err != nil {
54
- return nil, err
55
- }
56
-
57
- return &lock, nil
58
- }
59
-
60
- // moduleFor describes the set of protos under one directory.
61
- //
62
- // packages and files come from what was actually parsed rather than from the
63
- // lock, because the lock says what was fetched and this says what portolan
64
- // could read - and when they disagree, the second is the one a reader needs.
65
- func moduleFor(id, dir string, files []*File) catalog.ProtoModule {
66
- packages := map[string]bool{}
67
- paths := make([]string, 0, len(files))
68
- for _, file := range files {
69
- if file.Package != "" {
70
- packages[file.Package] = true
71
- }
72
- paths = append(paths, relativeTo(dir, file.Path))
73
- }
74
-
75
- module := catalog.ProtoModule{
76
- ID: id,
77
- Slug: moduleSlug(id),
78
- Name: moduleName(id),
79
- Registry: registryOf(id),
80
- Packages: sortedKeys(packages),
81
- Files: sortedCopy(paths),
82
- Source: filepath.ToSlash(dir),
83
- }
84
-
85
- return module
86
- }
87
-
88
- func relativeTo(dir, path string) string {
89
- rel, err := filepath.Rel(dir, path)
90
- if err != nil {
91
- return filepath.ToSlash(path)
92
- }
93
-
94
- return filepath.ToSlash(rel)
95
- }
96
-
97
- // sortedKeys and sortedCopy exist because the fragment is committed and
98
- // compared by `gen:check`. A map iterated in Go's order writes a different file
99
- // every run, which would turn every build into a diff.
100
- func sortedKeys(set map[string]bool) []string {
101
- out := make([]string, 0, len(set))
102
- for k := range set {
103
- out = append(out, k)
104
- }
105
- sort.Strings(out)
106
-
107
- return out
108
- }
109
-
110
- func sortedCopy(in []string) []string {
111
- out := append([]string(nil), in...)
112
- sort.Strings(out)
113
-
114
- return out
115
- }
116
-
117
- // trimSlash keeps a directory option comparable however it was written.
118
- func trimSlash(dir string) string {
119
- return strings.TrimSuffix(filepath.ToSlash(dir), "/")
120
- }