@shortlink-org/portolan 0.1.0
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.
- package/LICENSE +21 -0
- package/README.md +387 -0
- package/catalog/enum_test.go +46 -0
- package/catalog/model.go +932 -0
- package/catalog/roundtrip_test.go +185 -0
- package/catalog/via_test.go +38 -0
- package/cli/portolan.mjs +368 -0
- package/go.mod +14 -0
- package/go.sum +14 -0
- package/index.html +13 -0
- package/internal/commands/cargo.go +154 -0
- package/internal/commands/commands.go +143 -0
- package/internal/commands/commands_test.go +323 -0
- package/internal/commands/gradle.go +77 -0
- package/internal/commands/justfile.go +82 -0
- package/internal/commands/makefile.go +106 -0
- package/internal/commands/maven.go +93 -0
- package/internal/commands/packagejson.go +159 -0
- package/internal/commands/pyproject.go +169 -0
- package/internal/commands/taskfile.go +101 -0
- package/internal/commands/testdata/estate/.cargo/config.toml +7 -0
- package/internal/commands/testdata/estate/Makefile +33 -0
- package/internal/commands/testdata/estate/Taskfile.yml +21 -0
- package/internal/commands/testdata/estate/build.gradle.kts +21 -0
- package/internal/commands/testdata/estate/justfile +20 -0
- package/internal/commands/testdata/estate/package.json +13 -0
- package/internal/commands/testdata/estate/pom.xml +29 -0
- package/internal/commands/testdata/estate/pyproject.toml +27 -0
- package/internal/commands/testdata/estate/xtask/src/main.rs +27 -0
- package/internal/commands/testdata/golden/commands.json +305 -0
- package/internal/gohttp/analyze.go +2500 -0
- package/internal/gohttp/endpoints.go +1067 -0
- package/internal/gohttp/roots.go +320 -0
- package/internal/gohttp/typed.go +143 -0
- package/internal/goscan/constants.go +85 -0
- package/internal/goscan/goscan_test.go +227 -0
- package/internal/goscan/names.go +52 -0
- package/internal/goscan/parse_test.go +11 -0
- package/internal/goscan/source.go +36 -0
- package/internal/goscan/tree.go +155 -0
- package/internal/goscan/types.go +99 -0
- package/internal/wsdl/ids.go +127 -0
- package/internal/wsdl/ids_test.go +21 -0
- package/internal/wsdl/model.go +62 -0
- package/internal/wsdl/parse.go +920 -0
- package/internal/wsdl/parse_test.go +133 -0
- package/package.json +117 -0
- package/plugin/describe.go +107 -0
- package/plugin/describe_test.go +114 -0
- package/plugin/protocol.go +117 -0
- package/plugin/schematest/schematest.go +126 -0
- package/plugins/README.md +1160 -0
- package/plugins/extract-adr/describe.go +19 -0
- package/plugins/extract-adr/describe_test.go +11 -0
- package/plugins/extract-adr/extract.go +153 -0
- package/plugins/extract-adr/extract_test.go +350 -0
- package/plugins/extract-adr/history.go +99 -0
- package/plugins/extract-adr/main.go +65 -0
- package/plugins/extract-adr/options.schema.json +26 -0
- package/plugins/extract-adr/parse.go +642 -0
- package/plugins/extract-adr/parse_test.go +405 -0
- package/plugins/extract-asyncapi/describe.go +19 -0
- package/plugins/extract-asyncapi/describe_test.go +11 -0
- package/plugins/extract-asyncapi/extract.go +315 -0
- package/plugins/extract-asyncapi/extract_test.go +197 -0
- package/plugins/extract-asyncapi/main.go +48 -0
- package/plugins/extract-asyncapi/options.schema.json +26 -0
- package/plugins/extract-asyncapi/spec.go +151 -0
- package/plugins/extract-celery/README.md +169 -0
- package/plugins/extract-celery/extract.py +346 -0
- package/plugins/extract-celery/extract_test.py +192 -0
- package/plugins/extract-celery/main.py +66 -0
- package/plugins/extract-celery/options.py +31 -0
- package/plugins/extract-celery/options.schema.json +31 -0
- package/plugins/extract-celery/producers.py +156 -0
- package/plugins/extract-celery/routes_test.py +106 -0
- package/plugins/extract-commands/describe.go +19 -0
- package/plugins/extract-commands/describe_test.go +11 -0
- package/plugins/extract-commands/extract.go +79 -0
- package/plugins/extract-commands/extract_test.go +92 -0
- package/plugins/extract-commands/main.go +55 -0
- package/plugins/extract-commands/options.schema.json +20 -0
- package/plugins/extract-csr/avro.go +258 -0
- package/plugins/extract-csr/describe.go +19 -0
- package/plugins/extract-csr/describe_test.go +11 -0
- package/plugins/extract-csr/extract.go +338 -0
- package/plugins/extract-csr/extract_test.go +374 -0
- package/plugins/extract-csr/jsonschema.go +343 -0
- package/plugins/extract-csr/lock.go +25 -0
- package/plugins/extract-csr/main.go +84 -0
- package/plugins/extract-csr/options.schema.json +43 -0
- package/plugins/extract-csr/subject.go +102 -0
- package/plugins/extract-django/README.md +386 -0
- package/plugins/extract-django/apps.py +100 -0
- package/plugins/extract-django/auth.py +302 -0
- package/plugins/extract-django/auth_test.py +188 -0
- package/plugins/extract-django/clients.py +121 -0
- package/plugins/extract-django/contracts.py +458 -0
- package/plugins/extract-django/database.py +119 -0
- package/plugins/extract-django/domain.py +318 -0
- package/plugins/extract-django/events.py +86 -0
- package/plugins/extract-django/extract.py +601 -0
- package/plugins/extract-django/extract_test.py +397 -0
- package/plugins/extract-django/flows.py +1278 -0
- package/plugins/extract-django/flows_test.py +338 -0
- package/plugins/extract-django/ids.py +42 -0
- package/plugins/extract-django/ids_test.py +30 -0
- package/plugins/extract-django/lifecycle.py +222 -0
- package/plugins/extract-django/lifecycle_test.py +76 -0
- package/plugins/extract-django/main.py +66 -0
- package/plugins/extract-django/openapi.py +229 -0
- package/plugins/extract-django/openapi_test.py +60 -0
- package/plugins/extract-django/operations.py +96 -0
- package/plugins/extract-django/options.py +61 -0
- package/plugins/extract-django/options.schema.json +126 -0
- package/plugins/extract-django/routing.py +214 -0
- package/plugins/extract-django/routing_test.py +198 -0
- package/plugins/extract-django/serializers.py +558 -0
- package/plugins/extract-django/store.py +434 -0
- package/plugins/extract-django/transport.py +242 -0
- package/plugins/extract-flows/describe.go +19 -0
- package/plugins/extract-flows/describe_test.go +11 -0
- package/plugins/extract-flows/extract.go +91 -0
- package/plugins/extract-flows/main.go +45 -0
- package/plugins/extract-flows/options.schema.json +16 -0
- package/plugins/extract-flows/parse.go +593 -0
- package/plugins/extract-flows/parse_test.go +204 -0
- package/plugins/extract-glossary/describe.go +19 -0
- package/plugins/extract-glossary/describe_test.go +11 -0
- package/plugins/extract-glossary/extract.go +115 -0
- package/plugins/extract-glossary/extract_test.go +220 -0
- package/plugins/extract-glossary/main.go +59 -0
- package/plugins/extract-glossary/options.schema.json +21 -0
- package/plugins/extract-glossary/parse.go +214 -0
- package/plugins/extract-glossary/parse_test.go +203 -0
- package/plugins/extract-go/aggregate.go +214 -0
- package/plugins/extract-go/client.go +409 -0
- package/plugins/extract-go/client_test.go +266 -0
- package/plugins/extract-go/describe.go +19 -0
- package/plugins/extract-go/describe_test.go +11 -0
- package/plugins/extract-go/enum.go +195 -0
- package/plugins/extract-go/enum_test.go +82 -0
- package/plugins/extract-go/event.go +99 -0
- package/plugins/extract-go/extract.go +191 -0
- package/plugins/extract-go/extract_test.go +261 -0
- package/plugins/extract-go/flow.go +1441 -0
- package/plugins/extract-go/flow_test.go +609 -0
- package/plugins/extract-go/httpclient.go +174 -0
- package/plugins/extract-go/httpclient_test.go +296 -0
- package/plugins/extract-go/ids.go +92 -0
- package/plugins/extract-go/layout.go +225 -0
- package/plugins/extract-go/layout_test.go +125 -0
- package/plugins/extract-go/lifecycle.go +324 -0
- package/plugins/extract-go/lifecycle_test.go +108 -0
- package/plugins/extract-go/main.go +79 -0
- package/plugins/extract-go/operation.go +157 -0
- package/plugins/extract-go/options.schema.json +66 -0
- package/plugins/extract-go/source.go +316 -0
- package/plugins/extract-go/transport.go +321 -0
- package/plugins/extract-go/transport_test.go +145 -0
- package/plugins/extract-go/wiring.go +434 -0
- package/plugins/extract-go-nats/describe.go +19 -0
- package/plugins/extract-go-nats/describe_test.go +11 -0
- package/plugins/extract-go-nats/extract.go +177 -0
- package/plugins/extract-go-nats/extract_test.go +389 -0
- package/plugins/extract-go-nats/index.go +379 -0
- package/plugins/extract-go-nats/main.go +42 -0
- package/plugins/extract-go-nats/options.schema.json +21 -0
- package/plugins/extract-go-nats/resolve.go +161 -0
- package/plugins/extract-go-nats/sites.go +224 -0
- package/plugins/extract-graphql/describe.go +19 -0
- package/plugins/extract-graphql/describe_test.go +11 -0
- package/plugins/extract-graphql/extract.go +433 -0
- package/plugins/extract-graphql/extract_test.go +256 -0
- package/plugins/extract-graphql/ids.go +49 -0
- package/plugins/extract-graphql/lex.go +237 -0
- package/plugins/extract-graphql/main.go +51 -0
- package/plugins/extract-graphql/options.schema.json +31 -0
- package/plugins/extract-graphql/parse.go +621 -0
- package/plugins/extract-graphql/parse_test.go +122 -0
- package/plugins/extract-http-clients/describe.go +19 -0
- package/plugins/extract-http-clients/describe_test.go +11 -0
- package/plugins/extract-http-clients/extract.go +705 -0
- package/plugins/extract-http-clients/extract_test.go +1263 -0
- package/plugins/extract-http-clients/main.go +42 -0
- package/plugins/extract-http-clients/options.schema.json +33 -0
- package/plugins/extract-java/README.md +190 -0
- package/plugins/extract-java/build/org/portolan/extract/Catalog.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Clients$1.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Clients$2.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Clients$Call.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Clients$Client.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Clients$Route.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Clients.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Domain$Aggregate.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Domain.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Events$Found.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Events.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Extract.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Flows$1.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Flows$Binding.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Flows$Draft.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Flows$Frame.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Flows$Options.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Flows.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Ids.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Json$Reader.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Json.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Lifecycle$1.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Lifecycle$Move.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Lifecycle.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Main.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/OpenApi$Operation.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/OpenApi$Spec.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/OpenApi.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Operations$1.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Operations$UseCase.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Operations.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Proto$Rpc.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Proto$Service.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Proto.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Protocol$Builder.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Protocol$Input.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Protocol$Options.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Protocol.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Source$Project.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Source$Unit.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Source.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Transport$Endpoint.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Transport.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Yaml$Line.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Yaml$Reader.class +0 -0
- package/plugins/extract-java/build/org/portolan/extract/Yaml.class +0 -0
- package/plugins/extract-java/options.schema.json +70 -0
- package/plugins/extract-openapi/describe.go +19 -0
- package/plugins/extract-openapi/describe_test.go +11 -0
- package/plugins/extract-openapi/discover.go +243 -0
- package/plugins/extract-openapi/extract.go +526 -0
- package/plugins/extract-openapi/extract_test.go +545 -0
- package/plugins/extract-openapi/main.go +75 -0
- package/plugins/extract-openapi/options.schema.json +62 -0
- package/plugins/extract-openapi/spec.go +350 -0
- package/plugins/extract-project/README.md +22 -0
- package/plugins/extract-project/describe.go +19 -0
- package/plugins/extract-project/describe_test.go +11 -0
- package/plugins/extract-project/extract.go +221 -0
- package/plugins/extract-project/extract_test.go +109 -0
- package/plugins/extract-project/main.go +41 -0
- package/plugins/extract-project/options.schema.json +48 -0
- package/plugins/extract-proto/ast.go +125 -0
- package/plugins/extract-proto/consumes.go +77 -0
- package/plugins/extract-proto/describe.go +19 -0
- package/plugins/extract-proto/extract.go +293 -0
- package/plugins/extract-proto/extract_test.go +459 -0
- package/plugins/extract-proto/ids.go +89 -0
- package/plugins/extract-proto/ids_test.go +57 -0
- package/plugins/extract-proto/lex.go +285 -0
- package/plugins/extract-proto/main.go +100 -0
- package/plugins/extract-proto/module.go +120 -0
- package/plugins/extract-proto/options.schema.json +51 -0
- package/plugins/extract-proto/parse.go +720 -0
- package/plugins/extract-proto/parse_test.go +307 -0
- package/plugins/extract-proto/provides.go +236 -0
- package/plugins/extract-proto/resolve.go +222 -0
- package/plugins/extract-proto/resolve_test.go +119 -0
- package/plugins/extract-python-kafka/README.md +36 -0
- package/plugins/extract-python-kafka/extract.py +211 -0
- package/plugins/extract-python-kafka/extract_test.py +68 -0
- package/plugins/extract-python-kafka/main.py +59 -0
- package/plugins/extract-python-kafka/options.py +29 -0
- package/plugins/extract-python-kafka/options.schema.json +31 -0
- package/plugins/extract-redis/README.md +11 -0
- package/plugins/extract-redis/describe.go +19 -0
- package/plugins/extract-redis/describe_test.go +11 -0
- package/plugins/extract-redis/extract.go +183 -0
- package/plugins/extract-redis/extract_test.go +168 -0
- package/plugins/extract-redis/keyspaces.go +469 -0
- package/plugins/extract-redis/main.go +44 -0
- package/plugins/extract-redis/options.schema.json +30 -0
- package/plugins/extract-river/describe.go +19 -0
- package/plugins/extract-river/describe_test.go +11 -0
- package/plugins/extract-river/extract.go +507 -0
- package/plugins/extract-river/extract_test.go +132 -0
- package/plugins/extract-river/main.go +42 -0
- package/plugins/extract-river/options.schema.json +21 -0
- package/plugins/extract-rust/Cargo.lock +133 -0
- package/plugins/extract-rust/Cargo.toml +23 -0
- package/plugins/extract-rust/README.md +204 -0
- package/plugins/extract-rust/options.schema.json +65 -0
- package/plugins/extract-rust/rustfmt.toml +1 -0
- package/plugins/extract-sql/ddl.go +893 -0
- package/plugins/extract-sql/ddl_test.go +401 -0
- package/plugins/extract-sql/describe.go +19 -0
- package/plugins/extract-sql/describe_test.go +11 -0
- package/plugins/extract-sql/layout.go +221 -0
- package/plugins/extract-sql/layout_test.go +55 -0
- package/plugins/extract-sql/lineage.go +107 -0
- package/plugins/extract-sql/main.go +141 -0
- package/plugins/extract-sql/maps.go +564 -0
- package/plugins/extract-sql/maps_java.go +117 -0
- package/plugins/extract-sql/maps_rust.go +333 -0
- package/plugins/extract-sql/maps_rust_test.go +70 -0
- package/plugins/extract-sql/maps_test.go +204 -0
- package/plugins/extract-sql/maps_ts.go +398 -0
- package/plugins/extract-sql/maps_ts_test.go +136 -0
- package/plugins/extract-sql/options.schema.json +53 -0
- package/plugins/extract-sql/projection.go +70 -0
- package/plugins/extract-sql/projection_test.go +50 -0
- package/plugins/extract-sql/store.go +420 -0
- package/plugins/extract-sql/store_test.go +233 -0
- package/plugins/extract-sql/view.go +295 -0
- package/plugins/extract-ts/README.md +306 -0
- package/plugins/extract-ts/ast.test.ts +178 -0
- package/plugins/extract-ts/ast.ts +648 -0
- package/plugins/extract-ts/clients.ts +185 -0
- package/plugins/extract-ts/domain.ts +164 -0
- package/plugins/extract-ts/extract.test.ts +208 -0
- package/plugins/extract-ts/extract.ts +200 -0
- package/plugins/extract-ts/flows.ts +783 -0
- package/plugins/extract-ts/graphql.test.ts +73 -0
- package/plugins/extract-ts/graphql.ts +181 -0
- package/plugins/extract-ts/ids.test.ts +21 -0
- package/plugins/extract-ts/ids.ts +52 -0
- package/plugins/extract-ts/lifecycle.ts +138 -0
- package/plugins/extract-ts/main.ts +48 -0
- package/plugins/extract-ts/openapi.test.ts +64 -0
- package/plugins/extract-ts/openapi.ts +99 -0
- package/plugins/extract-ts/operations.ts +93 -0
- package/plugins/extract-ts/options.schema.json +96 -0
- package/plugins/extract-ts/source.test.ts +174 -0
- package/plugins/extract-ts/source.ts +465 -0
- package/plugins/extract-ts/transport.ts +147 -0
- package/plugins/extract-ts/tsconfig.json +13 -0
- package/plugins/extract-ts/wiring.ts +190 -0
- package/plugins/extract-watermill/describe.go +19 -0
- package/plugins/extract-watermill/describe_test.go +11 -0
- package/plugins/extract-watermill/extract.go +1228 -0
- package/plugins/extract-watermill/extract_test.go +234 -0
- package/plugins/extract-watermill/main.go +41 -0
- package/plugins/extract-watermill/options.schema.json +21 -0
- package/plugins/extract-wsdl/describe.go +19 -0
- package/plugins/extract-wsdl/describe_test.go +11 -0
- package/plugins/extract-wsdl/extract.go +148 -0
- package/plugins/extract-wsdl/extract_test.go +45 -0
- package/plugins/extract-wsdl/main.go +53 -0
- package/plugins/extract-wsdl/options.schema.json +59 -0
- package/plugins/fetch-bsr/auth.go +114 -0
- package/plugins/fetch-bsr/bsr.go +240 -0
- package/plugins/fetch-bsr/cache.go +66 -0
- package/plugins/fetch-bsr/describe.go +19 -0
- package/plugins/fetch-bsr/fetch.go +192 -0
- package/plugins/fetch-bsr/fetch_test.go +465 -0
- package/plugins/fetch-bsr/lock.go +71 -0
- package/plugins/fetch-bsr/main.go +117 -0
- package/plugins/fetch-bsr/options.schema.json +42 -0
- package/plugins/fetch-csr/auth.go +95 -0
- package/plugins/fetch-csr/cache.go +69 -0
- package/plugins/fetch-csr/describe.go +19 -0
- package/plugins/fetch-csr/describe_test.go +11 -0
- package/plugins/fetch-csr/fetch.go +254 -0
- package/plugins/fetch-csr/fetch_test.go +494 -0
- package/plugins/fetch-csr/lock.go +95 -0
- package/plugins/fetch-csr/main.go +122 -0
- package/plugins/fetch-csr/options.schema.json +42 -0
- package/plugins/fetch-csr/registry.go +209 -0
- package/plugins/fetch-git/cache.go +65 -0
- package/plugins/fetch-git/describe.go +19 -0
- package/plugins/fetch-git/describe_test.go +11 -0
- package/plugins/fetch-git/fetch.go +181 -0
- package/plugins/fetch-git/fetch_test.go +332 -0
- package/plugins/fetch-git/git.go +169 -0
- package/plugins/fetch-git/lock.go +72 -0
- package/plugins/fetch-git/main.go +127 -0
- package/plugins/fetch-git/offline.go +39 -0
- package/plugins/fetch-git/options.schema.json +42 -0
- package/plugins/fetch-git/pin.go +90 -0
- package/plugins/fetch-git/pin_test.go +74 -0
- package/plugins/gen-backstage/describe.go +17 -0
- package/plugins/gen-backstage/main.go +22 -0
- package/plugins/gen-backstage/options.schema.json +30 -0
- package/plugins/gen-backstage/plugin.go +473 -0
- package/plugins/gen-backstage/plugin_test.go +145 -0
- package/plugins/gen-backstage.wasm +0 -0
- package/plugins/gen-markdown/adr.go +162 -0
- package/plugins/gen-markdown/aggregate.go +362 -0
- package/plugins/gen-markdown/canonical.go +93 -0
- package/plugins/gen-markdown/context.go +90 -0
- package/plugins/gen-markdown/coverage_test.go +89 -0
- package/plugins/gen-markdown/describe.go +19 -0
- package/plugins/gen-markdown/describe_test.go +11 -0
- package/plugins/gen-markdown/external.go +71 -0
- package/plugins/gen-markdown/flow.go +277 -0
- package/plugins/gen-markdown/glossary.go +76 -0
- package/plugins/gen-markdown/glossary_test.go +148 -0
- package/plugins/gen-markdown/llms.go +302 -0
- package/plugins/gen-markdown/main.go +22 -0
- package/plugins/gen-markdown/markdown.go +254 -0
- package/plugins/gen-markdown/markdown_test.go +100 -0
- package/plugins/gen-markdown/module.go +107 -0
- package/plugins/gen-markdown/options.schema.json +16 -0
- package/plugins/gen-markdown/plugin.go +39 -0
- package/plugins/gen-markdown/quality_test.go +176 -0
- package/plugins/gen-markdown/redis_test.go +38 -0
- package/plugins/gen-markdown/render.go +344 -0
- package/plugins/gen-markdown/render_test.go +186 -0
- package/plugins/gen-markdown/service.go +456 -0
- package/plugins/gen-markdown/source.go +177 -0
- package/plugins/gen-markdown/store.go +201 -0
- package/plugins/gen-markdown.wasm +0 -0
- package/plugins/gen-mermaid/describe.go +17 -0
- package/plugins/gen-mermaid/main.go +22 -0
- package/plugins/gen-mermaid/options.schema.json +10 -0
- package/plugins/gen-mermaid/plugin.go +104 -0
- package/plugins/gen-mermaid/plugin_test.go +33 -0
- package/plugins/gen-mermaid.wasm +0 -0
- package/plugins/openapi/ids.go +261 -0
- package/plugins/openapi/ids_test.go +98 -0
- package/plugins/pyplugin/catalog.py +209 -0
- package/plugins/pyplugin/celery_conf.py +436 -0
- package/plugins/pyplugin/celery_tasks.py +76 -0
- package/plugins/pyplugin/kafka.py +570 -0
- package/plugins/pyplugin/names.py +38 -0
- package/plugins/pyplugin/protocol.py +79 -0
- package/plugins/pyplugin/source.py +285 -0
- package/plugins/verify-codeowners/describe.go +19 -0
- package/plugins/verify-codeowners/describe_test.go +11 -0
- package/plugins/verify-codeowners/main.go +75 -0
- package/plugins/verify-codeowners/match.go +85 -0
- package/plugins/verify-codeowners/match_test.go +47 -0
- package/plugins/verify-codeowners/options.schema.json +15 -0
- package/plugins/verify-codeowners/owners.go +164 -0
- package/plugins/verify-codeowners/owners_test.go +225 -0
- package/plugins/verify-codeowners/parse.go +90 -0
- package/plugins/verify-codeowners/parse_test.go +62 -0
- package/plugins/verify-otel/describe.go +19 -0
- package/plugins/verify-otel/describe_test.go +11 -0
- package/plugins/verify-otel/main.go +53 -0
- package/plugins/verify-otel/match.go +336 -0
- package/plugins/verify-otel/options.schema.json +30 -0
- package/plugins/verify-otel/otlp.go +200 -0
- package/plugins/verify-otel/verify.go +734 -0
- package/plugins/verify-otel/verify_test.go +460 -0
- package/portolan.json +1073 -0
- package/public/favicon.svg +12 -0
- package/schema/portolan.schema.json +2558 -0
- package/scripts/README.md +53 -0
- package/scripts/build-report.mjs +60 -0
- package/scripts/build-report.test.mjs +44 -0
- package/scripts/builtin-plugins.mjs +49 -0
- package/scripts/catalog-sources.mjs +67 -0
- package/scripts/diff.mjs +315 -0
- package/scripts/diff.test.mjs +151 -0
- package/scripts/forge-comment.mjs +144 -0
- package/scripts/forge-comment.test.mjs +151 -0
- package/scripts/forge-release.mjs +138 -0
- package/scripts/forge-release.test.mjs +106 -0
- package/scripts/forge.mjs +61 -0
- package/scripts/gen-likec4.mjs +854 -0
- package/scripts/gen-likec4.test.mjs +258 -0
- package/scripts/gen.mjs +603 -0
- package/scripts/generated-docs.test.mjs +66 -0
- package/scripts/local-api.mjs +1192 -0
- package/scripts/local-api.test.mjs +387 -0
- package/scripts/manifest.mjs +214 -0
- package/scripts/manifest.test.mjs +148 -0
- package/scripts/output-path.mjs +79 -0
- package/scripts/output-path.test.mjs +45 -0
- package/scripts/package-smoke.mjs +37 -0
- package/scripts/plugin-host.mjs +419 -0
- package/scripts/plugin-host.test.mjs +109 -0
- package/scripts/plugin-wasm-worker.mjs +34 -0
- package/scripts/run-builtin.mjs +81 -0
- package/scripts/schema.mjs +357 -0
- package/scripts/site-docs.mjs +295 -0
- package/scripts/site-docs.test.mjs +181 -0
- package/scripts/vendor-lock.mjs +58 -0
- package/scripts/vendor-lock.test.mjs +69 -0
- package/src/README.md +38 -0
- package/src/app/App.tsx +448 -0
- package/src/app/BranchPicker.test.ts +46 -0
- package/src/app/BranchPicker.tsx +153 -0
- package/src/app/Breadcrumbs.test.ts +38 -0
- package/src/app/Breadcrumbs.tsx +223 -0
- package/src/app/BuildStamp.tsx +146 -0
- package/src/app/CommandPalette.tsx +292 -0
- package/src/app/HashScroll.tsx +45 -0
- package/src/app/Sidebar.tsx +1742 -0
- package/src/app/TopBar.tsx +393 -0
- package/src/app/density.tsx +64 -0
- package/src/app/forge-access.test.ts +27 -0
- package/src/app/forge-access.tsx +80 -0
- package/src/app/panels.tsx +141 -0
- package/src/app/pins.tsx +242 -0
- package/src/app/query-client.ts +24 -0
- package/src/app/responsive.ts +55 -0
- package/src/app/shortcuts.test.ts +39 -0
- package/src/app/shortcuts.tsx +282 -0
- package/src/app/theme.tsx +51 -0
- package/src/app/title.test.ts +14 -0
- package/src/app/title.ts +30 -0
- package/src/app/toast.tsx +59 -0
- package/src/app/tree-keys.test.ts +80 -0
- package/src/app/tree-keys.ts +87 -0
- package/src/app/ui-store.ts +52 -0
- package/src/catalog-error.test.ts +105 -0
- package/src/catalog-profile.test.ts +59 -0
- package/src/catalog-profile.ts +101 -0
- package/src/catalog-stores.test.ts +431 -0
- package/src/catalog.test.ts +1215 -0
- package/src/catalog.ts +3125 -0
- package/src/chat/Cards.tsx +408 -0
- package/src/chat/ChatPanel.tsx +79 -0
- package/src/chat/ChatSettings.tsx +219 -0
- package/src/chat/Composer.tsx +99 -0
- package/src/chat/Conversation.tsx +281 -0
- package/src/chat/Header.tsx +46 -0
- package/src/chat/Message.tsx +49 -0
- package/src/chat/Notice.tsx +195 -0
- package/src/chat/Starter.tsx +67 -0
- package/src/chat/Steps.tsx +45 -0
- package/src/chat/Waiting.tsx +87 -0
- package/src/chat/flags.test.ts +59 -0
- package/src/chat/flags.ts +155 -0
- package/src/chat/linkify.test.ts +30 -0
- package/src/chat/linkify.ts +45 -0
- package/src/chat/prefs.ts +56 -0
- package/src/chat/prompt.test.ts +43 -0
- package/src/chat/prompt.ts +157 -0
- package/src/chat/store.ts +35 -0
- package/src/chat/tools.ts +58 -0
- package/src/chat/transport.ts +70 -0
- package/src/components/AdrRow.tsx +29 -0
- package/src/components/AnchorLink.tsx +67 -0
- package/src/components/ApiReference.tsx +134 -0
- package/src/components/AsyncApiReference.tsx +120 -0
- package/src/components/CatalogStamp.tsx +155 -0
- package/src/components/ChannelRows.tsx +132 -0
- package/src/components/CommandRows.tsx +139 -0
- package/src/components/DiagramSkeleton.tsx +71 -0
- package/src/components/EditorLink.tsx +85 -0
- package/src/components/FieldTree.tsx +305 -0
- package/src/components/FlowTrigger.tsx +34 -0
- package/src/components/Ident.tsx +89 -0
- package/src/components/Integrations.tsx +243 -0
- package/src/components/LifecycleDiagram.tsx +110 -0
- package/src/components/MachineDocs.tsx +42 -0
- package/src/components/Markdown.tsx +173 -0
- package/src/components/MarkdownTable.tsx +206 -0
- package/src/components/Mermaid.tsx +211 -0
- package/src/components/MethodRows.tsx +309 -0
- package/src/components/Overlay.tsx +125 -0
- package/src/components/PageHeader.tsx +189 -0
- package/src/components/RowActions.tsx +97 -0
- package/src/components/SchemaDocument.tsx +89 -0
- package/src/components/Select.tsx +126 -0
- package/src/components/ShapeRows.tsx +118 -0
- package/src/components/SourceDoc.tsx +82 -0
- package/src/components/SourcePreview.tsx +441 -0
- package/src/components/TabRow.tsx +182 -0
- package/src/components/TechIcon.tsx +34 -0
- package/src/components/Toc.tsx +132 -0
- package/src/components/WhatLinksHere.tsx +273 -0
- package/src/components/WsdlReference.tsx +84 -0
- package/src/components/ddd-icons.tsx +107 -0
- package/src/components/kind.tsx +157 -0
- package/src/components/logo.tsx +61 -0
- package/src/components/primitives.tsx +264 -0
- package/src/data.test.ts +18 -0
- package/src/data.ts +202 -0
- package/src/enrich.test.ts +1150 -0
- package/src/enrich.ts +672 -0
- package/src/er/ErCanvas.tsx +533 -0
- package/src/er/RedisSchema.tsx +74 -0
- package/src/er/RelationCard.tsx +267 -0
- package/src/er/StoreHeader.tsx +155 -0
- package/src/er/TableNode.tsx +84 -0
- package/src/er/ViewNode.tsx +83 -0
- package/src/er/layout.test.ts +115 -0
- package/src/er/layout.ts +77 -0
- package/src/er/lineage.test.ts +140 -0
- package/src/er/lineage.ts +107 -0
- package/src/er/markers.tsx +79 -0
- package/src/er/spec.test.ts +344 -0
- package/src/er/spec.ts +426 -0
- package/src/flow/ChainList.tsx +162 -0
- package/src/flow/FlowTable.tsx +123 -0
- package/src/flow/FlowToolbar.tsx +372 -0
- package/src/flow/StepDetail.tsx +380 -0
- package/src/flow/StepRail.tsx +428 -0
- package/src/flow/answers.test.ts +50 -0
- package/src/flow/answers.ts +58 -0
- package/src/flow/chain.test.ts +383 -0
- package/src/flow/chain.ts +353 -0
- package/src/flow/chapters.test.ts +185 -0
- package/src/flow/chapters.ts +225 -0
- package/src/flow/continues.test.ts +102 -0
- package/src/flow/continues.ts +65 -0
- package/src/flow/cross-context.test.ts +97 -0
- package/src/flow/cross-context.ts +35 -0
- package/src/flow/mermaid.test.ts +22 -0
- package/src/flow/mermaid.ts +141 -0
- package/src/flow/outline.test.ts +212 -0
- package/src/flow/outline.ts +170 -0
- package/src/flow/paths.test.ts +129 -0
- package/src/flow/paths.ts +147 -0
- package/src/flow/prefs.test.ts +80 -0
- package/src/flow/prefs.ts +104 -0
- package/src/graph/DependencyGraph.tsx +283 -0
- package/src/graph/DependencyNodes.tsx +162 -0
- package/src/graph/EdgeLabel.tsx +61 -0
- package/src/graph/FocusedEventGraph.tsx +211 -0
- package/src/graph/GraphToolbar.tsx +187 -0
- package/src/graph/RoutedEdge.tsx +80 -0
- package/src/graph/dependency-layout.test.ts +360 -0
- package/src/graph/dependency-layout.ts +444 -0
- package/src/graph/elk.test.ts +70 -0
- package/src/graph/elk.ts +287 -0
- package/src/graph/nodes.tsx +97 -0
- package/src/graph/theme.ts +81 -0
- package/src/graph/useElkFlow.ts +125 -0
- package/src/index.css +1547 -0
- package/src/language/InLanguage.tsx +40 -0
- package/src/language/TermCard.tsx +132 -0
- package/src/language/cards.test.ts +114 -0
- package/src/language/cards.ts +111 -0
- package/src/lib/admonition.test.ts +49 -0
- package/src/lib/admonition.ts +48 -0
- package/src/lib/adr.test.ts +131 -0
- package/src/lib/adr.ts +68 -0
- package/src/lib/api.test.ts +122 -0
- package/src/lib/api.ts +135 -0
- package/src/lib/backlinks.test.ts +330 -0
- package/src/lib/backlinks.ts +567 -0
- package/src/lib/branch-compare.ts +16 -0
- package/src/lib/build-info.test.ts +76 -0
- package/src/lib/build-info.ts +80 -0
- package/src/lib/catalog-diff.test.ts +275 -0
- package/src/lib/catalog-diff.ts +655 -0
- package/src/lib/clipboard.ts +43 -0
- package/src/lib/comparison-memory.test.ts +40 -0
- package/src/lib/comparison-memory.ts +39 -0
- package/src/lib/context-color.ts +27 -0
- package/src/lib/context-map.test.ts +148 -0
- package/src/lib/context-map.ts +399 -0
- package/src/lib/data-model.test.ts +245 -0
- package/src/lib/data-model.ts +399 -0
- package/src/lib/data-problems.test.ts +178 -0
- package/src/lib/data-problems.ts +314 -0
- package/src/lib/derive.test.ts +251 -0
- package/src/lib/derive.ts +515 -0
- package/src/lib/editor-link.test.ts +125 -0
- package/src/lib/editor-link.ts +96 -0
- package/src/lib/editor-prefs.ts +27 -0
- package/src/lib/event-graph.test.ts +237 -0
- package/src/lib/event-graph.ts +327 -0
- package/src/lib/export-canvas.ts +37 -0
- package/src/lib/export-file.test.ts +30 -0
- package/src/lib/export-file.ts +20 -0
- package/src/lib/flow-tree.test.ts +177 -0
- package/src/lib/flow-tree.ts +160 -0
- package/src/lib/forge-refs.test.ts +50 -0
- package/src/lib/forge-refs.ts +60 -0
- package/src/lib/format.test.ts +35 -0
- package/src/lib/format.ts +64 -0
- package/src/lib/github-catalog.test.ts +301 -0
- package/src/lib/github-catalog.ts +610 -0
- package/src/lib/integrations.test.ts +119 -0
- package/src/lib/integrations.ts +133 -0
- package/src/lib/kinds.test.ts +91 -0
- package/src/lib/kinds.ts +204 -0
- package/src/lib/lifecycle.test.ts +93 -0
- package/src/lib/lifecycle.ts +165 -0
- package/src/lib/local-api.ts +194 -0
- package/src/lib/motion-features.ts +11 -0
- package/src/lib/motion.test.ts +120 -0
- package/src/lib/motion.tsx +269 -0
- package/src/lib/palette-recent.test.ts +80 -0
- package/src/lib/palette-recent.ts +90 -0
- package/src/lib/palette.test.ts +365 -0
- package/src/lib/palette.ts +593 -0
- package/src/lib/pins.test.ts +139 -0
- package/src/lib/pins.ts +130 -0
- package/src/lib/problems.test.ts +112 -0
- package/src/lib/project-preview.ts +5 -0
- package/src/lib/proto-problems.test.ts +121 -0
- package/src/lib/proto-problems.ts +65 -0
- package/src/lib/queries.test.ts +113 -0
- package/src/lib/queries.ts +131 -0
- package/src/lib/registry.test.ts +219 -0
- package/src/lib/registry.ts +208 -0
- package/src/lib/scenarios.ts +547 -0
- package/src/lib/setup-info.test.ts +199 -0
- package/src/lib/setup-info.ts +415 -0
- package/src/lib/shape.test.ts +289 -0
- package/src/lib/shape.ts +454 -0
- package/src/lib/sidebar-prefs.test.ts +32 -0
- package/src/lib/sidebar-prefs.ts +75 -0
- package/src/lib/source-code.test.ts +159 -0
- package/src/lib/source-code.ts +286 -0
- package/src/lib/source-doc.test.ts +131 -0
- package/src/lib/source-doc.ts +103 -0
- package/src/lib/source-highlight.test.ts +29 -0
- package/src/lib/source-highlight.ts +24 -0
- package/src/lib/source-link.test.ts +153 -0
- package/src/lib/source-link.ts +201 -0
- package/src/lib/spec-files.test.ts +24 -0
- package/src/lib/spec-files.ts +23 -0
- package/src/lib/table-directive.test.ts +139 -0
- package/src/lib/table-directive.ts +106 -0
- package/src/lib/tech.test.ts +120 -0
- package/src/lib/tech.ts +421 -0
- package/src/lib/terms.test.ts +67 -0
- package/src/lib/terms.ts +179 -0
- package/src/lib/wire-problems.test.ts +263 -0
- package/src/lib/wire-problems.ts +281 -0
- package/src/likec4/C4View.tsx +55 -0
- package/src/likec4/CanvasBridge.tsx +187 -0
- package/src/likec4/FlowView.tsx +235 -0
- package/src/likec4/InteractiveView.tsx +144 -0
- package/src/likec4/canvas-viewport.test.ts +149 -0
- package/src/likec4/canvas-viewport.ts +135 -0
- package/src/likec4/flow-edges.test.ts +51 -0
- package/src/likec4/flow-edges.ts +89 -0
- package/src/likec4/frame-theme.test.ts +76 -0
- package/src/likec4/frame-theme.ts +101 -0
- package/src/likec4/highlight-css.test.ts +49 -0
- package/src/likec4/highlight-css.ts +52 -0
- package/src/likec4/ids.test.ts +151 -0
- package/src/likec4/ids.ts +115 -0
- package/src/likec4/levels.tsx +70 -0
- package/src/likec4/mapping.test.ts +66 -0
- package/src/likec4/mapping.ts +54 -0
- package/src/likec4/reserved.json +141 -0
- package/src/likec4/view-index.ts +78 -0
- package/src/main.tsx +13 -0
- package/src/map/ContextMapGraph.tsx +274 -0
- package/src/map/ContextNode.tsx +70 -0
- package/src/map/FloatingEdge.tsx +86 -0
- package/src/merge.test.ts +1038 -0
- package/src/merge.ts +1004 -0
- package/src/pages/AdrDetail.tsx +242 -0
- package/src/pages/AdrIndex.tsx +114 -0
- package/src/pages/AggregatePage.tsx +727 -0
- package/src/pages/BlockPage.tsx +478 -0
- package/src/pages/CatalogFailure.tsx +111 -0
- package/src/pages/Changes.tsx +313 -0
- package/src/pages/ContextMap.tsx +534 -0
- package/src/pages/ContextPage.tsx +346 -0
- package/src/pages/EnumPage.tsx +282 -0
- package/src/pages/EventPage.tsx +686 -0
- package/src/pages/ExternalPage.tsx +204 -0
- package/src/pages/FlowDetail.tsx +663 -0
- package/src/pages/FlowIndex.tsx +303 -0
- package/src/pages/GraphPage.tsx +217 -0
- package/src/pages/Language.tsx +257 -0
- package/src/pages/ModulePage.tsx +366 -0
- package/src/pages/NotFound.tsx +54 -0
- package/src/pages/Overview.tsx +344 -0
- package/src/pages/Problems.tsx +360 -0
- package/src/pages/RegistryIndex.tsx +118 -0
- package/src/pages/ServicePage.tsx +746 -0
- package/src/pages/Settings.tsx +975 -0
- package/src/pages/StorePage.tsx +114 -0
- package/src/peek/PeekCard.test.ts +35 -0
- package/src/peek/PeekCard.tsx +118 -0
- package/src/peek/PeekLayer.tsx +147 -0
- package/src/peek/model.test.ts +156 -0
- package/src/peek/model.ts +253 -0
- package/src/routes.test.ts +222 -0
- package/src/routes.ts +449 -0
- package/src/selection/DetailPanel.tsx +1407 -0
- package/src/selection/hash.test.ts +73 -0
- package/src/selection/hash.ts +58 -0
- package/src/selection/model.test.ts +199 -0
- package/src/selection/model.ts +473 -0
- package/src/selection/pages.test.ts +115 -0
- package/src/selection/pages.ts +268 -0
- package/src/selection/store.test.ts +62 -0
- package/src/selection/store.ts +46 -0
- package/src/selection/sync.tsx +99 -0
- package/src/table/ColumnsMenu.tsx +72 -0
- package/src/table/DataTable.tsx +780 -0
- package/src/table/Facets.tsx +54 -0
- package/src/table/GroupMenu.tsx +69 -0
- package/src/table/Toolbar.tsx +190 -0
- package/src/table/cells.tsx +117 -0
- package/src/table/compare.test.ts +117 -0
- package/src/table/compare.ts +196 -0
- package/src/table/export.test.ts +88 -0
- package/src/table/export.ts +66 -0
- package/src/table/facet-groups.test.ts +74 -0
- package/src/table/facet-groups.ts +56 -0
- package/src/table/grouping.test.ts +84 -0
- package/src/table/grouping.ts +82 -0
- package/src/table/infer.test.ts +57 -0
- package/src/table/infer.ts +50 -0
- package/src/table/persist.test.ts +76 -0
- package/src/table/persist.ts +112 -0
- package/src/table/sort-url.test.ts +75 -0
- package/src/table/sort-url.ts +52 -0
- package/src/table/types.ts +80 -0
- package/src/table/useTableState.ts +220 -0
- package/src/test-catalog.ts +7 -0
- package/src/testing/estate/data__catalog.json +2847 -0
- package/src/testing/estate/data__flows.json +1724 -0
- package/src/testing/estate/examples__auth__portolan__api.json +212 -0
- package/src/testing/estate/examples__auth__portolan__domain.json +1204 -0
- package/src/testing/estate/examples__auth__portolan__glossary.json +226 -0
- package/src/testing/estate/examples__auth__portolan__observed.json +757 -0
- package/src/testing/estate/examples__auth__portolan__stores.json +195 -0
- package/src/testing/estate/examples__shop__cart__portolan__api.json +234 -0
- package/src/testing/estate/examples__shop__cart__portolan__commands.json +86 -0
- package/src/testing/estate/examples__shop__cart__portolan__domain.json +966 -0
- package/src/testing/estate/examples__shop__cart__portolan__observed.json +498 -0
- package/src/testing/estate/examples__shop__cart__portolan__stores.json +208 -0
- package/src/testing/estate/examples__shop__oms__portolan__glossary.json +98 -0
- package/src/testing/estate/examples__shop__oms__portolan__proto.json +186 -0
- package/src/testing/estate.ts +49 -0
- package/src/trail/Trail.tsx +81 -0
- package/src/trail/model.test.ts +157 -0
- package/src/trail/model.ts +189 -0
- package/src/trail/record.tsx +32 -0
- package/src/trail/store.test.ts +66 -0
- package/src/trail/store.ts +102 -0
- package/tsconfig.json +35 -0
- package/vite.config.ts +171 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
// The only file that reads the environment.
|
|
4
|
+
//
|
|
5
|
+
// The plugin protocol says a plugin has "no ambient state to read, no
|
|
6
|
+
// environment". That is about FACTS: nothing about the estate may come from
|
|
7
|
+
// anywhere but the request, or a fragment stops being reproducible from the
|
|
8
|
+
// tree it describes.
|
|
9
|
+
//
|
|
10
|
+
// A credential is not a fact about the estate. It is how the transport is
|
|
11
|
+
// allowed to open a socket, the same way a git credential is - it changes
|
|
12
|
+
// whether the fetch succeeds, never what the fetch says. Isolating it in one
|
|
13
|
+
// file that nothing else calls is what keeps that claim checkable.
|
|
14
|
+
//
|
|
15
|
+
// It is also why this plugin can never be wasm. It needs a socket and a
|
|
16
|
+
// secret, and `process` exists for exactly that trade.
|
|
17
|
+
|
|
18
|
+
import (
|
|
19
|
+
"bufio"
|
|
20
|
+
"os"
|
|
21
|
+
"path/filepath"
|
|
22
|
+
"strings"
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
// TokenEnv is where `buf registry login` is usually mirrored in CI.
|
|
26
|
+
const TokenEnv = "BUF_TOKEN"
|
|
27
|
+
|
|
28
|
+
// token finds a credential for a registry, or returns none.
|
|
29
|
+
//
|
|
30
|
+
// None is a normal outcome, not a failure: public modules download
|
|
31
|
+
// anonymously, and an estate whose schemas are public never needs a token.
|
|
32
|
+
func token(registry string) string {
|
|
33
|
+
if t := strings.TrimSpace(os.Getenv(TokenEnv)); t != "" {
|
|
34
|
+
return t
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return netrcToken(registry)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// netrcToken reads the password `buf registry login` wrote.
|
|
41
|
+
func netrcToken(registry string) string {
|
|
42
|
+
home, err := os.UserHomeDir()
|
|
43
|
+
if err != nil {
|
|
44
|
+
return ""
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
for _, name := range []string{".netrc", "_netrc"} {
|
|
48
|
+
if t := readNetrc(filepath.Join(home, name), registry); t != "" {
|
|
49
|
+
return t
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return ""
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// readNetrc walks a netrc for the machine asked about.
|
|
57
|
+
//
|
|
58
|
+
// Deliberately small: netrc is a stream of words, and the only entry that
|
|
59
|
+
// matters here is the password belonging to one machine.
|
|
60
|
+
func readNetrc(path, machine string) string {
|
|
61
|
+
file, err := os.Open(path)
|
|
62
|
+
if err != nil {
|
|
63
|
+
return ""
|
|
64
|
+
}
|
|
65
|
+
defer file.Close()
|
|
66
|
+
|
|
67
|
+
words := bufio.NewScanner(file)
|
|
68
|
+
words.Split(bufio.ScanWords)
|
|
69
|
+
|
|
70
|
+
current := ""
|
|
71
|
+
for words.Scan() {
|
|
72
|
+
switch words.Text() {
|
|
73
|
+
case "machine":
|
|
74
|
+
if !words.Scan() {
|
|
75
|
+
return ""
|
|
76
|
+
}
|
|
77
|
+
current = words.Text()
|
|
78
|
+
case "default":
|
|
79
|
+
current = machine
|
|
80
|
+
case "password":
|
|
81
|
+
if !words.Scan() {
|
|
82
|
+
return ""
|
|
83
|
+
}
|
|
84
|
+
if current == machine {
|
|
85
|
+
return words.Text()
|
|
86
|
+
}
|
|
87
|
+
case "login", "account":
|
|
88
|
+
// Read past the value so it cannot be mistaken for a keyword.
|
|
89
|
+
words.Scan()
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return ""
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// OfflineEnv turns the fetch off. Explicit, rather than inferred from a socket
|
|
97
|
+
// timeout: CI sets it in one line, and a build that would otherwise depend on
|
|
98
|
+
// the registry being up cannot silently start doing so again.
|
|
99
|
+
const OfflineEnv = "PORTOLAN_OFFLINE"
|
|
100
|
+
|
|
101
|
+
func offline() bool {
|
|
102
|
+
if strings.TrimSpace(os.Getenv(OfflineEnv)) != "" {
|
|
103
|
+
return true
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// CI verifies what was committed. It never needs to reach the registry, and
|
|
107
|
+
// a fork's pull request has no secret to reach it with.
|
|
108
|
+
switch strings.ToLower(strings.TrimSpace(os.Getenv("CI"))) {
|
|
109
|
+
case "", "0", "false":
|
|
110
|
+
return false
|
|
111
|
+
default:
|
|
112
|
+
return true
|
|
113
|
+
}
|
|
114
|
+
}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
// The only file that knows the registry's wire.
|
|
4
|
+
//
|
|
5
|
+
// The BSR's public API is Connect, and a Connect unary call is an ordinary
|
|
6
|
+
// HTTP POST carrying the request message as JSON - so this needs net/http and
|
|
7
|
+
// encoding/json and nothing else. No grpc dependency, no protobuf runtime, in
|
|
8
|
+
// a go.mod that has two narrow dependencies.
|
|
9
|
+
//
|
|
10
|
+
// The message shapes below are buf/registry/module/v1, and the JSON names are
|
|
11
|
+
// protojson's: lowerCamelCase, `bytes` as base64. Everything the wire knows is
|
|
12
|
+
// in this file on purpose - if buf changes the shape, or the older
|
|
13
|
+
// buf.alpha.registry.v1alpha1 endpoints have to be fallen back to, this is the
|
|
14
|
+
// only file that moves.
|
|
15
|
+
|
|
16
|
+
import (
|
|
17
|
+
"bytes"
|
|
18
|
+
"encoding/hex"
|
|
19
|
+
"encoding/json"
|
|
20
|
+
"fmt"
|
|
21
|
+
"io"
|
|
22
|
+
"net/http"
|
|
23
|
+
"strings"
|
|
24
|
+
"time"
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
const (
|
|
28
|
+
downloadMethod = "/buf.registry.module.v1.DownloadService/Download"
|
|
29
|
+
commitsMethod = "/buf.registry.module.v1.CommitService/GetCommits"
|
|
30
|
+
|
|
31
|
+
// The Connect protocol asks a client to say which version it speaks.
|
|
32
|
+
connectVersionHeader = "Connect-Protocol-Version"
|
|
33
|
+
connectVersion = "1"
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
// resourceRef names a module and which version of it is wanted.
|
|
37
|
+
type resourceRef struct {
|
|
38
|
+
Name *refName `json:"name,omitempty"`
|
|
39
|
+
ID string `json:"id,omitempty"`
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
type refName struct {
|
|
43
|
+
Owner string `json:"owner"`
|
|
44
|
+
Module string `json:"module"`
|
|
45
|
+
// Ref is untyped: a commit id, a label, a tag. A pinned module always sends
|
|
46
|
+
// a commit id, which is the only form that makes a download reproducible.
|
|
47
|
+
Ref string `json:"ref,omitempty"`
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
type downloadRequest struct {
|
|
51
|
+
Values []downloadValue `json:"values"`
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
type downloadValue struct {
|
|
55
|
+
ResourceRef resourceRef `json:"resourceRef"`
|
|
56
|
+
// Only .proto: the docs and licence a module also carries are not something
|
|
57
|
+
// portolan reads, and fetching them would put files in the tree that
|
|
58
|
+
// nothing explains.
|
|
59
|
+
FileTypes []string `json:"fileTypes,omitempty"`
|
|
60
|
+
Paths []string `json:"paths,omitempty"`
|
|
61
|
+
// Without this, narrowing to a path the module does not have is an error
|
|
62
|
+
// rather than an empty answer.
|
|
63
|
+
PathsAllowNotExist bool `json:"pathsAllowNotExist,omitempty"`
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
type downloadResponse struct {
|
|
67
|
+
Contents []struct {
|
|
68
|
+
Commit wireCommit `json:"commit"`
|
|
69
|
+
Files []struct {
|
|
70
|
+
Path string `json:"path"`
|
|
71
|
+
// bytes on the wire, so base64 in JSON.
|
|
72
|
+
Content []byte `json:"content"`
|
|
73
|
+
} `json:"files"`
|
|
74
|
+
} `json:"contents"`
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
type wireCommit struct {
|
|
78
|
+
ID string `json:"id"`
|
|
79
|
+
Digest struct {
|
|
80
|
+
Type string `json:"type"`
|
|
81
|
+
Value []byte `json:"value"`
|
|
82
|
+
} `json:"digest"`
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// display renders a digest the way buf writes one: `b5:<hex>`.
|
|
86
|
+
func (c wireCommit) display() string {
|
|
87
|
+
if len(c.Digest.Value) == 0 {
|
|
88
|
+
return ""
|
|
89
|
+
}
|
|
90
|
+
kind := strings.ToLower(strings.TrimPrefix(c.Digest.Type, "DIGEST_TYPE_"))
|
|
91
|
+
if kind == "" || kind == "unspecified" {
|
|
92
|
+
kind = "b5"
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return kind + ":" + hex.EncodeToString(c.Digest.Value)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
type getCommitsRequest struct {
|
|
99
|
+
ResourceRefs []resourceRef `json:"resourceRefs"`
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
type getCommitsResponse struct {
|
|
103
|
+
Commits []wireCommit `json:"commits"`
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// client talks to one registry.
|
|
107
|
+
type client struct {
|
|
108
|
+
http *http.Client
|
|
109
|
+
base string
|
|
110
|
+
token string
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
func newClient(registry, token string) *client {
|
|
114
|
+
return &client{
|
|
115
|
+
// A timeout rather than none: a plugin that hangs holds up the whole
|
|
116
|
+
// generate run, and the host has no way to interrupt it.
|
|
117
|
+
http: &http.Client{Timeout: 60 * time.Second},
|
|
118
|
+
base: baseURL(registry),
|
|
119
|
+
token: token,
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// baseURL lets a registry be given with a scheme.
|
|
124
|
+
//
|
|
125
|
+
// buf.build is https and needs no help. A self-hosted BSR behind a plain-http
|
|
126
|
+
// internal address does, and so does a test server - which is the same need,
|
|
127
|
+
// and worth meeting once rather than threading a seam through the plugin.
|
|
128
|
+
func baseURL(registry string) string {
|
|
129
|
+
if strings.HasPrefix(registry, "http://") || strings.HasPrefix(registry, "https://") {
|
|
130
|
+
return strings.TrimSuffix(registry, "/")
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return "https://" + registry
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// download fetches a module's .proto files at a given ref.
|
|
137
|
+
func (c *client) download(owner, module, ref string, paths []string) (wireCommit, map[string][]byte, error) {
|
|
138
|
+
req := downloadRequest{Values: []downloadValue{{
|
|
139
|
+
ResourceRef: resourceRef{Name: &refName{Owner: owner, Module: module, Ref: ref}},
|
|
140
|
+
FileTypes: []string{"FILE_TYPE_PROTO"},
|
|
141
|
+
Paths: paths,
|
|
142
|
+
PathsAllowNotExist: len(paths) > 0,
|
|
143
|
+
}}}
|
|
144
|
+
|
|
145
|
+
var resp downloadResponse
|
|
146
|
+
if err := c.call(downloadMethod, req, &resp); err != nil {
|
|
147
|
+
return wireCommit{}, nil, err
|
|
148
|
+
}
|
|
149
|
+
if len(resp.Contents) == 0 {
|
|
150
|
+
return wireCommit{}, nil, fmt.Errorf("%s/%s: the registry returned no content", owner, module)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
content := resp.Contents[0]
|
|
154
|
+
files := make(map[string][]byte, len(content.Files))
|
|
155
|
+
for _, f := range content.Files {
|
|
156
|
+
files[f.Path] = f.Content
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return content.Commit, files, nil
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// resolve turns a label into the commit it currently points at.
|
|
163
|
+
func (c *client) resolve(owner, module, ref string) (wireCommit, error) {
|
|
164
|
+
req := getCommitsRequest{ResourceRefs: []resourceRef{
|
|
165
|
+
{Name: &refName{Owner: owner, Module: module, Ref: ref}},
|
|
166
|
+
}}
|
|
167
|
+
|
|
168
|
+
var resp getCommitsResponse
|
|
169
|
+
if err := c.call(commitsMethod, req, &resp); err != nil {
|
|
170
|
+
return wireCommit{}, err
|
|
171
|
+
}
|
|
172
|
+
if len(resp.Commits) == 0 {
|
|
173
|
+
return wireCommit{}, fmt.Errorf("%s/%s: no commit for %q", owner, module, ref)
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return resp.Commits[0], nil
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
func (c *client) call(method string, in, out any) error {
|
|
180
|
+
body, err := json.Marshal(in)
|
|
181
|
+
if err != nil {
|
|
182
|
+
return err
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
url := c.base + method
|
|
186
|
+
req, err := http.NewRequest(http.MethodPost, url, bytes.NewReader(body))
|
|
187
|
+
if err != nil {
|
|
188
|
+
return err
|
|
189
|
+
}
|
|
190
|
+
req.Header.Set("Content-Type", "application/json")
|
|
191
|
+
req.Header.Set(connectVersionHeader, connectVersion)
|
|
192
|
+
if c.token != "" {
|
|
193
|
+
req.Header.Set("Authorization", "Bearer "+c.token)
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
resp, err := c.http.Do(req)
|
|
197
|
+
if err != nil {
|
|
198
|
+
return err
|
|
199
|
+
}
|
|
200
|
+
defer resp.Body.Close()
|
|
201
|
+
|
|
202
|
+
raw, err := io.ReadAll(io.LimitReader(resp.Body, 256<<20))
|
|
203
|
+
if err != nil {
|
|
204
|
+
return err
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if resp.StatusCode != http.StatusOK {
|
|
208
|
+
return fmt.Errorf("%s: %s", method, connectError(resp.StatusCode, raw))
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return json.Unmarshal(raw, out)
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// connectError reads the error body Connect sends, falling back to the status
|
|
215
|
+
// when the body is not one.
|
|
216
|
+
func connectError(status int, body []byte) string {
|
|
217
|
+
var wire struct {
|
|
218
|
+
Code string `json:"code"`
|
|
219
|
+
Message string `json:"message"`
|
|
220
|
+
}
|
|
221
|
+
if err := json.Unmarshal(body, &wire); err == nil && wire.Message != "" {
|
|
222
|
+
if wire.Code != "" {
|
|
223
|
+
return wire.Code + ": " + wire.Message
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return wire.Message
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return fmt.Sprintf("http %d", status)
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// splitModule breaks `buf.build/acme/shop` into its three parts.
|
|
233
|
+
func splitModule(name string) (registry, owner, module string, err error) {
|
|
234
|
+
parts := strings.Split(strings.TrimSpace(name), "/")
|
|
235
|
+
if len(parts) != 3 || parts[0] == "" || parts[1] == "" || parts[2] == "" {
|
|
236
|
+
return "", "", "", fmt.Errorf("%q is not a module name; expected <registry>/<owner>/<module>", name)
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return parts[0], parts[1], parts[2], nil
|
|
240
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
// Replaying a fetch from what is already on disk.
|
|
4
|
+
//
|
|
5
|
+
// The cache is not a second copy of anything: it IS the tree. The protos this
|
|
6
|
+
// plugin fetched were written by the host through the ordinary Response.Files
|
|
7
|
+
// path, so they are committed, reviewable, and GC'd when the step stops naming
|
|
8
|
+
// them. Reading them back and checking them against the lock is what lets a
|
|
9
|
+
// build that never opens a socket produce byte-identical output.
|
|
10
|
+
|
|
11
|
+
import (
|
|
12
|
+
"fmt"
|
|
13
|
+
"os"
|
|
14
|
+
"path/filepath"
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
// cached is one module's files, read back from the tree.
|
|
18
|
+
type cached struct {
|
|
19
|
+
lock LockModule
|
|
20
|
+
files map[string][]byte
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// replay reads a module's committed copy and checks it against its lock.
|
|
24
|
+
//
|
|
25
|
+
// An incomplete or edited cache is reported rather than patched over. The two
|
|
26
|
+
// failures it distinguishes matter: nothing on disk means there is nothing to
|
|
27
|
+
// fall back to, and bytes that no longer match their digest mean somebody
|
|
28
|
+
// edited a vendored copy - the drift docs/adr/org.0001.md wants visible.
|
|
29
|
+
func replay(dir string) (*cached, error) {
|
|
30
|
+
raw, err := os.ReadFile(filepath.Join(dir, LockName))
|
|
31
|
+
if os.IsNotExist(err) {
|
|
32
|
+
return nil, fmt.Errorf("no %s in %s", LockName, filepath.ToSlash(dir))
|
|
33
|
+
}
|
|
34
|
+
if err != nil {
|
|
35
|
+
return nil, err
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
var lock Lock
|
|
39
|
+
if err := jsonUnmarshal(raw, &lock); err != nil {
|
|
40
|
+
return nil, fmt.Errorf("%s: %w", filepath.ToSlash(filepath.Join(dir, LockName)), err)
|
|
41
|
+
}
|
|
42
|
+
if len(lock.Modules) != 1 {
|
|
43
|
+
return nil, fmt.Errorf("%s names %d modules; expected exactly one",
|
|
44
|
+
filepath.ToSlash(filepath.Join(dir, LockName)), len(lock.Modules))
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
entry := lock.Modules[0]
|
|
48
|
+
files := make(map[string][]byte, len(entry.Files))
|
|
49
|
+
|
|
50
|
+
for _, want := range entry.Files {
|
|
51
|
+
at := filepath.Join(dir, filepath.FromSlash(want.Path))
|
|
52
|
+
content, err := os.ReadFile(at)
|
|
53
|
+
if os.IsNotExist(err) {
|
|
54
|
+
return nil, fmt.Errorf("%s is in the lock but not on disk", want.Path)
|
|
55
|
+
}
|
|
56
|
+
if err != nil {
|
|
57
|
+
return nil, err
|
|
58
|
+
}
|
|
59
|
+
if got := digestOf(content); got != want.SHA256 {
|
|
60
|
+
return nil, fmt.Errorf("%s does not match its digest; the vendored copy was edited by hand", want.Path)
|
|
61
|
+
}
|
|
62
|
+
files[want.Path] = content
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return &cached{lock: entry, files: files}, nil
|
|
66
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
_ "embed"
|
|
5
|
+
|
|
6
|
+
"github.com/shortlink-org/portolan/plugin"
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
//go:embed options.schema.json
|
|
10
|
+
var optionsSchema []byte
|
|
11
|
+
|
|
12
|
+
func descriptor() plugin.Descriptor {
|
|
13
|
+
return plugin.Descriptor{
|
|
14
|
+
Name: "fetch-bsr",
|
|
15
|
+
Summary: "Fetches pinned modules from a Buf Schema Registry into the tree, with a lock beside each, so the proto extractor can read a published contract.",
|
|
16
|
+
Phases: []string{plugin.PhaseExtract},
|
|
17
|
+
Options: optionsSchema,
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
// Deciding whether to fetch, and what to do when the fetch cannot happen.
|
|
4
|
+
//
|
|
5
|
+
// The rules below are the design, not error handling. The one that matters
|
|
6
|
+
// most is the third: a failed fetch with no cache is a NON-ZERO EXIT, never a
|
|
7
|
+
// short file list. The host deletes files a step stops naming, and dropping a
|
|
8
|
+
// repository's vendored protos because a laptop went offline is worse than a
|
|
9
|
+
// red build.
|
|
10
|
+
|
|
11
|
+
import (
|
|
12
|
+
"encoding/json"
|
|
13
|
+
"fmt"
|
|
14
|
+
"path"
|
|
15
|
+
"path/filepath"
|
|
16
|
+
"sort"
|
|
17
|
+
|
|
18
|
+
"github.com/shortlink-org/portolan/plugin"
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
func jsonUnmarshal(raw []byte, into any) error { return json.Unmarshal(raw, into) }
|
|
22
|
+
|
|
23
|
+
// fetch takes no plugin.Input: it reads nothing out of the tree being
|
|
24
|
+
// described. Its `cache` is repo-relative, like every other path in the
|
|
25
|
+
// manifest, and everything else it needs is in the options.
|
|
26
|
+
func fetch(opts Options) (plugin.Response, error) {
|
|
27
|
+
b := &plugin.Builder{}
|
|
28
|
+
|
|
29
|
+
if len(opts.Modules) == 0 {
|
|
30
|
+
return plugin.Response{}, fmt.Errorf("no modules to fetch: name at least one in the manifest")
|
|
31
|
+
}
|
|
32
|
+
if opts.Cache == "" {
|
|
33
|
+
return plugin.Response{}, fmt.Errorf(
|
|
34
|
+
"no cache directory: set `cache` to the same path as the step's `out`, " +
|
|
35
|
+
"so an offline run can replay what the last online one wrote")
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Sorted, so the file list and the diagnostics come out the same way every
|
|
39
|
+
// run whatever order the manifest happens to list them in.
|
|
40
|
+
wanted := append([]Module(nil), opts.Modules...)
|
|
41
|
+
sort.Slice(wanted, func(i, j int) bool { return wanted[i].Module < wanted[j].Module })
|
|
42
|
+
|
|
43
|
+
skip := offline()
|
|
44
|
+
|
|
45
|
+
for _, want := range wanted {
|
|
46
|
+
registry, owner, module, err := splitModule(want.Module)
|
|
47
|
+
if err != nil {
|
|
48
|
+
return plugin.Response{}, err
|
|
49
|
+
}
|
|
50
|
+
if opts.Registry != "" {
|
|
51
|
+
registry = opts.Registry
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Every module lives in its own directory with its own lock, so a
|
|
55
|
+
// vendored module is self-describing and extract-proto finds the lock
|
|
56
|
+
// by looking beside the files it is already reading.
|
|
57
|
+
dir := path.Join(owner, module)
|
|
58
|
+
at := filepath.Join(filepath.FromSlash(opts.Cache), filepath.FromSlash(dir))
|
|
59
|
+
|
|
60
|
+
if skip {
|
|
61
|
+
if err := emitCached(b, dir, at, want, "offline"); err != nil {
|
|
62
|
+
return plugin.Response{}, err
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
continue
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
commit, files, err := live(registry, owner, module, want, b)
|
|
69
|
+
if err != nil {
|
|
70
|
+
// Rule 2: the tree still holds a good copy, so the output is
|
|
71
|
+
// unchanged and `--check` stays clean.
|
|
72
|
+
if cacheErr := emitCached(b, dir, at, want, err.Error()); cacheErr != nil {
|
|
73
|
+
// Rule 3: nothing to fall back to.
|
|
74
|
+
return plugin.Response{}, fmt.Errorf(
|
|
75
|
+
"%s could not be fetched (%w) and there is no usable copy in the tree (%v)",
|
|
76
|
+
want.Module, err, cacheErr)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
continue
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if err := emitFetched(b, dir, want.Module, commit, files); err != nil {
|
|
83
|
+
return plugin.Response{}, err
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return b.Response(), nil
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// live fetches one module, pinning it first if the manifest did not.
|
|
91
|
+
func live(registry, owner, module string, want Module, b *plugin.Builder) (wireCommit, map[string][]byte, error) {
|
|
92
|
+
c := newClient(registry, token(registry))
|
|
93
|
+
|
|
94
|
+
ref := want.Commit
|
|
95
|
+
if ref == "" {
|
|
96
|
+
// Rule: pin, or every run is a lottery. Resolving a label still works,
|
|
97
|
+
// but it is said out loud, because two runs a day apart would then
|
|
98
|
+
// produce two different trees from one manifest.
|
|
99
|
+
ref = firstNonEmpty(want.Ref, "main")
|
|
100
|
+
resolved, err := c.resolve(owner, module, ref)
|
|
101
|
+
if err != nil {
|
|
102
|
+
return wireCommit{}, nil, err
|
|
103
|
+
}
|
|
104
|
+
b.Warn(want.Module, fmt.Sprintf(
|
|
105
|
+
"is not pinned; %q resolved to %s. Pin it in portolan.json or every run is a lottery.",
|
|
106
|
+
ref, resolved.ID))
|
|
107
|
+
ref = resolved.ID
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
commit, files, err := c.download(owner, module, ref, want.Paths)
|
|
111
|
+
if err != nil {
|
|
112
|
+
return wireCommit{}, nil, err
|
|
113
|
+
}
|
|
114
|
+
if len(files) == 0 {
|
|
115
|
+
return wireCommit{}, nil, fmt.Errorf("%s at %s holds no .proto files", want.Module, ref)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return commit, files, nil
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// emitFetched writes what came back, plus the lock that makes it checkable.
|
|
122
|
+
func emitFetched(b *plugin.Builder, dir, name string, commit wireCommit, files map[string][]byte) error {
|
|
123
|
+
entry := LockModule{Module: name, Commit: commit.ID, Digest: commit.display()}
|
|
124
|
+
|
|
125
|
+
paths := make([]string, 0, len(files))
|
|
126
|
+
for at := range files {
|
|
127
|
+
paths = append(paths, at)
|
|
128
|
+
}
|
|
129
|
+
sort.Strings(paths)
|
|
130
|
+
|
|
131
|
+
for _, at := range paths {
|
|
132
|
+
content := files[at]
|
|
133
|
+
b.File(path.Join(dir, at), string(content))
|
|
134
|
+
entry.Files = append(entry.Files, LockEntry{
|
|
135
|
+
Path: at,
|
|
136
|
+
SHA256: digestOf(content),
|
|
137
|
+
Size: len(content),
|
|
138
|
+
})
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
lock, err := Lock{Modules: []LockModule{entry}}.encode()
|
|
142
|
+
if err != nil {
|
|
143
|
+
return err
|
|
144
|
+
}
|
|
145
|
+
b.File(path.Join(dir, LockName), lock)
|
|
146
|
+
|
|
147
|
+
return nil
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// emitCached re-emits the committed copy unchanged.
|
|
151
|
+
//
|
|
152
|
+
// Byte-identical to what the last online run wrote, which is the whole point:
|
|
153
|
+
// `gen:check` sees no drift, so CI can verify an estate whose schemas live in a
|
|
154
|
+
// registry it never talks to.
|
|
155
|
+
func emitCached(b *plugin.Builder, dir, at string, want Module, why string) error {
|
|
156
|
+
if want.Commit == "" {
|
|
157
|
+
return fmt.Errorf("%s is not pinned to a commit, so there is nothing to replay", want.Module)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
held, err := replay(at)
|
|
161
|
+
if err != nil {
|
|
162
|
+
return err
|
|
163
|
+
}
|
|
164
|
+
if held.lock.Commit != want.Commit {
|
|
165
|
+
return fmt.Errorf("%s holds commit %s but the manifest pins %s; fetch it",
|
|
166
|
+
want.Module, held.lock.Commit, want.Commit)
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
for _, entry := range held.lock.Files {
|
|
170
|
+
b.File(path.Join(dir, entry.Path), string(held.files[entry.Path]))
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
lock, err := Lock{Modules: []LockModule{held.lock}}.encode()
|
|
174
|
+
if err != nil {
|
|
175
|
+
return err
|
|
176
|
+
}
|
|
177
|
+
b.File(path.Join(dir, LockName), lock)
|
|
178
|
+
|
|
179
|
+
b.Warn(want.Module, "not fetched ("+why+"); the copy committed in this repository is used unchanged")
|
|
180
|
+
|
|
181
|
+
return nil
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
func firstNonEmpty(values ...string) string {
|
|
185
|
+
for _, v := range values {
|
|
186
|
+
if v != "" {
|
|
187
|
+
return v
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return ""
|
|
192
|
+
}
|