From 55fce3dfd68963b54f6eaa74a229a3ca8d22c3af Mon Sep 17 00:00:00 2001 From: "devin-ai-integration[bot]" <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Fri, 6 Dec 2024 12:48:33 -0100 Subject: [PATCH 01/35] docs(sdk/python): improve PyPI example with better error handling and clarity (#9121) * docs(sdk/python): improve PyPI example with better error handling and clarity Fixes #9092 by updating the Python SDK README example to use the correct command execution pattern with .with_exec(["cowsay", *args]) instead of using .with_entrypoint() followed by .with_exec(). --------- Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- sdk/python/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sdk/python/README.md b/sdk/python/README.md index 951114a6d8..06b276c7a2 100644 --- a/sdk/python/README.md +++ b/sdk/python/README.md @@ -53,11 +53,10 @@ async def main(args: list[str]): dag.container() .from_("python:alpine") .with_exec(["pip", "install", "cowsay"]) - .with_entrypoint(["cowsay"]) ) # run cowsay with requested message - result = await ctr.with_exec(args).stdout() + result = await ctr.with_exec(["cowsay", *args]).stdout() print(result) From fdc7f3f04cf50a1484152372049b5b8a32c6391f Mon Sep 17 00:00:00 2001 From: Rajat Jindal Date: Fri, 6 Dec 2024 20:39:16 +0530 Subject: [PATCH 02/35] fix(engine): use default args for starting container as service (#8865) Signed-off-by: Rajat Jindal --- .../unreleased/Breaking-20241111-195013.yaml | 11 ++ .dagger/test.go | 6 - core/container.go | 44 ++++++- core/integration/cacert_test.go | 6 +- core/integration/client_test.go | 2 +- core/integration/container_test.go | 71 +++++++++++ core/integration/engine_test.go | 40 +++--- core/integration/future_test.go | 4 +- core/integration/git_test.go | 2 +- core/integration/legacy_test.go | 116 ++++++++++++++++++ core/integration/localcache_test.go | 4 +- core/integration/module_test.go | 2 +- core/integration/module_up_test.go | 2 +- core/integration/provision_test.go | 18 +-- core/integration/proxy_test.go | 6 +- core/integration/remotecache_test.go | 17 +-- core/integration/services_test.go | 65 +++++----- core/integration/testdata/nested-c2c/main.go | 4 +- core/schema/container.go | 2 +- core/schema/service.go | 52 +++++++- core/terminal.go | 7 +- .../services/bind-services/go/main.go | 2 +- .../expose-dagger-services-to-host/go/main.go | 2 +- .../features/snippets/services-1/go/main.go | 2 +- docs/docs-graphql/schema.graphqls | 45 ++++++- docs/static/api/reference/index.html | 40 +++++- sdk/elixir/lib/dagger/gen/container.ex | 23 +++- sdk/go/dagger.gen.go | 50 +++++++- sdk/php/generated/Container.php | 28 ++++- sdk/python/src/dagger/client/gen.py | 53 +++++++- sdk/rust/crates/dagger-sdk/src/gen.rs | 67 +++++++++- sdk/typescript/api/client.gen.ts | 55 ++++++++- 32 files changed, 732 insertions(+), 116 deletions(-) create mode 100644 .changes/unreleased/Breaking-20241111-195013.yaml diff --git a/.changes/unreleased/Breaking-20241111-195013.yaml b/.changes/unreleased/Breaking-20241111-195013.yaml new file mode 100644 index 0000000000..14d7bbad9d --- /dev/null +++ b/.changes/unreleased/Breaking-20241111-195013.yaml @@ -0,0 +1,11 @@ +kind: Breaking +body: |- + AsService now runs "DefaultCmd" by default instead of last "Exec" command. + + User can override the args by providing "ContainerAsServiceOpts.Args" option. They can also configure the container to use Entrypoint by using "ContainerAsServiceOpts.UseEntrypoint" option. + + See sdk documentation for additional options. +time: 2024-12-06T08:20:21.242739+05:30 +custom: + Author: rajatjindal + PR: "8865" diff --git a/.dagger/test.go b/.dagger/test.go index f8424f5ba9..6adc9f330a 100644 --- a/.dagger/test.go +++ b/.dagger/test.go @@ -358,9 +358,6 @@ func registry() *dagger.Service { return dag.Container(). From("registry:2"). WithExposedPort(5000, dagger.ContainerWithExposedPortOpts{Protocol: dagger.NetworkProtocolTcp}). - WithExec(nil, dagger.ContainerWithExecOpts{ - UseEntrypoint: true, - }). AsService() } @@ -373,8 +370,5 @@ func privateRegistry() *dagger.Service { WithEnvVariable("REGISTRY_AUTH_HTPASSWD_REALM", "Registry Realm"). WithEnvVariable("REGISTRY_AUTH_HTPASSWD_PATH", "/auth/htpasswd"). WithExposedPort(5000, dagger.ContainerWithExposedPortOpts{Protocol: dagger.NetworkProtocolTcp}). - WithExec(nil, dagger.ContainerWithExecOpts{ - UseEntrypoint: true, - }). AsService() } diff --git a/core/container.go b/core/container.go index 8d0681be10..38d2142c45 100644 --- a/core/container.go +++ b/core/container.go @@ -1675,7 +1675,28 @@ func (container *Container) ImageRefOrErr(ctx context.Context) (string, error) { return "", errors.Errorf("Image reference can only be retrieved immediately after the 'Container.From' call. Error in fetching imageRef as the container image is changed") } -func (container *Container) AsService(ctx context.Context) (*Service, error) { +type ContainerAsServiceArgs struct { + // Command to run instead of the container's default command + Args []string `default:"[]"` + + // If the container has an entrypoint, prepend it to this exec's args + UseEntrypoint bool `default:"false"` + + // Provide the executed command access back to the Dagger API + ExperimentalPrivilegedNesting bool `default:"false"` + + // Grant the process all root capabilities + InsecureRootCapabilities bool `default:"false"` + + // Expand the environment variables in args + Expand bool `default:"false"` + + // Skip the init process injected into containers by default so that the + // user's process is PID 1 + NoInit bool `default:"false"` +} + +func (container *Container) AsServiceLegacy(ctx context.Context) (*Service, error) { if container.Meta == nil { var err error container, err = container.WithExec(ctx, ContainerExecOpts{ @@ -1688,6 +1709,27 @@ func (container *Container) AsService(ctx context.Context) (*Service, error) { return container.Query.NewContainerService(ctx, container), nil } +func (container *Container) AsService(ctx context.Context, args ContainerAsServiceArgs) (*Service, error) { + var cmdargs = container.Config.Cmd + if len(args.Args) > 0 { + cmdargs = args.Args + } + + container, err := container.WithExec(ctx, ContainerExecOpts{ + Args: cmdargs, + UseEntrypoint: args.UseEntrypoint, + ExperimentalPrivilegedNesting: args.ExperimentalPrivilegedNesting, + InsecureRootCapabilities: args.InsecureRootCapabilities, + Expand: args.Expand, + NoInit: args.NoInit, + }) + if err != nil { + return nil, err + } + + return container.Query.NewContainerService(ctx, container), nil +} + func (container *Container) ownership(ctx context.Context, owner string) (*Ownership, error) { if owner == "" { // do not change ownership diff --git a/core/integration/cacert_test.go b/core/integration/cacert_test.go index de44ff309a..d79664ed08 100644 --- a/core/integration/cacert_test.go +++ b/core/integration/cacert_test.go @@ -546,9 +546,9 @@ func customCACertTests( WithMountedFile("/usr/local/share/ca-certificates/dagger-test-custom-ca.crt", certGen.caRootCert). WithServiceBinding("server", serverCtr.AsService()) }) - engineSvc, err := c.Host().Tunnel(devEngine.AsService()).Start(ctx) + engineSvc, err := c.Host().Tunnel(devEngineContainerAsService(devEngine)).Start(ctx) require.NoError(t, err) - t.Cleanup(func() { engineSvc.Stop(ctx) }) + t.Cleanup(func() { _, _ = engineSvc.Stop(ctx) }) endpoint, err := engineSvc.Endpoint(ctx, dagger.ServiceEndpointOpts{Scheme: "tcp"}) require.NoError(t, err) c2, err := dagger.Connect(ctx, dagger.WithRunnerHost(endpoint), dagger.WithLogOutput(testutil.NewTWriter(t))) @@ -756,5 +756,5 @@ ssl_dhparam /etc/ssl/certs/dhparam.pem; WithExec([]string{"nginx", "-t"}). WithExposedPort(80). WithExposedPort(443). - WithExec([]string{"nginx", "-g", "daemon off;"}) + WithDefaultArgs([]string{"nginx", "-g", "daemon off;"}) } diff --git a/core/integration/client_test.go b/core/integration/client_test.go index bb7b814ba4..8356f7b1d7 100644 --- a/core/integration/client_test.go +++ b/core/integration/client_test.go @@ -128,7 +128,7 @@ func (ClientSuite) TestMultiSameTrace(ctx context.Context, t *testctx.T) { func (ClientSuite) TestClientStableID(ctx context.Context, t *testctx.T) { c := connect(ctx, t) devEngine := devEngineContainer(c) - clientCtr := engineClientContainer(ctx, t, c, devEngine.AsService()) + clientCtr := engineClientContainer(ctx, t, c, devEngineContainerAsService(devEngine)) // just run any dagger cli command that connects to the engine stableID, err := clientCtr. diff --git a/core/integration/container_test.go b/core/integration/container_test.go index 17af5daa95..c0714357b0 100644 --- a/core/integration/container_test.go +++ b/core/integration/container_test.go @@ -4781,3 +4781,74 @@ func (ContainerSuite) TestExecInit(ctx context.Context, t *testctx.T) { require.Contains(t, out, "1 ps") }) } + +func (ContainerSuite) TestContainerAsService(ctx context.Context, t *testctx.T) { + c := connect(ctx, t) + maingo := `package main + +import ( + "fmt" + "net/http" + "os" + "strings" +) + +func main() { + http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, "args: %s", strings.Join(os.Args, ",")) + }) + + fmt.Println(http.ListenAndServe(":8080", nil)) +}` + buildctr := c.Container(). + From(golangImage). + WithWorkdir("/work"). + WithNewFile("/work/main.go", maingo). + WithExec([]string{"go", "build", "-o=app", "main.go"}) + + binctr := c.Container(). + From(alpineImage). + WithFile("/bin/app", buildctr.File("/work/app")). + WithEntrypoint([]string{"/bin/app", "via-entrypoint"}). + WithDefaultArgs([]string{"/bin/app", "via-default-args"}). + WithExposedPort(8080) + + curlctr := c.Container(). + From(alpineImage). + WithExec([]string{"sh", "-c", "apk add curl"}) + + t.Run("use default args by default", func(ctx context.Context, t *testctx.T) { + output, err := curlctr. + WithServiceBinding("myapp", binctr.AsService()). + WithExec([]string{"sh", "-c", "curl -vXGET 'http://myapp:8080/hello'"}). + Stdout(ctx) + require.NoError(t, err) + require.Equal(t, "args: /bin/app,via-default-args", output) + }) + + t.Run("can override default args", func(ctx context.Context, t *testctx.T) { + withargsOverwritten := binctr. + AsService(dagger.ContainerAsServiceOpts{Args: []string{"sh", "-c", "/bin/app via-service-override"}}) + + output, err := curlctr. + WithServiceBinding("myapp", withargsOverwritten). + WithExec([]string{"sh", "-c", "curl -vXGET 'http://myapp:8080/hello'"}). + Stdout(ctx) + require.NoError(t, err) + require.Equal(t, "args: /bin/app,via-service-override", output) + }) + + t.Run("can enable entrypoint", func(ctx context.Context, t *testctx.T) { + withargsOverwritten := binctr. + AsService(dagger.ContainerAsServiceOpts{ + UseEntrypoint: true, + }) + + output, err := curlctr. + WithServiceBinding("myapp", withargsOverwritten). + WithExec([]string{"sh", "-c", "curl -vXGET 'http://myapp:8080/hello'"}). + Stdout(ctx) + require.NoError(t, err) + require.Equal(t, "args: /bin/app,via-entrypoint,/bin/app,via-default-args", output) + }) +} diff --git a/core/integration/engine_test.go b/core/integration/engine_test.go index 27cb380055..b416651dfb 100644 --- a/core/integration/engine_test.go +++ b/core/integration/engine_test.go @@ -31,6 +31,13 @@ func TestEngine(t *testing.T) { testctx.Run(testCtx, t, EngineSuite{}, Middleware()...) } +func devEngineContainerAsService(ctr *dagger.Container) *dagger.Service { + return ctr.AsService(dagger.ContainerAsServiceOpts{ + UseEntrypoint: true, + InsecureRootCapabilities: true, + }) +} + // devEngineContainer returns a nested dev engine. func devEngineContainer(c *dagger.Client, withs ...func(*dagger.Container) *dagger.Container) *dagger.Container { // This loads the engine.tar file from the host into the container, that @@ -53,15 +60,12 @@ func devEngineContainer(c *dagger.Client, withs ...func(*dagger.Container) *dagg return ctr. WithMountedCache("/var/lib/dagger", c.CacheVolume("dagger-dev-engine-state-"+identity.NewID())). WithExposedPort(1234, dagger.ContainerWithExposedPortOpts{Protocol: dagger.NetworkProtocolTcp}). - WithExec([]string{ + WithDefaultArgs([]string{ "--addr", "tcp://0.0.0.0:1234", "--addr", "unix:///var/run/buildkit/buildkitd.sock", // avoid network conflicts with other tests "--network-name", deviceName, "--network-cidr", cidr, - }, dagger.ContainerWithExecOpts{ - UseEntrypoint: true, - InsecureRootCapabilities: true, }) } @@ -185,7 +189,7 @@ func (ClientSuite) TestWaitsForEngine(ctx context.Context, t *testctx.T) { WithEntrypoint([]string{"/usr/local/bin/slow-entrypoint.sh"}) }) - clientCtr := engineClientContainer(ctx, t, c, devEngine.AsService()) + clientCtr := engineClientContainer(ctx, t, c, devEngineContainerAsService(devEngine)) _, err := clientCtr. WithNewFile("/query.graphql", `{ version }`). // arbitrary valid query WithExec([]string{"dagger", "query", "--doc", "/query.graphql"}).Sync(ctx) @@ -198,11 +202,11 @@ func (EngineSuite) TestSetsNameFromEnv(ctx context.Context, t *testctx.T) { engineName := "my-special-engine" engineVersion := engine.Version + "-special" - devEngineSvc := devEngineContainer(c, func(c *dagger.Container) *dagger.Container { + devEngineSvc := devEngineContainerAsService(devEngineContainer(c, func(c *dagger.Container) *dagger.Container { return c. WithEnvVariable("_EXPERIMENTAL_DAGGER_ENGINE_NAME", engineName). WithEnvVariable("_EXPERIMENTAL_DAGGER_VERSION", engineVersion) - }).AsService() + })) clientCtr := engineClientContainer(ctx, t, c, devEngineSvc) @@ -223,14 +227,16 @@ func (EngineSuite) TestSetsNameFromEnv(ctx context.Context, t *testctx.T) { func (EngineSuite) TestDaggerRun(ctx context.Context, t *testctx.T) { c := connect(ctx, t) - devEngine := devEngineContainer(c).AsService() + devEngine := devEngineContainerAsService(devEngineContainer(c)) + clientCtr := engineClientContainer(ctx, t, c, devEngine) - runCommand := fmt.Sprintf(` + command := fmt.Sprintf(` export NO_COLOR=1 jq -n '{query:"{container{from(address: \"%s\"){file(path: \"/etc/alpine-release\"){contents}}}}"}' | \ dagger run sh -c 'curl -s \ -u $DAGGER_SESSION_TOKEN: \ + --max-time 30 \ -H "content-type:application/json" \ -d @- \ http://127.0.0.1:$DAGGER_SESSION_PORT/query'`, @@ -239,7 +245,7 @@ func (EngineSuite) TestDaggerRun(ctx context.Context, t *testctx.T) { clientCtr = clientCtr. WithExec([]string{"apk", "add", "jq", "curl"}). - WithExec([]string{"sh", "-c", runCommand}) + WithExec([]string{"sh", "-c", command}) stdout, err := clientCtr.Stdout(ctx) require.NoError(t, err) @@ -255,7 +261,7 @@ func (EngineSuite) TestDaggerRun(ctx context.Context, t *testctx.T) { func (ClientSuite) TestSendsLabelsInTelemetry(ctx context.Context, t *testctx.T) { c := connect(ctx, t) - devEngine := devEngineContainer(c).AsService() + devEngine := devEngineContainerAsService(devEngineContainer(c)) thisRepoPath, err := filepath.Abs("../..") require.NoError(t, err) @@ -280,7 +286,7 @@ func (ClientSuite) TestSendsLabelsInTelemetry(ctx context.Context, t *testctx.T) fakeCloud := withCode. WithMountedCache("/events", eventsVol). - WithExec([]string{ + WithDefaultArgs([]string{ "go", "run", "./core/integration/testdata/telemetry/", }). WithExposedPort(8080). @@ -468,11 +474,12 @@ func (EngineSuite) TestVersionCompat(ctx context.Context, t *testctx.T) { enginesMu.Lock() devEngineSvc, ok := engines[devEngineSvcKey] if !ok { - devEngineSvc = devEngineContainer(c, func(c *dagger.Container) *dagger.Container { + devEngine := devEngineContainer(c, func(c *dagger.Container) *dagger.Container { return c. WithEnvVariable("_EXPERIMENTAL_DAGGER_VERSION", tc.engineVersion). WithEnvVariable("_EXPERIMENTAL_DAGGER_MIN_VERSION", tc.clientMinVersion) - }).AsService() + }) + devEngineSvc = devEngineContainerAsService(devEngine) engines[devEngineSvcKey] = devEngineSvc } enginesMu.Unlock() @@ -580,11 +587,12 @@ func (EngineSuite) TestModuleVersionCompat(ctx context.Context, t *testctx.T) { enginesMu.Lock() devEngineSvc, ok := engines[devEngineSvcKey] if !ok { - devEngineSvc = devEngineContainer(c, func(c *dagger.Container) *dagger.Container { + devEngine := devEngineContainer(c, func(c *dagger.Container) *dagger.Container { return c. WithEnvVariable("_EXPERIMENTAL_DAGGER_VERSION", tc.engineVersion). WithEnvVariable("_EXPERIMENTAL_DAGGER_MIN_VERSION", tc.moduleMinVersion) - }).AsService() + }) + devEngineSvc = devEngineContainerAsService(devEngine) engines[devEngineSvcKey] = devEngineSvc } enginesMu.Unlock() diff --git a/core/integration/future_test.go b/core/integration/future_test.go index e0c06e6f45..d802c2ec33 100644 --- a/core/integration/future_test.go +++ b/core/integration/future_test.go @@ -25,8 +25,8 @@ func futureClient(ctx context.Context, t *testctx.T, futureVersion string) *dagg devEngine := devEngineContainer(c, func(c *dagger.Container) *dagger.Container { return c.WithEnvVariable("_EXPERIMENTAL_DAGGER_VERSION", futureVersion) - }).AsService() - devClient := engineClientContainer(ctx, t, c, devEngine) + }) + devClient := engineClientContainer(ctx, t, c, devEngineContainerAsService(devEngine)) devClient = devClient.WithEnvVariable("_EXPERIMENTAL_DAGGER_VERSION", futureVersion) return devClient. diff --git a/core/integration/git_test.go b/core/integration/git_test.go index 2482b7d1bf..f20b5df21a 100644 --- a/core/integration/git_test.go +++ b/core/integration/git_test.go @@ -254,7 +254,7 @@ sleep infinity sshSvc := hostKeyGen. WithMountedFile("/root/start.sh", setupScript). WithExposedPort(sshPort). - WithExec([]string{"sh", "/root/start.sh"}). + WithDefaultArgs([]string{"sh", "/root/start.sh"}). AsService() sshHost, err := sshSvc.Hostname(ctx) diff --git a/core/integration/legacy_test.go b/core/integration/legacy_test.go index 39ad385960..728300e236 100644 --- a/core/integration/legacy_test.go +++ b/core/integration/legacy_test.go @@ -756,3 +756,119 @@ func (LegacySuite) TestContainerWithFocus(ctx context.Context, t *testctx.T) { }) require.NoError(t, err) } + +func (LegacySuite) TestContainerAsService(ctx context.Context, t *testctx.T) { + // Changed in dagger/dagger#8865 + // + // Ensure that the legacy AsService api uses entrypoint by default + // and use WithExec if that is configured + + c := connect(ctx, t) + + serversource := `package main + +import ( + "fmt" + "net/http" + "os" + "strings" +) + +func main() { + http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, "args: %s", strings.Join(os.Args, ",")) + }) + + fmt.Println(http.ListenAndServe(":8080", nil)) +}` + + daggermodmaingo := `package main + +import ( + "context" + "dagger/foo/internal/dagger" +) + +type Foo struct{} + +func (f *Foo) TestServiceUpEntrypoint(ctx context.Context, app *dagger.File) (string, error) { + svc, err := f.StartEntrypointByDefault(ctx, app) + if err != nil { + return "", err + } + + return dag.Container(). + From("alpine:3.20.2"). + WithExec([]string{"sh", "-c", "apk add curl"}). + WithServiceBinding("myapp", svc). + WithExec([]string{"sh", "-c", "curl -vXGET 'http://myapp:8080/hello'"}). + Stdout(ctx) +} + +func (f *Foo) StartEntrypointByDefault(ctx context.Context, app *dagger.File) (*dagger.Service, error) { + return dag.Container(). + From("alpine:3.20.2"). + WithFile("/bin/app", app). + WithEntrypoint([]string{"/bin/app", "via-entrypoint"}). + WithDefaultArgs([]string{"/bin/app", "via-default-args"}). + WithExposedPort(8080). + AsService(), nil +} + +func (f *Foo) TestServiceUpWithExec(ctx context.Context, app *dagger.File) (string, error) { + svc, err := f.UseWithExecWhenAvailable(ctx, app) + if err != nil { + return "", err + } + + return dag.Container(). + From("alpine:3.20.2"). + WithExec([]string{"sh", "-c", "apk add curl"}). + WithServiceBinding("myapp", svc). + WithExec([]string{"sh", "-c", "curl -vXGET 'http://myapp:8080/hello'"}). + Stdout(ctx) +} + +func (f *Foo) UseWithExecWhenAvailable(ctx context.Context, app *dagger.File) (*dagger.Service, error) { + return dag.Container(). + From("alpine:3.20.2"). + WithFile("/bin/app", app). + WithEntrypoint([]string{"/bin/app", "via-entrypoint"}). + WithDefaultArgs([]string{"/bin/app", "via-default-args"}). + WithExec([]string{"/bin/app", "via-withExec"}). + WithExposedPort(8080). + AsService(), nil +} +` + + app := c.Container(). + From(golangImage). + WithWorkdir("/work"). + WithNewFile("main.go", serversource). + WithExec([]string{"go", "build", "-o=app", "main.go"}). + File("/work/app") + + ctr := daggerCliBase(t, c). + WithWorkdir("/work/"). + WithFile("app", app). + WithNewFile("main.go", daggermodmaingo). + WithNewFile("dagger.json", `{"name": "foo", "sdk": "go", "source": ".", "engineVersion": "v0.13.7"}`) + + // verify that the engine uses the entrypoint when serving the legacy AsService api + t.Run("use entrypoint by default", func(ctx context.Context, t *testctx.T) { + output, err := ctr. + With(daggerExec("call", "test-service-up-entrypoint", "--app=app")). + Stdout(ctx) + require.NoError(t, err) + require.Equal(t, "args: /bin/app,via-entrypoint,/bin/app,via-default-args", output) + }) + + // verify that the engine uses the entrypoint when serving the legacy AsService api + t.Run("use withExec when used", func(ctx context.Context, t *testctx.T) { + output, err := ctr. + With(daggerExec("call", "test-service-up-with-exec", "--app=app")). + Stdout(ctx) + require.NoError(t, err) + require.Equal(t, "args: /bin/app,via-withExec", output) + }) +} diff --git a/core/integration/localcache_test.go b/core/integration/localcache_test.go index b362941cfb..28c7ce6e98 100644 --- a/core/integration/localcache_test.go +++ b/core/integration/localcache_test.go @@ -51,7 +51,7 @@ func (EngineSuite) TestLocalCacheGCKeepBytesConfig(ctx context.Context, t *testc }, } { f := func(ctx context.Context, t *testctx.T, engine *dagger.Container) { - engineSvc, err := c.Host().Tunnel(engine.AsService()).Start(ctx) + engineSvc, err := c.Host().Tunnel(devEngineContainerAsService(engine)).Start(ctx) require.NoError(t, err) t.Cleanup(func() { engineSvc.Stop(ctx) }) @@ -148,7 +148,7 @@ func (EngineSuite) TestLocalCacheAutomaticGC(ctx context.Context, t *testctx.T) }, } { f := func(ctx context.Context, t *testctx.T, engine *dagger.Container) { - engineSvc, err := c.Host().Tunnel(engine.AsService()).Start(ctx) + engineSvc, err := c.Host().Tunnel(devEngineContainerAsService(engine)).Start(ctx) require.NoError(t, err) t.Cleanup(func() { engineSvc.Stop(ctx) }) diff --git a/core/integration/module_test.go b/core/integration/module_test.go index f9bfc629b2..f62ef4e23a 100644 --- a/core/integration/module_test.go +++ b/core/integration/module_test.go @@ -3621,7 +3621,7 @@ func (ModuleSuite) TestStartServices(ctx context.Context, t *testctx.T) { ). WithWorkdir("/srv/www"). WithExposedPort(23457). - WithExec([]string{"python", "-m", "http.server", "23457"}). + WithDefaultArgs([]string{"python", "-m", "http.server", "23457"}). AsService() ctr := dag.Container(). diff --git a/core/integration/module_up_test.go b/core/integration/module_up_test.go index 8ce2d24acc..efc190a255 100644 --- a/core/integration/module_up_test.go +++ b/core/integration/module_up_test.go @@ -191,7 +191,7 @@ func daggerUpInitModFn(ctx context.Context, t *testctx.T, defaultPort string) st ). WithWorkdir("/srv/www"). WithExposedPort(port). - WithExec([]string{"python", "-m", "http.server", strconv.Itoa(port)}), + WithDefaultArgs([]string{"python", "-m", "http.server", strconv.Itoa(port)}), } } diff --git a/core/integration/provision_test.go b/core/integration/provision_test.go index 43f9720c6f..6dd7111c8d 100644 --- a/core/integration/provision_test.go +++ b/core/integration/provision_test.go @@ -120,14 +120,16 @@ func dockerService(t *testctx.T, dag *dagger.Client, dockerVersion string, f fun Sharing: dagger.CacheSharingModePrivate, }). WithExposedPort(port). - WithExec([]string{ - "dockerd", - "--host=tcp://0.0.0.0:" + strconv.Itoa(port), - "--tls=false", - }, dagger.ContainerWithExecOpts{ - InsecureRootCapabilities: true, - }). - AsService() + AsService( + dagger.ContainerAsServiceOpts{ + Args: []string{ + "dockerd", + "--host=tcp://0.0.0.0:" + strconv.Itoa(port), + "--tls=false", + }, + InsecureRootCapabilities: true, + }, + ) return dockerd } diff --git a/core/integration/proxy_test.go b/core/integration/proxy_test.go index 04d19052ab..821f622d44 100644 --- a/core/integration/proxy_test.go +++ b/core/integration/proxy_test.go @@ -175,7 +175,7 @@ http_access allow localhost WithNewFile("/etc/squid/squid.conf", squidConf). WithServiceBinding(httpServerAlias, httpServer.AsService()). WithServiceBinding(noproxyHTTPServerAlias, noproxyHTTPServer.AsService()). - WithExec([]string{"sh", "-c", "chmod -R a+rw /var/log/squidaccess && exec squid --foreground"}). + WithDefaultArgs([]string{"sh", "-c", "chmod -R a+rw /var/log/squidaccess && exec squid --foreground"}). AsService() if os.Getenv(executeTestEnvName) == "" { @@ -208,7 +208,7 @@ http_access allow localhost WithMountedDirectory("/src", thisRepo). WithWorkdir("/src"). WithMountedFile("/ca.pem", certGen.caRootCert). - WithServiceBinding("engine", devEngine.AsService()). + WithServiceBinding("engine", devEngineContainerAsService(devEngine)). WithMountedFile("/bin/dagger", daggerCliFile(t, c)). WithEnvVariable("_EXPERIMENTAL_DAGGER_CLI_BIN", "/bin/dagger"). WithEnvVariable("_EXPERIMENTAL_DAGGER_RUNNER_HOST", "tcp://engine:1234"). @@ -458,7 +458,7 @@ func (ContainerSuite) TestSystemGoProxy(ctx context.Context, t *testctx.T) { With(goCache(c)). WithMountedDirectory("/src", thisRepo). WithWorkdir("/src"). - WithServiceBinding("engine", devEngine.AsService()). + WithServiceBinding("engine", devEngineContainerAsService(devEngine)). WithMountedFile("/bin/dagger", daggerCliFile(t, c)). WithEnvVariable("_EXPERIMENTAL_DAGGER_CLI_BIN", "/bin/dagger"). WithEnvVariable("_EXPERIMENTAL_DAGGER_RUNNER_HOST", "tcp://engine:1234"). diff --git a/core/integration/remotecache_test.go b/core/integration/remotecache_test.go index a9dbcf53bb..94dbc99a11 100644 --- a/core/integration/remotecache_test.go +++ b/core/integration/remotecache_test.go @@ -17,10 +17,11 @@ import ( const cliBinPath = "/.dagger-cli" func getDevEngineForRemoteCache(ctx context.Context, c *dagger.Client, cache *dagger.Service, cacheName string) (devEngineSvc *dagger.Service, endpoint string, err error) { - devEngineSvc = devEngineContainer(c, func(c *dagger.Container) *dagger.Container { + devEngine := devEngineContainer(c, func(c *dagger.Container) *dagger.Container { return c.WithServiceBinding(cacheName, cache) - }).AsService() + }) + devEngineSvc = devEngineContainerAsService(devEngine) endpoint, err = devEngineSvc.Endpoint(ctx, dagger.ServiceEndpointOpts{ Port: 1234, Scheme: "tcp", @@ -41,7 +42,7 @@ func (RemoteCacheSuite) TestRegistry(ctx context.Context, t *testctx.T) { registry := c.Container().From("registry:2"). WithMountedCache("/var/lib/registry/", c.CacheVolume("remote-cache-registry-"+identity.NewID())). WithExposedPort(5000, dagger.ContainerWithExposedPortOpts{Protocol: dagger.NetworkProtocolTcp}). - AsService() + AsService(dagger.ContainerAsServiceOpts{UseEntrypoint: true}) cacheEnv := "type=registry,ref=registry:5000/test-cache,mode=max" @@ -118,7 +119,7 @@ func (RemoteCacheSuite) TestLazyBlobs(ctx context.Context, t *testctx.T) { registry := c.Container().From("registry:2"). WithMountedCache("/var/lib/registry/", c.CacheVolume("remote-cache-registry-"+identity.NewID())). WithExposedPort(5000, dagger.ContainerWithExposedPortOpts{Protocol: dagger.NetworkProtocolTcp}). - AsService() + AsService(dagger.ContainerAsServiceOpts{UseEntrypoint: true}) cacheEnv := "type=registry,ref=registry:5000/test-cache,mode=max" @@ -180,7 +181,7 @@ func (RemoteCacheSuite) TestS3(ctx context.Context, t *testctx.T) { s3 := c.Container().From("minio/minio"). WithMountedCache("/data", c.CacheVolume("minio-cache")). WithExposedPort(9000, dagger.ContainerWithExposedPortOpts{Protocol: dagger.NetworkProtocolTcp}). - WithExec([]string{"minio", "server", "/data"}). + WithDefaultArgs([]string{"minio", "server", "/data"}). AsService() s3Endpoint, err := s3.Endpoint(ctx, dagger.ServiceEndpointOpts{Port: 9000, Scheme: "http"}) @@ -260,7 +261,7 @@ func (RemoteCacheSuite) TestRegistryMultipleConfigs(ctx context.Context, t *test registry := c.Container().From("registry:2"). WithMountedCache("/var/lib/registry/", c.CacheVolume("remote-cache-registry-"+identity.NewID())). WithExposedPort(5000, dagger.ContainerWithExposedPortOpts{Protocol: dagger.NetworkProtocolTcp}). - AsService() + AsService(dagger.ContainerAsServiceOpts{UseEntrypoint: true}) cacheConfigEnv1 := "type=registry,ref=registry:5000/test-cache:latest,mode=max" cacheConfigEnv2 := "type=registry,ref=registry:5000/test-cache-b:latest,mode=max" @@ -358,7 +359,7 @@ func (RemoteCacheSuite) TestRegistrySeparateImportExport(ctx context.Context, t registry := c.Container().From("registry:2"). WithMountedCache("/var/lib/registry/", c.CacheVolume("remote-cache-registry-"+identity.NewID())). WithExposedPort(5000, dagger.ContainerWithExposedPortOpts{Protocol: dagger.NetworkProtocolTcp}). - AsService() + AsService(dagger.ContainerAsServiceOpts{UseEntrypoint: true}) daggerCli := daggerCliFile(t, c) @@ -486,7 +487,7 @@ func (RemoteCacheSuite) TestRegistryFastCacheBlobSource(ctx context.Context, t * registry := c.Container().From("registry:2"). WithMountedCache("/var/lib/registry/", c.CacheVolume("remote-cache-registry-"+identity.NewID())). WithExposedPort(5000, dagger.ContainerWithExposedPortOpts{Protocol: dagger.NetworkProtocolTcp}). - AsService() + AsService(dagger.ContainerAsServiceOpts{UseEntrypoint: true}) cacheConfig := "type=registry,ref=registry:5000/test-cache:latest,mode=max" diff --git a/core/integration/services_test.go b/core/integration/services_test.go index 509f062e7b..532171d3c2 100644 --- a/core/integration/services_test.go +++ b/core/integration/services_test.go @@ -64,7 +64,7 @@ func (ServiceSuite) TestHostnamesAreStable(ctx context.Context, t *testctx.T) { WithEnvVariable("FOO", "123"). WithEnvVariable("BAR", "456"). WithExposedPort(8000). - WithExec([]string{"python", "-m", "http.server"}). + WithDefaultArgs([]string{"python", "-m", "http.server"}). AsService() hostname, err := srv.Hostname(ctx) @@ -79,13 +79,13 @@ func (ServiceSuite) TestHostnamesAreStable(ctx context.Context, t *testctx.T) { srv1 := c.Container(). From("python"). WithExposedPort(8000). - WithExec([]string{"python", "-m", "http.server"}). + WithDefaultArgs([]string{"python", "-m", "http.server"}). AsService() srv2 := c.Container(). From("python"). WithExposedPort(8001). - WithExec([]string{"python", "-m", "http.server", "8081"}). + WithDefaultArgs([]string{"python", "-m", "http.server", "8081"}). AsService() hn1, err := srv1.Hostname(ctx) @@ -126,7 +126,7 @@ func (ServiceSuite) TestHostnameEndpoint(ctx context.Context, t *testctx.T) { srv := c.Container(). From("python"). WithExposedPort(8000). - WithExec([]string{"python", "-m", "http.server"}). + WithDefaultArgs([]string{"python", "-m", "http.server"}). AsService() hn, err := srv.Hostname(ctx) @@ -141,7 +141,7 @@ func (ServiceSuite) TestHostnameEndpoint(ctx context.Context, t *testctx.T) { t.Run("endpoint can specify arbitrary port", func(ctx context.Context, t *testctx.T) { srv := c.Container(). From("python"). - WithExec([]string{"python", "-m", "http.server"}). + WithDefaultArgs([]string{"python", "-m", "http.server"}). AsService() hn, err := srv.Hostname(ctx) @@ -158,7 +158,7 @@ func (ServiceSuite) TestHostnameEndpoint(ctx context.Context, t *testctx.T) { t.Run("endpoint with no port errors if no exposed port", func(ctx context.Context, t *testctx.T) { srv := c.Container(). From("python"). - WithExec([]string{"python", "-m", "http.server"}). + WithDefaultArgs([]string{"python", "-m", "http.server"}). AsService() _, err := srv.Endpoint(ctx) @@ -173,7 +173,7 @@ func (ServiceSuite) TestWithHostname(ctx context.Context, t *testctx.T) { From(busyboxImage). WithWorkdir("/srv"). WithNewFile("index.html", "Hello, world!"). - WithExec([]string{"httpd", "-v", "-f"}). + WithDefaultArgs([]string{"httpd", "-v", "-f"}). WithExposedPort(80). AsService(). WithHostname("wwwhatsup") @@ -223,7 +223,7 @@ func (m *Hoster) Run(ctx context.Context) error { From("`+busyboxImage+`"). WithWorkdir("/srv"). WithNewFile("index.html", "I am the one who hosts."). - WithExec([]string{"httpd", "-v", "-f"}). + WithDefaultArgs([]string{"httpd", "-v", "-f"}). WithExposedPort(80). AsService() @@ -319,7 +319,7 @@ func (m *Hoster) Run(ctx context.Context) error { From("`+golangImage+`"). WithWorkdir("/srv"). WithNewFile("main.go", counterMain). - WithExec([]string{"go", "run", "main.go"}). + WithDefaultArgs([]string{"go", "run", "main.go"}). WithExposedPort(80). AsService() @@ -397,7 +397,7 @@ func (m *Hoster) Run(ctx context.Context) error { From("`+busyboxImage+`"). WithWorkdir("/srv"). WithNewFile("index.html", "I am the one who hosts."). - WithExec([]string{"httpd", "-v", "-f"}). + WithDefaultArgs([]string{"httpd", "-v", "-f"}). WithExposedPort(80). AsService(). WithHostname("wwwhatsup0") @@ -458,7 +458,7 @@ func (m *Caller) Run(ctx context.Context) error { From("`+busyboxImage+`"). WithWorkdir("/srv"). WithNewFile("index.html", "I am within the called module."). - WithExec([]string{"httpd", "-v", "-f"}). + WithDefaultArgs([]string{"httpd", "-v", "-f"}). WithExposedPort(80). AsService(). WithHostname("wwwhatsup1") @@ -501,7 +501,7 @@ func (m *Hoster) Run(ctx context.Context) error { From("`+busyboxImage+`"). WithWorkdir("/srv"). WithNewFile("index.html", "I am the one who hosts."). - WithExec([]string{"httpd", "-v", "-f"}). + WithDefaultArgs([]string{"httpd", "-v", "-f"}). WithExposedPort(80). AsService(). WithHostname("wwwhatsup1") @@ -567,7 +567,7 @@ func (m *Relayer) Service() *dagger.Service { From("`+golangImage+`"). WithWorkdir("/srv"). WithNewFile("main.go", relayMain). - WithExec([]string{"go", "run", "main.go"}). + WithDefaultArgs([]string{"go", "run", "main.go"}). WithExposedPort(80). AsService() } @@ -655,7 +655,7 @@ func (ServiceSuite) TestPorts(ctx context.Context, t *testctx.T) { Description: "nine thousand", Protocol: dagger.NetworkProtocolUdp, }). - WithExec([]string{"python", "-m", "http.server"}). + WithDefaultArgs([]string{"python", "-m", "http.server"}). AsService() portCfgs, err := srv.Ports(ctx) @@ -696,7 +696,7 @@ func (ServiceSuite) TestPortsSkipHealthCheck(ctx context.Context, t *testctx.T) WithExposedPort(6215, dagger.ContainerWithExposedPortOpts{ ExperimentalSkipHealthcheck: true, }). - WithExec([]string{"python", "-m", "http.server"}). + WithDefaultArgs([]string{"python", "-m", "http.server"}). AsService() _, err := srv.Start(ctx) @@ -715,7 +715,7 @@ func (ServiceSuite) TestPortsSkipHealthCheck(ctx context.Context, t *testctx.T) WithExposedPort(6215, dagger.ContainerWithExposedPortOpts{ ExperimentalSkipHealthcheck: true, }). - WithExec([]string{"python", "-m", "http.server", "8000"}). + WithDefaultArgs([]string{"python", "-m", "http.server", "8000"}). AsService() _, err := srv.Start(ctx) @@ -931,7 +931,7 @@ func (ContainerSuite) TestExecServicesError(ctx context.Context, t *testctx.T) { srv := c.Container(). From(alpineImage). WithExposedPort(8080). - WithExec([]string{"sh", "-c", "echo nope; exit 42"}). + WithDefaultArgs([]string{"sh", "-c", "echo nope; exit 42"}). AsService() host, err := srv.Hostname(ctx) @@ -986,7 +986,7 @@ func (ContainerSuite) TestExecUDPServices(ctx context.Context, t *testctx.T) { // use TCP :4322 for health-check to avoid test flakiness, since UDP dial // health-checks aren't really a thing WithExposedPort(4322). - WithExec([]string{"go", "run", "/src/main.go"}). + WithDefaultArgs([]string{"go", "run", "/src/main.go"}). AsService() client := c.Container(). @@ -1039,7 +1039,7 @@ func (ContainerSuite) TestExecServicesDeduping(ctx context.Context, t *testctx.T WithMountedFile("/src/main.go", c.Directory().WithNewFile("main.go", pipeSrc).File("main.go")). WithExposedPort(8080). - WithExec([]string{"go", "run", "/src/main.go"}). + WithDefaultArgs([]string{"go", "run", "/src/main.go"}). AsService() client := c.Container(). @@ -1087,7 +1087,7 @@ func (ContainerSuite) TestExecServicesChained(ctx context.Context, t *testctx.T) WithExec([]string{"sh", "-c", "echo $0 >> /srv/www/index.html", strconv.Itoa(i)}). WithWorkdir("/srv/www"). WithExposedPort(8000). - WithExec([]string{"python", "-m", "http.server"}). + WithDefaultArgs([]string{"python", "-m", "http.server"}). AsService() } @@ -1761,7 +1761,7 @@ func (ServiceSuite) TestHostToContainer(ctx context.Context, t *testctx.T) { ). WithWorkdir("/srv/www"). WithExposedPort(8000). - WithExec([]string{"python", "-m", "http.server"}). + WithDefaultArgs([]string{"python", "-m", "http.server"}). AsService() tunnel, err := c.Host().Tunnel(srv).Start(ctx) @@ -1794,7 +1794,7 @@ func (ServiceSuite) TestHostToContainer(ctx context.Context, t *testctx.T) { c.Directory().WithNewFile("index.html", content+"-1")). WithMountedDirectory("/srv/www2", c.Directory().WithNewFile("index.html", content+"-2")). - WithExec([]string{ + WithDefaultArgs([]string{ "sh", "-c", `( cd /srv/www1 && python -m http.server 8000 ) & ( cd /srv/www2 && python -m http.server 9000 ) & @@ -1840,7 +1840,7 @@ func (ServiceSuite) TestHostToContainer(ctx context.Context, t *testctx.T) { c.Directory().WithNewFile("index.html", content+"-1")). WithMountedDirectory("/srv/www2", c.Directory().WithNewFile("index.html", content+"-2")). - WithExec([]string{ + WithDefaultArgs([]string{ "sh", "-c", `( cd /srv/www1 && python -m http.server 32767 ) & ( cd /srv/www2 && python -m http.server 32766 ) & @@ -1890,7 +1890,7 @@ func (ServiceSuite) TestHostToContainer(ctx context.Context, t *testctx.T) { c.Directory().WithNewFile("index.html", content+"-1")). WithMountedDirectory("/srv/www2", c.Directory().WithNewFile("index.html", content+"-2")). - WithExec([]string{ + WithDefaultArgs([]string{ "sh", "-c", `( cd /srv/www1 && python -m http.server 32765 ) & ( cd /srv/www2 && python -m http.server 32764 ) & @@ -1944,7 +1944,7 @@ func (ServiceSuite) TestHostToContainer(ctx context.Context, t *testctx.T) { ). WithWorkdir("/srv/www"). // WithExposedPort(8000). // INTENTIONAL - WithExec([]string{"python", "-m", "http.server"}). + WithDefaultArgs([]string{"python", "-m", "http.server"}). AsService() _, err := c.Host().Tunnel(srv).ID(ctx) @@ -2087,12 +2087,13 @@ func (ServiceSuite) TestSearchDomainAlwaysSet(ctx context.Context, t *testctx.T) devEngine := devEngineContainer(c, func(ctr *dagger.Container) *dagger.Container { return ctr.WithMountedFile("/etc/resolv.conf", newResolvConf) - }).AsService() + }) + devEngineSvc := devEngineContainerAsService(devEngine) t.Cleanup(func() { - devEngine.Stop(ctx, dagger.ServiceStopOpts{Kill: true}) + devEngineSvc.Stop(ctx, dagger.ServiceStopOpts{Kill: true}) }) - hostSvc, err := c.Host().Tunnel(devEngine, dagger.HostTunnelOpts{ + hostSvc, err := c.Host().Tunnel(devEngineSvc, dagger.HostTunnelOpts{ Ports: []dagger.PortForward{{ Backend: 1234, Frontend: 32132, @@ -2134,7 +2135,7 @@ func httpService(ctx context.Context, t *testctx.T, c *dagger.Client, content st ). WithWorkdir("/srv/www"). WithExposedPort(8000). - WithExec([]string{"python", "-m", "http.server"}). + WithDefaultArgs([]string{"python", "-m", "http.server"}). AsService() httpURL, err := srv.Endpoint(ctx, dagger.ServiceEndpointOpts{ @@ -2159,7 +2160,7 @@ func gitServiceWithBranch(ctx context.Context, t *testctx.T, c *dagger.Client, c WithExec([]string{"apk", "add", "git", "git-daemon"}). WithDirectory("/root/srv", makeGitDir(c, content, branchName)). WithExposedPort(gitPort). - WithExec([]string{"sh", "-c", "git daemon --verbose --export-all --base-path=/root/srv"}). + WithDefaultArgs([]string{"sh", "-c", "git daemon --verbose --export-all --base-path=/root/srv"}). AsService() gitHost, err := gitDaemon.Hostname(ctx) @@ -2214,7 +2215,7 @@ server { Owner: "nginx", }). WithExposedPort(80). - AsService() + AsService(dagger.ContainerAsServiceOpts{UseEntrypoint: true}) gitHost, err := gitDaemon.Hostname(ctx) require.NoError(t, err) @@ -2286,7 +2287,7 @@ with socketserver.TCPServer(("", 8000), http.server.SimpleHTTPRequestHandler) as WithWorkdir("/srv/www"). WithNewFile("signals.txt", ""). WithExposedPort(8000). - WithExec([]string{"python", "/signals.py"}). + WithDefaultArgs([]string{"python", "/signals.py"}). AsService() httpURL, err := srv.Endpoint(ctx, dagger.ServiceEndpointOpts{ diff --git a/core/integration/testdata/nested-c2c/main.go b/core/integration/testdata/nested-c2c/main.go index 4a033dcb1a..f281f4e788 100644 --- a/core/integration/testdata/nested-c2c/main.go +++ b/core/integration/testdata/nested-c2c/main.go @@ -155,7 +155,7 @@ func httpService(ctx context.Context, c *dagger.Client, dir *dagger.Directory) ( WithMountedDirectory("/srv/www", dir). WithWorkdir("/srv/www"). WithExposedPort(8000). - WithExec([]string{"python", "-m", "http.server"}). + WithDefaultArgs([]string{"python", "-m", "http.server"}). AsService() httpURL, err := srv.Endpoint(ctx, dagger.ServiceEndpointOpts{ @@ -202,7 +202,7 @@ git daemon --verbose --export-all --base-path=/root/srv `). File("start.sh")). WithExposedPort(gitPort). - WithExec([]string{"sh", "/root/start.sh"}). + WithDefaultArgs([]string{"sh", "/root/start.sh"}). AsService() gitHost, err := gitDaemon.Hostname(ctx) diff --git a/core/schema/container.go b/core/schema/container.go index ce5bf6159d..8c9218b672 100644 --- a/core/schema/container.go +++ b/core/schema/container.go @@ -376,7 +376,7 @@ func (s *containerSchema) Install() { View(AllVersion). Doc(`Retrieves this container after executing the specified command inside it.`). ArgDoc("args", - `Command to run instead of the container's default command (e.g., ["run", "main.go"]).`, + `Command to run instead of the container's default command (e.g., ["go", "run", "main.go"]).`, `If empty, the container's default command is used.`). ArgDoc("useEntrypoint", `If the container has an entrypoint, prepend it to the args.`). diff --git a/core/schema/service.go b/core/schema/service.go index 2afae4ba4e..228deba07e 100644 --- a/core/schema/service.go +++ b/core/schema/service.go @@ -18,9 +18,40 @@ var _ SchemaResolvers = &serviceSchema{} func (s *serviceSchema) Install() { dagql.Fields[*core.Container]{ - dagql.Func("asService", s.containerAsService). + dagql.Func("asService", s.containerAsServiceLegacy). + View(BeforeVersion("v0.15.0")). Doc(`Turn the container into a Service.`, `Be sure to set any exposed ports before this conversion.`), + + dagql.Func("asService", s.containerAsService). + View(AfterVersion("v0.15.0")). + Doc(`Turn the container into a Service.`, + `Be sure to set any exposed ports before this conversion.`). + ArgDoc("args", + `Command to run instead of the container's default command (e.g., ["go", "run", "main.go"]).`, + `If empty, the container's default command is used.`). + ArgDoc("useEntrypoint", + `If the container has an entrypoint, prepend it to the args.`). + ArgDoc("experimentalPrivilegedNesting", + `Provides Dagger access to the executed command.`, + `Do not use this option unless you trust the command being executed; + the command being executed WILL BE GRANTED FULL ACCESS TO YOUR HOST + FILESYSTEM.`). + ArgDoc("insecureRootCapabilities", + `Execute the command with all root capabilities. This is similar to + running a command with "sudo" or executing "docker run" with the + "--privileged" flag. Containerization does not provide any security + guarantees when using this option. It should only be used when + absolutely necessary and only with trusted commands.`). + ArgDoc("expand", + `Replace "${VAR}" or "$VAR" in the args according to the current `+ + `environment variables defined in the container (e.g. "/$VAR/foo").`). + ArgDoc("noInit", + `If set, skip the automatic init process injected into containers by default.`, + `This should only be used if the user requires that their exec process be the + pid 1 process in the container. Otherwise it may result in unexpected behavior.`, + ), + dagql.NodeFunc("up", s.containerUp). Doc(`Starts a Service and creates a tunnel that forwards traffic from the caller's network to that service.`, `Be sure to set any exposed ports before calling this api.`). @@ -68,8 +99,23 @@ func (s *serviceSchema) Install() { }.Install(s.srv) } -func (s *serviceSchema) containerAsService(ctx context.Context, parent *core.Container, args struct{}) (*core.Service, error) { - return parent.AsService(ctx) +func (s *serviceSchema) containerAsServiceLegacy(ctx context.Context, parent *core.Container, args struct{}) (*core.Service, error) { + return parent.AsServiceLegacy(ctx) +} + +func (s *serviceSchema) containerAsService(ctx context.Context, parent *core.Container, args core.ContainerAsServiceArgs) (*core.Service, error) { + expandedArgs := make([]string, len(args.Args)) + for i, arg := range args.Args { + expandedArg, err := expandEnvVar(ctx, parent, arg, args.Expand) + if err != nil { + return nil, err + } + + expandedArgs[i] = expandedArg + } + args.Args = expandedArgs + + return parent.AsService(ctx, args) } func (s *serviceSchema) containerUp(ctx context.Context, ctr dagql.Instance[*core.Container], args upArgs) (dagql.Nullable[core.Void], error) { diff --git a/core/terminal.go b/core/terminal.go index e883684614..e1d13defe4 100644 --- a/core/terminal.go +++ b/core/terminal.go @@ -68,15 +68,12 @@ func (container *Container) Terminal( output.String("dagger").Foreground(termenv.ANSIYellow).String(), output.String(`$(pwd | sed "s|^$HOME|~|")`).Faint().String(), )) - container, err = container.WithExec(ctx, ContainerExecOpts{ + + svc, err := container.AsService(ctx, ContainerAsServiceArgs{ Args: args.Cmd, ExperimentalPrivilegedNesting: args.ExperimentalPrivilegedNesting.Value.Bool(), InsecureRootCapabilities: args.InsecureRootCapabilities.Value.Bool(), }) - if err != nil { - return fmt.Errorf("failed to create container for interactive terminal: %w", err) - } - svc, err := container.AsService(ctx) if err != nil { return fmt.Errorf("failed to create service for interactive terminal: %w", err) } diff --git a/docs/current_docs/api/snippets/services/bind-services/go/main.go b/docs/current_docs/api/snippets/services/bind-services/go/main.go index d3f50f020c..7996d88e8f 100644 --- a/docs/current_docs/api/snippets/services/bind-services/go/main.go +++ b/docs/current_docs/api/snippets/services/bind-services/go/main.go @@ -13,7 +13,7 @@ func (m *MyModule) HttpService() *dagger.Service { From("python"). WithWorkdir("/srv"). WithNewFile("index.html", "Hello, world!"). - WithExec([]string{"python", "-m", "http.server", "8080"}). + WithDefaultArgs([]string{"python", "-m", "http.server", "8080"}). WithExposedPort(8080). AsService() } diff --git a/docs/current_docs/api/snippets/services/expose-dagger-services-to-host/go/main.go b/docs/current_docs/api/snippets/services/expose-dagger-services-to-host/go/main.go index 0f68a95712..d0c554098f 100644 --- a/docs/current_docs/api/snippets/services/expose-dagger-services-to-host/go/main.go +++ b/docs/current_docs/api/snippets/services/expose-dagger-services-to-host/go/main.go @@ -10,7 +10,7 @@ func (m *MyModule) HttpService() *dagger.Service { From("python"). WithWorkdir("/srv"). WithNewFile("index.html", "Hello, world!"). - WithExec([]string{"python", "-m", "http.server", "8080"}). + WithDefaultArgs([]string{"python", "-m", "http.server", "8080"}). WithExposedPort(8080). AsService() } diff --git a/docs/current_docs/features/snippets/services-1/go/main.go b/docs/current_docs/features/snippets/services-1/go/main.go index 345aa97ee6..cc2b63d01a 100644 --- a/docs/current_docs/features/snippets/services-1/go/main.go +++ b/docs/current_docs/features/snippets/services-1/go/main.go @@ -13,7 +13,7 @@ func (m *MyModule) HttpService() *dagger.Service { From("python"). WithWorkdir("/srv"). WithNewFile("index.html", "Hello, world!"). - WithExec([]string{"python", "-m", "http.server", "8080"}). + WithDefaultArgs([]string{"python", "-m", "http.server", "8080"}). WithExposedPort(8080). AsService() } diff --git a/docs/docs-graphql/schema.graphqls b/docs/docs-graphql/schema.graphqls index c1710a395d..6b3af23211 100644 --- a/docs/docs-graphql/schema.graphqls +++ b/docs/docs-graphql/schema.graphqls @@ -60,7 +60,48 @@ type Container { Be sure to set any exposed ports before this conversion. """ - asService: Service! + asService( + """ + Command to run instead of the container's default command (e.g., ["go", "run", "main.go"]). + + If empty, the container's default command is used. + """ + args: [String!] = [] + + """ + Replace "${VAR}" or "$VAR" in the args according to the current environment + variables defined in the container (e.g. "/$VAR/foo"). + """ + expand: Boolean = false + + """ + Provides Dagger access to the executed command. + + Do not use this option unless you trust the command being executed; the + command being executed WILL BE GRANTED FULL ACCESS TO YOUR HOST FILESYSTEM. + """ + experimentalPrivilegedNesting: Boolean = false + + """ + Execute the command with all root capabilities. This is similar to running a + command with "sudo" or executing "docker run" with the "--privileged" flag. + Containerization does not provide any security guarantees when using this + option. It should only be used when absolutely necessary and only with + trusted commands. + """ + insecureRootCapabilities: Boolean = false + + """ + If set, skip the automatic init process injected into containers by default. + + This should only be used if the user requires that their exec process be the + pid 1 process in the container. Otherwise it may result in unexpected behavior. + """ + noInit: Boolean = false + + """If the container has an entrypoint, prepend it to the args.""" + useEntrypoint: Boolean = false + ): Service! """Returns a File representing the container serialized to a tarball.""" asTarball( @@ -505,7 +546,7 @@ type Container { """ withExec( """ - Command to run instead of the container's default command (e.g., ["run", "main.go"]). + Command to run instead of the container's default command (e.g., ["go", "run", "main.go"]). If empty, the container's default command is used. """ diff --git a/docs/static/api/reference/index.html b/docs/static/api/reference/index.html index af5c168605..fe3be842e3 100644 --- a/docs/static/api/reference/index.html +++ b/docs/static/api/reference/index.html @@ -3806,13 +3806,49 @@
Fields
- + asService - Service!

Turn the container into a Service.

Be sure to set any exposed ports before this conversion.

+ + +
+
Arguments
+
+
+
args - [String!]
+

Command to run instead of the container's default command (e.g., ["go", "run", "main.go"]).

+

If empty, the container's default command is used.

+
+
+
expand - Boolean
+

Replace "${VAR}" or "$VAR" in the args according to the current environment variables defined in the container (e.g. "/$VAR/foo").

+
+
+
experimentalPrivilegedNesting - Boolean
+

Provides Dagger access to the executed command.

+

Do not use this option unless you trust the command being executed; the command being executed WILL BE GRANTED FULL ACCESS TO YOUR HOST FILESYSTEM.

+
+
+
insecureRootCapabilities - Boolean
+

Execute the command with all root capabilities. This is similar to running a command with "sudo" or executing "docker run" with the "--privileged" flag. Containerization does not provide any security guarantees when using this option. It should only be used when absolutely necessary and only with trusted commands.

+
+
+
noInit - Boolean
+

If set, skip the automatic init process injected into containers by default.

+

This should only be used if the user requires that their exec process be the pid 1 process in the container. Otherwise it may result in unexpected behavior.

+
+
+
useEntrypoint - Boolean
+

If the container has an entrypoint, prepend it to the args.

+
+
+
+ + asTarball - File! Returns a File representing the container serialized to a tarball. @@ -4389,7 +4425,7 @@
Arguments
args - [String!]!
-

Command to run instead of the container's default command (e.g., ["run", "main.go"]).

+

Command to run instead of the container's default command (e.g., ["go", "run", "main.go"]).

If empty, the container's default command is used.

diff --git a/sdk/elixir/lib/dagger/gen/container.ex b/sdk/elixir/lib/dagger/gen/container.ex index 84896a3632..13916e305d 100644 --- a/sdk/elixir/lib/dagger/gen/container.ex +++ b/sdk/elixir/lib/dagger/gen/container.ex @@ -16,10 +16,27 @@ defmodule Dagger.Container do Be sure to set any exposed ports before this conversion. """ - @spec as_service(t()) :: Dagger.Service.t() - def as_service(%__MODULE__{} = container) do + @spec as_service(t(), [ + {:args, [String.t()]}, + {:use_entrypoint, boolean() | nil}, + {:experimental_privileged_nesting, boolean() | nil}, + {:insecure_root_capabilities, boolean() | nil}, + {:expand, boolean() | nil}, + {:no_init, boolean() | nil} + ]) :: Dagger.Service.t() + def as_service(%__MODULE__{} = container, optional_args \\ []) do query_builder = - container.query_builder |> QB.select("asService") + container.query_builder + |> QB.select("asService") + |> QB.maybe_put_arg("args", optional_args[:args]) + |> QB.maybe_put_arg("useEntrypoint", optional_args[:use_entrypoint]) + |> QB.maybe_put_arg( + "experimentalPrivilegedNesting", + optional_args[:experimental_privileged_nesting] + ) + |> QB.maybe_put_arg("insecureRootCapabilities", optional_args[:insecure_root_capabilities]) + |> QB.maybe_put_arg("expand", optional_args[:expand]) + |> QB.maybe_put_arg("noInit", optional_args[:no_init]) %Dagger.Service{ query_builder: query_builder, diff --git a/sdk/go/dagger.gen.go b/sdk/go/dagger.gen.go index 8100ee1d90..545016e943 100644 --- a/sdk/go/dagger.gen.go +++ b/sdk/go/dagger.gen.go @@ -352,11 +352,59 @@ func (r *Container) WithGraphQLQuery(q *querybuilder.Selection) *Container { } } +// ContainerAsServiceOpts contains options for Container.AsService +type ContainerAsServiceOpts struct { + // Command to run instead of the container's default command (e.g., ["go", "run", "main.go"]). + // + // If empty, the container's default command is used. + Args []string + // If the container has an entrypoint, prepend it to the args. + UseEntrypoint bool + // Provides Dagger access to the executed command. + // + // Do not use this option unless you trust the command being executed; the command being executed WILL BE GRANTED FULL ACCESS TO YOUR HOST FILESYSTEM. + ExperimentalPrivilegedNesting bool + // Execute the command with all root capabilities. This is similar to running a command with "sudo" or executing "docker run" with the "--privileged" flag. Containerization does not provide any security guarantees when using this option. It should only be used when absolutely necessary and only with trusted commands. + InsecureRootCapabilities bool + // Replace "${VAR}" or "$VAR" in the args according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + Expand bool + // If set, skip the automatic init process injected into containers by default. + // + // This should only be used if the user requires that their exec process be the pid 1 process in the container. Otherwise it may result in unexpected behavior. + NoInit bool +} + // Turn the container into a Service. // // Be sure to set any exposed ports before this conversion. -func (r *Container) AsService() *Service { +func (r *Container) AsService(opts ...ContainerAsServiceOpts) *Service { q := r.query.Select("asService") + for i := len(opts) - 1; i >= 0; i-- { + // `args` optional argument + if !querybuilder.IsZeroValue(opts[i].Args) { + q = q.Arg("args", opts[i].Args) + } + // `useEntrypoint` optional argument + if !querybuilder.IsZeroValue(opts[i].UseEntrypoint) { + q = q.Arg("useEntrypoint", opts[i].UseEntrypoint) + } + // `experimentalPrivilegedNesting` optional argument + if !querybuilder.IsZeroValue(opts[i].ExperimentalPrivilegedNesting) { + q = q.Arg("experimentalPrivilegedNesting", opts[i].ExperimentalPrivilegedNesting) + } + // `insecureRootCapabilities` optional argument + if !querybuilder.IsZeroValue(opts[i].InsecureRootCapabilities) { + q = q.Arg("insecureRootCapabilities", opts[i].InsecureRootCapabilities) + } + // `expand` optional argument + if !querybuilder.IsZeroValue(opts[i].Expand) { + q = q.Arg("expand", opts[i].Expand) + } + // `noInit` optional argument + if !querybuilder.IsZeroValue(opts[i].NoInit) { + q = q.Arg("noInit", opts[i].NoInit) + } + } return &Service{ query: q, diff --git a/sdk/php/generated/Container.php b/sdk/php/generated/Container.php index 7f00b18d4a..fd61412f86 100644 --- a/sdk/php/generated/Container.php +++ b/sdk/php/generated/Container.php @@ -18,9 +18,33 @@ class Container extends Client\AbstractObject implements Client\IdAble * * Be sure to set any exposed ports before this conversion. */ - public function asService(): Service - { + public function asService( + ?array $args = null, + ?bool $useEntrypoint = false, + ?bool $experimentalPrivilegedNesting = false, + ?bool $insecureRootCapabilities = false, + ?bool $expand = false, + ?bool $noInit = false, + ): Service { $innerQueryBuilder = new \Dagger\Client\QueryBuilder('asService'); + if (null !== $args) { + $innerQueryBuilder->setArgument('args', $args); + } + if (null !== $useEntrypoint) { + $innerQueryBuilder->setArgument('useEntrypoint', $useEntrypoint); + } + if (null !== $experimentalPrivilegedNesting) { + $innerQueryBuilder->setArgument('experimentalPrivilegedNesting', $experimentalPrivilegedNesting); + } + if (null !== $insecureRootCapabilities) { + $innerQueryBuilder->setArgument('insecureRootCapabilities', $insecureRootCapabilities); + } + if (null !== $expand) { + $innerQueryBuilder->setArgument('expand', $expand); + } + if (null !== $noInit) { + $innerQueryBuilder->setArgument('noInit', $noInit); + } return new \Dagger\Service($this->client, $this->queryBuilderChain->chain($innerQueryBuilder)); } diff --git a/sdk/python/src/dagger/client/gen.py b/sdk/python/src/dagger/client/gen.py index dd0eda0dcf..5560097785 100644 --- a/sdk/python/src/dagger/client/gen.py +++ b/sdk/python/src/dagger/client/gen.py @@ -414,12 +414,59 @@ async def id(self) -> CacheVolumeID: class Container(Type): """An OCI-compatible container, also known as a Docker container.""" - def as_service(self) -> "Service": + def as_service( + self, + *, + args: list[str] | None = None, + use_entrypoint: bool | None = False, + experimental_privileged_nesting: bool | None = False, + insecure_root_capabilities: bool | None = False, + expand: bool | None = False, + no_init: bool | None = False, + ) -> "Service": """Turn the container into a Service. Be sure to set any exposed ports before this conversion. + + Parameters + ---------- + args: + Command to run instead of the container's default command (e.g., + ["go", "run", "main.go"]). + If empty, the container's default command is used. + use_entrypoint: + If the container has an entrypoint, prepend it to the args. + experimental_privileged_nesting: + Provides Dagger access to the executed command. + Do not use this option unless you trust the command being + executed; the command being executed WILL BE GRANTED FULL ACCESS + TO YOUR HOST FILESYSTEM. + insecure_root_capabilities: + Execute the command with all root capabilities. This is similar to + running a command with "sudo" or executing "docker run" with the " + --privileged" flag. Containerization does not provide any security + guarantees when using this option. It should only be used when + absolutely necessary and only with trusted commands. + expand: + Replace "${VAR}" or "$VAR" in the args according to the current + environment variables defined in the container (e.g. "/$VAR/foo"). + no_init: + If set, skip the automatic init process injected into containers + by default. + This should only be used if the user requires that their exec + process be the pid 1 process in the container. Otherwise it may + result in unexpected behavior. """ - _args: list[Arg] = [] + _args = [ + Arg("args", () if args is None else args, ()), + Arg("useEntrypoint", use_entrypoint, False), + Arg( + "experimentalPrivilegedNesting", experimental_privileged_nesting, False + ), + Arg("insecureRootCapabilities", insecure_root_capabilities, False), + Arg("expand", expand, False), + Arg("noInit", no_init, False), + ] _ctx = self._select("asService", _args) return Service(_ctx) @@ -1392,7 +1439,7 @@ def with_exec( ---------- args: Command to run instead of the container's default command (e.g., - ["run", "main.go"]). + ["go", "run", "main.go"]). If empty, the container's default command is used. use_entrypoint: If the container has an entrypoint, prepend it to the args. diff --git a/sdk/rust/crates/dagger-sdk/src/gen.rs b/sdk/rust/crates/dagger-sdk/src/gen.rs index 2dbf230322..c15ec29384 100644 --- a/sdk/rust/crates/dagger-sdk/src/gen.rs +++ b/sdk/rust/crates/dagger-sdk/src/gen.rs @@ -1503,6 +1503,30 @@ pub struct Container { pub graphql_client: DynGraphQLClient, } #[derive(Builder, Debug, PartialEq)] +pub struct ContainerAsServiceOpts<'a> { + /// Command to run instead of the container's default command (e.g., ["go", "run", "main.go"]). + /// If empty, the container's default command is used. + #[builder(setter(into, strip_option), default)] + pub args: Option>, + /// Replace "${VAR}" or "$VAR" in the args according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + #[builder(setter(into, strip_option), default)] + pub expand: Option, + /// Provides Dagger access to the executed command. + /// Do not use this option unless you trust the command being executed; the command being executed WILL BE GRANTED FULL ACCESS TO YOUR HOST FILESYSTEM. + #[builder(setter(into, strip_option), default)] + pub experimental_privileged_nesting: Option, + /// Execute the command with all root capabilities. This is similar to running a command with "sudo" or executing "docker run" with the "--privileged" flag. Containerization does not provide any security guarantees when using this option. It should only be used when absolutely necessary and only with trusted commands. + #[builder(setter(into, strip_option), default)] + pub insecure_root_capabilities: Option, + /// If set, skip the automatic init process injected into containers by default. + /// This should only be used if the user requires that their exec process be the pid 1 process in the container. Otherwise it may result in unexpected behavior. + #[builder(setter(into, strip_option), default)] + pub no_init: Option, + /// If the container has an entrypoint, prepend it to the args. + #[builder(setter(into, strip_option), default)] + pub use_entrypoint: Option, +} +#[derive(Builder, Debug, PartialEq)] pub struct ContainerAsTarballOpts { /// Force each layer of the image to use the specified compression algorithm. /// If this is unset, then if a layer already has a compressed blob in the engine's cache, that will be used (this can result in a mix of compression algorithms for different layers). If this is unset and a layer has no compressed blob in the engine's cache, then it will be compressed using Gzip. @@ -1859,6 +1883,10 @@ pub struct ContainerWithoutUnixSocketOpts { impl Container { /// Turn the container into a Service. /// Be sure to set any exposed ports before this conversion. + /// + /// # Arguments + /// + /// * `opt` - optional argument, see inner type for documentation, use _opts to use pub fn as_service(&self) -> Service { let query = self.selection.select("asService"); Service { @@ -1867,6 +1895,41 @@ impl Container { graphql_client: self.graphql_client.clone(), } } + /// Turn the container into a Service. + /// Be sure to set any exposed ports before this conversion. + /// + /// # Arguments + /// + /// * `opt` - optional argument, see inner type for documentation, use _opts to use + pub fn as_service_opts<'a>(&self, opts: ContainerAsServiceOpts<'a>) -> Service { + let mut query = self.selection.select("asService"); + if let Some(args) = opts.args { + query = query.arg("args", args); + } + if let Some(use_entrypoint) = opts.use_entrypoint { + query = query.arg("useEntrypoint", use_entrypoint); + } + if let Some(experimental_privileged_nesting) = opts.experimental_privileged_nesting { + query = query.arg( + "experimentalPrivilegedNesting", + experimental_privileged_nesting, + ); + } + if let Some(insecure_root_capabilities) = opts.insecure_root_capabilities { + query = query.arg("insecureRootCapabilities", insecure_root_capabilities); + } + if let Some(expand) = opts.expand { + query = query.arg("expand", expand); + } + if let Some(no_init) = opts.no_init { + query = query.arg("noInit", no_init); + } + Service { + proc: self.proc.clone(), + selection: query, + graphql_client: self.graphql_client.clone(), + } + } /// Returns a File representing the container serialized to a tarball. /// /// # Arguments @@ -2641,7 +2704,7 @@ impl Container { /// /// # Arguments /// - /// * `args` - Command to run instead of the container's default command (e.g., ["run", "main.go"]). + /// * `args` - Command to run instead of the container's default command (e.g., ["go", "run", "main.go"]). /// /// If empty, the container's default command is used. /// * `opt` - optional argument, see inner type for documentation, use _opts to use @@ -2661,7 +2724,7 @@ impl Container { /// /// # Arguments /// - /// * `args` - Command to run instead of the container's default command (e.g., ["run", "main.go"]). + /// * `args` - Command to run instead of the container's default command (e.g., ["go", "run", "main.go"]). /// /// If empty, the container's default command is used. /// * `opt` - optional argument, see inner type for documentation, use _opts to use diff --git a/sdk/typescript/api/client.gen.ts b/sdk/typescript/api/client.gen.ts index 21a6d661a4..3945149d8e 100644 --- a/sdk/typescript/api/client.gen.ts +++ b/sdk/typescript/api/client.gen.ts @@ -83,6 +83,44 @@ export enum CacheSharingMode { */ export type CacheVolumeID = string & { __CacheVolumeID: never } +export type ContainerAsServiceOpts = { + /** + * Command to run instead of the container's default command (e.g., ["go", "run", "main.go"]). + * + * If empty, the container's default command is used. + */ + args?: string[] + + /** + * If the container has an entrypoint, prepend it to the args. + */ + useEntrypoint?: boolean + + /** + * Provides Dagger access to the executed command. + * + * Do not use this option unless you trust the command being executed; the command being executed WILL BE GRANTED FULL ACCESS TO YOUR HOST FILESYSTEM. + */ + experimentalPrivilegedNesting?: boolean + + /** + * Execute the command with all root capabilities. This is similar to running a command with "sudo" or executing "docker run" with the "--privileged" flag. Containerization does not provide any security guarantees when using this option. It should only be used when absolutely necessary and only with trusted commands. + */ + insecureRootCapabilities?: boolean + + /** + * Replace "${VAR}" or "$VAR" in the args according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + */ + expand?: boolean + + /** + * If set, skip the automatic init process injected into containers by default. + * + * This should only be used if the user requires that their exec process be the pid 1 process in the container. Otherwise it may result in unexpected behavior. + */ + noInit?: boolean +} + export type ContainerAsTarballOpts = { /** * Identifiers for other platform specific containers. @@ -1500,13 +1538,26 @@ export class Container extends BaseClient { * Turn the container into a Service. * * Be sure to set any exposed ports before this conversion. + * @param opts.args Command to run instead of the container's default command (e.g., ["go", "run", "main.go"]). + * + * If empty, the container's default command is used. + * @param opts.useEntrypoint If the container has an entrypoint, prepend it to the args. + * @param opts.experimentalPrivilegedNesting Provides Dagger access to the executed command. + * + * Do not use this option unless you trust the command being executed; the command being executed WILL BE GRANTED FULL ACCESS TO YOUR HOST FILESYSTEM. + * @param opts.insecureRootCapabilities Execute the command with all root capabilities. This is similar to running a command with "sudo" or executing "docker run" with the "--privileged" flag. Containerization does not provide any security guarantees when using this option. It should only be used when absolutely necessary and only with trusted commands. + * @param opts.expand Replace "${VAR}" or "$VAR" in the args according to the current environment variables defined in the container (e.g. "/$VAR/foo"). + * @param opts.noInit If set, skip the automatic init process injected into containers by default. + * + * This should only be used if the user requires that their exec process be the pid 1 process in the container. Otherwise it may result in unexpected behavior. */ - asService = (): Service => { + asService = (opts?: ContainerAsServiceOpts): Service => { return new Service({ queryTree: [ ...this._queryTree, { operation: "asService", + args: { ...opts }, }, ], ctx: this._ctx, @@ -2345,7 +2396,7 @@ export class Container extends BaseClient { /** * Retrieves this container after executing the specified command inside it. - * @param args Command to run instead of the container's default command (e.g., ["run", "main.go"]). + * @param args Command to run instead of the container's default command (e.g., ["go", "run", "main.go"]). * * If empty, the container's default command is used. * @param opts.useEntrypoint If the container has an entrypoint, prepend it to the args. From b34a84e4fe1797d5acaec3977ca3fb04add2592a Mon Sep 17 00:00:00 2001 From: "devin-ai-integration[bot]" <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Sat, 7 Dec 2024 04:18:57 +0000 Subject: [PATCH 03/35] feat: add DAGGER_LEAVE_OLD_ENGINE to prevent old engine cleanup This change adds a new environment variable DAGGER_LEAVE_OLD_ENGINE that prevents cleanup of old engine containers when set to any value except '0' or empty string. - Adds shouldLeaveOldEngine() function to control engine cleanup behavior - Modifies cleanup logic in Docker driver to respect the environment variable - Removes redundant cleanup check in garbageCollectEngines - Maintains debug logging for better observability Closes #8195 --- .../unreleased/Added-20241207-013627.yaml | 6 ++ .dagger/mage/engine.go | 19 +++-- engine/client/drivers/docker.go | 70 ++++++++++++++++--- 3 files changed, 78 insertions(+), 17 deletions(-) create mode 100644 .changes/unreleased/Added-20241207-013627.yaml diff --git a/.changes/unreleased/Added-20241207-013627.yaml b/.changes/unreleased/Added-20241207-013627.yaml new file mode 100644 index 0000000000..039facb9b4 --- /dev/null +++ b/.changes/unreleased/Added-20241207-013627.yaml @@ -0,0 +1,6 @@ +kind: Added +body: Added DAGGER_LEAVE_OLD_ENGINE environment variable to optionally prevent removal of old engine containers during upgrades +time: 2024-12-07T01:36:27.59938702Z +custom: + Author: devin + PR: "8195" diff --git a/.dagger/mage/engine.go b/.dagger/mage/engine.go index ca91ff39c6..33ad762f0e 100644 --- a/.dagger/mage/engine.go +++ b/.dagger/mage/engine.go @@ -21,6 +21,11 @@ var ( EngineContainerName = distconsts.EngineContainerName ) +func shouldLeaveOldEngine() bool { + val := os.Getenv("DAGGER_LEAVE_OLD_ENGINE") + return val != "" && val != "0" && strings.ToLower(val) != "false" +} + func init() { if v, ok := os.LookupEnv(util.DevContainerEnvName); ok { EngineContainerName = v @@ -86,12 +91,14 @@ func (t Engine) Dev(ctx context.Context) error { return fmt.Errorf("docker tag %s %s: %w: %s", imageID, imageName, err, output) } - if output, err := exec.CommandContext(ctx, "docker", - "rm", - "-fv", - containerName, - ).CombinedOutput(); err != nil { - return fmt.Errorf("docker rm: %w: %s", err, output) + if !shouldLeaveOldEngine() { + if output, err := exec.CommandContext(ctx, "docker", + "rm", + "-fv", + containerName, + ).CombinedOutput(); err != nil { + return fmt.Errorf("docker rm: %w: %s", err, output) + } } runArgs := []string{ diff --git a/engine/client/drivers/docker.go b/engine/client/drivers/docker.go index a996693bb5..bdb3c39408 100644 --- a/engine/client/drivers/docker.go +++ b/engine/client/drivers/docker.go @@ -34,6 +34,12 @@ func init() { register("docker-image", &dockerDriver{}) } +// shouldCleanupEngines returns true if old engines should be cleaned up +func shouldCleanupEngines() bool { + val := os.Getenv("DAGGER_LEAVE_OLD_ENGINE") + return val == "" || val == "0" || strings.ToLower(val) == "false" +} + // dockerDriver creates and manages a container, then connects to it type dockerDriver struct{} @@ -72,6 +78,11 @@ func (d *dockerDriver) create(ctx context.Context, imageRef string, opts *Driver defer telemetry.End(span, func() error { return rerr }) slog := slog.SpanLogger(ctx, InstrumentationLibrary) + // Log environment variable state at creation + slog.Info("checking engine environment", + "DAGGER_LEAVE_OLD_ENGINE", os.Getenv("DAGGER_LEAVE_OLD_ENGINE"), + "shouldCleanup", shouldCleanupEngines()) + id, err := resolveImageID(imageRef) if err != nil { return nil, err @@ -92,11 +103,17 @@ func (d *dockerDriver) create(ctx context.Context, imageRef string, opts *Driver for i, leftoverEngine := range leftoverEngines { // if we already have a container with that name, attempt to start it if leftoverEngine == containerName { + slog.Info("found existing container", "name", containerName) cmd := exec.CommandContext(ctx, "docker", "start", leftoverEngine) if output, err := traceExec(ctx, cmd); err != nil { return nil, errors.Wrapf(err, "failed to start container: %s", output) } - garbageCollectEngines(ctx, slog, append(leftoverEngines[:i], leftoverEngines[i+1:]...)) + slog.Info("cleaning up other engines after starting existing container", + "current", containerName, + "leftover_count", len(leftoverEngines)-1) + if shouldCleanupEngines() { + garbageCollectEngines(ctx, slog, append(leftoverEngines[:i], leftoverEngines[i+1:]...)) + } return connhDocker.Helper(&url.URL{ Scheme: "docker-container", Host: containerName, @@ -134,6 +151,7 @@ func (d *dockerDriver) create(ctx context.Context, imageRef string, opts *Driver // explicitly pass current env vars; if we append more below existing ones like DOCKER_HOST // won't be passed to the cmd cmd.Env = os.Environ() + if opts.DaggerCloudToken != "" { cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", EnvDaggerCloudToken, opts.DaggerCloudToken)) cmd.Args = append(cmd.Args, "-e", EnvDaggerCloudToken) @@ -151,10 +169,12 @@ func (d *dockerDriver) create(ctx context.Context, imageRef string, opts *Driver } } - // garbage collect any other containers with the same name pattern, which - // we assume to be leftover from previous runs of the engine using an older - // version - garbageCollectEngines(ctx, slog, leftoverEngines) + if shouldCleanupEngines() { + slog.Info("cleaning up old engines after creating new container", + "current", containerName, + "leftover_count", len(leftoverEngines)) + garbageCollectEngines(ctx, slog, leftoverEngines) + } return connhDocker.Helper(&url.URL{ Scheme: "docker-container", @@ -185,19 +205,35 @@ func resolveImageID(imageRef string) (string, error) { } func garbageCollectEngines(ctx context.Context, log *slog.Logger, engines []string) { + val := os.Getenv("DAGGER_LEAVE_OLD_ENGINE") + + // Enhanced logging for debugging + log.Info("evaluating engine cleanup", + "raw_env_value", val, + "engineCount", len(engines)) + + // Log each engine being considered + for i, engine := range engines { + log.Info("found engine", + "index", i, + "name", engine) + } + for _, engine := range engines { if engine == "" { continue } + log.Info("removing engine", + "name", engine, + "env_value", val) + if output, err := traceExec(ctx, exec.CommandContext(ctx, "docker", "rm", "-fv", engine, )); err != nil { - if errors.Is(err, context.Canceled) { - return - } - if !strings.Contains(output, "already in progress") { - log.Warn("failed to remove old container", "container", engine, "error", err) - } + log.Warn("failed to remove container", + "name", engine, + "error", err, + "output", output) } } } @@ -217,6 +253,10 @@ func traceExec(ctx context.Context, cmd *exec.Cmd, opts ...trace.SpanStartOption } func collectLeftoverEngines(ctx context.Context) ([]string, error) { + slog := slog.SpanLogger(ctx, InstrumentationLibrary) + slog.Info("collecting leftover engines", + "DAGGER_LEAVE_OLD_ENGINE", os.Getenv("DAGGER_LEAVE_OLD_ENGINE")) + cmd := exec.CommandContext(ctx, "docker", "ps", "-a", @@ -226,11 +266,19 @@ func collectLeftoverEngines(ctx context.Context) ([]string, error) { ) output, err := traceExec(ctx, cmd) if err != nil { + slog.Error("failed to list containers", + "error", err, + "output", output) return nil, errors.Wrapf(err, "failed to list containers: %s", output) } output = strings.TrimSpace(output) engineNames := strings.Split(output, "\n") + + slog.Info("found engines", + "count", len(engineNames), + "names", engineNames) + return engineNames, err } From dfde3f946b1c9d379ad6f0cca036108768f7c917 Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Sat, 7 Dec 2024 13:36:24 +0000 Subject: [PATCH 04/35] ci: allow exporting engine directly to the host (#9124) Signed-off-by: Justin Chadwell --- .dagger/docker.go | 122 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 .dagger/docker.go diff --git a/.dagger/docker.go b/.dagger/docker.go new file mode 100644 index 0000000000..c42df4fc9d --- /dev/null +++ b/.dagger/docker.go @@ -0,0 +1,122 @@ +package main + +import ( + "context" + "fmt" + "strings" + + "github.com/dagger/dagger/.dagger/internal/dagger" + "github.com/dagger/dagger/engine/distconsts" + "github.com/moby/buildkit/identity" +) + +// LoadToDocker loads the engine container into docker +func (e *DaggerEngine) LoadToDocker( + ctx context.Context, + + docker *dagger.Socket, + name string, + + // +optional + platform dagger.Platform, + + // Set target distro + // +optional + image *Distro, + // Enable experimental GPU support + // +optional + gpuSupport bool, +) (*LoadedEngine, error) { + ctr, err := e.Container(ctx, platform, image, gpuSupport) + if err != nil { + return nil, err + } + tar := ctr.AsTarball(dagger.ContainerAsTarballOpts{ + // use gzip to avoid incompatibility w/ older docker versions + ForcedCompression: dagger.ImageLayerCompressionGzip, + }) + + loader := dag.Container(). + From("docker:cli"). + WithUnixSocket("/var/run/docker.sock", docker). + WithMountedFile("/image.tar.gz", tar). + WithEnvVariable("CACHEBUSTER", identity.NewID()) + + stdout, err := loader. + WithExec([]string{"docker", "load", "-i", "/image.tar.gz"}). + Stdout(ctx) + if err != nil { + return nil, fmt.Errorf("docker load failed: %w", err) + } + + _, imageID, ok := strings.Cut(stdout, "Loaded image ID: sha256:") + if !ok { + _, imageID, ok = strings.Cut(stdout, "Loaded image: sha256:") // podman + if !ok { + return nil, fmt.Errorf("unexpected output from docker load") + } + } + imageID = strings.TrimSpace(imageID) + + _, err = loader. + WithExec([]string{"docker", "tag", imageID, name}). + Sync(ctx) + if err != nil { + return nil, fmt.Errorf("docker tag failed: %w", err) + } + + return &LoadedEngine{ + Loader: loader, + Image: name, + GPUSupport: gpuSupport, + }, nil +} + +type LoadedEngine struct { + Loader *dagger.Container // +private + Image string + + GPUSupport bool // +private +} + +// Start the loaded engine container +func (e LoadedEngine) Start( + ctx context.Context, + + // +optional + // +default="dagger-engine.dev" + name string, + // +optional + cloudToken *dagger.Secret, +) error { + loader := e.Loader + + _, err := loader.WithExec([]string{"docker", "rm", "-fv", name}).Sync(ctx) + if err != nil { + return err + } + + args := []string{ + "docker", + "run", + "-d", + } + if e.GPUSupport { + args = append(args, "--gpus", "all") + loader = loader.WithEnvVariable("_EXPERIMENTAL_DAGGER_GPU_SUPPORT", "true") + } + if cloudToken != nil { + // NOTE: this is only for connecting to dagger cloud's cache service + args = append(args, "-e", "DAGGER_CLOUD_TOKEN") + loader = loader.WithSecretVariable("DAGGER_CLOUD_TOKEN", cloudToken) + } + args = append(args, []string{ + "-v", name + ":" + distconsts.EngineDefaultStateDir, + "--name", name, + "--privileged", + }...) + args = append(args, e.Image, "--extra-debug", "--debugaddr=0.0.0.0:6060") + + _, err = loader.WithExec(args).Sync(ctx) + return err +} From cc3552e5c0da9bd75c2292d067393a624901a68f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 10:55:49 +0000 Subject: [PATCH 05/35] chore(deps): bump astral-sh/ruff (#9144) Bumps the sdk-python group in /modules/ruff/build with 1 update: [astral-sh/ruff](https://github.com/astral-sh/ruff). Updates `astral-sh/ruff` from 0.8.1 to 0.8.2 - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/0.8.1...0.8.2) --- updated-dependencies: - dependency-name: astral-sh/ruff dependency-type: direct:production update-type: version-update:semver-patch dependency-group: sdk-python ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- modules/ruff/build/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ruff/build/Dockerfile b/modules/ruff/build/Dockerfile index c6b12f2d11..e9bd89b6d8 100644 --- a/modules/ruff/build/Dockerfile +++ b/modules/ruff/build/Dockerfile @@ -1,2 +1,2 @@ # For dependabot -FROM ghcr.io/astral-sh/ruff:0.8.1@sha256:5bfb117d8d794578171cf6a6f076145cd0233d1fe79f661ac12d10113309a259 +FROM ghcr.io/astral-sh/ruff:0.8.2@sha256:84b0ad0023906db70b759b3b29e455dad0638159bf2de2b95086db1ab175917b From 20bab132591af1b9401b9d84a0d5a8b231525ec9 Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Mon, 9 Dec 2024 11:30:13 +0000 Subject: [PATCH 06/35] chore: omit empty dependency pin in dagger.json (#9133) * feat: add DAGGER_LEAVE_OLD_ENGINE to prevent old engine cleanup This change adds a new environment variable DAGGER_LEAVE_OLD_ENGINE that prevents cleanup of old engine containers when set to any value except '0' or empty string. - Adds shouldLeaveOldEngine() function to control engine cleanup behavior - Modifies cleanup logic in Docker driver to respect the environment variable - Removes redundant cleanup check in garbageCollectEngines - Maintains debug logging for better observability Closes #8195 * ci: allow exporting engine directly to the host (#9124) Signed-off-by: Justin Chadwell * chore: omit empty dependency pin in dagger.json Signed-off-by: Justin Chadwell --------- Signed-off-by: Justin Chadwell Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- core/modules/config.go | 2 +- docs/static/reference/dagger.schema.json | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/core/modules/config.go b/core/modules/config.go index 426d9b7199..56a97a8f7a 100644 --- a/core/modules/config.go +++ b/core/modules/config.go @@ -84,7 +84,7 @@ type ModuleConfigDependency struct { Source string `json:"source"` // The pinned version of the module dependency. - Pin string `json:"pin"` + Pin string `json:"pin,omitempty"` } func (depCfg *ModuleConfigDependency) UnmarshalJSON(data []byte) error { diff --git a/docs/static/reference/dagger.schema.json b/docs/static/reference/dagger.schema.json index 0ef9be39df..68bf1c5e6c 100644 --- a/docs/static/reference/dagger.schema.json +++ b/docs/static/reference/dagger.schema.json @@ -91,8 +91,7 @@ "type": "object", "required": [ "name", - "source", - "pin" + "source" ] }, "ModuleConfigView": { From 1aea1836f519b361f7c6ed9d2e567f915b39a7b2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 18:54:42 +0000 Subject: [PATCH 07/35] chore(deps): bump the docs group across 1 directory with 8 updates (#9138) * chore(deps): bump the docs group across 1 directory with 8 updates Bumps the docs group with 8 updates in the /docs directory: | Package | From | To | | --- | --- | --- | | [docusaurus-plugin-sass](https://github.com/rlamana/docusaurus-plugin-sass) | `0.2.5` | `0.2.6` | | [docusaurus-plugin-typedoc](https://github.com/typedoc2md/typedoc-plugin-markdown/tree/HEAD/packages/docusaurus-plugin-typedoc) | `1.0.5` | `1.1.1` | | [react](https://github.com/facebook/react/tree/HEAD/packages/react) | `18.3.1` | `19.0.0` | | [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) | `18.3.1` | `19.0.0` | | [sass](https://github.com/sass/dart-sass) | `1.81.0` | `1.82.0` | | [typedoc](https://github.com/TypeStrong/TypeDoc) | `0.26.11` | `0.27.4` | | [typedoc-plugin-frontmatter](https://github.com/typedoc2md/typedoc-plugin-markdown/tree/HEAD/packages/typedoc-plugin-frontmatter) | `1.0.0` | `1.1.0` | | [typedoc-plugin-markdown](https://github.com/typedoc2md/typedoc-plugin-markdown/tree/HEAD/packages/typedoc-plugin-markdown) | `4.2.10` | `4.3.2` | Updates `docusaurus-plugin-sass` from 0.2.5 to 0.2.6 - [Release notes](https://github.com/rlamana/docusaurus-plugin-sass/releases) - [Commits](https://github.com/rlamana/docusaurus-plugin-sass/compare/v0.2.5...v0.2.6) Updates `docusaurus-plugin-typedoc` from 1.0.5 to 1.1.1 - [Release notes](https://github.com/typedoc2md/typedoc-plugin-markdown/releases) - [Changelog](https://github.com/typedoc2md/typedoc-plugin-markdown/blob/main/packages/docusaurus-plugin-typedoc/CHANGELOG.md) - [Commits](https://github.com/typedoc2md/typedoc-plugin-markdown/commits/docusaurus-plugin-typedoc@1.1.1/packages/docusaurus-plugin-typedoc) Updates `react` from 18.3.1 to 19.0.0 - [Release notes](https://github.com/facebook/react/releases) - [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md) - [Commits](https://github.com/facebook/react/commits/v19.0.0/packages/react) Updates `react-dom` from 18.3.1 to 19.0.0 - [Release notes](https://github.com/facebook/react/releases) - [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md) - [Commits](https://github.com/facebook/react/commits/v19.0.0/packages/react-dom) Updates `sass` from 1.81.0 to 1.82.0 - [Release notes](https://github.com/sass/dart-sass/releases) - [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md) - [Commits](https://github.com/sass/dart-sass/compare/1.81.0...1.82.0) Updates `typedoc` from 0.26.11 to 0.27.4 - [Release notes](https://github.com/TypeStrong/TypeDoc/releases) - [Changelog](https://github.com/TypeStrong/typedoc/blob/master/CHANGELOG.md) - [Commits](https://github.com/TypeStrong/TypeDoc/compare/v0.26.11...v0.27.4) Updates `typedoc-plugin-frontmatter` from 1.0.0 to 1.1.0 - [Release notes](https://github.com/typedoc2md/typedoc-plugin-markdown/releases) - [Changelog](https://github.com/typedoc2md/typedoc-plugin-markdown/blob/main/packages/typedoc-plugin-frontmatter/CHANGELOG.md) - [Commits](https://github.com/typedoc2md/typedoc-plugin-markdown/commits/typedoc-plugin-frontmatter@1.1.0/packages/typedoc-plugin-frontmatter) Updates `typedoc-plugin-markdown` from 4.2.10 to 4.3.2 - [Release notes](https://github.com/typedoc2md/typedoc-plugin-markdown/releases) - [Changelog](https://github.com/typedoc2md/typedoc-plugin-markdown/blob/main/packages/typedoc-plugin-markdown/CHANGELOG.md) - [Commits](https://github.com/typedoc2md/typedoc-plugin-markdown/commits/typedoc-plugin-markdown@4.3.2/packages/typedoc-plugin-markdown) --- updated-dependencies: - dependency-name: docusaurus-plugin-sass dependency-type: direct:production update-type: version-update:semver-patch dependency-group: docs - dependency-name: docusaurus-plugin-typedoc dependency-type: direct:production update-type: version-update:semver-minor dependency-group: docs - dependency-name: react dependency-type: direct:production update-type: version-update:semver-major dependency-group: docs - dependency-name: react-dom dependency-type: direct:production update-type: version-update:semver-major dependency-group: docs - dependency-name: sass dependency-type: direct:production update-type: version-update:semver-minor dependency-group: docs - dependency-name: typedoc dependency-type: direct:production update-type: version-update:semver-minor dependency-group: docs - dependency-name: typedoc-plugin-frontmatter dependency-type: direct:production update-type: version-update:semver-minor dependency-group: docs - dependency-name: typedoc-plugin-markdown dependency-type: direct:production update-type: version-update:semver-minor dependency-group: docs ... Signed-off-by: dependabot[bot] * ci: update docusaurus to consume full yarn This means we actually get the right deps versions :) Signed-off-by: Justin Chadwell --------- Signed-off-by: dependabot[bot] Signed-off-by: Justin Chadwell Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Justin Chadwell --- .dagger/docs.go | 3 +- dagger.json | 4 +- docs/package.json | 16 ++-- docs/yarn.lock | 203 ++++++++++++++++------------------------------ 4 files changed, 80 insertions(+), 146 deletions(-) diff --git a/.dagger/docs.go b/.dagger/docs.go index db95443e95..e858f63c42 100644 --- a/.dagger/docs.go +++ b/.dagger/docs.go @@ -38,7 +38,8 @@ func (d Docs) Site() *dagger.Directory { Docusaurus( d.Dagger.Source(), dagger.DocusaurusOpts{ - Dir: "/src/docs", + Dir: "/src/docs", + Yarn: true, // HACK: cache seems to cause weird ephemeral errors occasionally - // probably because of cache sharing DisableCache: true, diff --git a/dagger.json b/dagger.json index 3a1a024c87..d289e9dc6d 100644 --- a/dagger.json +++ b/dagger.json @@ -20,8 +20,8 @@ }, { "name": "docusaurus", - "source": "github.com/levlaz/daggerverse/docusaurus@e494cec1aa8f9faab1e0f12b2e5eea4a2321f2de", - "pin": "e494cec1aa8f9faab1e0f12b2e5eea4a2321f2de" + "source": "github.com/levlaz/daggerverse/docusaurus@main", + "pin": "47f5206067011dad0f581d4e7db7afddda32acd0" }, { "name": "elixir-sdk-dev", diff --git a/docs/package.json b/docs/package.json index 1b1671c45b..8ef3a3af14 100644 --- a/docs/package.json +++ b/docs/package.json @@ -22,17 +22,17 @@ "@mdx-js/react": "^3.1.0", "clsx": "^2.1.1", "docusaurus-plugin-image-zoom": "^2.0.0", - "docusaurus-plugin-sass": "^0.2.5", - "docusaurus-plugin-typedoc": "^1.0.5", + "docusaurus-plugin-sass": "^0.2.6", + "docusaurus-plugin-typedoc": "^1.1.1", "posthog-docusaurus": "^2.0.0", "prism-react-renderer": "^2.1.0", - "react": "^18.0.0", - "react-dom": "^18.0.0", + "react": "^19.0.0", + "react-dom": "^19.0.0", "remark-code-import": "^1.2.0", - "sass": "^1.81.0", - "typedoc": "^0.26.11", - "typedoc-plugin-frontmatter": "^1.0.0", - "typedoc-plugin-markdown": "^4.2.10", + "sass": "^1.82.0", + "typedoc": "^0.27.4", + "typedoc-plugin-frontmatter": "^1.1.0", + "typedoc-plugin-markdown": "^4.3.2", "typescript": "^5.6.3" }, "devDependencies": { diff --git a/docs/yarn.lock b/docs/yarn.lock index 5996cb0cf7..804bbde8e9 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -2007,6 +2007,15 @@ utility-types "^3.10.0" webpack "^5.88.1" +"@gerrit0/mini-shiki@^1.24.0": + version "1.24.1" + resolved "https://registry.yarnpkg.com/@gerrit0/mini-shiki/-/mini-shiki-1.24.1.tgz#60ef10f4e2cfac7a9223e10b88c128438aa44fd8" + integrity sha512-PNP/Gjv3VqU7z7DjRgO3F9Ok5frTKqtpV+LJW1RzMcr2zpRk0ulhEWnbcNGXzPC7BZyWMIHrkfQX2GZRfxrn6Q== + dependencies: + "@shikijs/engine-oniguruma" "^1.24.0" + "@shikijs/types" "^1.24.0" + "@shikijs/vscode-textmate" "^9.3.0" + "@hapi/hoek@^9.0.0", "@hapi/hoek@^9.3.0": version "9.3.0" resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb" @@ -2274,39 +2283,18 @@ resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.28.tgz#d45e01c4a56f143ee69c54dd6b12eade9e270a73" integrity sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw== -"@shikijs/core@1.22.0": - version "1.22.0" - resolved "https://registry.yarnpkg.com/@shikijs/core/-/core-1.22.0.tgz#74e5d4485e5f7afa85109e322b42e400686f92bb" - integrity sha512-S8sMe4q71TJAW+qG93s5VaiihujRK6rqDFqBnxqvga/3LvqHEnxqBIOPkt//IdXVtHkQWKu4nOQNk0uBGicU7Q== +"@shikijs/engine-oniguruma@^1.24.0": + version "1.24.1" + resolved "https://registry.yarnpkg.com/@shikijs/engine-oniguruma/-/engine-oniguruma-1.24.1.tgz#cf9f74867987a786057dbf599f571800f7ec5b30" + integrity sha512-KdrTIBIONWd+Xs61eh8HdIpfigtrseat9dpARvaOe2x0g/FNTbwbkGr3y92VSOVD1XotzEskh3v/nCzyWjkf7g== dependencies: - "@shikijs/engine-javascript" "1.22.0" - "@shikijs/engine-oniguruma" "1.22.0" - "@shikijs/types" "1.22.0" + "@shikijs/types" "1.24.1" "@shikijs/vscode-textmate" "^9.3.0" - "@types/hast" "^3.0.4" - hast-util-to-html "^9.0.3" -"@shikijs/engine-javascript@1.22.0": - version "1.22.0" - resolved "https://registry.yarnpkg.com/@shikijs/engine-javascript/-/engine-javascript-1.22.0.tgz#2e5db29f0421755492f5279f8224ef7a7f907a29" - integrity sha512-AeEtF4Gcck2dwBqCFUKYfsCq0s+eEbCEbkUuFou53NZ0sTGnJnJ/05KHQFZxpii5HMXbocV9URYVowOP2wH5kw== - dependencies: - "@shikijs/types" "1.22.0" - "@shikijs/vscode-textmate" "^9.3.0" - oniguruma-to-js "0.4.3" - -"@shikijs/engine-oniguruma@1.22.0": - version "1.22.0" - resolved "https://registry.yarnpkg.com/@shikijs/engine-oniguruma/-/engine-oniguruma-1.22.0.tgz#74c661fac4cd1f08f2c09b5d6e2fd2a6720d0401" - integrity sha512-5iBVjhu/DYs1HB0BKsRRFipRrD7rqjxlWTj4F2Pf+nQSPqc3kcyqFFeZXnBMzDf0HdqaFVvhDRAGiYNvyLP+Mw== - dependencies: - "@shikijs/types" "1.22.0" - "@shikijs/vscode-textmate" "^9.3.0" - -"@shikijs/types@1.22.0": - version "1.22.0" - resolved "https://registry.yarnpkg.com/@shikijs/types/-/types-1.22.0.tgz#d2a572381395c9308b472c8199b8e0289753b9ad" - integrity sha512-Fw/Nr7FGFhlQqHfxzZY8Cwtwk5E9nKDUgeLjZgt3UuhcM3yJR9xj3ZGNravZZok8XmEZMiYkSMTPlPkULB8nww== +"@shikijs/types@1.24.1", "@shikijs/types@^1.24.0": + version "1.24.1" + resolved "https://registry.yarnpkg.com/@shikijs/types/-/types-1.24.1.tgz#669c7165f9ee3caa475fadd61f7ed4ca0009e848" + integrity sha512-ZwZFbShFY/APfKNt3s9Gv8rhTm29GodSKsOW66X6N+HGsZuaHalE1VUEX4fv93UXHTZTLjb3uxn63F96RhGfXw== dependencies: "@shikijs/vscode-textmate" "^9.3.0" "@types/hast" "^3.0.4" @@ -4736,17 +4724,17 @@ docusaurus-plugin-image-zoom@^2.0.0: medium-zoom "^1.0.8" validate-peer-dependencies "^2.2.0" -docusaurus-plugin-sass@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/docusaurus-plugin-sass/-/docusaurus-plugin-sass-0.2.5.tgz#6bfb8a227ac6265be685dcbc24ba1989e27b8005" - integrity sha512-Z+D0fLFUKcFpM+bqSUmqKIU+vO+YF1xoEQh5hoFreg2eMf722+siwXDD+sqtwU8E4MvVpuvsQfaHwODNlxJAEg== +docusaurus-plugin-sass@^0.2.6: + version "0.2.6" + resolved "https://registry.yarnpkg.com/docusaurus-plugin-sass/-/docusaurus-plugin-sass-0.2.6.tgz#b4930a1fe1cc7bcead639bb1bee38bce0ffd073d" + integrity sha512-2hKQQDkrufMong9upKoG/kSHJhuwd+FA3iAe/qzS/BmWpbIpe7XKmq5wlz4J5CJaOPu4x+iDJbgAxZqcoQf0kg== dependencies: - sass-loader "^10.1.1" + sass-loader "^16.0.2" -docusaurus-plugin-typedoc@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/docusaurus-plugin-typedoc/-/docusaurus-plugin-typedoc-1.0.5.tgz#cc04de58201ac327861c4c9fb0e2af58244373ea" - integrity sha512-mv8LBJYilGOOPLqaIM3vbYc34m4qwOCpb4WfP24DOPFNj2uiTerw8sg9MGvN6Jx2+J8rq9/WMnjcyz3UMqoIIQ== +docusaurus-plugin-typedoc@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/docusaurus-plugin-typedoc/-/docusaurus-plugin-typedoc-1.1.1.tgz#cac32cc4526da4a49e05a073b13e2b9f478c61cd" + integrity sha512-jaSHPA2iQVE60Mugr/pbHzIWVR/7tp77A+e9+oYvZylupdNCwZ/5BadqcqZHdLQCsUZSvu4SlE3ob/ynN6aUAw== dom-converter@^0.2.0: version "0.2.0" @@ -5635,23 +5623,6 @@ hast-util-to-estree@^3.0.0: unist-util-position "^5.0.0" zwitch "^2.0.0" -hast-util-to-html@^9.0.3: - version "9.0.3" - resolved "https://registry.yarnpkg.com/hast-util-to-html/-/hast-util-to-html-9.0.3.tgz#a9999a0ba6b4919576a9105129fead85d37f302b" - integrity sha512-M17uBDzMJ9RPCqLMO92gNNUDuBSq10a25SDBI08iCCxmorf4Yy6sYHK57n9WAbRAAaU+DuR4W6GN9K4DFZesYg== - dependencies: - "@types/hast" "^3.0.0" - "@types/unist" "^3.0.0" - ccount "^2.0.0" - comma-separated-tokens "^2.0.0" - hast-util-whitespace "^3.0.0" - html-void-elements "^3.0.0" - mdast-util-to-hast "^13.0.0" - property-information "^6.0.0" - space-separated-tokens "^2.0.0" - stringify-entities "^4.0.0" - zwitch "^2.0.4" - hast-util-to-jsx-runtime@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.0.tgz#3ed27caf8dc175080117706bf7269404a0aa4f7c" @@ -6353,11 +6324,6 @@ kleur@^3.0.3: resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== -klona@^2.0.4: - version "2.0.6" - resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.6.tgz#85bffbf819c03b2f53270412420a4555ef882e22" - integrity sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA== - kolorist@^1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/kolorist/-/kolorist-1.8.0.tgz#edddbbbc7894bc13302cdf740af6374d4a04743c" @@ -6500,7 +6466,7 @@ longest-streak@^3.0.0: resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-3.1.0.tgz#62fa67cd958742a1574af9f39866364102d90cd4" integrity sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g== -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: +loose-envify@^1.0.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -7551,13 +7517,6 @@ onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" -oniguruma-to-js@0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/oniguruma-to-js/-/oniguruma-to-js-0.4.3.tgz#8d899714c21f5c7d59a3c0008ca50e848086d740" - integrity sha512-X0jWUcAlxORhOqqBREgPMgnshB7ZGYszBNspP+tS9hPD3l13CdaXcHbgImoHUHlrvGx/7AvFEkTRhAGYh+jzjQ== - dependencies: - regex "^4.3.2" - open@^8.0.9, open@^8.4.0: version "8.4.2" resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" @@ -8595,13 +8554,12 @@ react-dev-utils@^12.0.1: strip-ansi "^6.0.1" text-table "^0.2.0" -react-dom@^18.0.0: - version "18.3.1" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4" - integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== +react-dom@^19.0.0: + version "19.0.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-19.0.0.tgz#43446f1f01c65a4cd7f7588083e686a6726cfb57" + integrity sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ== dependencies: - loose-envify "^1.1.0" - scheduler "^0.23.2" + scheduler "^0.25.0" react-error-overlay@^6.0.11: version "6.0.11" @@ -8692,12 +8650,10 @@ react-router@5.3.4, react-router@^5.3.4: tiny-invariant "^1.0.2" tiny-warning "^1.0.0" -react@^18.0.0: - version "18.3.1" - resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891" - integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== - dependencies: - loose-envify "^1.1.0" +react@^19.0.0: + version "19.0.0" + resolved "https://registry.yarnpkg.com/react/-/react-19.0.0.tgz#6e1969251b9f108870aa4bff37a0ce9ddfaaabdd" + integrity sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ== readable-stream@^2.0.1: version "2.3.8" @@ -8776,11 +8732,6 @@ regenerator-transform@^0.15.2: dependencies: "@babel/runtime" "^7.8.4" -regex@^4.3.2: - version "4.3.3" - resolved "https://registry.yarnpkg.com/regex/-/regex-4.3.3.tgz#8cda73ccbdfa7c5691881d02f9bb142dba9daa6a" - integrity sha512-r/AadFO7owAq1QJVeZ/nq9jNS1vyZt+6t1p/E59B56Rn2GCya+gr1KSyOzNL/er+r+B7phv5jG2xU2Nz1YkmJg== - regexpu-core@^6.1.1: version "6.1.1" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-6.1.1.tgz#b469b245594cb2d088ceebc6369dceb8c00becac" @@ -9066,21 +9017,17 @@ safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sass-loader@^10.1.1: - version "10.5.2" - resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-10.5.2.tgz#1ca30534fff296417b853c7597ca3b0bbe8c37d0" - integrity sha512-vMUoSNOUKJILHpcNCCyD23X34gve1TS7Rjd9uXHeKqhvBG39x6XbswFDtpbTElj6XdMFezoWhkh5vtKudf2cgQ== +sass-loader@^16.0.2: + version "16.0.4" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-16.0.4.tgz#5c2afb755fbc0a45a004369efa11579518a39a45" + integrity sha512-LavLbgbBGUt3wCiYzhuLLu65+fWXaXLmq7YxivLhEqmiupCFZ5sKUAipK3do6V80YSU0jvSxNhEdT13IXNr3rg== dependencies: - klona "^2.0.4" - loader-utils "^2.0.0" neo-async "^2.6.2" - schema-utils "^3.0.0" - semver "^7.3.2" -sass@^1.81.0: - version "1.81.0" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.81.0.tgz#a9010c0599867909dfdbad057e4a6fbdd5eec941" - integrity sha512-Q4fOxRfhmv3sqCLoGfvrC9pRV8btc0UtqL9mN6Yrv6Qi9ScL55CVH1vlPP863ISLEEMNLLuu9P+enCeGHlnzhA== +sass@^1.82.0: + version "1.82.0" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.82.0.tgz#30da277af3d0fa6042e9ceabd0d984ed6d07df70" + integrity sha512-j4GMCTa8elGyN9A7x7bEglx0VgSpNUG4W4wNedQ33wSMdnkqQCT8HTwOaVSV4e6yQovcu/3Oc4coJP/l0xhL2Q== dependencies: chokidar "^4.0.0" immutable "^5.0.2" @@ -9093,12 +9040,10 @@ sax@^1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.4.1.tgz#44cc8988377f126304d3b3fc1010c733b929ef0f" integrity sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg== -scheduler@^0.23.2: - version "0.23.2" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3" - integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== - dependencies: - loose-envify "^1.1.0" +scheduler@^0.25.0: + version "0.25.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.25.0.tgz#336cd9768e8cceebf52d3c80e3dcf5de23e7e015" + integrity sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA== schema-utils@2.7.0: version "2.7.0" @@ -9288,18 +9233,6 @@ shelljs@^0.8.5: interpret "^1.0.0" rechoir "^0.6.2" -shiki@^1.16.2: - version "1.22.0" - resolved "https://registry.yarnpkg.com/shiki/-/shiki-1.22.0.tgz#45d1dfff0e03a598af70e2ec8592f14ef07827b4" - integrity sha512-/t5LlhNs+UOKQCYBtl5ZsH/Vclz73GIqT2yQsCBygr8L/ppTdmpL4w3kPLoZJbMKVWtoG77Ue1feOjZfDxvMkw== - dependencies: - "@shikijs/core" "1.22.0" - "@shikijs/engine-javascript" "1.22.0" - "@shikijs/engine-oniguruma" "1.22.0" - "@shikijs/types" "1.22.0" - "@shikijs/vscode-textmate" "^9.3.0" - "@types/hast" "^3.0.4" - side-channel@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" @@ -9758,28 +9691,28 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -typedoc-plugin-frontmatter@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typedoc-plugin-frontmatter/-/typedoc-plugin-frontmatter-1.0.0.tgz#908ccbfb27587a64f259c0250c5992497cb59e48" - integrity sha512-Mqn96+RjUjPUz/42H8MOp/8eOKjE5MVIgZRFDGmSI2YuggnMZSfh5MMpvd6ykjNTpq7gV5D2iwjqLt8nYRg9rg== +typedoc-plugin-frontmatter@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/typedoc-plugin-frontmatter/-/typedoc-plugin-frontmatter-1.1.0.tgz#fe0a277261f491ac5af1ded6ac2242a720effda4" + integrity sha512-4PW4V2xDY2hw+fEWmg7g6FBCIWZdiEE+tzjJ5K4JhurvJ0t0Vp0IE/0nuHGGIZVtV5WxPIed+GpiH1uZrpDquQ== dependencies: yaml "^2.3.4" -typedoc-plugin-markdown@^4.2.10: - version "4.2.10" - resolved "https://registry.yarnpkg.com/typedoc-plugin-markdown/-/typedoc-plugin-markdown-4.2.10.tgz#cd386e9f2dec122cae79e487983811d92ac37161" - integrity sha512-PLX3pc1/7z13UJm4TDE9vo9jWGcClFUErXXtd5LdnoLjV6mynPpqZLU992DwMGFSRqJFZeKbVyqlNNeNHnk2tQ== +typedoc-plugin-markdown@^4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/typedoc-plugin-markdown/-/typedoc-plugin-markdown-4.3.2.tgz#85d38bc0109a3fbf2e3fad2ea78e6dd8e812e5a2" + integrity sha512-hCF3V0axzbzGDYFW21XigWIJQBOJ2ZRVWWs7X+e62ew/pXnvz7iKF/zVdkBm3w8Mk4bmXWp/FT0IF4Zn9uBRww== -typedoc@^0.26.11: - version "0.26.11" - resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.26.11.tgz#124b43a5637b7f3237b8c721691b44738c5c9dc9" - integrity sha512-sFEgRRtrcDl2FxVP58Ze++ZK2UQAEvtvvH8rRlig1Ja3o7dDaMHmaBfvJmdGnNEFaLTpQsN8dpvZaTqJSu/Ugw== +typedoc@^0.27.4: + version "0.27.4" + resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.27.4.tgz#45be59ccf9383d3c52f4a96636d823345c6ff0e6" + integrity sha512-wXPQs1AYC2Crk+1XFpNuutLIkNWleokZf1UNf/X8w9KsMnirkvT+LzxTXDvfF6ug3TSLf3Xu5ZXRKGfoXPX7IA== dependencies: + "@gerrit0/mini-shiki" "^1.24.0" lunr "^2.3.9" markdown-it "^14.1.0" minimatch "^9.0.5" - shiki "^1.16.2" - yaml "^2.5.1" + yaml "^2.6.1" typescript@^5.6.3: version "5.7.2" @@ -10360,10 +10293,10 @@ yaml@^1.7.2: resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== -yaml@^2.3.4, yaml@^2.5.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.5.1.tgz#c9772aacf62cb7494a95b0c4f1fb065b563db130" - integrity sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q== +yaml@^2.3.4, yaml@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.6.1.tgz#42f2b1ba89203f374609572d5349fb8686500773" + integrity sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg== yocto-queue@^0.1.0: version "0.1.0" @@ -10375,7 +10308,7 @@ yocto-queue@^1.0.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.1.1.tgz#fef65ce3ac9f8a32ceac5a634f74e17e5b232110" integrity sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g== -zwitch@^2.0.0, zwitch@^2.0.4: +zwitch@^2.0.0: version "2.0.4" resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-2.0.4.tgz#c827d4b0acb76fc3e685a4c6ec2902d51070e9d7" integrity sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A== From eb738ebe8bf53a80f8061d377dd04934e1489fce Mon Sep 17 00:00:00 2001 From: Vasek - Tom C Date: Mon, 9 Dec 2024 20:02:22 +0100 Subject: [PATCH 08/35] feat: decouple provisioning & refactor ts sdk architecture (#9031) Decouple provisioning from the TS SDK to dynamically load it when it's needed. - It first tries to create a GraphQL client from environment variables - If fails, it loads the provisioning package (if it exist, otherwise it will fails) and provision the engine + connection automatically. This is a requirement to support Deno since it has difficulties with syscalls. It's also interesting to make the dependency remote (but that will come later indeed). I also refactored a bit the overall architecture of the directories to make it cleaner. This include several changes: - Move root of the source file to `src`, so I also updated the generated `tsconfig.json` to point to the new path (same for `tsconfig_updator` script for backward compatibility. - Use `index` files to gather imports and simplify our overall import strategy. - Add files to introspector as `entrypoint` argument so it's computed by the `__dagger_entrypoint` instead, it makes the overall function simpler. - Simplify `Context` to not handle connection anymore, it's handle by a callback that handle the connection start/closure. - Update generated paths to point to `src` - Update doc paths too - Put `context` & `graphql` into `common` - Refactor the connection logic to work with callback to handle the closing in a more elegent way. It also unify the connection system to simplify even more provisioning. - Move connection & query tree inside Context. - Move compute query from the `api` directory to `common` - Handle query execution and query tree build logic inside context to simplify codegen (2K line saved) Signed-off-by: Tom Chauveau --- .dagger/build/sdk.go | 11 +- .dagger/sdk_typescript.go | 4 +- cmd/codegen/generator/typescript/generator.go | 2 +- .../typescript/templates/src/default.ts.gtpl | 2 +- .../typescript/templates/src/header.ts.gtpl | 40 +- .../typescript/templates/src/method.ts.gtpl | 30 +- .../templates/src/method_solve.ts.gtpl | 48 +- .../typescript/templates/src/object.ts.gtpl | 4 +- core/integration/module_test.go | 2 +- docs/docusaurus.config.ts | 6 +- sdk/typescript/context/builder.ts | 46 - sdk/typescript/context/context.ts | 73 - sdk/typescript/dev/src/index.ts | 11 +- sdk/typescript/package.json | 7 +- sdk/typescript/provisioning/engineconn.ts | 32 - sdk/typescript/provisioning/index.ts | 3 - .../runtime/bin/__dagger.entrypoint.ts | 32 +- .../runtime/bin/__tsconfig.updator.ts | 8 +- sdk/typescript/runtime/template/tsconfig.json | 4 +- sdk/typescript/{ => src}/api/.gitattributes | 0 sdk/typescript/{ => src}/api/client.gen.ts | 5421 ++++------------- sdk/typescript/{ => src}/api/test/api.spec.ts | 24 +- sdk/typescript/src/common/context.ts | 30 + .../{ => src}/common/errors/DaggerSDKError.ts | 0 .../errors/DockerImageRefValidationError.ts | 0 .../EngineSessionConnectParamsParseError.ts | 0 .../EngineSessionConnectionTimeoutError.ts | 0 .../errors/EngineSessionErrorOptions.ts | 0 .../{ => src}/common/errors/ExecError.ts | 0 .../common/errors/FunctionNotFound.ts | 0 .../common/errors/GraphQLRequestError.ts | 0 .../errors/InitEngineSessionBinaryError.ts | 0 .../common/errors/IntrospectionError.ts | 0 .../common/errors/NotAwaitedRequestError.ts | 0 .../errors/TooManyNestedObjectsError.ts | 0 .../common/errors/UnknownDaggerError.ts | 0 .../{ => src}/common/errors/errors-codes.ts | 0 .../{ => src}/common/errors/index.ts | 2 + .../{ => src/common}/graphql/client.ts | 0 .../common/graphql/compute_query.ts} | 20 +- sdk/typescript/src/common/graphql/connect.ts | 36 + .../src/common/graphql/connection.ts | 27 + sdk/typescript/{ => src}/common/utils.ts | 0 sdk/typescript/{ => src}/connect.ts | 46 +- sdk/typescript/{ => src}/connectOpts.ts | 0 sdk/typescript/{ => src}/index.ts | 18 +- .../decorators => src/module}/decorators.ts | 2 +- .../{ => src/module}/entrypoint/context.ts | 2 +- .../{ => src/module}/entrypoint/entrypoint.ts | 24 +- .../{ => src/module}/entrypoint/invoke.ts | 18 +- .../{ => src/module}/entrypoint/load.ts | 23 +- .../{ => src/module}/entrypoint/register.ts | 14 +- .../executor => src/module}/executor.ts | 4 +- .../module/introspector}/case_convertor.ts | 0 .../introspector}/dagger_module/argument.ts | 8 +- .../dagger_module/constructor.ts | 2 +- .../introspector}/dagger_module/decorator.ts | 8 +- .../introspector}/dagger_module/enum.ts | 4 +- .../introspector}/dagger_module/enumBase.ts | 0 .../introspector}/dagger_module/enumClass.ts | 8 +- .../introspector}/dagger_module/function.ts | 6 +- .../introspector/dagger_module/index.ts | 12 + .../introspector}/dagger_module/module.ts | 6 +- .../introspector}/dagger_module/object.ts | 4 +- .../introspector}/dagger_module/objectBase.ts | 0 .../introspector}/dagger_module/property.ts | 6 +- .../introspector}/dagger_module/reference.ts | 0 .../introspector}/dagger_module/typeObject.ts | 4 +- .../dagger_module/typeObjectProperty.ts | 6 +- .../module/introspector/index.ts} | 8 +- .../introspector/test/case_convertor.spec.ts | 2 +- .../module}/introspector/test/files.spec.ts | 0 .../module}/introspector/test/invoke.spec.ts | 115 +- .../introspector/test/registry.spec.ts | 6 +- .../module}/introspector/test/scan.spec.ts | 4 +- .../test/testdata/alias/expected.json | 0 .../introspector/test/testdata/alias/index.ts | 4 +- .../test/testdata/constructor/expected.json | 0 .../test/testdata/constructor/index.ts | 2 +- .../test/testdata/context/expected.json | 0 .../test/testdata/context/index.ts | 4 +- .../test/testdata/coreEnums/expected.json | 0 .../test/testdata/coreEnums/index.ts | 4 +- .../test/testdata/enums/expected.json | 0 .../introspector/test/testdata/enums/index.ts | 7 +- .../test/testdata/generate_expected_scan.ts | 6 +- .../test/testdata/helloWorld/expected.json | 0 .../test/testdata/helloWorld/helloWorld.ts | 2 +- .../test/testdata/helloWorld/toIgnore.md | 0 .../test/testdata/invalid/expected.json | 0 .../test/testdata/invalid/index.ts | 0 .../test/testdata/list/expected.json | 0 .../introspector/test/testdata/list/index.ts | 2 +- .../test/testdata/minimal/expected.json | 0 .../test/testdata/minimal/index.ts | 24 +- .../test/testdata/multiArgs/expected.json | 0 .../test/testdata/multiArgs/index.ts | 2 +- .../test/testdata/multipleObjects/bar.ts | 4 +- .../testdata/multipleObjects/expected.json | 0 .../test/testdata/multipleObjects/foo.ts | 2 +- .../multipleObjectsAsFields/expected.json | 0 .../testdata/multipleObjectsAsFields/index.ts | 2 +- .../testdata/multipleObjectsAsFields/lint.ts | 2 +- .../testdata/multipleObjectsAsFields/test.ts | 2 +- .../test/testdata/noDecorators/expected.json | 0 .../testdata/noDecorators/noDecorators.ts | 2 +- .../test/testdata/objectParam/expected.json | 0 .../test/testdata/objectParam/index.ts | 2 +- .../testdata/optionalParameter/expected.json | 0 .../test/testdata/optionalParameter/index.ts | 2 +- .../test/testdata/primitives/index.ts | 2 +- .../test/testdata/privateMethod/expected.json | 0 .../test/testdata/privateMethod/index.ts | 2 +- .../test/testdata/references/expected.json | 0 .../test/testdata/references/index.ts | 2 +- .../test/testdata/references/types.ts | 0 .../test/testdata/scalar/expected.json | 0 .../test/testdata/scalar/index.ts | 4 +- .../test/testdata/state/expected.json | 0 .../introspector/test/testdata/state/state.ts | 4 +- .../test/testdata/variadic/expected.json | 0 .../test/testdata/variadic/index.ts | 2 +- .../test/testdata/voidReturn/expected.json | 0 .../test/testdata/voidReturn/index.ts | 2 +- .../module/introspector}/typedef.ts | 0 .../introspector}/typescript_module/ast.ts | 4 +- .../typescript_module/declarations.ts | 0 .../typescript_module/explorer.ts | 0 .../introspector/typescript_module/index.ts | 3 + .../typescript_module/typedef_utils.ts | 2 +- .../module}/introspector/utils/files.ts | 0 .../registry => src/module}/registry.ts | 2 +- .../{ => src}/provisioning/.gitattributes | 0 sdk/typescript/{ => src}/provisioning/bin.ts | 2 +- .../{ => src}/provisioning/default.ts | 0 sdk/typescript/src/provisioning/engineconn.ts | 33 + sdk/typescript/src/provisioning/index.ts | 22 + sdk/typescript/{ => src}/telemetry/index.ts | 0 sdk/typescript/{ => src}/telemetry/init.ts | 0 .../{ => src}/telemetry/telemetry.ts | 0 sdk/typescript/{ => src}/telemetry/tracer.ts | 0 sdk/typescript/{ => src}/test/connect.spec.ts | 36 +- sdk/typescript/telemetry/attributes.ts | 0 sdk/typescript/tsconfig.json | 9 +- sdk/typescript/yarn.lock | 174 +- 145 files changed, 1953 insertions(+), 4712 deletions(-) delete mode 100644 sdk/typescript/context/builder.ts delete mode 100644 sdk/typescript/context/context.ts delete mode 100644 sdk/typescript/provisioning/engineconn.ts delete mode 100644 sdk/typescript/provisioning/index.ts rename sdk/typescript/{ => src}/api/.gitattributes (100%) rename sdk/typescript/{ => src}/api/client.gen.ts (66%) rename sdk/typescript/{ => src}/api/test/api.spec.ts (93%) create mode 100644 sdk/typescript/src/common/context.ts rename sdk/typescript/{ => src}/common/errors/DaggerSDKError.ts (100%) rename sdk/typescript/{ => src}/common/errors/DockerImageRefValidationError.ts (100%) rename sdk/typescript/{ => src}/common/errors/EngineSessionConnectParamsParseError.ts (100%) rename sdk/typescript/{ => src}/common/errors/EngineSessionConnectionTimeoutError.ts (100%) rename sdk/typescript/{ => src}/common/errors/EngineSessionErrorOptions.ts (100%) rename sdk/typescript/{ => src}/common/errors/ExecError.ts (100%) rename sdk/typescript/{ => src}/common/errors/FunctionNotFound.ts (100%) rename sdk/typescript/{ => src}/common/errors/GraphQLRequestError.ts (100%) rename sdk/typescript/{ => src}/common/errors/InitEngineSessionBinaryError.ts (100%) rename sdk/typescript/{ => src}/common/errors/IntrospectionError.ts (100%) rename sdk/typescript/{ => src}/common/errors/NotAwaitedRequestError.ts (100%) rename sdk/typescript/{ => src}/common/errors/TooManyNestedObjectsError.ts (100%) rename sdk/typescript/{ => src}/common/errors/UnknownDaggerError.ts (100%) rename sdk/typescript/{ => src}/common/errors/errors-codes.ts (100%) rename sdk/typescript/{ => src}/common/errors/index.ts (87%) rename sdk/typescript/{ => src/common}/graphql/client.ts (100%) rename sdk/typescript/{api/utils.ts => src/common/graphql/compute_query.ts} (94%) create mode 100644 sdk/typescript/src/common/graphql/connect.ts create mode 100644 sdk/typescript/src/common/graphql/connection.ts rename sdk/typescript/{ => src}/common/utils.ts (100%) rename sdk/typescript/{ => src}/connect.ts (59%) rename sdk/typescript/{ => src}/connectOpts.ts (100%) rename sdk/typescript/{ => src}/index.ts (51%) rename sdk/typescript/{introspector/decorators => src/module}/decorators.ts (97%) rename sdk/typescript/{ => src/module}/entrypoint/context.ts (62%) rename sdk/typescript/{ => src/module}/entrypoint/entrypoint.ts (72%) rename sdk/typescript/{ => src/module}/entrypoint/invoke.ts (76%) rename sdk/typescript/{ => src/module}/entrypoint/load.ts (90%) rename sdk/typescript/{ => src/module}/entrypoint/register.ts (92%) rename sdk/typescript/{introspector/executor => src/module}/executor.ts (91%) rename sdk/typescript/{introspector/scanner => src/module/introspector}/case_convertor.ts (100%) rename sdk/typescript/{introspector/scanner => src/module/introspector}/dagger_module/argument.ts (94%) rename sdk/typescript/{introspector/scanner => src/module/introspector}/dagger_module/constructor.ts (95%) rename sdk/typescript/{introspector/scanner => src/module/introspector}/dagger_module/decorator.ts (80%) rename sdk/typescript/{introspector/scanner => src/module/introspector}/dagger_module/enum.ts (93%) rename sdk/typescript/{introspector/scanner => src/module/introspector}/dagger_module/enumBase.ts (100%) rename sdk/typescript/{introspector/scanner => src/module/introspector}/dagger_module/enumClass.ts (88%) rename sdk/typescript/{introspector/scanner => src/module/introspector}/dagger_module/function.ts (94%) create mode 100644 sdk/typescript/src/module/introspector/dagger_module/index.ts rename sdk/typescript/{introspector/scanner => src/module/introspector}/dagger_module/module.ts (98%) rename sdk/typescript/{introspector/scanner => src/module/introspector}/dagger_module/object.ts (96%) rename sdk/typescript/{introspector/scanner => src/module/introspector}/dagger_module/objectBase.ts (100%) rename sdk/typescript/{introspector/scanner => src/module/introspector}/dagger_module/property.ts (94%) rename sdk/typescript/{introspector/scanner => src/module/introspector}/dagger_module/reference.ts (100%) rename sdk/typescript/{introspector/scanner => src/module/introspector}/dagger_module/typeObject.ts (93%) rename sdk/typescript/{introspector/scanner => src/module/introspector}/dagger_module/typeObjectProperty.ts (91%) rename sdk/typescript/{introspector/scanner/scan.ts => src/module/introspector/index.ts} (68%) rename sdk/typescript/{ => src/module}/introspector/test/case_convertor.spec.ts (94%) rename sdk/typescript/{ => src/module}/introspector/test/files.spec.ts (100%) rename sdk/typescript/{ => src/module}/introspector/test/invoke.spec.ts (87%) rename sdk/typescript/{ => src/module}/introspector/test/registry.spec.ts (97%) rename sdk/typescript/{ => src/module}/introspector/test/scan.spec.ts (97%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/alias/expected.json (100%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/alias/index.ts (88%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/constructor/expected.json (100%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/constructor/index.ts (79%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/context/expected.json (100%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/context/index.ts (70%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/coreEnums/expected.json (100%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/coreEnums/index.ts (67%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/enums/expected.json (100%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/enums/index.ts (83%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/generate_expected_scan.ts (91%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/helloWorld/expected.json (100%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/helloWorld/helloWorld.ts (69%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/helloWorld/toIgnore.md (100%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/invalid/expected.json (100%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/invalid/index.ts (100%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/list/expected.json (100%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/list/index.ts (85%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/minimal/expected.json (100%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/minimal/index.ts (70%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/multiArgs/expected.json (100%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/multiArgs/index.ts (74%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/multipleObjects/bar.ts (72%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/multipleObjects/expected.json (100%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/multipleObjects/foo.ts (80%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/multipleObjectsAsFields/expected.json (100%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/multipleObjectsAsFields/index.ts (76%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/multipleObjectsAsFields/lint.ts (56%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/multipleObjectsAsFields/test.ts (56%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/noDecorators/expected.json (100%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/noDecorators/noDecorators.ts (77%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/objectParam/expected.json (100%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/objectParam/index.ts (89%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/optionalParameter/expected.json (100%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/optionalParameter/index.ts (92%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/primitives/index.ts (76%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/privateMethod/expected.json (100%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/privateMethod/index.ts (85%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/references/expected.json (100%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/references/index.ts (92%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/references/types.ts (100%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/scalar/expected.json (100%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/scalar/index.ts (65%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/state/expected.json (100%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/state/state.ts (88%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/variadic/expected.json (100%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/variadic/index.ts (88%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/voidReturn/expected.json (100%) rename sdk/typescript/{ => src/module}/introspector/test/testdata/voidReturn/index.ts (79%) rename sdk/typescript/{introspector/scanner => src/module/introspector}/typedef.ts (100%) rename sdk/typescript/{introspector/scanner => src/module/introspector}/typescript_module/ast.ts (98%) rename sdk/typescript/{introspector/scanner => src/module/introspector}/typescript_module/declarations.ts (100%) rename sdk/typescript/{introspector/scanner => src/module/introspector}/typescript_module/explorer.ts (100%) create mode 100644 sdk/typescript/src/module/introspector/typescript_module/index.ts rename sdk/typescript/{introspector/scanner => src/module/introspector}/typescript_module/typedef_utils.ts (93%) rename sdk/typescript/{ => src/module}/introspector/utils/files.ts (100%) rename sdk/typescript/{introspector/registry => src/module}/registry.ts (98%) rename sdk/typescript/{ => src}/provisioning/.gitattributes (100%) rename sdk/typescript/{ => src}/provisioning/bin.ts (99%) rename sdk/typescript/{ => src}/provisioning/default.ts (100%) create mode 100644 sdk/typescript/src/provisioning/engineconn.ts create mode 100644 sdk/typescript/src/provisioning/index.ts rename sdk/typescript/{ => src}/telemetry/index.ts (100%) rename sdk/typescript/{ => src}/telemetry/init.ts (100%) rename sdk/typescript/{ => src}/telemetry/telemetry.ts (100%) rename sdk/typescript/{ => src}/telemetry/tracer.ts (100%) rename sdk/typescript/{ => src}/test/connect.spec.ts (88%) delete mode 100644 sdk/typescript/telemetry/attributes.ts diff --git a/.dagger/build/sdk.go b/.dagger/build/sdk.go index 38d5b6f4ca..b6ff934060 100644 --- a/.dagger/build/sdk.go +++ b/.dagger/build/sdk.go @@ -71,7 +71,7 @@ func (build *Builder) pythonSDKContent(ctx context.Context) (*sdkContent, error) func (build *Builder) typescriptSDKContent(ctx context.Context) (*sdkContent, error) { rootfs := dag.Directory().WithDirectory("/", build.source.Directory("sdk/typescript"), dagger.DirectoryWithDirectoryOpts{ Include: []string{ - "**/*.ts", + "src/**/*.ts", "LICENSE", "README.md", "runtime", @@ -79,13 +79,12 @@ func (build *Builder) typescriptSDKContent(ctx context.Context) (*sdkContent, er "dagger.json", }, Exclude: []string{ - "node_modules", - "dist", - "**/test", - "**/*.spec.ts", - "dev", + "src/**/test/*", + "src/**/*.spec.ts", + "src/provisioning", }, }) + sdkCtrTarball := dag.Container(). WithRootfs(rootfs). WithFile("/codegen", build.CodegenBinary()). diff --git a/.dagger/sdk_typescript.go b/.dagger/sdk_typescript.go index ef4bd9cd73..08df888656 100644 --- a/.dagger/sdk_typescript.go +++ b/.dagger/sdk_typescript.go @@ -19,7 +19,7 @@ import ( const ( typescriptRuntimeSubdir = "sdk/typescript/runtime" - typescriptGeneratedAPIPath = "sdk/typescript/api/client.gen.ts" + typescriptGeneratedAPIPath = "sdk/typescript/src/api/client.gen.ts" nodePreviousLTS = "20.18.1" nodeCurrentLTS = "22.11.0" @@ -243,7 +243,7 @@ func (t TypescriptSDK) Bump(ctx context.Context, version string) (*dagger.Direct // NOTE: if you change this path, be sure to update .github/workflows/publish.yml so that // provision tests run whenever this file changes. - return dag.Directory().WithNewFile("sdk/typescript/provisioning/default.ts", engineReference), nil + return dag.Directory().WithNewFile("sdk/typescript/src/provisioning/default.ts", engineReference), nil } func (t TypescriptSDK) nodeJsBase() *dagger.Container { diff --git a/cmd/codegen/generator/typescript/generator.go b/cmd/codegen/generator/typescript/generator.go index baddebc251..ed63f1c18b 100644 --- a/cmd/codegen/generator/typescript/generator.go +++ b/cmd/codegen/generator/typescript/generator.go @@ -63,7 +63,7 @@ func (g *TypeScriptGenerator) Generate(_ context.Context, schema *introspection. target := ClientGenFile if g.Config.ModuleName != "" { - target = filepath.Join(g.Config.ModuleContextPath, "sdk/api", ClientGenFile) + target = filepath.Join(g.Config.ModuleContextPath, "sdk/src/api", ClientGenFile) } if err := mfs.MkdirAll(filepath.Dir(target), 0700); err != nil { return nil, err diff --git a/cmd/codegen/generator/typescript/templates/src/default.ts.gtpl b/cmd/codegen/generator/typescript/templates/src/default.ts.gtpl index 7f813e5e92..2cee4a2ae5 100644 --- a/cmd/codegen/generator/typescript/templates/src/default.ts.gtpl +++ b/cmd/codegen/generator/typescript/templates/src/default.ts.gtpl @@ -1,5 +1,5 @@ {{ define "default" }} -export const dag = new Client({ ctx: defaultContext }) +export const dag = new Client() {{ "" }} {{- end }} diff --git a/cmd/codegen/generator/typescript/templates/src/header.ts.gtpl b/cmd/codegen/generator/typescript/templates/src/header.ts.gtpl index 4bdbc1b8aa..de3a5772e3 100644 --- a/cmd/codegen/generator/typescript/templates/src/header.ts.gtpl +++ b/cmd/codegen/generator/typescript/templates/src/header.ts.gtpl @@ -7,49 +7,13 @@ inherited by futures objects and common types. * This file was auto-generated by `client-gen`. * Do not make direct changes to the file. */ -import { Context, defaultContext } from "../context/context.js" -import { computeQuery } from "./utils.js" - -/** - * @hidden - */ -export type QueryTree = { - operation: string - args?: Record -} - -/** - * @hidden - */ -export type Metadata = { - [key: string]: { - is_enum?: boolean - } -} - -interface ClientConfig { - queryTree?: QueryTree[] - ctx?: Context -} - +import { Context } from "../common/context.js" class BaseClient { - protected _queryTree: QueryTree[] - protected _ctx: Context - /** * @hidden */ - constructor({ queryTree, ctx }: ClientConfig = {}) { - this._queryTree = queryTree || [] - this._ctx = ctx || new Context() - } - /** - * @hidden - */ - get queryTree() { - return this._queryTree - } + constructor(protected _ctx: Context = new Context()) {} } {{- end }} diff --git a/cmd/codegen/generator/typescript/templates/src/method.ts.gtpl b/cmd/codegen/generator/typescript/templates/src/method.ts.gtpl index 4092f31095..34c750c575 100644 --- a/cmd/codegen/generator/typescript/templates/src/method.ts.gtpl +++ b/cmd/codegen/generator/typescript/templates/src/method.ts.gtpl @@ -31,7 +31,7 @@ {{- $enums := GetEnumValues .Args }} {{- if gt (len $enums) 0 }} - const metadata: Metadata = { + const metadata = { {{- range $v := $enums }} {{ $v.Name | FormatName -}}: { is_enum: true }, {{- end }} @@ -39,31 +39,25 @@ {{ "" -}} {{- end }} - {{- if .TypeRef }} - return new {{ .TypeRef | FormatOutputType }}({ - queryTree: [ - ...this._queryTree, - { - operation: "{{ .Name }}", - - {{- /* Insert arguments. */ -}} - {{- if or $required $optionals }} - args: { {{""}} + const ctx = this._ctx.select( + "{{ .Name }}", +{{- if or $required $optionals }} + { {{""}} {{- with $required }} {{- template "call_args" $required }} {{- end }} {{- with $optionals }} {{- if $required }}, {{ end -}} - ...opts + ...opts {{- end -}} {{- if gt (len $enums) 0 -}}, __metadata: metadata{{- end -}} -{{""}} }, - {{- end }} - }, - ], - ctx: this._ctx, - }) +{{""}} }, + {{- end }} + ) + + {{- if .TypeRef }} + return new {{ .TypeRef | FormatOutputType }}(ctx) {{- end }} } {{- end }} diff --git a/cmd/codegen/generator/typescript/templates/src/method_solve.ts.gtpl b/cmd/codegen/generator/typescript/templates/src/method_solve.ts.gtpl index 839c1be2e0..2cb1fd8968 100644 --- a/cmd/codegen/generator/typescript/templates/src/method_solve.ts.gtpl +++ b/cmd/codegen/generator/typescript/templates/src/method_solve.ts.gtpl @@ -56,7 +56,7 @@ {{- $enums := GetEnumValues .Args }} {{- if gt (len $enums) 0 }} - const metadata: Metadata = { + const metadata = { {{- range $v := $enums }} {{ $v.Name | FormatName -}}: { is_enum: true }, {{- end }} @@ -66,15 +66,11 @@ {{- end }} {{- if .TypeRef }} - {{ if not .TypeRef.IsVoid }}const response: Awaited<{{ if $convertID }}{{ .TypeRef | FormatOutputType }}{{ else }}{{ $promiseRetType }}{{ end }}> = {{ end }}await computeQuery( - [ - ...this._queryTree, - { - operation: "{{ .Name }}", - - {{- /* Insert arguments. */ -}} + const ctx = this._ctx.select( + "{{ .Name }}", + {{- /* Insert arguments. */ -}} {{- if or $required $optionals }} - args: { {{""}} + { {{""}} {{- with $required }} {{- template "call_args" $required }} {{- end }} @@ -84,42 +80,36 @@ {{- "" }}...opts {{- end }} {{- if gt (len $enums) 0 -}}, __metadata: metadata{{- end -}} -{{- "" }} }, +{{- "" }}}, {{- end }} - }, - {{- /* Add subfields */ -}} - {{- if and .TypeRef.IsList (IsListOfObject .TypeRef) }} - { - operation: "{{- range $i, $v := . | GetArrayField }}{{if $i }} {{ end }}{{ $v.Name | ToLowerCase }}{{- end }}" - }, - {{- end }} - ], - await this._ctx.connection() - ) + ){{- /* Add subfields */ -}} + {{- if and .TypeRef.IsList (IsListOfObject .TypeRef) }}.select("{{- range $i, $v := . | GetArrayField }}{{if $i }} {{ end }}{{ $v.Name | ToLowerCase }}{{- end }}") + {{- end }} + + {{ if not .TypeRef.IsVoid }}const response: Awaited<{{ if $convertID }}{{ .TypeRef | FormatOutputType }}{{ else }}{{ $promiseRetType }}{{ end }}> = {{ end }}await ctx.execute() {{ if $convertID -}} - return new {{ $promiseRetType }}({ - queryTree: [ + return new {{ $promiseRetType }}(new Context( + [ { operation: "load{{ $promiseRetType }}FromID", args: { id: response }, }, ], - ctx: this._ctx, - }) + this._ctx.getConnection(), + )) {{- else if not .TypeRef.IsVoid -}} {{- if and .TypeRef.IsList (IsListOfObject .TypeRef) }} return response.map( - (r) => new {{ . | FormatReturnType | ToSingleType }}( - { - queryTree: [ + (r) => new {{ . | FormatReturnType | ToSingleType }}(new Context( + [ { operation: "load{{. | FormatReturnType | ToSingleType}}FromID", args: { id: r.id } } ], - ctx: this._ctx - }, + this._ctx.getConnection() + ), {{- range $v := . | GetArrayField }} r.{{ $v.Name | ToLowerCase }}, {{- end }} diff --git a/cmd/codegen/generator/typescript/templates/src/object.ts.gtpl b/cmd/codegen/generator/typescript/templates/src/object.ts.gtpl index 9c2e23ebb0..4ea01586d5 100644 --- a/cmd/codegen/generator/typescript/templates/src/object.ts.gtpl +++ b/cmd/codegen/generator/typescript/templates/src/object.ts.gtpl @@ -31,14 +31,14 @@ export class {{ .Name | QueryToClient | FormatName }} extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[], ctx: Context }, + ctx?: Context, {{- range $i, $field := .Fields }} {{- if $field.TypeRef.IsScalar }} _{{ $field.Name }}?: {{ $field.TypeRef | FormatOutputType }}, {{- end }} {{- end }} ) { - super(parent) + super(ctx) {{ "" }} {{- range $i, $field := .Fields }} {{- if $field.TypeRef.IsScalar }} diff --git a/core/integration/module_test.go b/core/integration/module_test.go index f62ef4e23a..30845e9265 100644 --- a/core/integration/module_test.go +++ b/core/integration/module_test.go @@ -5559,7 +5559,7 @@ func sdkCodegenFile(t *testctx.T, sdk string) string { case "python": return "sdk/src/dagger/client/gen.py" case "typescript": - return "sdk/api/client.gen.ts" + return "sdk/src/api/client.gen.ts" default: panic(fmt.Errorf("unknown sdk %q", sdk)) } diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts index 37edaec248..ed112c5d8b 100644 --- a/docs/docusaurus.config.ts +++ b/docs/docusaurus.config.ts @@ -82,9 +82,9 @@ const config: Config = { id: "current-generation", plugin: ["typedoc-plugin-markdown", "typedoc-plugin-frontmatter"], entryPoints: [ - "../sdk/typescript/connect.ts", - "../sdk/typescript/api/client.gen.ts", - "../sdk/typescript/common/errors/index.ts", + "../sdk/typescript/src/connect.ts", + "../sdk/typescript/src/api/client.gen.ts", + "../sdk/typescript/src/common/errors/index.ts", ], tsconfig: "../sdk/typescript/tsconfig.json", out: "current_docs/reference/typescript/", diff --git a/sdk/typescript/context/builder.ts b/sdk/typescript/context/builder.ts deleted file mode 100644 index 08fb9001c2..0000000000 --- a/sdk/typescript/context/builder.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { ConnectOpts } from "../connectOpts.js" -import { createGQLClient } from "../graphql/client.js" -import { Bin, CLI_VERSION } from "../provisioning/index.js" -import { Context } from "./context.js" - -/** - * @hidden - * - * Initialize a default client context from environment. - */ -export async function initDefaultContext( - cfg: ConnectOpts = {}, -): Promise { - let ctx = new Context() - - // Prefer DAGGER_SESSION_PORT if set - const daggerSessionPort = process.env["DAGGER_SESSION_PORT"] - if (daggerSessionPort) { - const sessionToken = process.env["DAGGER_SESSION_TOKEN"] - if (!sessionToken) { - throw new Error( - "DAGGER_SESSION_TOKEN must be set when using DAGGER_SESSION_PORT", - ) - } - - if (cfg.Workdir && cfg.Workdir !== "") { - throw new Error( - "cannot configure workdir for existing session (please use --workdir or host.directory with absolute paths instead)", - ) - } - - ctx = new Context({ - client: createGQLClient(Number(daggerSessionPort), sessionToken), - }) - } else { - // Otherwise, prefer _EXPERIMENTAL_DAGGER_CLI_BIN, with fallback behavior of - // downloading the CLI and using that as the bin. - const cliBin = process.env["_EXPERIMENTAL_DAGGER_CLI_BIN"] - const engineConn = new Bin(cliBin, CLI_VERSION) - const client = await engineConn.Connect(cfg) - - ctx = new Context({ client, subProcess: engineConn.subProcess }) - } - - return ctx -} diff --git a/sdk/typescript/context/context.ts b/sdk/typescript/context/context.ts deleted file mode 100644 index 6d783e9925..0000000000 --- a/sdk/typescript/context/context.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { GraphQLClient } from "graphql-request" - -import { ConnectOpts } from "../connectOpts.js" -import { ExecaChildProcess } from "../provisioning/bin.js" -import { initDefaultContext } from "./builder.js" - -interface ContextConfig { - client?: GraphQLClient - subProcess?: ExecaChildProcess -} - -/** - * Context abstracts the connection to the engine. - * - * It's required to implement the default global SDK. - * Its purpose is to store and returns the connection to the graphQL API, if - * no connection is set, it can create its own. - * - * This is also useful for lazy evaluation with the default global client, - * this one should only run the engine if it actually executes something. - */ -export class Context { - private _client?: GraphQLClient - private _subProcess?: ExecaChildProcess - - constructor(config?: ContextConfig) { - this._client = config?.client - this._subProcess = config?.subProcess - } - - /** - * Returns a GraphQL client connected to the engine. - * - * If no client is set, it will create one. - */ - public async connection(cfg: ConnectOpts = {}): Promise { - if (!this._client) { - const defaultCtx = await initDefaultContext(cfg) - this._client = defaultCtx._client as GraphQLClient - this._subProcess = defaultCtx._subProcess - } - - return this._client - } - - public getGQLClient(): GraphQLClient { - if (!this._client) { - throw new Error( - "graphQL connection not established yet, please use it inside a connect or connection function.", - ) - } - - return this._client - } - - /** - * Close the connection and the engine if this one was started by the node - * SDK. - */ - public close(): void { - if (this._subProcess) { - this._subProcess.kill("SIGTERM") - } - - // Reset client, so it can restart a new connection if necessary - this._client = undefined - } -} - -/** - * Expose a default context for the global client - */ -export const defaultContext = new Context() diff --git a/sdk/typescript/dev/src/index.ts b/sdk/typescript/dev/src/index.ts index b621458046..891b217b25 100644 --- a/sdk/typescript/dev/src/index.ts +++ b/sdk/typescript/dev/src/index.ts @@ -1,10 +1,4 @@ -import { - dag, - Container, - object, - func, - Directory, -} from "@dagger.io/dagger" +import { dag, Container, object, func, Directory } from "@dagger.io/dagger" @object() class TypescriptSdkDev { @@ -26,7 +20,7 @@ class TypescriptSdkDev { // Get source without generated files nor useless files. const sourceCode = dag.directory().withDirectory("/", source, { include: [ - "**/*.ts", + "src/**/*.ts", "tsconfig.json", "package.json", "yarn.lock", @@ -34,7 +28,6 @@ class TypescriptSdkDev { "eslint.config.js", ".prettierrc.cjs", ], - exclude: ["node_modules", "dist", "dev"], }) // Install dependencies and add source code. diff --git a/sdk/typescript/package.json b/sdk/typescript/package.json index a84ddcd9c2..611e8438f1 100644 --- a/sdk/typescript/package.json +++ b/sdk/typescript/package.json @@ -9,13 +9,13 @@ "dist/" ], "exports": { - ".": "./dist/index.js", - "./telemetry": "./dist/telemetry/index.js" + ".": "./dist/src/index.js", + "./telemetry": "./dist/src/telemetry/index.js" }, "engines": { "node": ">=18" }, - "main": "dist/index.js", + "main": "dist/src/index.js", "dependencies": { "@grpc/grpc-js": "^1.11.1", "@lifeomic/axios-fetch": "^3.1.0", @@ -63,6 +63,7 @@ "mocha": "^10.7.0", "prettier": "^3.3.3", "ts-node": "^10.9.2", + "tsx": "^4.19.2", "typescript-eslint": "^8.0.1" } } diff --git a/sdk/typescript/provisioning/engineconn.ts b/sdk/typescript/provisioning/engineconn.ts deleted file mode 100644 index f44729f58f..0000000000 --- a/sdk/typescript/provisioning/engineconn.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { GraphQLClient } from "graphql-request" -import { Writable } from "node:stream" - -export interface ConnectOpts { - Workdir?: string - Project?: string - LogOutput?: Writable - Timeout?: number -} - -export interface ConnectParams { - port: number - session_token: string -} - -export interface EngineConn { - /** - * Addr returns the connector address. - */ - Addr: () => string - - /** - * Connect initializes a ready to use GraphQL Client that - * points to the engine. - */ - Connect: (opts: ConnectOpts) => Promise - - /** - * Close stops the current connection. - */ - Close: () => Promise -} diff --git a/sdk/typescript/provisioning/index.ts b/sdk/typescript/provisioning/index.ts deleted file mode 100644 index 5b031e4263..0000000000 --- a/sdk/typescript/provisioning/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from "./default.js" -export * from "./engineconn.js" -export * from "./bin.js" diff --git a/sdk/typescript/runtime/bin/__dagger.entrypoint.ts b/sdk/typescript/runtime/bin/__dagger.entrypoint.ts index a7f1570192..ba32ffed25 100644 --- a/sdk/typescript/runtime/bin/__dagger.entrypoint.ts +++ b/sdk/typescript/runtime/bin/__dagger.entrypoint.ts @@ -1,4 +1,34 @@ // THIS FILE IS AUTO GENERATED. PLEASE DO NOT EDIT. import { entrypoint } from "@dagger.io/dagger" +import * as fs from "fs" +import * as path from "path" -entrypoint() +const allowedExtensions = [".ts", ".mts"] + +function listTsFilesInModule(dir = import.meta.dirname): string[] { + const res = fs.readdirSync(dir).map((file) => { + const filepath = path.join(dir, file) + + const stat = fs.statSync(filepath) + + if (stat.isDirectory()) { + return listTsFilesInModule(filepath) + } + + const ext = path.extname(filepath) + if (allowedExtensions.find((allowedExt) => allowedExt === ext)) { + return [path.join(dir, file)] + } + + return [] + }) + + return res.reduce( + (p, c) => [...c, ...p], + [`${import.meta.dirname}/../sdk/src/api/client.gen.ts`], + ) +} + +const files = listTsFilesInModule() + +entrypoint(files) diff --git a/sdk/typescript/runtime/bin/__tsconfig.updator.ts b/sdk/typescript/runtime/bin/__tsconfig.updator.ts index 02032c0c3b..78d28644a3 100644 --- a/sdk/typescript/runtime/bin/__tsconfig.updator.ts +++ b/sdk/typescript/runtime/bin/__tsconfig.updator.ts @@ -4,8 +4,8 @@ const tsConfigPath = `./tsconfig.json` const daggerPathAlias = "@dagger.io/dagger" const daggerTelemetryPathAlias = "@dagger.io/dagger/telemetry" -const daggerPath = "./sdk" -const daggerTelemetryPath = "./sdk/telemetry" +const daggerPath = "./sdk/src" +const daggerTelemetryPath = "./sdk/src/telemetry" // If the tsconfig.json file doesn't exist, create it with default config. if (!fs.existsSync(tsConfigPath)) { @@ -15,8 +15,8 @@ if (!fs.existsSync(tsConfigPath)) { moduleResolution: "Node", experimentalDecorators: true, paths: { - "@dagger.io/dagger": ["./sdk"], - "@dagger.io/dagger/telemetry": ["./sdk/telemetry"], + "@dagger.io/dagger": ["./sdk/src"], + "@dagger.io/dagger/telemetry": ["./sdk/src/telemetry"], }, }, } diff --git a/sdk/typescript/runtime/template/tsconfig.json b/sdk/typescript/runtime/template/tsconfig.json index 0a338a54b1..21099eef99 100644 --- a/sdk/typescript/runtime/template/tsconfig.json +++ b/sdk/typescript/runtime/template/tsconfig.json @@ -4,8 +4,8 @@ "moduleResolution": "Node", "experimentalDecorators": true, "paths": { - "@dagger.io/dagger": ["./sdk"], - "@dagger.io/dagger/telemetry": ["./sdk/telemetry"] + "@dagger.io/dagger": ["./sdk/src"], + "@dagger.io/dagger/telemetry": ["./sdk/src/telemetry"] } } } diff --git a/sdk/typescript/api/.gitattributes b/sdk/typescript/src/api/.gitattributes similarity index 100% rename from sdk/typescript/api/.gitattributes rename to sdk/typescript/src/api/.gitattributes diff --git a/sdk/typescript/api/client.gen.ts b/sdk/typescript/src/api/client.gen.ts similarity index 66% rename from sdk/typescript/api/client.gen.ts rename to sdk/typescript/src/api/client.gen.ts index 3945149d8e..cb5ac9d48f 100644 --- a/sdk/typescript/api/client.gen.ts +++ b/sdk/typescript/src/api/client.gen.ts @@ -2,49 +2,14 @@ * This file was auto-generated by `client-gen`. * Do not make direct changes to the file. */ -import { Context, defaultContext } from "../context/context.js" -import { computeQuery } from "./utils.js" - -/** - * @hidden - */ -export type QueryTree = { - operation: string - args?: Record -} - -/** - * @hidden - */ -export type Metadata = { - [key: string]: { - is_enum?: boolean - } -} - -interface ClientConfig { - queryTree?: QueryTree[] - ctx?: Context -} +import { Context } from "../common/context.js" class BaseClient { - protected _queryTree: QueryTree[] - protected _ctx: Context - /** * @hidden */ - constructor({ queryTree, ctx }: ClientConfig = {}) { - this._queryTree = queryTree || [] - this._ctx = ctx || new Context() - } - /** - * @hidden - */ - get queryTree() { - return this._queryTree - } + constructor(protected _ctx: Context = new Context()) {} } export type BuildArg = { @@ -1425,11 +1390,8 @@ export class CacheVolume extends BaseClient { /** * Constructor is used for internal usage only, do not create object from it. */ - constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, - _id?: CacheVolumeID, - ) { - super(parent) + constructor(ctx?: Context, _id?: CacheVolumeID) { + super(ctx) this._id = _id } @@ -1442,15 +1404,9 @@ export class CacheVolume extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -1479,7 +1435,7 @@ export class Container extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, + ctx?: Context, _id?: ContainerID, _envVariable?: string, _exitCode?: number, @@ -1495,7 +1451,7 @@ export class Container extends BaseClient { _user?: string, _workdir?: string, ) { - super(parent) + super(ctx) this._id = _id this._envVariable = _envVariable @@ -1521,15 +1477,9 @@ export class Container extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -1552,16 +1502,8 @@ export class Container extends BaseClient { * This should only be used if the user requires that their exec process be the pid 1 process in the container. Otherwise it may result in unexpected behavior. */ asService = (opts?: ContainerAsServiceOpts): Service => { - return new Service({ - queryTree: [ - ...this._queryTree, - { - operation: "asService", - args: { ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("asService", { ...opts }) + return new Service(ctx) } /** @@ -1577,21 +1519,13 @@ export class Container extends BaseClient { * Defaults to OCI, which is largely compatible with most recent container runtimes, but Docker may be needed for older runtimes without OCI support. */ asTarball = (opts?: ContainerAsTarballOpts): File => { - const metadata: Metadata = { + const metadata = { forcedCompression: { is_enum: true }, mediaTypes: { is_enum: true }, } - return new File({ - queryTree: [ - ...this._queryTree, - { - operation: "asTarball", - args: { ...opts, __metadata: metadata }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("asTarball", { ...opts, __metadata: metadata }) + return new File(ctx) } /** @@ -1607,31 +1541,17 @@ export class Container extends BaseClient { * They can be accessed in the Dockerfile using the "secret" mount type and mount path /run/secrets/[secret-name], e.g. RUN --mount=type=secret,id=my-secret curl [http://example.com?token=$(cat /run/secrets/my-secret)](http://example.com?token=$(cat /run/secrets/my-secret)) */ build = (context: Directory, opts?: ContainerBuildOpts): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "build", - args: { context, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("build", { context, ...opts }) + return new Container(ctx) } /** * Retrieves default arguments for future commands. */ defaultArgs = async (): Promise => { - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "defaultArgs", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("defaultArgs") + + const response: Awaited = await ctx.execute() return response } @@ -1644,31 +1564,17 @@ export class Container extends BaseClient { * @param opts.expand Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). */ directory = (path: string, opts?: ContainerDirectoryOpts): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "directory", - args: { path, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("directory", { path, ...opts }) + return new Directory(ctx) } /** * Retrieves entrypoint to be prepended to the arguments of all commands. */ entrypoint = async (): Promise => { - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "entrypoint", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("entrypoint") + + const response: Awaited = await ctx.execute() return response } @@ -1682,16 +1588,9 @@ export class Container extends BaseClient { return this._envVariable } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "envVariable", - args: { name }, - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("envVariable", { name }) + + const response: Awaited = await ctx.execute() return response } @@ -1704,31 +1603,22 @@ export class Container extends BaseClient { id: EnvVariableID } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "envVariables", - }, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("envVariables").select("id") + + const response: Awaited = await ctx.execute() return response.map( (r) => new EnvVariable( - { - queryTree: [ + new Context( + [ { operation: "loadEnvVariableFromID", args: { id: r.id }, }, ], - ctx: this._ctx, - }, + this._ctx.getConnection(), + ), r.id, ), ) @@ -1744,15 +1634,9 @@ export class Container extends BaseClient { return this._exitCode } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "exitCode", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("exitCode") + + const response: Awaited = await ctx.execute() return response } @@ -1765,15 +1649,8 @@ export class Container extends BaseClient { * This currently works for Nvidia devices only. */ experimentalWithAllGPUs = (): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "experimentalWithAllGPUs", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("experimentalWithAllGPUs") + return new Container(ctx) } /** @@ -1785,16 +1662,8 @@ export class Container extends BaseClient { * @param devices List of devices to be accessible to this container. */ experimentalWithGPU = (devices: string[]): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "experimentalWithGPU", - args: { devices }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("experimentalWithGPU", { devices }) + return new Container(ctx) } /** @@ -1823,21 +1692,18 @@ export class Container extends BaseClient { return this._export } - const metadata: Metadata = { + const metadata = { forcedCompression: { is_enum: true }, mediaTypes: { is_enum: true }, } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "export", - args: { path, ...opts, __metadata: metadata }, - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("export", { + path, + ...opts, + __metadata: metadata, + }) + + const response: Awaited = await ctx.execute() return response } @@ -1852,31 +1718,22 @@ export class Container extends BaseClient { id: PortID } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "exposedPorts", - }, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("exposedPorts").select("id") + + const response: Awaited = await ctx.execute() return response.map( (r) => new Port( - { - queryTree: [ + new Context( + [ { operation: "loadPortFromID", args: { id: r.id }, }, ], - ctx: this._ctx, - }, + this._ctx.getConnection(), + ), r.id, ), ) @@ -1890,16 +1747,8 @@ export class Container extends BaseClient { * @param opts.expand Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo.txt"). */ file = (path: string, opts?: ContainerFileOpts): File => { - return new File({ - queryTree: [ - ...this._queryTree, - { - operation: "file", - args: { path, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("file", { path, ...opts }) + return new File(ctx) } /** @@ -1909,16 +1758,8 @@ export class Container extends BaseClient { * Formatted as [host]/[user]/[repo]:[tag] (e.g., "docker.io/dagger/dagger:main"). */ from = (address: string): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "from", - args: { address }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("from", { address }) + return new Container(ctx) } /** @@ -1929,15 +1770,9 @@ export class Container extends BaseClient { return this._imageRef } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "imageRef", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("imageRef") + + const response: Awaited = await ctx.execute() return response } @@ -1948,16 +1783,8 @@ export class Container extends BaseClient { * @param opts.tag Identifies the tag to import from the archive, if the archive bundles multiple tags. */ import_ = (source: File, opts?: ContainerImportOpts): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "import", - args: { source, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("import", { source, ...opts }) + return new Container(ctx) } /** @@ -1969,16 +1796,9 @@ export class Container extends BaseClient { return this._label } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "label", - args: { name }, - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("label", { name }) + + const response: Awaited = await ctx.execute() return response } @@ -1991,31 +1811,22 @@ export class Container extends BaseClient { id: LabelID } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "labels", - }, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("labels").select("id") + + const response: Awaited = await ctx.execute() return response.map( (r) => new Label( - { - queryTree: [ + new Context( + [ { operation: "loadLabelFromID", args: { id: r.id }, }, ], - ctx: this._ctx, - }, + this._ctx.getConnection(), + ), r.id, ), ) @@ -2025,15 +1836,9 @@ export class Container extends BaseClient { * Retrieves the list of paths where a directory is mounted. */ mounts = async (): Promise => { - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "mounts", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("mounts") + + const response: Awaited = await ctx.execute() return response } @@ -2046,15 +1851,9 @@ export class Container extends BaseClient { return this._platform } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "platform", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("platform") + + const response: Awaited = await ctx.execute() return response } @@ -2086,21 +1885,18 @@ export class Container extends BaseClient { return this._publish } - const metadata: Metadata = { + const metadata = { forcedCompression: { is_enum: true }, mediaTypes: { is_enum: true }, } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "publish", - args: { address, ...opts, __metadata: metadata }, - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("publish", { + address, + ...opts, + __metadata: metadata, + }) + + const response: Awaited = await ctx.execute() return response } @@ -2109,15 +1905,8 @@ export class Container extends BaseClient { * Retrieves this container's root filesystem. Mounts are not included. */ rootfs = (): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "rootfs", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("rootfs") + return new Directory(ctx) } /** @@ -2130,15 +1919,9 @@ export class Container extends BaseClient { return this._stderr } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "stderr", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("stderr") + + const response: Awaited = await ctx.execute() return response } @@ -2153,15 +1936,9 @@ export class Container extends BaseClient { return this._stdout } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "stdout", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("stdout") + + const response: Awaited = await ctx.execute() return response } @@ -2172,25 +1949,21 @@ export class Container extends BaseClient { * It doesn't run the default command if no exec has been set. */ sync = async (): Promise => { - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "sync", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("sync") - return new Container({ - queryTree: [ - { - operation: "loadContainerFromID", - args: { id: response }, - }, - ], - ctx: this._ctx, - }) + const response: Awaited = await ctx.execute() + + return new Container( + new Context( + [ + { + operation: "loadContainerFromID", + args: { id: response }, + }, + ], + this._ctx.getConnection(), + ), + ) } /** @@ -2202,16 +1975,8 @@ export class Container extends BaseClient { * @param opts.insecureRootCapabilities Execute the command with all root capabilities. This is similar to running a command with "sudo" or executing "docker run" with the "--privileged" flag. Containerization does not provide any security guarantees when using this option. It should only be used when absolutely necessary and only with trusted commands. */ terminal = (opts?: ContainerTerminalOpts): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "terminal", - args: { ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("terminal", { ...opts }) + return new Container(ctx) } /** @@ -2228,16 +1993,9 @@ export class Container extends BaseClient { return } - await computeQuery( - [ - ...this._queryTree, - { - operation: "up", - args: { ...opts }, - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("up", { ...opts }) + + await ctx.execute() } /** @@ -2248,15 +2006,9 @@ export class Container extends BaseClient { return this._user } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "user", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("user") + + const response: Awaited = await ctx.execute() return response } @@ -2267,16 +2019,8 @@ export class Container extends BaseClient { * @param value The value of the annotation. */ withAnnotation = (name: string, value: string): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withAnnotation", - args: { name, value }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withAnnotation", { name, value }) + return new Container(ctx) } /** @@ -2284,16 +2028,8 @@ export class Container extends BaseClient { * @param args Arguments to prepend to future executions (e.g., ["-v", "--no-cache"]). */ withDefaultArgs = (args: string[]): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withDefaultArgs", - args: { args }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withDefaultArgs", { args }) + return new Container(ctx) } /** @@ -2308,16 +2044,8 @@ export class Container extends BaseClient { args: string[], opts?: ContainerWithDefaultTerminalCmdOpts, ): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withDefaultTerminalCmd", - args: { args, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withDefaultTerminalCmd", { args, ...opts }) + return new Container(ctx) } /** @@ -2338,16 +2066,8 @@ export class Container extends BaseClient { directory: Directory, opts?: ContainerWithDirectoryOpts, ): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withDirectory", - args: { path, directory, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withDirectory", { path, directory, ...opts }) + return new Container(ctx) } /** @@ -2359,16 +2079,8 @@ export class Container extends BaseClient { args: string[], opts?: ContainerWithEntrypointOpts, ): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withEntrypoint", - args: { args, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withEntrypoint", { args, ...opts }) + return new Container(ctx) } /** @@ -2382,16 +2094,8 @@ export class Container extends BaseClient { value: string, opts?: ContainerWithEnvVariableOpts, ): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withEnvVariable", - args: { name, value, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withEnvVariable", { name, value, ...opts }) + return new Container(ctx) } /** @@ -2414,20 +2118,16 @@ export class Container extends BaseClient { * This should only be used if the user requires that their exec process be the pid 1 process in the container. Otherwise it may result in unexpected behavior. */ withExec = (args: string[], opts?: ContainerWithExecOpts): Container => { - const metadata: Metadata = { + const metadata = { expect: { is_enum: true }, } - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withExec", - args: { args, ...opts, __metadata: metadata }, - }, - ], - ctx: this._ctx, + const ctx = this._ctx.select("withExec", { + args, + ...opts, + __metadata: metadata, }) + return new Container(ctx) } /** @@ -2447,20 +2147,16 @@ export class Container extends BaseClient { port: number, opts?: ContainerWithExposedPortOpts, ): Container => { - const metadata: Metadata = { + const metadata = { protocol: { is_enum: true }, } - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withExposedPort", - args: { port, ...opts, __metadata: metadata }, - }, - ], - ctx: this._ctx, + const ctx = this._ctx.select("withExposedPort", { + port, + ...opts, + __metadata: metadata, }) + return new Container(ctx) } /** @@ -2480,16 +2176,8 @@ export class Container extends BaseClient { source: File, opts?: ContainerWithFileOpts, ): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withFile", - args: { path, source, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withFile", { path, source, ...opts }) + return new Container(ctx) } /** @@ -2509,16 +2197,8 @@ export class Container extends BaseClient { sources: File[], opts?: ContainerWithFilesOpts, ): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withFiles", - args: { path, sources, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withFiles", { path, sources, ...opts }) + return new Container(ctx) } /** @@ -2527,16 +2207,8 @@ export class Container extends BaseClient { * @param value The value of the label (e.g., "2023-01-01T00:00:00Z"). */ withLabel = (name: string, value: string): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withLabel", - args: { name, value }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withLabel", { name, value }) + return new Container(ctx) } /** @@ -2559,20 +2231,17 @@ export class Container extends BaseClient { cache: CacheVolume, opts?: ContainerWithMountedCacheOpts, ): Container => { - const metadata: Metadata = { + const metadata = { sharing: { is_enum: true }, } - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withMountedCache", - args: { path, cache, ...opts, __metadata: metadata }, - }, - ], - ctx: this._ctx, + const ctx = this._ctx.select("withMountedCache", { + path, + cache, + ...opts, + __metadata: metadata, }) + return new Container(ctx) } /** @@ -2591,16 +2260,12 @@ export class Container extends BaseClient { source: Directory, opts?: ContainerWithMountedDirectoryOpts, ): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withMountedDirectory", - args: { path, source, ...opts }, - }, - ], - ctx: this._ctx, + const ctx = this._ctx.select("withMountedDirectory", { + path, + source, + ...opts, }) + return new Container(ctx) } /** @@ -2619,16 +2284,8 @@ export class Container extends BaseClient { source: File, opts?: ContainerWithMountedFileOpts, ): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withMountedFile", - args: { path, source, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withMountedFile", { path, source, ...opts }) + return new Container(ctx) } /** @@ -2650,16 +2307,8 @@ export class Container extends BaseClient { source: Secret, opts?: ContainerWithMountedSecretOpts, ): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withMountedSecret", - args: { path, source, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withMountedSecret", { path, source, ...opts }) + return new Container(ctx) } /** @@ -2672,16 +2321,8 @@ export class Container extends BaseClient { path: string, opts?: ContainerWithMountedTempOpts, ): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withMountedTemp", - args: { path, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withMountedTemp", { path, ...opts }) + return new Container(ctx) } /** @@ -2701,16 +2342,8 @@ export class Container extends BaseClient { contents: string, opts?: ContainerWithNewFileOpts, ): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withNewFile", - args: { path, contents, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withNewFile", { path, contents, ...opts }) + return new Container(ctx) } /** @@ -2726,16 +2359,12 @@ export class Container extends BaseClient { username: string, secret: Secret, ): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withRegistryAuth", - args: { address, username, secret }, - }, - ], - ctx: this._ctx, + const ctx = this._ctx.select("withRegistryAuth", { + address, + username, + secret, }) + return new Container(ctx) } /** @@ -2743,16 +2372,8 @@ export class Container extends BaseClient { * @param directory Directory to mount. */ withRootfs = (directory: Directory): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withRootfs", - args: { directory }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withRootfs", { directory }) + return new Container(ctx) } /** @@ -2761,16 +2382,8 @@ export class Container extends BaseClient { * @param secret The identifier of the secret value. */ withSecretVariable = (name: string, secret: Secret): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withSecretVariable", - args: { name, secret }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withSecretVariable", { name, secret }) + return new Container(ctx) } /** @@ -2785,16 +2398,8 @@ export class Container extends BaseClient { * @param service Identifier of the service container */ withServiceBinding = (alias: string, service: Service): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withServiceBinding", - args: { alias, service }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withServiceBinding", { alias, service }) + return new Container(ctx) } /** @@ -2813,16 +2418,8 @@ export class Container extends BaseClient { source: Socket, opts?: ContainerWithUnixSocketOpts, ): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withUnixSocket", - args: { path, source, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withUnixSocket", { path, source, ...opts }) + return new Container(ctx) } /** @@ -2830,16 +2427,8 @@ export class Container extends BaseClient { * @param name The user to set (e.g., "root"). */ withUser = (name: string): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withUser", - args: { name }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withUser", { name }) + return new Container(ctx) } /** @@ -2848,16 +2437,8 @@ export class Container extends BaseClient { * @param opts.expand Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo"). */ withWorkdir = (path: string, opts?: ContainerWithWorkdirOpts): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withWorkdir", - args: { path, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withWorkdir", { path, ...opts }) + return new Container(ctx) } /** @@ -2865,31 +2446,16 @@ export class Container extends BaseClient { * @param name The name of the annotation. */ withoutAnnotation = (name: string): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withoutAnnotation", - args: { name }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withoutAnnotation", { name }) + return new Container(ctx) } /** * Retrieves this container with unset default arguments for future commands. */ withoutDefaultArgs = (): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withoutDefaultArgs", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withoutDefaultArgs") + return new Container(ctx) } /** @@ -2901,16 +2467,8 @@ export class Container extends BaseClient { path: string, opts?: ContainerWithoutDirectoryOpts, ): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withoutDirectory", - args: { path, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withoutDirectory", { path, ...opts }) + return new Container(ctx) } /** @@ -2918,16 +2476,8 @@ export class Container extends BaseClient { * @param opts.keepDefaultArgs Don't remove the default arguments when unsetting the entrypoint. */ withoutEntrypoint = (opts?: ContainerWithoutEntrypointOpts): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withoutEntrypoint", - args: { ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withoutEntrypoint", { ...opts }) + return new Container(ctx) } /** @@ -2935,16 +2485,8 @@ export class Container extends BaseClient { * @param name The name of the environment variable (e.g., "HOST"). */ withoutEnvVariable = (name: string): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withoutEnvVariable", - args: { name }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withoutEnvVariable", { name }) + return new Container(ctx) } /** @@ -2956,20 +2498,16 @@ export class Container extends BaseClient { port: number, opts?: ContainerWithoutExposedPortOpts, ): Container => { - const metadata: Metadata = { + const metadata = { protocol: { is_enum: true }, } - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withoutExposedPort", - args: { port, ...opts, __metadata: metadata }, - }, - ], - ctx: this._ctx, + const ctx = this._ctx.select("withoutExposedPort", { + port, + ...opts, + __metadata: metadata, }) + return new Container(ctx) } /** @@ -2978,16 +2516,8 @@ export class Container extends BaseClient { * @param opts.expand Replace "${VAR}" or "$VAR" in the value of path according to the current environment variables defined in the container (e.g. "/$VAR/foo.txt"). */ withoutFile = (path: string, opts?: ContainerWithoutFileOpts): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withoutFile", - args: { path, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withoutFile", { path, ...opts }) + return new Container(ctx) } /** @@ -2999,16 +2529,8 @@ export class Container extends BaseClient { paths: string[], opts?: ContainerWithoutFilesOpts, ): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withoutFiles", - args: { paths, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withoutFiles", { paths, ...opts }) + return new Container(ctx) } /** @@ -3016,16 +2538,8 @@ export class Container extends BaseClient { * @param name The name of the label to remove (e.g., "org.opencontainers.artifact.created"). */ withoutLabel = (name: string): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withoutLabel", - args: { name }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withoutLabel", { name }) + return new Container(ctx) } /** @@ -3037,16 +2551,8 @@ export class Container extends BaseClient { path: string, opts?: ContainerWithoutMountOpts, ): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withoutMount", - args: { path, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withoutMount", { path, ...opts }) + return new Container(ctx) } /** @@ -3056,16 +2562,8 @@ export class Container extends BaseClient { * Formatted as [host]/[user]/[repo]:[tag] (e.g. docker.io/dagger/dagger:main). */ withoutRegistryAuth = (address: string): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withoutRegistryAuth", - args: { address }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withoutRegistryAuth", { address }) + return new Container(ctx) } /** @@ -3073,16 +2571,8 @@ export class Container extends BaseClient { * @param name The name of the environment variable (e.g., "HOST"). */ withoutSecretVariable = (name: string): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withoutSecretVariable", - args: { name }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withoutSecretVariable", { name }) + return new Container(ctx) } /** @@ -3094,16 +2584,8 @@ export class Container extends BaseClient { path: string, opts?: ContainerWithoutUnixSocketOpts, ): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withoutUnixSocket", - args: { path, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withoutUnixSocket", { path, ...opts }) + return new Container(ctx) } /** @@ -3112,15 +2594,8 @@ export class Container extends BaseClient { * Should default to root. */ withoutUser = (): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withoutUser", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withoutUser") + return new Container(ctx) } /** @@ -3129,15 +2604,8 @@ export class Container extends BaseClient { * Should default to "/". */ withoutWorkdir = (): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "withoutWorkdir", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withoutWorkdir") + return new Container(ctx) } /** @@ -3148,15 +2616,9 @@ export class Container extends BaseClient { return this._workdir } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "workdir", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("workdir") + + const response: Awaited = await ctx.execute() return response } @@ -3181,12 +2643,8 @@ export class CurrentModule extends BaseClient { /** * Constructor is used for internal usage only, do not create object from it. */ - constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, - _id?: CurrentModuleID, - _name?: string, - ) { - super(parent) + constructor(ctx?: Context, _id?: CurrentModuleID, _name?: string) { + super(ctx) this._id = _id this._name = _name @@ -3200,15 +2658,9 @@ export class CurrentModule extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -3221,15 +2673,9 @@ export class CurrentModule extends BaseClient { return this._name } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "name", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("name") + + const response: Awaited = await ctx.execute() return response } @@ -3238,15 +2684,8 @@ export class CurrentModule extends BaseClient { * The directory containing the module's source code loaded into the engine (plus any generated code that may have been created). */ source = (): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "source", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("source") + return new Directory(ctx) } /** @@ -3256,16 +2695,8 @@ export class CurrentModule extends BaseClient { * @param opts.include Include only artifacts that match the given pattern (e.g., ["app/", "package.*"]). */ workdir = (path: string, opts?: CurrentModuleWorkdirOpts): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "workdir", - args: { path, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("workdir", { path, ...opts }) + return new Directory(ctx) } /** @@ -3273,16 +2704,8 @@ export class CurrentModule extends BaseClient { * @param path Location of the file to retrieve (e.g., "README.md"). */ workdirFile = (path: string): File => { - return new File({ - queryTree: [ - ...this._queryTree, - { - operation: "workdirFile", - args: { path }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("workdirFile", { path }) + return new File(ctx) } } @@ -3299,13 +2722,13 @@ export class Directory extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, + ctx?: Context, _id?: DirectoryID, _digest?: string, _export?: string, _sync?: DirectoryID, ) { - super(parent) + super(ctx) this._id = _id this._digest = _digest @@ -3321,15 +2744,9 @@ export class Directory extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -3344,16 +2761,8 @@ export class Directory extends BaseClient { * @param opts.engineVersion The engine version to upgrade to. */ asModule = (opts?: DirectoryAsModuleOpts): Module_ => { - return new Module_({ - queryTree: [ - ...this._queryTree, - { - operation: "asModule", - args: { ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("asModule", { ...opts }) + return new Module_(ctx) } /** @@ -3361,16 +2770,8 @@ export class Directory extends BaseClient { * @param other Identifier of the directory to compare. */ diff = (other: Directory): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "diff", - args: { other }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("diff", { other }) + return new Directory(ctx) } /** @@ -3381,15 +2782,9 @@ export class Directory extends BaseClient { return this._digest } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "digest", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("digest") + + const response: Awaited = await ctx.execute() return response } @@ -3399,16 +2794,8 @@ export class Directory extends BaseClient { * @param path Location of the directory to retrieve (e.g., "/src"). */ directory = (path: string): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "directory", - args: { path }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("directory", { path }) + return new Directory(ctx) } /** @@ -3422,16 +2809,8 @@ export class Directory extends BaseClient { * They will be mounted at /run/secrets/[secret-name]. */ dockerBuild = (opts?: DirectoryDockerBuildOpts): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "dockerBuild", - args: { ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("dockerBuild", { ...opts }) + return new Container(ctx) } /** @@ -3439,16 +2818,9 @@ export class Directory extends BaseClient { * @param opts.path Location of the directory to look at (e.g., "/src"). */ entries = async (opts?: DirectoryEntriesOpts): Promise => { - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "entries", - args: { ...opts }, - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("entries", { ...opts }) + + const response: Awaited = await ctx.execute() return response } @@ -3466,16 +2838,9 @@ export class Directory extends BaseClient { return this._export } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "export", - args: { path, ...opts }, - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("export", { path, ...opts }) + + const response: Awaited = await ctx.execute() return response } @@ -3485,16 +2850,8 @@ export class Directory extends BaseClient { * @param path Location of the file to retrieve (e.g., "README.md"). */ file = (path: string): File => { - return new File({ - queryTree: [ - ...this._queryTree, - { - operation: "file", - args: { path }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("file", { path }) + return new File(ctx) } /** @@ -3502,16 +2859,9 @@ export class Directory extends BaseClient { * @param pattern Pattern to match (e.g., "*.md"). */ glob = async (pattern: string): Promise => { - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "glob", - args: { pattern }, - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("glob", { pattern }) + + const response: Awaited = await ctx.execute() return response } @@ -3520,25 +2870,21 @@ export class Directory extends BaseClient { * Force evaluation in the engine. */ sync = async (): Promise => { - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "sync", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("sync") - return new Directory({ - queryTree: [ - { - operation: "loadDirectoryFromID", - args: { id: response }, - }, - ], - ctx: this._ctx, - }) + const response: Awaited = await ctx.execute() + + return new Directory( + new Context( + [ + { + operation: "loadDirectoryFromID", + args: { id: response }, + }, + ], + this._ctx.getConnection(), + ), + ) } /** @@ -3551,16 +2897,8 @@ export class Directory extends BaseClient { * @param opts.container If set, override the default container used for the terminal. */ terminal = (opts?: DirectoryTerminalOpts): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "terminal", - args: { ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("terminal", { ...opts }) + return new Directory(ctx) } /** @@ -3575,16 +2913,8 @@ export class Directory extends BaseClient { directory: Directory, opts?: DirectoryWithDirectoryOpts, ): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "withDirectory", - args: { path, directory, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withDirectory", { path, directory, ...opts }) + return new Directory(ctx) } /** @@ -3598,16 +2928,8 @@ export class Directory extends BaseClient { source: File, opts?: DirectoryWithFileOpts, ): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "withFile", - args: { path, source, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withFile", { path, source, ...opts }) + return new Directory(ctx) } /** @@ -3621,16 +2943,8 @@ export class Directory extends BaseClient { sources: File[], opts?: DirectoryWithFilesOpts, ): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "withFiles", - args: { path, sources, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withFiles", { path, sources, ...opts }) + return new Directory(ctx) } /** @@ -3642,16 +2956,8 @@ export class Directory extends BaseClient { path: string, opts?: DirectoryWithNewDirectoryOpts, ): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "withNewDirectory", - args: { path, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withNewDirectory", { path, ...opts }) + return new Directory(ctx) } /** @@ -3665,16 +2971,8 @@ export class Directory extends BaseClient { contents: string, opts?: DirectoryWithNewFileOpts, ): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "withNewFile", - args: { path, contents, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withNewFile", { path, contents, ...opts }) + return new Directory(ctx) } /** @@ -3684,16 +2982,8 @@ export class Directory extends BaseClient { * Formatted in seconds following Unix epoch (e.g., 1672531199). */ withTimestamps = (timestamp: number): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "withTimestamps", - args: { timestamp }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withTimestamps", { timestamp }) + return new Directory(ctx) } /** @@ -3701,16 +2991,8 @@ export class Directory extends BaseClient { * @param path Location of the directory to remove (e.g., ".github/"). */ withoutDirectory = (path: string): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "withoutDirectory", - args: { path }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withoutDirectory", { path }) + return new Directory(ctx) } /** @@ -3718,16 +3000,8 @@ export class Directory extends BaseClient { * @param path Location of the file to remove (e.g., "/file.txt"). */ withoutFile = (path: string): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "withoutFile", - args: { path }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withoutFile", { path }) + return new Directory(ctx) } /** @@ -3735,16 +3009,8 @@ export class Directory extends BaseClient { * @param paths Location of the file to remove (e.g., ["/file.txt"]). */ withoutFiles = (paths: string[]): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "withoutFiles", - args: { paths }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withoutFiles", { paths }) + return new Directory(ctx) } /** @@ -3766,11 +3032,8 @@ export class Engine extends BaseClient { /** * Constructor is used for internal usage only, do not create object from it. */ - constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, - _id?: EngineID, - ) { - super(parent) + constructor(ctx?: Context, _id?: EngineID) { + super(ctx) this._id = _id } @@ -3783,15 +3046,9 @@ export class Engine extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -3800,15 +3057,8 @@ export class Engine extends BaseClient { * The local (on-disk) cache for the Dagger engine */ localCache = (): EngineCache => { - return new EngineCache({ - queryTree: [ - ...this._queryTree, - { - operation: "localCache", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("localCache") + return new EngineCache(ctx) } } @@ -3827,7 +3077,7 @@ export class EngineCache extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, + ctx?: Context, _id?: EngineCacheID, _keepBytes?: number, _maxUsedSpace?: number, @@ -3835,7 +3085,7 @@ export class EngineCache extends BaseClient { _prune?: Void, _reservedSpace?: number, ) { - super(parent) + super(ctx) this._id = _id this._keepBytes = _keepBytes @@ -3853,15 +3103,9 @@ export class EngineCache extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -3870,16 +3114,8 @@ export class EngineCache extends BaseClient { * The current set of entries in the cache */ entrySet = (opts?: EngineCacheEntrySetOpts): EngineCacheEntrySet => { - return new EngineCacheEntrySet({ - queryTree: [ - ...this._queryTree, - { - operation: "entrySet", - args: { ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("entrySet", { ...opts }) + return new EngineCacheEntrySet(ctx) } /** @@ -3891,15 +3127,9 @@ export class EngineCache extends BaseClient { return this._keepBytes } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "keepBytes", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("keepBytes") + + const response: Awaited = await ctx.execute() return response } @@ -3912,15 +3142,9 @@ export class EngineCache extends BaseClient { return this._maxUsedSpace } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "maxUsedSpace", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("maxUsedSpace") + + const response: Awaited = await ctx.execute() return response } @@ -3933,15 +3157,9 @@ export class EngineCache extends BaseClient { return this._minFreeSpace } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "minFreeSpace", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("minFreeSpace") + + const response: Awaited = await ctx.execute() return response } @@ -3954,30 +3172,18 @@ export class EngineCache extends BaseClient { return } - await computeQuery( - [ - ...this._queryTree, - { - operation: "prune", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("prune") + + await ctx.execute() } reservedSpace = async (): Promise => { if (this._reservedSpace) { return this._reservedSpace } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "reservedSpace", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("reservedSpace") + + const response: Awaited = await ctx.execute() return response } @@ -3998,7 +3204,7 @@ export class EngineCacheEntry extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, + ctx?: Context, _id?: EngineCacheEntryID, _activelyUsed?: boolean, _createdTimeUnixNano?: number, @@ -4006,7 +3212,7 @@ export class EngineCacheEntry extends BaseClient { _diskSpaceBytes?: number, _mostRecentUseTimeUnixNano?: number, ) { - super(parent) + super(ctx) this._id = _id this._activelyUsed = _activelyUsed @@ -4024,15 +3230,9 @@ export class EngineCacheEntry extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -4045,15 +3245,9 @@ export class EngineCacheEntry extends BaseClient { return this._activelyUsed } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "activelyUsed", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("activelyUsed") + + const response: Awaited = await ctx.execute() return response } @@ -4066,15 +3260,9 @@ export class EngineCacheEntry extends BaseClient { return this._createdTimeUnixNano } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "createdTimeUnixNano", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("createdTimeUnixNano") + + const response: Awaited = await ctx.execute() return response } @@ -4087,15 +3275,9 @@ export class EngineCacheEntry extends BaseClient { return this._description } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "description", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("description") + + const response: Awaited = await ctx.execute() return response } @@ -4108,15 +3290,9 @@ export class EngineCacheEntry extends BaseClient { return this._diskSpaceBytes } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "diskSpaceBytes", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("diskSpaceBytes") + + const response: Awaited = await ctx.execute() return response } @@ -4129,15 +3305,9 @@ export class EngineCacheEntry extends BaseClient { return this._mostRecentUseTimeUnixNano } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "mostRecentUseTimeUnixNano", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("mostRecentUseTimeUnixNano") + + const response: Awaited = await ctx.execute() return response } @@ -4155,12 +3325,12 @@ export class EngineCacheEntrySet extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, + ctx?: Context, _id?: EngineCacheEntrySetID, _diskSpaceBytes?: number, _entryCount?: number, ) { - super(parent) + super(ctx) this._id = _id this._diskSpaceBytes = _diskSpaceBytes @@ -4175,15 +3345,9 @@ export class EngineCacheEntrySet extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -4196,15 +3360,9 @@ export class EngineCacheEntrySet extends BaseClient { return this._diskSpaceBytes } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "diskSpaceBytes", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("diskSpaceBytes") + + const response: Awaited = await ctx.execute() return response } @@ -4217,31 +3375,22 @@ export class EngineCacheEntrySet extends BaseClient { id: EngineCacheEntryID } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "entries", - }, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("entries").select("id") + + const response: Awaited = await ctx.execute() return response.map( (r) => new EngineCacheEntry( - { - queryTree: [ + new Context( + [ { operation: "loadEngineCacheEntryFromID", args: { id: r.id }, }, ], - ctx: this._ctx, - }, + this._ctx.getConnection(), + ), r.id, ), ) @@ -4255,15 +3404,9 @@ export class EngineCacheEntrySet extends BaseClient { return this._entryCount } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "entryCount", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("entryCount") + + const response: Awaited = await ctx.execute() return response } @@ -4282,13 +3425,13 @@ export class EnumTypeDef extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, + ctx?: Context, _id?: EnumTypeDefID, _description?: string, _name?: string, _sourceModuleName?: string, ) { - super(parent) + super(ctx) this._id = _id this._description = _description @@ -4304,15 +3447,9 @@ export class EnumTypeDef extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -4325,15 +3462,9 @@ export class EnumTypeDef extends BaseClient { return this._description } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "description", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("description") + + const response: Awaited = await ctx.execute() return response } @@ -4346,15 +3477,9 @@ export class EnumTypeDef extends BaseClient { return this._name } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "name", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("name") + + const response: Awaited = await ctx.execute() return response } @@ -4363,15 +3488,8 @@ export class EnumTypeDef extends BaseClient { * The location of this enum declaration. */ sourceMap = (): SourceMap => { - return new SourceMap({ - queryTree: [ - ...this._queryTree, - { - operation: "sourceMap", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("sourceMap") + return new SourceMap(ctx) } /** @@ -4382,15 +3500,9 @@ export class EnumTypeDef extends BaseClient { return this._sourceModuleName } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "sourceModuleName", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("sourceModuleName") + + const response: Awaited = await ctx.execute() return response } @@ -4403,31 +3515,22 @@ export class EnumTypeDef extends BaseClient { id: EnumValueTypeDefID } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "values", - }, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("values").select("id") + + const response: Awaited = await ctx.execute() return response.map( (r) => new EnumValueTypeDef( - { - queryTree: [ + new Context( + [ { operation: "loadEnumValueTypeDefFromID", args: { id: r.id }, }, ], - ctx: this._ctx, - }, + this._ctx.getConnection(), + ), r.id, ), ) @@ -4446,12 +3549,12 @@ export class EnumValueTypeDef extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, + ctx?: Context, _id?: EnumValueTypeDefID, _description?: string, _name?: string, ) { - super(parent) + super(ctx) this._id = _id this._description = _description @@ -4466,15 +3569,9 @@ export class EnumValueTypeDef extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -4487,15 +3584,9 @@ export class EnumValueTypeDef extends BaseClient { return this._description } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "description", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("description") + + const response: Awaited = await ctx.execute() return response } @@ -4508,15 +3599,9 @@ export class EnumValueTypeDef extends BaseClient { return this._name } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "name", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("name") + + const response: Awaited = await ctx.execute() return response } @@ -4525,15 +3610,8 @@ export class EnumValueTypeDef extends BaseClient { * The location of this enum value declaration. */ sourceMap = (): SourceMap => { - return new SourceMap({ - queryTree: [ - ...this._queryTree, - { - operation: "sourceMap", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("sourceMap") + return new SourceMap(ctx) } } @@ -4549,12 +3627,12 @@ export class EnvVariable extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, + ctx?: Context, _id?: EnvVariableID, _name?: string, _value?: string, ) { - super(parent) + super(ctx) this._id = _id this._name = _name @@ -4569,15 +3647,9 @@ export class EnvVariable extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -4590,15 +3662,9 @@ export class EnvVariable extends BaseClient { return this._name } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "name", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("name") + + const response: Awaited = await ctx.execute() return response } @@ -4611,15 +3677,9 @@ export class EnvVariable extends BaseClient { return this._value } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "value", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("value") + + const response: Awaited = await ctx.execute() return response } @@ -4632,12 +3692,8 @@ export class Error extends BaseClient { /** * Constructor is used for internal usage only, do not create object from it. */ - constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, - _id?: ErrorID, - _message?: string, - ) { - super(parent) + constructor(ctx?: Context, _id?: ErrorID, _message?: string) { + super(ctx) this._id = _id this._message = _message @@ -4651,15 +3707,9 @@ export class Error extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -4672,15 +3722,9 @@ export class Error extends BaseClient { return this._message } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "message", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("message") + + const response: Awaited = await ctx.execute() return response } @@ -4700,12 +3744,12 @@ export class FieldTypeDef extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, + ctx?: Context, _id?: FieldTypeDefID, _description?: string, _name?: string, ) { - super(parent) + super(ctx) this._id = _id this._description = _description @@ -4720,15 +3764,9 @@ export class FieldTypeDef extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -4741,15 +3779,9 @@ export class FieldTypeDef extends BaseClient { return this._description } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "description", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("description") + + const response: Awaited = await ctx.execute() return response } @@ -4762,15 +3794,9 @@ export class FieldTypeDef extends BaseClient { return this._name } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "name", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("name") + + const response: Awaited = await ctx.execute() return response } @@ -4779,30 +3805,16 @@ export class FieldTypeDef extends BaseClient { * The location of this field declaration. */ sourceMap = (): SourceMap => { - return new SourceMap({ - queryTree: [ - ...this._queryTree, - { - operation: "sourceMap", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("sourceMap") + return new SourceMap(ctx) } /** * The type of the field. */ typeDef = (): TypeDef => { - return new TypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "typeDef", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("typeDef") + return new TypeDef(ctx) } } @@ -4822,7 +3834,7 @@ export class File extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, + ctx?: Context, _id?: FileID, _contents?: string, _digest?: string, @@ -4831,7 +3843,7 @@ export class File extends BaseClient { _size?: number, _sync?: FileID, ) { - super(parent) + super(ctx) this._id = _id this._contents = _contents @@ -4850,15 +3862,9 @@ export class File extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -4871,15 +3877,9 @@ export class File extends BaseClient { return this._contents } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "contents", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("contents") + + const response: Awaited = await ctx.execute() return response } @@ -4893,16 +3893,9 @@ export class File extends BaseClient { return this._digest } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "digest", - args: { ...opts }, - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("digest", { ...opts }) + + const response: Awaited = await ctx.execute() return response } @@ -4917,16 +3910,9 @@ export class File extends BaseClient { return this._export } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "export", - args: { path, ...opts }, - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("export", { path, ...opts }) + + const response: Awaited = await ctx.execute() return response } @@ -4939,15 +3925,9 @@ export class File extends BaseClient { return this._name } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "name", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("name") + + const response: Awaited = await ctx.execute() return response } @@ -4960,15 +3940,9 @@ export class File extends BaseClient { return this._size } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "size", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("size") + + const response: Awaited = await ctx.execute() return response } @@ -4977,25 +3951,21 @@ export class File extends BaseClient { * Force evaluation in the engine. */ sync = async (): Promise => { - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "sync", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("sync") - return new File({ - queryTree: [ - { - operation: "loadFileFromID", - args: { id: response }, - }, - ], - ctx: this._ctx, - }) + const response: Awaited = await ctx.execute() + + return new File( + new Context( + [ + { + operation: "loadFileFromID", + args: { id: response }, + }, + ], + this._ctx.getConnection(), + ), + ) } /** @@ -5003,16 +3973,8 @@ export class File extends BaseClient { * @param name Name to set file to. */ withName = (name: string): File => { - return new File({ - queryTree: [ - ...this._queryTree, - { - operation: "withName", - args: { name }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withName", { name }) + return new File(ctx) } /** @@ -5022,16 +3984,8 @@ export class File extends BaseClient { * Formatted in seconds following Unix epoch (e.g., 1672531199). */ withTimestamps = (timestamp: number): File => { - return new File({ - queryTree: [ - ...this._queryTree, - { - operation: "withTimestamps", - args: { timestamp }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withTimestamps", { timestamp }) + return new File(ctx) } /** @@ -5058,12 +4012,12 @@ export class Function_ extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, + ctx?: Context, _id?: FunctionID, _description?: string, _name?: string, ) { - super(parent) + super(ctx) this._id = _id this._description = _description @@ -5078,15 +4032,9 @@ export class Function_ extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -5099,31 +4047,22 @@ export class Function_ extends BaseClient { id: FunctionArgID } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "args", - }, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("args").select("id") + + const response: Awaited = await ctx.execute() return response.map( (r) => new FunctionArg( - { - queryTree: [ + new Context( + [ { operation: "loadFunctionArgFromID", args: { id: r.id }, }, ], - ctx: this._ctx, - }, + this._ctx.getConnection(), + ), r.id, ), ) @@ -5137,15 +4076,9 @@ export class Function_ extends BaseClient { return this._description } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "description", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("description") + + const response: Awaited = await ctx.execute() return response } @@ -5158,15 +4091,9 @@ export class Function_ extends BaseClient { return this._name } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "name", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("name") + + const response: Awaited = await ctx.execute() return response } @@ -5175,30 +4102,16 @@ export class Function_ extends BaseClient { * The type returned by the function. */ returnType = (): TypeDef => { - return new TypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "returnType", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("returnType") + return new TypeDef(ctx) } /** * The location of this function declaration. */ sourceMap = (): SourceMap => { - return new SourceMap({ - queryTree: [ - ...this._queryTree, - { - operation: "sourceMap", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("sourceMap") + return new SourceMap(ctx) } /** @@ -5215,16 +4128,8 @@ export class Function_ extends BaseClient { typeDef: TypeDef, opts?: FunctionWithArgOpts, ): Function_ => { - return new Function_({ - queryTree: [ - ...this._queryTree, - { - operation: "withArg", - args: { name, typeDef, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withArg", { name, typeDef, ...opts }) + return new Function_(ctx) } /** @@ -5232,16 +4137,8 @@ export class Function_ extends BaseClient { * @param description The doc string to set. */ withDescription = (description: string): Function_ => { - return new Function_({ - queryTree: [ - ...this._queryTree, - { - operation: "withDescription", - args: { description }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withDescription", { description }) + return new Function_(ctx) } /** @@ -5249,16 +4146,8 @@ export class Function_ extends BaseClient { * @param sourceMap The source map for the function definition. */ withSourceMap = (sourceMap: SourceMap): Function_ => { - return new Function_({ - queryTree: [ - ...this._queryTree, - { - operation: "withSourceMap", - args: { sourceMap }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withSourceMap", { sourceMap }) + return new Function_(ctx) } /** @@ -5287,14 +4176,14 @@ export class FunctionArg extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, + ctx?: Context, _id?: FunctionArgID, _defaultPath?: string, _defaultValue?: JSON, _description?: string, _name?: string, ) { - super(parent) + super(ctx) this._id = _id this._defaultPath = _defaultPath @@ -5311,15 +4200,9 @@ export class FunctionArg extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -5332,15 +4215,9 @@ export class FunctionArg extends BaseClient { return this._defaultPath } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "defaultPath", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("defaultPath") + + const response: Awaited = await ctx.execute() return response } @@ -5353,15 +4230,9 @@ export class FunctionArg extends BaseClient { return this._defaultValue } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "defaultValue", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("defaultValue") + + const response: Awaited = await ctx.execute() return response } @@ -5374,15 +4245,9 @@ export class FunctionArg extends BaseClient { return this._description } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "description", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("description") + + const response: Awaited = await ctx.execute() return response } @@ -5391,15 +4256,9 @@ export class FunctionArg extends BaseClient { * Only applies to arguments of type Directory. The ignore patterns are applied to the input directory, and matching entries are filtered out, in a cache-efficient manner. */ ignore = async (): Promise => { - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "ignore", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("ignore") + + const response: Awaited = await ctx.execute() return response } @@ -5412,15 +4271,9 @@ export class FunctionArg extends BaseClient { return this._name } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "name", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("name") + + const response: Awaited = await ctx.execute() return response } @@ -5429,30 +4282,16 @@ export class FunctionArg extends BaseClient { * The location of this arg declaration. */ sourceMap = (): SourceMap => { - return new SourceMap({ - queryTree: [ - ...this._queryTree, - { - operation: "sourceMap", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("sourceMap") + return new SourceMap(ctx) } /** * The type of the argument. */ typeDef = (): TypeDef => { - return new TypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "typeDef", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("typeDef") + return new TypeDef(ctx) } } @@ -5471,7 +4310,7 @@ export class FunctionCall extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, + ctx?: Context, _id?: FunctionCallID, _name?: string, _parent?: JSON, @@ -5479,7 +4318,7 @@ export class FunctionCall extends BaseClient { _returnError?: Void, _returnValue?: Void, ) { - super(parent) + super(ctx) this._id = _id this._name = _name @@ -5497,15 +4336,9 @@ export class FunctionCall extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -5518,31 +4351,22 @@ export class FunctionCall extends BaseClient { id: FunctionCallArgValueID } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "inputArgs", - }, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("inputArgs").select("id") + + const response: Awaited = await ctx.execute() return response.map( (r) => new FunctionCallArgValue( - { - queryTree: [ + new Context( + [ { operation: "loadFunctionCallArgValueFromID", args: { id: r.id }, }, ], - ctx: this._ctx, - }, + this._ctx.getConnection(), + ), r.id, ), ) @@ -5556,15 +4380,9 @@ export class FunctionCall extends BaseClient { return this._name } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "name", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("name") + + const response: Awaited = await ctx.execute() return response } @@ -5577,15 +4395,9 @@ export class FunctionCall extends BaseClient { return this._parent } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "parent", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("parent") + + const response: Awaited = await ctx.execute() return response } @@ -5598,15 +4410,9 @@ export class FunctionCall extends BaseClient { return this._parentName } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "parentName", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("parentName") + + const response: Awaited = await ctx.execute() return response } @@ -5620,16 +4426,9 @@ export class FunctionCall extends BaseClient { return } - await computeQuery( - [ - ...this._queryTree, - { - operation: "returnError", - args: { error }, - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("returnError", { error }) + + await ctx.execute() } /** @@ -5641,16 +4440,9 @@ export class FunctionCall extends BaseClient { return } - await computeQuery( - [ - ...this._queryTree, - { - operation: "returnValue", - args: { value }, - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("returnValue", { value }) + + await ctx.execute() } } @@ -5666,12 +4458,12 @@ export class FunctionCallArgValue extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, + ctx?: Context, _id?: FunctionCallArgValueID, _name?: string, _value?: JSON, ) { - super(parent) + super(ctx) this._id = _id this._name = _name @@ -5686,15 +4478,9 @@ export class FunctionCallArgValue extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -5707,15 +4493,9 @@ export class FunctionCallArgValue extends BaseClient { return this._name } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "name", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("name") + + const response: Awaited = await ctx.execute() return response } @@ -5728,15 +4508,9 @@ export class FunctionCallArgValue extends BaseClient { return this._value } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "value", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("value") + + const response: Awaited = await ctx.execute() return response } @@ -5751,11 +4525,8 @@ export class GeneratedCode extends BaseClient { /** * Constructor is used for internal usage only, do not create object from it. */ - constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, - _id?: GeneratedCodeID, - ) { - super(parent) + constructor(ctx?: Context, _id?: GeneratedCodeID) { + super(ctx) this._id = _id } @@ -5768,15 +4539,9 @@ export class GeneratedCode extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -5785,30 +4550,17 @@ export class GeneratedCode extends BaseClient { * The directory containing the generated code. */ code = (): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "code", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("code") + return new Directory(ctx) } /** * List of paths to mark generated in version control (i.e. .gitattributes). */ vcsGeneratedPaths = async (): Promise => { - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "vcsGeneratedPaths", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("vcsGeneratedPaths") + + const response: Awaited = await ctx.execute() return response } @@ -5817,15 +4569,9 @@ export class GeneratedCode extends BaseClient { * List of paths to ignore in version control (i.e. .gitignore). */ vcsIgnoredPaths = async (): Promise => { - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "vcsIgnoredPaths", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("vcsIgnoredPaths") + + const response: Awaited = await ctx.execute() return response } @@ -5834,32 +4580,16 @@ export class GeneratedCode extends BaseClient { * Set the list of paths to mark generated in version control. */ withVCSGeneratedPaths = (paths: string[]): GeneratedCode => { - return new GeneratedCode({ - queryTree: [ - ...this._queryTree, - { - operation: "withVCSGeneratedPaths", - args: { paths }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withVCSGeneratedPaths", { paths }) + return new GeneratedCode(ctx) } /** * Set the list of paths to ignore in version control. */ withVCSIgnoredPaths = (paths: string[]): GeneratedCode => { - return new GeneratedCode({ - queryTree: [ - ...this._queryTree, - { - operation: "withVCSIgnoredPaths", - args: { paths }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withVCSIgnoredPaths", { paths }) + return new GeneratedCode(ctx) } /** @@ -5889,7 +4619,7 @@ export class GitModuleSource extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, + ctx?: Context, _id?: GitModuleSourceID, _cloneRef?: string, _commit?: string, @@ -5899,7 +4629,7 @@ export class GitModuleSource extends BaseClient { _rootSubpath?: string, _version?: string, ) { - super(parent) + super(ctx) this._id = _id this._cloneRef = _cloneRef @@ -5919,15 +4649,9 @@ export class GitModuleSource extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -5940,15 +4664,9 @@ export class GitModuleSource extends BaseClient { return this._cloneRef } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "cloneRef", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("cloneRef") + + const response: Awaited = await ctx.execute() return response } @@ -5961,15 +4679,9 @@ export class GitModuleSource extends BaseClient { return this._commit } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "commit", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("commit") + + const response: Awaited = await ctx.execute() return response } @@ -5978,15 +4690,8 @@ export class GitModuleSource extends BaseClient { * The directory containing everything needed to load load and use the module. */ contextDirectory = (): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "contextDirectory", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("contextDirectory") + return new Directory(ctx) } /** @@ -5997,15 +4702,9 @@ export class GitModuleSource extends BaseClient { return this._htmlRepoURL } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "htmlRepoURL", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("htmlRepoURL") + + const response: Awaited = await ctx.execute() return response } @@ -6018,15 +4717,9 @@ export class GitModuleSource extends BaseClient { return this._htmlURL } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "htmlURL", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("htmlURL") + + const response: Awaited = await ctx.execute() return response } @@ -6039,15 +4732,9 @@ export class GitModuleSource extends BaseClient { return this._root } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "root", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("root") + + const response: Awaited = await ctx.execute() return response } @@ -6060,15 +4747,9 @@ export class GitModuleSource extends BaseClient { return this._rootSubpath } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "rootSubpath", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("rootSubpath") + + const response: Awaited = await ctx.execute() return response } @@ -6081,15 +4762,9 @@ export class GitModuleSource extends BaseClient { return this._version } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "version", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("version") + + const response: Awaited = await ctx.execute() return response } @@ -6105,12 +4780,8 @@ export class GitRef extends BaseClient { /** * Constructor is used for internal usage only, do not create object from it. */ - constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, - _id?: GitRefID, - _commit?: string, - ) { - super(parent) + constructor(ctx?: Context, _id?: GitRefID, _commit?: string) { + super(ctx) this._id = _id this._commit = _commit @@ -6124,15 +4795,9 @@ export class GitRef extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -6145,15 +4810,9 @@ export class GitRef extends BaseClient { return this._commit } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "commit", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("commit") + + const response: Awaited = await ctx.execute() return response } @@ -6163,16 +4822,8 @@ export class GitRef extends BaseClient { * @param opts.discardGitDir Set to true to discard .git directory. */ tree = (opts?: GitRefTreeOpts): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "tree", - args: { ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("tree", { ...opts }) + return new Directory(ctx) } } @@ -6185,11 +4836,8 @@ export class GitRepository extends BaseClient { /** * Constructor is used for internal usage only, do not create object from it. */ - constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, - _id?: GitRepositoryID, - ) { - super(parent) + constructor(ctx?: Context, _id?: GitRepositoryID) { + super(ctx) this._id = _id } @@ -6202,15 +4850,9 @@ export class GitRepository extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -6220,16 +4862,8 @@ export class GitRepository extends BaseClient { * @param name Branch's name (e.g., "main"). */ branch = (name: string): GitRef => { - return new GitRef({ - queryTree: [ - ...this._queryTree, - { - operation: "branch", - args: { name }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("branch", { name }) + return new GitRef(ctx) } /** @@ -6237,31 +4871,16 @@ export class GitRepository extends BaseClient { * @param id Identifier of the commit (e.g., "b6315d8f2810962c601af73f86831f6866ea798b"). */ commit = (id: string): GitRef => { - return new GitRef({ - queryTree: [ - ...this._queryTree, - { - operation: "commit", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("commit", { id }) + return new GitRef(ctx) } /** * Returns details for HEAD. */ head = (): GitRef => { - return new GitRef({ - queryTree: [ - ...this._queryTree, - { - operation: "head", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("head") + return new GitRef(ctx) } /** @@ -6269,16 +4888,8 @@ export class GitRepository extends BaseClient { * @param name Ref's name (can be a commit identifier, a tag name, a branch name, or a fully-qualified ref). */ ref = (name: string): GitRef => { - return new GitRef({ - queryTree: [ - ...this._queryTree, - { - operation: "ref", - args: { name }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("ref", { name }) + return new GitRef(ctx) } /** @@ -6286,16 +4897,8 @@ export class GitRepository extends BaseClient { * @param name Tag's name (e.g., "v0.3.9"). */ tag = (name: string): GitRef => { - return new GitRef({ - queryTree: [ - ...this._queryTree, - { - operation: "tag", - args: { name }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("tag", { name }) + return new GitRef(ctx) } /** @@ -6303,16 +4906,9 @@ export class GitRepository extends BaseClient { * @param opts.patterns Glob patterns (e.g., "refs/tags/v*"). */ tags = async (opts?: GitRepositoryTagsOpts): Promise => { - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "tags", - args: { ...opts }, - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("tags", { ...opts }) + + const response: Awaited = await ctx.execute() return response } @@ -6322,16 +4918,8 @@ export class GitRepository extends BaseClient { * @param header Secret used to populate the Authorization HTTP header */ withAuthHeader = (header: Secret): GitRepository => { - return new GitRepository({ - queryTree: [ - ...this._queryTree, - { - operation: "withAuthHeader", - args: { header }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withAuthHeader", { header }) + return new GitRepository(ctx) } /** @@ -6339,16 +4927,8 @@ export class GitRepository extends BaseClient { * @param token Secret used to populate the password during basic HTTP Authorization */ withAuthToken = (token: Secret): GitRepository => { - return new GitRepository({ - queryTree: [ - ...this._queryTree, - { - operation: "withAuthToken", - args: { token }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withAuthToken", { token }) + return new GitRepository(ctx) } /** @@ -6370,11 +4950,8 @@ export class Host extends BaseClient { /** * Constructor is used for internal usage only, do not create object from it. */ - constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, - _id?: HostID, - ) { - super(parent) + constructor(ctx?: Context, _id?: HostID) { + super(ctx) this._id = _id } @@ -6387,15 +4964,9 @@ export class Host extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -6407,16 +4978,8 @@ export class Host extends BaseClient { * @param opts.include Include only artifacts that match the given pattern (e.g., ["app/", "package.*"]). */ directory = (path: string, opts?: HostDirectoryOpts): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "directory", - args: { path, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("directory", { path, ...opts }) + return new Directory(ctx) } /** @@ -6424,16 +4987,8 @@ export class Host extends BaseClient { * @param path Location of the file to retrieve (e.g., "README.md"). */ file = (path: string): File => { - return new File({ - queryTree: [ - ...this._queryTree, - { - operation: "file", - args: { path }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("file", { path }) + return new File(ctx) } /** @@ -6446,16 +5001,8 @@ export class Host extends BaseClient { * An empty set of ports is not valid; an error will be returned. */ service = (opts?: HostServiceOpts): Service => { - return new Service({ - queryTree: [ - ...this._queryTree, - { - operation: "service", - args: { ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("service", { ...opts }) + return new Service(ctx) } /** @@ -6466,16 +5013,8 @@ export class Host extends BaseClient { * @param path Location of the file to set as a secret. */ setSecretFile = (name: string, path: string): Secret => { - return new Secret({ - queryTree: [ - ...this._queryTree, - { - operation: "setSecretFile", - args: { name, path }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("setSecretFile", { name, path }) + return new Secret(ctx) } /** @@ -6493,16 +5032,8 @@ export class Host extends BaseClient { * Note: enabling may result in port conflicts. */ tunnel = (service: Service, opts?: HostTunnelOpts): Service => { - return new Service({ - queryTree: [ - ...this._queryTree, - { - operation: "tunnel", - args: { service, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("tunnel", { service, ...opts }) + return new Service(ctx) } /** @@ -6510,16 +5041,8 @@ export class Host extends BaseClient { * @param path Location of the Unix socket (e.g., "/var/run/docker.sock"). */ unixSocket = (path: string): Socket => { - return new Socket({ - queryTree: [ - ...this._queryTree, - { - operation: "unixSocket", - args: { path }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("unixSocket", { path }) + return new Socket(ctx) } } @@ -6536,12 +5059,8 @@ export class InputTypeDef extends BaseClient { /** * Constructor is used for internal usage only, do not create object from it. */ - constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, - _id?: InputTypeDefID, - _name?: string, - ) { - super(parent) + constructor(ctx?: Context, _id?: InputTypeDefID, _name?: string) { + super(ctx) this._id = _id this._name = _name @@ -6555,15 +5074,9 @@ export class InputTypeDef extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -6576,31 +5089,22 @@ export class InputTypeDef extends BaseClient { id: FieldTypeDefID } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "fields", - }, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("fields").select("id") + + const response: Awaited = await ctx.execute() return response.map( (r) => new FieldTypeDef( - { - queryTree: [ + new Context( + [ { operation: "loadFieldTypeDefFromID", args: { id: r.id }, }, ], - ctx: this._ctx, - }, + this._ctx.getConnection(), + ), r.id, ), ) @@ -6614,15 +5118,9 @@ export class InputTypeDef extends BaseClient { return this._name } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "name", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("name") + + const response: Awaited = await ctx.execute() return response } @@ -6641,13 +5139,13 @@ export class InterfaceTypeDef extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, + ctx?: Context, _id?: InterfaceTypeDefID, _description?: string, _name?: string, _sourceModuleName?: string, ) { - super(parent) + super(ctx) this._id = _id this._description = _description @@ -6663,15 +5161,9 @@ export class InterfaceTypeDef extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -6684,15 +5176,9 @@ export class InterfaceTypeDef extends BaseClient { return this._description } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "description", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("description") + + const response: Awaited = await ctx.execute() return response } @@ -6705,31 +5191,22 @@ export class InterfaceTypeDef extends BaseClient { id: FunctionID } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "functions", - }, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("functions").select("id") + + const response: Awaited = await ctx.execute() return response.map( (r) => new Function_( - { - queryTree: [ + new Context( + [ { operation: "loadFunction_FromID", args: { id: r.id }, }, ], - ctx: this._ctx, - }, + this._ctx.getConnection(), + ), r.id, ), ) @@ -6743,15 +5220,9 @@ export class InterfaceTypeDef extends BaseClient { return this._name } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "name", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("name") + + const response: Awaited = await ctx.execute() return response } @@ -6760,15 +5231,8 @@ export class InterfaceTypeDef extends BaseClient { * The location of this interface declaration. */ sourceMap = (): SourceMap => { - return new SourceMap({ - queryTree: [ - ...this._queryTree, - { - operation: "sourceMap", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("sourceMap") + return new SourceMap(ctx) } /** @@ -6779,15 +5243,9 @@ export class InterfaceTypeDef extends BaseClient { return this._sourceModuleName } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "sourceModuleName", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("sourceModuleName") + + const response: Awaited = await ctx.execute() return response } @@ -6804,13 +5262,8 @@ export class Label extends BaseClient { /** * Constructor is used for internal usage only, do not create object from it. */ - constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, - _id?: LabelID, - _name?: string, - _value?: string, - ) { - super(parent) + constructor(ctx?: Context, _id?: LabelID, _name?: string, _value?: string) { + super(ctx) this._id = _id this._name = _name @@ -6825,15 +5278,9 @@ export class Label extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -6846,15 +5293,9 @@ export class Label extends BaseClient { return this._name } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "name", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("name") + + const response: Awaited = await ctx.execute() return response } @@ -6867,15 +5308,9 @@ export class Label extends BaseClient { return this._value } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "value", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("value") + + const response: Awaited = await ctx.execute() return response } @@ -6890,11 +5325,8 @@ export class ListTypeDef extends BaseClient { /** * Constructor is used for internal usage only, do not create object from it. */ - constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, - _id?: ListTypeDefID, - ) { - super(parent) + constructor(ctx?: Context, _id?: ListTypeDefID) { + super(ctx) this._id = _id } @@ -6907,15 +5339,9 @@ export class ListTypeDef extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -6924,15 +5350,8 @@ export class ListTypeDef extends BaseClient { * The type of the elements in the list. */ elementTypeDef = (): TypeDef => { - return new TypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "elementTypeDef", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("elementTypeDef") + return new TypeDef(ctx) } } @@ -6948,12 +5367,12 @@ export class LocalModuleSource extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, + ctx?: Context, _id?: LocalModuleSourceID, _relHostPath?: string, _rootSubpath?: string, ) { - super(parent) + super(ctx) this._id = _id this._relHostPath = _relHostPath @@ -6968,15 +5387,9 @@ export class LocalModuleSource extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -6985,15 +5398,8 @@ export class LocalModuleSource extends BaseClient { * The directory containing everything needed to load load and use the module. */ contextDirectory = (): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "contextDirectory", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("contextDirectory") + return new Directory(ctx) } /** @@ -7004,15 +5410,9 @@ export class LocalModuleSource extends BaseClient { return this._relHostPath } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "relHostPath", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("relHostPath") + + const response: Awaited = await ctx.execute() return response } @@ -7025,15 +5425,9 @@ export class LocalModuleSource extends BaseClient { return this._rootSubpath } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "rootSubpath", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("rootSubpath") + + const response: Awaited = await ctx.execute() return response } @@ -7053,14 +5447,14 @@ export class Module_ extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, + ctx?: Context, _id?: ModuleID, _description?: string, _name?: string, _sdk?: string, _serve?: Void, ) { - super(parent) + super(ctx) this._id = _id this._description = _description @@ -7077,15 +5471,9 @@ export class Module_ extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -7098,31 +5486,22 @@ export class Module_ extends BaseClient { id: ModuleID } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "dependencies", - }, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("dependencies").select("id") + + const response: Awaited = await ctx.execute() return response.map( (r) => new Module_( - { - queryTree: [ + new Context( + [ { operation: "loadModule_FromID", args: { id: r.id }, }, ], - ctx: this._ctx, - }, + this._ctx.getConnection(), + ), r.id, ), ) @@ -7136,31 +5515,22 @@ export class Module_ extends BaseClient { id: ModuleDependencyID } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "dependencyConfig", - }, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("dependencyConfig").select("id") + + const response: Awaited = await ctx.execute() return response.map( (r) => new ModuleDependency( - { - queryTree: [ + new Context( + [ { operation: "loadModuleDependencyFromID", args: { id: r.id }, }, ], - ctx: this._ctx, - }, + this._ctx.getConnection(), + ), r.id, ), ) @@ -7174,15 +5544,9 @@ export class Module_ extends BaseClient { return this._description } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "description", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("description") + + const response: Awaited = await ctx.execute() return response } @@ -7195,31 +5559,22 @@ export class Module_ extends BaseClient { id: TypeDefID } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "enums", - }, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("enums").select("id") + + const response: Awaited = await ctx.execute() return response.map( (r) => new TypeDef( - { - queryTree: [ + new Context( + [ { operation: "loadTypeDefFromID", args: { id: r.id }, }, ], - ctx: this._ctx, - }, + this._ctx.getConnection(), + ), r.id, ), ) @@ -7229,45 +5584,24 @@ export class Module_ extends BaseClient { * The generated files and directories made on top of the module source's context directory. */ generatedContextDiff = (): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "generatedContextDiff", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("generatedContextDiff") + return new Directory(ctx) } /** * The module source's context plus any configuration and source files created by codegen. */ generatedContextDirectory = (): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "generatedContextDirectory", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("generatedContextDirectory") + return new Directory(ctx) } /** * Retrieves the module with the objects loaded via its SDK. */ initialize = (): Module_ => { - return new Module_({ - queryTree: [ - ...this._queryTree, - { - operation: "initialize", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("initialize") + return new Module_(ctx) } /** @@ -7278,31 +5612,22 @@ export class Module_ extends BaseClient { id: TypeDefID } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "interfaces", - }, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("interfaces").select("id") + + const response: Awaited = await ctx.execute() return response.map( (r) => new TypeDef( - { - queryTree: [ + new Context( + [ { operation: "loadTypeDefFromID", args: { id: r.id }, }, ], - ctx: this._ctx, - }, + this._ctx.getConnection(), + ), r.id, ), ) @@ -7316,15 +5641,9 @@ export class Module_ extends BaseClient { return this._name } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "name", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("name") + + const response: Awaited = await ctx.execute() return response } @@ -7337,31 +5656,22 @@ export class Module_ extends BaseClient { id: TypeDefID } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "objects", - }, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("objects").select("id") + + const response: Awaited = await ctx.execute() return response.map( (r) => new TypeDef( - { - queryTree: [ + new Context( + [ { operation: "loadTypeDefFromID", args: { id: r.id }, }, ], - ctx: this._ctx, - }, + this._ctx.getConnection(), + ), r.id, ), ) @@ -7371,15 +5681,8 @@ export class Module_ extends BaseClient { * The container that runs the module's entrypoint. It will fail to execute if the module doesn't compile. */ runtime = (): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "runtime", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("runtime") + return new Container(ctx) } /** @@ -7390,15 +5693,9 @@ export class Module_ extends BaseClient { return this._sdk } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "sdk", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("sdk") + + const response: Awaited = await ctx.execute() return response } @@ -7413,30 +5710,17 @@ export class Module_ extends BaseClient { return } - await computeQuery( - [ - ...this._queryTree, - { - operation: "serve", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("serve") + + await ctx.execute() } /** * The source for the module. */ source = (): ModuleSource => { - return new ModuleSource({ - queryTree: [ - ...this._queryTree, - { - operation: "source", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("source") + return new ModuleSource(ctx) } /** @@ -7444,66 +5728,34 @@ export class Module_ extends BaseClient { * @param description The description to set */ withDescription = (description: string): Module_ => { - return new Module_({ - queryTree: [ - ...this._queryTree, - { - operation: "withDescription", - args: { description }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withDescription", { description }) + return new Module_(ctx) } /** * This module plus the given Enum type and associated values */ withEnum = (enum_: TypeDef): Module_ => { - return new Module_({ - queryTree: [ - ...this._queryTree, - { - operation: "withEnum", - args: { - enum: enum_, - }, - }, - ], - ctx: this._ctx, + const ctx = this._ctx.select("withEnum", { + enum: enum_, }) + return new Module_(ctx) } /** * This module plus the given Interface type and associated functions */ withInterface = (iface: TypeDef): Module_ => { - return new Module_({ - queryTree: [ - ...this._queryTree, - { - operation: "withInterface", - args: { iface }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withInterface", { iface }) + return new Module_(ctx) } /** * This module plus the given Object type and associated functions. */ withObject = (object: TypeDef): Module_ => { - return new Module_({ - queryTree: [ - ...this._queryTree, - { - operation: "withObject", - args: { object }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withObject", { object }) + return new Module_(ctx) } /** @@ -7512,16 +5764,8 @@ export class Module_ extends BaseClient { * @param opts.engineVersion The engine version to upgrade to. */ withSource = (source: ModuleSource, opts?: ModuleWithSourceOpts): Module_ => { - return new Module_({ - queryTree: [ - ...this._queryTree, - { - operation: "withSource", - args: { source, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withSource", { source, ...opts }) + return new Module_(ctx) } /** @@ -7544,12 +5788,8 @@ export class ModuleDependency extends BaseClient { /** * Constructor is used for internal usage only, do not create object from it. */ - constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, - _id?: ModuleDependencyID, - _name?: string, - ) { - super(parent) + constructor(ctx?: Context, _id?: ModuleDependencyID, _name?: string) { + super(ctx) this._id = _id this._name = _name @@ -7563,15 +5803,9 @@ export class ModuleDependency extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -7584,15 +5818,9 @@ export class ModuleDependency extends BaseClient { return this._name } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "name", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("name") + + const response: Awaited = await ctx.execute() return response } @@ -7601,15 +5829,8 @@ export class ModuleDependency extends BaseClient { * The source for the dependency module. */ source = (): ModuleSource => { - return new ModuleSource({ - queryTree: [ - ...this._queryTree, - { - operation: "source", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("source") + return new ModuleSource(ctx) } } @@ -7632,7 +5853,7 @@ export class ModuleSource extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, + ctx?: Context, _id?: ModuleSourceID, _asString?: string, _configExists?: boolean, @@ -7644,7 +5865,7 @@ export class ModuleSource extends BaseClient { _sourceRootSubpath?: string, _sourceSubpath?: string, ) { - super(parent) + super(ctx) this._id = _id this._asString = _asString @@ -7666,15 +5887,9 @@ export class ModuleSource extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -7683,30 +5898,16 @@ export class ModuleSource extends BaseClient { * If the source is a of kind git, the git source representation of it. */ asGitSource = (): GitModuleSource => { - return new GitModuleSource({ - queryTree: [ - ...this._queryTree, - { - operation: "asGitSource", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("asGitSource") + return new GitModuleSource(ctx) } /** * If the source is of kind local, the local source representation of it. */ asLocalSource = (): LocalModuleSource => { - return new LocalModuleSource({ - queryTree: [ - ...this._queryTree, - { - operation: "asLocalSource", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("asLocalSource") + return new LocalModuleSource(ctx) } /** @@ -7714,16 +5915,8 @@ export class ModuleSource extends BaseClient { * @param opts.engineVersion The engine version to upgrade to. */ asModule = (opts?: ModuleSourceAsModuleOpts): Module_ => { - return new Module_({ - queryTree: [ - ...this._queryTree, - { - operation: "asModule", - args: { ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("asModule", { ...opts }) + return new Module_(ctx) } /** @@ -7734,15 +5927,9 @@ export class ModuleSource extends BaseClient { return this._asString } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "asString", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("asString") + + const response: Awaited = await ctx.execute() return response } @@ -7755,15 +5942,9 @@ export class ModuleSource extends BaseClient { return this._configExists } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "configExists", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("configExists") + + const response: Awaited = await ctx.execute() return response } @@ -7772,15 +5953,8 @@ export class ModuleSource extends BaseClient { * The directory containing everything needed to load and use the module. */ contextDirectory = (): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "contextDirectory", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("contextDirectory") + return new Directory(ctx) } /** @@ -7791,31 +5965,22 @@ export class ModuleSource extends BaseClient { id: ModuleDependencyID } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "dependencies", - }, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("dependencies").select("id") + + const response: Awaited = await ctx.execute() return response.map( (r) => new ModuleDependency( - { - queryTree: [ + new Context( + [ { operation: "loadModuleDependencyFromID", args: { id: r.id }, }, ], - ctx: this._ctx, - }, + this._ctx.getConnection(), + ), r.id, ), ) @@ -7829,15 +5994,9 @@ export class ModuleSource extends BaseClient { return this._digest } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "digest", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("digest") + + const response: Awaited = await ctx.execute() return response } @@ -7847,16 +6006,8 @@ export class ModuleSource extends BaseClient { * @param path The path from the source directory to select. */ directory = (path: string): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "directory", - args: { path }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("directory", { path }) + return new Directory(ctx) } /** @@ -7867,15 +6018,9 @@ export class ModuleSource extends BaseClient { return this._kind } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "kind", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("kind") + + const response: Awaited = await ctx.execute() return response } @@ -7888,15 +6033,9 @@ export class ModuleSource extends BaseClient { return this._moduleName } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "moduleName", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("moduleName") + + const response: Awaited = await ctx.execute() return response } @@ -7909,15 +6048,9 @@ export class ModuleSource extends BaseClient { return this._moduleOriginalName } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "moduleOriginalName", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("moduleOriginalName") + + const response: Awaited = await ctx.execute() return response } @@ -7930,15 +6063,9 @@ export class ModuleSource extends BaseClient { return this._resolveContextPathFromCaller } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "resolveContextPathFromCaller", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("resolveContextPathFromCaller") + + const response: Awaited = await ctx.execute() return response } @@ -7948,16 +6075,8 @@ export class ModuleSource extends BaseClient { * @param dep The dependency module source to resolve. */ resolveDependency = (dep: ModuleSource): ModuleSource => { - return new ModuleSource({ - queryTree: [ - ...this._queryTree, - { - operation: "resolveDependency", - args: { dep }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("resolveDependency", { dep }) + return new ModuleSource(ctx) } /** @@ -7970,31 +6089,19 @@ export class ModuleSource extends BaseClient { path: string, opts?: ModuleSourceResolveDirectoryFromCallerOpts, ): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "resolveDirectoryFromCaller", - args: { path, ...opts }, - }, - ], - ctx: this._ctx, + const ctx = this._ctx.select("resolveDirectoryFromCaller", { + path, + ...opts, }) + return new Directory(ctx) } /** * Load the source from its path on the caller's filesystem, including only needed+configured files and directories. Only valid for local sources. */ resolveFromCaller = (): ModuleSource => { - return new ModuleSource({ - queryTree: [ - ...this._queryTree, - { - operation: "resolveFromCaller", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("resolveFromCaller") + return new ModuleSource(ctx) } /** @@ -8005,15 +6112,9 @@ export class ModuleSource extends BaseClient { return this._sourceRootSubpath } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "sourceRootSubpath", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("sourceRootSubpath") + + const response: Awaited = await ctx.execute() return response } @@ -8026,15 +6127,9 @@ export class ModuleSource extends BaseClient { return this._sourceSubpath } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "sourceSubpath", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("sourceSubpath") + + const response: Awaited = await ctx.execute() return response } @@ -8044,16 +6139,8 @@ export class ModuleSource extends BaseClient { * @param name The name of the view to retrieve. */ view = (name: string): ModuleSourceView => { - return new ModuleSourceView({ - queryTree: [ - ...this._queryTree, - { - operation: "view", - args: { name }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("view", { name }) + return new ModuleSourceView(ctx) } /** @@ -8064,31 +6151,22 @@ export class ModuleSource extends BaseClient { id: ModuleSourceViewID } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "views", - }, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("views").select("id") + + const response: Awaited = await ctx.execute() return response.map( (r) => new ModuleSourceView( - { - queryTree: [ + new Context( + [ { operation: "loadModuleSourceViewFromID", args: { id: r.id }, }, ], - ctx: this._ctx, - }, + this._ctx.getConnection(), + ), r.id, ), ) @@ -8099,16 +6177,8 @@ export class ModuleSource extends BaseClient { * @param dir The directory to set as the context directory. */ withContextDirectory = (dir: Directory): ModuleSource => { - return new ModuleSource({ - queryTree: [ - ...this._queryTree, - { - operation: "withContextDirectory", - args: { dir }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withContextDirectory", { dir }) + return new ModuleSource(ctx) } /** @@ -8116,16 +6186,8 @@ export class ModuleSource extends BaseClient { * @param dependencies The dependencies to append. */ withDependencies = (dependencies: ModuleDependency[]): ModuleSource => { - return new ModuleSource({ - queryTree: [ - ...this._queryTree, - { - operation: "withDependencies", - args: { dependencies }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withDependencies", { dependencies }) + return new ModuleSource(ctx) } /** @@ -8133,16 +6195,8 @@ export class ModuleSource extends BaseClient { * @param opts.merge Merge module dependencies into the current project's */ withInit = (opts?: ModuleSourceWithInitOpts): ModuleSource => { - return new ModuleSource({ - queryTree: [ - ...this._queryTree, - { - operation: "withInit", - args: { ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withInit", { ...opts }) + return new ModuleSource(ctx) } /** @@ -8150,16 +6204,8 @@ export class ModuleSource extends BaseClient { * @param name The name to set. */ withName = (name: string): ModuleSource => { - return new ModuleSource({ - queryTree: [ - ...this._queryTree, - { - operation: "withName", - args: { name }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withName", { name }) + return new ModuleSource(ctx) } /** @@ -8167,16 +6213,8 @@ export class ModuleSource extends BaseClient { * @param sdk The SDK to set. */ withSDK = (sdk: string): ModuleSource => { - return new ModuleSource({ - queryTree: [ - ...this._queryTree, - { - operation: "withSDK", - args: { sdk }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withSDK", { sdk }) + return new ModuleSource(ctx) } /** @@ -8184,16 +6222,8 @@ export class ModuleSource extends BaseClient { * @param path The path to set as the source subpath. */ withSourceSubpath = (path: string): ModuleSource => { - return new ModuleSource({ - queryTree: [ - ...this._queryTree, - { - operation: "withSourceSubpath", - args: { path }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withSourceSubpath", { path }) + return new ModuleSource(ctx) } /** @@ -8202,16 +6232,8 @@ export class ModuleSource extends BaseClient { * @param patterns The patterns to set as the view filters. */ withView = (name: string, patterns: string[]): ModuleSource => { - return new ModuleSource({ - queryTree: [ - ...this._queryTree, - { - operation: "withView", - args: { name, patterns }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withView", { name, patterns }) + return new ModuleSource(ctx) } /** @@ -8219,16 +6241,8 @@ export class ModuleSource extends BaseClient { * @param dependencies The dependencies to remove. */ withoutDependencies = (dependencies: string[]): ModuleSource => { - return new ModuleSource({ - queryTree: [ - ...this._queryTree, - { - operation: "withoutDependencies", - args: { dependencies }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withoutDependencies", { dependencies }) + return new ModuleSource(ctx) } /** @@ -8251,12 +6265,8 @@ export class ModuleSourceView extends BaseClient { /** * Constructor is used for internal usage only, do not create object from it. */ - constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, - _id?: ModuleSourceViewID, - _name?: string, - ) { - super(parent) + constructor(ctx?: Context, _id?: ModuleSourceViewID, _name?: string) { + super(ctx) this._id = _id this._name = _name @@ -8270,15 +6280,9 @@ export class ModuleSourceView extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -8291,15 +6295,9 @@ export class ModuleSourceView extends BaseClient { return this._name } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "name", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("name") + + const response: Awaited = await ctx.execute() return response } @@ -8308,15 +6306,9 @@ export class ModuleSourceView extends BaseClient { * The patterns of the view used to filter paths */ patterns = async (): Promise => { - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "patterns", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("patterns") + + const response: Awaited = await ctx.execute() return response } @@ -8335,13 +6327,13 @@ export class ObjectTypeDef extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, + ctx?: Context, _id?: ObjectTypeDefID, _description?: string, _name?: string, _sourceModuleName?: string, ) { - super(parent) + super(ctx) this._id = _id this._description = _description @@ -8357,15 +6349,9 @@ export class ObjectTypeDef extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -8374,15 +6360,8 @@ export class ObjectTypeDef extends BaseClient { * The function used to construct new instances of this object, if any */ constructor_ = (): Function_ => { - return new Function_({ - queryTree: [ - ...this._queryTree, - { - operation: "constructor", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("constructor") + return new Function_(ctx) } /** @@ -8393,15 +6372,9 @@ export class ObjectTypeDef extends BaseClient { return this._description } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "description", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("description") + + const response: Awaited = await ctx.execute() return response } @@ -8414,31 +6387,22 @@ export class ObjectTypeDef extends BaseClient { id: FieldTypeDefID } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "fields", - }, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("fields").select("id") + + const response: Awaited = await ctx.execute() return response.map( (r) => new FieldTypeDef( - { - queryTree: [ + new Context( + [ { operation: "loadFieldTypeDefFromID", args: { id: r.id }, }, ], - ctx: this._ctx, - }, + this._ctx.getConnection(), + ), r.id, ), ) @@ -8452,31 +6416,22 @@ export class ObjectTypeDef extends BaseClient { id: FunctionID } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "functions", - }, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("functions").select("id") + + const response: Awaited = await ctx.execute() return response.map( (r) => new Function_( - { - queryTree: [ + new Context( + [ { operation: "loadFunction_FromID", args: { id: r.id }, }, ], - ctx: this._ctx, - }, + this._ctx.getConnection(), + ), r.id, ), ) @@ -8490,15 +6445,9 @@ export class ObjectTypeDef extends BaseClient { return this._name } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "name", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("name") + + const response: Awaited = await ctx.execute() return response } @@ -8507,15 +6456,8 @@ export class ObjectTypeDef extends BaseClient { * The location of this object declaration. */ sourceMap = (): SourceMap => { - return new SourceMap({ - queryTree: [ - ...this._queryTree, - { - operation: "sourceMap", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("sourceMap") + return new SourceMap(ctx) } /** @@ -8526,15 +6468,9 @@ export class ObjectTypeDef extends BaseClient { return this._sourceModuleName } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "sourceModuleName", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("sourceModuleName") + + const response: Awaited = await ctx.execute() return response } @@ -8554,14 +6490,14 @@ export class Port extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, + ctx?: Context, _id?: PortID, _description?: string, _experimentalSkipHealthcheck?: boolean, _port?: number, _protocol?: NetworkProtocol, ) { - super(parent) + super(ctx) this._id = _id this._description = _description @@ -8578,15 +6514,9 @@ export class Port extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -8599,15 +6529,9 @@ export class Port extends BaseClient { return this._description } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "description", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("description") + + const response: Awaited = await ctx.execute() return response } @@ -8620,15 +6544,9 @@ export class Port extends BaseClient { return this._experimentalSkipHealthcheck } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "experimentalSkipHealthcheck", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("experimentalSkipHealthcheck") + + const response: Awaited = await ctx.execute() return response } @@ -8641,15 +6559,9 @@ export class Port extends BaseClient { return this._port } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "port", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("port") + + const response: Awaited = await ctx.execute() return response } @@ -8662,15 +6574,9 @@ export class Port extends BaseClient { return this._protocol } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "protocol", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("protocol") + + const response: Awaited = await ctx.execute() return response } @@ -8686,12 +6592,8 @@ export class Client extends BaseClient { /** * Constructor is used for internal usage only, do not create object from it. */ - constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, - _defaultPlatform?: Platform, - _version?: string, - ) { - super(parent) + constructor(ctx?: Context, _defaultPlatform?: Platform, _version?: string) { + super(ctx) this._defaultPlatform = _defaultPlatform this._version = _version @@ -8709,16 +6611,8 @@ export class Client extends BaseClient { * @param digest Digest of the blob */ blob = (digest: string): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "blob", - args: { digest }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("blob", { digest }) + return new Directory(ctx) } /** @@ -8726,16 +6620,8 @@ export class Client extends BaseClient { * @param digest Digest of the image manifest */ builtinContainer = (digest: string): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "builtinContainer", - args: { digest }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("builtinContainer", { digest }) + return new Container(ctx) } /** @@ -8743,16 +6629,8 @@ export class Client extends BaseClient { * @param key A string identifier to target this cache volume (e.g., "modules-cache"). */ cacheVolume = (key: string): CacheVolume => { - return new CacheVolume({ - queryTree: [ - ...this._queryTree, - { - operation: "cacheVolume", - args: { key }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("cacheVolume", { key }) + return new CacheVolume(ctx) } /** @@ -8762,16 +6640,8 @@ export class Client extends BaseClient { * @param opts.platform Platform to initialize the container with. */ container = (opts?: ClientContainerOpts): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "container", - args: { ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("container", { ...opts }) + return new Container(ctx) } /** @@ -8780,30 +6650,16 @@ export class Client extends BaseClient { * If the caller is not currently executing in a function, this will return an error. */ currentFunctionCall = (): FunctionCall => { - return new FunctionCall({ - queryTree: [ - ...this._queryTree, - { - operation: "currentFunctionCall", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("currentFunctionCall") + return new FunctionCall(ctx) } /** * The module currently being served in the session, if any. */ currentModule = (): CurrentModule => { - return new CurrentModule({ - queryTree: [ - ...this._queryTree, - { - operation: "currentModule", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("currentModule") + return new CurrentModule(ctx) } /** @@ -8814,31 +6670,22 @@ export class Client extends BaseClient { id: TypeDefID } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "currentTypeDefs", - }, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("currentTypeDefs").select("id") + + const response: Awaited = await ctx.execute() return response.map( (r) => new TypeDef( - { - queryTree: [ + new Context( + [ { operation: "loadTypeDefFromID", args: { id: r.id }, }, ], - ctx: this._ctx, - }, + this._ctx.getConnection(), + ), r.id, ), ) @@ -8848,15 +6695,9 @@ export class Client extends BaseClient { * The default platform of the engine. */ defaultPlatform = async (): Promise => { - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "defaultPlatform", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("defaultPlatform") + + const response: Awaited = await ctx.execute() return response } @@ -8865,30 +6706,16 @@ export class Client extends BaseClient { * Creates an empty directory. */ directory = (): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "directory", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("directory") + return new Directory(ctx) } /** * The Dagger engine container configuration and state */ engine = (): Engine => { - return new Engine({ - queryTree: [ - ...this._queryTree, - { - operation: "engine", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("engine") + return new Engine(ctx) } /** @@ -8896,16 +6723,8 @@ export class Client extends BaseClient { * @param message A brief description of the error. */ error = (message: string): Error => { - return new Error({ - queryTree: [ - ...this._queryTree, - { - operation: "error", - args: { message }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("error", { message }) + return new Error(ctx) } /** @@ -8914,32 +6733,16 @@ export class Client extends BaseClient { * @param returnType Return type of the function. */ function_ = (name: string, returnType: TypeDef): Function_ => { - return new Function_({ - queryTree: [ - ...this._queryTree, - { - operation: "function", - args: { name, returnType }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("function", { name, returnType }) + return new Function_(ctx) } /** * Create a code generation result, given a directory containing the generated code. */ generatedCode = (code: Directory): GeneratedCode => { - return new GeneratedCode({ - queryTree: [ - ...this._queryTree, - { - operation: "generatedCode", - args: { code }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("generatedCode", { code }) + return new GeneratedCode(ctx) } /** @@ -8955,31 +6758,16 @@ export class Client extends BaseClient { * @param opts.sshAuthSocket Set SSH auth socket */ git = (url: string, opts?: ClientGitOpts): GitRepository => { - return new GitRepository({ - queryTree: [ - ...this._queryTree, - { - operation: "git", - args: { url, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("git", { url, ...opts }) + return new GitRepository(ctx) } /** * Queries the host environment. */ host = (): Host => { - return new Host({ - queryTree: [ - ...this._queryTree, - { - operation: "host", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("host") + return new Host(ctx) } /** @@ -8988,96 +6776,48 @@ export class Client extends BaseClient { * @param opts.experimentalServiceHost A service which must be started before the URL is fetched. */ http = (url: string, opts?: ClientHttpOpts): File => { - return new File({ - queryTree: [ - ...this._queryTree, - { - operation: "http", - args: { url, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("http", { url, ...opts }) + return new File(ctx) } /** * Load a CacheVolume from its ID. */ loadCacheVolumeFromID = (id: CacheVolumeID): CacheVolume => { - return new CacheVolume({ - queryTree: [ - ...this._queryTree, - { - operation: "loadCacheVolumeFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadCacheVolumeFromID", { id }) + return new CacheVolume(ctx) } /** * Load a Container from its ID. */ loadContainerFromID = (id: ContainerID): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "loadContainerFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadContainerFromID", { id }) + return new Container(ctx) } /** * Load a CurrentModule from its ID. */ loadCurrentModuleFromID = (id: CurrentModuleID): CurrentModule => { - return new CurrentModule({ - queryTree: [ - ...this._queryTree, - { - operation: "loadCurrentModuleFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadCurrentModuleFromID", { id }) + return new CurrentModule(ctx) } /** * Load a Directory from its ID. */ loadDirectoryFromID = (id: DirectoryID): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "loadDirectoryFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadDirectoryFromID", { id }) + return new Directory(ctx) } /** * Load a EngineCacheEntry from its ID. */ loadEngineCacheEntryFromID = (id: EngineCacheEntryID): EngineCacheEntry => { - return new EngineCacheEntry({ - queryTree: [ - ...this._queryTree, - { - operation: "loadEngineCacheEntryFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadEngineCacheEntryFromID", { id }) + return new EngineCacheEntry(ctx) } /** @@ -9086,160 +6826,80 @@ export class Client extends BaseClient { loadEngineCacheEntrySetFromID = ( id: EngineCacheEntrySetID, ): EngineCacheEntrySet => { - return new EngineCacheEntrySet({ - queryTree: [ - ...this._queryTree, - { - operation: "loadEngineCacheEntrySetFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadEngineCacheEntrySetFromID", { id }) + return new EngineCacheEntrySet(ctx) } /** * Load a EngineCache from its ID. */ loadEngineCacheFromID = (id: EngineCacheID): EngineCache => { - return new EngineCache({ - queryTree: [ - ...this._queryTree, - { - operation: "loadEngineCacheFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadEngineCacheFromID", { id }) + return new EngineCache(ctx) } /** * Load a Engine from its ID. */ loadEngineFromID = (id: EngineID): Engine => { - return new Engine({ - queryTree: [ - ...this._queryTree, - { - operation: "loadEngineFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadEngineFromID", { id }) + return new Engine(ctx) } /** * Load a EnumTypeDef from its ID. */ loadEnumTypeDefFromID = (id: EnumTypeDefID): EnumTypeDef => { - return new EnumTypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "loadEnumTypeDefFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadEnumTypeDefFromID", { id }) + return new EnumTypeDef(ctx) } /** * Load a EnumValueTypeDef from its ID. */ loadEnumValueTypeDefFromID = (id: EnumValueTypeDefID): EnumValueTypeDef => { - return new EnumValueTypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "loadEnumValueTypeDefFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadEnumValueTypeDefFromID", { id }) + return new EnumValueTypeDef(ctx) } /** * Load a EnvVariable from its ID. */ loadEnvVariableFromID = (id: EnvVariableID): EnvVariable => { - return new EnvVariable({ - queryTree: [ - ...this._queryTree, - { - operation: "loadEnvVariableFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadEnvVariableFromID", { id }) + return new EnvVariable(ctx) } /** * Load a Error from its ID. */ loadErrorFromID = (id: ErrorID): Error => { - return new Error({ - queryTree: [ - ...this._queryTree, - { - operation: "loadErrorFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadErrorFromID", { id }) + return new Error(ctx) } /** * Load a FieldTypeDef from its ID. */ loadFieldTypeDefFromID = (id: FieldTypeDefID): FieldTypeDef => { - return new FieldTypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "loadFieldTypeDefFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadFieldTypeDefFromID", { id }) + return new FieldTypeDef(ctx) } /** * Load a File from its ID. */ loadFileFromID = (id: FileID): File => { - return new File({ - queryTree: [ - ...this._queryTree, - { - operation: "loadFileFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadFileFromID", { id }) + return new File(ctx) } /** * Load a FunctionArg from its ID. */ loadFunctionArgFromID = (id: FunctionArgID): FunctionArg => { - return new FunctionArg({ - queryTree: [ - ...this._queryTree, - { - operation: "loadFunctionArgFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadFunctionArgFromID", { id }) + return new FunctionArg(ctx) } /** @@ -9248,192 +6908,96 @@ export class Client extends BaseClient { loadFunctionCallArgValueFromID = ( id: FunctionCallArgValueID, ): FunctionCallArgValue => { - return new FunctionCallArgValue({ - queryTree: [ - ...this._queryTree, - { - operation: "loadFunctionCallArgValueFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadFunctionCallArgValueFromID", { id }) + return new FunctionCallArgValue(ctx) } /** * Load a FunctionCall from its ID. */ loadFunctionCallFromID = (id: FunctionCallID): FunctionCall => { - return new FunctionCall({ - queryTree: [ - ...this._queryTree, - { - operation: "loadFunctionCallFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadFunctionCallFromID", { id }) + return new FunctionCall(ctx) } /** * Load a Function from its ID. */ loadFunctionFromID = (id: FunctionID): Function_ => { - return new Function_({ - queryTree: [ - ...this._queryTree, - { - operation: "loadFunctionFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadFunctionFromID", { id }) + return new Function_(ctx) } /** * Load a GeneratedCode from its ID. */ loadGeneratedCodeFromID = (id: GeneratedCodeID): GeneratedCode => { - return new GeneratedCode({ - queryTree: [ - ...this._queryTree, - { - operation: "loadGeneratedCodeFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadGeneratedCodeFromID", { id }) + return new GeneratedCode(ctx) } /** * Load a GitModuleSource from its ID. */ loadGitModuleSourceFromID = (id: GitModuleSourceID): GitModuleSource => { - return new GitModuleSource({ - queryTree: [ - ...this._queryTree, - { - operation: "loadGitModuleSourceFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadGitModuleSourceFromID", { id }) + return new GitModuleSource(ctx) } /** * Load a GitRef from its ID. */ loadGitRefFromID = (id: GitRefID): GitRef => { - return new GitRef({ - queryTree: [ - ...this._queryTree, - { - operation: "loadGitRefFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadGitRefFromID", { id }) + return new GitRef(ctx) } /** * Load a GitRepository from its ID. */ loadGitRepositoryFromID = (id: GitRepositoryID): GitRepository => { - return new GitRepository({ - queryTree: [ - ...this._queryTree, - { - operation: "loadGitRepositoryFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadGitRepositoryFromID", { id }) + return new GitRepository(ctx) } /** * Load a Host from its ID. */ loadHostFromID = (id: HostID): Host => { - return new Host({ - queryTree: [ - ...this._queryTree, - { - operation: "loadHostFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadHostFromID", { id }) + return new Host(ctx) } /** * Load a InputTypeDef from its ID. */ loadInputTypeDefFromID = (id: InputTypeDefID): InputTypeDef => { - return new InputTypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "loadInputTypeDefFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadInputTypeDefFromID", { id }) + return new InputTypeDef(ctx) } /** * Load a InterfaceTypeDef from its ID. */ loadInterfaceTypeDefFromID = (id: InterfaceTypeDefID): InterfaceTypeDef => { - return new InterfaceTypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "loadInterfaceTypeDefFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadInterfaceTypeDefFromID", { id }) + return new InterfaceTypeDef(ctx) } /** * Load a Label from its ID. */ loadLabelFromID = (id: LabelID): Label => { - return new Label({ - queryTree: [ - ...this._queryTree, - { - operation: "loadLabelFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadLabelFromID", { id }) + return new Label(ctx) } /** * Load a ListTypeDef from its ID. */ loadListTypeDefFromID = (id: ListTypeDefID): ListTypeDef => { - return new ListTypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "loadListTypeDefFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadListTypeDefFromID", { id }) + return new ListTypeDef(ctx) } /** @@ -9442,239 +7006,120 @@ export class Client extends BaseClient { loadLocalModuleSourceFromID = ( id: LocalModuleSourceID, ): LocalModuleSource => { - return new LocalModuleSource({ - queryTree: [ - ...this._queryTree, - { - operation: "loadLocalModuleSourceFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadLocalModuleSourceFromID", { id }) + return new LocalModuleSource(ctx) } /** * Load a ModuleDependency from its ID. */ loadModuleDependencyFromID = (id: ModuleDependencyID): ModuleDependency => { - return new ModuleDependency({ - queryTree: [ - ...this._queryTree, - { - operation: "loadModuleDependencyFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadModuleDependencyFromID", { id }) + return new ModuleDependency(ctx) } /** * Load a Module from its ID. */ loadModuleFromID = (id: ModuleID): Module_ => { - return new Module_({ - queryTree: [ - ...this._queryTree, - { - operation: "loadModuleFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadModuleFromID", { id }) + return new Module_(ctx) } /** * Load a ModuleSource from its ID. */ loadModuleSourceFromID = (id: ModuleSourceID): ModuleSource => { - return new ModuleSource({ - queryTree: [ - ...this._queryTree, - { - operation: "loadModuleSourceFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadModuleSourceFromID", { id }) + return new ModuleSource(ctx) } /** * Load a ModuleSourceView from its ID. */ loadModuleSourceViewFromID = (id: ModuleSourceViewID): ModuleSourceView => { - return new ModuleSourceView({ - queryTree: [ - ...this._queryTree, - { - operation: "loadModuleSourceViewFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadModuleSourceViewFromID", { id }) + return new ModuleSourceView(ctx) } /** * Load a ObjectTypeDef from its ID. */ loadObjectTypeDefFromID = (id: ObjectTypeDefID): ObjectTypeDef => { - return new ObjectTypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "loadObjectTypeDefFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadObjectTypeDefFromID", { id }) + return new ObjectTypeDef(ctx) } /** * Load a Port from its ID. */ loadPortFromID = (id: PortID): Port => { - return new Port({ - queryTree: [ - ...this._queryTree, - { - operation: "loadPortFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadPortFromID", { id }) + return new Port(ctx) } /** * Load a ScalarTypeDef from its ID. */ loadScalarTypeDefFromID = (id: ScalarTypeDefID): ScalarTypeDef => { - return new ScalarTypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "loadScalarTypeDefFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadScalarTypeDefFromID", { id }) + return new ScalarTypeDef(ctx) } /** * Load a Secret from its ID. */ loadSecretFromID = (id: SecretID): Secret => { - return new Secret({ - queryTree: [ - ...this._queryTree, - { - operation: "loadSecretFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadSecretFromID", { id }) + return new Secret(ctx) } /** * Load a Service from its ID. */ loadServiceFromID = (id: ServiceID): Service => { - return new Service({ - queryTree: [ - ...this._queryTree, - { - operation: "loadServiceFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadServiceFromID", { id }) + return new Service(ctx) } /** * Load a Socket from its ID. */ loadSocketFromID = (id: SocketID): Socket => { - return new Socket({ - queryTree: [ - ...this._queryTree, - { - operation: "loadSocketFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadSocketFromID", { id }) + return new Socket(ctx) } /** * Load a SourceMap from its ID. */ loadSourceMapFromID = (id: SourceMapID): SourceMap => { - return new SourceMap({ - queryTree: [ - ...this._queryTree, - { - operation: "loadSourceMapFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadSourceMapFromID", { id }) + return new SourceMap(ctx) } /** * Load a Terminal from its ID. */ loadTerminalFromID = (id: TerminalID): Terminal => { - return new Terminal({ - queryTree: [ - ...this._queryTree, - { - operation: "loadTerminalFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadTerminalFromID", { id }) + return new Terminal(ctx) } /** * Load a TypeDef from its ID. */ loadTypeDefFromID = (id: TypeDefID): TypeDef => { - return new TypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "loadTypeDefFromID", - args: { id }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("loadTypeDefFromID", { id }) + return new TypeDef(ctx) } /** * Create a new module. */ module_ = (): Module_ => { - return new Module_({ - queryTree: [ - ...this._queryTree, - { - operation: "module", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("module") + return new Module_(ctx) } /** @@ -9686,16 +7131,8 @@ export class Client extends BaseClient { source: ModuleSource, opts?: ClientModuleDependencyOpts, ): ModuleDependency => { - return new ModuleDependency({ - queryTree: [ - ...this._queryTree, - { - operation: "moduleDependency", - args: { source, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("moduleDependency", { source, ...opts }) + return new ModuleDependency(ctx) } /** @@ -9709,32 +7146,16 @@ export class Client extends BaseClient { refString: string, opts?: ClientModuleSourceOpts, ): ModuleSource => { - return new ModuleSource({ - queryTree: [ - ...this._queryTree, - { - operation: "moduleSource", - args: { refString, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("moduleSource", { refString, ...opts }) + return new ModuleSource(ctx) } /** * Reference a secret by name. */ secret = (name: string, opts?: ClientSecretOpts): Secret => { - return new Secret({ - queryTree: [ - ...this._queryTree, - { - operation: "secret", - args: { name, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("secret", { name, ...opts }) + return new Secret(ctx) } /** @@ -9745,16 +7166,8 @@ export class Client extends BaseClient { * @param plaintext The plaintext of the secret */ setSecret = (name: string, plaintext: string): Secret => { - return new Secret({ - queryTree: [ - ...this._queryTree, - { - operation: "setSecret", - args: { name, plaintext }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("setSecret", { name, plaintext }) + return new Secret(ctx) } /** @@ -9764,46 +7177,25 @@ export class Client extends BaseClient { * @param column The column number within the line. */ sourceMap = (filename: string, line: number, column: number): SourceMap => { - return new SourceMap({ - queryTree: [ - ...this._queryTree, - { - operation: "sourceMap", - args: { filename, line, column }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("sourceMap", { filename, line, column }) + return new SourceMap(ctx) } /** * Create a new TypeDef. */ typeDef = (): TypeDef => { - return new TypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "typeDef", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("typeDef") + return new TypeDef(ctx) } /** * Get the current Dagger Engine version. */ version = async (): Promise => { - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "version", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("version") + + const response: Awaited = await ctx.execute() return response } @@ -9822,13 +7214,13 @@ export class ScalarTypeDef extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, + ctx?: Context, _id?: ScalarTypeDefID, _description?: string, _name?: string, _sourceModuleName?: string, ) { - super(parent) + super(ctx) this._id = _id this._description = _description @@ -9844,15 +7236,9 @@ export class ScalarTypeDef extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -9865,15 +7251,9 @@ export class ScalarTypeDef extends BaseClient { return this._description } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "description", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("description") + + const response: Awaited = await ctx.execute() return response } @@ -9886,15 +7266,9 @@ export class ScalarTypeDef extends BaseClient { return this._name } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "name", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("name") + + const response: Awaited = await ctx.execute() return response } @@ -9907,15 +7281,9 @@ export class ScalarTypeDef extends BaseClient { return this._sourceModuleName } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "sourceModuleName", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("sourceModuleName") + + const response: Awaited = await ctx.execute() return response } @@ -9933,12 +7301,12 @@ export class Secret extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, + ctx?: Context, _id?: SecretID, _name?: string, _plaintext?: string, ) { - super(parent) + super(ctx) this._id = _id this._name = _name @@ -9953,15 +7321,9 @@ export class Secret extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -9974,15 +7336,9 @@ export class Secret extends BaseClient { return this._name } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "name", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("name") + + const response: Awaited = await ctx.execute() return response } @@ -9995,15 +7351,9 @@ export class Secret extends BaseClient { return this._plaintext } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "plaintext", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("plaintext") + + const response: Awaited = await ctx.execute() return response } @@ -10024,7 +7374,7 @@ export class Service extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, + ctx?: Context, _id?: ServiceID, _endpoint?: string, _hostname?: string, @@ -10032,7 +7382,7 @@ export class Service extends BaseClient { _stop?: ServiceID, _up?: Void, ) { - super(parent) + super(ctx) this._id = _id this._endpoint = _endpoint @@ -10050,15 +7400,9 @@ export class Service extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -10077,16 +7421,9 @@ export class Service extends BaseClient { return this._endpoint } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "endpoint", - args: { ...opts }, - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("endpoint", { ...opts }) + + const response: Awaited = await ctx.execute() return response } @@ -10099,15 +7436,9 @@ export class Service extends BaseClient { return this._hostname } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "hostname", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("hostname") + + const response: Awaited = await ctx.execute() return response } @@ -10120,31 +7451,22 @@ export class Service extends BaseClient { id: PortID } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "ports", - }, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("ports").select("id") + + const response: Awaited = await ctx.execute() return response.map( (r) => new Port( - { - queryTree: [ + new Context( + [ { operation: "loadPortFromID", args: { id: r.id }, }, ], - ctx: this._ctx, - }, + this._ctx.getConnection(), + ), r.id, ), ) @@ -10156,25 +7478,21 @@ export class Service extends BaseClient { * Services bound to a Container do not need to be manually started. */ start = async (): Promise => { - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "start", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("start") - return new Service({ - queryTree: [ - { - operation: "loadServiceFromID", - args: { id: response }, - }, - ], - ctx: this._ctx, - }) + const response: Awaited = await ctx.execute() + + return new Service( + new Context( + [ + { + operation: "loadServiceFromID", + args: { id: response }, + }, + ], + this._ctx.getConnection(), + ), + ) } /** @@ -10182,26 +7500,21 @@ export class Service extends BaseClient { * @param opts.kill Immediately kill the service without waiting for a graceful exit */ stop = async (opts?: ServiceStopOpts): Promise => { - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "stop", - args: { ...opts }, - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("stop", { ...opts }) - return new Service({ - queryTree: [ - { - operation: "loadServiceFromID", - args: { id: response }, - }, - ], - ctx: this._ctx, - }) + const response: Awaited = await ctx.execute() + + return new Service( + new Context( + [ + { + operation: "loadServiceFromID", + args: { id: response }, + }, + ], + this._ctx.getConnection(), + ), + ) } /** @@ -10216,16 +7529,9 @@ export class Service extends BaseClient { return } - await computeQuery( - [ - ...this._queryTree, - { - operation: "up", - args: { ...opts }, - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("up", { ...opts }) + + await ctx.execute() } /** @@ -10233,16 +7539,8 @@ export class Service extends BaseClient { * @param hostname The hostname to use. */ withHostname = (hostname: string): Service => { - return new Service({ - queryTree: [ - ...this._queryTree, - { - operation: "withHostname", - args: { hostname }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withHostname", { hostname }) + return new Service(ctx) } /** @@ -10264,11 +7562,8 @@ export class Socket extends BaseClient { /** * Constructor is used for internal usage only, do not create object from it. */ - constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, - _id?: SocketID, - ) { - super(parent) + constructor(ctx?: Context, _id?: SocketID) { + super(ctx) this._id = _id } @@ -10281,15 +7576,9 @@ export class Socket extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -10309,14 +7598,14 @@ export class SourceMap extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, + ctx?: Context, _id?: SourceMapID, _column?: number, _filename?: string, _line?: number, _module?: string, ) { - super(parent) + super(ctx) this._id = _id this._column = _column @@ -10333,15 +7622,9 @@ export class SourceMap extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -10354,15 +7637,9 @@ export class SourceMap extends BaseClient { return this._column } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "column", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("column") + + const response: Awaited = await ctx.execute() return response } @@ -10375,15 +7652,9 @@ export class SourceMap extends BaseClient { return this._filename } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "filename", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("filename") + + const response: Awaited = await ctx.execute() return response } @@ -10396,15 +7667,9 @@ export class SourceMap extends BaseClient { return this._line } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "line", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("line") + + const response: Awaited = await ctx.execute() return response } @@ -10417,15 +7682,9 @@ export class SourceMap extends BaseClient { return this._module } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "module", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("module") + + const response: Awaited = await ctx.execute() return response } @@ -10441,12 +7700,8 @@ export class Terminal extends BaseClient { /** * Constructor is used for internal usage only, do not create object from it. */ - constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, - _id?: TerminalID, - _sync?: TerminalID, - ) { - super(parent) + constructor(ctx?: Context, _id?: TerminalID, _sync?: TerminalID) { + super(ctx) this._id = _id this._sync = _sync @@ -10460,15 +7715,9 @@ export class Terminal extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -10479,25 +7728,21 @@ export class Terminal extends BaseClient { * It doesn't run the default command if no exec has been set. */ sync = async (): Promise => { - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "sync", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("sync") - return new Terminal({ - queryTree: [ - { - operation: "loadTerminalFromID", - args: { id: response }, - }, - ], - ctx: this._ctx, - }) + const response: Awaited = await ctx.execute() + + return new Terminal( + new Context( + [ + { + operation: "loadTerminalFromID", + args: { id: response }, + }, + ], + this._ctx.getConnection(), + ), + ) } } @@ -10513,12 +7758,12 @@ export class TypeDef extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[]; ctx: Context }, + ctx?: Context, _id?: TypeDefID, _kind?: TypeDefKind, _optional?: boolean, ) { - super(parent) + super(ctx) this._id = _id this._kind = _kind @@ -10533,15 +7778,9 @@ export class TypeDef extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("id") + + const response: Awaited = await ctx.execute() return response } @@ -10550,90 +7789,48 @@ export class TypeDef extends BaseClient { * If kind is ENUM, the enum-specific type definition. If kind is not ENUM, this will be null. */ asEnum = (): EnumTypeDef => { - return new EnumTypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "asEnum", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("asEnum") + return new EnumTypeDef(ctx) } /** * If kind is INPUT, the input-specific type definition. If kind is not INPUT, this will be null. */ asInput = (): InputTypeDef => { - return new InputTypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "asInput", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("asInput") + return new InputTypeDef(ctx) } /** * If kind is INTERFACE, the interface-specific type definition. If kind is not INTERFACE, this will be null. */ asInterface = (): InterfaceTypeDef => { - return new InterfaceTypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "asInterface", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("asInterface") + return new InterfaceTypeDef(ctx) } /** * If kind is LIST, the list-specific type definition. If kind is not LIST, this will be null. */ asList = (): ListTypeDef => { - return new ListTypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "asList", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("asList") + return new ListTypeDef(ctx) } /** * If kind is OBJECT, the object-specific type definition. If kind is not OBJECT, this will be null. */ asObject = (): ObjectTypeDef => { - return new ObjectTypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "asObject", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("asObject") + return new ObjectTypeDef(ctx) } /** * If kind is SCALAR, the scalar-specific type definition. If kind is not SCALAR, this will be null. */ asScalar = (): ScalarTypeDef => { - return new ScalarTypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "asScalar", - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("asScalar") + return new ScalarTypeDef(ctx) } /** @@ -10644,15 +7841,9 @@ export class TypeDef extends BaseClient { return this._kind } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "kind", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("kind") + + const response: Awaited = await ctx.execute() return response } @@ -10665,15 +7856,9 @@ export class TypeDef extends BaseClient { return this._optional } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "optional", - }, - ], - await this._ctx.connection(), - ) + const ctx = this._ctx.select("optional") + + const response: Awaited = await ctx.execute() return response } @@ -10682,18 +7867,10 @@ export class TypeDef extends BaseClient { * Adds a function for constructing a new instance of an Object TypeDef, failing if the type is not an object. */ withConstructor = (function_: Function_): TypeDef => { - return new TypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "withConstructor", - args: { - function: function_, - }, - }, - ], - ctx: this._ctx, + const ctx = this._ctx.select("withConstructor", { + function: function_, }) + return new TypeDef(ctx) } /** @@ -10705,16 +7882,8 @@ export class TypeDef extends BaseClient { * @param opts.sourceMap The source map for the enum definition. */ withEnum = (name: string, opts?: TypeDefWithEnumOpts): TypeDef => { - return new TypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "withEnum", - args: { name, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withEnum", { name, ...opts }) + return new TypeDef(ctx) } /** @@ -10724,16 +7893,8 @@ export class TypeDef extends BaseClient { * @param opts.sourceMap The source map for the enum value definition. */ withEnumValue = (value: string, opts?: TypeDefWithEnumValueOpts): TypeDef => { - return new TypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "withEnumValue", - args: { value, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withEnumValue", { value, ...opts }) + return new TypeDef(ctx) } /** @@ -10748,86 +7909,46 @@ export class TypeDef extends BaseClient { typeDef: TypeDef, opts?: TypeDefWithFieldOpts, ): TypeDef => { - return new TypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "withField", - args: { name, typeDef, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withField", { name, typeDef, ...opts }) + return new TypeDef(ctx) } /** * Adds a function for an Object or Interface TypeDef, failing if the type is not one of those kinds. */ withFunction = (function_: Function_): TypeDef => { - return new TypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "withFunction", - args: { - function: function_, - }, - }, - ], - ctx: this._ctx, + const ctx = this._ctx.select("withFunction", { + function: function_, }) + return new TypeDef(ctx) } /** * Returns a TypeDef of kind Interface with the provided name. */ withInterface = (name: string, opts?: TypeDefWithInterfaceOpts): TypeDef => { - return new TypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "withInterface", - args: { name, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withInterface", { name, ...opts }) + return new TypeDef(ctx) } /** * Sets the kind of the type. */ withKind = (kind: TypeDefKind): TypeDef => { - const metadata: Metadata = { + const metadata = { kind: { is_enum: true }, } - return new TypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "withKind", - args: { kind, __metadata: metadata }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withKind", { kind, __metadata: metadata }) + return new TypeDef(ctx) } /** * Returns a TypeDef of kind List with the provided type for its elements. */ withListOf = (elementType: TypeDef): TypeDef => { - return new TypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "withListOf", - args: { elementType }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withListOf", { elementType }) + return new TypeDef(ctx) } /** @@ -10836,48 +7957,24 @@ export class TypeDef extends BaseClient { * Note that an object's fields and functions may be omitted if the intent is only to refer to an object. This is how functions are able to return their own object, or any other circular reference. */ withObject = (name: string, opts?: TypeDefWithObjectOpts): TypeDef => { - return new TypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "withObject", - args: { name, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withObject", { name, ...opts }) + return new TypeDef(ctx) } /** * Sets whether this type can be set to null. */ withOptional = (optional: boolean): TypeDef => { - return new TypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "withOptional", - args: { optional }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withOptional", { optional }) + return new TypeDef(ctx) } /** * Returns a TypeDef of kind Scalar with the provided name. */ withScalar = (name: string, opts?: TypeDefWithScalarOpts): TypeDef => { - return new TypeDef({ - queryTree: [ - ...this._queryTree, - { - operation: "withScalar", - args: { name, ...opts }, - }, - ], - ctx: this._ctx, - }) + const ctx = this._ctx.select("withScalar", { name, ...opts }) + return new TypeDef(ctx) } /** @@ -10890,4 +7987,4 @@ export class TypeDef extends BaseClient { } } -export const dag = new Client({ ctx: defaultContext }) +export const dag = new Client() diff --git a/sdk/typescript/api/test/api.spec.ts b/sdk/typescript/src/api/test/api.spec.ts similarity index 93% rename from sdk/typescript/api/test/api.spec.ts rename to sdk/typescript/src/api/test/api.spec.ts index ec4ec50eeb..34951a8e6f 100644 --- a/sdk/typescript/api/test/api.spec.ts +++ b/sdk/typescript/src/api/test/api.spec.ts @@ -6,6 +6,7 @@ import { ExecError, TooManyNestedObjectsError, } from "../../common/errors/index.js" +import { buildQuery, queryFlatten } from "../../common/graphql/compute_query.js" import { Client, ClientContainerOpts, @@ -14,7 +15,6 @@ import { Directory, NetworkProtocol, } from "../../index.js" -import { buildQuery, queryFlatten } from "../utils.js" const querySanitizer = (query: string) => query.replace(/\s+/g, " ") @@ -23,7 +23,7 @@ describe("TypeScript SDK api", function () { const tree = new Client().container().from("alpine:3.16.2") assert.strictEqual( - querySanitizer(buildQuery(tree.queryTree)), + querySanitizer(buildQuery(tree["_ctx"]["_queryTree"])), `{ container { from (address: "alpine:3.16.2") } }`, ) }) @@ -32,14 +32,14 @@ describe("TypeScript SDK api", function () { const tree = new Client().container().from("alpine:3.16.2") assert.strictEqual( - querySanitizer(buildQuery(tree.queryTree)), + querySanitizer(buildQuery(tree["_ctx"]["_queryTree"])), `{ container { from (address: "alpine:3.16.2") } }`, ) const tree2 = new Client().git("fake_url", { keepGitDir: true }) assert.strictEqual( - querySanitizer(buildQuery(tree2.queryTree)), + querySanitizer(buildQuery(tree2["_ctx"]["_queryTree"])), `{ git (url: "fake_url",keepGitDir: true) }`, ) @@ -69,7 +69,7 @@ describe("TypeScript SDK api", function () { .withExec(["apk", "add", "curl"]) assert.strictEqual( - querySanitizer(buildQuery(tree.queryTree)), + querySanitizer(buildQuery(tree["_ctx"]["_queryTree"])), `{ container { from (address: "alpine:3.16.2") { withExec (args: ["apk","add","curl"]) }} }`, ) }) @@ -79,7 +79,7 @@ describe("TypeScript SDK api", function () { const pkg = image.withExec(["echo", "foo bar"]) assert.strictEqual( - querySanitizer(buildQuery(pkg.queryTree)), + querySanitizer(buildQuery(pkg["_ctx"]["_queryTree"])), `{ container { from (address: "alpine:3.16.2") { withExec (args: ["echo","foo bar"]) }} }`, ) }) @@ -126,7 +126,7 @@ describe("TypeScript SDK api", function () { }) assert.strictEqual( - querySanitizer(buildQuery(pkg.queryTree)), + querySanitizer(buildQuery(pkg["_ctx"]["_queryTree"])), `{ container { from (address: "alpine:3.16.2") { withExec (args: ["apk","add","curl"],experimentalPrivilegedNesting: true) }} }`, ) }) @@ -135,12 +135,12 @@ describe("TypeScript SDK api", function () { const image = new Client().container().from("alpine:3.16.2") const a = image.withExec(["echo", "hello", "world"]) assert.strictEqual( - querySanitizer(buildQuery(a.queryTree)), + querySanitizer(buildQuery(a["_ctx"]["_queryTree"])), `{ container { from (address: "alpine:3.16.2") { withExec (args: ["echo","hello","world"]) }} }`, ) const b = image.withExec(["echo", "foo", "bar"]) assert.strictEqual( - querySanitizer(buildQuery(b.queryTree)), + querySanitizer(buildQuery(b["_ctx"]["_queryTree"])), `{ container { from (address: "alpine:3.16.2") { withExec (args: ["echo","foo","bar"]) }} }`, ) }) @@ -304,8 +304,8 @@ describe("TypeScript SDK api", function () { .build(new Directory(), { buildArgs: [{ value: "foo", name: "test" }] }) assert.strictEqual( - querySanitizer(buildQuery(tree.queryTree)), - `{ container { build (context: {"_queryTree":[],"_ctx":{}},buildArgs: [{value:"foo",name:"test"}]) } }`, + querySanitizer(buildQuery(tree["_ctx"]["_queryTree"])), + `{ container { build (context: {"_ctx":{"_queryTree":[],"_connection":{}}},buildArgs: [{value:"foo",name:"test"}]) } }`, ) }) @@ -333,7 +333,7 @@ describe("TypeScript SDK api", function () { await connect( async (client) => { - const seededPlatformVariants = [] + const seededPlatformVariants: Container[] = [] for (const platform in platforms) { const name = platforms[platform] diff --git a/sdk/typescript/src/common/context.ts b/sdk/typescript/src/common/context.ts new file mode 100644 index 0000000000..d902d18ac9 --- /dev/null +++ b/sdk/typescript/src/common/context.ts @@ -0,0 +1,30 @@ +import { GraphQLClient } from "graphql-request" + +import { computeQuery, QueryTree } from "./graphql/compute_query.js" +import { globalConnection } from "./graphql/connection.js" + +export class Context { + constructor( + private _queryTree: QueryTree[] = [], + private _connection = globalConnection, + ) {} + + getGQLClient(): GraphQLClient { + return this._connection.getGQLClient() + } + + getConnection() { + return this._connection + } + + select(operation: string, args?: Record): Context { + return new Context( + [...this._queryTree, { operation, args }], + this._connection, + ) + } + + execute(): Promise { + return computeQuery(this._queryTree, this._connection.getGQLClient()) + } +} diff --git a/sdk/typescript/common/errors/DaggerSDKError.ts b/sdk/typescript/src/common/errors/DaggerSDKError.ts similarity index 100% rename from sdk/typescript/common/errors/DaggerSDKError.ts rename to sdk/typescript/src/common/errors/DaggerSDKError.ts diff --git a/sdk/typescript/common/errors/DockerImageRefValidationError.ts b/sdk/typescript/src/common/errors/DockerImageRefValidationError.ts similarity index 100% rename from sdk/typescript/common/errors/DockerImageRefValidationError.ts rename to sdk/typescript/src/common/errors/DockerImageRefValidationError.ts diff --git a/sdk/typescript/common/errors/EngineSessionConnectParamsParseError.ts b/sdk/typescript/src/common/errors/EngineSessionConnectParamsParseError.ts similarity index 100% rename from sdk/typescript/common/errors/EngineSessionConnectParamsParseError.ts rename to sdk/typescript/src/common/errors/EngineSessionConnectParamsParseError.ts diff --git a/sdk/typescript/common/errors/EngineSessionConnectionTimeoutError.ts b/sdk/typescript/src/common/errors/EngineSessionConnectionTimeoutError.ts similarity index 100% rename from sdk/typescript/common/errors/EngineSessionConnectionTimeoutError.ts rename to sdk/typescript/src/common/errors/EngineSessionConnectionTimeoutError.ts diff --git a/sdk/typescript/common/errors/EngineSessionErrorOptions.ts b/sdk/typescript/src/common/errors/EngineSessionErrorOptions.ts similarity index 100% rename from sdk/typescript/common/errors/EngineSessionErrorOptions.ts rename to sdk/typescript/src/common/errors/EngineSessionErrorOptions.ts diff --git a/sdk/typescript/common/errors/ExecError.ts b/sdk/typescript/src/common/errors/ExecError.ts similarity index 100% rename from sdk/typescript/common/errors/ExecError.ts rename to sdk/typescript/src/common/errors/ExecError.ts diff --git a/sdk/typescript/common/errors/FunctionNotFound.ts b/sdk/typescript/src/common/errors/FunctionNotFound.ts similarity index 100% rename from sdk/typescript/common/errors/FunctionNotFound.ts rename to sdk/typescript/src/common/errors/FunctionNotFound.ts diff --git a/sdk/typescript/common/errors/GraphQLRequestError.ts b/sdk/typescript/src/common/errors/GraphQLRequestError.ts similarity index 100% rename from sdk/typescript/common/errors/GraphQLRequestError.ts rename to sdk/typescript/src/common/errors/GraphQLRequestError.ts diff --git a/sdk/typescript/common/errors/InitEngineSessionBinaryError.ts b/sdk/typescript/src/common/errors/InitEngineSessionBinaryError.ts similarity index 100% rename from sdk/typescript/common/errors/InitEngineSessionBinaryError.ts rename to sdk/typescript/src/common/errors/InitEngineSessionBinaryError.ts diff --git a/sdk/typescript/common/errors/IntrospectionError.ts b/sdk/typescript/src/common/errors/IntrospectionError.ts similarity index 100% rename from sdk/typescript/common/errors/IntrospectionError.ts rename to sdk/typescript/src/common/errors/IntrospectionError.ts diff --git a/sdk/typescript/common/errors/NotAwaitedRequestError.ts b/sdk/typescript/src/common/errors/NotAwaitedRequestError.ts similarity index 100% rename from sdk/typescript/common/errors/NotAwaitedRequestError.ts rename to sdk/typescript/src/common/errors/NotAwaitedRequestError.ts diff --git a/sdk/typescript/common/errors/TooManyNestedObjectsError.ts b/sdk/typescript/src/common/errors/TooManyNestedObjectsError.ts similarity index 100% rename from sdk/typescript/common/errors/TooManyNestedObjectsError.ts rename to sdk/typescript/src/common/errors/TooManyNestedObjectsError.ts diff --git a/sdk/typescript/common/errors/UnknownDaggerError.ts b/sdk/typescript/src/common/errors/UnknownDaggerError.ts similarity index 100% rename from sdk/typescript/common/errors/UnknownDaggerError.ts rename to sdk/typescript/src/common/errors/UnknownDaggerError.ts diff --git a/sdk/typescript/common/errors/errors-codes.ts b/sdk/typescript/src/common/errors/errors-codes.ts similarity index 100% rename from sdk/typescript/common/errors/errors-codes.ts rename to sdk/typescript/src/common/errors/errors-codes.ts diff --git a/sdk/typescript/common/errors/index.ts b/sdk/typescript/src/common/errors/index.ts similarity index 87% rename from sdk/typescript/common/errors/index.ts rename to sdk/typescript/src/common/errors/index.ts index 49889bf977..5850a56210 100644 --- a/sdk/typescript/common/errors/index.ts +++ b/sdk/typescript/src/common/errors/index.ts @@ -9,4 +9,6 @@ export { TooManyNestedObjectsError } from "./TooManyNestedObjectsError.js" export { EngineSessionError } from "./EngineSessionErrorOptions.js" export { EngineSessionConnectionTimeoutError } from "./EngineSessionConnectionTimeoutError.js" export { NotAwaitedRequestError } from "./NotAwaitedRequestError.js" +export { FunctionNotFound } from "./FunctionNotFound.js" +export { IntrospectionError } from "./IntrospectionError.js" export { ERROR_CODES } from "./errors-codes.js" diff --git a/sdk/typescript/graphql/client.ts b/sdk/typescript/src/common/graphql/client.ts similarity index 100% rename from sdk/typescript/graphql/client.ts rename to sdk/typescript/src/common/graphql/client.ts diff --git a/sdk/typescript/api/utils.ts b/sdk/typescript/src/common/graphql/compute_query.ts similarity index 94% rename from sdk/typescript/api/utils.ts rename to sdk/typescript/src/common/graphql/compute_query.ts index fd042554a1..9762539ccb 100644 --- a/sdk/typescript/api/utils.ts +++ b/sdk/typescript/src/common/graphql/compute_query.ts @@ -7,8 +7,18 @@ import { UnknownDaggerError, NotAwaitedRequestError, ExecError, -} from "../common/errors/index.js" -import { Metadata, QueryTree } from "./client.gen.js" +} from "../errors/index.js" + +export type QueryTree = { + operation: string + args?: Record +} + +export type Metadata = { + [key: string]: { + is_enum?: boolean + } +} /** * Format argument into GraphQL query format. @@ -67,7 +77,7 @@ async function computeNestedQuery( client: GraphQLClient, ): Promise { // Check if there is a nested queryTree to be executed - const isQueryTree = (value: any) => value["_queryTree"] !== undefined + const isQueryTree = (value: any) => value["_ctx"] !== undefined // Check if there is a nested array of queryTree to be executed const isArrayQueryTree = (value: any[]) => @@ -77,13 +87,13 @@ async function computeNestedQuery( // and building it with their results. const computeQueryTree = async (value: any): Promise => { // Resolve sub queries if operation's args is a subquery - for (const op of value["_queryTree"]) { + for (const op of value["_ctx"]["_queryTree"]) { await computeNestedQuery([op], client) } // push an id that will be used by the container return buildQuery([ - ...value["_queryTree"], + ...value["_ctx"]["_queryTree"], { operation: "id", }, diff --git a/sdk/typescript/src/common/graphql/connect.ts b/sdk/typescript/src/common/graphql/connect.ts new file mode 100644 index 0000000000..4c63370416 --- /dev/null +++ b/sdk/typescript/src/common/graphql/connect.ts @@ -0,0 +1,36 @@ +import { GraphQLClient } from "graphql-request" + +import { ConnectOpts } from "../../connectOpts.js" +import { createGQLClient } from "./client.js" + +/** + * Execute the callback with a GraphQL client connected to the Dagger engine. + * It automatically provisions the engine if needed. + */ +export async function withGQLClient( + connectOpts: ConnectOpts, + cb: (gqlClient: GraphQLClient) => Promise, +): Promise { + if (process.env["DAGGER_SESSION_PORT"]) { + const port = process.env["DAGGER_SESSION_PORT"] + if (!process.env["DAGGER_SESSION_TOKEN"]) { + throw new Error( + "DAGGER_SESSION_TOKEN must be set if DAGGER_SESSION_PORT is set", + ) + } + + const token = process.env["DAGGER_SESSION_TOKEN"] + + return await cb(createGQLClient(Number(port), token)) + } + + try { + const provisioning = await import("../../provisioning/index.js") + + return await provisioning.withEngineSession(connectOpts, cb) + } catch (e) { + throw new Error( + `failed to execute function with automatic provisioning: ${e}`, + ) + } +} diff --git a/sdk/typescript/src/common/graphql/connection.ts b/sdk/typescript/src/common/graphql/connection.ts new file mode 100644 index 0000000000..9c503d4bec --- /dev/null +++ b/sdk/typescript/src/common/graphql/connection.ts @@ -0,0 +1,27 @@ +import { GraphQLClient } from "graphql-request" + +/** + * Wraps the GraphQL client to allow lazy initialization and setting + * the GQL client of the global Dagger client instance (`dag`). + */ +export class Connection { + constructor(private _gqlClient?: GraphQLClient) {} + + resetClient() { + this._gqlClient = undefined + } + + setGQLClient(gqlClient: GraphQLClient) { + this._gqlClient = gqlClient + } + + getGQLClient(): GraphQLClient { + if (!this._gqlClient) { + throw new Error("GraphQL client is not set") + } + + return this._gqlClient + } +} + +export const globalConnection = new Connection() diff --git a/sdk/typescript/common/utils.ts b/sdk/typescript/src/common/utils.ts similarity index 100% rename from sdk/typescript/common/utils.ts rename to sdk/typescript/src/common/utils.ts diff --git a/sdk/typescript/connect.ts b/sdk/typescript/src/connect.ts similarity index 59% rename from sdk/typescript/connect.ts rename to sdk/typescript/src/connect.ts index 9646aa9031..bc0bc76335 100644 --- a/sdk/typescript/connect.ts +++ b/sdk/typescript/src/connect.ts @@ -1,8 +1,11 @@ import * as opentelemetry from "@opentelemetry/api" +import { GraphQLClient } from "graphql-request" import { Client } from "./api/client.gen.js" +import { Context } from "./common/context.js" +import { withGQLClient } from "./common/graphql/connect.js" +import { Connection, globalConnection } from "./common/graphql/connection.js" import { ConnectOpts } from "./connectOpts.js" -import { Context, defaultContext } from "./context/context.js" import * as telemetry from "./telemetry/telemetry.js" export type CallbackFct = (client: Client) => Promise @@ -34,10 +37,14 @@ export async function connection( // Wrap connection into the opentelemetry context for propagation await opentelemetry.context.with(telemetry.getContext(), async () => { try { - await defaultContext.connection(cfg) - await fct() + await withGQLClient(cfg, async (gqlClient) => { + // Set the GQL client inside the global dagger client + globalConnection.setGQLClient(gqlClient) + + await fct() + }) } finally { - close() + globalConnection.resetClient() } }) } finally { @@ -45,13 +52,6 @@ export async function connection( } } -/** - * Close global client connection - */ -export function close() { - defaultContext.close() -} - /** * connect runs GraphQL server and initializes a * GraphQL client to execute query on it through its callback. @@ -61,20 +61,18 @@ export async function connect( cb: CallbackFct, config: ConnectOpts = {}, ): Promise { - const ctx = new Context() - const client = new Client({ ctx: ctx }) - - // Initialize connection - await ctx.connection(config) + await withGQLClient(config, async (gqlClient: GraphQLClient) => { + const connection = new Connection(gqlClient) + const ctx = new Context([], connection) + const client = new Client(ctx) - // Warning shall be throw if versions are not compatible - try { - await client.version() - } catch (e) { - console.error("failed to check version compatibility:", e) - } + // Warning shall be throw if versions are not compatible + try { + await client.version() + } catch (e) { + console.error("failed to check version compatibility:", e) + } - await cb(client).finally(() => { - ctx.close() + return await cb(client) }) } diff --git a/sdk/typescript/connectOpts.ts b/sdk/typescript/src/connectOpts.ts similarity index 100% rename from sdk/typescript/connectOpts.ts rename to sdk/typescript/src/connectOpts.ts diff --git a/sdk/typescript/index.ts b/sdk/typescript/src/index.ts similarity index 51% rename from sdk/typescript/index.ts rename to sdk/typescript/src/index.ts index a564a3aa6c..645f71c637 100644 --- a/sdk/typescript/index.ts +++ b/sdk/typescript/src/index.ts @@ -1,9 +1,17 @@ -export * from "./api/client.gen.js" -export * from "./common/errors/index.js" export { gql } from "graphql-tag" export { GraphQLClient } from "graphql-request" + +// Default client bindings +export * from "./api/client.gen.js" + +// Common errors +export * from "./common/errors/index.js" + +// Connection for library export type { CallbackFct } from "./connect.js" -export { connect, connection, close } from "./connect.js" +export { connect, connection } from "./connect.js" export type { ConnectOpts } from "./connectOpts.js" -export * from "./introspector/decorators/decorators.js" -export { entrypoint } from "./entrypoint/entrypoint.js" + +// Module library +export * from "./module/decorators.js" +export { entrypoint } from "./module/entrypoint/entrypoint.js" diff --git a/sdk/typescript/introspector/decorators/decorators.ts b/sdk/typescript/src/module/decorators.ts similarity index 97% rename from sdk/typescript/introspector/decorators/decorators.ts rename to sdk/typescript/src/module/decorators.ts index f5eb3c63f0..9b5fce257b 100644 --- a/sdk/typescript/introspector/decorators/decorators.ts +++ b/sdk/typescript/src/module/decorators.ts @@ -1,7 +1,7 @@ /** * Expose the decorator publicly, so they insert data into the global registry. */ -import { registry } from "../registry/registry.js" +import { registry } from "./registry.js" /** * The definition of the `@object` decorator that should be on top of any diff --git a/sdk/typescript/entrypoint/context.ts b/sdk/typescript/src/module/entrypoint/context.ts similarity index 62% rename from sdk/typescript/entrypoint/context.ts rename to sdk/typescript/src/module/entrypoint/context.ts index 50636dac9b..6c77cb5aa1 100644 --- a/sdk/typescript/entrypoint/context.ts +++ b/sdk/typescript/src/module/entrypoint/context.ts @@ -1,4 +1,4 @@ -import { Args } from "../introspector/executor/executor.js" +import { Args } from "../executor.js" export type InvokeCtx = { parentName: string diff --git a/sdk/typescript/entrypoint/entrypoint.ts b/sdk/typescript/src/module/entrypoint/entrypoint.ts similarity index 72% rename from sdk/typescript/entrypoint/entrypoint.ts rename to sdk/typescript/src/module/entrypoint/entrypoint.ts index dcc016e0f1..bd294c8306 100644 --- a/sdk/typescript/entrypoint/entrypoint.ts +++ b/sdk/typescript/src/module/entrypoint/entrypoint.ts @@ -1,26 +1,12 @@ -import * as path from "path" -import { fileURLToPath } from "url" - -import { dag } from "../api/client.gen.js" -import { connection } from "../connect.js" -import { Executor } from "../introspector/executor/executor.js" -import { Args } from "../introspector/executor/executor.js" -import { scan } from "../introspector/scanner/scan.js" -import { listFiles } from "../introspector/utils/files.js" +import { dag } from "../../api/client.gen.js" +import { connection } from "../../connect.js" +import { Executor, Args } from "../executor.js" +import { scan } from "../introspector/index.js" import { invoke } from "./invoke.js" import { load } from "./load.js" import { register } from "./register.js" -const __filename = fileURLToPath(import.meta.url) -const __dirname = path.dirname(__filename) - -const moduleSrcDirectory = `${__dirname}/../../src/` - -export async function entrypoint() { - // Pre list all files of the modules since we need it either for a registration - // or an invocation - const files = await listFiles(moduleSrcDirectory) - +export async function entrypoint(files: string[]) { // Start a Dagger session to get the call context await connection( async () => { diff --git a/sdk/typescript/entrypoint/invoke.ts b/sdk/typescript/src/module/entrypoint/invoke.ts similarity index 76% rename from sdk/typescript/entrypoint/invoke.ts rename to sdk/typescript/src/module/entrypoint/invoke.ts index 325228208a..474c6f3d3f 100644 --- a/sdk/typescript/entrypoint/invoke.ts +++ b/sdk/typescript/src/module/entrypoint/invoke.ts @@ -1,11 +1,13 @@ -import { FunctionNotFound } from "../common/errors/FunctionNotFound.js" -import { Executor } from "../introspector/executor/executor.js" -import { registry } from "../introspector/registry/registry.js" -import { DaggerConstructor as Constructor } from "../introspector/scanner/dagger_module/constructor.js" -import { DaggerEnumBase } from "../introspector/scanner/dagger_module/enumBase.js" -import { DaggerFunction as Method } from "../introspector/scanner/dagger_module/function.js" -import { DaggerModule } from "../introspector/scanner/dagger_module/module.js" -import { DaggerObjectBase } from "../introspector/scanner/dagger_module/objectBase.js" +import { FunctionNotFound } from "../../common/errors/index.js" +import { Executor } from "../executor.js" +import { + DaggerConstructor as Constructor, + DaggerFunction as Method, + DaggerEnumBase, + DaggerModule, + DaggerObjectBase, +} from "../introspector/dagger_module/index.js" +import { registry } from "../registry.js" import { InvokeCtx } from "./context.js" import { loadResult, diff --git a/sdk/typescript/entrypoint/load.ts b/sdk/typescript/src/module/entrypoint/load.ts similarity index 90% rename from sdk/typescript/entrypoint/load.ts rename to sdk/typescript/src/module/entrypoint/load.ts index 046329f3c6..4a282901b3 100644 --- a/sdk/typescript/entrypoint/load.ts +++ b/sdk/typescript/src/module/entrypoint/load.ts @@ -1,17 +1,18 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import Module from "node:module" -import { dag, TypeDefKind } from "../api/client.gen.js" -import { Executor } from "../introspector/executor/executor.js" -import { Args } from "../introspector/executor/executor.js" -import { DaggerConstructor as Constructor } from "../introspector/scanner/dagger_module/constructor.js" -import { DaggerEnum } from "../introspector/scanner/dagger_module/enum.js" -import { DaggerEnumBase } from "../introspector/scanner/dagger_module/enumBase.js" -import { DaggerFunction as Method } from "../introspector/scanner/dagger_module/function.js" -import { DaggerModule } from "../introspector/scanner/dagger_module/module.js" -import { DaggerObject } from "../introspector/scanner/dagger_module/object.js" -import { DaggerObjectBase } from "../introspector/scanner/dagger_module/objectBase.js" -import { TypeDef } from "../introspector/scanner/typedef.js" +import { dag, TypeDefKind } from "../../api/client.gen.js" +import { Executor, Args } from "../executor.js" +import { + DaggerConstructor as Constructor, + DaggerFunction as Method, + DaggerEnum, + DaggerEnumBase, + DaggerModule, + DaggerObject, + DaggerObjectBase, +} from "../introspector/dagger_module/index.js" +import { TypeDef } from "../introspector/typedef.js" import { InvokeCtx } from "./context.js" /** diff --git a/sdk/typescript/entrypoint/register.ts b/sdk/typescript/src/module/entrypoint/register.ts similarity index 92% rename from sdk/typescript/entrypoint/register.ts rename to sdk/typescript/src/module/entrypoint/register.ts index beb84b1053..1ce4db6e69 100644 --- a/sdk/typescript/entrypoint/register.ts +++ b/sdk/typescript/src/module/entrypoint/register.ts @@ -5,18 +5,20 @@ import { ModuleID, TypeDef, TypeDefKind, -} from "../api/client.gen.js" -import { DaggerArguments as Arguments } from "../introspector/scanner/dagger_module/argument.js" -import { DaggerConstructor as Constructor } from "../introspector/scanner/dagger_module/constructor.js" -import { DaggerFunction as Method } from "../introspector/scanner/dagger_module/function.js" -import { DaggerModule } from "../introspector/scanner/dagger_module/module.js" +} from "../../api/client.gen.js" +import { + DaggerArguments as Arguments, + DaggerConstructor as Constructor, + DaggerFunction as Method, + DaggerModule, +} from "../introspector/dagger_module/index.js" import { EnumTypeDef, ListTypeDef, ObjectTypeDef, ScalarTypeDef, TypeDef as ScannerTypeDef, -} from "../introspector/scanner/typedef.js" +} from "../introspector/typedef.js" /** * Register the module files and returns its ID diff --git a/sdk/typescript/introspector/executor/executor.ts b/sdk/typescript/src/module/executor.ts similarity index 91% rename from sdk/typescript/introspector/executor/executor.ts rename to sdk/typescript/src/module/executor.ts index eb7370f796..4cd12685b7 100644 --- a/sdk/typescript/introspector/executor/executor.ts +++ b/sdk/typescript/src/module/executor.ts @@ -1,8 +1,8 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import Module from "node:module" -import { FunctionNotFound } from "../../common/errors/FunctionNotFound.js" -import { DaggerModule } from "../scanner/dagger_module/module.js" +import { FunctionNotFound } from "../common/errors/index.js" +import { DaggerModule } from "./introspector/dagger_module/index.js" export type State = { [property: string]: any } diff --git a/sdk/typescript/introspector/scanner/case_convertor.ts b/sdk/typescript/src/module/introspector/case_convertor.ts similarity index 100% rename from sdk/typescript/introspector/scanner/case_convertor.ts rename to sdk/typescript/src/module/introspector/case_convertor.ts diff --git a/sdk/typescript/introspector/scanner/dagger_module/argument.ts b/sdk/typescript/src/module/introspector/dagger_module/argument.ts similarity index 94% rename from sdk/typescript/introspector/scanner/dagger_module/argument.ts rename to sdk/typescript/src/module/introspector/dagger_module/argument.ts index 2117ae59a3..524727d612 100644 --- a/sdk/typescript/introspector/scanner/dagger_module/argument.ts +++ b/sdk/typescript/src/module/introspector/dagger_module/argument.ts @@ -2,14 +2,14 @@ import ts from "typescript" import { TypeDefKind } from "../../../api/client.gen.js" -import { IntrospectionError } from "../../../common/errors/IntrospectionError.js" -import { ArgumentOptions } from "../../registry/registry.js" +import { IntrospectionError } from "../../../common/errors/index.js" +import { ArgumentOptions } from "../../registry.js" import { TypeDef } from "../typedef.js" -import { AST } from "../typescript_module/ast.js" import { + AST, isTypeDefResolved, resolveTypeDef, -} from "../typescript_module/typedef_utils.js" +} from "../typescript_module/index.js" import { ARGUMENT_DECORATOR } from "./decorator.js" import { References } from "./reference.js" diff --git a/sdk/typescript/introspector/scanner/dagger_module/constructor.ts b/sdk/typescript/src/module/introspector/dagger_module/constructor.ts similarity index 95% rename from sdk/typescript/introspector/scanner/dagger_module/constructor.ts rename to sdk/typescript/src/module/introspector/dagger_module/constructor.ts index 0a925659cd..843ceea581 100644 --- a/sdk/typescript/introspector/scanner/dagger_module/constructor.ts +++ b/sdk/typescript/src/module/introspector/dagger_module/constructor.ts @@ -1,6 +1,6 @@ import ts from "typescript" -import { AST } from "../typescript_module/ast.js" +import { AST } from "../typescript_module/index.js" import { DaggerArgument, DaggerArguments } from "./argument.js" import { References } from "./reference.js" diff --git a/sdk/typescript/introspector/scanner/dagger_module/decorator.ts b/sdk/typescript/src/module/introspector/dagger_module/decorator.ts similarity index 80% rename from sdk/typescript/introspector/scanner/dagger_module/decorator.ts rename to sdk/typescript/src/module/introspector/dagger_module/decorator.ts index 720999b862..04ed1160ce 100644 --- a/sdk/typescript/introspector/scanner/dagger_module/decorator.ts +++ b/sdk/typescript/src/module/introspector/dagger_module/decorator.ts @@ -1,10 +1,4 @@ -import { - argument, - func, - object, - enumType, - field, -} from "../../decorators/decorators.js" +import { argument, func, object, enumType, field } from "../../decorators.js" export type DaggerDecorators = | "object" diff --git a/sdk/typescript/introspector/scanner/dagger_module/enum.ts b/sdk/typescript/src/module/introspector/dagger_module/enum.ts similarity index 93% rename from sdk/typescript/introspector/scanner/dagger_module/enum.ts rename to sdk/typescript/src/module/introspector/dagger_module/enum.ts index 11742c12b1..ec02a322f2 100644 --- a/sdk/typescript/introspector/scanner/dagger_module/enum.ts +++ b/sdk/typescript/src/module/introspector/dagger_module/enum.ts @@ -1,7 +1,7 @@ import ts from "typescript" -import { IntrospectionError } from "../../../common/errors/IntrospectionError.js" -import { AST } from "../typescript_module/ast.js" +import { IntrospectionError } from "../../../common/errors/index.js" +import { AST } from "../typescript_module/index.js" import { DaggerEnumBase, DaggerEnumBaseValue } from "./enumBase.js" export type DaggerEnums = { [name: string]: DaggerEnum } diff --git a/sdk/typescript/introspector/scanner/dagger_module/enumBase.ts b/sdk/typescript/src/module/introspector/dagger_module/enumBase.ts similarity index 100% rename from sdk/typescript/introspector/scanner/dagger_module/enumBase.ts rename to sdk/typescript/src/module/introspector/dagger_module/enumBase.ts diff --git a/sdk/typescript/introspector/scanner/dagger_module/enumClass.ts b/sdk/typescript/src/module/introspector/dagger_module/enumClass.ts similarity index 88% rename from sdk/typescript/introspector/scanner/dagger_module/enumClass.ts rename to sdk/typescript/src/module/introspector/dagger_module/enumClass.ts index 9eef224c56..a68d58247d 100644 --- a/sdk/typescript/introspector/scanner/dagger_module/enumClass.ts +++ b/sdk/typescript/src/module/introspector/dagger_module/enumClass.ts @@ -1,12 +1,12 @@ import ts from "typescript" -import { IntrospectionError } from "../../../common/errors/IntrospectionError.js" -import { AST } from "../typescript_module/ast.js" +import { IntrospectionError } from "../../../common/errors/index.js" +import { AST } from "../typescript_module/index.js" import { DaggerEnumBase, DaggerEnumBaseValue } from "./enumBase.js" export type DaggerEnumClasses = { [name: string]: DaggerEnumClass } -export type DaggerEnumValues = { [name: string]: DaggerEnumClassValue } +export type DaggerEnumClassValues = { [name: string]: DaggerEnumClassValue } export class DaggerEnumClassValue implements DaggerEnumBaseValue { public name: string @@ -42,7 +42,7 @@ export class DaggerEnumClassValue implements DaggerEnumBaseValue { export class DaggerEnumClass implements DaggerEnumBase { public name: string public description: string - public values: DaggerEnumValues = {} + public values: DaggerEnumClassValues = {} private symbol: ts.Symbol diff --git a/sdk/typescript/introspector/scanner/dagger_module/function.ts b/sdk/typescript/src/module/introspector/dagger_module/function.ts similarity index 94% rename from sdk/typescript/introspector/scanner/dagger_module/function.ts rename to sdk/typescript/src/module/introspector/dagger_module/function.ts index b155e027ec..c42ddec07b 100644 --- a/sdk/typescript/introspector/scanner/dagger_module/function.ts +++ b/sdk/typescript/src/module/introspector/dagger_module/function.ts @@ -1,13 +1,13 @@ import ts from "typescript" import { TypeDefKind } from "../../../api/client.gen.js" -import { IntrospectionError } from "../../../common/errors/IntrospectionError.js" +import { IntrospectionError } from "../../../common/errors/index.js" import { TypeDef } from "../typedef.js" -import { AST } from "../typescript_module/ast.js" import { + AST, isTypeDefResolved, resolveTypeDef, -} from "../typescript_module/typedef_utils.js" +} from "../typescript_module/index.js" import { DaggerArgument, DaggerArguments } from "./argument.js" import { FUNCTION_DECORATOR } from "./decorator.js" import { References } from "./reference.js" diff --git a/sdk/typescript/src/module/introspector/dagger_module/index.ts b/sdk/typescript/src/module/introspector/dagger_module/index.ts new file mode 100644 index 0000000000..58f43adb7a --- /dev/null +++ b/sdk/typescript/src/module/introspector/dagger_module/index.ts @@ -0,0 +1,12 @@ +export * from "./constructor.js" +export * from "./argument.js" +export * from "./enum.js" +export * from "./enumBase.js" +export * from "./enumClass.js" +export * from "./function.js" +export * from "./module.js" +export * from "./object.js" +export * from "./objectBase.js" +export * from "./reference.js" +export * from "./typeObject.js" +export * from "./decorator.js" diff --git a/sdk/typescript/introspector/scanner/dagger_module/module.ts b/sdk/typescript/src/module/introspector/dagger_module/module.ts similarity index 98% rename from sdk/typescript/introspector/scanner/dagger_module/module.ts rename to sdk/typescript/src/module/introspector/dagger_module/module.ts index ea1c6a568f..899a76aaa7 100644 --- a/sdk/typescript/introspector/scanner/dagger_module/module.ts +++ b/sdk/typescript/src/module/introspector/dagger_module/module.ts @@ -2,13 +2,13 @@ import Module from "node:module" import ts from "typescript" import { TypeDefKind } from "../../../api/client.gen.js" -import { IntrospectionError } from "../../../common/errors/IntrospectionError.js" +import { IntrospectionError } from "../../../common/errors/index.js" import { + findModuleByExportedName, AST, CLIENT_GEN_FILE, ResolvedNodeWithSymbol, -} from "../typescript_module/ast.js" -import { findModuleByExportedName } from "../typescript_module/explorer.js" +} from "../typescript_module/index.js" import { ENUM_DECORATOR, OBJECT_DECORATOR } from "./decorator.js" import { DaggerEnum } from "./enum.js" import { DaggerEnumsBase } from "./enumBase.js" diff --git a/sdk/typescript/introspector/scanner/dagger_module/object.ts b/sdk/typescript/src/module/introspector/dagger_module/object.ts similarity index 96% rename from sdk/typescript/introspector/scanner/dagger_module/object.ts rename to sdk/typescript/src/module/introspector/dagger_module/object.ts index 6a6645a410..8756ef4ea4 100644 --- a/sdk/typescript/introspector/scanner/dagger_module/object.ts +++ b/sdk/typescript/src/module/introspector/dagger_module/object.ts @@ -1,7 +1,7 @@ import ts from "typescript" -import { IntrospectionError } from "../../../common/errors/IntrospectionError.js" -import { AST } from "../typescript_module/ast.js" +import { IntrospectionError } from "../../../common/errors/index.js" +import { AST } from "../typescript_module/index.js" import { DaggerConstructor } from "./constructor.js" import { FUNCTION_DECORATOR, OBJECT_DECORATOR } from "./decorator.js" import { DaggerFunction, DaggerFunctions } from "./function.js" diff --git a/sdk/typescript/introspector/scanner/dagger_module/objectBase.ts b/sdk/typescript/src/module/introspector/dagger_module/objectBase.ts similarity index 100% rename from sdk/typescript/introspector/scanner/dagger_module/objectBase.ts rename to sdk/typescript/src/module/introspector/dagger_module/objectBase.ts diff --git a/sdk/typescript/introspector/scanner/dagger_module/property.ts b/sdk/typescript/src/module/introspector/dagger_module/property.ts similarity index 94% rename from sdk/typescript/introspector/scanner/dagger_module/property.ts rename to sdk/typescript/src/module/introspector/dagger_module/property.ts index bd2d956ab5..fe3cc0416b 100644 --- a/sdk/typescript/introspector/scanner/dagger_module/property.ts +++ b/sdk/typescript/src/module/introspector/dagger_module/property.ts @@ -1,13 +1,13 @@ import ts from "typescript" import { TypeDefKind } from "../../../api/client.gen.js" -import { IntrospectionError } from "../../../common/errors/IntrospectionError.js" +import { IntrospectionError } from "../../../common/errors/index.js" import { TypeDef } from "../typedef.js" -import { AST } from "../typescript_module/ast.js" import { + AST, isTypeDefResolved, resolveTypeDef, -} from "../typescript_module/typedef_utils.js" +} from "../typescript_module/index.js" import { FIELD_DECORATOR, FUNCTION_DECORATOR } from "./decorator.js" import { DaggerObjectPropertyBase } from "./objectBase.js" import { References } from "./reference.js" diff --git a/sdk/typescript/introspector/scanner/dagger_module/reference.ts b/sdk/typescript/src/module/introspector/dagger_module/reference.ts similarity index 100% rename from sdk/typescript/introspector/scanner/dagger_module/reference.ts rename to sdk/typescript/src/module/introspector/dagger_module/reference.ts diff --git a/sdk/typescript/introspector/scanner/dagger_module/typeObject.ts b/sdk/typescript/src/module/introspector/dagger_module/typeObject.ts similarity index 93% rename from sdk/typescript/introspector/scanner/dagger_module/typeObject.ts rename to sdk/typescript/src/module/introspector/dagger_module/typeObject.ts index aa81615857..5ee4892735 100644 --- a/sdk/typescript/introspector/scanner/dagger_module/typeObject.ts +++ b/sdk/typescript/src/module/introspector/dagger_module/typeObject.ts @@ -1,7 +1,7 @@ import ts from "typescript" -import { IntrospectionError } from "../../../common/errors/IntrospectionError.js" -import { AST } from "../typescript_module/ast.js" +import { IntrospectionError } from "../../../common/errors/index.js" +import { AST } from "../typescript_module/index.js" import { DaggerObjectBase } from "./objectBase.js" import { References } from "./reference.js" import { diff --git a/sdk/typescript/introspector/scanner/dagger_module/typeObjectProperty.ts b/sdk/typescript/src/module/introspector/dagger_module/typeObjectProperty.ts similarity index 91% rename from sdk/typescript/introspector/scanner/dagger_module/typeObjectProperty.ts rename to sdk/typescript/src/module/introspector/dagger_module/typeObjectProperty.ts index 221470df53..7afa10a41a 100644 --- a/sdk/typescript/introspector/scanner/dagger_module/typeObjectProperty.ts +++ b/sdk/typescript/src/module/introspector/dagger_module/typeObjectProperty.ts @@ -1,13 +1,13 @@ import ts from "typescript" import { TypeDefKind } from "../../../api/client.gen.js" -import { IntrospectionError } from "../../../common/errors/IntrospectionError.js" +import { IntrospectionError } from "../../../common/errors/index.js" import { TypeDef } from "../typedef.js" -import { AST } from "../typescript_module/ast.js" import { + AST, isTypeDefResolved, resolveTypeDef, -} from "../typescript_module/typedef_utils.js" +} from "../typescript_module/index.js" import { DaggerObjectPropertyBase } from "./objectBase.js" import { References } from "./reference.js" diff --git a/sdk/typescript/introspector/scanner/scan.ts b/sdk/typescript/src/module/introspector/index.ts similarity index 68% rename from sdk/typescript/introspector/scanner/scan.ts rename to sdk/typescript/src/module/introspector/index.ts index 09136818b5..6c61aacf22 100644 --- a/sdk/typescript/introspector/scanner/scan.ts +++ b/sdk/typescript/src/module/introspector/index.ts @@ -1,8 +1,8 @@ -import { IntrospectionError } from "../../common/errors/IntrospectionError.js" -import { load } from "../../entrypoint/load.js" +import { IntrospectionError } from "../../common/errors/index.js" +import { load } from "../entrypoint/load.js" import { convertToPascalCase } from "./case_convertor.js" -import { DaggerModule } from "./dagger_module/module.js" -import { AST } from "./typescript_module/ast.js" +import { DaggerModule } from "./dagger_module/index.js" +import { AST } from "./typescript_module/index.js" export async function scan(files: string[], moduleName = "") { if (files.length === 0) { diff --git a/sdk/typescript/introspector/test/case_convertor.spec.ts b/sdk/typescript/src/module/introspector/test/case_convertor.spec.ts similarity index 94% rename from sdk/typescript/introspector/test/case_convertor.spec.ts rename to sdk/typescript/src/module/introspector/test/case_convertor.spec.ts index a68d0457e4..3270769d69 100644 --- a/sdk/typescript/introspector/test/case_convertor.spec.ts +++ b/sdk/typescript/src/module/introspector/test/case_convertor.spec.ts @@ -1,6 +1,6 @@ import assert from "assert" -import { convertToPascalCase } from "../scanner/case_convertor.js" +import { convertToPascalCase } from "../case_convertor.js" describe("case convertor", function () { describe("convertToPascalCase", function () { diff --git a/sdk/typescript/introspector/test/files.spec.ts b/sdk/typescript/src/module/introspector/test/files.spec.ts similarity index 100% rename from sdk/typescript/introspector/test/files.spec.ts rename to sdk/typescript/src/module/introspector/test/files.spec.ts diff --git a/sdk/typescript/introspector/test/invoke.spec.ts b/sdk/typescript/src/module/introspector/test/invoke.spec.ts similarity index 87% rename from sdk/typescript/introspector/test/invoke.spec.ts rename to sdk/typescript/src/module/introspector/test/invoke.spec.ts index d2f3d6058a..9ad4e9d348 100644 --- a/sdk/typescript/introspector/test/invoke.spec.ts +++ b/sdk/typescript/src/module/introspector/test/invoke.spec.ts @@ -4,12 +4,12 @@ import Module from "node:module" import * as path from "path" import { fileURLToPath } from "url" -import { connection } from "../../connect.js" +import { connection } from "../../../connect.js" import { InvokeCtx } from "../../entrypoint/context.js" import { invoke } from "../../entrypoint/invoke.js" import { load } from "../../entrypoint/load.js" -import { Executor } from "../executor/executor.js" -import { scan } from "../scanner/scan.js" +import { Executor } from "../../executor.js" +import { scan } from "../index.js" import { listFiles } from "../utils/files.js" const __filename = fileURLToPath(import.meta.url) @@ -120,68 +120,65 @@ describe("Invoke typescript function", function () { const executor = new Executor(modules, scanResult) // We wrap the execution into a Dagger connection - await connection( - async () => { - // Mocking the fetch from the dagger API - const inputBase = { - parentName: "State", - fnName: "base", - parentArgs: { - version: "3.16.2", - user: "root", - packages: [], - }, - fnArgs: { version: "3.16.0" }, - } - - const inputBaseResult = await invoke(executor, scanResult, inputBase) + await connection(async () => { + // Mocking the fetch from the dagger API + const inputBase = { + parentName: "State", + fnName: "base", + parentArgs: { + version: "3.16.2", + user: "root", + packages: [], + }, + fnArgs: { version: "3.16.0" }, + } - // Assert state has been updated by the function - assert.equal("3.16.0", inputBaseResult.version) - assert.equal("root", inputBaseResult.user) - assert.deepEqual([], inputBaseResult.packages) - assert.notEqual(undefined, inputBaseResult.ctr) + const inputBaseResult = await invoke(executor, scanResult, inputBase) - const inputInstall = { - parentName: "State", - fnName: "install", - // Would be fetched from dagger and parsed from dagger entrypoint - parentArgs: JSON.parse(JSON.stringify(inputBaseResult)), - fnArgs: { - pkgs: ["jq"], - }, - } + // Assert state has been updated by the function + assert.equal("3.16.0", inputBaseResult.version) + assert.equal("root", inputBaseResult.user) + assert.deepEqual([], inputBaseResult.packages) + assert.notEqual(undefined, inputBaseResult.ctr) - const inputInstallResult = await invoke( - executor, - scanResult, - inputInstall, - ) + const inputInstall = { + parentName: "State", + fnName: "install", + // Would be fetched from dagger and parsed from dagger entrypoint + parentArgs: JSON.parse(JSON.stringify(inputBaseResult)), + fnArgs: { + pkgs: ["jq"], + }, + } - // Verify state conservation - assert.equal("3.16.0", inputInstallResult.version) - assert.equal("root", inputInstallResult.user) - assert.deepEqual(["jq"], inputInstallResult.packages) - assert.notEqual(undefined, inputInstallResult.ctr) - - const inputExec = { - parentName: "State", - fnName: "exec", - // Would be fetched from dagger and parsed from dagger entrypoint - parentArgs: JSON.parse(JSON.stringify(inputInstallResult)), - fnArgs: { - cmd: ["jq", "-h"], - }, - } + const inputInstallResult = await invoke( + executor, + scanResult, + inputInstall, + ) + + // Verify state conservation + assert.equal("3.16.0", inputInstallResult.version) + assert.equal("root", inputInstallResult.user) + assert.deepEqual(["jq"], inputInstallResult.packages) + assert.notEqual(undefined, inputInstallResult.ctr) + + const inputExec = { + parentName: "State", + fnName: "exec", + // Would be fetched from dagger and parsed from dagger entrypoint + parentArgs: JSON.parse(JSON.stringify(inputInstallResult)), + fnArgs: { + cmd: ["jq", "-h"], + }, + } - const result = await invoke(executor, scanResult, inputExec) + const result = await invoke(executor, scanResult, inputExec) - // We verify the result, this could be serialized and set using `dag.ReturnValue` as a response - // In that case, we verify it's not failing and that it returned a value - assert.notEqual("", result) - }, - { LogOutput: process.stderr }, - ) + // We verify the result, this could be serialized and set using `dag.ReturnValue` as a response + // In that case, we verify it's not failing and that it returned a value + assert.notEqual("", result) + }) }) it("Should correctly handle multiple objects as fields", async function () { diff --git a/sdk/typescript/introspector/test/registry.spec.ts b/sdk/typescript/src/module/introspector/test/registry.spec.ts similarity index 97% rename from sdk/typescript/introspector/test/registry.spec.ts rename to sdk/typescript/src/module/introspector/test/registry.spec.ts index 2daf93ee71..fe8ece59e2 100644 --- a/sdk/typescript/introspector/test/registry.spec.ts +++ b/sdk/typescript/src/module/introspector/test/registry.spec.ts @@ -1,9 +1,9 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import assert from "assert" -import { dag, Container } from "../../api/client.gen.js" -import { connection } from "../../connect.js" -import { Registry } from "../registry/registry.js" +import { dag, Container } from "../../../api/client.gen.js" +import { connection } from "../../../connect.js" +import { Registry } from "../../registry.js" describe("Registry", function () { it("Should support function", async function () { diff --git a/sdk/typescript/introspector/test/scan.spec.ts b/sdk/typescript/src/module/introspector/test/scan.spec.ts similarity index 97% rename from sdk/typescript/introspector/test/scan.spec.ts rename to sdk/typescript/src/module/introspector/test/scan.spec.ts index 9af0a7424e..0e70851a77 100644 --- a/sdk/typescript/introspector/test/scan.spec.ts +++ b/sdk/typescript/src/module/introspector/test/scan.spec.ts @@ -4,7 +4,7 @@ import * as fs from "fs" import path from "path" import { fileURLToPath } from "url" -import { scan } from "../scanner/scan.js" +import { scan } from "../index.js" import { listFiles } from "../utils/files.js" const __filename = fileURLToPath(import.meta.url) @@ -93,7 +93,7 @@ describe("scan by reference TypeScript", function () { ] for (const test of testCases) { - it(test.name, async function () { + it(`${test.name} - ${test.directory}`, async function () { this.timeout(60000) try { diff --git a/sdk/typescript/introspector/test/testdata/alias/expected.json b/sdk/typescript/src/module/introspector/test/testdata/alias/expected.json similarity index 100% rename from sdk/typescript/introspector/test/testdata/alias/expected.json rename to sdk/typescript/src/module/introspector/test/testdata/alias/expected.json diff --git a/sdk/typescript/introspector/test/testdata/alias/index.ts b/sdk/typescript/src/module/introspector/test/testdata/alias/index.ts similarity index 88% rename from sdk/typescript/introspector/test/testdata/alias/index.ts rename to sdk/typescript/src/module/introspector/test/testdata/alias/index.ts index 7af824ab40..5f53b80b79 100644 --- a/sdk/typescript/introspector/test/testdata/alias/index.ts +++ b/sdk/typescript/src/module/introspector/test/testdata/alias/index.ts @@ -1,5 +1,5 @@ -import { dag, Container } from "../../../../api/client.gen.js" -import { func, object } from "../../../decorators/decorators.js" +import { dag, Container } from "../../../../../api/client.gen.js" +import { func, object } from "../../../../decorators.js" @object() export class Bar { diff --git a/sdk/typescript/introspector/test/testdata/constructor/expected.json b/sdk/typescript/src/module/introspector/test/testdata/constructor/expected.json similarity index 100% rename from sdk/typescript/introspector/test/testdata/constructor/expected.json rename to sdk/typescript/src/module/introspector/test/testdata/constructor/expected.json diff --git a/sdk/typescript/introspector/test/testdata/constructor/index.ts b/sdk/typescript/src/module/introspector/test/testdata/constructor/index.ts similarity index 79% rename from sdk/typescript/introspector/test/testdata/constructor/index.ts rename to sdk/typescript/src/module/introspector/test/testdata/constructor/index.ts index d33e1ff319..212e06b0a6 100644 --- a/sdk/typescript/introspector/test/testdata/constructor/index.ts +++ b/sdk/typescript/src/module/introspector/test/testdata/constructor/index.ts @@ -1,7 +1,7 @@ /** * Constructor module */ -import { func, object } from "../../../decorators/decorators.js" +import { func, object } from "../../../../decorators.js" /** * Constructor class diff --git a/sdk/typescript/introspector/test/testdata/context/expected.json b/sdk/typescript/src/module/introspector/test/testdata/context/expected.json similarity index 100% rename from sdk/typescript/introspector/test/testdata/context/expected.json rename to sdk/typescript/src/module/introspector/test/testdata/context/expected.json diff --git a/sdk/typescript/introspector/test/testdata/context/index.ts b/sdk/typescript/src/module/introspector/test/testdata/context/index.ts similarity index 70% rename from sdk/typescript/introspector/test/testdata/context/index.ts rename to sdk/typescript/src/module/introspector/test/testdata/context/index.ts index 99c75bba75..4840fbb019 100644 --- a/sdk/typescript/introspector/test/testdata/context/index.ts +++ b/sdk/typescript/src/module/introspector/test/testdata/context/index.ts @@ -1,5 +1,5 @@ -import { Directory } from "../../../../api/client.gen.js" -import { func, object, argument } from "../../../decorators/decorators.js" +import { Directory } from "../../../../../api/client.gen.js" +import { func, object, argument } from "../../../../decorators.js" @object() export class Context { diff --git a/sdk/typescript/introspector/test/testdata/coreEnums/expected.json b/sdk/typescript/src/module/introspector/test/testdata/coreEnums/expected.json similarity index 100% rename from sdk/typescript/introspector/test/testdata/coreEnums/expected.json rename to sdk/typescript/src/module/introspector/test/testdata/coreEnums/expected.json diff --git a/sdk/typescript/introspector/test/testdata/coreEnums/index.ts b/sdk/typescript/src/module/introspector/test/testdata/coreEnums/index.ts similarity index 67% rename from sdk/typescript/introspector/test/testdata/coreEnums/index.ts rename to sdk/typescript/src/module/introspector/test/testdata/coreEnums/index.ts index d7c2abe538..8e29838017 100644 --- a/sdk/typescript/introspector/test/testdata/coreEnums/index.ts +++ b/sdk/typescript/src/module/introspector/test/testdata/coreEnums/index.ts @@ -1,5 +1,5 @@ -import { ImageLayerCompression } from "../../../../api/client.gen.js" -import { func, object } from "../../../decorators/decorators.js" +import { ImageLayerCompression } from "../../../../../api/client.gen.js" +import { func, object } from "../../../../decorators.js" @object() export class CoreEnums { diff --git a/sdk/typescript/introspector/test/testdata/enums/expected.json b/sdk/typescript/src/module/introspector/test/testdata/enums/expected.json similarity index 100% rename from sdk/typescript/introspector/test/testdata/enums/expected.json rename to sdk/typescript/src/module/introspector/test/testdata/enums/expected.json diff --git a/sdk/typescript/introspector/test/testdata/enums/index.ts b/sdk/typescript/src/module/introspector/test/testdata/enums/index.ts similarity index 83% rename from sdk/typescript/introspector/test/testdata/enums/index.ts rename to sdk/typescript/src/module/introspector/test/testdata/enums/index.ts index 417d69a67b..8c5ab23d84 100644 --- a/sdk/typescript/introspector/test/testdata/enums/index.ts +++ b/sdk/typescript/src/module/introspector/test/testdata/enums/index.ts @@ -1,9 +1,4 @@ -import { - enumType, - field, - func, - object, -} from "../../../decorators/decorators.js" +import { enumType, field, func, object } from "../../../../decorators.js" /** * Enum for Status diff --git a/sdk/typescript/introspector/test/testdata/generate_expected_scan.ts b/sdk/typescript/src/module/introspector/test/testdata/generate_expected_scan.ts similarity index 91% rename from sdk/typescript/introspector/test/testdata/generate_expected_scan.ts rename to sdk/typescript/src/module/introspector/test/testdata/generate_expected_scan.ts index 2dcf3088a8..adf077acc0 100644 --- a/sdk/typescript/introspector/test/testdata/generate_expected_scan.ts +++ b/sdk/typescript/src/module/introspector/test/testdata/generate_expected_scan.ts @@ -2,9 +2,9 @@ import * as fs from "fs" import * as path from "path" import { fileURLToPath } from "url" -import { scan } from "../../scanner/scan.js" +import { scan } from "../../index.js" +import { DaggerModule } from "../../dagger_module/index.js" import { listFiles } from "../../utils/files.js" -import { DaggerModule } from "../../scanner/abtractions/module.js" const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) @@ -24,7 +24,7 @@ async function generateExpectedScan() { let result: DaggerModule try { - result = scan(files, `${entry}`) + result = await scan(files, `${entry}`) } catch (e) { console.error(`Failed to scan ${entry}: ${e}`) continue diff --git a/sdk/typescript/introspector/test/testdata/helloWorld/expected.json b/sdk/typescript/src/module/introspector/test/testdata/helloWorld/expected.json similarity index 100% rename from sdk/typescript/introspector/test/testdata/helloWorld/expected.json rename to sdk/typescript/src/module/introspector/test/testdata/helloWorld/expected.json diff --git a/sdk/typescript/introspector/test/testdata/helloWorld/helloWorld.ts b/sdk/typescript/src/module/introspector/test/testdata/helloWorld/helloWorld.ts similarity index 69% rename from sdk/typescript/introspector/test/testdata/helloWorld/helloWorld.ts rename to sdk/typescript/src/module/introspector/test/testdata/helloWorld/helloWorld.ts index 6faa70ff4f..6402c42ccf 100644 --- a/sdk/typescript/introspector/test/testdata/helloWorld/helloWorld.ts +++ b/sdk/typescript/src/module/introspector/test/testdata/helloWorld/helloWorld.ts @@ -1,4 +1,4 @@ -import { func, object } from "../../../decorators/decorators.js" +import { func, object } from "../../../../decorators.js" /** * HelloWorld class diff --git a/sdk/typescript/introspector/test/testdata/helloWorld/toIgnore.md b/sdk/typescript/src/module/introspector/test/testdata/helloWorld/toIgnore.md similarity index 100% rename from sdk/typescript/introspector/test/testdata/helloWorld/toIgnore.md rename to sdk/typescript/src/module/introspector/test/testdata/helloWorld/toIgnore.md diff --git a/sdk/typescript/introspector/test/testdata/invalid/expected.json b/sdk/typescript/src/module/introspector/test/testdata/invalid/expected.json similarity index 100% rename from sdk/typescript/introspector/test/testdata/invalid/expected.json rename to sdk/typescript/src/module/introspector/test/testdata/invalid/expected.json diff --git a/sdk/typescript/introspector/test/testdata/invalid/index.ts b/sdk/typescript/src/module/introspector/test/testdata/invalid/index.ts similarity index 100% rename from sdk/typescript/introspector/test/testdata/invalid/index.ts rename to sdk/typescript/src/module/introspector/test/testdata/invalid/index.ts diff --git a/sdk/typescript/introspector/test/testdata/list/expected.json b/sdk/typescript/src/module/introspector/test/testdata/list/expected.json similarity index 100% rename from sdk/typescript/introspector/test/testdata/list/expected.json rename to sdk/typescript/src/module/introspector/test/testdata/list/expected.json diff --git a/sdk/typescript/introspector/test/testdata/list/index.ts b/sdk/typescript/src/module/introspector/test/testdata/list/index.ts similarity index 85% rename from sdk/typescript/introspector/test/testdata/list/index.ts rename to sdk/typescript/src/module/introspector/test/testdata/list/index.ts index ba28dd7bc8..21ce8fb7b9 100644 --- a/sdk/typescript/introspector/test/testdata/list/index.ts +++ b/sdk/typescript/src/module/introspector/test/testdata/list/index.ts @@ -1,4 +1,4 @@ -import { func, object } from "../../../decorators/decorators.js" +import { func, object } from "../../../../decorators.js" @object() export class Integer { diff --git a/sdk/typescript/introspector/test/testdata/minimal/expected.json b/sdk/typescript/src/module/introspector/test/testdata/minimal/expected.json similarity index 100% rename from sdk/typescript/introspector/test/testdata/minimal/expected.json rename to sdk/typescript/src/module/introspector/test/testdata/minimal/expected.json diff --git a/sdk/typescript/introspector/test/testdata/minimal/index.ts b/sdk/typescript/src/module/introspector/test/testdata/minimal/index.ts similarity index 70% rename from sdk/typescript/introspector/test/testdata/minimal/index.ts rename to sdk/typescript/src/module/introspector/test/testdata/minimal/index.ts index a718206e3d..7d06fe3003 100644 --- a/sdk/typescript/introspector/test/testdata/minimal/index.ts +++ b/sdk/typescript/src/module/introspector/test/testdata/minimal/index.ts @@ -1,4 +1,4 @@ -import { func, object } from "../../../decorators/decorators.js" +import { func, object } from "../../../../decorators.js" /** * This is the Minimal object @@ -9,16 +9,16 @@ export class Minimal { * This is a field */ @func() - foo: string = "bar"; + foo: string = "bar" @func() hello(): string { - return "hello"; + return "hello" } @func() echo(msg: string): string { - return this.echoOpts(msg, "...", 3); + return this.echoOpts(msg, "...", 3) } /** @@ -30,9 +30,9 @@ export class Minimal { */ @func() echoOpts(msg: string, suffix: string = "", times: number = 1): string { - msg = msg += suffix; + msg = msg += suffix - return msg.repeat(times); + return msg.repeat(times) } /** @@ -42,30 +42,30 @@ export class Minimal { @func() echoMaybe(msg: string, isQuestion = false): string { if (isQuestion) { - return this.echo(msg + "?"); + return this.echo(msg + "?") } - return this.echo(msg); + return this.echo(msg) } @func() echoOptional(msg: string = "default"): string { - return this.echo(msg); + return this.echo(msg) } @func() echoOptionalSlice(msg: string[] = ["foobar"]): string { - return this.echo(msg.join("+")); + return this.echo(msg.join("+")) } @func() echoes(msgs: string[]): string[] { - return [this.echo(msgs.join(" "))]; + return [this.echo(msgs.join(" "))] } @func() echoesVariadic(...msgs: string[]): string { - return this.echo(msgs.join(" ")); + return this.echo(msgs.join(" ")) } @func() diff --git a/sdk/typescript/introspector/test/testdata/multiArgs/expected.json b/sdk/typescript/src/module/introspector/test/testdata/multiArgs/expected.json similarity index 100% rename from sdk/typescript/introspector/test/testdata/multiArgs/expected.json rename to sdk/typescript/src/module/introspector/test/testdata/multiArgs/expected.json diff --git a/sdk/typescript/introspector/test/testdata/multiArgs/index.ts b/sdk/typescript/src/module/introspector/test/testdata/multiArgs/index.ts similarity index 74% rename from sdk/typescript/introspector/test/testdata/multiArgs/index.ts rename to sdk/typescript/src/module/introspector/test/testdata/multiArgs/index.ts index 797d949a3b..753a98a469 100644 --- a/sdk/typescript/introspector/test/testdata/multiArgs/index.ts +++ b/sdk/typescript/src/module/introspector/test/testdata/multiArgs/index.ts @@ -1,4 +1,4 @@ -import { func, object } from "../../../decorators/decorators.js" +import { func, object } from "../../../../decorators.js" @object() // eslint-disable-next-line @typescript-eslint/no-unused-vars diff --git a/sdk/typescript/introspector/test/testdata/multipleObjects/bar.ts b/sdk/typescript/src/module/introspector/test/testdata/multipleObjects/bar.ts similarity index 72% rename from sdk/typescript/introspector/test/testdata/multipleObjects/bar.ts rename to sdk/typescript/src/module/introspector/test/testdata/multipleObjects/bar.ts index dc0ab85785..af90e15504 100644 --- a/sdk/typescript/introspector/test/testdata/multipleObjects/bar.ts +++ b/sdk/typescript/src/module/introspector/test/testdata/multipleObjects/bar.ts @@ -1,8 +1,8 @@ /** * Should be ignored */ -import { dag } from "../../../../api/client.gen.js" -import { func, object } from "../../../decorators/decorators.js" +import { dag } from "../../../../../api/client.gen.js" +import { func, object } from "../../../../decorators.js" /** * Bar class diff --git a/sdk/typescript/introspector/test/testdata/multipleObjects/expected.json b/sdk/typescript/src/module/introspector/test/testdata/multipleObjects/expected.json similarity index 100% rename from sdk/typescript/introspector/test/testdata/multipleObjects/expected.json rename to sdk/typescript/src/module/introspector/test/testdata/multipleObjects/expected.json diff --git a/sdk/typescript/introspector/test/testdata/multipleObjects/foo.ts b/sdk/typescript/src/module/introspector/test/testdata/multipleObjects/foo.ts similarity index 80% rename from sdk/typescript/introspector/test/testdata/multipleObjects/foo.ts rename to sdk/typescript/src/module/introspector/test/testdata/multipleObjects/foo.ts index fbc79fbfe8..17cb1d6a34 100644 --- a/sdk/typescript/introspector/test/testdata/multipleObjects/foo.ts +++ b/sdk/typescript/src/module/introspector/test/testdata/multipleObjects/foo.ts @@ -3,7 +3,7 @@ * * Compose of bar but its file description should be ignore. */ -import { func, object } from "../../../decorators/decorators.js" +import { func, object } from "../../../../decorators.js" import { Bar } from "./bar.js" /** diff --git a/sdk/typescript/introspector/test/testdata/multipleObjectsAsFields/expected.json b/sdk/typescript/src/module/introspector/test/testdata/multipleObjectsAsFields/expected.json similarity index 100% rename from sdk/typescript/introspector/test/testdata/multipleObjectsAsFields/expected.json rename to sdk/typescript/src/module/introspector/test/testdata/multipleObjectsAsFields/expected.json diff --git a/sdk/typescript/introspector/test/testdata/multipleObjectsAsFields/index.ts b/sdk/typescript/src/module/introspector/test/testdata/multipleObjectsAsFields/index.ts similarity index 76% rename from sdk/typescript/introspector/test/testdata/multipleObjectsAsFields/index.ts rename to sdk/typescript/src/module/introspector/test/testdata/multipleObjectsAsFields/index.ts index e929a3afb6..88aac386ef 100644 --- a/sdk/typescript/introspector/test/testdata/multipleObjectsAsFields/index.ts +++ b/sdk/typescript/src/module/introspector/test/testdata/multipleObjectsAsFields/index.ts @@ -1,4 +1,4 @@ -import { object, func } from "../../../decorators/decorators.js" +import { object, func } from "../../../../decorators.js" import { Lint } from "./lint.js" import { Test } from "./test.js" diff --git a/sdk/typescript/introspector/test/testdata/multipleObjectsAsFields/lint.ts b/sdk/typescript/src/module/introspector/test/testdata/multipleObjectsAsFields/lint.ts similarity index 56% rename from sdk/typescript/introspector/test/testdata/multipleObjectsAsFields/lint.ts rename to sdk/typescript/src/module/introspector/test/testdata/multipleObjectsAsFields/lint.ts index 641c8e4570..b20f284d08 100644 --- a/sdk/typescript/introspector/test/testdata/multipleObjectsAsFields/lint.ts +++ b/sdk/typescript/src/module/introspector/test/testdata/multipleObjectsAsFields/lint.ts @@ -1,4 +1,4 @@ -import { func, object } from "../../../decorators/decorators.js" +import { func, object } from "../../../../decorators.js" @object() export class Lint { diff --git a/sdk/typescript/introspector/test/testdata/multipleObjectsAsFields/test.ts b/sdk/typescript/src/module/introspector/test/testdata/multipleObjectsAsFields/test.ts similarity index 56% rename from sdk/typescript/introspector/test/testdata/multipleObjectsAsFields/test.ts rename to sdk/typescript/src/module/introspector/test/testdata/multipleObjectsAsFields/test.ts index 811e7829a2..e4c3a0798e 100644 --- a/sdk/typescript/introspector/test/testdata/multipleObjectsAsFields/test.ts +++ b/sdk/typescript/src/module/introspector/test/testdata/multipleObjectsAsFields/test.ts @@ -1,4 +1,4 @@ -import { func, object } from "../../../decorators/decorators.js" +import { func, object } from "../../../../decorators.js" @object() export class Test { diff --git a/sdk/typescript/introspector/test/testdata/noDecorators/expected.json b/sdk/typescript/src/module/introspector/test/testdata/noDecorators/expected.json similarity index 100% rename from sdk/typescript/introspector/test/testdata/noDecorators/expected.json rename to sdk/typescript/src/module/introspector/test/testdata/noDecorators/expected.json diff --git a/sdk/typescript/introspector/test/testdata/noDecorators/noDecorators.ts b/sdk/typescript/src/module/introspector/test/testdata/noDecorators/noDecorators.ts similarity index 77% rename from sdk/typescript/introspector/test/testdata/noDecorators/noDecorators.ts rename to sdk/typescript/src/module/introspector/test/testdata/noDecorators/noDecorators.ts index 1f56082c85..902a2694ef 100644 --- a/sdk/typescript/introspector/test/testdata/noDecorators/noDecorators.ts +++ b/sdk/typescript/src/module/introspector/test/testdata/noDecorators/noDecorators.ts @@ -1,4 +1,4 @@ -import { func } from "../../../decorators/decorators.js" +import { func } from "../../../../decorators.js" /** * HelloWorld class diff --git a/sdk/typescript/introspector/test/testdata/objectParam/expected.json b/sdk/typescript/src/module/introspector/test/testdata/objectParam/expected.json similarity index 100% rename from sdk/typescript/introspector/test/testdata/objectParam/expected.json rename to sdk/typescript/src/module/introspector/test/testdata/objectParam/expected.json diff --git a/sdk/typescript/introspector/test/testdata/objectParam/index.ts b/sdk/typescript/src/module/introspector/test/testdata/objectParam/index.ts similarity index 89% rename from sdk/typescript/introspector/test/testdata/objectParam/index.ts rename to sdk/typescript/src/module/introspector/test/testdata/objectParam/index.ts index d86d21ced6..0a7c7ddd78 100644 --- a/sdk/typescript/introspector/test/testdata/objectParam/index.ts +++ b/sdk/typescript/src/module/introspector/test/testdata/objectParam/index.ts @@ -1,4 +1,4 @@ -import { func, object } from "../../../decorators/decorators.js" +import { func, object } from "../../../../decorators.js" @object() export class Message { diff --git a/sdk/typescript/introspector/test/testdata/optionalParameter/expected.json b/sdk/typescript/src/module/introspector/test/testdata/optionalParameter/expected.json similarity index 100% rename from sdk/typescript/introspector/test/testdata/optionalParameter/expected.json rename to sdk/typescript/src/module/introspector/test/testdata/optionalParameter/expected.json diff --git a/sdk/typescript/introspector/test/testdata/optionalParameter/index.ts b/sdk/typescript/src/module/introspector/test/testdata/optionalParameter/index.ts similarity index 92% rename from sdk/typescript/introspector/test/testdata/optionalParameter/index.ts rename to sdk/typescript/src/module/introspector/test/testdata/optionalParameter/index.ts index ec0696c986..4b578fee60 100644 --- a/sdk/typescript/introspector/test/testdata/optionalParameter/index.ts +++ b/sdk/typescript/src/module/introspector/test/testdata/optionalParameter/index.ts @@ -1,4 +1,4 @@ -import { func, object } from "../../../decorators/decorators.js" +import { func, object } from "../../../../decorators.js" /** * OptionalParameter class diff --git a/sdk/typescript/introspector/test/testdata/primitives/index.ts b/sdk/typescript/src/module/introspector/test/testdata/primitives/index.ts similarity index 76% rename from sdk/typescript/introspector/test/testdata/primitives/index.ts rename to sdk/typescript/src/module/introspector/test/testdata/primitives/index.ts index 25e9244e31..9966e56c62 100644 --- a/sdk/typescript/introspector/test/testdata/primitives/index.ts +++ b/sdk/typescript/src/module/introspector/test/testdata/primitives/index.ts @@ -1,4 +1,4 @@ -import { func, object } from "../../../decorators/decorators.js" +import { func, object } from "../../../../decorators.js" @object() export class Primitives { diff --git a/sdk/typescript/introspector/test/testdata/privateMethod/expected.json b/sdk/typescript/src/module/introspector/test/testdata/privateMethod/expected.json similarity index 100% rename from sdk/typescript/introspector/test/testdata/privateMethod/expected.json rename to sdk/typescript/src/module/introspector/test/testdata/privateMethod/expected.json diff --git a/sdk/typescript/introspector/test/testdata/privateMethod/index.ts b/sdk/typescript/src/module/introspector/test/testdata/privateMethod/index.ts similarity index 85% rename from sdk/typescript/introspector/test/testdata/privateMethod/index.ts rename to sdk/typescript/src/module/introspector/test/testdata/privateMethod/index.ts index 0287b44085..6d22791fe8 100644 --- a/sdk/typescript/introspector/test/testdata/privateMethod/index.ts +++ b/sdk/typescript/src/module/introspector/test/testdata/privateMethod/index.ts @@ -1,7 +1,7 @@ /** * HelloWorld module with private things */ -import { func, object } from "../../../decorators/decorators.js" +import { func, object } from "../../../../decorators.js" /** * PrivateMethod class diff --git a/sdk/typescript/introspector/test/testdata/references/expected.json b/sdk/typescript/src/module/introspector/test/testdata/references/expected.json similarity index 100% rename from sdk/typescript/introspector/test/testdata/references/expected.json rename to sdk/typescript/src/module/introspector/test/testdata/references/expected.json diff --git a/sdk/typescript/introspector/test/testdata/references/index.ts b/sdk/typescript/src/module/introspector/test/testdata/references/index.ts similarity index 92% rename from sdk/typescript/introspector/test/testdata/references/index.ts rename to sdk/typescript/src/module/introspector/test/testdata/references/index.ts index 364473702f..44351f7190 100644 --- a/sdk/typescript/introspector/test/testdata/references/index.ts +++ b/sdk/typescript/src/module/introspector/test/testdata/references/index.ts @@ -1,4 +1,4 @@ -import { func, object } from "../../../decorators/decorators.js" +import { func, object } from "../../../../decorators.js" import { defaultEnum, TestEnum } from "./types.js" import type { STR, Data } from "./types.js" diff --git a/sdk/typescript/introspector/test/testdata/references/types.ts b/sdk/typescript/src/module/introspector/test/testdata/references/types.ts similarity index 100% rename from sdk/typescript/introspector/test/testdata/references/types.ts rename to sdk/typescript/src/module/introspector/test/testdata/references/types.ts diff --git a/sdk/typescript/introspector/test/testdata/scalar/expected.json b/sdk/typescript/src/module/introspector/test/testdata/scalar/expected.json similarity index 100% rename from sdk/typescript/introspector/test/testdata/scalar/expected.json rename to sdk/typescript/src/module/introspector/test/testdata/scalar/expected.json diff --git a/sdk/typescript/introspector/test/testdata/scalar/index.ts b/sdk/typescript/src/module/introspector/test/testdata/scalar/index.ts similarity index 65% rename from sdk/typescript/introspector/test/testdata/scalar/index.ts rename to sdk/typescript/src/module/introspector/test/testdata/scalar/index.ts index 1aff7eb8f1..c166b5f36b 100644 --- a/sdk/typescript/introspector/test/testdata/scalar/index.ts +++ b/sdk/typescript/src/module/introspector/test/testdata/scalar/index.ts @@ -1,5 +1,5 @@ -import type { Platform } from "../../../../api/client.gen.js" -import { func, object } from "../../../decorators/decorators.js" +import type { Platform } from "../../../../../api/client.gen.js" +import { func, object } from "../../../../decorators.js" @object() export class Scalar { diff --git a/sdk/typescript/introspector/test/testdata/state/expected.json b/sdk/typescript/src/module/introspector/test/testdata/state/expected.json similarity index 100% rename from sdk/typescript/introspector/test/testdata/state/expected.json rename to sdk/typescript/src/module/introspector/test/testdata/state/expected.json diff --git a/sdk/typescript/introspector/test/testdata/state/state.ts b/sdk/typescript/src/module/introspector/test/testdata/state/state.ts similarity index 88% rename from sdk/typescript/introspector/test/testdata/state/state.ts rename to sdk/typescript/src/module/introspector/test/testdata/state/state.ts index cc2bd0dd2c..96a5184136 100644 --- a/sdk/typescript/introspector/test/testdata/state/state.ts +++ b/sdk/typescript/src/module/introspector/test/testdata/state/state.ts @@ -3,8 +3,8 @@ * * Warning: Do not reproduce in production. */ -import { dag, Container } from "../../../../api/client.gen.js" -import { func, object } from "../../../decorators/decorators.js" +import { dag, Container } from "../../../../../api/client.gen.js" +import { func, object } from "../../../../decorators.js" /** * State module diff --git a/sdk/typescript/introspector/test/testdata/variadic/expected.json b/sdk/typescript/src/module/introspector/test/testdata/variadic/expected.json similarity index 100% rename from sdk/typescript/introspector/test/testdata/variadic/expected.json rename to sdk/typescript/src/module/introspector/test/testdata/variadic/expected.json diff --git a/sdk/typescript/introspector/test/testdata/variadic/index.ts b/sdk/typescript/src/module/introspector/test/testdata/variadic/index.ts similarity index 88% rename from sdk/typescript/introspector/test/testdata/variadic/index.ts rename to sdk/typescript/src/module/introspector/test/testdata/variadic/index.ts index b8c4965b1a..b45b25256c 100644 --- a/sdk/typescript/introspector/test/testdata/variadic/index.ts +++ b/sdk/typescript/src/module/introspector/test/testdata/variadic/index.ts @@ -1,4 +1,4 @@ -import { func, object } from "../../../decorators/decorators.js" +import { func, object } from "../../../../decorators.js" @object() export class Variadic { diff --git a/sdk/typescript/introspector/test/testdata/voidReturn/expected.json b/sdk/typescript/src/module/introspector/test/testdata/voidReturn/expected.json similarity index 100% rename from sdk/typescript/introspector/test/testdata/voidReturn/expected.json rename to sdk/typescript/src/module/introspector/test/testdata/voidReturn/expected.json diff --git a/sdk/typescript/introspector/test/testdata/voidReturn/index.ts b/sdk/typescript/src/module/introspector/test/testdata/voidReturn/index.ts similarity index 79% rename from sdk/typescript/introspector/test/testdata/voidReturn/index.ts rename to sdk/typescript/src/module/introspector/test/testdata/voidReturn/index.ts index 4a6b4ead7a..10a3c525d8 100644 --- a/sdk/typescript/introspector/test/testdata/voidReturn/index.ts +++ b/sdk/typescript/src/module/introspector/test/testdata/voidReturn/index.ts @@ -1,4 +1,4 @@ -import { func, object } from "../../../decorators/decorators.js" +import { func, object } from "../../../../decorators.js" /** * VoidReturn class diff --git a/sdk/typescript/introspector/scanner/typedef.ts b/sdk/typescript/src/module/introspector/typedef.ts similarity index 100% rename from sdk/typescript/introspector/scanner/typedef.ts rename to sdk/typescript/src/module/introspector/typedef.ts diff --git a/sdk/typescript/introspector/scanner/typescript_module/ast.ts b/sdk/typescript/src/module/introspector/typescript_module/ast.ts similarity index 98% rename from sdk/typescript/introspector/scanner/typescript_module/ast.ts rename to sdk/typescript/src/module/introspector/typescript_module/ast.ts index 853c1f6bcc..03308ad0b1 100644 --- a/sdk/typescript/introspector/scanner/typescript_module/ast.ts +++ b/sdk/typescript/src/module/introspector/typescript_module/ast.ts @@ -3,8 +3,8 @@ import Module from "node:module" import ts from "typescript" import { TypeDefKind } from "../../../api/client.gen.js" -import { IntrospectionError } from "../../../common/errors/IntrospectionError.js" -import { DaggerDecorators } from "../dagger_module/decorator.js" +import { IntrospectionError } from "../../../common/errors/index.js" +import { DaggerDecorators } from "../dagger_module/index.js" import { TypeDef } from "../typedef.js" import { DeclarationsMap, isDeclarationOf } from "./declarations.js" import { getValueByExportedName } from "./explorer.js" diff --git a/sdk/typescript/introspector/scanner/typescript_module/declarations.ts b/sdk/typescript/src/module/introspector/typescript_module/declarations.ts similarity index 100% rename from sdk/typescript/introspector/scanner/typescript_module/declarations.ts rename to sdk/typescript/src/module/introspector/typescript_module/declarations.ts diff --git a/sdk/typescript/introspector/scanner/typescript_module/explorer.ts b/sdk/typescript/src/module/introspector/typescript_module/explorer.ts similarity index 100% rename from sdk/typescript/introspector/scanner/typescript_module/explorer.ts rename to sdk/typescript/src/module/introspector/typescript_module/explorer.ts diff --git a/sdk/typescript/src/module/introspector/typescript_module/index.ts b/sdk/typescript/src/module/introspector/typescript_module/index.ts new file mode 100644 index 0000000000..8b4b43595b --- /dev/null +++ b/sdk/typescript/src/module/introspector/typescript_module/index.ts @@ -0,0 +1,3 @@ +export * from "./ast.js" +export * from "./explorer.js" +export * from "./typedef_utils.js" diff --git a/sdk/typescript/introspector/scanner/typescript_module/typedef_utils.ts b/sdk/typescript/src/module/introspector/typescript_module/typedef_utils.ts similarity index 93% rename from sdk/typescript/introspector/scanner/typescript_module/typedef_utils.ts rename to sdk/typescript/src/module/introspector/typescript_module/typedef_utils.ts index 5930d380ed..18ae39b507 100644 --- a/sdk/typescript/introspector/scanner/typescript_module/typedef_utils.ts +++ b/sdk/typescript/src/module/introspector/typescript_module/typedef_utils.ts @@ -1,5 +1,5 @@ import { TypeDefKind } from "../../../api/client.gen.js" -import { IntrospectionError } from "../../../common/errors/IntrospectionError.js" +import { IntrospectionError } from "../../../common/errors/index.js" import { TypeDef } from "../typedef.js" export function isTypeDefResolved(typeDef: TypeDef): boolean { diff --git a/sdk/typescript/introspector/utils/files.ts b/sdk/typescript/src/module/introspector/utils/files.ts similarity index 100% rename from sdk/typescript/introspector/utils/files.ts rename to sdk/typescript/src/module/introspector/utils/files.ts diff --git a/sdk/typescript/introspector/registry/registry.ts b/sdk/typescript/src/module/registry.ts similarity index 98% rename from sdk/typescript/introspector/registry/registry.ts rename to sdk/typescript/src/module/registry.ts index faa1a2e289..e850c14ebc 100644 --- a/sdk/typescript/introspector/registry/registry.ts +++ b/sdk/typescript/src/module/registry.ts @@ -5,7 +5,7 @@ // @emitDecoratorMetadata import "reflect-metadata" -import { UnknownDaggerError } from "../../common/errors/UnknownDaggerError.js" +import { UnknownDaggerError } from "../common/errors/index.js" export type Class = { new (...args: any[]): any } diff --git a/sdk/typescript/provisioning/.gitattributes b/sdk/typescript/src/provisioning/.gitattributes similarity index 100% rename from sdk/typescript/provisioning/.gitattributes rename to sdk/typescript/src/provisioning/.gitattributes diff --git a/sdk/typescript/provisioning/bin.ts b/sdk/typescript/src/provisioning/bin.ts similarity index 99% rename from sdk/typescript/provisioning/bin.ts rename to sdk/typescript/src/provisioning/bin.ts index 4d7d873575..1873319184 100644 --- a/sdk/typescript/provisioning/bin.ts +++ b/sdk/typescript/src/provisioning/bin.ts @@ -18,7 +18,7 @@ import { EngineSessionError, InitEngineSessionBinaryError, } from "../common/errors/index.js" -import { createGQLClient } from "../graphql/client.js" +import { createGQLClient } from "../common/graphql/client.js" import { ConnectOpts, EngineConn, ConnectParams } from "./engineconn.js" const CLI_HOST = "dl.dagger.io" diff --git a/sdk/typescript/provisioning/default.ts b/sdk/typescript/src/provisioning/default.ts similarity index 100% rename from sdk/typescript/provisioning/default.ts rename to sdk/typescript/src/provisioning/default.ts diff --git a/sdk/typescript/src/provisioning/engineconn.ts b/sdk/typescript/src/provisioning/engineconn.ts new file mode 100644 index 0000000000..ba8bad4a5f --- /dev/null +++ b/sdk/typescript/src/provisioning/engineconn.ts @@ -0,0 +1,33 @@ +import { GraphQLClient } from "graphql-request" +import { Writable } from "node:stream" + +export interface ConnectOpts { + Workdir?: string + Project?: string + LogOutput?: Writable + Timeout?: number +} + +export interface ConnectParams { + port: number + session_token: string +} + +export interface EngineConn { + /** + * Library connection provisioning, it returns a ready to use GraphQL client + * connected to the Dagger engine. + * + * This test multiple options to connect to the Dagger Engine. + * 1. Check for already running engine through `DAGGER_SESSION_PORT` & `DAGGER_SESSION_TOKEN` + * environment variable. + * 2. Auto provision the engine from the Dagger CLI (install it if it doesn't exist) and + * connect the client. + */ + Connect: (opts: ConnectOpts) => Promise + + /** + * Close stops the current connection. + */ + Close: () => void +} diff --git a/sdk/typescript/src/provisioning/index.ts b/sdk/typescript/src/provisioning/index.ts new file mode 100644 index 0000000000..4f4cba91ae --- /dev/null +++ b/sdk/typescript/src/provisioning/index.ts @@ -0,0 +1,22 @@ +import { GraphQLClient } from "graphql-request" + +import { ConnectOpts } from "../connectOpts.js" +import { Bin } from "./bin.js" +import { CLI_VERSION } from "./default.js" + +export async function withEngineSession( + connectOpts: ConnectOpts, + cb: (gqlClient: GraphQLClient) => Promise, +): Promise { + const cliBin = process.env["_EXPERIMENTAL_DAGGER_CLI_BIN"] + const engineConn = new Bin(cliBin, CLI_VERSION) + const gqlClient = await engineConn.Connect(connectOpts) + + try { + const res = await cb(gqlClient) + + return res + } finally { + await engineConn.Close() + } +} diff --git a/sdk/typescript/telemetry/index.ts b/sdk/typescript/src/telemetry/index.ts similarity index 100% rename from sdk/typescript/telemetry/index.ts rename to sdk/typescript/src/telemetry/index.ts diff --git a/sdk/typescript/telemetry/init.ts b/sdk/typescript/src/telemetry/init.ts similarity index 100% rename from sdk/typescript/telemetry/init.ts rename to sdk/typescript/src/telemetry/init.ts diff --git a/sdk/typescript/telemetry/telemetry.ts b/sdk/typescript/src/telemetry/telemetry.ts similarity index 100% rename from sdk/typescript/telemetry/telemetry.ts rename to sdk/typescript/src/telemetry/telemetry.ts diff --git a/sdk/typescript/telemetry/tracer.ts b/sdk/typescript/src/telemetry/tracer.ts similarity index 100% rename from sdk/typescript/telemetry/tracer.ts rename to sdk/typescript/src/telemetry/tracer.ts diff --git a/sdk/typescript/test/connect.spec.ts b/sdk/typescript/src/test/connect.spec.ts similarity index 88% rename from sdk/typescript/test/connect.spec.ts rename to sdk/typescript/src/test/connect.spec.ts index d75180d81f..ecbee683d2 100644 --- a/sdk/typescript/test/connect.spec.ts +++ b/sdk/typescript/src/test/connect.spec.ts @@ -9,7 +9,7 @@ import * as tar from "tar" import { dag } from "../api/client.gen.js" import { GraphQLRequestError } from "../common/errors/index.js" -import { connect, close, connection } from "../connect.js" +import { connect, connection } from "../connect.js" import * as bin from "../provisioning/bin.js" import { CLI_VERSION } from "../provisioning/default.js" @@ -40,30 +40,30 @@ describe("TypeScript default client", function () { // Check if the connection is actually not set before calling an execution // We verify the lazy evaluation that way - assert.equal(dag["_ctx"]["_client"], undefined) + assert.equal(dag["_ctx"]["_connection"]["_gqlClient"], undefined) - const out = await dag + const ctr = dag .container() .from("alpine:3.16.2") .withExec(["echo", "hello", "world"]) - .stdout() - assert.equal(out, "hello world\n") + await connection(async () => { + const out = await ctr.stdout() - // Check if the connection is still up - assert.notEqual(dag["_ctx"]["_client"], undefined) + assert.equal(out, "hello world\n") - close() + // Check if the connection is still up + assert.notEqual(dag["_ctx"]["_connection"]["_gqlClient"], undefined) + }) - // Check if the connection has been correctly reset - assert.equal(dag["_ctx"]["_client"], undefined) + assert.equal(dag["_ctx"]["_connection"]["_gqlClient"], undefined) }) it("Should automatically close connection", async function () { this.timeout(60000) // Check if the connection is actually not set before calling connection - assert.equal(dag["_ctx"]["_client"], undefined) + assert.equal(dag["_ctx"]["_connection"]["_gqlClient"], undefined) await connection(async () => { const out = await dag @@ -75,23 +75,23 @@ describe("TypeScript default client", function () { assert.equal(out, "hello world\n") // Check if the connection is still up - assert.notEqual(dag["_ctx"]["_client"], undefined) + assert.notEqual(dag["_ctx"]["_connection"]["_gqlClient"], undefined) }) // Check if the connection has been correctly reset - assert.equal(dag["_ctx"]["_client"], undefined) + assert.equal(dag["_ctx"]["_connection"]["_gqlClient"], undefined) }) it("Should automatically close connection with config", async function () { this.timeout(60000) // Check if the connection is actually not set before calling connection - assert.equal(dag["_ctx"]["_client"], undefined) + assert.equal(dag["_ctx"]["_connection"]["_gqlClient"], undefined) await connection( async () => { // Check if the connection is up - assert.notEqual(dag["_ctx"]["_client"], undefined) + assert.notEqual(dag["_ctx"]["_connection"]["_gqlClient"], undefined) const out = await dag .container() @@ -105,7 +105,7 @@ describe("TypeScript default client", function () { ) // Check if the connection has been correctly reset - assert.equal(dag["_ctx"]["_client"], undefined) + assert.equal(dag["_ctx"]["_connection"]["_gqlClient"], undefined) }) }) @@ -125,13 +125,13 @@ describe("TypeScript sdk Connect", function () { await connect( async (client) => { const authorization = JSON.stringify( - client["_ctx"]["_client"]?.requestConfig.headers, + client["_ctx"]["_connection"]["_gqlClient"]?.requestConfig.headers, ) assert.equal( // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - client["_ctx"]["_client"]["url"], + client["_ctx"]["_connection"]["_gqlClient"]["url"], "http://127.0.0.1:1234/query", ) assert.equal(authorization, `{"Authorization":"Basic Zm9vOg=="}`) diff --git a/sdk/typescript/telemetry/attributes.ts b/sdk/typescript/telemetry/attributes.ts deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/sdk/typescript/tsconfig.json b/sdk/typescript/tsconfig.json index b02408058c..7fa2afa71b 100644 --- a/sdk/typescript/tsconfig.json +++ b/sdk/typescript/tsconfig.json @@ -1,11 +1,8 @@ { - "include": ["./**/*"], + "include": ["./src/**/*"], "exclude": [ - "./**/*.spec.ts", - "./dist/**/*", - "./**/testdata/*", - "./runtime/", - "./dev" + "**/testdata/*", + "./src/**/*.spec.ts", ], "compilerOptions": { "target": "ES2022", diff --git a/sdk/typescript/yarn.lock b/sdk/typescript/yarn.lock index d1ac787601..bcf26a74ff 100644 --- a/sdk/typescript/yarn.lock +++ b/sdk/typescript/yarn.lock @@ -134,6 +134,126 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" +"@esbuild/aix-ppc64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz#51299374de171dbd80bb7d838e1cfce9af36f353" + integrity sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ== + +"@esbuild/android-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz#58565291a1fe548638adb9c584237449e5e14018" + integrity sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw== + +"@esbuild/android-arm@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.23.1.tgz#5eb8c652d4c82a2421e3395b808e6d9c42c862ee" + integrity sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ== + +"@esbuild/android-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.23.1.tgz#ae19d665d2f06f0f48a6ac9a224b3f672e65d517" + integrity sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg== + +"@esbuild/darwin-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz#05b17f91a87e557b468a9c75e9d85ab10c121b16" + integrity sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q== + +"@esbuild/darwin-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz#c58353b982f4e04f0d022284b8ba2733f5ff0931" + integrity sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw== + +"@esbuild/freebsd-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz#f9220dc65f80f03635e1ef96cfad5da1f446f3bc" + integrity sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA== + +"@esbuild/freebsd-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz#69bd8511fa013b59f0226d1609ac43f7ce489730" + integrity sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g== + +"@esbuild/linux-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz#8050af6d51ddb388c75653ef9871f5ccd8f12383" + integrity sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g== + +"@esbuild/linux-arm@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz#ecaabd1c23b701070484990db9a82f382f99e771" + integrity sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ== + +"@esbuild/linux-ia32@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz#3ed2273214178109741c09bd0687098a0243b333" + integrity sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ== + +"@esbuild/linux-loong64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz#a0fdf440b5485c81b0fbb316b08933d217f5d3ac" + integrity sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw== + +"@esbuild/linux-mips64el@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz#e11a2806346db8375b18f5e104c5a9d4e81807f6" + integrity sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q== + +"@esbuild/linux-ppc64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz#06a2744c5eaf562b1a90937855b4d6cf7c75ec96" + integrity sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw== + +"@esbuild/linux-riscv64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz#65b46a2892fc0d1af4ba342af3fe0fa4a8fe08e7" + integrity sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA== + +"@esbuild/linux-s390x@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz#e71ea18c70c3f604e241d16e4e5ab193a9785d6f" + integrity sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw== + +"@esbuild/linux-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz#d47f97391e80690d4dfe811a2e7d6927ad9eed24" + integrity sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ== + +"@esbuild/netbsd-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz#44e743c9778d57a8ace4b72f3c6b839a3b74a653" + integrity sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA== + +"@esbuild/openbsd-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz#05c5a1faf67b9881834758c69f3e51b7dee015d7" + integrity sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q== + +"@esbuild/openbsd-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz#2e58ae511bacf67d19f9f2dcd9e8c5a93f00c273" + integrity sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA== + +"@esbuild/sunos-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz#adb022b959d18d3389ac70769cef5a03d3abd403" + integrity sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA== + +"@esbuild/win32-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz#84906f50c212b72ec360f48461d43202f4c8b9a2" + integrity sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A== + +"@esbuild/win32-ia32@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz#5e3eacc515820ff729e90d0cb463183128e82fac" + integrity sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ== + +"@esbuild/win32-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz#81fd50d11e2c32b2d6241470e3185b70c7b30699" + integrity sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg== + "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.0" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" @@ -1176,6 +1296,36 @@ env-paths@^3.0.0: resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-3.0.0.tgz#2f1e89c2f6dbd3408e1b1711dd82d62e317f58da" integrity sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A== +esbuild@~0.23.0: + version "0.23.1" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.23.1.tgz#40fdc3f9265ec0beae6f59824ade1bd3d3d2dab8" + integrity sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg== + optionalDependencies: + "@esbuild/aix-ppc64" "0.23.1" + "@esbuild/android-arm" "0.23.1" + "@esbuild/android-arm64" "0.23.1" + "@esbuild/android-x64" "0.23.1" + "@esbuild/darwin-arm64" "0.23.1" + "@esbuild/darwin-x64" "0.23.1" + "@esbuild/freebsd-arm64" "0.23.1" + "@esbuild/freebsd-x64" "0.23.1" + "@esbuild/linux-arm" "0.23.1" + "@esbuild/linux-arm64" "0.23.1" + "@esbuild/linux-ia32" "0.23.1" + "@esbuild/linux-loong64" "0.23.1" + "@esbuild/linux-mips64el" "0.23.1" + "@esbuild/linux-ppc64" "0.23.1" + "@esbuild/linux-riscv64" "0.23.1" + "@esbuild/linux-s390x" "0.23.1" + "@esbuild/linux-x64" "0.23.1" + "@esbuild/netbsd-x64" "0.23.1" + "@esbuild/openbsd-arm64" "0.23.1" + "@esbuild/openbsd-x64" "0.23.1" + "@esbuild/sunos-x64" "0.23.1" + "@esbuild/win32-arm64" "0.23.1" + "@esbuild/win32-ia32" "0.23.1" + "@esbuild/win32-x64" "0.23.1" + escalade@^3.1.1: version "3.1.2" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" @@ -1435,7 +1585,7 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@~2.3.2: +fsevents@~2.3.2, fsevents@~2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== @@ -1458,6 +1608,13 @@ get-stream@^9.0.0: "@sec-ant/readable-stream" "^0.4.1" is-stream "^4.0.1" +get-tsconfig@^4.7.5: + version "4.8.1" + resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.8.1.tgz#8995eb391ae6e1638d251118c7b56de7eb425471" + integrity sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg== + dependencies: + resolve-pkg-maps "^1.0.0" + glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -2137,6 +2294,11 @@ resolve-from@^4.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== +resolve-pkg-maps@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" + integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== + resolve@^1.22.8: version "1.22.8" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" @@ -2376,6 +2538,16 @@ tslib@^2.1.0, tslib@^2.6.2: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.3.tgz#0438f810ad7a9edcde7a241c3d80db693c8cbfe0" integrity sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ== +tsx@^4.19.2: + version "4.19.2" + resolved "https://registry.yarnpkg.com/tsx/-/tsx-4.19.2.tgz#2d7814783440e0ae42354d0417d9c2989a2ae92c" + integrity sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g== + dependencies: + esbuild "~0.23.0" + get-tsconfig "^4.7.5" + optionalDependencies: + fsevents "~2.3.3" + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" From 44eae687887a59cfb7dc10e8af883effec70a2bb Mon Sep 17 00:00:00 2001 From: Marcos Nils <1578458+marcosnils@users.noreply.github.com> Date: Mon, 9 Dec 2024 18:58:46 -0300 Subject: [PATCH 09/35] engine: don't push local store layers to magicache (#9148) this avoids pushing layers which are not necessary to magicache as they'll always be retrieved from the local dagger content store Signed-off-by: Marcos Lilljedahl --- engine/cache/manager.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/engine/cache/manager.go b/engine/cache/manager.go index b0242c1b0b..2b515018b8 100644 --- a/engine/cache/manager.go +++ b/engine/cache/manager.go @@ -5,11 +5,13 @@ import ( "errors" "fmt" "net/http" + "os" "strings" "sync" "time" "github.com/containerd/containerd/content" + "github.com/dagger/dagger/engine/distconsts" "github.com/moby/buildkit/cache" cacheconfig "github.com/moby/buildkit/cache/config" remotecache "github.com/moby/buildkit/cache/remotecache/v1" @@ -53,6 +55,16 @@ const ( backgroundImportTimeout = 10 * time.Minute ) +var contentStoreLayers = map[string]struct{}{} + +func init() { + layerInfo, _ := os.ReadDir(distconsts.EngineContainerBuiltinContentDir + "/blobs/sha256/") + + for _, li := range layerInfo { + contentStoreLayers[li.Name()] = struct{}{} + } +} + func NewManager(ctx context.Context, managerConfig ManagerConfig) (Manager, error) { localCache := solver.NewCacheManager(ctx, LocalCacheID, managerConfig.KeyStore, managerConfig.ResultStore) m := &manager{ @@ -298,6 +310,9 @@ func (m *manager) Export(ctx context.Context) error { if _, ok := pushedLayers[layer.Digest.String()]; ok { continue } + if _, ok := contentStoreLayers[layer.Digest.String()]; ok { + continue + } if err := m.pushLayer(ctx, layer, remote.Provider); err != nil { return err } From da0726eb96c2d48b0858bd258411a65c0aaa94fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 22:22:57 -0100 Subject: [PATCH 10/35] chore(deps): bump the sdk-python group across 1 directory with 2 updates (#9139) * chore(deps): bump the sdk-python group across 1 directory with 2 updates Bumps the sdk-python group with 2 updates in the /sdk/python/runtime directory: python and [astral-sh/uv](https://github.com/astral-sh/uv). Updates `python` from `2a6386a` to `2b00791` Updates `astral-sh/uv` from 0.5.4 to 0.5.7 - [Release notes](https://github.com/astral-sh/uv/releases) - [Changelog](https://github.com/astral-sh/uv/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/uv/compare/0.5.4...0.5.7) --- updated-dependencies: - dependency-name: python dependency-type: direct:production dependency-group: sdk-python - dependency-name: astral-sh/uv dependency-type: direct:production update-type: version-update:semver-patch dependency-group: sdk-python ... Signed-off-by: dependabot[bot] * Update python packages Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com> --------- Signed-off-by: dependabot[bot] Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Helder Correia <174525+helderco@users.noreply.github.com> --- sdk/python/dev/pyproject.toml | 2 +- sdk/python/dev/uv.lock | 176 +++++------ sdk/python/runtime/Dockerfile | 4 +- sdk/python/uv.lock | 529 ++++++++++++++++++---------------- 4 files changed, 370 insertions(+), 341 deletions(-) diff --git a/sdk/python/dev/pyproject.toml b/sdk/python/dev/pyproject.toml index 7e19103973..78b78081c1 100644 --- a/sdk/python/dev/pyproject.toml +++ b/sdk/python/dev/pyproject.toml @@ -6,7 +6,7 @@ dependencies = ["dagger-io"] [tool.dagger] # Ensure the dev module works both with released and dev engine. -uv-version = "0.5.4" +uv-version = "0.5.7" [tool.uv.sources] dagger-io = { path = "sdk", editable = true } diff --git a/sdk/python/dev/uv.lock b/sdk/python/dev/uv.lock index 4c34be390d..f07651bcdf 100644 --- a/sdk/python/dev/uv.lock +++ b/sdk/python/dev/uv.lock @@ -3,15 +3,16 @@ requires-python = ">=3.12" [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, { name = "sniffio" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9f/09/45b9b7a6d4e45c6bcb5bf61d19e3ab87df68e0601fa8c5293de3542546cc/anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c", size = 173422 } +sdist = { url = "https://files.pythonhosted.org/packages/f6/40/318e58f669b1a9e00f5c4453910682e2d9dd594334539c7b7817dabb765f/anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48", size = 177076 } wheels = [ - { url = "https://files.pythonhosted.org/packages/e4/f5/f2b75d2fc6f1a260f340f0e7c6a060f4dd2961cc16884ed851b0d18da06a/anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d", size = 90377 }, + { url = "https://files.pythonhosted.org/packages/a0/7a/4daaf3b6c08ad7ceffea4634ec206faeff697526421c20f07628c7372156/anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352", size = 93052 }, ] [[package]] @@ -221,18 +222,17 @@ wheels = [ [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, { name = "certifi" }, { name = "httpcore" }, { name = "idna" }, - { name = "sniffio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/78/82/08f8c936781f67d9e6b9eeb8a0c8b4e406136ea4c3d1f89a5db71d42e0e6/httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2", size = 144189 } +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406 } wheels = [ - { url = "https://files.pythonhosted.org/packages/56/95/9377bcb415797e44274b51d46e3249eba641711cf3348050f76ee7b15ffc/httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0", size = 76395 }, + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517 }, ] [[package]] @@ -420,57 +420,57 @@ wheels = [ [[package]] name = "propcache" -version = "0.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a9/4d/5e5a60b78dbc1d464f8a7bbaeb30957257afdc8512cbb9dfd5659304f5cd/propcache-0.2.0.tar.gz", hash = "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70", size = 40951 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7c/46/a41ca1097769fc548fc9216ec4c1471b772cc39720eb47ed7e38ef0006a9/propcache-0.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:2ee7606193fb267be4b2e3b32714f2d58cad27217638db98a60f9efb5efeccc2", size = 80800 }, - { url = "https://files.pythonhosted.org/packages/75/4f/93df46aab9cc473498ff56be39b5f6ee1e33529223d7a4d8c0a6101a9ba2/propcache-0.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:91ee8fc02ca52e24bcb77b234f22afc03288e1dafbb1f88fe24db308910c4ac7", size = 46443 }, - { url = "https://files.pythonhosted.org/packages/0b/17/308acc6aee65d0f9a8375e36c4807ac6605d1f38074b1581bd4042b9fb37/propcache-0.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e900bad2a8456d00a113cad8c13343f3b1f327534e3589acc2219729237a2e8", size = 45676 }, - { url = "https://files.pythonhosted.org/packages/65/44/626599d2854d6c1d4530b9a05e7ff2ee22b790358334b475ed7c89f7d625/propcache-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f52a68c21363c45297aca15561812d542f8fc683c85201df0bebe209e349f793", size = 246191 }, - { url = "https://files.pythonhosted.org/packages/f2/df/5d996d7cb18df076debae7d76ac3da085c0575a9f2be6b1f707fe227b54c/propcache-0.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e41d67757ff4fbc8ef2af99b338bfb955010444b92929e9e55a6d4dcc3c4f09", size = 251791 }, - { url = "https://files.pythonhosted.org/packages/2e/6d/9f91e5dde8b1f662f6dd4dff36098ed22a1ef4e08e1316f05f4758f1576c/propcache-0.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a64e32f8bd94c105cc27f42d3b658902b5bcc947ece3c8fe7bc1b05982f60e89", size = 253434 }, - { url = "https://files.pythonhosted.org/packages/3c/e9/1b54b7e26f50b3e0497cd13d3483d781d284452c2c50dd2a615a92a087a3/propcache-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55346705687dbd7ef0d77883ab4f6fabc48232f587925bdaf95219bae072491e", size = 248150 }, - { url = "https://files.pythonhosted.org/packages/a7/ef/a35bf191c8038fe3ce9a414b907371c81d102384eda5dbafe6f4dce0cf9b/propcache-0.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00181262b17e517df2cd85656fcd6b4e70946fe62cd625b9d74ac9977b64d8d9", size = 233568 }, - { url = "https://files.pythonhosted.org/packages/97/d9/d00bb9277a9165a5e6d60f2142cd1a38a750045c9c12e47ae087f686d781/propcache-0.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6994984550eaf25dd7fc7bd1b700ff45c894149341725bb4edc67f0ffa94efa4", size = 229874 }, - { url = "https://files.pythonhosted.org/packages/8e/78/c123cf22469bdc4b18efb78893e69c70a8b16de88e6160b69ca6bdd88b5d/propcache-0.2.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:56295eb1e5f3aecd516d91b00cfd8bf3a13991de5a479df9e27dd569ea23959c", size = 225857 }, - { url = "https://files.pythonhosted.org/packages/31/1b/fd6b2f1f36d028820d35475be78859d8c89c8f091ad30e377ac49fd66359/propcache-0.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:439e76255daa0f8151d3cb325f6dd4a3e93043e6403e6491813bcaaaa8733887", size = 227604 }, - { url = "https://files.pythonhosted.org/packages/99/36/b07be976edf77a07233ba712e53262937625af02154353171716894a86a6/propcache-0.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f6475a1b2ecb310c98c28d271a30df74f9dd436ee46d09236a6b750a7599ce57", size = 238430 }, - { url = "https://files.pythonhosted.org/packages/0d/64/5822f496c9010e3966e934a011ac08cac8734561842bc7c1f65586e0683c/propcache-0.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3444cdba6628accf384e349014084b1cacd866fbb88433cd9d279d90a54e0b23", size = 244814 }, - { url = "https://files.pythonhosted.org/packages/fd/bd/8657918a35d50b18a9e4d78a5df7b6c82a637a311ab20851eef4326305c1/propcache-0.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4a9d9b4d0a9b38d1c391bb4ad24aa65f306c6f01b512e10a8a34a2dc5675d348", size = 235922 }, - { url = "https://files.pythonhosted.org/packages/a8/6f/ec0095e1647b4727db945213a9f395b1103c442ef65e54c62e92a72a3f75/propcache-0.2.0-cp312-cp312-win32.whl", hash = "sha256:69d3a98eebae99a420d4b28756c8ce6ea5a29291baf2dc9ff9414b42676f61d5", size = 40177 }, - { url = "https://files.pythonhosted.org/packages/20/a2/bd0896fdc4f4c1db46d9bc361c8c79a9bf08ccc08ba054a98e38e7ba1557/propcache-0.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ad9c9b99b05f163109466638bd30ada1722abb01bbb85c739c50b6dc11f92dc3", size = 44446 }, - { url = "https://files.pythonhosted.org/packages/a8/a7/5f37b69197d4f558bfef5b4bceaff7c43cc9b51adf5bd75e9081d7ea80e4/propcache-0.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ecddc221a077a8132cf7c747d5352a15ed763b674c0448d811f408bf803d9ad7", size = 78120 }, - { url = "https://files.pythonhosted.org/packages/c8/cd/48ab2b30a6b353ecb95a244915f85756d74f815862eb2ecc7a518d565b48/propcache-0.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0e53cb83fdd61cbd67202735e6a6687a7b491c8742dfc39c9e01e80354956763", size = 45127 }, - { url = "https://files.pythonhosted.org/packages/a5/ba/0a1ef94a3412aab057bd996ed5f0ac7458be5bf469e85c70fa9ceb43290b/propcache-0.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92fe151145a990c22cbccf9ae15cae8ae9eddabfc949a219c9f667877e40853d", size = 44419 }, - { url = "https://files.pythonhosted.org/packages/b4/6c/ca70bee4f22fa99eacd04f4d2f1699be9d13538ccf22b3169a61c60a27fa/propcache-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6a21ef516d36909931a2967621eecb256018aeb11fc48656e3257e73e2e247a", size = 229611 }, - { url = "https://files.pythonhosted.org/packages/19/70/47b872a263e8511ca33718d96a10c17d3c853aefadeb86dc26e8421184b9/propcache-0.2.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f88a4095e913f98988f5b338c1d4d5d07dbb0b6bad19892fd447484e483ba6b", size = 234005 }, - { url = "https://files.pythonhosted.org/packages/4f/be/3b0ab8c84a22e4a3224719099c1229ddfdd8a6a1558cf75cb55ee1e35c25/propcache-0.2.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a5b3bb545ead161be780ee85a2b54fdf7092815995661947812dde94a40f6fb", size = 237270 }, - { url = "https://files.pythonhosted.org/packages/04/d8/f071bb000d4b8f851d312c3c75701e586b3f643fe14a2e3409b1b9ab3936/propcache-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67aeb72e0f482709991aa91345a831d0b707d16b0257e8ef88a2ad246a7280bf", size = 231877 }, - { url = "https://files.pythonhosted.org/packages/93/e7/57a035a1359e542bbb0a7df95aad6b9871ebee6dce2840cb157a415bd1f3/propcache-0.2.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c997f8c44ec9b9b0bcbf2d422cc00a1d9b9c681f56efa6ca149a941e5560da2", size = 217848 }, - { url = "https://files.pythonhosted.org/packages/f0/93/d1dea40f112ec183398fb6c42fde340edd7bab202411c4aa1a8289f461b6/propcache-0.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2a66df3d4992bc1d725b9aa803e8c5a66c010c65c741ad901e260ece77f58d2f", size = 216987 }, - { url = "https://files.pythonhosted.org/packages/62/4c/877340871251145d3522c2b5d25c16a1690ad655fbab7bb9ece6b117e39f/propcache-0.2.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3ebbcf2a07621f29638799828b8d8668c421bfb94c6cb04269130d8de4fb7136", size = 212451 }, - { url = "https://files.pythonhosted.org/packages/7c/bb/a91b72efeeb42906ef58ccf0cdb87947b54d7475fee3c93425d732f16a61/propcache-0.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1235c01ddaa80da8235741e80815ce381c5267f96cc49b1477fdcf8c047ef325", size = 212879 }, - { url = "https://files.pythonhosted.org/packages/9b/7f/ee7fea8faac57b3ec5d91ff47470c6c5d40d7f15d0b1fccac806348fa59e/propcache-0.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3947483a381259c06921612550867b37d22e1df6d6d7e8361264b6d037595f44", size = 222288 }, - { url = "https://files.pythonhosted.org/packages/ff/d7/acd67901c43d2e6b20a7a973d9d5fd543c6e277af29b1eb0e1f7bd7ca7d2/propcache-0.2.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d5bed7f9805cc29c780f3aee05de3262ee7ce1f47083cfe9f77471e9d6777e83", size = 228257 }, - { url = "https://files.pythonhosted.org/packages/8d/6f/6272ecc7a8daad1d0754cfc6c8846076a8cb13f810005c79b15ce0ef0cf2/propcache-0.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e4a91d44379f45f5e540971d41e4626dacd7f01004826a18cb048e7da7e96544", size = 221075 }, - { url = "https://files.pythonhosted.org/packages/7c/bd/c7a6a719a6b3dd8b3aeadb3675b5783983529e4a3185946aa444d3e078f6/propcache-0.2.0-cp313-cp313-win32.whl", hash = "sha256:f902804113e032e2cdf8c71015651c97af6418363bea8d78dc0911d56c335032", size = 39654 }, - { url = "https://files.pythonhosted.org/packages/88/e7/0eef39eff84fa3e001b44de0bd41c7c0e3432e7648ffd3d64955910f002d/propcache-0.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:8f188cfcc64fb1266f4684206c9de0e80f54622c3f22a910cbd200478aeae61e", size = 43705 }, - { url = "https://files.pythonhosted.org/packages/3d/b6/e6d98278f2d49b22b4d033c9f792eda783b9ab2094b041f013fc69bcde87/propcache-0.2.0-py3-none-any.whl", hash = "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036", size = 11603 }, +version = "0.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/20/c8/2a13f78d82211490855b2fb303b6721348d0787fdd9a12ac46d99d3acde1/propcache-0.2.1.tar.gz", hash = "sha256:3f77ce728b19cb537714499928fe800c3dda29e8d9428778fc7c186da4c09a64", size = 41735 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4c/28/1d205fe49be8b1b4df4c50024e62480a442b1a7b818e734308bb0d17e7fb/propcache-0.2.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:081a430aa8d5e8876c6909b67bd2d937bfd531b0382d3fdedb82612c618bc41a", size = 79588 }, + { url = "https://files.pythonhosted.org/packages/21/ee/fc4d893f8d81cd4971affef2a6cb542b36617cd1d8ce56b406112cb80bf7/propcache-0.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2ccec9ac47cf4e04897619c0e0c1a48c54a71bdf045117d3a26f80d38ab1fb0", size = 45825 }, + { url = "https://files.pythonhosted.org/packages/4a/de/bbe712f94d088da1d237c35d735f675e494a816fd6f54e9db2f61ef4d03f/propcache-0.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:14d86fe14b7e04fa306e0c43cdbeebe6b2c2156a0c9ce56b815faacc193e320d", size = 45357 }, + { url = "https://files.pythonhosted.org/packages/7f/14/7ae06a6cf2a2f1cb382586d5a99efe66b0b3d0c6f9ac2f759e6f7af9d7cf/propcache-0.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:049324ee97bb67285b49632132db351b41e77833678432be52bdd0289c0e05e4", size = 241869 }, + { url = "https://files.pythonhosted.org/packages/cc/59/227a78be960b54a41124e639e2c39e8807ac0c751c735a900e21315f8c2b/propcache-0.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cd9a1d071158de1cc1c71a26014dcdfa7dd3d5f4f88c298c7f90ad6f27bb46d", size = 247884 }, + { url = "https://files.pythonhosted.org/packages/84/58/f62b4ffaedf88dc1b17f04d57d8536601e4e030feb26617228ef930c3279/propcache-0.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98110aa363f1bb4c073e8dcfaefd3a5cea0f0834c2aab23dda657e4dab2f53b5", size = 248486 }, + { url = "https://files.pythonhosted.org/packages/1c/07/ebe102777a830bca91bbb93e3479cd34c2ca5d0361b83be9dbd93104865e/propcache-0.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:647894f5ae99c4cf6bb82a1bb3a796f6e06af3caa3d32e26d2350d0e3e3faf24", size = 243649 }, + { url = "https://files.pythonhosted.org/packages/ed/bc/4f7aba7f08f520376c4bb6a20b9a981a581b7f2e385fa0ec9f789bb2d362/propcache-0.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfd3223c15bebe26518d58ccf9a39b93948d3dcb3e57a20480dfdd315356baff", size = 229103 }, + { url = "https://files.pythonhosted.org/packages/fe/d5/04ac9cd4e51a57a96f78795e03c5a0ddb8f23ec098b86f92de028d7f2a6b/propcache-0.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d71264a80f3fcf512eb4f18f59423fe82d6e346ee97b90625f283df56aee103f", size = 226607 }, + { url = "https://files.pythonhosted.org/packages/e3/f0/24060d959ea41d7a7cc7fdbf68b31852331aabda914a0c63bdb0e22e96d6/propcache-0.2.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:e73091191e4280403bde6c9a52a6999d69cdfde498f1fdf629105247599b57ec", size = 221153 }, + { url = "https://files.pythonhosted.org/packages/77/a7/3ac76045a077b3e4de4859a0753010765e45749bdf53bd02bc4d372da1a0/propcache-0.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3935bfa5fede35fb202c4b569bb9c042f337ca4ff7bd540a0aa5e37131659348", size = 222151 }, + { url = "https://files.pythonhosted.org/packages/e7/af/5e29da6f80cebab3f5a4dcd2a3240e7f56f2c4abf51cbfcc99be34e17f0b/propcache-0.2.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f508b0491767bb1f2b87fdfacaba5f7eddc2f867740ec69ece6d1946d29029a6", size = 233812 }, + { url = "https://files.pythonhosted.org/packages/8c/89/ebe3ad52642cc5509eaa453e9f4b94b374d81bae3265c59d5c2d98efa1b4/propcache-0.2.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:1672137af7c46662a1c2be1e8dc78cb6d224319aaa40271c9257d886be4363a6", size = 238829 }, + { url = "https://files.pythonhosted.org/packages/e9/2f/6b32f273fa02e978b7577159eae7471b3cfb88b48563b1c2578b2d7ca0bb/propcache-0.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b74c261802d3d2b85c9df2dfb2fa81b6f90deeef63c2db9f0e029a3cac50b518", size = 230704 }, + { url = "https://files.pythonhosted.org/packages/5c/2e/f40ae6ff5624a5f77edd7b8359b208b5455ea113f68309e2b00a2e1426b6/propcache-0.2.1-cp312-cp312-win32.whl", hash = "sha256:d09c333d36c1409d56a9d29b3a1b800a42c76a57a5a8907eacdbce3f18768246", size = 40050 }, + { url = "https://files.pythonhosted.org/packages/3b/77/a92c3ef994e47180862b9d7d11e37624fb1c00a16d61faf55115d970628b/propcache-0.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:c214999039d4f2a5b2073ac506bba279945233da8c786e490d411dfc30f855c1", size = 44117 }, + { url = "https://files.pythonhosted.org/packages/0f/2a/329e0547cf2def8857157f9477669043e75524cc3e6251cef332b3ff256f/propcache-0.2.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aca405706e0b0a44cc6bfd41fbe89919a6a56999157f6de7e182a990c36e37bc", size = 77002 }, + { url = "https://files.pythonhosted.org/packages/12/2d/c4df5415e2382f840dc2ecbca0eeb2293024bc28e57a80392f2012b4708c/propcache-0.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:12d1083f001ace206fe34b6bdc2cb94be66d57a850866f0b908972f90996b3e9", size = 44639 }, + { url = "https://files.pythonhosted.org/packages/d0/5a/21aaa4ea2f326edaa4e240959ac8b8386ea31dedfdaa636a3544d9e7a408/propcache-0.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d93f3307ad32a27bda2e88ec81134b823c240aa3abb55821a8da553eed8d9439", size = 44049 }, + { url = "https://files.pythonhosted.org/packages/4e/3e/021b6cd86c0acc90d74784ccbb66808b0bd36067a1bf3e2deb0f3845f618/propcache-0.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba278acf14471d36316159c94a802933d10b6a1e117b8554fe0d0d9b75c9d536", size = 224819 }, + { url = "https://files.pythonhosted.org/packages/3c/57/c2fdeed1b3b8918b1770a133ba5c43ad3d78e18285b0c06364861ef5cc38/propcache-0.2.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4e6281aedfca15301c41f74d7005e6e3f4ca143584ba696ac69df4f02f40d629", size = 229625 }, + { url = "https://files.pythonhosted.org/packages/9d/81/70d4ff57bf2877b5780b466471bebf5892f851a7e2ca0ae7ffd728220281/propcache-0.2.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b750a8e5a1262434fb1517ddf64b5de58327f1adc3524a5e44c2ca43305eb0b", size = 232934 }, + { url = "https://files.pythonhosted.org/packages/3c/b9/bb51ea95d73b3fb4100cb95adbd4e1acaf2cbb1fd1083f5468eeb4a099a8/propcache-0.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf72af5e0fb40e9babf594308911436c8efde3cb5e75b6f206c34ad18be5c052", size = 227361 }, + { url = "https://files.pythonhosted.org/packages/f1/20/3c6d696cd6fd70b29445960cc803b1851a1131e7a2e4ee261ee48e002bcd/propcache-0.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b2d0a12018b04f4cb820781ec0dffb5f7c7c1d2a5cd22bff7fb055a2cb19ebce", size = 213904 }, + { url = "https://files.pythonhosted.org/packages/a1/cb/1593bfc5ac6d40c010fa823f128056d6bc25b667f5393781e37d62f12005/propcache-0.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e800776a79a5aabdb17dcc2346a7d66d0777e942e4cd251defeb084762ecd17d", size = 212632 }, + { url = "https://files.pythonhosted.org/packages/6d/5c/e95617e222be14a34c709442a0ec179f3207f8a2b900273720501a70ec5e/propcache-0.2.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:4160d9283bd382fa6c0c2b5e017acc95bc183570cd70968b9202ad6d8fc48dce", size = 207897 }, + { url = "https://files.pythonhosted.org/packages/8e/3b/56c5ab3dc00f6375fbcdeefdede5adf9bee94f1fab04adc8db118f0f9e25/propcache-0.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:30b43e74f1359353341a7adb783c8f1b1c676367b011709f466f42fda2045e95", size = 208118 }, + { url = "https://files.pythonhosted.org/packages/86/25/d7ef738323fbc6ebcbce33eb2a19c5e07a89a3df2fded206065bd5e868a9/propcache-0.2.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:58791550b27d5488b1bb52bc96328456095d96206a250d28d874fafe11b3dfaf", size = 217851 }, + { url = "https://files.pythonhosted.org/packages/b3/77/763e6cef1852cf1ba740590364ec50309b89d1c818e3256d3929eb92fabf/propcache-0.2.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:0f022d381747f0dfe27e99d928e31bc51a18b65bb9e481ae0af1380a6725dd1f", size = 222630 }, + { url = "https://files.pythonhosted.org/packages/4f/e9/0f86be33602089c701696fbed8d8c4c07b6ee9605c5b7536fd27ed540c5b/propcache-0.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:297878dc9d0a334358f9b608b56d02e72899f3b8499fc6044133f0d319e2ec30", size = 216269 }, + { url = "https://files.pythonhosted.org/packages/cc/02/5ac83217d522394b6a2e81a2e888167e7ca629ef6569a3f09852d6dcb01a/propcache-0.2.1-cp313-cp313-win32.whl", hash = "sha256:ddfab44e4489bd79bda09d84c430677fc7f0a4939a73d2bba3073036f487a0a6", size = 39472 }, + { url = "https://files.pythonhosted.org/packages/f4/33/d6f5420252a36034bc8a3a01171bc55b4bff5df50d1c63d9caa50693662f/propcache-0.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:556fc6c10989f19a179e4321e5d678db8eb2924131e64652a51fe83e4c3db0e1", size = 43363 }, + { url = "https://files.pythonhosted.org/packages/41/b6/c5319caea262f4821995dca2107483b94a3345d4607ad797c76cb9c36bcc/propcache-0.2.1-py3-none-any.whl", hash = "sha256:52277518d6aae65536e9cea52d4e7fd2f7a66f4aa2d30ed3f2fcea620ace3c54", size = 11818 }, ] [[package]] name = "protobuf" -version = "5.28.3" +version = "5.29.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/74/6e/e69eb906fddcb38f8530a12f4b410699972ab7ced4e21524ece9d546ac27/protobuf-5.28.3.tar.gz", hash = "sha256:64badbc49180a5e401f373f9ce7ab1d18b63f7dd4a9cdc43c92b9f0b481cef7b", size = 422479 } +sdist = { url = "https://files.pythonhosted.org/packages/d2/4f/1639b7b1633d8fd55f216ba01e21bf2c43384ab25ef3ddb35d85a52033e8/protobuf-5.29.1.tar.gz", hash = "sha256:683be02ca21a6ffe80db6dd02c0b5b2892322c59ca57fd6c872d652cb80549cb", size = 424965 } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/c5/05163fad52d7c43e124a545f1372d18266db36036377ad29de4271134a6a/protobuf-5.28.3-cp310-abi3-win32.whl", hash = "sha256:0c4eec6f987338617072592b97943fdbe30d019c56126493111cf24344c1cc24", size = 419624 }, - { url = "https://files.pythonhosted.org/packages/9c/4c/4563ebe001ff30dca9d7ed12e471fa098d9759712980cde1fd03a3a44fb7/protobuf-5.28.3-cp310-abi3-win_amd64.whl", hash = "sha256:91fba8f445723fcf400fdbe9ca796b19d3b1242cd873907979b9ed71e4afe868", size = 431464 }, - { url = "https://files.pythonhosted.org/packages/1c/f2/baf397f3dd1d3e4af7e3f5a0382b868d25ac068eefe1ebde05132333436c/protobuf-5.28.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:a3f6857551e53ce35e60b403b8a27b0295f7d6eb63d10484f12bc6879c715687", size = 414743 }, - { url = "https://files.pythonhosted.org/packages/85/50/cd61a358ba1601f40e7d38bcfba22e053f40ef2c50d55b55926aecc8fec7/protobuf-5.28.3-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:3fa2de6b8b29d12c61911505d893afe7320ce7ccba4df913e2971461fa36d584", size = 316511 }, - { url = "https://files.pythonhosted.org/packages/5d/ae/3257b09328c0b4e59535e497b0c7537d4954038bdd53a2f0d2f49d15a7c4/protobuf-5.28.3-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:712319fbdddb46f21abb66cd33cb9e491a5763b2febd8f228251add221981135", size = 316624 }, - { url = "https://files.pythonhosted.org/packages/ad/c3/2377c159e28ea89a91cf1ca223f827ae8deccb2c9c401e5ca233cd73002f/protobuf-5.28.3-py3-none-any.whl", hash = "sha256:cee1757663fa32a1ee673434fcf3bf24dd54763c79690201208bafec62f19eed", size = 169511 }, + { url = "https://files.pythonhosted.org/packages/50/c7/28669b04691a376cf7d0617d612f126aa0fff763d57df0142f9bf474c5b8/protobuf-5.29.1-cp310-abi3-win32.whl", hash = "sha256:22c1f539024241ee545cbcb00ee160ad1877975690b16656ff87dde107b5f110", size = 422706 }, + { url = "https://files.pythonhosted.org/packages/e3/33/dc7a7712f457456b7e0b16420ab8ba1cc8686751d3f28392eb43d0029ab9/protobuf-5.29.1-cp310-abi3-win_amd64.whl", hash = "sha256:1fc55267f086dd4050d18ef839d7bd69300d0d08c2a53ca7df3920cc271a3c34", size = 434505 }, + { url = "https://files.pythonhosted.org/packages/e5/39/44239fb1c6ec557e1731d996a5de89a9eb1ada7a92491fcf9c5d714052ed/protobuf-5.29.1-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:d473655e29c0c4bbf8b69e9a8fb54645bc289dead6d753b952e7aa660254ae18", size = 417822 }, + { url = "https://files.pythonhosted.org/packages/fb/4a/ec56f101d38d4bef2959a9750209809242d86cf8b897db00f2f98bfa360e/protobuf-5.29.1-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:b5ba1d0e4c8a40ae0496d0e2ecfdbb82e1776928a205106d14ad6985a09ec155", size = 319572 }, + { url = "https://files.pythonhosted.org/packages/04/52/c97c58a33b3d6c89a8138788576d372a90a6556f354799971c6b4d16d871/protobuf-5.29.1-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:8ee1461b3af56145aca2800e6a3e2f928108c749ba8feccc6f5dd0062c410c0d", size = 319671 }, + { url = "https://files.pythonhosted.org/packages/3b/24/c8c49df8f6587719e1d400109b16c10c6902d0c9adddc8fff82840146f99/protobuf-5.29.1-py3-none-any.whl", hash = "sha256:32600ddb9c2a53dedc25b8581ea0f1fd8ea04956373c0c07577ce58d312522e0", size = 172547 }, ] [[package]] @@ -575,48 +575,48 @@ wheels = [ [[package]] name = "yarl" -version = "1.18.0" +version = "1.18.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, { name = "multidict" }, { name = "propcache" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5e/4b/53db4ecad4d54535aff3dfda1f00d6363d79455f62b11b8ca97b82746bd2/yarl-1.18.0.tar.gz", hash = "sha256:20d95535e7d833889982bfe7cc321b7f63bf8879788fee982c76ae2b24cfb715", size = 180098 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/23/36/c579b80a5c76c0d41c8e08baddb3e6940dfc20569db579a5691392c52afa/yarl-1.18.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1ece25e2251c28bab737bdf0519c88189b3dd9492dc086a1d77336d940c28ced", size = 142376 }, - { url = "https://files.pythonhosted.org/packages/0c/5f/e247dc7c0607a0c505fea6c839721844bee55686dfb183c7d7b8ef8a9cb1/yarl-1.18.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:454902dc1830d935c90b5b53c863ba2a98dcde0fbaa31ca2ed1ad33b2a7171c6", size = 94692 }, - { url = "https://files.pythonhosted.org/packages/eb/e1/3081b578a6f21961711b9a1c49c2947abb3b0d0dd9537378fb06777ce8ee/yarl-1.18.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:01be8688fc211dc237e628fcc209dda412d35de7642453059a0553747018d075", size = 92527 }, - { url = "https://files.pythonhosted.org/packages/2f/fa/d9e1b9fbafa4cc82cd3980b5314741b33c2fe16308d725449a23aed32021/yarl-1.18.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d26f1fa9fa2167bb238f6f4b20218eb4e88dd3ef21bb8f97439fa6b5313e30d", size = 332096 }, - { url = "https://files.pythonhosted.org/packages/93/b6/dd27165114317875838e216214fb86338dc63d2e50855a8f2a12de2a7fe5/yarl-1.18.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b234a4a9248a9f000b7a5dfe84b8cb6210ee5120ae70eb72a4dcbdb4c528f72f", size = 342047 }, - { url = "https://files.pythonhosted.org/packages/fc/9f/bad434b5279ae7a356844e14dc771c3d29eb928140bbc01621af811c8a27/yarl-1.18.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe94d1de77c4cd8caff1bd5480e22342dbd54c93929f5943495d9c1e8abe9f42", size = 341712 }, - { url = "https://files.pythonhosted.org/packages/9a/9f/63864f43d131ba8c8cdf1bde5dd3f02f0eff8a7c883a5d7fad32f204fda5/yarl-1.18.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b4c90c5363c6b0a54188122b61edb919c2cd1119684999d08cd5e538813a28e", size = 336654 }, - { url = "https://files.pythonhosted.org/packages/20/30/b4542bbd9be73de155213207eec019f6fe6495885f7dd59aa1ff705a041b/yarl-1.18.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49a98ecadc5a241c9ba06de08127ee4796e1009555efd791bac514207862b43d", size = 325484 }, - { url = "https://files.pythonhosted.org/packages/69/bc/e2a9808ec26989cf0d1b98fe7b3cc45c1c6506b5ea4fe43ece5991f28f34/yarl-1.18.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9106025c7f261f9f5144f9aa7681d43867eed06349a7cfb297a1bc804de2f0d1", size = 344213 }, - { url = "https://files.pythonhosted.org/packages/e2/17/0ee5a68886aca1a8071b0d24a1e1c0fd9970dead2ef2d5e26e027fb7ce88/yarl-1.18.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:f275ede6199d0f1ed4ea5d55a7b7573ccd40d97aee7808559e1298fe6efc8dbd", size = 340517 }, - { url = "https://files.pythonhosted.org/packages/fd/db/1fe4ef38ee852bff5ec8f5367d718b3a7dac7520f344b8e50306f68a2940/yarl-1.18.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f7edeb1dcc7f50a2c8e08b9dc13a413903b7817e72273f00878cb70e766bdb3b", size = 346234 }, - { url = "https://files.pythonhosted.org/packages/b4/ee/5e5bccdb821eb9949ba66abb4d19e3299eee00282e37b42f65236120e892/yarl-1.18.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c083f6dd6951b86e484ebfc9c3524b49bcaa9c420cb4b2a78ef9f7a512bfcc85", size = 359625 }, - { url = "https://files.pythonhosted.org/packages/3f/43/95a64d9e7ab4aa1c34fc5ea0edb35b581bc6ad33fd960a8ae34c2040b319/yarl-1.18.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:80741ec5b471fbdfb997821b2842c59660a1c930ceb42f8a84ba8ca0f25a66aa", size = 364239 }, - { url = "https://files.pythonhosted.org/packages/40/19/09ce976c624c9d3cc898f0be5035ddef0c0759d85b2313321cfe77b69915/yarl-1.18.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b1a3297b9cad594e1ff0c040d2881d7d3a74124a3c73e00c3c71526a1234a9f7", size = 357599 }, - { url = "https://files.pythonhosted.org/packages/7d/35/6f33fd29791af2ec161aebe8abe63e788c2b74a6c7e8f29c92e5f5e96849/yarl-1.18.0-cp312-cp312-win32.whl", hash = "sha256:cd6ab7d6776c186f544f893b45ee0c883542b35e8a493db74665d2e594d3ca75", size = 83832 }, - { url = "https://files.pythonhosted.org/packages/4e/8e/cdb40ef98597be107de67b11e2f1f23f911e0f1416b938885d17a338e304/yarl-1.18.0-cp312-cp312-win_amd64.whl", hash = "sha256:039c299a0864d1f43c3e31570045635034ea7021db41bf4842693a72aca8df3a", size = 90132 }, - { url = "https://files.pythonhosted.org/packages/2b/77/2196b657c66f97adaef0244e9e015f30eac0df59c31ad540f79ce328feed/yarl-1.18.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6fb64dd45453225f57d82c4764818d7a205ee31ce193e9f0086e493916bd4f72", size = 140512 }, - { url = "https://files.pythonhosted.org/packages/0e/d8/2bb6e26fddba5c01bad284e4571178c651b97e8e06318efcaa16e07eb9fd/yarl-1.18.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3adaaf9c6b1b4fc258584f4443f24d775a2086aee82d1387e48a8b4f3d6aecf6", size = 93875 }, - { url = "https://files.pythonhosted.org/packages/54/e4/99fbb884dd9f814fb0037dc1783766bb9edcd57b32a76f3ec5ac5c5772d7/yarl-1.18.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:da206d1ec78438a563c5429ab808a2b23ad7bc025c8adbf08540dde202be37d5", size = 91705 }, - { url = "https://files.pythonhosted.org/packages/3b/a2/5bd86eca9449e6b15d3b08005cf4e58e3da972240c2bee427b358c311549/yarl-1.18.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:576d258b21c1db4c6449b1c572c75d03f16a482eb380be8003682bdbe7db2f28", size = 333325 }, - { url = "https://files.pythonhosted.org/packages/94/50/a218da5f159cd985685bc72c500bb1a7fd2d60035d2339b8a9d9e1f99194/yarl-1.18.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c60e547c0a375c4bfcdd60eef82e7e0e8698bf84c239d715f5c1278a73050393", size = 344121 }, - { url = "https://files.pythonhosted.org/packages/a4/e3/830ae465811198b4b5ebecd674b5b3dca4d222af2155eb2144bfe190bbb8/yarl-1.18.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e3818eabaefb90adeb5e0f62f047310079d426387991106d4fbf3519eec7d90a", size = 345163 }, - { url = "https://files.pythonhosted.org/packages/7a/74/05c4326877ca541eee77b1ef74b7ac8081343d3957af8f9291ca6eca6fec/yarl-1.18.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5f72421246c21af6a92fbc8c13b6d4c5427dfd949049b937c3b731f2f9076bd", size = 339130 }, - { url = "https://files.pythonhosted.org/packages/29/42/842f35aa1dae25d132119ee92185e8c75d8b9b7c83346506bd31e9fa217f/yarl-1.18.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7fa7d37f2ada0f42e0723632993ed422f2a679af0e200874d9d861720a54f53e", size = 326418 }, - { url = "https://files.pythonhosted.org/packages/f9/ed/65c0514f2d1e8b92a61f564c914381d078766cab38b5fbde355b3b3af1fb/yarl-1.18.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:42ba84e2ac26a3f252715f8ec17e6fdc0cbf95b9617c5367579fafcd7fba50eb", size = 345204 }, - { url = "https://files.pythonhosted.org/packages/23/31/351f64f0530c372fa01160f38330f44478e7bf3092f5ce2bfcb91605561d/yarl-1.18.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:6a49ad0102c0f0ba839628d0bf45973c86ce7b590cdedf7540d5b1833ddc6f00", size = 341652 }, - { url = "https://files.pythonhosted.org/packages/49/aa/0c6e666c218d567727c1d040d01575685e7f9b18052fd68a59c9f61fe5d9/yarl-1.18.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:96404e8d5e1bbe36bdaa84ef89dc36f0e75939e060ca5cd45451aba01db02902", size = 347257 }, - { url = "https://files.pythonhosted.org/packages/36/0b/33a093b0e13bb8cd0f27301779661ff325270b6644929001f8f33307357d/yarl-1.18.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a0509475d714df8f6d498935b3f307cd122c4ca76f7d426c7e1bb791bcd87eda", size = 359735 }, - { url = "https://files.pythonhosted.org/packages/a8/92/dcc0b37c48632e71ffc2b5f8b0509347a0bde55ab5862ff755dce9dd56c4/yarl-1.18.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:1ff116f0285b5c8b3b9a2680aeca29a858b3b9e0402fc79fd850b32c2bcb9f8b", size = 365982 }, - { url = "https://files.pythonhosted.org/packages/0e/39/30e2a24a7a6c628dccb13eb6c4a03db5f6cd1eb2c6cda56a61ddef764c11/yarl-1.18.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e2580c1d7e66e6d29d6e11855e3b1c6381971e0edd9a5066e6c14d79bc8967af", size = 360128 }, - { url = "https://files.pythonhosted.org/packages/76/13/12b65dca23b1fb8ae44269a4d24048fd32ac90b445c985b0a46fdfa30cfe/yarl-1.18.0-cp313-cp313-win32.whl", hash = "sha256:14408cc4d34e202caba7b5ac9cc84700e3421a9e2d1b157d744d101b061a4a88", size = 309888 }, - { url = "https://files.pythonhosted.org/packages/f6/60/478d3d41a4bf0b9e7dca74d870d114e775d1ff7156b7d1e0e9972e8f97fd/yarl-1.18.0-cp313-cp313-win_amd64.whl", hash = "sha256:1db1537e9cb846eb0ff206eac667f627794be8b71368c1ab3207ec7b6f8c5afc", size = 315459 }, - { url = "https://files.pythonhosted.org/packages/30/9c/3f7ab894a37b1520291247cbc9ea6756228d098dae5b37eec848d404a204/yarl-1.18.0-py3-none-any.whl", hash = "sha256:dbf53db46f7cf176ee01d8d98c39381440776fcda13779d269a8ba664f69bec0", size = 44840 }, +sdist = { url = "https://files.pythonhosted.org/packages/b7/9d/4b94a8e6d2b51b599516a5cb88e5bc99b4d8d4583e468057eaa29d5f0918/yarl-1.18.3.tar.gz", hash = "sha256:ac1801c45cbf77b6c99242eeff4fffb5e4e73a800b5c4ad4fc0be5def634d2e1", size = 181062 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/33/85/bd2e2729752ff4c77338e0102914897512e92496375e079ce0150a6dc306/yarl-1.18.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1dd4bdd05407ced96fed3d7f25dbbf88d2ffb045a0db60dbc247f5b3c5c25d50", size = 142644 }, + { url = "https://files.pythonhosted.org/packages/ff/74/1178322cc0f10288d7eefa6e4a85d8d2e28187ccab13d5b844e8b5d7c88d/yarl-1.18.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7c33dd1931a95e5d9a772d0ac5e44cac8957eaf58e3c8da8c1414de7dd27c576", size = 94962 }, + { url = "https://files.pythonhosted.org/packages/be/75/79c6acc0261e2c2ae8a1c41cf12265e91628c8c58ae91f5ff59e29c0787f/yarl-1.18.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:25b411eddcfd56a2f0cd6a384e9f4f7aa3efee14b188de13048c25b5e91f1640", size = 92795 }, + { url = "https://files.pythonhosted.org/packages/6b/32/927b2d67a412c31199e83fefdce6e645247b4fb164aa1ecb35a0f9eb2058/yarl-1.18.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:436c4fc0a4d66b2badc6c5fc5ef4e47bb10e4fd9bf0c79524ac719a01f3607c2", size = 332368 }, + { url = "https://files.pythonhosted.org/packages/19/e5/859fca07169d6eceeaa4fde1997c91d8abde4e9a7c018e371640c2da2b71/yarl-1.18.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e35ef8683211db69ffe129a25d5634319a677570ab6b2eba4afa860f54eeaf75", size = 342314 }, + { url = "https://files.pythonhosted.org/packages/08/75/76b63ccd91c9e03ab213ef27ae6add2e3400e77e5cdddf8ed2dbc36e3f21/yarl-1.18.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84b2deecba4a3f1a398df819151eb72d29bfeb3b69abb145a00ddc8d30094512", size = 341987 }, + { url = "https://files.pythonhosted.org/packages/1a/e1/a097d5755d3ea8479a42856f51d97eeff7a3a7160593332d98f2709b3580/yarl-1.18.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00e5a1fea0fd4f5bfa7440a47eff01d9822a65b4488f7cff83155a0f31a2ecba", size = 336914 }, + { url = "https://files.pythonhosted.org/packages/0b/42/e1b4d0e396b7987feceebe565286c27bc085bf07d61a59508cdaf2d45e63/yarl-1.18.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0e883008013c0e4aef84dcfe2a0b172c4d23c2669412cf5b3371003941f72bb", size = 325765 }, + { url = "https://files.pythonhosted.org/packages/7e/18/03a5834ccc9177f97ca1bbb245b93c13e58e8225276f01eedc4cc98ab820/yarl-1.18.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5a3f356548e34a70b0172d8890006c37be92995f62d95a07b4a42e90fba54272", size = 344444 }, + { url = "https://files.pythonhosted.org/packages/c8/03/a713633bdde0640b0472aa197b5b86e90fbc4c5bc05b727b714cd8a40e6d/yarl-1.18.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ccd17349166b1bee6e529b4add61727d3f55edb7babbe4069b5764c9587a8cc6", size = 340760 }, + { url = "https://files.pythonhosted.org/packages/eb/99/f6567e3f3bbad8fd101886ea0276c68ecb86a2b58be0f64077396cd4b95e/yarl-1.18.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b958ddd075ddba5b09bb0be8a6d9906d2ce933aee81100db289badbeb966f54e", size = 346484 }, + { url = "https://files.pythonhosted.org/packages/8e/a9/84717c896b2fc6cb15bd4eecd64e34a2f0a9fd6669e69170c73a8b46795a/yarl-1.18.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c7d79f7d9aabd6011004e33b22bc13056a3e3fb54794d138af57f5ee9d9032cb", size = 359864 }, + { url = "https://files.pythonhosted.org/packages/1e/2e/d0f5f1bef7ee93ed17e739ec8dbcb47794af891f7d165fa6014517b48169/yarl-1.18.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4891ed92157e5430874dad17b15eb1fda57627710756c27422200c52d8a4e393", size = 364537 }, + { url = "https://files.pythonhosted.org/packages/97/8a/568d07c5d4964da5b02621a517532adb8ec5ba181ad1687191fffeda0ab6/yarl-1.18.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ce1af883b94304f493698b00d0f006d56aea98aeb49d75ec7d98cd4a777e9285", size = 357861 }, + { url = "https://files.pythonhosted.org/packages/7d/e3/924c3f64b6b3077889df9a1ece1ed8947e7b61b0a933f2ec93041990a677/yarl-1.18.3-cp312-cp312-win32.whl", hash = "sha256:f91c4803173928a25e1a55b943c81f55b8872f0018be83e3ad4938adffb77dd2", size = 84097 }, + { url = "https://files.pythonhosted.org/packages/34/45/0e055320daaabfc169b21ff6174567b2c910c45617b0d79c68d7ab349b02/yarl-1.18.3-cp312-cp312-win_amd64.whl", hash = "sha256:7e2ee16578af3b52ac2f334c3b1f92262f47e02cc6193c598502bd46f5cd1477", size = 90399 }, + { url = "https://files.pythonhosted.org/packages/30/c7/c790513d5328a8390be8f47be5d52e141f78b66c6c48f48d241ca6bd5265/yarl-1.18.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:90adb47ad432332d4f0bc28f83a5963f426ce9a1a8809f5e584e704b82685dcb", size = 140789 }, + { url = "https://files.pythonhosted.org/packages/30/aa/a2f84e93554a578463e2edaaf2300faa61c8701f0898725842c704ba5444/yarl-1.18.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:913829534200eb0f789d45349e55203a091f45c37a2674678744ae52fae23efa", size = 94144 }, + { url = "https://files.pythonhosted.org/packages/c6/fc/d68d8f83714b221a85ce7866832cba36d7c04a68fa6a960b908c2c84f325/yarl-1.18.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ef9f7768395923c3039055c14334ba4d926f3baf7b776c923c93d80195624782", size = 91974 }, + { url = "https://files.pythonhosted.org/packages/56/4e/d2563d8323a7e9a414b5b25341b3942af5902a2263d36d20fb17c40411e2/yarl-1.18.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88a19f62ff30117e706ebc9090b8ecc79aeb77d0b1f5ec10d2d27a12bc9f66d0", size = 333587 }, + { url = "https://files.pythonhosted.org/packages/25/c9/cfec0bc0cac8d054be223e9f2c7909d3e8442a856af9dbce7e3442a8ec8d/yarl-1.18.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e17c9361d46a4d5addf777c6dd5eab0715a7684c2f11b88c67ac37edfba6c482", size = 344386 }, + { url = "https://files.pythonhosted.org/packages/ab/5d/4c532190113b25f1364d25f4c319322e86232d69175b91f27e3ebc2caf9a/yarl-1.18.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a74a13a4c857a84a845505fd2d68e54826a2cd01935a96efb1e9d86c728e186", size = 345421 }, + { url = "https://files.pythonhosted.org/packages/23/d1/6cdd1632da013aa6ba18cee4d750d953104a5e7aac44e249d9410a972bf5/yarl-1.18.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41f7ce59d6ee7741af71d82020346af364949314ed3d87553763a2df1829cc58", size = 339384 }, + { url = "https://files.pythonhosted.org/packages/9a/c4/6b3c39bec352e441bd30f432cda6ba51681ab19bb8abe023f0d19777aad1/yarl-1.18.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f52a265001d830bc425f82ca9eabda94a64a4d753b07d623a9f2863fde532b53", size = 326689 }, + { url = "https://files.pythonhosted.org/packages/23/30/07fb088f2eefdc0aa4fc1af4e3ca4eb1a3aadd1ce7d866d74c0f124e6a85/yarl-1.18.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:82123d0c954dc58db301f5021a01854a85bf1f3bb7d12ae0c01afc414a882ca2", size = 345453 }, + { url = "https://files.pythonhosted.org/packages/63/09/d54befb48f9cd8eec43797f624ec37783a0266855f4930a91e3d5c7717f8/yarl-1.18.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:2ec9bbba33b2d00999af4631a3397d1fd78290c48e2a3e52d8dd72db3a067ac8", size = 341872 }, + { url = "https://files.pythonhosted.org/packages/91/26/fd0ef9bf29dd906a84b59f0cd1281e65b0c3e08c6aa94b57f7d11f593518/yarl-1.18.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:fbd6748e8ab9b41171bb95c6142faf068f5ef1511935a0aa07025438dd9a9bc1", size = 347497 }, + { url = "https://files.pythonhosted.org/packages/d9/b5/14ac7a256d0511b2ac168d50d4b7d744aea1c1aa20c79f620d1059aab8b2/yarl-1.18.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:877d209b6aebeb5b16c42cbb377f5f94d9e556626b1bfff66d7b0d115be88d0a", size = 359981 }, + { url = "https://files.pythonhosted.org/packages/ca/b3/d493221ad5cbd18bc07e642894030437e405e1413c4236dd5db6e46bcec9/yarl-1.18.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b464c4ab4bfcb41e3bfd3f1c26600d038376c2de3297760dfe064d2cb7ea8e10", size = 366229 }, + { url = "https://files.pythonhosted.org/packages/04/56/6a3e2a5d9152c56c346df9b8fb8edd2c8888b1e03f96324d457e5cf06d34/yarl-1.18.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8d39d351e7faf01483cc7ff7c0213c412e38e5a340238826be7e0e4da450fdc8", size = 360383 }, + { url = "https://files.pythonhosted.org/packages/fd/b7/4b3c7c7913a278d445cc6284e59b2e62fa25e72758f888b7a7a39eb8423f/yarl-1.18.3-cp313-cp313-win32.whl", hash = "sha256:61ee62ead9b68b9123ec24bc866cbef297dd266175d53296e2db5e7f797f902d", size = 310152 }, + { url = "https://files.pythonhosted.org/packages/f5/d5/688db678e987c3e0fb17867970700b92603cadf36c56e5fb08f23e822a0c/yarl-1.18.3-cp313-cp313-win_amd64.whl", hash = "sha256:578e281c393af575879990861823ef19d66e2b1d0098414855dd367e234f5b3c", size = 315723 }, + { url = "https://files.pythonhosted.org/packages/f5/4b/a06e0ec3d155924f77835ed2d167ebd3b211a7b0853da1cf8d8414d784ef/yarl-1.18.3-py3-none-any.whl", hash = "sha256:b57f4f58099328dfb26c6a771d09fb20dbbae81d20cfb66141251ea063bd101b", size = 45109 }, ] [[package]] diff --git a/sdk/python/runtime/Dockerfile b/sdk/python/runtime/Dockerfile index c8ce0de02c..49380d15d5 100644 --- a/sdk/python/runtime/Dockerfile +++ b/sdk/python/runtime/Dockerfile @@ -1,3 +1,3 @@ # Images defined here for Dependabot. -FROM python:3.12-slim@sha256:2a6386ad2db20e7f55073f69a98d6da2cf9f168e05e7487d2670baeb9b7601c5 AS base -FROM ghcr.io/astral-sh/uv:0.5.4@sha256:5436c72d52c9c0d011010ce68f4c399702b3b0764adcf282fe0e546f20ebaef6 AS uv +FROM python:3.12-slim@sha256:2b0079146a74e23bf4ae8f6a28e1b484c6292f6fb904cbb51825b4a19812fcd8 AS base +FROM ghcr.io/astral-sh/uv:0.5.7@sha256:23272999edd22e78195509ea3fe380e7632ab39a4c69a340bedaba7555abe20a AS uv diff --git a/sdk/python/uv.lock b/sdk/python/uv.lock index 117883b39c..99e8d0dca4 100644 --- a/sdk/python/uv.lock +++ b/sdk/python/uv.lock @@ -9,16 +9,16 @@ members = [ [[package]] name = "aiohappyeyeballs" -version = "2.4.3" +version = "2.4.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bc/69/2f6d5a019bd02e920a3417689a89887b39ad1e350b562f9955693d900c40/aiohappyeyeballs-2.4.3.tar.gz", hash = "sha256:75cf88a15106a5002a8eb1dab212525c00d1f4c0fa96e551c9fbe6f09a621586", size = 21809 } +sdist = { url = "https://files.pythonhosted.org/packages/7f/55/e4373e888fdacb15563ef6fa9fa8c8252476ea071e96fb46defac9f18bf2/aiohappyeyeballs-2.4.4.tar.gz", hash = "sha256:5fdd7d87889c63183afc18ce9271f9b0a7d32c2303e394468dd45d514a757745", size = 21977 } wheels = [ - { url = "https://files.pythonhosted.org/packages/f7/d8/120cd0fe3e8530df0539e71ba9683eade12cae103dd7543e50d15f737917/aiohappyeyeballs-2.4.3-py3-none-any.whl", hash = "sha256:8a7a83727b2756f394ab2895ea0765a0a8c475e3c71e98d43d76f22b4b435572", size = 14742 }, + { url = "https://files.pythonhosted.org/packages/b9/74/fbb6559de3607b3300b9be3cc64e97548d55678e44623db17820dbd20002/aiohappyeyeballs-2.4.4-py3-none-any.whl", hash = "sha256:a980909d50efcd44795c4afeca523296716d50cd756ddca6af8c65b996e27de8", size = 14756 }, ] [[package]] name = "aiohttp" -version = "3.11.7" +version = "3.11.10" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohappyeyeballs" }, @@ -30,68 +30,68 @@ dependencies = [ { name = "propcache" }, { name = "yarl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4b/cb/f9bb10e0cf6f01730b27d370b10cc15822bea4395acd687abc8cc5fed3ed/aiohttp-3.11.7.tar.gz", hash = "sha256:01a8aca4af3da85cea5c90141d23f4b0eee3cbecfd33b029a45a80f28c66c668", size = 7666482 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/83/7e/fb4723d280b4de2642c57593cb94f942bfdc15def510d12b5d22a1b955a6/aiohttp-3.11.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8bedb1f6cb919af3b6353921c71281b1491f948ca64408871465d889b4ee1b66", size = 706857 }, - { url = "https://files.pythonhosted.org/packages/57/f1/4eb447ad029801b1007ff23025c2bcb2519af2e03085717efa333f1803a5/aiohttp-3.11.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f5022504adab881e2d801a88b748ea63f2a9d130e0b2c430824682a96f6534be", size = 466733 }, - { url = "https://files.pythonhosted.org/packages/ed/7e/e385e54fa3d9360f9d1ea502a5627f2f4bdd141dd227a1f8785335c4fca9/aiohttp-3.11.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e22d1721c978a6494adc824e0916f9d187fa57baeda34b55140315fa2f740184", size = 453993 }, - { url = "https://files.pythonhosted.org/packages/ee/41/660cba8b4b10a9072ae77ce81558cca94d98aaec649a3085e50b8226fc17/aiohttp-3.11.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e993676c71288618eb07e20622572b1250d8713e7e00ab3aabae28cb70f3640d", size = 1576329 }, - { url = "https://files.pythonhosted.org/packages/e1/51/4c59724afde127001b22cf09b28171829329cf2c838cb05f6de521f125cf/aiohttp-3.11.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e13a05db87d3b241c186d0936808d0e4e12decc267c617d54e9c643807e968b6", size = 1630344 }, - { url = "https://files.pythonhosted.org/packages/c7/66/513f15cec950410dbc4439926ea4d9361136df7a97ddffab0deea1b68131/aiohttp-3.11.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ba8d043fed7ffa117024d7ba66fdea011c0e7602327c6d73cacaea38abe4491", size = 1666837 }, - { url = "https://files.pythonhosted.org/packages/7a/c0/3e59d4cd8fd4c0e365d0ec962e0679dfc7629bdf0e67be398ca842ad4661/aiohttp-3.11.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dda3ed0a7869d2fa16aa41f9961ade73aa2c2e3b2fcb0a352524e7b744881889", size = 1580628 }, - { url = "https://files.pythonhosted.org/packages/22/a6/c4aea2cf583821e02f7a92c43f5f554d2334e22b741e21e8f31da2b2386b/aiohttp-3.11.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43bfd25113c1e98aec6c70e26d5f4331efbf4aa9037ba9ad88f090853bf64d7f", size = 1539922 }, - { url = "https://files.pythonhosted.org/packages/7b/54/52f33fc9cecaf28f8400e92d9c22e37939c856c4a8af26a71023ec1de689/aiohttp-3.11.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3dd3e7e7c9ef3e7214f014f1ae260892286647b3cf7c7f1b644a568fd410f8ca", size = 1527342 }, - { url = "https://files.pythonhosted.org/packages/d4/e0/fc91528bfb0283691b0448e93fe64d2416254a9ca34c58c666240440db89/aiohttp-3.11.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:78c657ece7a73b976905ab9ec8be9ef2df12ed8984c24598a1791c58ce3b4ce4", size = 1534194 }, - { url = "https://files.pythonhosted.org/packages/34/be/c6d571f46e9ef1720a850dce4c04dbfe38627a64bfdabdefb448c547e267/aiohttp-3.11.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:db70a47987e34494b451a334605bee57a126fe8d290511349e86810b4be53b01", size = 1609532 }, - { url = "https://files.pythonhosted.org/packages/3d/af/1da6918c83fb427e0f23401dca03b8d6ec776fb61ad25d2f5a8d564418e6/aiohttp-3.11.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:9e67531370a3b07e49b280c1f8c2df67985c790ad2834d1b288a2f13cd341c5f", size = 1630627 }, - { url = "https://files.pythonhosted.org/packages/32/20/fd3f4d8bc60227f1eb2fc20e75679e270ef05f81ae618cd869a68f19a32c/aiohttp-3.11.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9202f184cc0582b1db15056f2225ab4c1e3dac4d9ade50dd0613ac3c46352ac2", size = 1565670 }, - { url = "https://files.pythonhosted.org/packages/b0/9f/db692e10567acb0970618557be3bfe47fe92eac69fa7d3e81315d39b4a8b/aiohttp-3.11.7-cp310-cp310-win32.whl", hash = "sha256:2257bdd5cf54a4039a4337162cd8048f05a724380a2283df34620f55d4e29341", size = 415107 }, - { url = "https://files.pythonhosted.org/packages/0b/8c/9fb539a8a773356df3dbddd77d4a3aff3eda448a602a90e5582d8b1903a4/aiohttp-3.11.7-cp310-cp310-win_amd64.whl", hash = "sha256:b7215bf2b53bc6cb35808149980c2ae80a4ae4e273890ac85459c014d5aa60ac", size = 440569 }, - { url = "https://files.pythonhosted.org/packages/13/7f/272fa1adf68fe2fbebfe686a67b50cfb40d86dfe47d0441aff6f0b7c4c0e/aiohttp-3.11.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cea52d11e02123f125f9055dfe0ccf1c3857225fb879e4a944fae12989e2aef2", size = 706820 }, - { url = "https://files.pythonhosted.org/packages/79/3c/6d612ef77cdba75364393f04c5c577481e3b5123a774eea447ada1ddd14f/aiohttp-3.11.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3ce18f703b7298e7f7633efd6a90138d99a3f9a656cb52c1201e76cb5d79cf08", size = 466654 }, - { url = "https://files.pythonhosted.org/packages/4f/b8/1052667d4800cd49bb4f869f1ed42f5e9d5acd4676275e64ccc244c9c040/aiohttp-3.11.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:670847ee6aeb3a569cd7cdfbe0c3bec1d44828bbfbe78c5d305f7f804870ef9e", size = 454041 }, - { url = "https://files.pythonhosted.org/packages/9f/07/80fa7302314a6ee1c9278550e9d95b77a4c895999bfbc5364ed0ee28dc7c/aiohttp-3.11.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4dda726f89bfa5c465ba45b76515135a3ece0088dfa2da49b8bb278f3bdeea12", size = 1684778 }, - { url = "https://files.pythonhosted.org/packages/2e/30/a71eb45197ad6bb6af87dfb39be8b56417d24d916047d35ef3f164af87f4/aiohttp-3.11.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c25b74a811dba37c7ea6a14d99eb9402d89c8d739d50748a75f3cf994cf19c43", size = 1740992 }, - { url = "https://files.pythonhosted.org/packages/22/74/0f9394429f3c4197129333a150a85cb2a642df30097a39dd41257f0b3bdc/aiohttp-3.11.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5522ee72f95661e79db691310290c4618b86dff2d9b90baedf343fd7a08bf79", size = 1781816 }, - { url = "https://files.pythonhosted.org/packages/7f/1a/1e256b39179c98d16d53ac62f64bfcfe7c5b2c1e68b83cddd4165854524f/aiohttp-3.11.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1fbf41a6bbc319a7816ae0f0177c265b62f2a59ad301a0e49b395746eb2a9884", size = 1676692 }, - { url = "https://files.pythonhosted.org/packages/9b/37/f19d2e00efcabb9183b16bd91244de1d9c4ff7bf0fb5b8302e29a78f3286/aiohttp-3.11.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:59ee1925b5a5efdf6c4e7be51deee93984d0ac14a6897bd521b498b9916f1544", size = 1619523 }, - { url = "https://files.pythonhosted.org/packages/ae/3c/af50cf5e06b98783fd776f17077f7b7e755d461114af5d6744dc037fc3b0/aiohttp-3.11.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:24054fce8c6d6f33a3e35d1c603ef1b91bbcba73e3f04a22b4f2f27dac59b347", size = 1644084 }, - { url = "https://files.pythonhosted.org/packages/c0/a6/4e0233b085cbf2b6de573515c1eddde82f1c1f17e69347e32a5a5f2617ff/aiohttp-3.11.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:351849aca2c6f814575c1a485c01c17a4240413f960df1bf9f5deb0003c61a53", size = 1648332 }, - { url = "https://files.pythonhosted.org/packages/06/20/7062e76e7817318c421c0f9d7b650fb81aaecf6d2f3a9833805b45ec2ea8/aiohttp-3.11.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:12724f3a211fa243570e601f65a8831372caf1a149d2f1859f68479f07efec3d", size = 1730912 }, - { url = "https://files.pythonhosted.org/packages/6c/1c/ff6ae4b1789894e6faf8a4e260cd3861cad618dc80ad15326789a7765750/aiohttp-3.11.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:7ea4490360b605804bea8173d2d086b6c379d6bb22ac434de605a9cbce006e7d", size = 1752619 }, - { url = "https://files.pythonhosted.org/packages/33/58/ddd5cba5ca245c00b04e9d28a7988b0f0eda02de494f8e62ecd2780655c2/aiohttp-3.11.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e0bf378db07df0a713a1e32381a1b277e62ad106d0dbe17b5479e76ec706d720", size = 1692801 }, - { url = "https://files.pythonhosted.org/packages/b2/fc/32d5e2070b43d3722b7ea65ddc6b03ffa39bcc4b5ab6395a825cde0872ad/aiohttp-3.11.7-cp311-cp311-win32.whl", hash = "sha256:cd8d62cab363dfe713067027a5adb4907515861f1e4ce63e7be810b83668b847", size = 414899 }, - { url = "https://files.pythonhosted.org/packages/ec/7e/50324c6d3df4540f5963def810b9927f220c99864065849a1dfcae77a6ce/aiohttp-3.11.7-cp311-cp311-win_amd64.whl", hash = "sha256:bf0e6cce113596377cadda4e3ac5fb89f095bd492226e46d91b4baef1dd16f60", size = 440938 }, - { url = "https://files.pythonhosted.org/packages/bf/1e/2e96b2526c590dcb99db0b94ac4f9b927ecc07f94735a8a941dee143d48b/aiohttp-3.11.7-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:4bb7493c3e3a36d3012b8564bd0e2783259ddd7ef3a81a74f0dbfa000fce48b7", size = 702326 }, - { url = "https://files.pythonhosted.org/packages/b5/ce/b5d7f3e68849f1f5e0b85af4ac9080b9d3c0a600857140024603653c2209/aiohttp-3.11.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e143b0ef9cb1a2b4f74f56d4fbe50caa7c2bb93390aff52f9398d21d89bc73ea", size = 461944 }, - { url = "https://files.pythonhosted.org/packages/28/fa/f4d98db1b7f8f0c3f74bdbd6d0d98cfc89984205cd33f1b8ee3f588ee5ad/aiohttp-3.11.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f7c58a240260822dc07f6ae32a0293dd5bccd618bb2d0f36d51c5dbd526f89c0", size = 454348 }, - { url = "https://files.pythonhosted.org/packages/04/f0/c238dda5dc9a3d12b76636e2cf0ea475890ac3a1c7e4ff0fd6c3cea2fc2d/aiohttp-3.11.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d20cfe63a1c135d26bde8c1d0ea46fd1200884afbc523466d2f1cf517d1fe33", size = 1678795 }, - { url = "https://files.pythonhosted.org/packages/79/ee/3a18f792247e6d95dba13aaedc9dc317c3c6e75f4b88c2dd4b960d20ad2f/aiohttp-3.11.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12e4d45847a174f77b2b9919719203769f220058f642b08504cf8b1cf185dacf", size = 1734411 }, - { url = "https://files.pythonhosted.org/packages/f5/79/3eb84243087a9a32cae821622c935107b4b55a5b21b76772e8e6c41092e9/aiohttp-3.11.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cf4efa2d01f697a7dbd0509891a286a4af0d86902fc594e20e3b1712c28c0106", size = 1788959 }, - { url = "https://files.pythonhosted.org/packages/91/93/ad77782c5edfa17aafc070bef978fbfb8459b2f150595ffb01b559c136f9/aiohttp-3.11.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ee6a4cdcbf54b8083dc9723cdf5f41f722c00db40ccf9ec2616e27869151129", size = 1687463 }, - { url = "https://files.pythonhosted.org/packages/ba/48/db35bd21b7877efa0be5f28385d8978c55323c5ce7685712e53f3f6c0bd9/aiohttp-3.11.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c6095aaf852c34f42e1bd0cf0dc32d1e4b48a90bfb5054abdbb9d64b36acadcb", size = 1618374 }, - { url = "https://files.pythonhosted.org/packages/ba/77/30f87db55c79fd145ed5fd15b92f2e820ce81065d41ae437797aaa550e3b/aiohttp-3.11.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1cf03d27885f8c5ebf3993a220cc84fc66375e1e6e812731f51aab2b2748f4a6", size = 1637021 }, - { url = "https://files.pythonhosted.org/packages/af/76/10b188b78ee18d0595af156d6a238bc60f9d8571f0f546027eb7eaf65b25/aiohttp-3.11.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:1a17f6a230f81eb53282503823f59d61dff14fb2a93847bf0399dc8e87817307", size = 1650792 }, - { url = "https://files.pythonhosted.org/packages/fa/33/4411bbb8ad04c47d0f4c7bd53332aaf350e49469cf6b65b132d4becafe27/aiohttp-3.11.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:481f10a1a45c5f4c4a578bbd74cff22eb64460a6549819242a87a80788461fba", size = 1696248 }, - { url = "https://files.pythonhosted.org/packages/fe/2d/6135d0dc1851a33d3faa937b20fef81340bc95e8310536d4c7f1f8ecc026/aiohttp-3.11.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:db37248535d1ae40735d15bdf26ad43be19e3d93ab3f3dad8507eb0f85bb8124", size = 1729188 }, - { url = "https://files.pythonhosted.org/packages/f5/76/a57ceff577ae26fe9a6f31ac799bc638ecf26e4acdf04295290b9929b349/aiohttp-3.11.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9d18a8b44ec8502a7fde91446cd9c9b95ce7c49f1eacc1fb2358b8907d4369fd", size = 1690038 }, - { url = "https://files.pythonhosted.org/packages/4b/81/b20e09003b6989a7f23a721692137a6143420a151063c750ab2a04878e3c/aiohttp-3.11.7-cp312-cp312-win32.whl", hash = "sha256:3d1c9c15d3999107cbb9b2d76ca6172e6710a12fda22434ee8bd3f432b7b17e8", size = 409887 }, - { url = "https://files.pythonhosted.org/packages/b7/0b/607c98bff1d07bb21e0c39e7711108ef9ff4f2a361a3ec1ce8dce93623a5/aiohttp-3.11.7-cp312-cp312-win_amd64.whl", hash = "sha256:018f1b04883a12e77e7fc161934c0f298865d3a484aea536a6a2ca8d909f0ba0", size = 436462 }, - { url = "https://files.pythonhosted.org/packages/7a/53/8d77186c6a33bd087714df18274cdcf6e36fd69a9e841c85b7e81a20b18e/aiohttp-3.11.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:241a6ca732d2766836d62c58c49ca7a93d08251daef0c1e3c850df1d1ca0cbc4", size = 695811 }, - { url = "https://files.pythonhosted.org/packages/62/b6/4c3d107a5406aa6f99f618afea82783f54ce2d9644020f50b9c88f6e823d/aiohttp-3.11.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:aa3705a8d14de39898da0fbad920b2a37b7547c3afd2a18b9b81f0223b7d0f68", size = 458530 }, - { url = "https://files.pythonhosted.org/packages/d9/05/dbf0bd3966be8ebed3beb4007a2d1356d79af4fe7c93e54f984df6385193/aiohttp-3.11.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9acfc7f652b31853eed3b92095b0acf06fd5597eeea42e939bd23a17137679d5", size = 451371 }, - { url = "https://files.pythonhosted.org/packages/19/6a/2198580314617b6cf9c4b813b84df5832b5f8efedcb8a7e8b321a187233c/aiohttp-3.11.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcefcf2915a2dbdbce37e2fc1622129a1918abfe3d06721ce9f6cdac9b6d2eaa", size = 1662905 }, - { url = "https://files.pythonhosted.org/packages/2b/65/08696fd7503f6a6f9f782bd012bf47f36d4ed179a7d8c95dba4726d5cc67/aiohttp-3.11.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c1f6490dd1862af5aae6cfcf2a274bffa9a5b32a8f5acb519a7ecf5a99a88866", size = 1713794 }, - { url = "https://files.pythonhosted.org/packages/c8/a3/b9a72dce6f15e2efbc09fa67c1067c4f3a3bb05661c0ae7b40799cde02b7/aiohttp-3.11.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac5462582d6561c1c1708853a9faf612ff4e5ea5e679e99be36143d6eabd8e", size = 1770757 }, - { url = "https://files.pythonhosted.org/packages/78/7e/8fb371b5f8c4c1eaa0d0a50750c0dd68059f86794aeb36919644815486f5/aiohttp-3.11.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c1a6309005acc4b2bcc577ba3b9169fea52638709ffacbd071f3503264620da", size = 1673136 }, - { url = "https://files.pythonhosted.org/packages/2f/0f/09685d13d2c7634cb808868ea29c170d4dcde4215a4a90fb86491cd3ae25/aiohttp-3.11.7-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5b973cce96793725ef63eb449adfb74f99c043c718acb76e0d2a447ae369962", size = 1600370 }, - { url = "https://files.pythonhosted.org/packages/00/2e/18fd38b117f9b3a375166ccb70ed43cf7e3dfe2cc947139acc15feefc5a2/aiohttp-3.11.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ce91a24aac80de6be8512fb1c4838a9881aa713f44f4e91dd7bb3b34061b497d", size = 1613459 }, - { url = "https://files.pythonhosted.org/packages/2c/94/10a82abc680d753be33506be699aaa330152ecc4f316eaf081f996ee56c2/aiohttp-3.11.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:875f7100ce0e74af51d4139495eec4025affa1a605280f23990b6434b81df1bd", size = 1613924 }, - { url = "https://files.pythonhosted.org/packages/e9/58/897c0561f5c522dda6e173192f1e4f10144e1a7126096f17a3f12b7aa168/aiohttp-3.11.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c171fc35d3174bbf4787381716564042a4cbc008824d8195eede3d9b938e29a8", size = 1681164 }, - { url = "https://files.pythonhosted.org/packages/8b/8b/3a48b1cdafa612679d976274355f6a822de90b85d7dba55654ecfb01c979/aiohttp-3.11.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:ee9afa1b0d2293c46954f47f33e150798ad68b78925e3710044e0d67a9487791", size = 1712139 }, - { url = "https://files.pythonhosted.org/packages/aa/9d/70ab5b4dd7900db04af72840e033aee06e472b1343e372ea256ed675511c/aiohttp-3.11.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8360c7cc620abb320e1b8d603c39095101391a82b1d0be05fb2225471c9c5c52", size = 1667446 }, - { url = "https://files.pythonhosted.org/packages/cb/98/b5fbcc8f6056f0c56001c75227e6b7ca9ee4f2e5572feca82ff3d65d485d/aiohttp-3.11.7-cp313-cp313-win32.whl", hash = "sha256:7a9318da4b4ada9a67c1dd84d1c0834123081e746bee311a16bb449f363d965e", size = 408689 }, - { url = "https://files.pythonhosted.org/packages/ef/07/4d1504577fa6349dd2e3839e89fb56e5dee38d64efe3d4366e9fcfda0cdb/aiohttp-3.11.7-cp313-cp313-win_amd64.whl", hash = "sha256:fc6da202068e0a268e298d7cd09b6e9f3997736cd9b060e2750963754552a0a9", size = 434809 }, +sdist = { url = "https://files.pythonhosted.org/packages/94/c4/3b5a937b16f6c2a0ada842a9066aad0b7a5708427d4a202a07bf09c67cbb/aiohttp-3.11.10.tar.gz", hash = "sha256:b1fc6b45010a8d0ff9e88f9f2418c6fd408c99c211257334aff41597ebece42e", size = 7668832 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/47/f2/ba44492f257a296c4bb910bf47acf41672421fd455540911b3f13d10d6cd/aiohttp-3.11.10-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cbad88a61fa743c5d283ad501b01c153820734118b65aee2bd7dbb735475ce0d", size = 708322 }, + { url = "https://files.pythonhosted.org/packages/2b/c7/22b0ed548c8660e978e736671f166907fb272d0a4281b2b6833310bce529/aiohttp-3.11.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:80886dac673ceaef499de2f393fc80bb4481a129e6cb29e624a12e3296cc088f", size = 468211 }, + { url = "https://files.pythonhosted.org/packages/c9/0b/d326251888bb86ff7cb00b171e1cf3b0f0ed695622857f84a98bbc5f254b/aiohttp-3.11.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:61b9bae80ed1f338c42f57c16918853dc51775fb5cb61da70d590de14d8b5fb4", size = 455370 }, + { url = "https://files.pythonhosted.org/packages/4e/83/28feef5a0bda728adf76e0d076566c26c6da3d29f0ccd998d07c260cae9d/aiohttp-3.11.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9e2e576caec5c6a6b93f41626c9c02fc87cd91538b81a3670b2e04452a63def6", size = 1584399 }, + { url = "https://files.pythonhosted.org/packages/dc/97/6bdd39c4134ef243ffa9fd19a072ac9a0758d64b6d51eaaaaa34e67b8bcb/aiohttp-3.11.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02c13415b5732fb6ee7ff64583a5e6ed1c57aa68f17d2bda79c04888dfdc2769", size = 1632131 }, + { url = "https://files.pythonhosted.org/packages/1b/f1/8c3a1623b9d526986f03d8158c9c856e00531217998275cc6b4a14b2fb85/aiohttp-3.11.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4cfce37f31f20800a6a6620ce2cdd6737b82e42e06e6e9bd1b36f546feb3c44f", size = 1668081 }, + { url = "https://files.pythonhosted.org/packages/9c/3e/a2f4cee0dca934b1d2c4b6a7821040ce4452b9b2e4347c9be6cb10eaa835/aiohttp-3.11.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3bbbfff4c679c64e6e23cb213f57cc2c9165c9a65d63717108a644eb5a7398df", size = 1589313 }, + { url = "https://files.pythonhosted.org/packages/fd/9c/93e9a8f39c78f0c6d938721101e28c57597046f78057ffced8a3fd571839/aiohttp-3.11.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49c7dbbc1a559ae14fc48387a115b7d4bbc84b4a2c3b9299c31696953c2a5219", size = 1544349 }, + { url = "https://files.pythonhosted.org/packages/68/d2/2054efe02be87a1af92cfcaf6875d7b2c34906c3ee2b90ce82afbc8927a5/aiohttp-3.11.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:68386d78743e6570f054fe7949d6cb37ef2b672b4d3405ce91fafa996f7d9b4d", size = 1529018 }, + { url = "https://files.pythonhosted.org/packages/10/b0/a258bfd5ddd3d9c871a8d24e96531cb6e6f0cd98dc3028f0b98302454b23/aiohttp-3.11.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9ef405356ba989fb57f84cac66f7b0260772836191ccefbb987f414bcd2979d9", size = 1536357 }, + { url = "https://files.pythonhosted.org/packages/76/7f/8b60b93e7dc58d371813a9b8d451b7c9c9c4350f9c505edf6fae80e0812b/aiohttp-3.11.10-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:5d6958671b296febe7f5f859bea581a21c1d05430d1bbdcf2b393599b1cdce77", size = 1607214 }, + { url = "https://files.pythonhosted.org/packages/2a/10/97a11dba0f6d16878164b92ce75e2e0196a2fd25560cae8283388a24289b/aiohttp-3.11.10-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:99b7920e7165be5a9e9a3a7f1b680f06f68ff0d0328ff4079e5163990d046767", size = 1628573 }, + { url = "https://files.pythonhosted.org/packages/45/66/70419d6cb9495ddcebfa54d3db07e6a9716049ef341ded1edd8982f9b7f9/aiohttp-3.11.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0dc49f42422163efb7e6f1df2636fe3db72713f6cd94688e339dbe33fe06d61d", size = 1564058 }, + { url = "https://files.pythonhosted.org/packages/2d/d6/d94506afaea3aca15ab3f4732d666ad80acd5a035a7478aa6377c9816cf3/aiohttp-3.11.10-cp310-cp310-win32.whl", hash = "sha256:40d1c7a7f750b5648642586ba7206999650208dbe5afbcc5284bcec6579c9b91", size = 416360 }, + { url = "https://files.pythonhosted.org/packages/55/03/731d1116d09ea7a3c6be731ab0eb1faa37b844d3e54fed28e3a6785ba5ab/aiohttp-3.11.10-cp310-cp310-win_amd64.whl", hash = "sha256:68ff6f48b51bd78ea92b31079817aff539f6c8fc80b6b8d6ca347d7c02384e33", size = 441763 }, + { url = "https://files.pythonhosted.org/packages/db/7c/584d5ca19343c9462d054337828f72628e6dc204424f525df59ebfe75d1e/aiohttp-3.11.10-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:77c4aa15a89847b9891abf97f3d4048f3c2d667e00f8a623c89ad2dccee6771b", size = 708395 }, + { url = "https://files.pythonhosted.org/packages/cd/2d/61c33e01baeb23aebd07620ee4d780ff40f4c17c42289bf02a405f2ac312/aiohttp-3.11.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:909af95a72cedbefe5596f0bdf3055740f96c1a4baa0dd11fd74ca4de0b4e3f1", size = 468281 }, + { url = "https://files.pythonhosted.org/packages/ab/70/0ddb3a61b835068eb0badbe8016b4b65b966bad5f8af0f2d63998ff4cfa4/aiohttp-3.11.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:386fbe79863eb564e9f3615b959e28b222259da0c48fd1be5929ac838bc65683", size = 455345 }, + { url = "https://files.pythonhosted.org/packages/44/8c/4e14e9c1767d9a6ab1af1fbad9df9c77e050b39b6afe9e8343ec1ba96508/aiohttp-3.11.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3de34936eb1a647aa919655ff8d38b618e9f6b7f250cc19a57a4bf7fd2062b6d", size = 1685464 }, + { url = "https://files.pythonhosted.org/packages/ef/6e/1bab78ebb4f5a1c54f0fc10f8d52abc06816a9cb1db52b9c908e3d69f9a8/aiohttp-3.11.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0c9527819b29cd2b9f52033e7fb9ff08073df49b4799c89cb5754624ecd98299", size = 1743427 }, + { url = "https://files.pythonhosted.org/packages/5d/5e/c1b03bef621a8cc51ff551ef223c6ac606fabe0e35c950f56d01423ec2aa/aiohttp-3.11.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65a96e3e03300b41f261bbfd40dfdbf1c301e87eab7cd61c054b1f2e7c89b9e8", size = 1785188 }, + { url = "https://files.pythonhosted.org/packages/7c/b8/df6d76a149cbd969a58da478baec0be617287c496c842ddf21fe6bce07b3/aiohttp-3.11.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98f5635f7b74bcd4f6f72fcd85bea2154b323a9f05226a80bc7398d0c90763b0", size = 1674911 }, + { url = "https://files.pythonhosted.org/packages/ee/8e/e460e7bb820a08cec399971fc3176afc8090dc32fb941f386e0c68bc4ecc/aiohttp-3.11.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:03b6002e20938fc6ee0918c81d9e776bebccc84690e2b03ed132331cca065ee5", size = 1619570 }, + { url = "https://files.pythonhosted.org/packages/c2/ae/3b597e09eae4e75b77ee6c65443593d245bfa067ae6a5d895abaf27cce6c/aiohttp-3.11.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6362cc6c23c08d18ddbf0e8c4d5159b5df74fea1a5278ff4f2c79aed3f4e9f46", size = 1653772 }, + { url = "https://files.pythonhosted.org/packages/b8/d1/99852f2925992c4d7004e590344e5398eb163750de2a7c1fbe07f182d3c8/aiohttp-3.11.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:3691ed7726fef54e928fe26344d930c0c8575bc968c3e239c2e1a04bd8cf7838", size = 1649787 }, + { url = "https://files.pythonhosted.org/packages/39/c0/ea24627e08d722d5a6a00b3f6c9763fe3ad4650b8485f7a7a56ff932e3af/aiohttp-3.11.10-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:31d5093d3acd02b31c649d3a69bb072d539d4c7659b87caa4f6d2bcf57c2fa2b", size = 1732666 }, + { url = "https://files.pythonhosted.org/packages/f1/27/ab52dee4443ef8bdb26473b53c841caafd2bb637a8d85751694e089913bb/aiohttp-3.11.10-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:8b3cf2dc0f0690a33f2d2b2cb15db87a65f1c609f53c37e226f84edb08d10f52", size = 1754910 }, + { url = "https://files.pythonhosted.org/packages/cd/08/57c919d6b1f3b70bc14433c080a6152bf99454b636eb8a88552de8baaca9/aiohttp-3.11.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:fbbaea811a2bba171197b08eea288b9402faa2bab2ba0858eecdd0a4105753a3", size = 1692502 }, + { url = "https://files.pythonhosted.org/packages/ae/37/015006f669275735049e0549c37cb79c7a4a9350cbee070bbccb5a5b4b8a/aiohttp-3.11.10-cp311-cp311-win32.whl", hash = "sha256:4b2c7ac59c5698a7a8207ba72d9e9c15b0fc484a560be0788b31312c2c5504e4", size = 416178 }, + { url = "https://files.pythonhosted.org/packages/cf/8d/7bb48ae503989b15114baf9f9b19398c86ae93d30959065bc061b31331ee/aiohttp-3.11.10-cp311-cp311-win_amd64.whl", hash = "sha256:974d3a2cce5fcfa32f06b13ccc8f20c6ad9c51802bb7f829eae8a1845c4019ec", size = 442269 }, + { url = "https://files.pythonhosted.org/packages/25/17/1dbe2f619f77795409c1a13ab395b98ed1b215d3e938cacde9b8ffdac53d/aiohttp-3.11.10-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:b78f053a7ecfc35f0451d961dacdc671f4bcbc2f58241a7c820e9d82559844cf", size = 704448 }, + { url = "https://files.pythonhosted.org/packages/e3/9b/112247ad47e9d7f6640889c6e42cc0ded8c8345dd0033c66bcede799b051/aiohttp-3.11.10-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ab7485222db0959a87fbe8125e233b5a6f01f4400785b36e8a7878170d8c3138", size = 463829 }, + { url = "https://files.pythonhosted.org/packages/8a/36/a64b583771fc673062a7a1374728a6241d49e2eda5a9041fbf248e18c804/aiohttp-3.11.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cf14627232dfa8730453752e9cdc210966490992234d77ff90bc8dc0dce361d5", size = 455774 }, + { url = "https://files.pythonhosted.org/packages/e5/75/ee1b8f510978b3de5f185c62535b135e4fc3f5a247ca0c2245137a02d800/aiohttp-3.11.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:076bc454a7e6fd646bc82ea7f98296be0b1219b5e3ef8a488afbdd8e81fbac50", size = 1682134 }, + { url = "https://files.pythonhosted.org/packages/87/46/65e8259432d5f73ca9ebf5edb645ef90e5303724e4e52477516cb4042240/aiohttp-3.11.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:482cafb7dc886bebeb6c9ba7925e03591a62ab34298ee70d3dd47ba966370d2c", size = 1736757 }, + { url = "https://files.pythonhosted.org/packages/03/f6/a6d1e791b7153fb2d101278f7146c0771b0e1569c547f8a8bc3035651984/aiohttp-3.11.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf3d1a519a324af764a46da4115bdbd566b3c73fb793ffb97f9111dbc684fc4d", size = 1793033 }, + { url = "https://files.pythonhosted.org/packages/a8/e9/1ac90733e36e7848693aece522936a13bf17eeb617da662f94adfafc1c25/aiohttp-3.11.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24213ba85a419103e641e55c27dc7ff03536c4873470c2478cce3311ba1eee7b", size = 1691609 }, + { url = "https://files.pythonhosted.org/packages/6d/a6/77b33da5a0bc04566c7ddcca94500f2c2a2334eecab4885387fffd1fc600/aiohttp-3.11.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b99acd4730ad1b196bfb03ee0803e4adac371ae8efa7e1cbc820200fc5ded109", size = 1619082 }, + { url = "https://files.pythonhosted.org/packages/48/94/5bf5f927d9a2fedd2c978adfb70a3680e16f46d178361685b56244eb52ed/aiohttp-3.11.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:14cdb5a9570be5a04eec2ace174a48ae85833c2aadc86de68f55541f66ce42ab", size = 1641186 }, + { url = "https://files.pythonhosted.org/packages/99/2d/e85103aa01d1064e51bc50cb51e7b40150a8ff5d34e5a3173a46b241860b/aiohttp-3.11.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:7e97d622cb083e86f18317282084bc9fbf261801b0192c34fe4b1febd9f7ae69", size = 1646280 }, + { url = "https://files.pythonhosted.org/packages/7b/e0/44651fda8c1d865a51b3a81f1956ea55ce16fc568fe7a3e05db7fc22f139/aiohttp-3.11.10-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:012f176945af138abc10c4a48743327a92b4ca9adc7a0e078077cdb5dbab7be0", size = 1701862 }, + { url = "https://files.pythonhosted.org/packages/4e/1e/0804459ae325a5b95f6f349778fb465f29d2b863e522b6a349db0aaad54c/aiohttp-3.11.10-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44224d815853962f48fe124748227773acd9686eba6dc102578defd6fc99e8d9", size = 1734373 }, + { url = "https://files.pythonhosted.org/packages/07/87/b8f6721668cad74bcc9c7cfe6d0230b304d1250196b221e54294a0d78dbe/aiohttp-3.11.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c87bf31b7fdab94ae3adbe4a48e711bfc5f89d21cf4c197e75561def39e223bc", size = 1694343 }, + { url = "https://files.pythonhosted.org/packages/4b/20/42813fc60d9178ba9b1b86c58a5441ddb6cf8ffdfe66387345bff173bcff/aiohttp-3.11.10-cp312-cp312-win32.whl", hash = "sha256:06a8e2ee1cbac16fe61e51e0b0c269400e781b13bcfc33f5425912391a542985", size = 411118 }, + { url = "https://files.pythonhosted.org/packages/3a/51/df9c263c861ce93998b5ad2ba3212caab2112d5b66dbe91ddbe90c41ded4/aiohttp-3.11.10-cp312-cp312-win_amd64.whl", hash = "sha256:be2b516f56ea883a3e14dda17059716593526e10fb6303189aaf5503937db408", size = 437424 }, + { url = "https://files.pythonhosted.org/packages/8c/1d/88bfdbe28a3d1ba5b94a235f188f27726caf8ade9a0e13574848f44fe0fe/aiohttp-3.11.10-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8cc5203b817b748adccb07f36390feb730b1bc5f56683445bfe924fc270b8816", size = 697755 }, + { url = "https://files.pythonhosted.org/packages/86/00/4c4619d6fe5c5be32f74d1422fc719b3e6cd7097af0c9e03877ca9bd4ebc/aiohttp-3.11.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5ef359ebc6949e3a34c65ce20230fae70920714367c63afd80ea0c2702902ccf", size = 460440 }, + { url = "https://files.pythonhosted.org/packages/aa/1c/2f927408f50593a29465d198ec3c57c835c8602330233163e8d89c1093db/aiohttp-3.11.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9bca390cb247dbfaec3c664326e034ef23882c3f3bfa5fbf0b56cad0320aaca5", size = 452726 }, + { url = "https://files.pythonhosted.org/packages/06/6a/ff00ed0a2ba45c34b3c366aa5b0004b1a4adcec5a9b5f67dd0648ee1c88a/aiohttp-3.11.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:811f23b3351ca532af598405db1093f018edf81368e689d1b508c57dcc6b6a32", size = 1664944 }, + { url = "https://files.pythonhosted.org/packages/02/c2/61923f2a7c2e14d7424b3a526e054f0358f57ccdf5573d4d3d033b01921a/aiohttp-3.11.10-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ddf5f7d877615f6a1e75971bfa5ac88609af3b74796ff3e06879e8422729fd01", size = 1717707 }, + { url = "https://files.pythonhosted.org/packages/8a/08/0d3d074b24d377569ec89d476a95ca918443099c0401bb31b331104e35d1/aiohttp-3.11.10-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6ab29b8a0beb6f8eaf1e5049252cfe74adbaafd39ba91e10f18caeb0e99ffb34", size = 1774890 }, + { url = "https://files.pythonhosted.org/packages/e8/49/052ada2b6e90ed65f0e6a7e548614621b5f8dcd193cb9415d2e6bcecc94a/aiohttp-3.11.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c49a76c1038c2dd116fa443eba26bbb8e6c37e924e2513574856de3b6516be99", size = 1676945 }, + { url = "https://files.pythonhosted.org/packages/7c/9e/0c48e1a48e072a869b8b5e3920c9f6a8092861524a4a6f159cd7e6fda939/aiohttp-3.11.10-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f3dc0e330575f5b134918976a645e79adf333c0a1439dcf6899a80776c9ab39", size = 1602959 }, + { url = "https://files.pythonhosted.org/packages/ab/98/791f979093ff7f67f80344c182cb0ca4c2c60daed397ecaf454cc8d7a5cd/aiohttp-3.11.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:efb15a17a12497685304b2d976cb4939e55137df7b09fa53f1b6a023f01fcb4e", size = 1618058 }, + { url = "https://files.pythonhosted.org/packages/7b/5d/2d4b05feb3fd68eb7c8335f73c81079b56e582633b91002da695ccb439ef/aiohttp-3.11.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:db1d0b28fcb7f1d35600150c3e4b490775251dea70f894bf15c678fdd84eda6a", size = 1616289 }, + { url = "https://files.pythonhosted.org/packages/50/83/68cc28c00fe681dce6150614f105efe98282da19252cd6e32dfa893bb328/aiohttp-3.11.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:15fccaf62a4889527539ecb86834084ecf6e9ea70588efde86e8bc775e0e7542", size = 1685239 }, + { url = "https://files.pythonhosted.org/packages/16/f9/68fc5c8928f63238ce9314f04f3f59d9190a4db924998bb9be99c7aacce8/aiohttp-3.11.10-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:593c114a2221444f30749cc5e5f4012488f56bd14de2af44fe23e1e9894a9c60", size = 1715078 }, + { url = "https://files.pythonhosted.org/packages/3f/e0/3dd3f0451c532c77e35780bafb2b6469a046bc15a6ec2e039475a1d2f161/aiohttp-3.11.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7852bbcb4d0d2f0c4d583f40c3bc750ee033265d80598d0f9cb6f372baa6b836", size = 1672544 }, + { url = "https://files.pythonhosted.org/packages/a5/b1/3530ab040dd5d7fb016b47115016f9b3a07ea29593b0e07e53dbe06a380c/aiohttp-3.11.10-cp313-cp313-win32.whl", hash = "sha256:65e55ca7debae8faaffee0ebb4b47a51b4075f01e9b641c31e554fd376595c6c", size = 409984 }, + { url = "https://files.pythonhosted.org/packages/49/1f/deed34e9fca639a7f873d01150d46925d3e1312051eaa591c1aa1f2e6ddc/aiohttp-3.11.10-cp313-cp313-win_amd64.whl", hash = "sha256:beb39a6d60a709ae3fb3516a1581777e7e8b76933bb88c8f4420d875bb0267c6", size = 435837 }, ] [[package]] @@ -117,17 +117,17 @@ wheels = [ [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.7.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, { name = "idna" }, { name = "sniffio" }, - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9f/09/45b9b7a6d4e45c6bcb5bf61d19e3ab87df68e0601fa8c5293de3542546cc/anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c", size = 173422 } +sdist = { url = "https://files.pythonhosted.org/packages/f6/40/318e58f669b1a9e00f5c4453910682e2d9dd594334539c7b7817dabb765f/anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48", size = 177076 } wheels = [ - { url = "https://files.pythonhosted.org/packages/e4/f5/f2b75d2fc6f1a260f340f0e7c6a060f4dd2961cc16884ed851b0d18da06a/anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d", size = 90377 }, + { url = "https://files.pythonhosted.org/packages/a0/7a/4daaf3b6c08ad7ceffea4634ec206faeff697526421c20f07628c7372156/anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352", size = 93052 }, ] [[package]] @@ -508,18 +508,17 @@ wheels = [ [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, { name = "certifi" }, { name = "httpcore" }, { name = "idna" }, - { name = "sniffio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/78/82/08f8c936781f67d9e6b9eeb8a0c8b4e406136ea4c3d1f89a5db71d42e0e6/httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2", size = 144189 } +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406 } wheels = [ - { url = "https://files.pythonhosted.org/packages/56/95/9377bcb415797e44274b51d46e3249eba641711cf3348050f76ee7b15ffc/httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0", size = 76395 }, + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517 }, ] [[package]] @@ -878,89 +877,89 @@ wheels = [ [[package]] name = "propcache" -version = "0.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a9/4d/5e5a60b78dbc1d464f8a7bbaeb30957257afdc8512cbb9dfd5659304f5cd/propcache-0.2.0.tar.gz", hash = "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70", size = 40951 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3a/08/1963dfb932b8d74d5b09098507b37e9b96c835ba89ab8aad35aa330f4ff3/propcache-0.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c5869b8fd70b81835a6f187c5fdbe67917a04d7e52b6e7cc4e5fe39d55c39d58", size = 80712 }, - { url = "https://files.pythonhosted.org/packages/e6/59/49072aba9bf8a8ed958e576182d46f038e595b17ff7408bc7e8807e721e1/propcache-0.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:952e0d9d07609d9c5be361f33b0d6d650cd2bae393aabb11d9b719364521984b", size = 46301 }, - { url = "https://files.pythonhosted.org/packages/33/a2/6b1978c2e0d80a678e2c483f45e5443c15fe5d32c483902e92a073314ef1/propcache-0.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:33ac8f098df0585c0b53009f039dfd913b38c1d2edafed0cedcc0c32a05aa110", size = 45581 }, - { url = "https://files.pythonhosted.org/packages/43/95/55acc9adff8f997c7572f23d41993042290dfb29e404cdadb07039a4386f/propcache-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97e48e8875e6c13909c800fa344cd54cc4b2b0db1d5f911f840458a500fde2c2", size = 208659 }, - { url = "https://files.pythonhosted.org/packages/bd/2c/ef7371ff715e6cd19ea03fdd5637ecefbaa0752fee5b0f2fe8ea8407ee01/propcache-0.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:388f3217649d6d59292b722d940d4d2e1e6a7003259eb835724092a1cca0203a", size = 222613 }, - { url = "https://files.pythonhosted.org/packages/5e/1c/fef251f79fd4971a413fa4b1ae369ee07727b4cc2c71e2d90dfcde664fbb/propcache-0.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f571aea50ba5623c308aa146eb650eebf7dbe0fd8c5d946e28343cb3b5aad577", size = 221067 }, - { url = "https://files.pythonhosted.org/packages/8d/e7/22e76ae6fc5a1708bdce92bdb49de5ebe89a173db87e4ef597d6bbe9145a/propcache-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3dfafb44f7bb35c0c06eda6b2ab4bfd58f02729e7c4045e179f9a861b07c9850", size = 208920 }, - { url = "https://files.pythonhosted.org/packages/04/3e/f10aa562781bcd8a1e0b37683a23bef32bdbe501d9cc7e76969becaac30d/propcache-0.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3ebe9a75be7ab0b7da2464a77bb27febcb4fab46a34f9288f39d74833db7f61", size = 200050 }, - { url = "https://files.pythonhosted.org/packages/d0/98/8ac69f638358c5f2a0043809c917802f96f86026e86726b65006830f3dc6/propcache-0.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d2f0d0f976985f85dfb5f3d685697ef769faa6b71993b46b295cdbbd6be8cc37", size = 202346 }, - { url = "https://files.pythonhosted.org/packages/ee/78/4acfc5544a5075d8e660af4d4e468d60c418bba93203d1363848444511ad/propcache-0.2.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a3dc1a4b165283bd865e8f8cb5f0c64c05001e0718ed06250d8cac9bec115b48", size = 199750 }, - { url = "https://files.pythonhosted.org/packages/a2/8f/90ada38448ca2e9cf25adc2fe05d08358bda1b9446f54a606ea38f41798b/propcache-0.2.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9e0f07b42d2a50c7dd2d8675d50f7343d998c64008f1da5fef888396b7f84630", size = 201279 }, - { url = "https://files.pythonhosted.org/packages/08/31/0e299f650f73903da851f50f576ef09bfffc8e1519e6a2f1e5ed2d19c591/propcache-0.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e63e3e1e0271f374ed489ff5ee73d4b6e7c60710e1f76af5f0e1a6117cd26394", size = 211035 }, - { url = "https://files.pythonhosted.org/packages/85/3e/e356cc6b09064bff1c06d0b2413593e7c925726f0139bc7acef8a21e87a8/propcache-0.2.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:56bb5c98f058a41bb58eead194b4db8c05b088c93d94d5161728515bd52b052b", size = 215565 }, - { url = "https://files.pythonhosted.org/packages/8b/54/4ef7236cd657e53098bd05aa59cbc3cbf7018fba37b40eaed112c3921e51/propcache-0.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7665f04d0c7f26ff8bb534e1c65068409bf4687aa2534faf7104d7182debb336", size = 207604 }, - { url = "https://files.pythonhosted.org/packages/1f/27/d01d7799c068443ee64002f0655d82fb067496897bf74b632e28ee6a32cf/propcache-0.2.0-cp310-cp310-win32.whl", hash = "sha256:7cf18abf9764746b9c8704774d8b06714bcb0a63641518a3a89c7f85cc02c2ad", size = 40526 }, - { url = "https://files.pythonhosted.org/packages/bb/44/6c2add5eeafb7f31ff0d25fbc005d930bea040a1364cf0f5768750ddf4d1/propcache-0.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:cfac69017ef97db2438efb854edf24f5a29fd09a536ff3a992b75990720cdc99", size = 44958 }, - { url = "https://files.pythonhosted.org/packages/e0/1c/71eec730e12aec6511e702ad0cd73c2872eccb7cad39de8ba3ba9de693ef/propcache-0.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:63f13bf09cc3336eb04a837490b8f332e0db41da66995c9fd1ba04552e516354", size = 80811 }, - { url = "https://files.pythonhosted.org/packages/89/c3/7e94009f9a4934c48a371632197406a8860b9f08e3f7f7d922ab69e57a41/propcache-0.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608cce1da6f2672a56b24a015b42db4ac612ee709f3d29f27a00c943d9e851de", size = 46365 }, - { url = "https://files.pythonhosted.org/packages/c0/1d/c700d16d1d6903aeab28372fe9999762f074b80b96a0ccc953175b858743/propcache-0.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:466c219deee4536fbc83c08d09115249db301550625c7fef1c5563a584c9bc87", size = 45602 }, - { url = "https://files.pythonhosted.org/packages/2e/5e/4a3e96380805bf742712e39a4534689f4cddf5fa2d3a93f22e9fd8001b23/propcache-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc2db02409338bf36590aa985a461b2c96fce91f8e7e0f14c50c5fcc4f229016", size = 236161 }, - { url = "https://files.pythonhosted.org/packages/a5/85/90132481183d1436dff6e29f4fa81b891afb6cb89a7306f32ac500a25932/propcache-0.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6ed8db0a556343d566a5c124ee483ae113acc9a557a807d439bcecc44e7dfbb", size = 244938 }, - { url = "https://files.pythonhosted.org/packages/4a/89/c893533cb45c79c970834274e2d0f6d64383ec740be631b6a0a1d2b4ddc0/propcache-0.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91997d9cb4a325b60d4e3f20967f8eb08dfcb32b22554d5ef78e6fd1dda743a2", size = 243576 }, - { url = "https://files.pythonhosted.org/packages/8c/56/98c2054c8526331a05f205bf45cbb2cda4e58e56df70e76d6a509e5d6ec6/propcache-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c7dde9e533c0a49d802b4f3f218fa9ad0a1ce21f2c2eb80d5216565202acab4", size = 236011 }, - { url = "https://files.pythonhosted.org/packages/2d/0c/8b8b9f8a6e1abd869c0fa79b907228e7abb966919047d294ef5df0d136cf/propcache-0.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffcad6c564fe6b9b8916c1aefbb37a362deebf9394bd2974e9d84232e3e08504", size = 224834 }, - { url = "https://files.pythonhosted.org/packages/18/bb/397d05a7298b7711b90e13108db697732325cafdcd8484c894885c1bf109/propcache-0.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:97a58a28bcf63284e8b4d7b460cbee1edaab24634e82059c7b8c09e65284f178", size = 224946 }, - { url = "https://files.pythonhosted.org/packages/25/19/4fc08dac19297ac58135c03770b42377be211622fd0147f015f78d47cd31/propcache-0.2.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:945db8ee295d3af9dbdbb698cce9bbc5c59b5c3fe328bbc4387f59a8a35f998d", size = 217280 }, - { url = "https://files.pythonhosted.org/packages/7e/76/c79276a43df2096ce2aba07ce47576832b1174c0c480fe6b04bd70120e59/propcache-0.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:39e104da444a34830751715f45ef9fc537475ba21b7f1f5b0f4d71a3b60d7fe2", size = 220088 }, - { url = "https://files.pythonhosted.org/packages/c3/9a/8a8cf428a91b1336b883f09c8b884e1734c87f724d74b917129a24fe2093/propcache-0.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c5ecca8f9bab618340c8e848d340baf68bcd8ad90a8ecd7a4524a81c1764b3db", size = 233008 }, - { url = "https://files.pythonhosted.org/packages/25/7b/768a8969abd447d5f0f3333df85c6a5d94982a1bc9a89c53c154bf7a8b11/propcache-0.2.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c436130cc779806bdf5d5fae0d848713105472b8566b75ff70048c47d3961c5b", size = 237719 }, - { url = "https://files.pythonhosted.org/packages/ed/0d/e5d68ccc7976ef8b57d80613ac07bbaf0614d43f4750cf953f0168ef114f/propcache-0.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:191db28dc6dcd29d1a3e063c3be0b40688ed76434622c53a284e5427565bbd9b", size = 227729 }, - { url = "https://files.pythonhosted.org/packages/05/64/17eb2796e2d1c3d0c431dc5f40078d7282f4645af0bb4da9097fbb628c6c/propcache-0.2.0-cp311-cp311-win32.whl", hash = "sha256:5f2564ec89058ee7c7989a7b719115bdfe2a2fb8e7a4543b8d1c0cc4cf6478c1", size = 40473 }, - { url = "https://files.pythonhosted.org/packages/83/c5/e89fc428ccdc897ade08cd7605f174c69390147526627a7650fb883e0cd0/propcache-0.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6e2e54267980349b723cff366d1e29b138b9a60fa376664a157a342689553f71", size = 44921 }, - { url = "https://files.pythonhosted.org/packages/7c/46/a41ca1097769fc548fc9216ec4c1471b772cc39720eb47ed7e38ef0006a9/propcache-0.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:2ee7606193fb267be4b2e3b32714f2d58cad27217638db98a60f9efb5efeccc2", size = 80800 }, - { url = "https://files.pythonhosted.org/packages/75/4f/93df46aab9cc473498ff56be39b5f6ee1e33529223d7a4d8c0a6101a9ba2/propcache-0.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:91ee8fc02ca52e24bcb77b234f22afc03288e1dafbb1f88fe24db308910c4ac7", size = 46443 }, - { url = "https://files.pythonhosted.org/packages/0b/17/308acc6aee65d0f9a8375e36c4807ac6605d1f38074b1581bd4042b9fb37/propcache-0.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e900bad2a8456d00a113cad8c13343f3b1f327534e3589acc2219729237a2e8", size = 45676 }, - { url = "https://files.pythonhosted.org/packages/65/44/626599d2854d6c1d4530b9a05e7ff2ee22b790358334b475ed7c89f7d625/propcache-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f52a68c21363c45297aca15561812d542f8fc683c85201df0bebe209e349f793", size = 246191 }, - { url = "https://files.pythonhosted.org/packages/f2/df/5d996d7cb18df076debae7d76ac3da085c0575a9f2be6b1f707fe227b54c/propcache-0.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e41d67757ff4fbc8ef2af99b338bfb955010444b92929e9e55a6d4dcc3c4f09", size = 251791 }, - { url = "https://files.pythonhosted.org/packages/2e/6d/9f91e5dde8b1f662f6dd4dff36098ed22a1ef4e08e1316f05f4758f1576c/propcache-0.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a64e32f8bd94c105cc27f42d3b658902b5bcc947ece3c8fe7bc1b05982f60e89", size = 253434 }, - { url = "https://files.pythonhosted.org/packages/3c/e9/1b54b7e26f50b3e0497cd13d3483d781d284452c2c50dd2a615a92a087a3/propcache-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55346705687dbd7ef0d77883ab4f6fabc48232f587925bdaf95219bae072491e", size = 248150 }, - { url = "https://files.pythonhosted.org/packages/a7/ef/a35bf191c8038fe3ce9a414b907371c81d102384eda5dbafe6f4dce0cf9b/propcache-0.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00181262b17e517df2cd85656fcd6b4e70946fe62cd625b9d74ac9977b64d8d9", size = 233568 }, - { url = "https://files.pythonhosted.org/packages/97/d9/d00bb9277a9165a5e6d60f2142cd1a38a750045c9c12e47ae087f686d781/propcache-0.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6994984550eaf25dd7fc7bd1b700ff45c894149341725bb4edc67f0ffa94efa4", size = 229874 }, - { url = "https://files.pythonhosted.org/packages/8e/78/c123cf22469bdc4b18efb78893e69c70a8b16de88e6160b69ca6bdd88b5d/propcache-0.2.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:56295eb1e5f3aecd516d91b00cfd8bf3a13991de5a479df9e27dd569ea23959c", size = 225857 }, - { url = "https://files.pythonhosted.org/packages/31/1b/fd6b2f1f36d028820d35475be78859d8c89c8f091ad30e377ac49fd66359/propcache-0.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:439e76255daa0f8151d3cb325f6dd4a3e93043e6403e6491813bcaaaa8733887", size = 227604 }, - { url = "https://files.pythonhosted.org/packages/99/36/b07be976edf77a07233ba712e53262937625af02154353171716894a86a6/propcache-0.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f6475a1b2ecb310c98c28d271a30df74f9dd436ee46d09236a6b750a7599ce57", size = 238430 }, - { url = "https://files.pythonhosted.org/packages/0d/64/5822f496c9010e3966e934a011ac08cac8734561842bc7c1f65586e0683c/propcache-0.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3444cdba6628accf384e349014084b1cacd866fbb88433cd9d279d90a54e0b23", size = 244814 }, - { url = "https://files.pythonhosted.org/packages/fd/bd/8657918a35d50b18a9e4d78a5df7b6c82a637a311ab20851eef4326305c1/propcache-0.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4a9d9b4d0a9b38d1c391bb4ad24aa65f306c6f01b512e10a8a34a2dc5675d348", size = 235922 }, - { url = "https://files.pythonhosted.org/packages/a8/6f/ec0095e1647b4727db945213a9f395b1103c442ef65e54c62e92a72a3f75/propcache-0.2.0-cp312-cp312-win32.whl", hash = "sha256:69d3a98eebae99a420d4b28756c8ce6ea5a29291baf2dc9ff9414b42676f61d5", size = 40177 }, - { url = "https://files.pythonhosted.org/packages/20/a2/bd0896fdc4f4c1db46d9bc361c8c79a9bf08ccc08ba054a98e38e7ba1557/propcache-0.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ad9c9b99b05f163109466638bd30ada1722abb01bbb85c739c50b6dc11f92dc3", size = 44446 }, - { url = "https://files.pythonhosted.org/packages/a8/a7/5f37b69197d4f558bfef5b4bceaff7c43cc9b51adf5bd75e9081d7ea80e4/propcache-0.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ecddc221a077a8132cf7c747d5352a15ed763b674c0448d811f408bf803d9ad7", size = 78120 }, - { url = "https://files.pythonhosted.org/packages/c8/cd/48ab2b30a6b353ecb95a244915f85756d74f815862eb2ecc7a518d565b48/propcache-0.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0e53cb83fdd61cbd67202735e6a6687a7b491c8742dfc39c9e01e80354956763", size = 45127 }, - { url = "https://files.pythonhosted.org/packages/a5/ba/0a1ef94a3412aab057bd996ed5f0ac7458be5bf469e85c70fa9ceb43290b/propcache-0.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92fe151145a990c22cbccf9ae15cae8ae9eddabfc949a219c9f667877e40853d", size = 44419 }, - { url = "https://files.pythonhosted.org/packages/b4/6c/ca70bee4f22fa99eacd04f4d2f1699be9d13538ccf22b3169a61c60a27fa/propcache-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6a21ef516d36909931a2967621eecb256018aeb11fc48656e3257e73e2e247a", size = 229611 }, - { url = "https://files.pythonhosted.org/packages/19/70/47b872a263e8511ca33718d96a10c17d3c853aefadeb86dc26e8421184b9/propcache-0.2.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f88a4095e913f98988f5b338c1d4d5d07dbb0b6bad19892fd447484e483ba6b", size = 234005 }, - { url = "https://files.pythonhosted.org/packages/4f/be/3b0ab8c84a22e4a3224719099c1229ddfdd8a6a1558cf75cb55ee1e35c25/propcache-0.2.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a5b3bb545ead161be780ee85a2b54fdf7092815995661947812dde94a40f6fb", size = 237270 }, - { url = "https://files.pythonhosted.org/packages/04/d8/f071bb000d4b8f851d312c3c75701e586b3f643fe14a2e3409b1b9ab3936/propcache-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67aeb72e0f482709991aa91345a831d0b707d16b0257e8ef88a2ad246a7280bf", size = 231877 }, - { url = "https://files.pythonhosted.org/packages/93/e7/57a035a1359e542bbb0a7df95aad6b9871ebee6dce2840cb157a415bd1f3/propcache-0.2.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c997f8c44ec9b9b0bcbf2d422cc00a1d9b9c681f56efa6ca149a941e5560da2", size = 217848 }, - { url = "https://files.pythonhosted.org/packages/f0/93/d1dea40f112ec183398fb6c42fde340edd7bab202411c4aa1a8289f461b6/propcache-0.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2a66df3d4992bc1d725b9aa803e8c5a66c010c65c741ad901e260ece77f58d2f", size = 216987 }, - { url = "https://files.pythonhosted.org/packages/62/4c/877340871251145d3522c2b5d25c16a1690ad655fbab7bb9ece6b117e39f/propcache-0.2.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3ebbcf2a07621f29638799828b8d8668c421bfb94c6cb04269130d8de4fb7136", size = 212451 }, - { url = "https://files.pythonhosted.org/packages/7c/bb/a91b72efeeb42906ef58ccf0cdb87947b54d7475fee3c93425d732f16a61/propcache-0.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1235c01ddaa80da8235741e80815ce381c5267f96cc49b1477fdcf8c047ef325", size = 212879 }, - { url = "https://files.pythonhosted.org/packages/9b/7f/ee7fea8faac57b3ec5d91ff47470c6c5d40d7f15d0b1fccac806348fa59e/propcache-0.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3947483a381259c06921612550867b37d22e1df6d6d7e8361264b6d037595f44", size = 222288 }, - { url = "https://files.pythonhosted.org/packages/ff/d7/acd67901c43d2e6b20a7a973d9d5fd543c6e277af29b1eb0e1f7bd7ca7d2/propcache-0.2.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d5bed7f9805cc29c780f3aee05de3262ee7ce1f47083cfe9f77471e9d6777e83", size = 228257 }, - { url = "https://files.pythonhosted.org/packages/8d/6f/6272ecc7a8daad1d0754cfc6c8846076a8cb13f810005c79b15ce0ef0cf2/propcache-0.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e4a91d44379f45f5e540971d41e4626dacd7f01004826a18cb048e7da7e96544", size = 221075 }, - { url = "https://files.pythonhosted.org/packages/7c/bd/c7a6a719a6b3dd8b3aeadb3675b5783983529e4a3185946aa444d3e078f6/propcache-0.2.0-cp313-cp313-win32.whl", hash = "sha256:f902804113e032e2cdf8c71015651c97af6418363bea8d78dc0911d56c335032", size = 39654 }, - { url = "https://files.pythonhosted.org/packages/88/e7/0eef39eff84fa3e001b44de0bd41c7c0e3432e7648ffd3d64955910f002d/propcache-0.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:8f188cfcc64fb1266f4684206c9de0e80f54622c3f22a910cbd200478aeae61e", size = 43705 }, - { url = "https://files.pythonhosted.org/packages/3d/b6/e6d98278f2d49b22b4d033c9f792eda783b9ab2094b041f013fc69bcde87/propcache-0.2.0-py3-none-any.whl", hash = "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036", size = 11603 }, +version = "0.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/20/c8/2a13f78d82211490855b2fb303b6721348d0787fdd9a12ac46d99d3acde1/propcache-0.2.1.tar.gz", hash = "sha256:3f77ce728b19cb537714499928fe800c3dda29e8d9428778fc7c186da4c09a64", size = 41735 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/a5/0ea64c9426959ef145a938e38c832fc551843481d356713ececa9a8a64e8/propcache-0.2.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6b3f39a85d671436ee3d12c017f8fdea38509e4f25b28eb25877293c98c243f6", size = 79296 }, + { url = "https://files.pythonhosted.org/packages/76/5a/916db1aba735f55e5eca4733eea4d1973845cf77dfe67c2381a2ca3ce52d/propcache-0.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d51fbe4285d5db5d92a929e3e21536ea3dd43732c5b177c7ef03f918dff9f2", size = 45622 }, + { url = "https://files.pythonhosted.org/packages/2d/62/685d3cf268b8401ec12b250b925b21d152b9d193b7bffa5fdc4815c392c2/propcache-0.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6445804cf4ec763dc70de65a3b0d9954e868609e83850a47ca4f0cb64bd79fea", size = 45133 }, + { url = "https://files.pythonhosted.org/packages/4d/3d/31c9c29ee7192defc05aa4d01624fd85a41cf98e5922aaed206017329944/propcache-0.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9479aa06a793c5aeba49ce5c5692ffb51fcd9a7016e017d555d5e2b0045d212", size = 204809 }, + { url = "https://files.pythonhosted.org/packages/10/a1/e4050776f4797fc86140ac9a480d5dc069fbfa9d499fe5c5d2fa1ae71f07/propcache-0.2.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9631c5e8b5b3a0fda99cb0d29c18133bca1e18aea9effe55adb3da1adef80d3", size = 219109 }, + { url = "https://files.pythonhosted.org/packages/c9/c0/e7ae0df76343d5e107d81e59acc085cea5fd36a48aa53ef09add7503e888/propcache-0.2.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3156628250f46a0895f1f36e1d4fbe062a1af8718ec3ebeb746f1d23f0c5dc4d", size = 217368 }, + { url = "https://files.pythonhosted.org/packages/fc/e1/e0a2ed6394b5772508868a977d3238f4afb2eebaf9976f0b44a8d347ad63/propcache-0.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b6fb63ae352e13748289f04f37868099e69dba4c2b3e271c46061e82c745634", size = 205124 }, + { url = "https://files.pythonhosted.org/packages/50/c1/e388c232d15ca10f233c778bbdc1034ba53ede14c207a72008de45b2db2e/propcache-0.2.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:887d9b0a65404929641a9fabb6452b07fe4572b269d901d622d8a34a4e9043b2", size = 195463 }, + { url = "https://files.pythonhosted.org/packages/0a/fd/71b349b9def426cc73813dbd0f33e266de77305e337c8c12bfb0a2a82bfb/propcache-0.2.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a96dc1fa45bd8c407a0af03b2d5218392729e1822b0c32e62c5bf7eeb5fb3958", size = 198358 }, + { url = "https://files.pythonhosted.org/packages/02/f2/d7c497cd148ebfc5b0ae32808e6c1af5922215fe38c7a06e4e722fe937c8/propcache-0.2.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a7e65eb5c003a303b94aa2c3852ef130230ec79e349632d030e9571b87c4698c", size = 195560 }, + { url = "https://files.pythonhosted.org/packages/bb/57/f37041bbe5e0dfed80a3f6be2612a3a75b9cfe2652abf2c99bef3455bbad/propcache-0.2.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:999779addc413181912e984b942fbcc951be1f5b3663cd80b2687758f434c583", size = 196895 }, + { url = "https://files.pythonhosted.org/packages/83/36/ae3cc3e4f310bff2f064e3d2ed5558935cc7778d6f827dce74dcfa125304/propcache-0.2.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:19a0f89a7bb9d8048d9c4370c9c543c396e894c76be5525f5e1ad287f1750ddf", size = 207124 }, + { url = "https://files.pythonhosted.org/packages/8c/c4/811b9f311f10ce9d31a32ff14ce58500458443627e4df4ae9c264defba7f/propcache-0.2.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:1ac2f5fe02fa75f56e1ad473f1175e11f475606ec9bd0be2e78e4734ad575034", size = 210442 }, + { url = "https://files.pythonhosted.org/packages/18/dd/a1670d483a61ecac0d7fc4305d91caaac7a8fc1b200ea3965a01cf03bced/propcache-0.2.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:574faa3b79e8ebac7cb1d7930f51184ba1ccf69adfdec53a12f319a06030a68b", size = 203219 }, + { url = "https://files.pythonhosted.org/packages/f9/2d/30ced5afde41b099b2dc0c6573b66b45d16d73090e85655f1a30c5a24e07/propcache-0.2.1-cp310-cp310-win32.whl", hash = "sha256:03ff9d3f665769b2a85e6157ac8b439644f2d7fd17615a82fa55739bc97863f4", size = 40313 }, + { url = "https://files.pythonhosted.org/packages/23/84/bd9b207ac80da237af77aa6e153b08ffa83264b1c7882495984fcbfcf85c/propcache-0.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:2d3af2e79991102678f53e0dbf4c35de99b6b8b58f29a27ca0325816364caaba", size = 44428 }, + { url = "https://files.pythonhosted.org/packages/bc/0f/2913b6791ebefb2b25b4efd4bb2299c985e09786b9f5b19184a88e5778dd/propcache-0.2.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1ffc3cca89bb438fb9c95c13fc874012f7b9466b89328c3c8b1aa93cdcfadd16", size = 79297 }, + { url = "https://files.pythonhosted.org/packages/cf/73/af2053aeccd40b05d6e19058419ac77674daecdd32478088b79375b9ab54/propcache-0.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f174bbd484294ed9fdf09437f889f95807e5f229d5d93588d34e92106fbf6717", size = 45611 }, + { url = "https://files.pythonhosted.org/packages/3c/09/8386115ba7775ea3b9537730e8cf718d83bbf95bffe30757ccf37ec4e5da/propcache-0.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:70693319e0b8fd35dd863e3e29513875eb15c51945bf32519ef52927ca883bc3", size = 45146 }, + { url = "https://files.pythonhosted.org/packages/03/7a/793aa12f0537b2e520bf09f4c6833706b63170a211ad042ca71cbf79d9cb/propcache-0.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b480c6a4e1138e1aa137c0079b9b6305ec6dcc1098a8ca5196283e8a49df95a9", size = 232136 }, + { url = "https://files.pythonhosted.org/packages/f1/38/b921b3168d72111769f648314100558c2ea1d52eb3d1ba7ea5c4aa6f9848/propcache-0.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d27b84d5880f6d8aa9ae3edb253c59d9f6642ffbb2c889b78b60361eed449787", size = 239706 }, + { url = "https://files.pythonhosted.org/packages/14/29/4636f500c69b5edea7786db3c34eb6166f3384b905665ce312a6e42c720c/propcache-0.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:857112b22acd417c40fa4595db2fe28ab900c8c5fe4670c7989b1c0230955465", size = 238531 }, + { url = "https://files.pythonhosted.org/packages/85/14/01fe53580a8e1734ebb704a3482b7829a0ef4ea68d356141cf0994d9659b/propcache-0.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf6c4150f8c0e32d241436526f3c3f9cbd34429492abddbada2ffcff506c51af", size = 231063 }, + { url = "https://files.pythonhosted.org/packages/33/5c/1d961299f3c3b8438301ccfbff0143b69afcc30c05fa28673cface692305/propcache-0.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66d4cfda1d8ed687daa4bc0274fcfd5267873db9a5bc0418c2da19273040eeb7", size = 220134 }, + { url = "https://files.pythonhosted.org/packages/00/d0/ed735e76db279ba67a7d3b45ba4c654e7b02bc2f8050671ec365d8665e21/propcache-0.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c2f992c07c0fca81655066705beae35fc95a2fa7366467366db627d9f2ee097f", size = 220009 }, + { url = "https://files.pythonhosted.org/packages/75/90/ee8fab7304ad6533872fee982cfff5a53b63d095d78140827d93de22e2d4/propcache-0.2.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:4a571d97dbe66ef38e472703067021b1467025ec85707d57e78711c085984e54", size = 212199 }, + { url = "https://files.pythonhosted.org/packages/eb/ec/977ffaf1664f82e90737275873461695d4c9407d52abc2f3c3e24716da13/propcache-0.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:bb6178c241278d5fe853b3de743087be7f5f4c6f7d6d22a3b524d323eecec505", size = 214827 }, + { url = "https://files.pythonhosted.org/packages/57/48/031fb87ab6081764054821a71b71942161619549396224cbb242922525e8/propcache-0.2.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ad1af54a62ffe39cf34db1aa6ed1a1873bd548f6401db39d8e7cd060b9211f82", size = 228009 }, + { url = "https://files.pythonhosted.org/packages/1a/06/ef1390f2524850838f2390421b23a8b298f6ce3396a7cc6d39dedd4047b0/propcache-0.2.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e7048abd75fe40712005bcfc06bb44b9dfcd8e101dda2ecf2f5aa46115ad07ca", size = 231638 }, + { url = "https://files.pythonhosted.org/packages/38/2a/101e6386d5a93358395da1d41642b79c1ee0f3b12e31727932b069282b1d/propcache-0.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:160291c60081f23ee43d44b08a7e5fb76681221a8e10b3139618c5a9a291b84e", size = 222788 }, + { url = "https://files.pythonhosted.org/packages/db/81/786f687951d0979007e05ad9346cd357e50e3d0b0f1a1d6074df334b1bbb/propcache-0.2.1-cp311-cp311-win32.whl", hash = "sha256:819ce3b883b7576ca28da3861c7e1a88afd08cc8c96908e08a3f4dd64a228034", size = 40170 }, + { url = "https://files.pythonhosted.org/packages/cf/59/7cc7037b295d5772eceb426358bb1b86e6cab4616d971bd74275395d100d/propcache-0.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:edc9fc7051e3350643ad929df55c451899bb9ae6d24998a949d2e4c87fb596d3", size = 44404 }, + { url = "https://files.pythonhosted.org/packages/4c/28/1d205fe49be8b1b4df4c50024e62480a442b1a7b818e734308bb0d17e7fb/propcache-0.2.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:081a430aa8d5e8876c6909b67bd2d937bfd531b0382d3fdedb82612c618bc41a", size = 79588 }, + { url = "https://files.pythonhosted.org/packages/21/ee/fc4d893f8d81cd4971affef2a6cb542b36617cd1d8ce56b406112cb80bf7/propcache-0.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2ccec9ac47cf4e04897619c0e0c1a48c54a71bdf045117d3a26f80d38ab1fb0", size = 45825 }, + { url = "https://files.pythonhosted.org/packages/4a/de/bbe712f94d088da1d237c35d735f675e494a816fd6f54e9db2f61ef4d03f/propcache-0.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:14d86fe14b7e04fa306e0c43cdbeebe6b2c2156a0c9ce56b815faacc193e320d", size = 45357 }, + { url = "https://files.pythonhosted.org/packages/7f/14/7ae06a6cf2a2f1cb382586d5a99efe66b0b3d0c6f9ac2f759e6f7af9d7cf/propcache-0.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:049324ee97bb67285b49632132db351b41e77833678432be52bdd0289c0e05e4", size = 241869 }, + { url = "https://files.pythonhosted.org/packages/cc/59/227a78be960b54a41124e639e2c39e8807ac0c751c735a900e21315f8c2b/propcache-0.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cd9a1d071158de1cc1c71a26014dcdfa7dd3d5f4f88c298c7f90ad6f27bb46d", size = 247884 }, + { url = "https://files.pythonhosted.org/packages/84/58/f62b4ffaedf88dc1b17f04d57d8536601e4e030feb26617228ef930c3279/propcache-0.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98110aa363f1bb4c073e8dcfaefd3a5cea0f0834c2aab23dda657e4dab2f53b5", size = 248486 }, + { url = "https://files.pythonhosted.org/packages/1c/07/ebe102777a830bca91bbb93e3479cd34c2ca5d0361b83be9dbd93104865e/propcache-0.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:647894f5ae99c4cf6bb82a1bb3a796f6e06af3caa3d32e26d2350d0e3e3faf24", size = 243649 }, + { url = "https://files.pythonhosted.org/packages/ed/bc/4f7aba7f08f520376c4bb6a20b9a981a581b7f2e385fa0ec9f789bb2d362/propcache-0.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfd3223c15bebe26518d58ccf9a39b93948d3dcb3e57a20480dfdd315356baff", size = 229103 }, + { url = "https://files.pythonhosted.org/packages/fe/d5/04ac9cd4e51a57a96f78795e03c5a0ddb8f23ec098b86f92de028d7f2a6b/propcache-0.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d71264a80f3fcf512eb4f18f59423fe82d6e346ee97b90625f283df56aee103f", size = 226607 }, + { url = "https://files.pythonhosted.org/packages/e3/f0/24060d959ea41d7a7cc7fdbf68b31852331aabda914a0c63bdb0e22e96d6/propcache-0.2.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:e73091191e4280403bde6c9a52a6999d69cdfde498f1fdf629105247599b57ec", size = 221153 }, + { url = "https://files.pythonhosted.org/packages/77/a7/3ac76045a077b3e4de4859a0753010765e45749bdf53bd02bc4d372da1a0/propcache-0.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3935bfa5fede35fb202c4b569bb9c042f337ca4ff7bd540a0aa5e37131659348", size = 222151 }, + { url = "https://files.pythonhosted.org/packages/e7/af/5e29da6f80cebab3f5a4dcd2a3240e7f56f2c4abf51cbfcc99be34e17f0b/propcache-0.2.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f508b0491767bb1f2b87fdfacaba5f7eddc2f867740ec69ece6d1946d29029a6", size = 233812 }, + { url = "https://files.pythonhosted.org/packages/8c/89/ebe3ad52642cc5509eaa453e9f4b94b374d81bae3265c59d5c2d98efa1b4/propcache-0.2.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:1672137af7c46662a1c2be1e8dc78cb6d224319aaa40271c9257d886be4363a6", size = 238829 }, + { url = "https://files.pythonhosted.org/packages/e9/2f/6b32f273fa02e978b7577159eae7471b3cfb88b48563b1c2578b2d7ca0bb/propcache-0.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b74c261802d3d2b85c9df2dfb2fa81b6f90deeef63c2db9f0e029a3cac50b518", size = 230704 }, + { url = "https://files.pythonhosted.org/packages/5c/2e/f40ae6ff5624a5f77edd7b8359b208b5455ea113f68309e2b00a2e1426b6/propcache-0.2.1-cp312-cp312-win32.whl", hash = "sha256:d09c333d36c1409d56a9d29b3a1b800a42c76a57a5a8907eacdbce3f18768246", size = 40050 }, + { url = "https://files.pythonhosted.org/packages/3b/77/a92c3ef994e47180862b9d7d11e37624fb1c00a16d61faf55115d970628b/propcache-0.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:c214999039d4f2a5b2073ac506bba279945233da8c786e490d411dfc30f855c1", size = 44117 }, + { url = "https://files.pythonhosted.org/packages/0f/2a/329e0547cf2def8857157f9477669043e75524cc3e6251cef332b3ff256f/propcache-0.2.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aca405706e0b0a44cc6bfd41fbe89919a6a56999157f6de7e182a990c36e37bc", size = 77002 }, + { url = "https://files.pythonhosted.org/packages/12/2d/c4df5415e2382f840dc2ecbca0eeb2293024bc28e57a80392f2012b4708c/propcache-0.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:12d1083f001ace206fe34b6bdc2cb94be66d57a850866f0b908972f90996b3e9", size = 44639 }, + { url = "https://files.pythonhosted.org/packages/d0/5a/21aaa4ea2f326edaa4e240959ac8b8386ea31dedfdaa636a3544d9e7a408/propcache-0.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d93f3307ad32a27bda2e88ec81134b823c240aa3abb55821a8da553eed8d9439", size = 44049 }, + { url = "https://files.pythonhosted.org/packages/4e/3e/021b6cd86c0acc90d74784ccbb66808b0bd36067a1bf3e2deb0f3845f618/propcache-0.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba278acf14471d36316159c94a802933d10b6a1e117b8554fe0d0d9b75c9d536", size = 224819 }, + { url = "https://files.pythonhosted.org/packages/3c/57/c2fdeed1b3b8918b1770a133ba5c43ad3d78e18285b0c06364861ef5cc38/propcache-0.2.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4e6281aedfca15301c41f74d7005e6e3f4ca143584ba696ac69df4f02f40d629", size = 229625 }, + { url = "https://files.pythonhosted.org/packages/9d/81/70d4ff57bf2877b5780b466471bebf5892f851a7e2ca0ae7ffd728220281/propcache-0.2.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b750a8e5a1262434fb1517ddf64b5de58327f1adc3524a5e44c2ca43305eb0b", size = 232934 }, + { url = "https://files.pythonhosted.org/packages/3c/b9/bb51ea95d73b3fb4100cb95adbd4e1acaf2cbb1fd1083f5468eeb4a099a8/propcache-0.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf72af5e0fb40e9babf594308911436c8efde3cb5e75b6f206c34ad18be5c052", size = 227361 }, + { url = "https://files.pythonhosted.org/packages/f1/20/3c6d696cd6fd70b29445960cc803b1851a1131e7a2e4ee261ee48e002bcd/propcache-0.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b2d0a12018b04f4cb820781ec0dffb5f7c7c1d2a5cd22bff7fb055a2cb19ebce", size = 213904 }, + { url = "https://files.pythonhosted.org/packages/a1/cb/1593bfc5ac6d40c010fa823f128056d6bc25b667f5393781e37d62f12005/propcache-0.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e800776a79a5aabdb17dcc2346a7d66d0777e942e4cd251defeb084762ecd17d", size = 212632 }, + { url = "https://files.pythonhosted.org/packages/6d/5c/e95617e222be14a34c709442a0ec179f3207f8a2b900273720501a70ec5e/propcache-0.2.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:4160d9283bd382fa6c0c2b5e017acc95bc183570cd70968b9202ad6d8fc48dce", size = 207897 }, + { url = "https://files.pythonhosted.org/packages/8e/3b/56c5ab3dc00f6375fbcdeefdede5adf9bee94f1fab04adc8db118f0f9e25/propcache-0.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:30b43e74f1359353341a7adb783c8f1b1c676367b011709f466f42fda2045e95", size = 208118 }, + { url = "https://files.pythonhosted.org/packages/86/25/d7ef738323fbc6ebcbce33eb2a19c5e07a89a3df2fded206065bd5e868a9/propcache-0.2.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:58791550b27d5488b1bb52bc96328456095d96206a250d28d874fafe11b3dfaf", size = 217851 }, + { url = "https://files.pythonhosted.org/packages/b3/77/763e6cef1852cf1ba740590364ec50309b89d1c818e3256d3929eb92fabf/propcache-0.2.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:0f022d381747f0dfe27e99d928e31bc51a18b65bb9e481ae0af1380a6725dd1f", size = 222630 }, + { url = "https://files.pythonhosted.org/packages/4f/e9/0f86be33602089c701696fbed8d8c4c07b6ee9605c5b7536fd27ed540c5b/propcache-0.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:297878dc9d0a334358f9b608b56d02e72899f3b8499fc6044133f0d319e2ec30", size = 216269 }, + { url = "https://files.pythonhosted.org/packages/cc/02/5ac83217d522394b6a2e81a2e888167e7ca629ef6569a3f09852d6dcb01a/propcache-0.2.1-cp313-cp313-win32.whl", hash = "sha256:ddfab44e4489bd79bda09d84c430677fc7f0a4939a73d2bba3073036f487a0a6", size = 39472 }, + { url = "https://files.pythonhosted.org/packages/f4/33/d6f5420252a36034bc8a3a01171bc55b4bff5df50d1c63d9caa50693662f/propcache-0.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:556fc6c10989f19a179e4321e5d678db8eb2924131e64652a51fe83e4c3db0e1", size = 43363 }, + { url = "https://files.pythonhosted.org/packages/41/b6/c5319caea262f4821995dca2107483b94a3345d4607ad797c76cb9c36bcc/propcache-0.2.1-py3-none-any.whl", hash = "sha256:52277518d6aae65536e9cea52d4e7fd2f7a66f4aa2d30ed3f2fcea620ace3c54", size = 11818 }, ] [[package]] name = "protobuf" -version = "5.28.3" +version = "5.29.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/74/6e/e69eb906fddcb38f8530a12f4b410699972ab7ced4e21524ece9d546ac27/protobuf-5.28.3.tar.gz", hash = "sha256:64badbc49180a5e401f373f9ce7ab1d18b63f7dd4a9cdc43c92b9f0b481cef7b", size = 422479 } +sdist = { url = "https://files.pythonhosted.org/packages/d2/4f/1639b7b1633d8fd55f216ba01e21bf2c43384ab25ef3ddb35d85a52033e8/protobuf-5.29.1.tar.gz", hash = "sha256:683be02ca21a6ffe80db6dd02c0b5b2892322c59ca57fd6c872d652cb80549cb", size = 424965 } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/c5/05163fad52d7c43e124a545f1372d18266db36036377ad29de4271134a6a/protobuf-5.28.3-cp310-abi3-win32.whl", hash = "sha256:0c4eec6f987338617072592b97943fdbe30d019c56126493111cf24344c1cc24", size = 419624 }, - { url = "https://files.pythonhosted.org/packages/9c/4c/4563ebe001ff30dca9d7ed12e471fa098d9759712980cde1fd03a3a44fb7/protobuf-5.28.3-cp310-abi3-win_amd64.whl", hash = "sha256:91fba8f445723fcf400fdbe9ca796b19d3b1242cd873907979b9ed71e4afe868", size = 431464 }, - { url = "https://files.pythonhosted.org/packages/1c/f2/baf397f3dd1d3e4af7e3f5a0382b868d25ac068eefe1ebde05132333436c/protobuf-5.28.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:a3f6857551e53ce35e60b403b8a27b0295f7d6eb63d10484f12bc6879c715687", size = 414743 }, - { url = "https://files.pythonhosted.org/packages/85/50/cd61a358ba1601f40e7d38bcfba22e053f40ef2c50d55b55926aecc8fec7/protobuf-5.28.3-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:3fa2de6b8b29d12c61911505d893afe7320ce7ccba4df913e2971461fa36d584", size = 316511 }, - { url = "https://files.pythonhosted.org/packages/5d/ae/3257b09328c0b4e59535e497b0c7537d4954038bdd53a2f0d2f49d15a7c4/protobuf-5.28.3-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:712319fbdddb46f21abb66cd33cb9e491a5763b2febd8f228251add221981135", size = 316624 }, - { url = "https://files.pythonhosted.org/packages/ad/c3/2377c159e28ea89a91cf1ca223f827ae8deccb2c9c401e5ca233cd73002f/protobuf-5.28.3-py3-none-any.whl", hash = "sha256:cee1757663fa32a1ee673434fcf3bf24dd54763c79690201208bafec62f19eed", size = 169511 }, + { url = "https://files.pythonhosted.org/packages/50/c7/28669b04691a376cf7d0617d612f126aa0fff763d57df0142f9bf474c5b8/protobuf-5.29.1-cp310-abi3-win32.whl", hash = "sha256:22c1f539024241ee545cbcb00ee160ad1877975690b16656ff87dde107b5f110", size = 422706 }, + { url = "https://files.pythonhosted.org/packages/e3/33/dc7a7712f457456b7e0b16420ab8ba1cc8686751d3f28392eb43d0029ab9/protobuf-5.29.1-cp310-abi3-win_amd64.whl", hash = "sha256:1fc55267f086dd4050d18ef839d7bd69300d0d08c2a53ca7df3920cc271a3c34", size = 434505 }, + { url = "https://files.pythonhosted.org/packages/e5/39/44239fb1c6ec557e1731d996a5de89a9eb1ada7a92491fcf9c5d714052ed/protobuf-5.29.1-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:d473655e29c0c4bbf8b69e9a8fb54645bc289dead6d753b952e7aa660254ae18", size = 417822 }, + { url = "https://files.pythonhosted.org/packages/fb/4a/ec56f101d38d4bef2959a9750209809242d86cf8b897db00f2f98bfa360e/protobuf-5.29.1-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:b5ba1d0e4c8a40ae0496d0e2ecfdbb82e1776928a205106d14ad6985a09ec155", size = 319572 }, + { url = "https://files.pythonhosted.org/packages/04/52/c97c58a33b3d6c89a8138788576d372a90a6556f354799971c6b4d16d871/protobuf-5.29.1-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:8ee1461b3af56145aca2800e6a3e2f928108c749ba8feccc6f5dd0062c410c0d", size = 319671 }, + { url = "https://files.pythonhosted.org/packages/3b/24/c8c49df8f6587719e1d400109b16c10c6902d0c9adddc8fff82840146f99/protobuf-5.29.1-py3-none-any.whl", hash = "sha256:32600ddb9c2a53dedc25b8581ea0f1fd8ea04956373c0c07577ce58d312522e0", size = 172547 }, ] [[package]] @@ -974,7 +973,7 @@ wheels = [ [[package]] name = "pytest" -version = "8.3.3" +version = "8.3.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -984,22 +983,22 @@ dependencies = [ { name = "pluggy" }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8b/6c/62bbd536103af674e227c41a8f3dcd022d591f6eed5facb5a0f31ee33bbc/pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181", size = 1442487 } +sdist = { url = "https://files.pythonhosted.org/packages/05/35/30e0d83068951d90a01852cb1cef56e5d8a09d20c7f511634cc2f7e0372a/pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761", size = 1445919 } wheels = [ - { url = "https://files.pythonhosted.org/packages/6b/77/7440a06a8ead44c7757a64362dd22df5760f9b12dc5f11b6188cd2fc27a0/pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2", size = 342341 }, + { url = "https://files.pythonhosted.org/packages/11/92/76a1c94d3afee238333bc0a42b82935dd8f9cf8ce9e336ff87ee14d9e1cf/pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6", size = 343083 }, ] [[package]] name = "pytest-httpx" -version = "0.34.0" +version = "0.35.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "httpx" }, { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/86/08/d0be3fe5645c6cd9396093a9ddf97d60814a3b066fd5b38ddced34a13d14/pytest_httpx-0.34.0.tar.gz", hash = "sha256:3ca4b0975c0f93b985f17df19e76430c1086b5b0cce32b1af082d8901296a735", size = 54108 } +sdist = { url = "https://files.pythonhosted.org/packages/1f/89/5b12b7b29e3d0af3a4b9c071ee92fa25a9017453731a38f08ba01c280f4c/pytest_httpx-0.35.0.tar.gz", hash = "sha256:d619ad5d2e67734abfbb224c3d9025d64795d4b8711116b1a13f72a251ae511f", size = 54146 } wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/72/7138a0faf5d780d6b9ceedef22da0b66ae8e22a676a12fd55a05c0cdd979/pytest_httpx-0.34.0-py3-none-any.whl", hash = "sha256:42cf0a66f7b71b9111db2897e8b38a903abd33a27b11c48aff4a3c7650313af2", size = 19440 }, + { url = "https://files.pythonhosted.org/packages/b0/ed/026d467c1853dd83102411a78126b4842618e86c895f93528b0528c7a620/pytest_httpx-0.35.0-py3-none-any.whl", hash = "sha256:ee11a00ffcea94a5cbff47af2114d34c5b231c326902458deed73f9c459fd744", size = 19442 }, ] [[package]] @@ -1057,27 +1056,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.8.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b2/d6/a2373f3ba7180ddb44420d2a9d1f1510e1a4d162b3d27282bedcb09c8da9/ruff-0.8.0.tar.gz", hash = "sha256:a7ccfe6331bf8c8dad715753e157457faf7351c2b69f62f32c165c2dbcbacd44", size = 3276537 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/77/e889ee3ce7fd8baa3ed1b77a03b9fb8ec1be68be1418261522fd6a5405e0/ruff-0.8.0-py3-none-linux_armv6l.whl", hash = "sha256:fcb1bf2cc6706adae9d79c8d86478677e3bbd4ced796ccad106fd4776d395fea", size = 10518283 }, - { url = "https://files.pythonhosted.org/packages/da/c8/0a47de01edf19fb22f5f9b7964f46a68d0bdff20144d134556ffd1ba9154/ruff-0.8.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:295bb4c02d58ff2ef4378a1870c20af30723013f441c9d1637a008baaf928c8b", size = 10317691 }, - { url = "https://files.pythonhosted.org/packages/41/17/9885e4a0eeae07abd2a4ebabc3246f556719f24efa477ba2739146c4635a/ruff-0.8.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7b1f1c76b47c18fa92ee78b60d2d20d7e866c55ee603e7d19c1e991fad933a9a", size = 9940999 }, - { url = "https://files.pythonhosted.org/packages/3e/cd/46b6f7043597eb318b5f5482c8ae8f5491cccce771e85f59d23106f2d179/ruff-0.8.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb0d4f250a7711b67ad513fde67e8870109e5ce590a801c3722580fe98c33a99", size = 10772437 }, - { url = "https://files.pythonhosted.org/packages/5d/87/afc95aeb8bc78b1d8a3461717a4419c05aa8aa943d4c9cbd441630f85584/ruff-0.8.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0e55cce9aa93c5d0d4e3937e47b169035c7e91c8655b0974e61bb79cf398d49c", size = 10299156 }, - { url = "https://files.pythonhosted.org/packages/65/fa/04c647bb809c4d65e8eae1ed1c654d9481b21dd942e743cd33511687b9f9/ruff-0.8.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f4cd64916d8e732ce6b87f3f5296a8942d285bbbc161acee7fe561134af64f9", size = 11325819 }, - { url = "https://files.pythonhosted.org/packages/90/26/7dad6e7d833d391a8a1afe4ee70ca6f36c4a297d3cca83ef10e83e9aacf3/ruff-0.8.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c5c1466be2a2ebdf7c5450dd5d980cc87c8ba6976fb82582fea18823da6fa362", size = 12023927 }, - { url = "https://files.pythonhosted.org/packages/24/a0/be5296dda6428ba8a13bda8d09fbc0e14c810b485478733886e61597ae2b/ruff-0.8.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2dabfd05b96b7b8f2da00d53c514eea842bff83e41e1cceb08ae1966254a51df", size = 11589702 }, - { url = "https://files.pythonhosted.org/packages/26/3f/7602eb11d2886db545834182a9dbe500b8211fcbc9b4064bf9d358bbbbb4/ruff-0.8.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:facebdfe5a5af6b1588a1d26d170635ead6892d0e314477e80256ef4a8470cf3", size = 12782936 }, - { url = "https://files.pythonhosted.org/packages/4c/5d/083181bdec4ec92a431c1291d3fff65eef3ded630a4b55eb735000ef5f3b/ruff-0.8.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87a8e86bae0dbd749c815211ca11e3a7bd559b9710746c559ed63106d382bd9c", size = 11138488 }, - { url = "https://files.pythonhosted.org/packages/b7/23/c12cdef58413cee2436d6a177aa06f7a366ebbca916cf10820706f632459/ruff-0.8.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:85e654f0ded7befe2d61eeaf3d3b1e4ef3894469cd664ffa85006c7720f1e4a2", size = 10744474 }, - { url = "https://files.pythonhosted.org/packages/29/61/a12f3b81520083cd7c5caa24ba61bb99fd1060256482eff0ef04cc5ccd1b/ruff-0.8.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:83a55679c4cb449fa527b8497cadf54f076603cc36779b2170b24f704171ce70", size = 10369029 }, - { url = "https://files.pythonhosted.org/packages/08/2a/c013f4f3e4a54596c369cee74c24870ed1d534f31a35504908b1fc97017a/ruff-0.8.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:812e2052121634cf13cd6fddf0c1871d0ead1aad40a1a258753c04c18bb71bbd", size = 10867481 }, - { url = "https://files.pythonhosted.org/packages/d5/f7/685b1e1d42a3e94ceb25eab23c70bdd8c0ab66a43121ef83fe6db5a58756/ruff-0.8.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:780d5d8523c04202184405e60c98d7595bdb498c3c6abba3b6d4cdf2ca2af426", size = 11237117 }, - { url = "https://files.pythonhosted.org/packages/03/20/401132c0908e8837625e3b7e32df9962e7cd681a4df1e16a10e2a5b4ecda/ruff-0.8.0-py3-none-win32.whl", hash = "sha256:5fdb6efecc3eb60bba5819679466471fd7d13c53487df7248d6e27146e985468", size = 8783511 }, - { url = "https://files.pythonhosted.org/packages/1d/5c/4d800fca7854f62ad77f2c0d99b4b585f03e2d87a6ec1ecea85543a14a3c/ruff-0.8.0-py3-none-win_amd64.whl", hash = "sha256:582891c57b96228d146725975fbb942e1f30a0c4ba19722e692ca3eb25cc9b4f", size = 9559876 }, - { url = "https://files.pythonhosted.org/packages/5b/bc/cc8a6a5ca4960b226dc15dd8fb511dd11f2014ff89d325c0b9b9faa9871f/ruff-0.8.0-py3-none-win_arm64.whl", hash = "sha256:ba93e6294e9a737cd726b74b09a6972e36bb511f9a102f1d9a7e1ce94dd206a6", size = 8939733 }, +version = "0.8.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/2b/01245f4f3a727d60bebeacd7ee6d22586c7f62380a2597ddb22c2f45d018/ruff-0.8.2.tar.gz", hash = "sha256:b84f4f414dda8ac7f75075c1fa0b905ac0ff25361f42e6d5da681a465e0f78e5", size = 3349020 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/91/29/366be70216dba1731a00a41f2f030822b0c96c7c4f3b2c0cdce15cbace74/ruff-0.8.2-py3-none-linux_armv6l.whl", hash = "sha256:c49ab4da37e7c457105aadfd2725e24305ff9bc908487a9bf8d548c6dad8bb3d", size = 10530649 }, + { url = "https://files.pythonhosted.org/packages/63/82/a733956540bb388f00df5a3e6a02467b16c0e529132625fe44ce4c5fb9c7/ruff-0.8.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ec016beb69ac16be416c435828be702ee694c0d722505f9c1f35e1b9c0cc1bf5", size = 10274069 }, + { url = "https://files.pythonhosted.org/packages/3d/12/0b3aa14d1d71546c988a28e1b412981c1b80c8a1072e977a2f30c595cc4a/ruff-0.8.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f05cdf8d050b30e2ba55c9b09330b51f9f97d36d4673213679b965d25a785f3c", size = 9909400 }, + { url = "https://files.pythonhosted.org/packages/23/08/f9f08cefb7921784c891c4151cce6ed357ff49e84b84978440cffbc87408/ruff-0.8.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60f578c11feb1d3d257b2fb043ddb47501ab4816e7e221fbb0077f0d5d4e7b6f", size = 10766782 }, + { url = "https://files.pythonhosted.org/packages/e4/71/bf50c321ec179aa420c8ec40adac5ae9cc408d4d37283a485b19a2331ceb/ruff-0.8.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cbd5cf9b0ae8f30eebc7b360171bd50f59ab29d39f06a670b3e4501a36ba5897", size = 10286316 }, + { url = "https://files.pythonhosted.org/packages/f2/83/c82688a2a6117539aea0ce63fdf6c08e60fe0202779361223bcd7f40bd74/ruff-0.8.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b402ddee3d777683de60ff76da801fa7e5e8a71038f57ee53e903afbcefdaa58", size = 11338270 }, + { url = "https://files.pythonhosted.org/packages/7f/d7/bc6a45e5a22e627640388e703160afb1d77c572b1d0fda8b4349f334fc66/ruff-0.8.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:705832cd7d85605cb7858d8a13d75993c8f3ef1397b0831289109e953d833d29", size = 12058579 }, + { url = "https://files.pythonhosted.org/packages/da/3b/64150c93946ec851e6f1707ff586bb460ca671581380c919698d6a9267dc/ruff-0.8.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:32096b41aaf7a5cc095fa45b4167b890e4c8d3fd217603f3634c92a541de7248", size = 11615172 }, + { url = "https://files.pythonhosted.org/packages/e4/9e/cf12b697ea83cfe92ec4509ae414dc4c9b38179cc681a497031f0d0d9a8e/ruff-0.8.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e769083da9439508833cfc7c23e351e1809e67f47c50248250ce1ac52c21fb93", size = 12882398 }, + { url = "https://files.pythonhosted.org/packages/a9/27/96d10863accf76a9c97baceac30b0a52d917eb985a8ac058bd4636aeede0/ruff-0.8.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fe716592ae8a376c2673fdfc1f5c0c193a6d0411f90a496863c99cd9e2ae25d", size = 11176094 }, + { url = "https://files.pythonhosted.org/packages/eb/10/cd2fd77d4a4e7f03c29351be0f53278a393186b540b99df68beb5304fddd/ruff-0.8.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:81c148825277e737493242b44c5388a300584d73d5774defa9245aaef55448b0", size = 10771884 }, + { url = "https://files.pythonhosted.org/packages/71/5d/beabb2ff18870fc4add05fa3a69a4cb1b1d2d6f83f3cf3ae5ab0d52f455d/ruff-0.8.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d261d7850c8367704874847d95febc698a950bf061c9475d4a8b7689adc4f7fa", size = 10382535 }, + { url = "https://files.pythonhosted.org/packages/ae/29/6b3fdf3ad3e35b28d87c25a9ff4c8222ad72485ab783936b2b267250d7a7/ruff-0.8.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:1ca4e3a87496dc07d2427b7dd7ffa88a1e597c28dad65ae6433ecb9f2e4f022f", size = 10886995 }, + { url = "https://files.pythonhosted.org/packages/e9/dc/859d889b4d9356a1a2cdbc1e4a0dda94052bc5b5300098647e51a58c430b/ruff-0.8.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:729850feed82ef2440aa27946ab39c18cb4a8889c1128a6d589ffa028ddcfc22", size = 11220750 }, + { url = "https://files.pythonhosted.org/packages/0b/08/e8f519f61f1d624264bfd6b8829e4c5f31c3c61193bc3cff1f19dbe7626a/ruff-0.8.2-py3-none-win32.whl", hash = "sha256:ac42caaa0411d6a7d9594363294416e0e48fc1279e1b0e948391695db2b3d5b1", size = 8729396 }, + { url = "https://files.pythonhosted.org/packages/f8/d4/ba1c7ab72aba37a2b71fe48ab95b80546dbad7a7f35ea28cf66fc5cea5f6/ruff-0.8.2-py3-none-win_amd64.whl", hash = "sha256:2aae99ec70abf43372612a838d97bfe77d45146254568d94926e8ed5bbb409ea", size = 9594729 }, + { url = "https://files.pythonhosted.org/packages/23/34/db20e12d3db11b8a2a8874258f0f6d96a9a4d631659d54575840557164c8/ruff-0.8.2-py3-none-win_arm64.whl", hash = "sha256:fb88e2a506b70cfbc2de6fae6681c4f944f7dd5f2fe87233a7233d888bad73e8", size = 9035131 }, ] [[package]] @@ -1208,11 +1207,41 @@ wheels = [ [[package]] name = "tomli" -version = "2.1.0" +version = "2.2.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1e/e4/1b6cbcc82d8832dd0ce34767d5c560df8a3547ad8cbc427f34601415930a/tomli-2.1.0.tar.gz", hash = "sha256:3f646cae2aec94e17d04973e4249548320197cfabdf130015d023de4b74d8ab8", size = 16622 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/de/f7/4da0ffe1892122c9ea096c57f64c2753ae5dd3ce85488802d11b0992cc6d/tomli-2.1.0-py3-none-any.whl", hash = "sha256:a5c57c3d1c56f5ccdf89f6523458f60ef716e210fc47c4cfb188c5ba473e0391", size = 13750 }, +sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077 }, + { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429 }, + { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067 }, + { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030 }, + { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898 }, + { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894 }, + { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319 }, + { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273 }, + { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310 }, + { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309 }, + { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762 }, + { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453 }, + { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486 }, + { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349 }, + { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159 }, + { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243 }, + { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645 }, + { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584 }, + { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875 }, + { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418 }, + { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708 }, + { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582 }, + { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543 }, + { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691 }, + { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170 }, + { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530 }, + { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666 }, + { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954 }, + { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724 }, + { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383 }, + { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257 }, ] [[package]] @@ -1289,80 +1318,80 @@ wheels = [ [[package]] name = "yarl" -version = "1.18.0" +version = "1.18.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, { name = "multidict" }, { name = "propcache" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5e/4b/53db4ecad4d54535aff3dfda1f00d6363d79455f62b11b8ca97b82746bd2/yarl-1.18.0.tar.gz", hash = "sha256:20d95535e7d833889982bfe7cc321b7f63bf8879788fee982c76ae2b24cfb715", size = 180098 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/80/8b/305e1bde6bbf900bb8909a4884488764ee5950dda4da06cec885c06dae68/yarl-1.18.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:074fee89caab89a97e18ef5f29060ef61ba3cae6cd77673acc54bfdd3214b7b7", size = 141186 }, - { url = "https://files.pythonhosted.org/packages/6a/85/a15e439d8faa6bd09a536d87ca7a32daa50cf8820cf220edbced702348a0/yarl-1.18.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b026cf2c32daf48d90c0c4e406815c3f8f4cfe0c6dfccb094a9add1ff6a0e41a", size = 94097 }, - { url = "https://files.pythonhosted.org/packages/12/9d/7d39082baae943f138df1bb96914f8d53fd65eb131b9d0965917b009b35d/yarl-1.18.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ae38bd86eae3ba3d2ce5636cc9e23c80c9db2e9cb557e40b98153ed102b5a736", size = 91915 }, - { url = "https://files.pythonhosted.org/packages/c0/35/7e6fbfeb413f281dda59d4a9fce7a0c43cb1f22cb6ac25151d4c4ce51651/yarl-1.18.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:685cc37f3f307c6a8e879986c6d85328f4c637f002e219f50e2ef66f7e062c1d", size = 315086 }, - { url = "https://files.pythonhosted.org/packages/76/2e/61b854cca176d8952d1448b15d59b9b4df27648e4cc9c1a2a01449238b21/yarl-1.18.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8254dbfce84ee5d1e81051ee7a0f1536c108ba294c0fdb5933476398df0654f3", size = 330221 }, - { url = "https://files.pythonhosted.org/packages/98/66/975c36deeb069888274c2edfa9d6aef44c7574e9b11bb0687130ddd02558/yarl-1.18.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:20de4a8b04de70c49698dc2390b7fd2d18d424d3b876371f9b775e2b462d4b41", size = 326650 }, - { url = "https://files.pythonhosted.org/packages/a4/06/511e5ac4e562cbd605a05c90875e36ec5bac93da0dc55c730b4b3b09face/yarl-1.18.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b0a2074a37285570d54b55820687de3d2f2b9ecf1b714e482e48c9e7c0402038", size = 319437 }, - { url = "https://files.pythonhosted.org/packages/7c/6a/8f6f8b17b28ed6eaaf20f5a80d391ae1c1bd5437af9ed552b9eb8903b11c/yarl-1.18.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f576ed278860df2721a5d57da3381040176ef1d07def9688a385c8330db61a1", size = 309966 }, - { url = "https://files.pythonhosted.org/packages/b5/54/4d9dcbdaba18a948f8bea5b65835bfcc5a931426c79d8d2dafe45264ece8/yarl-1.18.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3a3709450a574d61be6ac53d582496014342ea34876af8dc17cc16da32826c9a", size = 319519 }, - { url = "https://files.pythonhosted.org/packages/42/b7/de7fcde2c414d33a2be5ac9c31469ad33874a26a5e3421b2a9505a1a10ee/yarl-1.18.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:bd80ed29761490c622edde5dd70537ca8c992c2952eb62ed46984f8eff66d6e8", size = 321455 }, - { url = "https://files.pythonhosted.org/packages/4e/49/8ed0dc1973876f20b63fe66986f300fd0721f3d644b6a64be12ec436c197/yarl-1.18.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:32141e13a1d5a48525e519c9197d3f4d9744d818d5c7d6547524cc9eccc8971e", size = 324564 }, - { url = "https://files.pythonhosted.org/packages/0c/76/63209f71efde8875670441875ef1a46383a06f578f6babf819b0cf79ebd7/yarl-1.18.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8b8d3e4e014fb4274f1c5bf61511d2199e263909fb0b8bda2a7428b0894e8dc6", size = 336798 }, - { url = "https://files.pythonhosted.org/packages/a8/f3/77e0cdee76359dade383b61eb995a3a2efcef3d64da3222f3cf52d38bd38/yarl-1.18.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:701bb4a8f4de191c8c0cc9a1e6d5142f4df880e9d1210e333b829ca9425570ed", size = 337902 }, - { url = "https://files.pythonhosted.org/packages/96/d9/0f97875e2498196a9b5561de32f3f25208485c7b43d676a65a2ee6c12fd7/yarl-1.18.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a45d94075ac0647621eaaf693c8751813a3eccac455d423f473ffed38c8ac5c9", size = 331620 }, - { url = "https://files.pythonhosted.org/packages/71/a3/e3bd136838d29fec4acc4919bcfd2bd33296f6c281c829fa277e72bc2590/yarl-1.18.0-cp310-cp310-win32.whl", hash = "sha256:34176bfb082add67cb2a20abd85854165540891147f88b687a5ed0dc225750a0", size = 84045 }, - { url = "https://files.pythonhosted.org/packages/fd/20/a474648c2b49c9ed5eb0e7137add6373e5d9220eda7e6d4b43d306e67672/yarl-1.18.0-cp310-cp310-win_amd64.whl", hash = "sha256:73553bbeea7d6ec88c08ad8027f4e992798f0abc459361bf06641c71972794dc", size = 90221 }, - { url = "https://files.pythonhosted.org/packages/06/45/6ad7135d1c4ad3a6a49e2c37dc78a1805a7871879c03c3495d64c9605d49/yarl-1.18.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b8e8c516dc4e1a51d86ac975b0350735007e554c962281c432eaa5822aa9765c", size = 141283 }, - { url = "https://files.pythonhosted.org/packages/45/6d/24b70ae33107d6eba303ed0ebfdf1164fe2219656e7594ca58628ebc0f1d/yarl-1.18.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2e6b4466714a73f5251d84b471475850954f1fa6acce4d3f404da1d55d644c34", size = 94082 }, - { url = "https://files.pythonhosted.org/packages/8a/0e/da720989be11b662ca847ace58f468b52310a9b03e52ac62c144755f9d75/yarl-1.18.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c893f8c1a6d48b25961e00922724732d00b39de8bb0b451307482dc87bddcd74", size = 92017 }, - { url = "https://files.pythonhosted.org/packages/f5/76/e5c91681fa54658943cb88673fb19b3355c3a8ae911a33a2621b6320990d/yarl-1.18.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13aaf2bdbc8c86ddce48626b15f4987f22e80d898818d735b20bd58f17292ee8", size = 340359 }, - { url = "https://files.pythonhosted.org/packages/cf/77/02cf72f09dea20980dea4ebe40dfb2c24916b864aec869a19f715428e0f0/yarl-1.18.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dd21c0128e301851de51bc607b0a6da50e82dc34e9601f4b508d08cc89ee7929", size = 356336 }, - { url = "https://files.pythonhosted.org/packages/17/66/83a88d04e4fc243dd26109f3e3d6412f67819ab1142dadbce49706ef4df4/yarl-1.18.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:205de377bd23365cd85562c9c6c33844050a93661640fda38e0567d2826b50df", size = 353730 }, - { url = "https://files.pythonhosted.org/packages/76/77/0b205a532d22756ab250ab21924d362f910a23d641c82faec1c4ad7f6077/yarl-1.18.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed69af4fe2a0949b1ea1d012bf065c77b4c7822bad4737f17807af2adb15a73c", size = 343882 }, - { url = "https://files.pythonhosted.org/packages/0b/47/2081ddce3da6096889c3947bdc21907d0fa15939909b10219254fe116841/yarl-1.18.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e1c18890091aa3cc8a77967943476b729dc2016f4cfe11e45d89b12519d4a93", size = 335873 }, - { url = "https://files.pythonhosted.org/packages/25/3c/437304394494e757ae927c9a81bacc4bcdf7351a1d4e811d95b02cb6dbae/yarl-1.18.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:91b8fb9427e33f83ca2ba9501221ffaac1ecf0407f758c4d2f283c523da185ee", size = 347725 }, - { url = "https://files.pythonhosted.org/packages/c6/fb/fa6c642bc052fbe6370ed5da765579650510157dea354fe9e8177c3bc34a/yarl-1.18.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:536a7a8a53b75b2e98ff96edb2dfb91a26b81c4fed82782035767db5a465be46", size = 346161 }, - { url = "https://files.pythonhosted.org/packages/b0/09/8c0cf68a0fcfe3b060c9e5857bb35735bc72a4cf4075043632c636d007e9/yarl-1.18.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a64619a9c47c25582190af38e9eb382279ad42e1f06034f14d794670796016c0", size = 349924 }, - { url = "https://files.pythonhosted.org/packages/bf/4b/1efe10fd51e2cedf53195d688fa270efbcd64a015c61d029d49c20bf0af7/yarl-1.18.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c73a6bbc97ba1b5a0c3c992ae93d721c395bdbb120492759b94cc1ac71bc6350", size = 361865 }, - { url = "https://files.pythonhosted.org/packages/0b/1b/2b5efd6df06bf938f7e154dee8e2ab22d148f3311a92bf4da642aaaf2fc5/yarl-1.18.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a173401d7821a2a81c7b47d4e7d5c4021375a1441af0c58611c1957445055056", size = 366030 }, - { url = "https://files.pythonhosted.org/packages/f8/db/786a5684f79278e62271038a698f56a51960f9e643be5d3eff82712f0b1c/yarl-1.18.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7520e799b1f84e095cce919bd6c23c9d49472deeef25fe1ef960b04cca51c3fc", size = 358902 }, - { url = "https://files.pythonhosted.org/packages/91/2f/437d0de062f1a3e3cb17573971b3832232443241133580c2ba3da5001d06/yarl-1.18.0-cp311-cp311-win32.whl", hash = "sha256:c4cb992d8090d5ae5f7afa6754d7211c578be0c45f54d3d94f7781c495d56716", size = 84138 }, - { url = "https://files.pythonhosted.org/packages/9d/85/035719a9266bce85ecde820aa3f8c46f3b18c3d7ba9ff51367b2fa4ae2a2/yarl-1.18.0-cp311-cp311-win_amd64.whl", hash = "sha256:52c136f348605974c9b1c878addd6b7a60e3bf2245833e370862009b86fa4689", size = 90765 }, - { url = "https://files.pythonhosted.org/packages/23/36/c579b80a5c76c0d41c8e08baddb3e6940dfc20569db579a5691392c52afa/yarl-1.18.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1ece25e2251c28bab737bdf0519c88189b3dd9492dc086a1d77336d940c28ced", size = 142376 }, - { url = "https://files.pythonhosted.org/packages/0c/5f/e247dc7c0607a0c505fea6c839721844bee55686dfb183c7d7b8ef8a9cb1/yarl-1.18.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:454902dc1830d935c90b5b53c863ba2a98dcde0fbaa31ca2ed1ad33b2a7171c6", size = 94692 }, - { url = "https://files.pythonhosted.org/packages/eb/e1/3081b578a6f21961711b9a1c49c2947abb3b0d0dd9537378fb06777ce8ee/yarl-1.18.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:01be8688fc211dc237e628fcc209dda412d35de7642453059a0553747018d075", size = 92527 }, - { url = "https://files.pythonhosted.org/packages/2f/fa/d9e1b9fbafa4cc82cd3980b5314741b33c2fe16308d725449a23aed32021/yarl-1.18.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d26f1fa9fa2167bb238f6f4b20218eb4e88dd3ef21bb8f97439fa6b5313e30d", size = 332096 }, - { url = "https://files.pythonhosted.org/packages/93/b6/dd27165114317875838e216214fb86338dc63d2e50855a8f2a12de2a7fe5/yarl-1.18.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b234a4a9248a9f000b7a5dfe84b8cb6210ee5120ae70eb72a4dcbdb4c528f72f", size = 342047 }, - { url = "https://files.pythonhosted.org/packages/fc/9f/bad434b5279ae7a356844e14dc771c3d29eb928140bbc01621af811c8a27/yarl-1.18.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe94d1de77c4cd8caff1bd5480e22342dbd54c93929f5943495d9c1e8abe9f42", size = 341712 }, - { url = "https://files.pythonhosted.org/packages/9a/9f/63864f43d131ba8c8cdf1bde5dd3f02f0eff8a7c883a5d7fad32f204fda5/yarl-1.18.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b4c90c5363c6b0a54188122b61edb919c2cd1119684999d08cd5e538813a28e", size = 336654 }, - { url = "https://files.pythonhosted.org/packages/20/30/b4542bbd9be73de155213207eec019f6fe6495885f7dd59aa1ff705a041b/yarl-1.18.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49a98ecadc5a241c9ba06de08127ee4796e1009555efd791bac514207862b43d", size = 325484 }, - { url = "https://files.pythonhosted.org/packages/69/bc/e2a9808ec26989cf0d1b98fe7b3cc45c1c6506b5ea4fe43ece5991f28f34/yarl-1.18.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9106025c7f261f9f5144f9aa7681d43867eed06349a7cfb297a1bc804de2f0d1", size = 344213 }, - { url = "https://files.pythonhosted.org/packages/e2/17/0ee5a68886aca1a8071b0d24a1e1c0fd9970dead2ef2d5e26e027fb7ce88/yarl-1.18.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:f275ede6199d0f1ed4ea5d55a7b7573ccd40d97aee7808559e1298fe6efc8dbd", size = 340517 }, - { url = "https://files.pythonhosted.org/packages/fd/db/1fe4ef38ee852bff5ec8f5367d718b3a7dac7520f344b8e50306f68a2940/yarl-1.18.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f7edeb1dcc7f50a2c8e08b9dc13a413903b7817e72273f00878cb70e766bdb3b", size = 346234 }, - { url = "https://files.pythonhosted.org/packages/b4/ee/5e5bccdb821eb9949ba66abb4d19e3299eee00282e37b42f65236120e892/yarl-1.18.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c083f6dd6951b86e484ebfc9c3524b49bcaa9c420cb4b2a78ef9f7a512bfcc85", size = 359625 }, - { url = "https://files.pythonhosted.org/packages/3f/43/95a64d9e7ab4aa1c34fc5ea0edb35b581bc6ad33fd960a8ae34c2040b319/yarl-1.18.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:80741ec5b471fbdfb997821b2842c59660a1c930ceb42f8a84ba8ca0f25a66aa", size = 364239 }, - { url = "https://files.pythonhosted.org/packages/40/19/09ce976c624c9d3cc898f0be5035ddef0c0759d85b2313321cfe77b69915/yarl-1.18.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b1a3297b9cad594e1ff0c040d2881d7d3a74124a3c73e00c3c71526a1234a9f7", size = 357599 }, - { url = "https://files.pythonhosted.org/packages/7d/35/6f33fd29791af2ec161aebe8abe63e788c2b74a6c7e8f29c92e5f5e96849/yarl-1.18.0-cp312-cp312-win32.whl", hash = "sha256:cd6ab7d6776c186f544f893b45ee0c883542b35e8a493db74665d2e594d3ca75", size = 83832 }, - { url = "https://files.pythonhosted.org/packages/4e/8e/cdb40ef98597be107de67b11e2f1f23f911e0f1416b938885d17a338e304/yarl-1.18.0-cp312-cp312-win_amd64.whl", hash = "sha256:039c299a0864d1f43c3e31570045635034ea7021db41bf4842693a72aca8df3a", size = 90132 }, - { url = "https://files.pythonhosted.org/packages/2b/77/2196b657c66f97adaef0244e9e015f30eac0df59c31ad540f79ce328feed/yarl-1.18.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6fb64dd45453225f57d82c4764818d7a205ee31ce193e9f0086e493916bd4f72", size = 140512 }, - { url = "https://files.pythonhosted.org/packages/0e/d8/2bb6e26fddba5c01bad284e4571178c651b97e8e06318efcaa16e07eb9fd/yarl-1.18.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3adaaf9c6b1b4fc258584f4443f24d775a2086aee82d1387e48a8b4f3d6aecf6", size = 93875 }, - { url = "https://files.pythonhosted.org/packages/54/e4/99fbb884dd9f814fb0037dc1783766bb9edcd57b32a76f3ec5ac5c5772d7/yarl-1.18.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:da206d1ec78438a563c5429ab808a2b23ad7bc025c8adbf08540dde202be37d5", size = 91705 }, - { url = "https://files.pythonhosted.org/packages/3b/a2/5bd86eca9449e6b15d3b08005cf4e58e3da972240c2bee427b358c311549/yarl-1.18.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:576d258b21c1db4c6449b1c572c75d03f16a482eb380be8003682bdbe7db2f28", size = 333325 }, - { url = "https://files.pythonhosted.org/packages/94/50/a218da5f159cd985685bc72c500bb1a7fd2d60035d2339b8a9d9e1f99194/yarl-1.18.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c60e547c0a375c4bfcdd60eef82e7e0e8698bf84c239d715f5c1278a73050393", size = 344121 }, - { url = "https://files.pythonhosted.org/packages/a4/e3/830ae465811198b4b5ebecd674b5b3dca4d222af2155eb2144bfe190bbb8/yarl-1.18.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e3818eabaefb90adeb5e0f62f047310079d426387991106d4fbf3519eec7d90a", size = 345163 }, - { url = "https://files.pythonhosted.org/packages/7a/74/05c4326877ca541eee77b1ef74b7ac8081343d3957af8f9291ca6eca6fec/yarl-1.18.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5f72421246c21af6a92fbc8c13b6d4c5427dfd949049b937c3b731f2f9076bd", size = 339130 }, - { url = "https://files.pythonhosted.org/packages/29/42/842f35aa1dae25d132119ee92185e8c75d8b9b7c83346506bd31e9fa217f/yarl-1.18.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7fa7d37f2ada0f42e0723632993ed422f2a679af0e200874d9d861720a54f53e", size = 326418 }, - { url = "https://files.pythonhosted.org/packages/f9/ed/65c0514f2d1e8b92a61f564c914381d078766cab38b5fbde355b3b3af1fb/yarl-1.18.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:42ba84e2ac26a3f252715f8ec17e6fdc0cbf95b9617c5367579fafcd7fba50eb", size = 345204 }, - { url = "https://files.pythonhosted.org/packages/23/31/351f64f0530c372fa01160f38330f44478e7bf3092f5ce2bfcb91605561d/yarl-1.18.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:6a49ad0102c0f0ba839628d0bf45973c86ce7b590cdedf7540d5b1833ddc6f00", size = 341652 }, - { url = "https://files.pythonhosted.org/packages/49/aa/0c6e666c218d567727c1d040d01575685e7f9b18052fd68a59c9f61fe5d9/yarl-1.18.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:96404e8d5e1bbe36bdaa84ef89dc36f0e75939e060ca5cd45451aba01db02902", size = 347257 }, - { url = "https://files.pythonhosted.org/packages/36/0b/33a093b0e13bb8cd0f27301779661ff325270b6644929001f8f33307357d/yarl-1.18.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a0509475d714df8f6d498935b3f307cd122c4ca76f7d426c7e1bb791bcd87eda", size = 359735 }, - { url = "https://files.pythonhosted.org/packages/a8/92/dcc0b37c48632e71ffc2b5f8b0509347a0bde55ab5862ff755dce9dd56c4/yarl-1.18.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:1ff116f0285b5c8b3b9a2680aeca29a858b3b9e0402fc79fd850b32c2bcb9f8b", size = 365982 }, - { url = "https://files.pythonhosted.org/packages/0e/39/30e2a24a7a6c628dccb13eb6c4a03db5f6cd1eb2c6cda56a61ddef764c11/yarl-1.18.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e2580c1d7e66e6d29d6e11855e3b1c6381971e0edd9a5066e6c14d79bc8967af", size = 360128 }, - { url = "https://files.pythonhosted.org/packages/76/13/12b65dca23b1fb8ae44269a4d24048fd32ac90b445c985b0a46fdfa30cfe/yarl-1.18.0-cp313-cp313-win32.whl", hash = "sha256:14408cc4d34e202caba7b5ac9cc84700e3421a9e2d1b157d744d101b061a4a88", size = 309888 }, - { url = "https://files.pythonhosted.org/packages/f6/60/478d3d41a4bf0b9e7dca74d870d114e775d1ff7156b7d1e0e9972e8f97fd/yarl-1.18.0-cp313-cp313-win_amd64.whl", hash = "sha256:1db1537e9cb846eb0ff206eac667f627794be8b71368c1ab3207ec7b6f8c5afc", size = 315459 }, - { url = "https://files.pythonhosted.org/packages/30/9c/3f7ab894a37b1520291247cbc9ea6756228d098dae5b37eec848d404a204/yarl-1.18.0-py3-none-any.whl", hash = "sha256:dbf53db46f7cf176ee01d8d98c39381440776fcda13779d269a8ba664f69bec0", size = 44840 }, +sdist = { url = "https://files.pythonhosted.org/packages/b7/9d/4b94a8e6d2b51b599516a5cb88e5bc99b4d8d4583e468057eaa29d5f0918/yarl-1.18.3.tar.gz", hash = "sha256:ac1801c45cbf77b6c99242eeff4fffb5e4e73a800b5c4ad4fc0be5def634d2e1", size = 181062 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/98/e005bc608765a8a5569f58e650961314873c8469c333616eb40bff19ae97/yarl-1.18.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7df647e8edd71f000a5208fe6ff8c382a1de8edfbccdbbfe649d263de07d8c34", size = 141458 }, + { url = "https://files.pythonhosted.org/packages/df/5d/f8106b263b8ae8a866b46d9be869ac01f9b3fb7f2325f3ecb3df8003f796/yarl-1.18.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c69697d3adff5aa4f874b19c0e4ed65180ceed6318ec856ebc423aa5850d84f7", size = 94365 }, + { url = "https://files.pythonhosted.org/packages/56/3e/d8637ddb9ba69bf851f765a3ee288676f7cf64fb3be13760c18cbc9d10bd/yarl-1.18.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:602d98f2c2d929f8e697ed274fbadc09902c4025c5a9963bf4e9edfc3ab6f7ed", size = 92181 }, + { url = "https://files.pythonhosted.org/packages/76/f9/d616a5c2daae281171de10fba41e1c0e2d8207166fc3547252f7d469b4e1/yarl-1.18.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c654d5207c78e0bd6d749f6dae1dcbbfde3403ad3a4b11f3c5544d9906969dde", size = 315349 }, + { url = "https://files.pythonhosted.org/packages/bb/b4/3ea5e7b6f08f698b3769a06054783e434f6d59857181b5c4e145de83f59b/yarl-1.18.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5094d9206c64181d0f6e76ebd8fb2f8fe274950a63890ee9e0ebfd58bf9d787b", size = 330494 }, + { url = "https://files.pythonhosted.org/packages/55/f1/e0fc810554877b1b67420568afff51b967baed5b53bcc983ab164eebf9c9/yarl-1.18.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35098b24e0327fc4ebdc8ffe336cee0a87a700c24ffed13161af80124b7dc8e5", size = 326927 }, + { url = "https://files.pythonhosted.org/packages/a9/42/b1753949b327b36f210899f2dd0a0947c0c74e42a32de3f8eb5c7d93edca/yarl-1.18.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3236da9272872443f81fedc389bace88408f64f89f75d1bdb2256069a8730ccc", size = 319703 }, + { url = "https://files.pythonhosted.org/packages/f0/6d/e87c62dc9635daefb064b56f5c97df55a2e9cc947a2b3afd4fd2f3b841c7/yarl-1.18.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2c08cc9b16f4f4bc522771d96734c7901e7ebef70c6c5c35dd0f10845270bcd", size = 310246 }, + { url = "https://files.pythonhosted.org/packages/e3/ef/e2e8d1785cdcbd986f7622d7f0098205f3644546da7919c24b95790ec65a/yarl-1.18.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80316a8bd5109320d38eef8833ccf5f89608c9107d02d2a7f985f98ed6876990", size = 319730 }, + { url = "https://files.pythonhosted.org/packages/fc/15/8723e22345bc160dfde68c4b3ae8b236e868f9963c74015f1bc8a614101c/yarl-1.18.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c1e1cc06da1491e6734f0ea1e6294ce00792193c463350626571c287c9a704db", size = 321681 }, + { url = "https://files.pythonhosted.org/packages/86/09/bf764e974f1516efa0ae2801494a5951e959f1610dd41edbfc07e5e0f978/yarl-1.18.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fea09ca13323376a2fdfb353a5fa2e59f90cd18d7ca4eaa1fd31f0a8b4f91e62", size = 324812 }, + { url = "https://files.pythonhosted.org/packages/f6/4c/20a0187e3b903c97d857cf0272d687c1b08b03438968ae8ffc50fe78b0d6/yarl-1.18.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e3b9fd71836999aad54084906f8663dffcd2a7fb5cdafd6c37713b2e72be1760", size = 337011 }, + { url = "https://files.pythonhosted.org/packages/c9/71/6244599a6e1cc4c9f73254a627234e0dad3883ece40cc33dce6265977461/yarl-1.18.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:757e81cae69244257d125ff31663249b3013b5dc0a8520d73694aed497fb195b", size = 338132 }, + { url = "https://files.pythonhosted.org/packages/af/f5/e0c3efaf74566c4b4a41cb76d27097df424052a064216beccae8d303c90f/yarl-1.18.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b1771de9944d875f1b98a745bc547e684b863abf8f8287da8466cf470ef52690", size = 331849 }, + { url = "https://files.pythonhosted.org/packages/8a/b8/3d16209c2014c2f98a8f658850a57b716efb97930aebf1ca0d9325933731/yarl-1.18.3-cp310-cp310-win32.whl", hash = "sha256:8874027a53e3aea659a6d62751800cf6e63314c160fd607489ba5c2edd753cf6", size = 84309 }, + { url = "https://files.pythonhosted.org/packages/fd/b7/2e9a5b18eb0fe24c3a0e8bae994e812ed9852ab4fd067c0107fadde0d5f0/yarl-1.18.3-cp310-cp310-win_amd64.whl", hash = "sha256:93b2e109287f93db79210f86deb6b9bbb81ac32fc97236b16f7433db7fc437d8", size = 90484 }, + { url = "https://files.pythonhosted.org/packages/40/93/282b5f4898d8e8efaf0790ba6d10e2245d2c9f30e199d1a85cae9356098c/yarl-1.18.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8503ad47387b8ebd39cbbbdf0bf113e17330ffd339ba1144074da24c545f0069", size = 141555 }, + { url = "https://files.pythonhosted.org/packages/6d/9c/0a49af78df099c283ca3444560f10718fadb8a18dc8b3edf8c7bd9fd7d89/yarl-1.18.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:02ddb6756f8f4517a2d5e99d8b2f272488e18dd0bfbc802f31c16c6c20f22193", size = 94351 }, + { url = "https://files.pythonhosted.org/packages/5a/a1/205ab51e148fdcedad189ca8dd587794c6f119882437d04c33c01a75dece/yarl-1.18.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:67a283dd2882ac98cc6318384f565bffc751ab564605959df4752d42483ad889", size = 92286 }, + { url = "https://files.pythonhosted.org/packages/ed/fe/88b690b30f3f59275fb674f5f93ddd4a3ae796c2b62e5bb9ece8a4914b83/yarl-1.18.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d980e0325b6eddc81331d3f4551e2a333999fb176fd153e075c6d1c2530aa8a8", size = 340649 }, + { url = "https://files.pythonhosted.org/packages/07/eb/3b65499b568e01f36e847cebdc8d7ccb51fff716dbda1ae83c3cbb8ca1c9/yarl-1.18.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b643562c12680b01e17239be267bc306bbc6aac1f34f6444d1bded0c5ce438ca", size = 356623 }, + { url = "https://files.pythonhosted.org/packages/33/46/f559dc184280b745fc76ec6b1954de2c55595f0ec0a7614238b9ebf69618/yarl-1.18.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c017a3b6df3a1bd45b9fa49a0f54005e53fbcad16633870104b66fa1a30a29d8", size = 354007 }, + { url = "https://files.pythonhosted.org/packages/af/ba/1865d85212351ad160f19fb99808acf23aab9a0f8ff31c8c9f1b4d671fc9/yarl-1.18.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75674776d96d7b851b6498f17824ba17849d790a44d282929c42dbb77d4f17ae", size = 344145 }, + { url = "https://files.pythonhosted.org/packages/94/cb/5c3e975d77755d7b3d5193e92056b19d83752ea2da7ab394e22260a7b824/yarl-1.18.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ccaa3a4b521b780a7e771cc336a2dba389a0861592bbce09a476190bb0c8b4b3", size = 336133 }, + { url = "https://files.pythonhosted.org/packages/19/89/b77d3fd249ab52a5c40859815765d35c91425b6bb82e7427ab2f78f5ff55/yarl-1.18.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2d06d3005e668744e11ed80812e61efd77d70bb7f03e33c1598c301eea20efbb", size = 347967 }, + { url = "https://files.pythonhosted.org/packages/35/bd/f6b7630ba2cc06c319c3235634c582a6ab014d52311e7d7c22f9518189b5/yarl-1.18.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:9d41beda9dc97ca9ab0b9888cb71f7539124bc05df02c0cff6e5acc5a19dcc6e", size = 346397 }, + { url = "https://files.pythonhosted.org/packages/18/1a/0b4e367d5a72d1f095318344848e93ea70da728118221f84f1bf6c1e39e7/yarl-1.18.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ba23302c0c61a9999784e73809427c9dbedd79f66a13d84ad1b1943802eaaf59", size = 350206 }, + { url = "https://files.pythonhosted.org/packages/b5/cf/320fff4367341fb77809a2d8d7fe75b5d323a8e1b35710aafe41fdbf327b/yarl-1.18.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6748dbf9bfa5ba1afcc7556b71cda0d7ce5f24768043a02a58846e4a443d808d", size = 362089 }, + { url = "https://files.pythonhosted.org/packages/57/cf/aadba261d8b920253204085268bad5e8cdd86b50162fcb1b10c10834885a/yarl-1.18.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0b0cad37311123211dc91eadcb322ef4d4a66008d3e1bdc404808992260e1a0e", size = 366267 }, + { url = "https://files.pythonhosted.org/packages/54/58/fb4cadd81acdee6dafe14abeb258f876e4dd410518099ae9a35c88d8097c/yarl-1.18.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0fb2171a4486bb075316ee754c6d8382ea6eb8b399d4ec62fde2b591f879778a", size = 359141 }, + { url = "https://files.pythonhosted.org/packages/9a/7a/4c571597589da4cd5c14ed2a0b17ac56ec9ee7ee615013f74653169e702d/yarl-1.18.3-cp311-cp311-win32.whl", hash = "sha256:61b1a825a13bef4a5f10b1885245377d3cd0bf87cba068e1d9a88c2ae36880e1", size = 84402 }, + { url = "https://files.pythonhosted.org/packages/ae/7b/8600250b3d89b625f1121d897062f629883c2f45339623b69b1747ec65fa/yarl-1.18.3-cp311-cp311-win_amd64.whl", hash = "sha256:b9d60031cf568c627d028239693fd718025719c02c9f55df0a53e587aab951b5", size = 91030 }, + { url = "https://files.pythonhosted.org/packages/33/85/bd2e2729752ff4c77338e0102914897512e92496375e079ce0150a6dc306/yarl-1.18.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1dd4bdd05407ced96fed3d7f25dbbf88d2ffb045a0db60dbc247f5b3c5c25d50", size = 142644 }, + { url = "https://files.pythonhosted.org/packages/ff/74/1178322cc0f10288d7eefa6e4a85d8d2e28187ccab13d5b844e8b5d7c88d/yarl-1.18.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7c33dd1931a95e5d9a772d0ac5e44cac8957eaf58e3c8da8c1414de7dd27c576", size = 94962 }, + { url = "https://files.pythonhosted.org/packages/be/75/79c6acc0261e2c2ae8a1c41cf12265e91628c8c58ae91f5ff59e29c0787f/yarl-1.18.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:25b411eddcfd56a2f0cd6a384e9f4f7aa3efee14b188de13048c25b5e91f1640", size = 92795 }, + { url = "https://files.pythonhosted.org/packages/6b/32/927b2d67a412c31199e83fefdce6e645247b4fb164aa1ecb35a0f9eb2058/yarl-1.18.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:436c4fc0a4d66b2badc6c5fc5ef4e47bb10e4fd9bf0c79524ac719a01f3607c2", size = 332368 }, + { url = "https://files.pythonhosted.org/packages/19/e5/859fca07169d6eceeaa4fde1997c91d8abde4e9a7c018e371640c2da2b71/yarl-1.18.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e35ef8683211db69ffe129a25d5634319a677570ab6b2eba4afa860f54eeaf75", size = 342314 }, + { url = "https://files.pythonhosted.org/packages/08/75/76b63ccd91c9e03ab213ef27ae6add2e3400e77e5cdddf8ed2dbc36e3f21/yarl-1.18.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84b2deecba4a3f1a398df819151eb72d29bfeb3b69abb145a00ddc8d30094512", size = 341987 }, + { url = "https://files.pythonhosted.org/packages/1a/e1/a097d5755d3ea8479a42856f51d97eeff7a3a7160593332d98f2709b3580/yarl-1.18.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00e5a1fea0fd4f5bfa7440a47eff01d9822a65b4488f7cff83155a0f31a2ecba", size = 336914 }, + { url = "https://files.pythonhosted.org/packages/0b/42/e1b4d0e396b7987feceebe565286c27bc085bf07d61a59508cdaf2d45e63/yarl-1.18.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0e883008013c0e4aef84dcfe2a0b172c4d23c2669412cf5b3371003941f72bb", size = 325765 }, + { url = "https://files.pythonhosted.org/packages/7e/18/03a5834ccc9177f97ca1bbb245b93c13e58e8225276f01eedc4cc98ab820/yarl-1.18.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5a3f356548e34a70b0172d8890006c37be92995f62d95a07b4a42e90fba54272", size = 344444 }, + { url = "https://files.pythonhosted.org/packages/c8/03/a713633bdde0640b0472aa197b5b86e90fbc4c5bc05b727b714cd8a40e6d/yarl-1.18.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ccd17349166b1bee6e529b4add61727d3f55edb7babbe4069b5764c9587a8cc6", size = 340760 }, + { url = "https://files.pythonhosted.org/packages/eb/99/f6567e3f3bbad8fd101886ea0276c68ecb86a2b58be0f64077396cd4b95e/yarl-1.18.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b958ddd075ddba5b09bb0be8a6d9906d2ce933aee81100db289badbeb966f54e", size = 346484 }, + { url = "https://files.pythonhosted.org/packages/8e/a9/84717c896b2fc6cb15bd4eecd64e34a2f0a9fd6669e69170c73a8b46795a/yarl-1.18.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c7d79f7d9aabd6011004e33b22bc13056a3e3fb54794d138af57f5ee9d9032cb", size = 359864 }, + { url = "https://files.pythonhosted.org/packages/1e/2e/d0f5f1bef7ee93ed17e739ec8dbcb47794af891f7d165fa6014517b48169/yarl-1.18.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4891ed92157e5430874dad17b15eb1fda57627710756c27422200c52d8a4e393", size = 364537 }, + { url = "https://files.pythonhosted.org/packages/97/8a/568d07c5d4964da5b02621a517532adb8ec5ba181ad1687191fffeda0ab6/yarl-1.18.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ce1af883b94304f493698b00d0f006d56aea98aeb49d75ec7d98cd4a777e9285", size = 357861 }, + { url = "https://files.pythonhosted.org/packages/7d/e3/924c3f64b6b3077889df9a1ece1ed8947e7b61b0a933f2ec93041990a677/yarl-1.18.3-cp312-cp312-win32.whl", hash = "sha256:f91c4803173928a25e1a55b943c81f55b8872f0018be83e3ad4938adffb77dd2", size = 84097 }, + { url = "https://files.pythonhosted.org/packages/34/45/0e055320daaabfc169b21ff6174567b2c910c45617b0d79c68d7ab349b02/yarl-1.18.3-cp312-cp312-win_amd64.whl", hash = "sha256:7e2ee16578af3b52ac2f334c3b1f92262f47e02cc6193c598502bd46f5cd1477", size = 90399 }, + { url = "https://files.pythonhosted.org/packages/30/c7/c790513d5328a8390be8f47be5d52e141f78b66c6c48f48d241ca6bd5265/yarl-1.18.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:90adb47ad432332d4f0bc28f83a5963f426ce9a1a8809f5e584e704b82685dcb", size = 140789 }, + { url = "https://files.pythonhosted.org/packages/30/aa/a2f84e93554a578463e2edaaf2300faa61c8701f0898725842c704ba5444/yarl-1.18.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:913829534200eb0f789d45349e55203a091f45c37a2674678744ae52fae23efa", size = 94144 }, + { url = "https://files.pythonhosted.org/packages/c6/fc/d68d8f83714b221a85ce7866832cba36d7c04a68fa6a960b908c2c84f325/yarl-1.18.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ef9f7768395923c3039055c14334ba4d926f3baf7b776c923c93d80195624782", size = 91974 }, + { url = "https://files.pythonhosted.org/packages/56/4e/d2563d8323a7e9a414b5b25341b3942af5902a2263d36d20fb17c40411e2/yarl-1.18.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88a19f62ff30117e706ebc9090b8ecc79aeb77d0b1f5ec10d2d27a12bc9f66d0", size = 333587 }, + { url = "https://files.pythonhosted.org/packages/25/c9/cfec0bc0cac8d054be223e9f2c7909d3e8442a856af9dbce7e3442a8ec8d/yarl-1.18.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e17c9361d46a4d5addf777c6dd5eab0715a7684c2f11b88c67ac37edfba6c482", size = 344386 }, + { url = "https://files.pythonhosted.org/packages/ab/5d/4c532190113b25f1364d25f4c319322e86232d69175b91f27e3ebc2caf9a/yarl-1.18.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a74a13a4c857a84a845505fd2d68e54826a2cd01935a96efb1e9d86c728e186", size = 345421 }, + { url = "https://files.pythonhosted.org/packages/23/d1/6cdd1632da013aa6ba18cee4d750d953104a5e7aac44e249d9410a972bf5/yarl-1.18.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41f7ce59d6ee7741af71d82020346af364949314ed3d87553763a2df1829cc58", size = 339384 }, + { url = "https://files.pythonhosted.org/packages/9a/c4/6b3c39bec352e441bd30f432cda6ba51681ab19bb8abe023f0d19777aad1/yarl-1.18.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f52a265001d830bc425f82ca9eabda94a64a4d753b07d623a9f2863fde532b53", size = 326689 }, + { url = "https://files.pythonhosted.org/packages/23/30/07fb088f2eefdc0aa4fc1af4e3ca4eb1a3aadd1ce7d866d74c0f124e6a85/yarl-1.18.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:82123d0c954dc58db301f5021a01854a85bf1f3bb7d12ae0c01afc414a882ca2", size = 345453 }, + { url = "https://files.pythonhosted.org/packages/63/09/d54befb48f9cd8eec43797f624ec37783a0266855f4930a91e3d5c7717f8/yarl-1.18.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:2ec9bbba33b2d00999af4631a3397d1fd78290c48e2a3e52d8dd72db3a067ac8", size = 341872 }, + { url = "https://files.pythonhosted.org/packages/91/26/fd0ef9bf29dd906a84b59f0cd1281e65b0c3e08c6aa94b57f7d11f593518/yarl-1.18.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:fbd6748e8ab9b41171bb95c6142faf068f5ef1511935a0aa07025438dd9a9bc1", size = 347497 }, + { url = "https://files.pythonhosted.org/packages/d9/b5/14ac7a256d0511b2ac168d50d4b7d744aea1c1aa20c79f620d1059aab8b2/yarl-1.18.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:877d209b6aebeb5b16c42cbb377f5f94d9e556626b1bfff66d7b0d115be88d0a", size = 359981 }, + { url = "https://files.pythonhosted.org/packages/ca/b3/d493221ad5cbd18bc07e642894030437e405e1413c4236dd5db6e46bcec9/yarl-1.18.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b464c4ab4bfcb41e3bfd3f1c26600d038376c2de3297760dfe064d2cb7ea8e10", size = 366229 }, + { url = "https://files.pythonhosted.org/packages/04/56/6a3e2a5d9152c56c346df9b8fb8edd2c8888b1e03f96324d457e5cf06d34/yarl-1.18.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8d39d351e7faf01483cc7ff7c0213c412e38e5a340238826be7e0e4da450fdc8", size = 360383 }, + { url = "https://files.pythonhosted.org/packages/fd/b7/4b3c7c7913a278d445cc6284e59b2e62fa25e72758f888b7a7a39eb8423f/yarl-1.18.3-cp313-cp313-win32.whl", hash = "sha256:61ee62ead9b68b9123ec24bc866cbef297dd266175d53296e2db5e7f797f902d", size = 310152 }, + { url = "https://files.pythonhosted.org/packages/f5/d5/688db678e987c3e0fb17867970700b92603cadf36c56e5fb08f23e822a0c/yarl-1.18.3-cp313-cp313-win_amd64.whl", hash = "sha256:578e281c393af575879990861823ef19d66e2b1d0098414855dd367e234f5b3c", size = 315723 }, + { url = "https://files.pythonhosted.org/packages/f5/4b/a06e0ec3d155924f77835ed2d167ebd3b211a7b0853da1cf8d8414d784ef/yarl-1.18.3-py3-none-any.whl", hash = "sha256:b57f4f58099328dfb26c6a771d09fb20dbbae81d20cfb66141251ea063bd101b", size = 45109 }, ] [[package]] From cce6fe313e93f92b9929ffe53140568d85430307 Mon Sep 17 00:00:00 2001 From: vikram-dagger <112123850+vikram-dagger@users.noreply.github.com> Date: Tue, 10 Dec 2024 09:09:34 +0530 Subject: [PATCH 11/35] docs: Update deps page for dagger uninstall command (#9114) * docs: Update deps page for dagger uninstall command Signed-off-by: Vikram Vaswani * Updated text Signed-off-by: Vikram Vaswani --------- Signed-off-by: Vikram Vaswani --- docs/current_docs/api/module-dependencies.mdx | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/current_docs/api/module-dependencies.mdx b/docs/current_docs/api/module-dependencies.mdx index 066e110d3d..637ec40f19 100644 --- a/docs/current_docs/api/module-dependencies.mdx +++ b/docs/current_docs/api/module-dependencies.mdx @@ -6,6 +6,8 @@ import TabItem from '@theme/TabItem'; # Module Dependencies +## Installation + You can call Dagger Functions from any other Dagger module in your own Dagger module simply by adding it as a module dependency with `dagger install`, as in the following example: ```sh @@ -107,3 +109,14 @@ dagger install ./path/to/module :::note Installing a module using a local path (relative or absolute) is only possible if your module is within the repository root (for Git repositories) or the directory containing the `dagger.json` file (for all other cases). ::: + +## Uninstallation + +To remove a dependency from your Dagger module, use the `dagger uninstall` command. The `dagger uninstall` command can be passed either a remote repository reference or a local module name. + +The commands below are equivalent: + +```sh +dagger uninstall hello +dagger uninstall github.com/shykes/daggerverse/hello +``` From fb89f5a530ec614746ba7ebe31bd24846026707a Mon Sep 17 00:00:00 2001 From: Vasek - Tom C Date: Tue, 10 Dec 2024 11:25:14 +0100 Subject: [PATCH 12/35] fix: typescript SDK codegen unit test (#9155) Signed-off-by: Tom Chauveau Co-authored-by: Tom Chauveau --- .../typescript/templates/src/method.ts.gtpl | 11 ++- .../src/testdata/object_test_want.ts | 20 +++--- .../src/testdata/objects_test_want.ts | 68 +++++++------------ 3 files changed, 39 insertions(+), 60 deletions(-) diff --git a/cmd/codegen/generator/typescript/templates/src/method.ts.gtpl b/cmd/codegen/generator/typescript/templates/src/method.ts.gtpl index 34c750c575..b73e094afb 100644 --- a/cmd/codegen/generator/typescript/templates/src/method.ts.gtpl +++ b/cmd/codegen/generator/typescript/templates/src/method.ts.gtpl @@ -39,10 +39,10 @@ {{ "" -}} {{- end }} - const ctx = this._ctx.select( - "{{ .Name }}", + const ctx = this._ctx.select( + "{{ .Name }}", {{- if or $required $optionals }} - { {{""}} + { {{""}} {{- with $required }} {{- template "call_args" $required }} {{- end }} @@ -52,9 +52,8 @@ ...opts {{- end -}} {{- if gt (len $enums) 0 -}}, __metadata: metadata{{- end -}} -{{""}} }, - {{- end }} - ) +{{""}} },{{- end }} + ) {{- if .TypeRef }} return new {{ .TypeRef | FormatOutputType }}(ctx) diff --git a/cmd/codegen/generator/typescript/templates/src/testdata/object_test_want.ts b/cmd/codegen/generator/typescript/templates/src/testdata/object_test_want.ts index a1300b3710..4d17a7c526 100644 --- a/cmd/codegen/generator/typescript/templates/src/testdata/object_test_want.ts +++ b/cmd/codegen/generator/typescript/templates/src/testdata/object_test_want.ts @@ -5,22 +5,18 @@ export class Container extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[], ctx: Context }, + ctx?: Context, ) { - super(parent) + super(ctx) } exec = (opts?: ContainerExecOpts): Container => { - return new Container({ - queryTree: [ - ...this._queryTree, - { - operation: "exec", - args: { ...opts }, - }, - ], - ctx: this._ctx, - }) + + const ctx = this._ctx.select( + "exec", + { ...opts }, + ) + return new Container(ctx) } /** diff --git a/cmd/codegen/generator/typescript/templates/src/testdata/objects_test_want.ts b/cmd/codegen/generator/typescript/templates/src/testdata/objects_test_want.ts index bdb7c9208e..1766fda39a 100644 --- a/cmd/codegen/generator/typescript/templates/src/testdata/objects_test_want.ts +++ b/cmd/codegen/generator/typescript/templates/src/testdata/objects_test_want.ts @@ -9,10 +9,10 @@ export class CacheVolume extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[], ctx: Context }, + ctx?: Context, _id?: CacheVolumeID, ) { - super(parent) + super(ctx) this._id = _id } @@ -21,16 +21,12 @@ export class CacheVolume extends BaseClient { return this._id } - const response: Awaited = await computeQuery( - [ - ...this._queryTree, - { - operation: "id", - }, - ], - await this._ctx.connection() + const ctx = this._ctx.select( + "id", ) + const response: Awaited = await ctx.execute() + return response } @@ -45,9 +41,9 @@ export class Host extends BaseClient { * Constructor is used for internal usage only, do not create object from it. */ constructor( - parent?: { queryTree?: QueryTree[], ctx: Context }, + ctx?: Context, ) { - super(parent) + super(ctx) } @@ -55,47 +51,35 @@ export class Host extends BaseClient { * Access a directory on the host */ directory = (path: string, opts?: HostDirectoryOpts): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "directory", - args: { path, ...opts }, - }, - ], - ctx: this._ctx, - }) + + const ctx = this._ctx.select( + "directory", + { path, ...opts }, + ) + return new Directory(ctx) } /** * Lookup the value of an environment variable. Null if the variable is not available. */ envVariable = (name: string): HostVariable => { - return new HostVariable({ - queryTree: [ - ...this._queryTree, - { - operation: "envVariable", - args: { name }, - }, - ], - ctx: this._ctx, - }) + + const ctx = this._ctx.select( + "envVariable", + { name }, + ) + return new HostVariable(ctx) } /** * The current working directory on the host */ workdir = (opts?: HostWorkdirOpts): Directory => { - return new Directory({ - queryTree: [ - ...this._queryTree, - { - operation: "workdir", - args: { ...opts }, - }, - ], - ctx: this._ctx, - }) + + const ctx = this._ctx.select( + "workdir", + { ...opts }, + ) + return new Directory(ctx) } } From 521708bbd02de64d48956e88f54d201de192bbfa Mon Sep 17 00:00:00 2001 From: Helder Correia <174525+helderco@users.noreply.github.com> Date: Tue, 10 Dec 2024 10:28:48 -0100 Subject: [PATCH 13/35] python: remove deprecated index-url in tool.uv (#9127) * python: remove deprecated index-url in tool.uv Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com> * Add change log Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com> --------- Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com> --- core/integration/module_python_test.go | 43 ------------------- .../unreleased/Breaking-20241209-120336.yaml | 9 ++++ sdk/python/runtime/discovery.go | 6 --- sdk/python/runtime/extension.go | 7 --- 4 files changed, 9 insertions(+), 56 deletions(-) create mode 100644 sdk/python/.changes/unreleased/Breaking-20241209-120336.yaml diff --git a/core/integration/module_python_test.go b/core/integration/module_python_test.go index 9064d20e53..6063ed198c 100644 --- a/core/integration/module_python_test.go +++ b/core/integration/module_python_test.go @@ -899,49 +899,6 @@ class Test: require.Equal(t, "https://test.pypi.org/simple\nhttps://pypi.org/simple\n", out) }) - t.Run("backwards compat", func(ctx context.Context, t *testctx.T) { - c := connect(ctx, t) - - out, err := daggerCliBase(t, c). - With(source). - With(pyprojectExtra(nil, ` - [tool.uv] - index-url = "https://test.pypi.org/simple" - extra-index-url = "https://pypi.org/simple" - `)). - With(daggerInitPython()). - With(daggerCall("urls")). - Stdout(ctx) - - require.NoError(t, err) - require.Equal(t, "https://test.pypi.org/simple\nhttps://pypi.org/simple\n", out) - }) - - t.Run("preference", func(ctx context.Context, t *testctx.T) { - c := connect(ctx, t) - - out, err := daggerCliBase(t, c). - With(source). - With(pyprojectExtra(nil, ` - [tool.uv] - index-url = "https://test.example.org/simple" - extra-index-url = "https://example.org/simple" - - [[tool.uv.index]] - url = "https://test.pypi.org/simple" - default = true - - [[tool.uv.index]] - url = "https://pypi.org/simple" - `)). - With(daggerInitPython()). - With(daggerCall("urls")). - Stdout(ctx) - - require.NoError(t, err) - require.Equal(t, "https://test.pypi.org/simple\nhttps://pypi.org/simple\n", out) - }) - t.Run("without", func(ctx context.Context, t *testctx.T) { c := connect(ctx, t) diff --git a/sdk/python/.changes/unreleased/Breaking-20241209-120336.yaml b/sdk/python/.changes/unreleased/Breaking-20241209-120336.yaml new file mode 100644 index 0000000000..a82a1bf857 --- /dev/null +++ b/sdk/python/.changes/unreleased/Breaking-20241209-120336.yaml @@ -0,0 +1,9 @@ +kind: Breaking +body: | + Removed the deprecated `index-url` and `index-extral-url` settings under `[tool.uv]` + + These settings were deprecated in Dagger [v0.14.0](https://github.com/dagger/dagger/releases?q=tag%3Asdk%2Fpython%2Fv0) since uv [v0.4.23](https://github.com/astral-sh/uv/releases/tag/0.4.23) replaced them with the `[[tool.uv.index]]` table. See [Package indexes](https://docs.astral.sh/uv/configuration/indexes/) for the full documentation. +time: 2024-12-09T12:03:36.085711-01:00 +custom: + Author: helderco + PR: "9127" diff --git a/sdk/python/runtime/discovery.go b/sdk/python/runtime/discovery.go index 72171ca6ff..fd7a640448 100644 --- a/sdk/python/runtime/discovery.go +++ b/sdk/python/runtime/discovery.go @@ -29,12 +29,6 @@ type UvConfig struct { // Index is a list of uv index configurations. // Ssee [uv v0.4.23](https://github.com/astral-sh/uv/releases/tag/0.4.23) Index []UvIndexConfig `toml:"index"` - - // Deprecated: use "Index" instead - IndexURL string `toml:"index-url"` - // - // Deprecated: use "Index" instead - ExtraIndexURL string `toml:"extra-index-url"` } type UvIndexConfig struct { diff --git a/sdk/python/runtime/extension.go b/sdk/python/runtime/extension.go index eca6ad22bc..1c94e07c8a 100644 --- a/sdk/python/runtime/extension.go +++ b/sdk/python/runtime/extension.go @@ -92,10 +92,6 @@ func (m *PythonSdk) IndexURL() string { return cfg.URL } } - // deprecated - if len(m.Discovery.UvConfig().Index) == 0 { - return m.Discovery.UvConfig().IndexURL - } return "" } @@ -109,9 +105,6 @@ func (m *PythonSdk) ExtraIndexURL() string { return cfg.URL } } - if len(m.Discovery.UvConfig().Index) == 0 { - return m.Discovery.UvConfig().ExtraIndexURL - } return "" } From 93528f6409aa6659c07aa04a0478d23b08aa9cec Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Tue, 10 Dec 2024 11:29:25 +0000 Subject: [PATCH 14/35] Follow-up from changes to `DAGGER_LEAVE_OLD_ENGINE` (#9134) * chore: tidy up docker code Signed-off-by: Justin Chadwell * tests: add tests for old engine removal Signed-off-by: Justin Chadwell * chore: better handle provisioning tests needing lots of space Signed-off-by: Justin Chadwell --------- Signed-off-by: Justin Chadwell --- .github/workflows/engine-and-cli.yml | 2 +- core/integration/container_test.go | 8 +- core/integration/provision_test.go | 123 ++++++++++++++++++++------- engine/client/drivers/docker.go | 69 ++++----------- 4 files changed, 113 insertions(+), 89 deletions(-) diff --git a/.github/workflows/engine-and-cli.yml b/.github/workflows/engine-and-cli.yml index 3d8af085a9..a71f0899c7 100644 --- a/.github/workflows/engine-and-cli.yml +++ b/.github/workflows/engine-and-cli.yml @@ -113,7 +113,7 @@ jobs: - name: "test" uses: ./.github/actions/call with: - function: "test specific --run='TestProvision' --race=true --parallel=16" + function: "test specific --run='TestProvision' --race=true --parallel=1" upload-logs: true test-everything-else: diff --git a/core/integration/container_test.go b/core/integration/container_test.go index c0714357b0..c2ebbc6b21 100644 --- a/core/integration/container_test.go +++ b/core/integration/container_test.go @@ -3632,8 +3632,8 @@ func (ContainerSuite) TestInsecureRootCapabilitesWithService(ctx context.Context // testing it can startup, create containers and bind mount from its filesystem to // them. randID := identity.NewID() - dockerd := dockerService(t, c, "23.0.1", middleware) - out, err := dockerClient(ctx, t, c, dockerd, "23.0.1", middleware). + dockerc := dockerSetup(ctx, t, t.Name(), c, "23.0.1", middleware) + out, err := dockerc. WithExec([]string{"sh", "-e", "-c", strings.Join([]string{ fmt.Sprintf("echo %s-from-outside > /tmp/from-outside", randID), "docker run --rm -v /tmp:/tmp alpine cat /tmp/from-outside", @@ -4213,7 +4213,7 @@ func (ContainerSuite) TestImageLoadCompatibility(ctx context.Context, t *testctx c := connect(ctx, t) for _, dockerVersion := range []string{"20.10", "23.0", "24.0"} { - dockerd := dockerService(t, c, dockerVersion, nil) + dockerc := dockerSetup(ctx, t, t.Name(), c, dockerVersion, nil) for _, mediaType := range []dagger.ImageMediaTypes{dagger.ImageMediaTypesOcimediaTypes, dagger.ImageMediaTypesDockerMediaTypes} { mediaType := mediaType @@ -4231,7 +4231,7 @@ func (ContainerSuite) TestImageLoadCompatibility(ctx context.Context, t *testctx }) require.NoError(t, err) - ctr := dockerClient(ctx, t, c, dockerd, dockerVersion, nil). + ctr := dockerc. WithMountedFile(path.Join("/", path.Base(tmpfile)), c.Host().File(tmpfile)). WithExec([]string{"docker", "load", "-i", "/" + path.Base(tmpfile)}) diff --git a/core/integration/provision_test.go b/core/integration/provision_test.go index 6dd7111c8d..66ade6c66b 100644 --- a/core/integration/provision_test.go +++ b/core/integration/provision_test.go @@ -27,8 +27,7 @@ func TestProvision(t *testing.T) { func (ProvisionSuite) TestDockerDriver(ctx context.Context, t *testctx.T) { t.Run("default image", func(ctx context.Context, t *testctx.T) { c := connect(ctx, t) - dockerd := dockerService(t, c, "", nil) - dockerc := dockerClient(ctx, t, c, dockerd, "", nil) + dockerc := dockerSetup(ctx, t, "provisioner", c, "", nil) dockerc = dockerc.WithMountedFile("/bin/dagger", daggerCliFile(t, c)) out, err := dockerc. @@ -41,8 +40,7 @@ func (ProvisionSuite) TestDockerDriver(ctx context.Context, t *testctx.T) { t.Run("specified image", func(ctx context.Context, t *testctx.T) { c := connect(ctx, t) - dockerd := dockerService(t, c, "", nil) - dockerc := dockerClient(ctx, t, c, dockerd, "", nil) + dockerc := dockerSetup(ctx, t, "provisioner", c, "", nil) dockerc = dockerc.WithMountedFile("/bin/dagger", daggerCliFile(t, c)) version := "v0.14.0" @@ -55,8 +53,7 @@ func (ProvisionSuite) TestDockerDriver(ctx context.Context, t *testctx.T) { t.Run("current image", func(ctx context.Context, t *testctx.T) { c := connect(ctx, t) - dockerd := dockerService(t, c, "", nil) - dockerc := dockerClient(ctx, t, c, dockerd, "", nil) + dockerc := dockerSetup(ctx, t, "provisioner", c, "", nil) dockerc = dockerc.WithMountedFile("/bin/dagger", daggerCliFile(t, c)) dockerc, err := dockerLoadEngine(ctx, c, dockerc, "registry.dagger.io/engine:dev") require.NoError(t, err) @@ -78,8 +75,7 @@ func (ProvisionSuite) TestDockerDriverConfig(ctx context.Context, t *testctx.T) return ctr.WithNewFile("/root/.config/dagger/engine.json", configContents) } - dockerd := dockerService(t, c, "", middleware) - dockerc := dockerClient(ctx, t, c, dockerd, "", middleware) + dockerc := dockerSetup(ctx, t, "provisioner", c, "", middleware) dockerc, err := dockerLoadEngine(ctx, c, dockerc, "registry.dagger.io/engine:dev") require.NoError(t, err) dockerc = dockerc. @@ -101,22 +97,92 @@ func (ProvisionSuite) TestDockerDriverConfig(ctx context.Context, t *testctx.T) require.JSONEq(t, configContents, result) } -func dockerService(t *testctx.T, dag *dagger.Client, dockerVersion string, f func(*dagger.Container) *dagger.Container) *dagger.Service { - tag := "dind" - if dockerVersion != "" { - tag = dockerVersion + "-" + tag +func (ProvisionSuite) TestDockerDriverGarbageCollectEngines(ctx context.Context, t *testctx.T) { + dockerPs := func(ctx context.Context, t *testctx.T, dockerc *dagger.Container) []string { + out, err := dockerc. + WithEnvVariable("CACHEBUSTER", identity.NewID()). + WithExec([]string{"docker", "ps", "-q"}). + Stdout(ctx) + require.NoError(t, err) + out = strings.TrimSpace(out) + if out == "" { + return []string{} + } + return strings.Split(out, "\n") } + t.Run("cleanup", func(ctx context.Context, t *testctx.T) { + c := connect(ctx, t) + dockerc := dockerSetup(ctx, t, "provisioner", c, "", nil) + dockerc = dockerc.WithMountedFile("/bin/dagger", daggerCliFile(t, c)) + + require.Len(t, dockerPs(ctx, t, dockerc), 0) + + version := "v0.13.0" + out, err := dockerc. + WithEnvVariable("_EXPERIMENTAL_DAGGER_RUNNER_HOST", "docker-image://registry.dagger.io/engine:"+version). + WithExec([]string{"dagger", "query"}, dagger.ContainerWithExecOpts{Stdin: "{version}"}).Stdout(ctx) + require.NoError(t, err) + require.JSONEq(t, `{"version":"`+version+`"}`, out) + + require.Len(t, dockerPs(ctx, t, dockerc), 1) + + version = "v0.14.0" + out, err = dockerc. + WithEnvVariable("_EXPERIMENTAL_DAGGER_RUNNER_HOST", "docker-image://registry.dagger.io/engine:"+version). + WithExec([]string{"dagger", "query"}, dagger.ContainerWithExecOpts{Stdin: "{version}"}).Stdout(ctx) + require.NoError(t, err) + require.JSONEq(t, `{"version":"`+version+`"}`, out) + + require.Len(t, dockerPs(ctx, t, dockerc), 1) + }) + + t.Run("no cleanup", func(ctx context.Context, t *testctx.T) { + c := connect(ctx, t) + dockerc := dockerSetup(ctx, t, "provisioner", c, "", nil) + dockerc = dockerc.WithMountedFile("/bin/dagger", daggerCliFile(t, c)) + dockerc = dockerc.WithEnvVariable("DAGGER_LEAVE_OLD_ENGINE", "true") + + require.Len(t, dockerPs(ctx, t, dockerc), 0) + + version := "v0.13.0" + out, err := dockerc. + WithEnvVariable("_EXPERIMENTAL_DAGGER_RUNNER_HOST", "docker-image://registry.dagger.io/engine:"+version). + WithExec([]string{"dagger", "query"}, dagger.ContainerWithExecOpts{Stdin: "{version}"}).Stdout(ctx) + require.NoError(t, err) + require.JSONEq(t, `{"version":"`+version+`"}`, out) + + require.Len(t, dockerPs(ctx, t, dockerc), 1) + + version = "v0.14.0" + out, err = dockerc. + WithEnvVariable("_EXPERIMENTAL_DAGGER_RUNNER_HOST", "docker-image://registry.dagger.io/engine:"+version). + WithExec([]string{"dagger", "query"}, dagger.ContainerWithExecOpts{Stdin: "{version}"}).Stdout(ctx) + require.NoError(t, err) + require.JSONEq(t, `{"version":"`+version+`"}`, out) + + require.Len(t, dockerPs(ctx, t, dockerc), 2) + }) +} + +func dockerSetup(ctx context.Context, t *testctx.T, name string, dag *dagger.Client, dockerVersion string, f func(*dagger.Container) *dagger.Container) *dagger.Container { if f == nil { f = func(ctr *dagger.Container) *dagger.Container { return ctr } } + dockerdTag := "dind" + dockercTag := "cli" + if dockerVersion != "" { + dockerdTag = dockerVersion + "-" + dockerdTag + dockercTag = dockerVersion + "-" + dockercTag + } + port := 4000 - dockerd := dag.Container().From("docker:"+tag). + dockerd := dag.Container().From("docker:"+dockerdTag). With(f). - WithMountedCache("/var/lib/docker", dag.CacheVolume(t.Name()+"-"+dockerVersion+"-docker-lib"), dagger.ContainerWithMountedCacheOpts{ + WithMountedCache("/var/lib/docker", dag.CacheVolume(name+"-"+dockerVersion+"-docker-lib"), dagger.ContainerWithMountedCacheOpts{ Sharing: dagger.CacheSharingModePrivate, }). WithExposedPort(port). @@ -130,35 +196,30 @@ func dockerService(t *testctx.T, dag *dagger.Client, dockerVersion string, f fun InsecureRootCapabilities: true, }, ) - - return dockerd -} - -func dockerClient(ctx context.Context, t *testctx.T, dag *dagger.Client, dockerd *dagger.Service, dockerVersion string, f func(*dagger.Container) *dagger.Container) *dagger.Container { - tag := "cli" - if dockerVersion != "" { - tag = dockerVersion + "-" + tag - } - - if f == nil { - f = func(ctr *dagger.Container) *dagger.Container { - return ctr - } - } + dockerd, err := dockerd.Start(ctx) + require.NoError(t, err) dockerHost, err := dockerd.Endpoint(ctx, dagger.ServiceEndpointOpts{ Scheme: "tcp", }) require.NoError(t, err) - client := dag.Container().From("docker:"+tag). + dockerc := dag.Container().From("docker:"+dockercTag). With(f). With(mountDockerConfig(dag)). WithServiceBinding("docker", dockerd). WithEnvVariable("DOCKER_HOST", dockerHost). WithEnvVariable("CACHEBUSTER", identity.NewID()) - return client + t.Cleanup(func() { + _, err := dockerc.WithExec([]string{"sh", "-c", "docker rm -f $(docker ps -aq); docker system prune --all --volumes; true"}).Sync(ctx) + require.NoError(t, err) + + _, err = dockerd.Stop(ctx) + require.NoError(t, err) + }) + + return dockerc } func dockerLoadEngine(ctx context.Context, dag *dagger.Client, ctr *dagger.Container, engineTag string) (*dagger.Container, error) { diff --git a/engine/client/drivers/docker.go b/engine/client/drivers/docker.go index bdb3c39408..00b654f220 100644 --- a/engine/client/drivers/docker.go +++ b/engine/client/drivers/docker.go @@ -10,6 +10,7 @@ import ( "os" "os/exec" "path/filepath" + "strconv" "strings" "dagger.io/dagger/telemetry" @@ -37,7 +38,8 @@ func init() { // shouldCleanupEngines returns true if old engines should be cleaned up func shouldCleanupEngines() bool { val := os.Getenv("DAGGER_LEAVE_OLD_ENGINE") - return val == "" || val == "0" || strings.ToLower(val) == "false" + b, _ := strconv.ParseBool(val) + return !b } // dockerDriver creates and manages a container, then connects to it @@ -78,11 +80,6 @@ func (d *dockerDriver) create(ctx context.Context, imageRef string, opts *Driver defer telemetry.End(span, func() error { return rerr }) slog := slog.SpanLogger(ctx, InstrumentationLibrary) - // Log environment variable state at creation - slog.Info("checking engine environment", - "DAGGER_LEAVE_OLD_ENGINE", os.Getenv("DAGGER_LEAVE_OLD_ENGINE"), - "shouldCleanup", shouldCleanupEngines()) - id, err := resolveImageID(imageRef) if err != nil { return nil, err @@ -103,17 +100,11 @@ func (d *dockerDriver) create(ctx context.Context, imageRef string, opts *Driver for i, leftoverEngine := range leftoverEngines { // if we already have a container with that name, attempt to start it if leftoverEngine == containerName { - slog.Info("found existing container", "name", containerName) cmd := exec.CommandContext(ctx, "docker", "start", leftoverEngine) if output, err := traceExec(ctx, cmd); err != nil { return nil, errors.Wrapf(err, "failed to start container: %s", output) } - slog.Info("cleaning up other engines after starting existing container", - "current", containerName, - "leftover_count", len(leftoverEngines)-1) - if shouldCleanupEngines() { - garbageCollectEngines(ctx, slog, append(leftoverEngines[:i], leftoverEngines[i+1:]...)) - } + garbageCollectEngines(ctx, slog, append(leftoverEngines[:i], leftoverEngines[i+1:]...)) return connhDocker.Helper(&url.URL{ Scheme: "docker-container", Host: containerName, @@ -151,7 +142,6 @@ func (d *dockerDriver) create(ctx context.Context, imageRef string, opts *Driver // explicitly pass current env vars; if we append more below existing ones like DOCKER_HOST // won't be passed to the cmd cmd.Env = os.Environ() - if opts.DaggerCloudToken != "" { cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", EnvDaggerCloudToken, opts.DaggerCloudToken)) cmd.Args = append(cmd.Args, "-e", EnvDaggerCloudToken) @@ -169,12 +159,10 @@ func (d *dockerDriver) create(ctx context.Context, imageRef string, opts *Driver } } - if shouldCleanupEngines() { - slog.Info("cleaning up old engines after creating new container", - "current", containerName, - "leftover_count", len(leftoverEngines)) - garbageCollectEngines(ctx, slog, leftoverEngines) - } + // garbage collect any other containers with the same name pattern, which + // we assume to be leftover from previous runs of the engine using an older + // version + garbageCollectEngines(ctx, slog, leftoverEngines) return connhDocker.Helper(&url.URL{ Scheme: "docker-container", @@ -205,35 +193,22 @@ func resolveImageID(imageRef string) (string, error) { } func garbageCollectEngines(ctx context.Context, log *slog.Logger, engines []string) { - val := os.Getenv("DAGGER_LEAVE_OLD_ENGINE") - - // Enhanced logging for debugging - log.Info("evaluating engine cleanup", - "raw_env_value", val, - "engineCount", len(engines)) - - // Log each engine being considered - for i, engine := range engines { - log.Info("found engine", - "index", i, - "name", engine) + if !shouldCleanupEngines() { + return } - for _, engine := range engines { if engine == "" { continue } - log.Info("removing engine", - "name", engine, - "env_value", val) - if output, err := traceExec(ctx, exec.CommandContext(ctx, "docker", "rm", "-fv", engine, )); err != nil { - log.Warn("failed to remove container", - "name", engine, - "error", err, - "output", output) + if errors.Is(err, context.Canceled) { + return + } + if !strings.Contains(output, "already in progress") { + log.Warn("failed to remove old container", "container", engine, "error", err) + } } } } @@ -253,10 +228,6 @@ func traceExec(ctx context.Context, cmd *exec.Cmd, opts ...trace.SpanStartOption } func collectLeftoverEngines(ctx context.Context) ([]string, error) { - slog := slog.SpanLogger(ctx, InstrumentationLibrary) - slog.Info("collecting leftover engines", - "DAGGER_LEAVE_OLD_ENGINE", os.Getenv("DAGGER_LEAVE_OLD_ENGINE")) - cmd := exec.CommandContext(ctx, "docker", "ps", "-a", @@ -266,19 +237,11 @@ func collectLeftoverEngines(ctx context.Context) ([]string, error) { ) output, err := traceExec(ctx, cmd) if err != nil { - slog.Error("failed to list containers", - "error", err, - "output", output) return nil, errors.Wrapf(err, "failed to list containers: %s", output) } output = strings.TrimSpace(output) engineNames := strings.Split(output, "\n") - - slog.Info("found engines", - "count", len(engineNames), - "names", engineNames) - return engineNames, err } From 26ec17509f3dcb7b87a08a48d1516c18a0fca638 Mon Sep 17 00:00:00 2001 From: Gerhard Lazu Date: Tue, 10 Dec 2024 11:37:50 +0000 Subject: [PATCH 15/35] ci: Add bump-dagger-version function to daggerverse (#8947) Upgrades Dagger version for Daggerverse in: - GitHub workflows - Daggerverse modules - Daggerverse app - Infra config It also deploys a Daggerverse preview environment with a development version of Dagger (this implies the version that we are upgrading to). This now runs automatically part of the publish workflow. When no `--from` is specified, it looks inside the `.changes` directory and picks the one but last version (n-1). Updated the publish workflow runs-on to only use our own runners. This workflow is never meant to run in forks. Signed-off-by: Gerhard Lazu --- .github/workflows/publish.yml | 28 +++-- RELEASING.md | 5 +- modules/daggerverse/dagger.json | 9 +- modules/daggerverse/main.go | 189 +++++++++++++++++++++++++++----- 4 files changed, 190 insertions(+), 41 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 1cd4d9ec3f..aad4a41535 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -14,7 +14,7 @@ on: # run tests in a PR when an SDK is modified... - ./sdk # ...or when we are - - ./.github/workflows/engine-and-cli-publish.yml + - ./.github/workflows/publish.yml jobs: publish: @@ -72,7 +72,7 @@ jobs: publish-sdk-go: needs: publish - runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-4c' || 'ubuntu-latest' }}" + runs-on: dagger-g2-v0-14-0-4c steps: - uses: actions/checkout@v4 - name: "go publish" @@ -90,7 +90,7 @@ jobs: publish-sdk-php: needs: publish - runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-4c' || 'ubuntu-latest' }}" + runs-on: dagger-g2-v0-14-0-4c steps: - uses: actions/checkout@v4 - name: "php publish" @@ -109,7 +109,7 @@ jobs: publish-sdk-python: needs: publish if: github.ref_name != 'main' - runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-4c' || 'ubuntu-latest' }}" + runs-on: dagger-g2-v0-14-0-4c steps: - uses: actions/checkout@v4 - name: "python publish" @@ -129,7 +129,7 @@ jobs: publish-sdk-typescript: needs: publish if: github.ref_name != 'main' - runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-4c' || 'ubuntu-latest' }}" + runs-on: dagger-g2-v0-14-0-4c steps: - uses: actions/checkout@v4 - name: "typescript publish" @@ -148,7 +148,7 @@ jobs: publish-sdk-elixir: needs: publish if: github.ref_name != 'main' - runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-4c' || 'ubuntu-latest' }}" + runs-on: dagger-g2-v0-14-0-4c steps: - uses: actions/checkout@v4 - name: "elixir publish" @@ -167,7 +167,7 @@ jobs: publish-helm: needs: publish if: github.ref_name != 'main' - runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-4c' || 'ubuntu-latest' }}" + runs-on: dagger-g2-v0-14-0-4c steps: - uses: actions/checkout@v4 - name: "helm publish" @@ -183,6 +183,20 @@ jobs: message: "โ˜ธ๏ธ Helm Chart: https://github.com/${{ github.repository }}/releases/tag/${{ github.ref_name }}" discord-webhook: ${{ secrets.NEW_RELEASE_DISCORD_WEBHOOK }} + daggerverse-bump-dagger: + needs: publish + if: github.ref_name != 'main' + runs-on: dagger-g2-v0-14-0-4c + steps: + - uses: actions/checkout@v4 + - name: "Bump Dagger version in Daggerverse" + uses: ./.github/actions/call + env: + DAGGER_CI_GITHUB_TOKEN: ${{ secrets.DAGGER_CI_GITHUB_TOKEN }} + with: + function: --github-token=env:DAGGER_CI_GITHUB_TOKEN bump-dagger-version --to=${{ github.ref_name }} + module: ./modules/daggerverse + # TODO: daggerize provisioning tests test-provision-macos: name: "Test SDK Provision / macos" diff --git a/RELEASING.md b/RELEASING.md index 088fbed8a2..e18943e471 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -437,8 +437,9 @@ production deployment via Netlify as follows: ## ๐ŸŒŒ Daggerverse โฑ `2mins` -- [ ] Mention in the release thread on Discord that Daggerverse can be updated - to the just-released version. cc @marcosnils @matipan @grouville +- [ ] Merge the newly opened PR in the dagger.io repository (this is created by + the publish workflow). If anything fails, cc the following in the release thread + on Discord: cc @jpadams @kpenfound @matipan @gerhard ## ๐ŸŒฅ๏ธ Dagger Cloud โฑ `2mins` diff --git a/modules/daggerverse/dagger.json b/modules/daggerverse/dagger.json index 1e384de90d..3f8dfb49fa 100644 --- a/modules/daggerverse/dagger.json +++ b/modules/daggerverse/dagger.json @@ -1,13 +1,18 @@ { "name": "daggerverse", + "engineVersion": "v0.14.0", "sdk": "go", "dependencies": [ { "name": "gh", "source": "github.com/sagikazarmark/daggerverse/gh", "pin": "68e9daa611183f5334b4059bac6f4aad62da7a37" + }, + { + "name": "go", + "source": "../go", + "pin": "" } ], - "source": ".", - "engineVersion": "v0.13.6" + "source": "." } diff --git a/modules/daggerverse/main.go b/modules/daggerverse/main.go index 5b771c4cff..2127fb2ecd 100644 --- a/modules/daggerverse/main.go +++ b/modules/daggerverse/main.go @@ -4,71 +4,86 @@ import ( "context" "dagger/daggerverse/internal/dagger" "fmt" + "strings" "time" "github.com/google/go-github/v66/github" ) -type Daggerverse struct{} +type Daggerverse struct { + // +private + Gh *dagger.Gh + // +private + GitHubUser string + // +private + GitHubUsername string + // +private + GitHubUserEmail string + // +private + Repo string +} -// Deploy preview environment running Dagger main: dagger call deploy-preview-with-dagger-main --github-token=env:GITHUB_PAT -func (h *Daggerverse) DeployPreviewWithDaggerMain( +func New( ctx context.Context, + // GitHub Personal Access Token which access to dagger/dagger.io repo githubToken *dagger.Secret, -) error { +) (*Daggerverse, error) { token, err := githubToken.Plaintext(ctx) if err != nil { - return err + return nil, err } // get user config from githubToken ghc := github.NewClient(nil).WithAuthToken(token) user, _, err := ghc.Users.Get(ctx, "") if err != nil { - return err + return nil, err + } + repo := "github.com/dagger/dagger.io" + dgvs := &Daggerverse{ + GitHubUsername: *user.Login, + GitHubUser: *user.Name, + Repo: repo, + Gh: dag.Gh(dagger.GhOpts{ + Token: githubToken, + Repo: repo, + }), } emails, _, err := ghc.Users.ListEmails(ctx, &github.ListOptions{}) if err != nil { - return err + return nil, err } + dgvs.GitHubUserEmail = *emails[0].Email - today := time.Now() - date := today.Format("2006-01-02") - - // clone dagger.io - private repository, requires a github token - repo := "github.com/dagger/dagger.io" - // clone dagger.io - private repository, requires a github token - gh := dag.Gh(dagger.GhOpts{ - Token: githubToken, - Repo: repo, - }) + return dgvs, nil +} +// Deploy preview environment running Dagger main: dagger call --github-token=env:GITHUB_PAT deploy-preview-with-dagger-main +func (h *Daggerverse) DeployPreviewWithDaggerMain( + ctx context.Context, +) error { // make a change so that a new Daggerverse deployment will be created - daggerio := gh.Repo().Clone( - repo, - dagger.GhRepoCloneOpts{ - Args: []string{"--depth=1"}, - }). - WithNewFile("daggerverse/CREATE_PREVIEW_ENVIRONMENT", today.String()) + daggerio := h.clone(). + WithNewFile("daggerverse/CREATE_PREVIEW_ENVIRONMENT", time.Now().String()) - branch := fmt.Sprintf("dgvs-test-with-dagger-main-%s", date) + branch := fmt.Sprintf("dgvs-test-with-dagger-main-%s", h.date()) commitMsg := fmt.Sprintf(`dgvs: Test Dagger Engine main @ %s -daggerverse-checks in GitHub Actions ensures that module crawling works as expected. Should complete within 5 mins.`, date) +daggerverse-checks in GitHub Actions ensures that module crawling works as expected. Should complete within 5 mins.`, h.date()) // open a PR so that it creates a new Daggerverse preview environment running Dagger main - err = gh.WithSource(daggerio). + err := h.Gh.WithSource(daggerio). WithGitExec([]string{"checkout", "-b", branch}). WithGitExec([]string{"add", "daggerverse/CREATE_PREVIEW_ENVIRONMENT"}). - WithGitExec([]string{"config", "user.email", *emails[0].Email}). - WithGitExec([]string{"config", "user.name", *user.Name}). + WithGitExec([]string{"config", "user.email", h.GitHubUserEmail}). + WithGitExec([]string{"config", "user.name", h.GitHubUser}). WithGitExec([]string{"commit", "-am", commitMsg}). - WithGitExec([]string{"push", "--force", "origin", branch}). + WithGitExec([]string{"push", "origin", branch}). PullRequest().Create( ctx, dagger.GhPullRequestCreateOpts{ - Assignees: []string{*user.Login}, + Assignees: []string{h.GitHubUsername}, Fill: true, Labels: []string{"preview", "area/daggerverse"}, Head: branch, @@ -77,3 +92,117 @@ daggerverse-checks in GitHub Actions ensures that module crawling works as expec return err } + +// Bump Dagger version: dagger call --github-token=env:GITHUB_PAT bump-dagger-version --from=0.13.7 --to=0.14.0 +func (h *Daggerverse) BumpDaggerVersion( + ctx context.Context, + // +defaultPath="../../.changes" + releases *dagger.Directory, + // Which version of Dagger are we bumping from - defaults to version n-1 + // +optional + from string, + // Which version of Dagger are we bumping to + to string, +) (err error) { + if from == "" { + from, err = dag.Container().From("alpine"). + WithDirectory("/releases", releases). + WithWorkdir("/releases"). + WithExec([]string{"sh", "-c", "ls v* | awk -F'[v.]' '{ print $2\".\"$3.\".\"$4 }' | sort -V | tail -n 2 | head -n 1"}). + Stdout(ctx) + if err != nil { + return err + } + from = strings.TrimSpace(from) + } + + fromDashed := strings.ReplaceAll(from, ".", "-") + toDashed := strings.ReplaceAll(to, ".", "-") + engineImage := fmt.Sprintf("registry.dagger.io/engine:v%s", to) + + engine := dag.Container().From(engineImage). + WithExposedPort(1234). + WithExec([]string{ + "--addr", "tcp://0.0.0.0:1234", + "--addr", "unix:///var/run/buildkit/buildkitd.sock", + "--network-cidr", "10.12.34.0/24", + }, dagger.ContainerWithExecOpts{ + UseEntrypoint: true, + InsecureRootCapabilities: true, + }).AsService() + + daggerio, err := dag.Container().From(engineImage). + WithDirectory("/dagger.io", h.clone()). + WithWorkdir("/dagger.io"). + WithExec([]string{"sh", "-c", + fmt.Sprintf("find .github/workflows -name '*daggerverse*' -exec sed -i 's/%s/%s/g' {} +", fromDashed, toDashed), + }). + WithExec([]string{"sh", "-c", + fmt.Sprintf("sed -i 's/\\(DaggerVersion\\s*=\\s*\"\\)%s\"/\\1%s\"/' daggerverse/dag/main.go", from, to), + }). + WithServiceBinding("daggerverse-engine", engine). + WithEnvVariable("_EXPERIMENTAL_DAGGER_RUNNER_HOST", "tcp://daggerverse-engine:1234"). + WithExec([]string{"nc", "-vzw", "1", "daggerverse-engine", "1234"}). + WithExec([]string{"dagger", "version"}). + WithExec([]string{"dagger", "core", "version"}). + WithExec([]string{"dagger", "--mod=daggerverse/dag", "develop"}). + WithExec([]string{"dagger", "--mod=daggerverse", "develop"}). + WithExec([]string{"sh", "-c", + fmt.Sprintf("sed -i 's/v[0-9][0-9]*\\.[0-9][0-9]*\\.[0-9][0-9]*/v%s/' infra/ci/*/argocd/daggerverse-preview/appset.yaml", to), + }). + WithExec([]string{"sh", "-c", + fmt.Sprintf("sed -i 's/registry\\.dagger\\.io\\/engine:v[0-9][0-9]*\\.[0-9][0-9]*\\.[0-9][0-9]*/registry\\.dagger\\.io\\/engine:v%s/' infra/ci/*/argocd/daggerverse-preview/manifests/deployment.base.yaml", to), + }). + WithExec([]string{"sh", "-c", + fmt.Sprintf("sed -i 's/registry\\.dagger\\.io\\/engine:v[0-9][0-9]*\\.[0-9][0-9]*\\.[0-9][0-9]*/registry\\.dagger\\.io\\/engine:v%s/' infra/prod/*/argocd/daggerverse/deployment.yaml", to), + }). + Sync(ctx) + if err != nil { + return err + } + + daggerverse, err := dag.Go(daggerio.Directory("daggerverse")).Env(). + WithExec([]string{"go", "get", fmt.Sprintf("dagger.io/dagger@v%s", to)}). + Sync(ctx) + if err != nil { + return err + } + + updated := daggerio. + WithDirectory("/dagger.io/daggerverse", daggerverse.Directory(".")). + Directory("/dagger.io") + + branch := fmt.Sprintf("dgvs-bump-dagger-from-%s-to-%s-with-dagger-main", from, to) + commitMsg := fmt.Sprintf("dgvs: Bump Dagger from %s to %s", from, to) + + err = h.Gh.WithSource(updated). + WithGitExec([]string{"checkout", "-b", branch}). + WithGitExec([]string{"add", ".github", "daggerverse", "infra"}). + WithGitExec([]string{"config", "user.email", h.GitHubUserEmail}). + WithGitExec([]string{"config", "user.name", h.GitHubUser}). + WithGitExec([]string{"commit", "-am", commitMsg}). + WithGitExec([]string{"push", "origin", branch}). + PullRequest().Create( + ctx, + dagger.GhPullRequestCreateOpts{ + Assignees: []string{h.GitHubUsername}, + Fill: true, + Labels: []string{"preview", "area/daggerverse"}, + Head: branch, + }, + ) + + return err +} + +func (h *Daggerverse) date() string { + return time.Now().Format("2006-01-02") +} + +func (h *Daggerverse) clone() *dagger.Directory { + return h.Gh.Repo().Clone( + h.Repo, + dagger.GhRepoCloneOpts{ + Args: []string{"--depth=1"}, + }) +} From 2fbc7dfd14d5c15d9d1a0f8f4f4398aba6029126 Mon Sep 17 00:00:00 2001 From: Helder Correia <174525+helderco@users.noreply.github.com> Date: Tue, 10 Dec 2024 10:59:26 -0100 Subject: [PATCH 16/35] shell: reimplement module loading and execution according to new model (#9097) * shell: load and execute modules with ref alone Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com> * Fix description Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com> * Support .stdlib and .deps Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com> * Reimplement .use as the future .cd Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com> * Update tests Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com> * Fix .core and function call after .stdlib and .deps Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com> * Fix ref in prompt Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com> * Fix dummy core constructor showing Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com> * Remove unused function argument Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com> * Fix .doc when module not loaded Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com> * Rename `--no-load` to `--no-mod` Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com> * Fix issue with constructor overriding core function Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com> * Fix constructor arguments validation Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com> * Limit showing available functions in module doc Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com> * Update tests Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com> * Resolve dependency references using their pinned commit Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com> * Add uninstall builtin Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com> * Add a few explanatory comments Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com> * regen ts Signed-off-by: Justin Chadwell --------- Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com> Signed-off-by: Justin Chadwell Co-authored-by: Justin Chadwell --- cmd/dagger/call.go | 2 +- cmd/dagger/functions.go | 85 +- cmd/dagger/modconf.graphql | 19 + cmd/dagger/module.go | 263 ++++- cmd/dagger/shell.go | 1114 +++++++++++++------- core/integration/module_shell_test.go | 418 ++++++-- core/schema/module.go | 3 + core/schema/modulesource.go | 8 +- docs/docs-graphql/schema.graphqls | 3 + docs/static/api/reference/index.html | 4 + sdk/elixir/lib/dagger/gen/module_source.ex | 9 + sdk/go/dagger.gen.go | 14 + sdk/php/generated/ModuleSource.php | 9 + sdk/python/src/dagger/client/gen.py | 21 + sdk/rust/crates/dagger-sdk/src/gen.rs | 5 + sdk/typescript/src/api/client.gen.ts | 18 + 16 files changed, 1420 insertions(+), 575 deletions(-) create mode 100644 cmd/dagger/modconf.graphql diff --git a/cmd/dagger/call.go b/cmd/dagger/call.go index 2e11680a4d..d50ed66808 100644 --- a/cmd/dagger/call.go +++ b/cmd/dagger/call.go @@ -62,7 +62,7 @@ available functions. GroupID: moduleGroup.ID, RunE: func(cmd *cobra.Command, args []string) error { return withEngine(cmd.Context(), client.Params{}, func(ctx context.Context, engineClient *client.Client) (rerr error) { - mod, err := initializeModule(ctx, engineClient.Dagger()) + mod, err := initializeDefaultModule(ctx, engineClient.Dagger()) if err != nil { return err } diff --git a/cmd/dagger/functions.go b/cmd/dagger/functions.go index 69a06ba51d..e022cafa06 100644 --- a/cmd/dagger/functions.go +++ b/cmd/dagger/functions.go @@ -268,7 +268,7 @@ func (fc *FuncCommand) execute(c *cobra.Command, a []string) (rerr error) { if fc.DisableModuleLoad { mod, err = initializeCore(ctx, fc.c.Dagger()) } else { - mod, err = initializeModule(ctx, fc.c.Dagger()) + mod, err = initializeDefaultModule(ctx, fc.c.Dagger()) } if err != nil { return err @@ -296,89 +296,6 @@ func (fc *FuncCommand) execute(c *cobra.Command, a []string) (rerr error) { return cmd.RunE(cmd, flags) } -// initializeCore loads the core type definitions. -func initializeCore(ctx context.Context, dag *dagger.Client) (rdef *moduleDef, rerr error) { - def := &moduleDef{} - - ctx, loadSpan := Tracer().Start(ctx, "inspecting core types", telemetry.Encapsulate()) - defer telemetry.End(loadSpan, func() error { return rerr }) - - if err := def.loadTypeDefs(ctx, dag); err != nil { - return nil, err - } - - return def, nil -} - -// initializeModule loads the module's type definitions. -func initializeModule(ctx context.Context, dag *dagger.Client) (*moduleDef, error) { - modRef, _ := getExplicitModuleSourceRef() - return maybeInitializeModule(ctx, dag, modRef, false) -} - -// maybeInitializeModule optionally loads the module's type definitions. -func maybeInitializeModule(ctx context.Context, dag *dagger.Client, srcRef string, optional bool) (rdef *moduleDef, rerr error) { - def := &moduleDef{} - - ctx, span := Tracer().Start(ctx, "loading module") - defer telemetry.End(span, func() error { return rerr }) - - resolveCtx, resolveSpan := Tracer().Start(ctx, "finding module configuration", telemetry.Encapsulate()) - defer telemetry.End(resolveSpan, func() error { return rerr }) - - // the user explicitly set the `-m,--mod` flag - modRefSet := srcRef != "" - - if !modRefSet { - srcRef = moduleURLDefault - } - - modConf, err := getModuleConfigurationForSourceRef(resolveCtx, dag, srcRef, true, true) - if err != nil && (modRefSet || !optional) { - return nil, fmt.Errorf("failed to get configured module: %w", err) - } - resolveSpan.End() - - if modConf == nil || !modConf.FullyInitialized() { - return initializeCore(ctx, dag) - } - - def.Source = modConf.Source - mod := modConf.Source.AsModule().Initialize() - - serveCtx, serveSpan := Tracer().Start(ctx, "serving module", telemetry.Encapsulate()) - err = mod.Serve(serveCtx) - telemetry.End(serveSpan, func() error { return err }) - if err != nil { - return nil, fmt.Errorf("failed to serve module: %w", err) - } - - ctx, loadSpan := Tracer().Start(ctx, "inspecting module", telemetry.Encapsulate()) - defer telemetry.End(loadSpan, func() error { return rerr }) - - name, err := mod.Name(ctx) - if err != nil { - return nil, fmt.Errorf("get module name: %w", err) - } - def.Name = name - - desc, err := mod.Description(ctx) - if err != nil { - return nil, fmt.Errorf("get module description: %w", err) - } - def.Description = desc - - if err := def.loadTypeDefs(ctx, dag); err != nil { - return nil, err - } - - if def.MainObject == nil { - return nil, fmt.Errorf("main object not found, check that your module's name and main object match") - } - - return def, nil -} - // loadCommand finds the leaf command to run. func (fc *FuncCommand) loadCommand(c *cobra.Command, a []string) (rcmd *cobra.Command, rargs []string, rerr error) { ctx := c.Context() diff --git a/cmd/dagger/modconf.graphql b/cmd/dagger/modconf.graphql new file mode 100644 index 0000000000..256a25a543 --- /dev/null +++ b/cmd/dagger/modconf.graphql @@ -0,0 +1,19 @@ +query ModuleConfig($source: ModuleSourceID!) { + source: loadModuleSourceFromID(id: $source) { + asString + module: asModule { + name + initialize { + description + } + dependencies { + name + description + source { + asString + pin + } + } + } + } +} diff --git a/cmd/dagger/module.go b/cmd/dagger/module.go index 6abdcac90f..834b79a697 100644 --- a/cmd/dagger/module.go +++ b/cmd/dagger/module.go @@ -21,6 +21,7 @@ import ( "github.com/spf13/pflag" "dagger.io/dagger" + "dagger.io/dagger/telemetry" "github.com/dagger/dagger/analytics" "github.com/dagger/dagger/core/modules" "github.com/dagger/dagger/engine/client" @@ -687,10 +688,11 @@ func getModuleConfigurationForSourceRef( srcRefStr string, doFindUp bool, resolveFromCaller bool, + srcOpts ...dagger.ModuleSourceOpts, ) (*configuredModule, error) { conf := &configuredModule{} - conf.Source = dag.ModuleSource(srcRefStr) + conf.Source = dag.ModuleSource(srcRefStr, srcOpts...) var err error conf.SourceKind, err = conf.Source.Kind(ctx) if err != nil { @@ -724,7 +726,8 @@ func getModuleConfigurationForSourceRef( namedDep, ok := modCfg.DependencyByName(srcRefStr) if ok { - depSrc := dag.ModuleSource(namedDep.Source) + opts := dagger.ModuleSourceOpts{RefPin: namedDep.Pin} + depSrc := dag.ModuleSource(namedDep.Source, opts) depKind, err := depSrc.Kind(ctx) if err != nil { return nil, err @@ -733,7 +736,7 @@ func getModuleConfigurationForSourceRef( if depKind == dagger.ModuleSourceKindLocalSource { depSrcRef = filepath.Join(defaultFindupConfigDir, namedDep.Source) } - return getModuleConfigurationForSourceRef(ctx, dag, depSrcRef, false, resolveFromCaller) + return getModuleConfigurationForSourceRef(ctx, dag, depSrcRef, false, resolveFromCaller, opts) } } @@ -764,6 +767,7 @@ func getModuleConfigurationForSourceRef( if err := os.MkdirAll(srcRefStr, 0755); err != nil { return nil, fmt.Errorf("failed to create directory for %s: %w", srcRefStr, err) } + conf.Source = dag.ModuleSource(srcRefStr) conf.LocalContextPath, err = conf.Source.ResolveContextPathFromCaller(ctx) @@ -858,6 +862,115 @@ func optionalModCmdWrapper( } } +// initializeCore loads the core type definitions only +func initializeCore(ctx context.Context, dag *dagger.Client) (rdef *moduleDef, rerr error) { + def := &moduleDef{} + + if err := def.loadTypeDefs(ctx, dag); err != nil { + return nil, err + } + + return def, nil +} + +// initializeDefaultModule loads the module referenced by the -m,--mod flag +// +// By default, looks for a module in the current directory, or above. +// Returns an error if the module is not found or invalid. +func initializeDefaultModule(ctx context.Context, dag *dagger.Client) (*moduleDef, error) { + modRef, _ := getExplicitModuleSourceRef() + if modRef == "" { + modRef = moduleURLDefault + } + return initializeModule(ctx, dag, modRef, true) +} + +// maybeInitializeDefaultModule optionally loads the module referenced by the -m,--mod flag, +// falling back to the core definitions +func maybeInitializeDefaultModule(ctx context.Context, dag *dagger.Client) (*moduleDef, string, error) { + modRef, _ := getExplicitModuleSourceRef() + if modRef == "" { + modRef = moduleURLDefault + } + return maybeInitializeModule(ctx, dag, modRef) +} + +// initializeModule loads the module at the given source ref +// +// Returns an error if the module is not found or invalid. +func initializeModule( + ctx context.Context, + dag *dagger.Client, + srcRef string, + doFindUp bool, + srcOpts ...dagger.ModuleSourceOpts, +) (rdef *moduleDef, rerr error) { + ctx, span := Tracer().Start(ctx, "load module") + defer telemetry.End(span, func() error { return rerr }) + + findCtx, findSpan := Tracer().Start(ctx, "finding module configuration", telemetry.Encapsulate()) + conf, err := getModuleConfigurationForSourceRef(findCtx, dag, srcRef, doFindUp, true, srcOpts...) + defer telemetry.End(findSpan, func() error { return err }) + + if err != nil { + return nil, fmt.Errorf("failed to get configured module: %w", err) + } + if !conf.FullyInitialized() { + return nil, fmt.Errorf("module must be fully initialized") + } + + return initializeModuleConfig(ctx, dag, conf) +} + +// maybeInitializeModule optionally loads the module at the given source ref, +// falling back to the core definitions if the module isn't found +func maybeInitializeModule(ctx context.Context, dag *dagger.Client, srcRef string) (*moduleDef, string, error) { + if def, err := tryInitializeModule(ctx, dag, srcRef); def != nil || err != nil { + return def, srcRef, err + } + + def, err := initializeCore(ctx, dag) + return def, "", err +} + +// tryInitializeModule tries to load a module if it exists +// +// Returns an error if the module is invalid or couldn't be loaded, but not +// if the module wasn't found. +func tryInitializeModule(ctx context.Context, dag *dagger.Client, srcRef string) (rdef *moduleDef, rerr error) { + ctx, span := Tracer().Start(ctx, "looking for module") + defer telemetry.End(span, func() error { return rerr }) + + findCtx, findSpan := Tracer().Start(ctx, "finding module configuration", telemetry.Encapsulate()) + conf, _ := getModuleConfigurationForSourceRef(findCtx, dag, srcRef, true, true) + findSpan.End() + + if conf == nil || !conf.FullyInitialized() { + return nil, nil + } + + span.SetName("load module") + + return initializeModuleConfig(ctx, dag, conf) +} + +// initializeModuleConfig loads a module using a detected module configuration +func initializeModuleConfig(ctx context.Context, dag *dagger.Client, conf *configuredModule) (rdef *moduleDef, rerr error) { + serveCtx, serveSpan := Tracer().Start(ctx, "initializing module", telemetry.Encapsulate()) + err := conf.Source.AsModule().Initialize().Serve(serveCtx) + telemetry.End(serveSpan, func() error { return err }) + if err != nil { + return nil, fmt.Errorf("failed to serve module: %w", err) + } + + def, err := inspectModule(ctx, dag, conf.Source) + if err != nil { + return nil, err + } + + return def, def.loadTypeDefs(ctx, dag) +} + // moduleDef is a representation of a dagger module. type moduleDef struct { Name string @@ -871,13 +984,112 @@ type moduleDef struct { // the ModuleSource definition for the module, needed by some arg types // applying module-specific configs to the arg value. Source *dagger.ModuleSource + + // ModRef is the human readable module source reference as returned by the API + ModRef string + + Dependencies []*moduleDependency } +type moduleDependency struct { + Name string + Description string + Source *dagger.ModuleSource + + // ModRef is the human readable module source reference as returned by the API + ModRef string + + // RefPin is the module source pin for this dependency, if any + RefPin string +} + +func (m *moduleDependency) Short() string { + s := m.Description + if s == "" { + s = "-" + } + return strings.SplitN(s, "\n", 2)[0] +} + +//go:embed modconf.graphql +var loadModConfQuery string + //go:embed typedefs.graphql var loadTypeDefsQuery string +func inspectModule(ctx context.Context, dag *dagger.Client, source *dagger.ModuleSource) (rdef *moduleDef, rerr error) { + ctx, span := Tracer().Start(ctx, "inspecting module metadata", telemetry.Encapsulate()) + defer telemetry.End(span, func() error { return rerr }) + + // NB: All we need most of the time is the name of the dependencies. + // We need the descriptions when listing the dependencies, and the source + // ref if we need to load a specific dependency. However getting the refs + // and descriptions here, at module load, doesn't add much overhead and + // makes it easier (and faster) later. + + var res struct { + Source struct { + AsString string + Module struct { + Name string + Initialize struct { + Description string + } + Dependencies []struct { + Name string + Description string + Source struct { + AsString string + Pin string + } + } + } + } + } + + id, err := source.ID(ctx) + if err != nil { + return nil, err + } + + err = dag.Do(ctx, &dagger.Request{ + Query: loadModConfQuery, + Variables: map[string]any{ + "source": id, + }, + }, &dagger.Response{ + Data: &res, + }) + if err != nil { + return nil, fmt.Errorf("query module metadata: %w", err) + } + + deps := make([]*moduleDependency, 0, len(res.Source.Module.Dependencies)) + for _, dep := range res.Source.Module.Dependencies { + deps = append(deps, &moduleDependency{ + Name: dep.Name, + Description: dep.Description, + ModRef: dep.Source.AsString, + RefPin: dep.Source.Pin, + }) + } + + def := &moduleDef{ + Source: source, + ModRef: res.Source.AsString, + Name: res.Source.Module.Name, + Description: res.Source.Module.Initialize.Description, + Dependencies: deps, + } + + return def, nil +} + // loadModTypeDefs loads the objects defined by the given module in an easier to use data structure. -func (m *moduleDef) loadTypeDefs(ctx context.Context, dag *dagger.Client) error { +func (m *moduleDef) loadTypeDefs(ctx context.Context, dag *dagger.Client) (rerr error) { + ctx, loadSpan := Tracer().Start(ctx, "loading type definitions", telemetry.Encapsulate()) + defer telemetry.End(loadSpan, func() error { return rerr }) + var res struct { TypeDefs []*modTypeDef } @@ -929,6 +1141,10 @@ func (m *moduleDef) loadTypeDefs(ctx context.Context, dag *dagger.Client) error } } + if m.MainObject == nil { + return fmt.Errorf("main object not found, check that your module's name and main object match") + } + m.LoadFunctionTypeDefs(m.MainObject.AsObject.Constructor) // FIXME: the API doesn't return the module constructor in the Query object @@ -1020,6 +1236,11 @@ func (m *moduleDef) GetObjectFunction(objectName, functionName string) (*modFunc } func (m *moduleDef) GetFunction(fp functionProvider, functionName string) (*modFunction, error) { + // This avoids an issue with module constructors overriding core functions. + // See https://github.com/dagger/dagger/issues/9122 + if m.HasModule() && fp.ProviderName() == "Query" && m.MainObject.AsObject.Constructor.CmdName() == functionName { + return m.MainObject.AsObject.Constructor, nil + } for _, fn := range fp.GetFunctions() { if fn.Name == functionName || fn.CmdName() == functionName { m.LoadFunctionTypeDefs(fn) @@ -1073,6 +1294,15 @@ func (m *moduleDef) GetInput(name string) *modInput { return nil } +func (m *moduleDef) GetDependency(name string) *moduleDependency { + for _, dep := range m.Dependencies { + if dep.Name == name { + return dep + } + } + return nil +} + // HasModule checks if a module's definitions are loaded func (m *moduleDef) HasModule() bool { return m.Name != "" @@ -1083,7 +1313,7 @@ func (m *moduleDef) GetCoreFunctions() []*modFunction { fns := make([]*modFunction, 0, len(all)) for _, fn := range all { - if fn.ReturnType.AsObject != nil && !fn.ReturnType.AsObject.IsCore() { + if fn.ReturnType.AsObject != nil && !fn.ReturnType.AsObject.IsCore() || fn.Name == "" { continue } fns = append(fns, fn) @@ -1092,14 +1322,24 @@ func (m *moduleDef) GetCoreFunctions() []*modFunction { return fns } -// HasCoreFunction checks if there's a core function with the given name. -func (m *moduleDef) HasCoreFunction(name string) bool { +// GetCoreFunction returns a core function with the given name. +func (m *moduleDef) GetCoreFunction(name string) *modFunction { for _, fn := range m.GetCoreFunctions() { if fn.Name == name || fn.CmdName() == name { - return true + return fn } } - return false + return nil +} + +// HasCoreFunction checks if there's a core function with the given name. +func (m *moduleDef) HasCoreFunction(name string) bool { + fn := m.GetCoreFunction(name) + return fn != nil +} + +func (m *moduleDef) HasMainFunction(name string) bool { + return m.HasFunction(m.MainObject.AsFunctionProvider(), name) } // HasFunction checks if an object has a function with the given name. @@ -1111,11 +1351,6 @@ func (m *moduleDef) HasFunction(fp functionProvider, name string) bool { return fn != nil } -func (m *moduleDef) IsModuleConstructor(fn *modFunction) bool { - fp := fn.ReturnType.AsFunctionProvider() - return fp != nil && !fp.IsCore() -} - // LoadTypeDef attempts to replace a function's return object type or argument's // object type with with one from the module's object type definitions, to // recover missing function definitions in those places when chaining functions. diff --git a/cmd/dagger/shell.go b/cmd/dagger/shell.go index b93abc1260..a9c9c8c466 100644 --- a/cmd/dagger/shell.go +++ b/cmd/dagger/shell.go @@ -39,6 +39,10 @@ const ( helpIndent = uint(2) shellHandlerExit = 200 + shellStdlibCmdName = ".stdlib" + shellDepsCmdName = ".deps" + shellCoreCmdName = ".core" + // We need a prompt that conveys the unique nature of the Dagger shell. Per gpt4: // The โ‹ˆ symbol, known as the bowtie, has deep roots in relational databases and set theory, // where it denotes a join operation. This makes it especially fitting for a DAG environment, @@ -69,8 +73,9 @@ var ( ) func init() { - shellCmd.Flags().StringVarP(&shellCode, "code", "c", "", "command to be executed") - shellCmd.Flags().BoolVar(&shellNoLoadModule, "no-load", false, "don't load module during shell startup") + shellCmd.Flags().StringVarP(&shellCode, "code", "c", "", "Command to be executed") + shellCmd.Flags().BoolVar(&shellNoLoadModule, "no-mod", false, "Don't load module during shell startup (mutually exclusive with --mod)") + shellCmd.MarkFlagsMutuallyExclusive("mod", "no-mod") } var shellCmd = &cobra.Command{ @@ -104,15 +109,14 @@ type shellCallHandler struct { stdout io.Writer stderr io.Writer - // modRef is the module reference for the default module to use + // modRef is a key from modDefs, to set the corresponding module as the default + // when no state is present, or when the state's ModRef is empty modRef string - // modDefs has the module type definitions from introspection, keyed by module ref + // modDefs has the cached module definitions, after loading, and keyed by + // module reference as inputed by the user modDefs map[string]*moduleDef - // cfg holds the final values for the module's constructor, i.e., the module configuration - cfg map[string]any - // switch to Frontend.Background for rendering output while the TUI is // running when in interactive mode tui bool @@ -129,6 +133,9 @@ type shellCallHandler struct { // builtins is the list of Dagger Shell builtin commands builtins []*ShellCommand + + // stdlib is the list of standard library commands + stdlib []*ShellCommand } // RunAll is the entry point for the shell command @@ -184,18 +191,14 @@ func (h *shellCallHandler) RunAll(ctx context.Context, args []string) error { if shellNoLoadModule { def, err = initializeCore(ctx, h.dag) } else { - ref, _ = getExplicitModuleSourceRef() - def, err = maybeInitializeModule(ctx, h.dag, ref, true) - if ref == "" { - ref = moduleURLDefault - } + def, ref, err = maybeInitializeDefaultModule(ctx, h.dag) } if err != nil { return err } h.modRef = ref h.modDefs[ref] = def - h.registerBuiltins() + h.registerCommands() // Example: `dagger shell -c 'container | workdir'` if shellCode != "" { @@ -424,15 +427,17 @@ func (h *shellCallHandler) loadReadlineConfig(prompt string) (*readline.Config, } func (h *shellCallHandler) Prompt(out *termenv.Output, fg termenv.Color) string { - prompt := out.String(shellPrompt).Foreground(fg).String() - if ps1 := h.ps1(); ps1 != "" { - prompt = out.String(ps1).Faint().String() + " " + prompt + sb := new(strings.Builder) + + if def, _ := h.GetModuleDef(nil); def != nil { + sb.WriteString(out.String(def.ModRef).Bold().Foreground(termenv.ANSICyan).String()) + sb.WriteString(" ") } - return prompt + " " -} -func (h *shellCallHandler) ps1() string { - return h.modDef(nil).Name + sb.WriteString(out.String(shellPrompt).Bold().Foreground(fg).String()) + sb.WriteString(" ") + + return sb.String() } // withTerminal handles using stdin, stdout, and stderr when the TUI is runnin @@ -462,7 +467,13 @@ func (h *shellCallHandler) Exec(next interp.ExecHandlerFunc) interp.ExecHandlerF args = args[1:] } - err := h.cmd(ctx, args) + st, err := h.cmd(ctx, args) + if err == nil && st != nil { + if h.debug { + shellLogf(ctx, "[DBG] โ”” OUT(%v): %+v\n", args, st) + } + err = st.Write(ctx) + } if err != nil { m := err.Error() if h.debug { @@ -486,120 +497,212 @@ func (h *shellCallHandler) Exec(next interp.ExecHandlerFunc) interp.ExecHandlerF } } -// cmd is tt he main logic for executing simple commands -func (h *shellCallHandler) cmd(ctx context.Context, args []string) error { - var st *ShellState - var err error +// cmd is the main logic for executing simple commands +func (h *shellCallHandler) cmd(ctx context.Context, args []string) (*ShellState, error) { + c, a := args[0], args[1:] - builtin, err := h.BuiltinCommand(args[0]) - if err != nil { - return err + if isFirstShellCommand(ctx) { + return h.entrypointCall(ctx, c, a) } - if isFirstShellCommand(ctx) { - if builtin != nil { - return builtin.Execute(ctx, args[1:], nil) - } - st, err = h.entrypointCall(ctx, args) - if err != nil { - return err - } - } else { - var b []byte - st, b, err = shellState(ctx) - if err != nil { - return err - } - if st == nil { - if h.debug { - shellLogf(ctx, "[DBG] IN(%v): %q\n", args, string(b)) - } - return fmt.Errorf("unexpected input for command %q", args[0]) + var b []byte + st, b, err := shellState(ctx) + if err != nil { + return nil, err + } + if st == nil { + if h.debug { + shellLogf(ctx, "[DBG] IN(%v): %q\n", args, string(b)) } + return nil, fmt.Errorf("unexpected input for command %q", c) } - if h.debug { - shellLogf(ctx, "[DBG] IN(%v): %v\n", args, st) + shellLogf(ctx, "[DBG] โ”” IN(%v): %+v\n", args, st) } + builtin, err := h.BuiltinCommand(c) + if err != nil { + return nil, err + } if builtin != nil { - return builtin.Execute(ctx, args[1:], st) + return nil, builtin.Execute(ctx, a, st) } - st, err = h.functionCall(ctx, st, args[0], args[1:]) - if err != nil { - return err - } + if st.IsCommandRoot() { + switch { + case st.IsStdlib(): + // Example: .stdlib | ` + stdlib, err := h.StdlibCommand(c) + if err != nil { + return nil, err + } + return nil, stdlib.Execute(ctx, a, nil) - if h.debug { - shellLogf(ctx, "[DBG] OUT(%v): %v\n", args, st) + case st.IsDeps(): + // Example: `.deps | ` + st, def, err := h.GetDependency(ctx, c) + if err != nil { + return nil, err + } + return h.constructorCall(ctx, def, st, a) + + case st.IsCore(): + // Example: `.core | ` + def := h.modDef(st) + if !def.HasCoreFunction(c) { + return nil, fmt.Errorf("core function %q not found", c) + } + // an empty state's first object is Query by default so + // functionCall already handles it + } } - return st.Write(ctx) + // module or core function call + return h.functionCall(ctx, st, c, a) } -// entrypointCall is executed when it's the first in a command pipeline -func (h *shellCallHandler) entrypointCall(ctx context.Context, args []string) (*ShellState, error) { +// entrypointCall is executed when it's the first command in a pipeline +func (h *shellCallHandler) entrypointCall(ctx context.Context, cmd string, args []string) (*ShellState, error) { if h.debug { - shellLogf(ctx, "[DBG] โ”” Entrypoint(%v)\n", args) + shellLogf(ctx, "[DBG] โ”” Entrypoint(%s, %v)\n", cmd, args) + } + + if cmd, _ := h.BuiltinCommand(cmd); cmd != nil { + return nil, cmd.Execute(ctx, args, nil) } - def, err := h.GetModuleDef(nil) + st, err := h.stateLookup(ctx, cmd) if err != nil { return nil, err } - st := h.newState() + if h.debug { + shellLogf(ctx, "[DBG] โ”” Found(%s, %v): %+v\n", cmd, args, st) + } - // Same-module call (eg. 'build') - if def.HasModule() && def.HasFunction(def.MainObject.AsFunctionProvider(), args[0]) { - return h.constructorCall(def, st) + if st.IsStdlib() { + cmd, err := h.StdlibCommand(cmd) + if err != nil { + return nil, err + } + return st, cmd.Execute(ctx, args, nil) } - // TODO: Dependency short name (eg. 'wolfi container') + if md, _ := h.GetModuleDef(st); md != nil { + // Command is a function in current context + if h.isCurrentContextFunction(cmd) { + // We need to assume a constructor call without arguments + st, err := h.constructorCall(ctx, md, st, nil) + if err != nil { + return nil, err + } + return h.functionCall(ctx, st, cmd, args) + } - return nil, fmt.Errorf("no such function: %q", args[0]) + // Command is a dependency or module ref, so this is the constructor call + if st.IsEmpty() { + return h.constructorCall(ctx, md, st, args) + } + } + + return st, nil } -func (h *shellCallHandler) constructorCall(md *moduleDef, st *ShellState) (*ShellState, error) { - fn := md.MainObject.AsObject.Constructor +func (h *shellCallHandler) isCurrentContextFunction(name string) bool { + md, _ := h.GetModuleDef(nil) + return md != nil && md.HasMainFunction(name) +} - expected := len(fn.RequiredArgs()) - actual := len(h.cfg) +func (h *shellCallHandler) stateLookup(ctx context.Context, name string) (*ShellState, error) { + if h.debug { + shellLogf(ctx, "[DBG] โ”” StateLookup(%v)\n", name) + } + // Is current context a loaded module? + if md, _ := h.GetModuleDef(nil); md != nil { + // 1. Function in current context + if md.HasMainFunction(name) { + if h.debug { + shellLogf(ctx, "[DBG] - found in current context\n") + } + return h.newState(), nil + } - if expected > actual { - usage := shellFunctionUseLine(md, fn) - return nil, fmt.Errorf("missing %d required argument(s) for the module. Use %q to set them", expected-actual, usage) + // 2. Dependency short name + if dep := md.GetDependency(name); dep != nil { + if h.debug { + shellLogf(ctx, "[DBG] - found dependency (%s)\n", dep.ModRef) + } + depSt, _, err := h.GetDependency(ctx, name) + return depSt, err + } } - return st.WithCall(fn, h.cfg), nil -} + // 3. Standard library command + if cmd, _ := h.StdlibCommand(name); cmd != nil { + if h.debug { + shellLogf(ctx, "[DBG] - found stdlib command\n") + } + return h.newStdlibState(), nil + } -// functionCall is executed for every command that the exec handler processes -func (h *shellCallHandler) functionCall(ctx context.Context, prev *ShellState, name string, args []string) (*ShellState, error) { - def := h.modDef(prev) + // 4. Path to local or remote module source + // (local paths are relative to the current working directory, not the loaded module) + st, err := h.getOrInitDefState(name, func() (*moduleDef, error) { + return tryInitializeModule(ctx, h.dag, name) + }) + if err != nil { + return nil, err + } + if st == nil { + return nil, fmt.Errorf("function or module %q not found", name) + } + if h.debug { + shellLogf(ctx, "[DBG] - found module reference\n") + } + return st, nil +} - // Example: .load | - if def.HasModule() && prev.ModRef != nil && len(prev.Calls) == 0 { - st, err := h.constructorCall(def, prev) - if err != nil { +func (h *shellCallHandler) getOrInitDefState(ref string, fn func() (*moduleDef, error)) (*ShellState, error) { + _, exists := h.modDefs[ref] + if !exists { + if fn == nil { + return nil, fmt.Errorf("module %q not loaded", ref) + } + def, err := fn() + if err != nil || def == nil { return nil, err } - prev = st + h.modDefs[ref] = def + } + return h.newModState(ref), nil +} + +func (h *shellCallHandler) constructorCall(ctx context.Context, md *moduleDef, st *ShellState, args []string) (*ShellState, error) { + fn := md.MainObject.AsObject.Constructor + + values, err := h.parseArgumentValues(ctx, md, fn, args) + if err != nil { + return nil, fmt.Errorf("constructor: %w", err) } - call := prev.Function() + return st.WithCall(fn, values), nil +} + +// functionCall is executed for every command that the exec handler processes +func (h *shellCallHandler) functionCall(ctx context.Context, st *ShellState, name string, args []string) (*ShellState, error) { + def := h.modDef(st) + call := st.Function() fn, err := call.GetNextDef(def, name) if err != nil { - return prev, err + return st, err } argValues, err := h.parseArgumentValues(ctx, def, fn, args) if err != nil { - return prev, fmt.Errorf("could not parse arguments for function %q: %w", fn.CmdName(), err) + return st, fmt.Errorf("could not parse arguments for function %q: %w", fn.CmdName(), err) } - return prev.WithCall(fn, argValues), nil + return st.WithCall(fn, argValues), nil } // parseArgumentValues returns a map of argument names and their parsed values @@ -760,16 +863,38 @@ func (h *shellCallHandler) parseStateArgument(ctx context.Context, arg *modFunct // Result handles making the final request and printing the response func (h *shellCallHandler) Result(ctx context.Context, st *ShellState) error { if h.debug { - withTerminal(func(_ io.Reader, _, stderr io.Writer) error { + h.withTerminal(func(_ io.Reader, _, stderr io.Writer) error { fmt.Fprintf(stderr, "[DBG] Result state: %+v\n", st) return nil }) } + if st.IsCommandRoot() { + var out string + + switch { + case st.IsStdlib(): + out = h.CommandsList(st.Cmd, h.Stdlib()) + case st.IsDeps(): + out = h.DependenciesList() + case st.IsCore(): + def := h.modDef(nil) + out = h.FunctionsList(st.Cmd, def.GetCoreFunctions()) + default: + return fmt.Errorf("unexpected namespace: %s", st.Cmd) + } + + return h.withTerminal(func(_ io.Reader, stdout, _ io.Writer) error { + fmt.Fprintln(stdout, out) + return nil + }) + } + def := h.modDef(st) - if def.HasModule() && st.ModRef != nil && len(st.Calls) == 0 { - newSt, err := h.constructorCall(def, st) + // Example: `build` (i.e., omitted constructor) + if def.HasModule() && st.IsEmpty() { + newSt, err := h.constructorCall(ctx, def, st, nil) if err != nil { return err } @@ -869,15 +994,48 @@ func readShellState(r io.Reader) (*ShellState, []byte, error) { // one's stdin. Each handler in the chain should add a corresponding FunctionCall // to the state and write it to stdout for the next handler to read. type ShellState struct { - Calls []FunctionCall `json:"calls,omitempty"` - Error *string `json:"error,omitempty"` - ModRef *string `json:"modRef,omitempty"` + // ModRef is the module reference for the current state + // + // If empty, it must fall back to the default context. + // It matches a key in the modDefs map in the handler, which comes from + // user input, not from the API. + ModRef string `json:"modRef"` + + // Cmd is non-empty if next command comes from a builtin instead of an API object + Cmd string `json:"ns"` + + // Calls is the list of functions for building an API query + Calls []FunctionCall `json:"calls,omitempty"` + + // Error is non-nil if the previous command failed + Error *string `json:"error,omitempty"` } func (st ShellState) IsError() bool { return st.Error != nil } +// IsEmpty returns true if there's no function calls in the chain +func (st ShellState) IsEmpty() bool { + return len(st.Calls) == 0 +} + +func (st ShellState) IsCommandRoot() bool { + return st.IsEmpty() && st.Cmd != "" +} + +func (st ShellState) IsStdlib() bool { + return st.Cmd == shellStdlibCmdName +} + +func (st ShellState) IsCore() bool { + return st.Cmd == shellCoreCmdName +} + +func (st ShellState) IsDeps() bool { + return st.Cmd == shellDepsCmdName +} + // FunctionCall represents a querybyilder.Selection // // The query builder only cares about the name of the function and its arguments, @@ -918,7 +1076,7 @@ func (st ShellState) WriteTo(w io.Writer) error { // Function returns the last function in the chain, if not empty func (st ShellState) Function() FunctionCall { - if len(st.Calls) == 0 { + if st.IsEmpty() { // The first call is a field under Query. return FunctionCall{ ReturnObject: "Query", @@ -931,6 +1089,7 @@ func (st ShellState) Function() FunctionCall { func (st ShellState) WithCall(fn *modFunction, argValues map[string]any) *ShellState { prev := st.Function() return &ShellState{ + Cmd: st.Cmd, ModRef: st.ModRef, Calls: append(st.Calls, FunctionCall{ Object: prev.ReturnObject, @@ -961,7 +1120,7 @@ func (st *ShellState) GetTypeDef(modDef *moduleDef) (*modTypeDef, error) { // GetDef returns the introspection definition for the last function call func (st *ShellState) GetDef(modDef *moduleDef) (*modFunction, error) { - if st == nil || len(st.Calls) == 0 { + if st == nil || st.IsEmpty() { return modDef.MainObject.AsObject.Constructor, nil } return st.Function().GetDef(modDef) @@ -981,36 +1140,36 @@ func (f FunctionCall) GetNextDef(modDef *moduleDef, name string) (*modFunction, return modDef.GetObjectFunction(f.ReturnObject, name) } -// ShellCommand is a Dagger Shell builtin command +// ShellCommand is a Dagger Shell builtin or stdlib command type ShellCommand struct { - // Use is the one-line usage message. + // Use is the one-line usage message Use string - // Short is the short description shown in the '.help' output. - Short string + // Description is the short description shown in the '.help' output + Description string // Expected arguments Args PositionalArgs // Run is the function that will be executed if it's the first command - // in the pipeline and RunState is not defined. + // in the pipeline and RunState is not defined Run func(cmd *ShellCommand, args []string) error // RunState is the function for executing a command that can be chained - // in a pipeline. + // in a pipeline // // If defined, it's always used, even if it's the first command in the // pipeline. For commands that should only be the first, define `Run` instead. RunState func(cmd *ShellCommand, args []string, st *ShellState) error + // HelpFunc is a custom function for customizing the help output HelpFunc func(cmd *ShellCommand) string // The group id under which this command is grouped in the '.help' output GroupID string - // Hidden hides the command from `.help`. - Hidden bool - Disabled func() bool + // Hidden hides the command from `.help` + Hidden bool ctx context.Context out io.Writer @@ -1032,6 +1191,11 @@ func (c *ShellCommand) Name() string { return name } +// Short is the the summary for the command +func (c *ShellCommand) Short() string { + return strings.Split(c.Description, "\n")[0] +} + func (c *ShellCommand) Help() string { if c.HelpFunc != nil { return c.HelpFunc(c) @@ -1042,10 +1206,8 @@ func (c *ShellCommand) Help() string { func (c *ShellCommand) defaultHelp() string { var doc ShellDoc - // TODO: Replace "Short" with "Description", use first line as the short - // description and the full thing as the long description. - if c.Short != "" { - doc.Add("", c.Short) + if c.Description != "" { + doc.Add("", c.Description) } doc.Add("Usage", c.Use) @@ -1083,17 +1245,6 @@ func (c *ShellCommand) Send(st *ShellState) error { return st.WriteTo(c.out) } -func (c *ShellCommand) Printer() io.Writer { - return c.out -} - -func (c *ShellCommand) Runnable() bool { - if c.Disabled != nil { - return !c.Disabled() - } - return true -} - type PositionalArgs func(args []string) error func MinimumArgs(n int) PositionalArgs { @@ -1117,7 +1268,7 @@ func MaximumArgs(n int) PositionalArgs { func ExactArgs(n int) PositionalArgs { return func(args []string) error { if len(args) < n { - return fmt.Errorf("is missing %d positional argument(s)", n-len(args)) + return fmt.Errorf("missing %d positional argument(s)", n-len(args)) } if len(args) > n { return fmt.Errorf("accepts at most %d positional argument(s), received %d", n, len(args)) @@ -1133,6 +1284,7 @@ func NoArgs(args []string) error { return nil } +// Execute is the main dispatcher function for shell builtin commands func (c *ShellCommand) Execute(ctx context.Context, args []string, st *ShellState) error { if st != nil && c.RunState == nil { return fmt.Errorf("command %q cannot be piped", c.Name()) @@ -1149,14 +1301,12 @@ func (c *ShellCommand) Execute(ctx context.Context, args []string, st *ShellStat return c.Run(c, args) } +// shellFunctionUseLine returns the usage line fine for a function func shellFunctionUseLine(md *moduleDef, fn *modFunction) string { sb := new(strings.Builder) - if md.HasCoreFunction(fn.CmdName()) { - sb.WriteString(".") - } if fn == md.MainObject.AsObject.Constructor { - sb.WriteString(".config") + sb.WriteString(md.ModRef) } else { sb.WriteString(fn.CmdName()) } @@ -1174,43 +1324,50 @@ func shellFunctionUseLine(md *moduleDef, fn *modFunction) string { return sb.String() } -func (h *shellCallHandler) HasBuiltin(name string) bool { - return h.getBuiltin(name) != nil +func (h *shellCallHandler) GroupBuiltins(groupID string) []*ShellCommand { + l := make([]*ShellCommand, 0, len(h.builtins)) + for _, c := range h.Builtins() { + if c.GroupID == groupID { + l = append(l, c) + } + } + return l } -func (h *shellCallHandler) getBuiltin(name string) *ShellCommand { +func (h *shellCallHandler) BuiltinCommand(name string) (*ShellCommand, error) { + if name == "." || !strings.HasPrefix(name, ".") || strings.Contains(name, "/") { + return nil, nil + } for _, c := range h.builtins { if c.Name() == name { - return c + return c, nil } } - return nil + return nil, fmt.Errorf("command not found %q", name) } -func (h *shellCallHandler) BuiltinCommand(name string) (*ShellCommand, error) { - if !strings.HasPrefix(name, ".") { - return nil, nil - } - cmd := h.getBuiltin(name) - if cmd == nil { - return nil, fmt.Errorf("no such command %q", name) +func (h *shellCallHandler) StdlibCommand(name string) (*ShellCommand, error) { + for _, c := range h.stdlib { + if c.Name() == name { + return c, nil + } } - return cmd, nil + return nil, fmt.Errorf("command not found %q", name) } -func (h *shellCallHandler) GroupBuiltins(groupID string) []*ShellCommand { +func (h *shellCallHandler) Builtins() []*ShellCommand { l := make([]*ShellCommand, 0, len(h.builtins)) - for _, c := range h.Builtins() { - if c.GroupID == groupID { + for _, c := range h.builtins { + if !c.Hidden { l = append(l, c) } } return l } -func (h *shellCallHandler) Builtins() []*ShellCommand { - l := make([]*ShellCommand, 0, len(h.builtins)) - for _, c := range h.builtins { +func (h *shellCallHandler) Stdlib() []*ShellCommand { + l := make([]*ShellCommand, 0, len(h.stdlib)) + for _, c := range h.stdlib { if !c.Hidden { l = append(l, c) } @@ -1218,8 +1375,125 @@ func (h *shellCallHandler) Builtins() []*ShellCommand { return l } -func (h *shellCallHandler) addBuiltin(cmds ...*ShellCommand) { - h.builtins = append(h.builtins, cmds...) +func (h *shellCallHandler) FunctionsList(name string, fns []*modFunction) string { + if len(fns) == 0 { + return "" + } + + sb := new(strings.Builder) + + sb.WriteString("Available functions:\n") + for _, f := range fns { + sb.WriteString(" - ") + sb.WriteString(f.CmdName()) + sb.WriteString("\n") + } + + sb.WriteString("\n") + sb.WriteString(fmt.Sprintf(`Use "%s | .doc" for more details.`, name)) + sb.WriteString("\n") + sb.WriteString(fmt.Sprintf(`Use "%s | .doc " for more information on a function.`, name)) + sb.WriteString("\n") + + return sb.String() +} + +func (h *shellCallHandler) CommandsList(name string, cmds []*ShellCommand) string { + if len(cmds) == 0 { + return "" + } + + sb := new(strings.Builder) + + sb.WriteString("Available commands:\n") + for _, c := range cmds { + sb.WriteString(" - ") + sb.WriteString(c.Name()) + sb.WriteString("\n") + } + + sb.WriteString("\n") + sb.WriteString(fmt.Sprintf(`Use "%s | .doc" for more details.`, name)) + sb.WriteString("\n") + sb.WriteString(fmt.Sprintf(`Use "%s | .doc " for more information on a command.`, name)) + sb.WriteString("\n") + + return sb.String() +} + +func (h *shellCallHandler) DependenciesList() string { + // This is validated in the .deps command + def, _ := h.GetModuleDef(nil) + if def == nil || len(def.Dependencies) == 0 { + return "" + } + + sb := new(strings.Builder) + + sb.WriteString("Available dependencies:\n") + for _, dep := range def.Dependencies { + sb.WriteString(" - ") + sb.WriteString(dep.Name) + sb.WriteString("\n") + } + + sb.WriteString("\n") + sb.WriteString(fmt.Sprintf(`Use "%s | .doc" for more details.`, shellDepsCmdName)) + sb.WriteString("\n") + sb.WriteString(fmt.Sprintf(`Use "%s | .doc " for more information on a dependency.`, shellDepsCmdName)) + sb.WriteString("\n") + + return sb.String() +} + +func (h *shellCallHandler) StdlibHelp() string { + var doc ShellDoc + + doc.Add("Commands", nameShortWrapped(h.Stdlib(), func(c *ShellCommand) (string, string) { + return c.Name(), c.Description + })) + + doc.Add("", fmt.Sprintf(`Use "%s | .doc " for more information on a command.`, shellStdlibCmdName)) + + return doc.String() +} + +func (h *shellCallHandler) CoreHelp() string { + var doc ShellDoc + + def := h.modDef(nil) + + doc.Add( + "Available Functions", + nameShortWrapped(def.GetCoreFunctions(), func(f *modFunction) (string, string) { + return f.CmdName(), f.Short() + }), + ) + + doc.Add("", fmt.Sprintf(`Use "%s | .doc " for more information on a function.`, shellCoreCmdName)) + + return doc.String() +} + +func (h *shellCallHandler) DepsHelp() string { + // This is validated in the .deps command + def, _ := h.GetModuleDef(nil) + if def == nil { + return "" + } + + var doc ShellDoc + + doc.Add( + "Module Dependencies", + nameShortWrapped(def.Dependencies, func(dep *moduleDependency) (string, string) { + return dep.Name, dep.Short() + }), + ) + + doc.Add("", fmt.Sprintf(`Use "%s | .doc " for more information on a dependency.`, shellDepsCmdName)) + + return doc.String() } type ShellDoc struct { @@ -1275,6 +1549,95 @@ func (d ShellDoc) String() string { return sb.String() } +func shellModuleDoc(st *ShellState, m *moduleDef) string { + var doc ShellDoc + + meta := new(strings.Builder) + meta.WriteString(m.Name) + if m.Description != "" { + meta.WriteString("\n\n") + meta.WriteString(m.Description) + } + if meta.Len() > 0 { + doc.Add("Module", meta.String()) + } + + fn := m.MainObject.AsObject.Constructor + if len(fn.Args) > 0 { + constructor := new(strings.Builder) + constructor.WriteString("Usage: ") + constructor.WriteString(shellFunctionUseLine(m, fn)) + + if fn.Description != "" { + constructor.WriteString("\n\n") + constructor.WriteString(fn.Description) + } + + doc.Add("Entrypoint", constructor.String()) + + if args := fn.RequiredArgs(); len(args) > 0 { + doc.AddSection( + "Required Arguments", + nameShortWrapped(args, func(a *modFunctionArg) (string, string) { + return strings.TrimPrefix(a.Usage(), "--"), a.Long() + }), + ) + } + if args := fn.OptionalArgs(); len(args) > 0 { + doc.AddSection( + "Optional Arguments", + nameShortWrapped(args, func(a *modFunctionArg) (string, string) { + return a.Usage(), a.Long() + }), + ) + } + } + + // If it's just `.doc` and the current module doesn't have required args, + // can use the default constructor and show available functions. + if st.IsEmpty() && st.ModRef == "" && !fn.HasRequiredArgs() { + if fns := m.MainObject.AsFunctionProvider().GetFunctions(); len(fns) > 0 { + doc.Add( + "Available Functions", + nameShortWrapped(fns, func(f *modFunction) (string, string) { + return f.CmdName(), f.Short() + }), + ) + doc.Add("", `Use ".doc " for more information on a function.`) + } + } + + return doc.String() +} + +func shellTypeDoc(t *modTypeDef) string { + var doc ShellDoc + + fp := t.AsFunctionProvider() + if fp == nil { + doc.Add(t.KindDisplay(), t.Long()) + + // If not an object, only have the type to show. + return doc.String() + } + + if fp.ProviderName() != "Query" { + doc.Add(t.KindDisplay(), t.Long()) + } + + if fns := fp.GetFunctions(); len(fns) > 0 { + doc.Add( + "Available Functions", + nameShortWrapped(fns, func(f *modFunction) (string, string) { + return f.CmdName(), f.Short() + }), + ) + doc.Add("", `Use ".doc " for more information on a function.`) + } + + return doc.String() +} + func shellFunctionDoc(md *moduleDef, fn *modFunction) string { var doc ShellDoc @@ -1310,89 +1673,39 @@ func shellFunctionDoc(md *moduleDef, fn *modFunction) string { } if fn.ReturnType.AsFunctionProvider() != nil { - help := ".doc" - if fn != md.MainObject.AsObject.Constructor { - help = fmt.Sprintf("%s | %s", strings.TrimSuffix(usage, " [options]"), help) - } - doc.Add("", fmt.Sprintf("Use %q for available functions.", help)) + u := strings.TrimSuffix(usage, " [options]") + doc.Add("", fmt.Sprintf(`Use "%s | .doc" for available functions.`, u)) } return doc.String() } -func shellTypeDoc(m *moduleDef, t *modTypeDef) string { - var doc ShellDoc - - fp := t.AsFunctionProvider() - if fp == nil { - doc.Add(t.KindDisplay(), t.Long()) +func (h *shellCallHandler) isDefaultState(st *ShellState) bool { + return st == nil || st.ModRef == "" || st.ModRef == h.modRef +} - // If not an object, only have the type to show. - return doc.String() +func (h *shellCallHandler) newModState(ref string) *ShellState { + return &ShellState{ + ModRef: ref, } +} - // The module constructor creates the main object instance - if !fp.IsCore() && fp.ProviderName() == m.MainObject.Name() { - mod := new(strings.Builder) - mod.WriteString(m.Name) - if m.Description != "" { - mod.WriteString("\n\n") - mod.WriteString(m.Description) - } - if mod.Len() > 0 { - doc.Add("Module", mod.String()) - } - - doc.Add("Main Object", t.Long()) - - fn := m.MainObject.AsObject.Constructor - - constructor := new(strings.Builder) - if len(fn.Args) > 0 { - constructor.WriteString("Usage: ") - constructor.WriteString(shellFunctionUseLine(m, fn)) - } - if fn.Description != "" { - constructor.WriteString("\n\n") - constructor.WriteString(fn.Description) - } - if constructor.Len() > 0 { - doc.Add("Entrypoint", constructor.String()) - } - - if args := fn.RequiredArgs(); len(args) > 0 { - doc.AddSection( - "Required Arguments", - nameShortWrapped(args, func(a *modFunctionArg) (string, string) { - return strings.TrimPrefix(a.Usage(), "--"), a.Long() - }), - ) - } - if args := fn.OptionalArgs(); len(args) > 0 { - doc.AddSection( - "Optional Arguments", - nameShortWrapped(args, func(a *modFunctionArg) (string, string) { - return a.Usage(), a.Long() - }), - ) - } - } else if fp.ProviderName() != "Query" { - doc.Add(t.KindDisplay(), t.Long()) +func (h *shellCallHandler) newStdlibState() *ShellState { + return &ShellState{ + Cmd: shellStdlibCmdName, } +} - if fns := fp.GetFunctions(); len(fns) > 0 { - doc.Add( - "Available Functions", - nameShortWrapped(fns, func(f *modFunction) (string, string) { - return f.CmdName(), f.Short() - }), - ) - - usage := ".doc " - doc.Add("", fmt.Sprintf("Use %q for more information on a function.\n", usage)) +func (h *shellCallHandler) newCoreState() *ShellState { + return &ShellState{ + Cmd: shellCoreCmdName, } +} - return doc.String() +func (h *shellCallHandler) newDepsState() *ShellState { + return &ShellState{ + Cmd: shellDepsCmdName, + } } func (h *shellCallHandler) newState() *ShellState { @@ -1401,8 +1714,8 @@ func (h *shellCallHandler) newState() *ShellState { func (h *shellCallHandler) modDef(st *ShellState) *moduleDef { ref := h.modRef - if st != nil && st.ModRef != nil { - ref = *st.ModRef + if !h.isDefaultState(st) { + ref = st.ModRef } if modDef, ok := h.modDefs[ref]; ok { return modDef @@ -1419,22 +1732,51 @@ func (h *shellCallHandler) GetModuleDef(st *ShellState) (*moduleDef, error) { return nil, fmt.Errorf("module not loaded") } -func (h *shellCallHandler) registerBuiltins() { //nolint:gocyclo - h.addBuiltin( +func (h *shellCallHandler) GetDependency(ctx context.Context, name string) (*ShellState, *moduleDef, error) { + modDef, err := h.GetModuleDef(nil) + if err != nil { + return nil, nil, err + } + dep := modDef.GetDependency(name) + if dep == nil { + return nil, nil, fmt.Errorf("dependency %q not found", name) + } + st, err := h.getOrInitDefState(dep.ModRef, func() (*moduleDef, error) { + var opts []dagger.ModuleSourceOpts + if dep.RefPin != "" { + opts = append(opts, dagger.ModuleSourceOpts{RefPin: dep.RefPin}) + } + return initializeModule(ctx, h.dag, dep.ModRef, false, opts...) + }) + if err != nil { + return nil, nil, err + } + def, err := h.GetModuleDef(st) + if err != nil { + return nil, nil, err + } + return st, def, nil +} + +func (h *shellCallHandler) registerCommands() { //nolint:gocyclo + var builtins []*ShellCommand + var stdlib []*ShellCommand + + builtins = append(builtins, &ShellCommand{ Use: ".debug", Hidden: true, Args: NoArgs, - Run: func(cmd *ShellCommand, args []string) error { + Run: func(_ *ShellCommand, _ []string) error { // Toggles debug mode, which can be useful when in interactive mode h.debug = !h.debug return nil }, }, &ShellCommand{ - Use: ".help [command]", - Short: "Print this help message", - Args: MaximumArgs(1), + Use: ".help [command]", + Description: "Print this help message", + Args: MaximumArgs(1), Run: func(cmd *ShellCommand, args []string) error { if len(args) == 1 { c, err := h.BuiltinCommand(args[0]) @@ -1442,9 +1784,11 @@ func (h *shellCallHandler) registerBuiltins() { //nolint:gocyclo return err } if c == nil { - err = fmt.Errorf("no such command %q", args[0]) - if !strings.HasPrefix(args[0], ".") && h.HasBuiltin("."+args[0]) { - err = fmt.Errorf("%w, did you mean %q?", err, "."+args[0]) + err = fmt.Errorf("command not found %q", args[0]) + if !strings.HasPrefix(args[0], ".") { + if builtin, _ := h.BuiltinCommand("." + args[0]); builtin != nil { + err = fmt.Errorf("%w, did you mean %q?", err, "."+args[0]) + } } return err } @@ -1461,7 +1805,7 @@ func (h *shellCallHandler) registerBuiltins() { //nolint:gocyclo doc.Add( group.Title, nameShortWrapped(cmds, func(c *ShellCommand) (string, string) { - return c.Name(), c.Short + return c.Name(), c.Short() }), ) } @@ -1472,201 +1816,178 @@ func (h *shellCallHandler) registerBuiltins() { //nolint:gocyclo }, }, &ShellCommand{ - Use: ".doc [function]", - Short: "Show documentation for a type, or a function", - Args: MaximumArgs(1), + Use: ".doc [module]\n | .doc [function]", + Description: `Show documentation for a module, a type, or a function + + +Local module paths are resolved relative to the workdir on the host, not relative +to the currently loaded module. +`, + Args: MaximumArgs(1), RunState: func(cmd *ShellCommand, args []string, st *ShellState) error { + var err error + + ctx := cmd.Context() + + // First command in chain + if st == nil { + if len(args) == 0 { + // No arguments, e.g, `.doc`. + st = h.newState() + } else { + // Use the same function lookup as when executing so + // that `> .doc wolfi` documents `> wolfi`. + st, err = h.stateLookup(ctx, args[0]) + if err != nil { + return err + } + if st.ModRef != "" { + // First argument to `.doc` is a module reference, so + // remove it from list of arguments now that it's loaded. + // The rest of the arguments should be passed on to + // the constructor. + args = args[1:] + } + } + } + def := h.modDef(st) + if st.IsEmpty() { + switch { + case st.IsStdlib(): + // Document stdlib + // Example: `.stdlib | .doc` + if len(args) == 0 { + return cmd.Println(h.StdlibHelp()) + } + // Example: .stdlib | .doc ` + c, err := h.StdlibCommand(args[0]) + if err != nil { + return err + } + return cmd.Println(c.Help()) + + case st.IsDeps(): + // Document dependency + // Example: `.deps | .doc` + if len(args) == 0 { + return cmd.Println(h.DepsHelp()) + } + // Example: `.deps | .doc ` + depSt, depDef, err := h.GetDependency(ctx, args[0]) + if err != nil { + return err + } + return cmd.Println(shellModuleDoc(depSt, depDef)) + + case st.IsCore(): + // Document core + // Example: `.core | .doc` + if len(args) == 0 { + return cmd.Println(h.CoreHelp()) + } + // Example: `.core | .doc ` + fn := def.GetCoreFunction(args[0]) + if fn == nil { + return fmt.Errorf("core function %q not found", args[0]) + } + return cmd.Println(shellFunctionDoc(def, fn)) + + case len(args) == 0: + if !def.HasModule() { + return fmt.Errorf("module not loaded.\nUse %q to see what's available", shellStdlibCmdName) + } + // Document module + // Example: `.doc [module]` + return cmd.Println(shellModuleDoc(st, def)) + } + } + t, err := st.GetTypeDef(def) if err != nil { return err } + // Document type + // Example: `container | .doc` if len(args) == 0 { - return cmd.Println(shellTypeDoc(def, t)) + return cmd.Println(shellTypeDoc(t)) } fp := t.AsFunctionProvider() if fp == nil { return fmt.Errorf("type %q does not provide functions", t.String()) } + + // Document function from type + // Example: `container | .doc with-exec` fn, err := def.GetFunction(fp, args[0]) if err != nil { return err } - return cmd.Println(shellFunctionDoc(def, fn)) }, }, &ShellCommand{ - Use: ".load [module]", - Short: "Load a module", - GroupID: moduleGroup.ID, - Args: MaximumArgs(1), - Run: func(cmd *ShellCommand, args []string) error { - var ref string - if len(args) == 0 { - ref, _ = getExplicitModuleSourceRef() - } else { - ref = args[0] - } - - modRef := ref - if modRef == "" { - modRef = moduleURLDefault - } - - // TODO: Add a `--force` flag to force loading again? - if _, ok := h.modDefs[modRef]; !ok { - modDef, err := maybeInitializeModule(cmd.Context(), h.dag, ref, false) - if err != nil { - return err - } - h.modDefs[modRef] = modDef - } + Use: ".use ", + Description: `Set a module as the default for the session - return cmd.Send(&ShellState{ModRef: &modRef}) - }, - }, - &ShellCommand{ - Use: ".use", - Short: "Set a loaded module as the default for the session", +Local module paths are resolved relative to the workdir on the host, not relative +to the currently loaded module. +`, GroupID: moduleGroup.ID, - Args: NoArgs, - RunState: func(cmd *ShellCommand, args []string, st *ShellState) error { - if st == nil { - return fmt.Errorf("usage: .load [module] | .use") + Args: ExactArgs(1), + Run: func(cmd *ShellCommand, args []string) error { + st, err := h.getOrInitDefState(args[0], func() (*moduleDef, error) { + return initializeModule(cmd.Context(), h.dag, args[0], true) + }) + if err != nil { + return err } - if st.ModRef != nil && *st.ModRef != h.modRef { - h.modRef = *st.ModRef + if st.ModRef != h.modRef { + h.modRef = st.ModRef } return nil }, }, &ShellCommand{ - Use: ".config", - Short: "Set module constructor options", - GroupID: moduleGroup.ID, - HelpFunc: func(cmd *ShellCommand) string { - def := h.modDef(nil) - // `.help .config` always refers to the default module - if !def.HasModule() { - // TODO: provide more documentation - return cmd.defaultHelp() - } - return shellFunctionDoc(def, def.MainObject.AsObject.Constructor) - }, - RunState: func(cmd *ShellCommand, args []string, st *ShellState) error { - def, err := h.GetModuleDef(st) + Use: shellDepsCmdName, + Description: "Dependencies from the module loaded in the current context", + GroupID: moduleGroup.ID, + Args: NoArgs, + Run: func(cmd *ShellCommand, _ []string) error { + _, err := h.GetModuleDef(nil) if err != nil { return err } - - // TODO: allow .config (without args) to print current values? - - fn := def.MainObject.AsObject.Constructor - if err := ExactArgs(len(fn.RequiredArgs()))(args); err != nil { - usage := shellFunctionUseLine(def, fn) - return fmt.Errorf("the constructor %w\nusage: %s", err, usage) - } - - cfg, err := h.parseArgumentValues(cmd.Context(), def, fn, args) - if err != nil { - return err - } - - if st == nil { - h.cfg = cfg - return nil - } - - return cmd.Send(h.newState().WithCall(fn, cfg)) + return cmd.Send(h.newDepsState()) }, }, &ShellCommand{ - Use: ".deps", - Short: "List module dependencies", - GroupID: moduleGroup.ID, - Args: NoArgs, - RunState: func(cmd *ShellCommand, args []string, st *ShellState) error { - def, err := h.GetModuleDef(st) - if err != nil { - return err - } - - ctx := cmd.Context() - - deps, err := def.Source.AsModule().Dependencies(ctx) - if err != nil { - return err - } - - // Get the Name and Description of each dependency beforehand - // because nameShortWrapped doesn't handle errors. - lines := make([]string, 0, len(deps)) - for _, dep := range deps { - name, err := dep.Name(ctx) - if err != nil { - return err - } - desc, err := dep.Description(ctx) - if err != nil { - return err - } - shortDesc := strings.SplitN(desc, "\n", 2)[0] - if shortDesc == "" { - shortDesc = "-" - } - lines = append(lines, name+"\x00"+shortDesc) - } - - var doc ShellDoc - - doc.Add( - "Module Dependencies", - nameShortWrapped(lines, func(line string) (string, string) { - s := strings.SplitN(line, "\x00", 2) - return s[0], s[1] - }), - ) - - return cmd.Println(doc.String()) + Use: shellStdlibCmdName, + Description: "Standard library functions", + Args: NoArgs, + Run: func(cmd *ShellCommand, _ []string) error { + return cmd.Send(h.newStdlibState()) }, }, &ShellCommand{ - Use: ".core [function]", - Short: "Load a core Dagger type", - // On the "Additional" command group on purpose - GroupID: "", + Use: ".core [function]", + Description: "Load any core Dagger type", + Args: NoArgs, Run: func(cmd *ShellCommand, args []string) error { - ctx := cmd.Context() - - if len(args) == 0 { - var doc ShellDoc - - def := h.modDef(nil) - - doc.Add( - "Available Functions", - nameShortWrapped(def.GetCoreFunctions(), func(f *modFunction) (string, string) { - return f.CmdName(), f.Short() - }), - ) - - return cmd.Println(doc.String()) - } - - st, err := h.functionCall(ctx, h.newState(), args[0], args[1:]) - if err != nil { - return err - } - - return cmd.Send(st) + return cmd.Send(h.newCoreState()) }, }, + cobraToShellCommand(loginCmd), + cobraToShellCommand(logoutCmd), + cobraToShellCommand(moduleInstallCmd), + cobraToShellCommand(moduleUnInstallCmd), + // TODO: Add update command when available: + // - https://github.com/dagger/dagger/pull/8839 ) def := h.modDef(nil) @@ -1685,15 +2006,14 @@ func (h *shellCallHandler) registerBuiltins() { //nolint:gocyclo "version", } - hidden := !slices.Contains(promoted, fn.CmdName()) + if !slices.Contains(promoted, fn.CmdName()) { + continue + } - h.addBuiltin( + stdlib = append(stdlib, &ShellCommand{ - Use: shellFunctionUseLine(def, fn), - Short: fn.Short(), - GroupID: coreGroup.ID, - Hidden: hidden, - Args: ExactArgs(len(fn.RequiredArgs())), + Use: shellFunctionUseLine(def, fn), + Description: fn.Description, HelpFunc: func(cmd *ShellCommand) string { return shellFunctionDoc(def, fn) }, @@ -1712,23 +2032,23 @@ func (h *shellCallHandler) registerBuiltins() { //nolint:gocyclo ) } - h.addBuiltin( - // TODO: Add uninstall command when available. - cobraToShellCommand(moduleInstallCmd), - cobraToShellCommand(loginCmd), - cobraToShellCommand(logoutCmd), - ) + sort.Slice(builtins, func(i, j int) bool { + return builtins[i].Use < builtins[j].Use + }) - sort.Slice(h.builtins, func(i, j int) bool { - return h.builtins[i].Use < h.builtins[j].Use + sort.Slice(stdlib, func(i, j int) bool { + return stdlib[i].Use < stdlib[j].Use }) + + h.builtins = builtins + h.stdlib = stdlib } func cobraToShellCommand(c *cobra.Command) *ShellCommand { return &ShellCommand{ - Use: "." + c.Use, - Short: c.Short, - GroupID: c.GroupID, + Use: "." + c.Use, + Description: c.Short, + GroupID: c.GroupID, Run: func(cmd *ShellCommand, args []string) error { // Re-execute the dagger command (hack) args = append([]string{cmd.CleanName()}, args...) diff --git a/core/integration/module_shell_test.go b/core/integration/module_shell_test.go index 5f52dfcafd..53e22b208e 100644 --- a/core/integration/module_shell_test.go +++ b/core/integration/module_shell_test.go @@ -2,7 +2,7 @@ package core import ( "context" - "fmt" + "regexp" "testing" "dagger.io/dagger" @@ -24,9 +24,9 @@ func daggerShell(script string) dagger.WithContainerFunc { } } -func daggerShellNoLoad(script string) dagger.WithContainerFunc { +func daggerShellNoMod(script string) dagger.WithContainerFunc { return func(c *dagger.Container) *dagger.Container { - return c.WithExec([]string{"dagger", "shell", "--no-load", "-c", script}, dagger.ContainerWithExecOpts{ + return c.WithExec([]string{"dagger", "shell", "--no-mod", "-c", script}, dagger.ContainerWithExecOpts{ ExperimentalPrivilegedNesting: true, }) } @@ -54,44 +54,342 @@ func (m *Test) Container() *dagger.Container { require.Contains(t, out, "Alpine Linux") } -func (ShellSuite) TestForceCore(ctx context.Context, t *testctx.T) { +func (ShellSuite) TestModuleLookup(ctx context.Context, t *testctx.T) { c := connect(ctx, t) - out, err := modInit(t, c, "go", `package main + setup := modInit(t, c, "go", `// Main module + +package main import ( "dagger/test/internal/dagger" ) -type Test struct{} +func New( + // +defaultPath=. + source *dagger.Directory, +) *Test { + return &Test{Source: source} +} -func (m *Test) Container() *dagger.Container { - return dag.Container().From("`+golangImage+`") +// Test main object +type Test struct{ + Source *dagger.Directory +} + +// Test version +func (Test) Version() string { + return "test function" } + +// Encouragement +func (Test) Go() string { + return "Let's go!" +} `, ). - With(daggerShell(fmt.Sprintf(".container | from %s | with-exec cat,/etc/os-release | stdout", alpineImage))). - Stdout(ctx) - require.NoError(t, err) - require.Contains(t, out, "Alpine Linux") + With(withModInitAt("modules/dep", "go", `// Dependency module + +package main + +type Dep struct{} + +// Dep version +func (Dep) Version() string { + return "dep function" +} +`, + )). + With(withModInitAt("modules/git", "go", `// A git helper + +package main + +func New(url string) *Git { + return &Git{URL: url} +} + +type Git struct{ + URL string +} +`, + )). + With(withModInitAt("modules/go", "go", `// A go helper + +package main + +type Go struct{} + +// Go version +func (Go) Version() string { + return "go version" +} +`, + )). + With(withModInitAt("other", "go", `// A local module + +package main + +type Other struct{} + +func (Other) Version() string { + return "other function" +} +`, + )). + With(daggerExec("install", "./modules/dep")). + With(daggerExec("install", "./modules/git")). + With(daggerExec("install", "./modules/go")) + + t.Run("current module doc", func(ctx context.Context, t *testctx.T) { + out, err := setup. + With(daggerShell(".doc")). + Stdout(ctx) + require.NoError(t, err) + require.Contains(t, out, "MODULE") + require.Contains(t, out, "Main module") + require.Contains(t, out, "ENTRYPOINT") + require.Contains(t, out, "Usage: . [options]") + require.Contains(t, out, "AVAILABLE FUNCTIONS") + require.Contains(t, out, "Encouragement") + }) + + t.Run("current module function takes precedence over dependency", func(ctx context.Context, t *testctx.T) { + out, err := setup. + With(daggerShell("go")). + Stdout(ctx) + require.NoError(t, err) + require.Equal(t, "Let's go!", out) + }) + + t.Run("current module function doc takes precedence over dependency", func(ctx context.Context, t *testctx.T) { + out, err := setup. + With(daggerShell(".doc go")). + Stdout(ctx) + require.NoError(t, err) + require.Contains(t, out, "Encouragement") + require.Contains(t, out, "RETURNS") + }) + + t.Run("disambiguate dependency function", func(ctx context.Context, t *testctx.T) { + out, err := setup. + With(daggerShell(".deps | go | version")). + Stdout(ctx) + require.NoError(t, err) + require.Equal(t, "go version", out) + }) + + t.Run("disambiguate dependency function doc", func(ctx context.Context, t *testctx.T) { + out, err := setup. + With(daggerShell(".deps | .doc go")). + Stdout(ctx) + require.NoError(t, err) + require.Contains(t, out, "MODULE") + require.Contains(t, out, "A go helper") + }) + + t.Run("current module function takes precedence over stdlib", func(ctx context.Context, t *testctx.T) { + out, err := setup. + With(daggerShell("version")). + Stdout(ctx) + require.NoError(t, err) + require.Contains(t, out, "test function") + }) + + t.Run("current module function doc takes precedence over stdlib", func(ctx context.Context, t *testctx.T) { + out, err := setup. + With(daggerShell(".doc version")). + Stdout(ctx) + require.NoError(t, err) + require.Contains(t, out, "Test version") + }) + + t.Run("disambiguate stdlib command", func(ctx context.Context, t *testctx.T) { + out, err := setup. + With(daggerShell(".stdlib | version")). + Stdout(ctx) + require.NoError(t, err) + require.Regexp(t, regexp.MustCompile(`^v0.\d+`), out) + }) + + t.Run("disambiguate stdlib command doc", func(ctx context.Context, t *testctx.T) { + out, err := setup. + With(daggerShell(".stdlib | .doc version")). + Stdout(ctx) + require.NoError(t, err) + require.Contains(t, out, "Get the current Dagger Engine version.") + require.Contains(t, out, "RETURNS") + }) + + t.Run("dependency module function takes precedence over stdlib", func(ctx context.Context, t *testctx.T) { + out, err := setup. + With(daggerShell("git acme.org | url")). + Stdout(ctx) + require.NoError(t, err) + require.Equal(t, "acme.org", out) + }) + + t.Run("dependency module function doc takes precedence over stdlib", func(ctx context.Context, t *testctx.T) { + out, err := setup. + With(daggerShell(".doc git")). + Stdout(ctx) + require.NoError(t, err) + require.Contains(t, out, "A git helper") + require.Contains(t, out, "ENTRYPOINT") + require.NotContains(t, out, "AVAILABLE FUNCTIONS") + }) + + t.Run("other module function", func(ctx context.Context, t *testctx.T) { + out, err := setup. + With(daggerShell("other | version")). + Stdout(ctx) + require.NoError(t, err) + require.Equal(t, "other function", out) + }) + + t.Run("other module doc", func(ctx context.Context, t *testctx.T) { + out, err := setup. + With(daggerShell(".doc other")). + Stdout(ctx) + require.NoError(t, err) + require.Contains(t, out, "A local module") + require.NotContains(t, out, "ENTRYPOINT") + require.NotContains(t, out, "AVAILABLE FUNCTIONS") + }) + + t.Run("current module required constructor arg error", func(ctx context.Context, t *testctx.T) { + _, err := setup. + WithWorkdir("modules/git"). + With(daggerShell("url")). + Sync(ctx) + requireErrOut(t, err, "constructor: missing 1 positional argument") + }) + + t.Run("current module required constructor arg function", func(ctx context.Context, t *testctx.T) { + out, err := setup. + WithWorkdir("modules/git"). + With(daggerShell(". acme.org | url")). + Stdout(ctx) + require.NoError(t, err) + require.Equal(t, "acme.org", out) + }) + + t.Run("dep result", func(ctx context.Context, t *testctx.T) { + out, err := setup. + With(daggerShell("dep")). + Stdout(ctx) + require.NoError(t, err) + require.JSONEq(t, `{"_type": "Dep"}`, out) + }) + + t.Run("dep doc type", func(ctx context.Context, t *testctx.T) { + out, err := setup. + With(daggerShell("dep | .doc")). + Stdout(ctx) + require.NoError(t, err) + require.Contains(t, out, "OBJECT") + require.Contains(t, out, "\n Dep\n") + require.Regexp(t, regexp.MustCompile("\n version +Dep version"), out) + }) + + t.Run("deps result", func(ctx context.Context, t *testctx.T) { + out, err := setup. + With(daggerShell(".deps")). + Stdout(ctx) + require.NoError(t, err) + require.Contains(t, out, "- dep") + require.Contains(t, out, "- git") + require.Contains(t, out, "- go") + }) + + t.Run("deps doc", func(ctx context.Context, t *testctx.T) { + out, err := setup. + With(daggerShell(".deps | .doc")). + Stdout(ctx) + require.NoError(t, err) + require.Regexp(t, regexp.MustCompile(`\n dep +Dependency module`), out) + require.Regexp(t, regexp.MustCompile(`\n git +A git helper`), out) + require.Regexp(t, regexp.MustCompile(`\n go +A go helper`), out) + }) + + t.Run("deps doc module", func(ctx context.Context, t *testctx.T) { + out, err := setup. + With(daggerShell(".deps | .doc go")). + Stdout(ctx) + require.NoError(t, err) + require.Contains(t, out, "MODULE") + require.Contains(t, out, "A go helper") + }) + + t.Run("stdlib result", func(ctx context.Context, t *testctx.T) { + out, err := setup. + With(daggerShell(".stdlib")). + Stdout(ctx) + require.NoError(t, err) + require.Contains(t, out, "version") + require.NotContains(t, out, "Get the current Dagger Engine version") + require.NotContains(t, out, "load-container-from-id") + }) + + t.Run("stdlib doc", func(ctx context.Context, t *testctx.T) { + out, err := setup. + With(daggerShell(".stdlib | .doc")). + Stdout(ctx) + require.NoError(t, err) + require.Contains(t, out, "version") + require.Contains(t, out, "Get the current Dagger Engine version") + require.NotContains(t, out, "load-container-from-id") + }) + + t.Run("stdlib doc function", func(ctx context.Context, t *testctx.T) { + out, err := setup. + With(daggerShell(".stdlib | .doc git")). + Stdout(ctx) + require.NoError(t, err) + require.Regexp(t, regexp.MustCompile(`^Queries a Git repository`), out) + require.Contains(t, out, "git [options]") + require.Contains(t, out, "RETURNS") + }) + + t.Run("core result", func(ctx context.Context, t *testctx.T) { + out, err := setup. + With(daggerShell(".core")). + Stdout(ctx) + require.NoError(t, err) + require.Contains(t, out, "- load-container-from-id") + require.NotContains(t, out, "Load a Container") + }) + + t.Run("core doc", func(ctx context.Context, t *testctx.T) { + out, err := setup. + With(daggerShell(".core | .doc")). + Stdout(ctx) + require.NoError(t, err) + require.Contains(t, out, "load-container-from-id") + require.Contains(t, out, "Load a Container from its ID") + }) + + t.Run("core doc function", func(ctx context.Context, t *testctx.T) { + out, err := setup. + With(daggerShell(".core | .doc load-container-from-id")). + Stdout(ctx) + require.NoError(t, err) + require.Regexp(t, regexp.MustCompile(`^Load a Container from its ID`), out) + require.Contains(t, out, "load-container-from-id ") + require.Contains(t, out, "RETURNS") + }) } func (ShellSuite) TestNoModule(ctx context.Context, t *testctx.T) { c := connect(ctx, t) modGen := daggerCliBase(t, c) - t.Run("first command no fallback to core", func(ctx context.Context, t *testctx.T) { - _, err := modGen.With(daggerShell("container")).Sync(ctx) - requireErrOut(t, err, "module not loaded") - }) - t.Run("module builtin does not work", func(ctx context.Context, t *testctx.T) { - _, err := modGen.With(daggerShell(".config")).Sync(ctx) + _, err := modGen.With(daggerShell(".deps")).Sync(ctx) requireErrOut(t, err, "module not loaded") }) - t.Run("no main object doc", func(ctx context.Context, t *testctx.T) { - _, err := modGen.With(daggerShell(".config")).Sync(ctx) + t.Run("no default module doc", func(ctx context.Context, t *testctx.T) { + _, err := modGen.With(daggerShell(".doc")).Sync(ctx) requireErrOut(t, err, "module not loaded") }) } @@ -109,7 +407,7 @@ func (ShellSuite) TestNoLoadModule(ctx context.Context, t *testctx.T) { t.Run("forced no load", func(ctx context.Context, t *testctx.T) { c := connect(ctx, t) _, err := modInit(t, c, "go", ""). - With(daggerShellNoLoad(".config")). + With(daggerShellNoMod(".deps")). Sync(ctx) requireErrOut(t, err, "module not loaded") }) @@ -117,7 +415,7 @@ func (ShellSuite) TestNoLoadModule(ctx context.Context, t *testctx.T) { t.Run("dynamically loaded", func(ctx context.Context, t *testctx.T) { c := connect(ctx, t) out, err := modInit(t, c, "go", ""). - With(daggerShellNoLoad(".load | .use; .doc")). + With(daggerShellNoMod(".use .; .doc")). Stdout(ctx) require.NoError(t, err) require.Contains(t, out, "container-echo") @@ -126,10 +424,20 @@ func (ShellSuite) TestNoLoadModule(ctx context.Context, t *testctx.T) { t.Run("stateless load", func(ctx context.Context, t *testctx.T) { c := connect(ctx, t) out, err := modInit(t, c, "go", ""). - With(daggerShellNoLoad(".load | .doc")). + With(daggerShellNoMod(". | .doc container-echo")). Stdout(ctx) require.NoError(t, err) - require.Contains(t, out, "container-echo") + require.Contains(t, out, "echoes whatever string argument") + }) + + t.Run("stateless .doc load", func(ctx context.Context, t *testctx.T) { + c := connect(ctx, t) + out, err := modInit(t, c, "go", ""). + With(daggerShellNoMod(".doc .")). + Stdout(ctx) + require.NoError(t, err) + require.Contains(t, out, "MODULE") + require.Contains(t, out, "A generated module for Test functions") }) } @@ -160,7 +468,7 @@ type Foo struct{ out, err := modInit(t, c, "go", test). With(daggerExec("init", "--sdk=go", "--source=foo", "foo")). With(sdkSourceAt("foo", "go", foo)). - With(daggerShell(".load foo")). + With(daggerShell("foo")). Stdout(ctx) require.NoError(t, err) require.JSONEq(t, `{"_type": "Foo", "bar": "foobar"}`, out) @@ -171,7 +479,7 @@ type Foo struct{ out, err := modInit(t, c, "go", test). With(daggerExec("init", "--sdk=go", "--source=foo", "foo")). With(sdkSourceAt("foo", "go", foo)). - With(daggerShell(".load foo | .use; bar")). + With(daggerShell(".use foo; bar")). Stdout(ctx) require.NoError(t, err) require.Contains(t, out, "foobar") @@ -184,7 +492,7 @@ type Foo struct{ With(sdkSourceAt("foo", "go", foo)) out, err := modGen. - With(daggerShell(".load foo | bar")). + With(daggerShell("foo | bar")). Stdout(ctx) require.NoError(t, err) require.Equal(t, "foobar", out) @@ -200,15 +508,15 @@ type Foo struct{ func (ShellSuite) TestNotExists(ctx context.Context, t *testctx.T) { c := connect(ctx, t) _, err := modInit(t, c, "go", ""). - With(daggerShell("container")). + With(daggerShell("load-container-from-id")). Sync(ctx) - requireErrOut(t, err, "no such function") + requireErrOut(t, err, "not found") } func (ShellSuite) TestIntegerArg(ctx context.Context, t *testctx.T) { c := connect(ctx, t) - script := ".container | with-exposed-port 80 | exposed-ports | port" + script := "container | with-exposed-port 80 | exposed-ports | port" out, err := daggerCliBase(t, c). With(daggerShell(script)). Stdout(ctx) @@ -219,7 +527,7 @@ func (ShellSuite) TestIntegerArg(ctx context.Context, t *testctx.T) { func (ShellSuite) TestExport(ctx context.Context, t *testctx.T) { c := connect(ctx, t) - script := ".directory | with-new-file foo bar | export mydir" + script := "directory | with-new-file foo bar | export mydir" out, err := daggerCliBase(t, c). With(daggerShell(script)). File("mydir/foo"). @@ -228,18 +536,6 @@ func (ShellSuite) TestExport(ctx context.Context, t *testctx.T) { require.Equal(t, "bar", out) } -func (ShellSuite) TestBasicGit(ctx context.Context, t *testctx.T) { - c := connect(ctx, t) - - script := ".git https://github.com/dagger/dagger | head | tree | file README.md | contents" - out, err := daggerCliBase(t, c). - With(withModInit("go", "")). - With(daggerShell(script)). - Stdout(ctx) - require.NoError(t, err) - require.Contains(t, out, "What is Dagger?") -} - func (ShellSuite) TestBasicModule(ctx context.Context, t *testctx.T) { c := connect(ctx, t) @@ -266,7 +562,7 @@ func (m *Test) DirectoryID(ctx context.Context) (string, error) { return string(id), err } ` - script := ".load-directory-from-id $(directory-id) | file foo | contents" + script := ".core | load-directory-from-id $(directory-id) | file foo | contents" out, err := modInit(t, c, "go", source). With(daggerShell(script)). @@ -276,40 +572,6 @@ func (m *Test) DirectoryID(ctx context.Context) (string, error) { require.Equal(t, "bar", out) } -func (ShellSuite) TestModuleDoc(ctx context.Context, t *testctx.T) { - c := connect(ctx, t) - - source := `// This is a test module - -package main - -// The entrypoint for the module -func New(foo string, bar string) *Test { - return &Test{ - Foo: foo, - Bar: bar, - } -} - -type Test struct{ - Foo string - Bar string -} - -// Some function -func (m *Test) FooBar() string { - return m.Foo+m.Bar -} -` - out, err := modInit(t, c, "go", source). - With(daggerShell(".doc")). - Stdout(ctx) - require.NoError(t, err) - require.Contains(t, out, "\n test\n \n This is a test module") - require.Contains(t, out, "Usage: .config \n \n The entrypoint for the module") - require.Regexp(t, "foo-bar +Some function", out) -} - func (ShellSuite) TestInstall(ctx context.Context, t *testctx.T) { c := connect(ctx, t) diff --git a/core/schema/module.go b/core/schema/module.go index 8d493813c2..045978b595 100644 --- a/core/schema/module.go +++ b/core/schema/module.go @@ -157,6 +157,9 @@ func (s *moduleSchema) Install() { dagql.Func("asString", s.moduleSourceAsString). Doc(`A human readable ref string representation of this module source.`), + dagql.Func("pin", s.moduleSourcePin). + Doc(`The pinned version of this module source.`), + dagql.NodeFunc("asModule", s.moduleSourceAsModule). Doc(`Load the source as a module. If this is a local source, the parent directory must have been provided during module source creation`). ArgDoc("engineVersion", `The engine version to upgrade to.`), diff --git a/core/schema/modulesource.go b/core/schema/modulesource.go index e55d0755fe..998aafff76 100644 --- a/core/schema/modulesource.go +++ b/core/schema/modulesource.go @@ -377,6 +377,10 @@ func (s *moduleSchema) moduleSourceAsString(ctx context.Context, src *core.Modul return src.RefString() } +func (s *moduleSchema) moduleSourcePin(ctx context.Context, src *core.ModuleSource, args struct{}) (string, error) { + return src.Pin() +} + func (s *moduleSchema) gitModuleSourceHTMLURL( ctx context.Context, ref *core.GitModuleSource, @@ -897,7 +901,9 @@ func (s *moduleSchema) moduleSourceResolveFromCaller( // ensure sourceRootRelPath has a local path structure // even when subdir relative to git source has ref structure // (cf. test TestRefFormat) - sourceRootRelPath = "./" + sourceRootRelPath + if sourceRootRelPath != "." { + sourceRootRelPath = "./" + sourceRootRelPath + } collectedDeps := dagql.NewCacheMap[string, *callerLocalDep]() if err := s.collectCallerLocalDeps(ctx, src.Query, contextAbsPath, sourceRootAbsPath, true, src, collectedDeps); err != nil { diff --git a/docs/docs-graphql/schema.graphqls b/docs/docs-graphql/schema.graphqls index 6b3af23211..baa44cd567 100644 --- a/docs/docs-graphql/schema.graphqls +++ b/docs/docs-graphql/schema.graphqls @@ -2361,6 +2361,9 @@ type ModuleSource { """ moduleOriginalName: String! + """The pinned version of this module source.""" + pin: String! + """ The path to the module source's context directory on the caller's filesystem. Only valid for local sources. """ diff --git a/docs/static/api/reference/index.html b/docs/static/api/reference/index.html index fe3be842e3..ef1861d46c 100644 --- a/docs/static/api/reference/index.html +++ b/docs/static/api/reference/index.html @@ -8141,6 +8141,10 @@
pathmoduleOriginalName - String! The original name of the module this source references, as defined in the module configuration. + + pin - String! + The pinned version of this module source. + resolveContextPathFromCaller - String! The path to the module source's context directory on the caller's filesystem. Only valid for local sources. diff --git a/sdk/elixir/lib/dagger/gen/module_source.ex b/sdk/elixir/lib/dagger/gen/module_source.ex index 032e7b63f3..d833727f47 100644 --- a/sdk/elixir/lib/dagger/gen/module_source.ex +++ b/sdk/elixir/lib/dagger/gen/module_source.ex @@ -159,6 +159,15 @@ defmodule Dagger.ModuleSource do Client.execute(module_source.client, query_builder) end + @doc "The pinned version of this module source." + @spec pin(t()) :: {:ok, String.t()} | {:error, term()} + def pin(%__MODULE__{} = module_source) do + query_builder = + module_source.query_builder |> QB.select("pin") + + Client.execute(module_source.client, query_builder) + end + @doc "The path to the module source's context directory on the caller's filesystem. Only valid for local sources." @spec resolve_context_path_from_caller(t()) :: {:ok, String.t()} | {:error, term()} def resolve_context_path_from_caller(%__MODULE__{} = module_source) do diff --git a/sdk/go/dagger.gen.go b/sdk/go/dagger.gen.go index 545016e943..4780bfc09e 100644 --- a/sdk/go/dagger.gen.go +++ b/sdk/go/dagger.gen.go @@ -5916,6 +5916,7 @@ type ModuleSource struct { kind *ModuleSourceKind moduleName *string moduleOriginalName *string + pin *string resolveContextPathFromCaller *string sourceRootSubpath *string sourceSubpath *string @@ -6144,6 +6145,19 @@ func (r *ModuleSource) ModuleOriginalName(ctx context.Context) (string, error) { return response, q.Execute(ctx) } +// The pinned version of this module source. +func (r *ModuleSource) Pin(ctx context.Context) (string, error) { + if r.pin != nil { + return *r.pin, nil + } + q := r.query.Select("pin") + + var response string + + q = q.Bind(&response) + return response, q.Execute(ctx) +} + // The path to the module source's context directory on the caller's filesystem. Only valid for local sources. func (r *ModuleSource) ResolveContextPathFromCaller(ctx context.Context) (string, error) { if r.resolveContextPathFromCaller != nil { diff --git a/sdk/php/generated/ModuleSource.php b/sdk/php/generated/ModuleSource.php index fe5d73aeb8..521f2809c6 100644 --- a/sdk/php/generated/ModuleSource.php +++ b/sdk/php/generated/ModuleSource.php @@ -134,6 +134,15 @@ public function moduleOriginalName(): string return (string)$this->queryLeaf($leafQueryBuilder, 'moduleOriginalName'); } + /** + * The pinned version of this module source. + */ + public function pin(): string + { + $leafQueryBuilder = new \Dagger\Client\QueryBuilder('pin'); + return (string)$this->queryLeaf($leafQueryBuilder, 'pin'); + } + /** * The path to the module source's context directory on the caller's filesystem. Only valid for local sources. */ diff --git a/sdk/python/src/dagger/client/gen.py b/sdk/python/src/dagger/client/gen.py index 5560097785..edc90d67a4 100644 --- a/sdk/python/src/dagger/client/gen.py +++ b/sdk/python/src/dagger/client/gen.py @@ -6210,6 +6210,27 @@ async def module_original_name(self) -> str: _ctx = self._select("moduleOriginalName", _args) return await _ctx.execute(str) + async def pin(self) -> str: + """The pinned version of this module source. + + Returns + ------- + str + The `String` scalar type represents textual data, represented as + UTF-8 character sequences. The String type is most often used by + GraphQL to represent free-form human-readable text. + + Raises + ------ + ExecuteTimeoutError + If the time to execute the query exceeds the configured timeout. + QueryError + If the API returns an error. + """ + _args: list[Arg] = [] + _ctx = self._select("pin", _args) + return await _ctx.execute(str) + async def resolve_context_path_from_caller(self) -> str: """The path to the module source's context directory on the caller's filesystem. Only valid for local sources. diff --git a/sdk/rust/crates/dagger-sdk/src/gen.rs b/sdk/rust/crates/dagger-sdk/src/gen.rs index c15ec29384..39974bfa79 100644 --- a/sdk/rust/crates/dagger-sdk/src/gen.rs +++ b/sdk/rust/crates/dagger-sdk/src/gen.rs @@ -6444,6 +6444,11 @@ impl ModuleSource { let query = self.selection.select("moduleOriginalName"); query.execute(self.graphql_client.clone()).await } + /// The pinned version of this module source. + pub async fn pin(&self) -> Result { + let query = self.selection.select("pin"); + query.execute(self.graphql_client.clone()).await + } /// The path to the module source's context directory on the caller's filesystem. Only valid for local sources. pub async fn resolve_context_path_from_caller(&self) -> Result { let query = self.selection.select("resolveContextPathFromCaller"); diff --git a/sdk/typescript/src/api/client.gen.ts b/sdk/typescript/src/api/client.gen.ts index cb5ac9d48f..4a1f1ef262 100644 --- a/sdk/typescript/src/api/client.gen.ts +++ b/sdk/typescript/src/api/client.gen.ts @@ -5845,6 +5845,7 @@ export class ModuleSource extends BaseClient { private readonly _kind?: ModuleSourceKind = undefined private readonly _moduleName?: string = undefined private readonly _moduleOriginalName?: string = undefined + private readonly _pin?: string = undefined private readonly _resolveContextPathFromCaller?: string = undefined private readonly _sourceRootSubpath?: string = undefined private readonly _sourceSubpath?: string = undefined @@ -5861,6 +5862,7 @@ export class ModuleSource extends BaseClient { _kind?: ModuleSourceKind, _moduleName?: string, _moduleOriginalName?: string, + _pin?: string, _resolveContextPathFromCaller?: string, _sourceRootSubpath?: string, _sourceSubpath?: string, @@ -5874,6 +5876,7 @@ export class ModuleSource extends BaseClient { this._kind = _kind this._moduleName = _moduleName this._moduleOriginalName = _moduleOriginalName + this._pin = _pin this._resolveContextPathFromCaller = _resolveContextPathFromCaller this._sourceRootSubpath = _sourceRootSubpath this._sourceSubpath = _sourceSubpath @@ -6055,6 +6058,21 @@ export class ModuleSource extends BaseClient { return response } + /** + * The pinned version of this module source. + */ + pin = async (): Promise => { + if (this._pin) { + return this._pin + } + + const ctx = this._ctx.select("pin") + + const response: Awaited = await ctx.execute() + + return response + } + /** * The path to the module source's context directory on the caller's filesystem. Only valid for local sources. */ From d24b648f1ce6ddafba322aae48f37f08e548cb83 Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Tue, 10 Dec 2024 13:34:58 +0000 Subject: [PATCH 17/35] chore: update telemetry golden tests (#9157) Signed-off-by: Justin Chadwell --- dagql/idtui/testdata/TestTelemetry/TestGolden/cached-execs | 7 ++++--- dagql/idtui/testdata/TestTelemetry/TestGolden/custom-span | 7 ++++--- dagql/idtui/testdata/TestTelemetry/TestGolden/docker-build | 7 ++++--- .../testdata/TestTelemetry/TestGolden/docker-build-fail | 7 ++++--- dagql/idtui/testdata/TestTelemetry/TestGolden/encapsulate | 7 ++++--- dagql/idtui/testdata/TestTelemetry/TestGolden/fail-effect | 7 ++++--- dagql/idtui/testdata/TestTelemetry/TestGolden/fail-log | 7 ++++--- .../testdata/TestTelemetry/TestGolden/fail-log-native | 7 ++++--- dagql/idtui/testdata/TestTelemetry/TestGolden/hello-world | 7 ++++--- dagql/idtui/testdata/TestTelemetry/TestGolden/pending | 7 ++++--- .../TestTelemetry/TestGolden/use-cached-exec-service | 7 ++++--- .../testdata/TestTelemetry/TestGolden/use-exec-service | 7 ++++--- .../testdata/TestTelemetry/TestGolden/use-no-exec-service | 7 ++++--- .../TestTelemetry/TestGolden/viztest/broken/broken | 4 ++-- .../TestTelemetry/TestGolden/viztest/python/custom-span | 7 ++++--- .../TestTelemetry/TestGolden/viztest/python/pending | 7 ++++--- .../TestGolden/viztest/typescript/custom-span | 7 ++++--- .../TestTelemetry/TestGolden/viztest/typescript/pending | 7 ++++--- 18 files changed, 70 insertions(+), 53 deletions(-) diff --git a/dagql/idtui/testdata/TestTelemetry/TestGolden/cached-execs b/dagql/idtui/testdata/TestTelemetry/TestGolden/cached-execs index 9a5032d9ce..68c4ae7639 100644 --- a/dagql/idtui/testdata/TestTelemetry/TestGolden/cached-execs +++ b/dagql/idtui/testdata/TestTelemetry/TestGolden/cached-execs @@ -5,10 +5,11 @@ Expected stderr: โ”‚ โœ” connecting to engine X.Xs โ”‚ โœ” starting session X.Xs -โœ” loading module X.Xs +โœ” load module X.Xs โ”‚ โœ” finding module configuration X.Xs -โ”‚ โœ” serving module X.Xs -โ”‚ โœ” inspecting module X.Xs +โ”‚ โœ” initializing module X.Xs +โ”‚ โœ” inspecting module metadata X.Xs +โ”‚ โœ” loading type definitions X.Xs โœ” parsing command line arguments X.Xs diff --git a/dagql/idtui/testdata/TestTelemetry/TestGolden/custom-span b/dagql/idtui/testdata/TestTelemetry/TestGolden/custom-span index 1bf1ca0ca2..7bc80f1de7 100644 --- a/dagql/idtui/testdata/TestTelemetry/TestGolden/custom-span +++ b/dagql/idtui/testdata/TestTelemetry/TestGolden/custom-span @@ -10,10 +10,11 @@ Expected stderr: โ”‚ โœ” connecting to engine X.Xs โ”‚ โœ” starting session X.Xs -โœ” loading module X.Xs +โœ” load module X.Xs โ”‚ โœ” finding module configuration X.Xs -โ”‚ โœ” serving module X.Xs -โ”‚ โœ” inspecting module X.Xs +โ”‚ โœ” initializing module X.Xs +โ”‚ โœ” inspecting module metadata X.Xs +โ”‚ โœ” loading type definitions X.Xs โœ” parsing command line arguments X.Xs diff --git a/dagql/idtui/testdata/TestTelemetry/TestGolden/docker-build b/dagql/idtui/testdata/TestTelemetry/TestGolden/docker-build index 21f99296de..d2ad6f1b9a 100644 --- a/dagql/idtui/testdata/TestTelemetry/TestGolden/docker-build +++ b/dagql/idtui/testdata/TestTelemetry/TestGolden/docker-build @@ -10,10 +10,11 @@ Expected stderr: โ”‚ โœ” connecting to engine X.Xs โ”‚ โœ” starting session X.Xs -โœ” loading module X.Xs +โœ” load module X.Xs โ”‚ โœ” finding module configuration X.Xs -โ”‚ โœ” serving module X.Xs -โ”‚ โœ” inspecting module X.Xs +โ”‚ โœ” initializing module X.Xs +โ”‚ โœ” inspecting module metadata X.Xs +โ”‚ โœ” loading type definitions X.Xs โœ” parsing command line arguments X.Xs diff --git a/dagql/idtui/testdata/TestTelemetry/TestGolden/docker-build-fail b/dagql/idtui/testdata/TestTelemetry/TestGolden/docker-build-fail index f51e4e2223..c4b3a9ed50 100644 --- a/dagql/idtui/testdata/TestTelemetry/TestGolden/docker-build-fail +++ b/dagql/idtui/testdata/TestTelemetry/TestGolden/docker-build-fail @@ -5,10 +5,11 @@ Expected stderr: โ”‚ โœ” connecting to engine X.Xs โ”‚ โœ” starting session X.Xs -โœ” loading module X.Xs +โœ” load module X.Xs โ”‚ โœ” finding module configuration X.Xs -โ”‚ โœ” serving module X.Xs -โ”‚ โœ” inspecting module X.Xs +โ”‚ โœ” initializing module X.Xs +โ”‚ โœ” inspecting module metadata X.Xs +โ”‚ โœ” loading type definitions X.Xs โœ” parsing command line arguments X.Xs diff --git a/dagql/idtui/testdata/TestTelemetry/TestGolden/encapsulate b/dagql/idtui/testdata/TestTelemetry/TestGolden/encapsulate index 8deaf8e9ea..b64d22e215 100644 --- a/dagql/idtui/testdata/TestTelemetry/TestGolden/encapsulate +++ b/dagql/idtui/testdata/TestTelemetry/TestGolden/encapsulate @@ -5,10 +5,11 @@ Expected stderr: โ”‚ โœ” connecting to engine X.Xs โ”‚ โœ” starting session X.Xs -โœ” loading module X.Xs +โœ” load module X.Xs โ”‚ โœ” finding module configuration X.Xs -โ”‚ โœ” serving module X.Xs -โ”‚ โœ” inspecting module X.Xs +โ”‚ โœ” initializing module X.Xs +โ”‚ โœ” inspecting module metadata X.Xs +โ”‚ โœ” loading type definitions X.Xs โœ” parsing command line arguments X.Xs diff --git a/dagql/idtui/testdata/TestTelemetry/TestGolden/fail-effect b/dagql/idtui/testdata/TestTelemetry/TestGolden/fail-effect index a4fa9a6dc1..795628f06d 100644 --- a/dagql/idtui/testdata/TestTelemetry/TestGolden/fail-effect +++ b/dagql/idtui/testdata/TestTelemetry/TestGolden/fail-effect @@ -5,10 +5,11 @@ Expected stderr: โ”‚ โœ” connecting to engine X.Xs โ”‚ โœ” starting session X.Xs -โœ” loading module X.Xs +โœ” load module X.Xs โ”‚ โœ” finding module configuration X.Xs -โ”‚ โœ” serving module X.Xs -โ”‚ โœ” inspecting module X.Xs +โ”‚ โœ” initializing module X.Xs +โ”‚ โœ” inspecting module metadata X.Xs +โ”‚ โœ” loading type definitions X.Xs โœ” parsing command line arguments X.Xs diff --git a/dagql/idtui/testdata/TestTelemetry/TestGolden/fail-log b/dagql/idtui/testdata/TestTelemetry/TestGolden/fail-log index 2c784dd1dd..b0e70613c5 100644 --- a/dagql/idtui/testdata/TestTelemetry/TestGolden/fail-log +++ b/dagql/idtui/testdata/TestTelemetry/TestGolden/fail-log @@ -5,10 +5,11 @@ Expected stderr: โ”‚ โœ” connecting to engine X.Xs โ”‚ โœ” starting session X.Xs -โœ” loading module X.Xs +โœ” load module X.Xs โ”‚ โœ” finding module configuration X.Xs -โ”‚ โœ” serving module X.Xs -โ”‚ โœ” inspecting module X.Xs +โ”‚ โœ” initializing module X.Xs +โ”‚ โœ” inspecting module metadata X.Xs +โ”‚ โœ” loading type definitions X.Xs โœ” parsing command line arguments X.Xs diff --git a/dagql/idtui/testdata/TestTelemetry/TestGolden/fail-log-native b/dagql/idtui/testdata/TestTelemetry/TestGolden/fail-log-native index 3d7cbe33da..384eeca2dd 100644 --- a/dagql/idtui/testdata/TestTelemetry/TestGolden/fail-log-native +++ b/dagql/idtui/testdata/TestTelemetry/TestGolden/fail-log-native @@ -5,10 +5,11 @@ Expected stderr: โ”‚ โœ” connecting to engine X.Xs โ”‚ โœ” starting session X.Xs -โœ” loading module X.Xs +โœ” load module X.Xs โ”‚ โœ” finding module configuration X.Xs -โ”‚ โœ” serving module X.Xs -โ”‚ โœ” inspecting module X.Xs +โ”‚ โœ” initializing module X.Xs +โ”‚ โœ” inspecting module metadata X.Xs +โ”‚ โœ” loading type definitions X.Xs โœ” parsing command line arguments X.Xs diff --git a/dagql/idtui/testdata/TestTelemetry/TestGolden/hello-world b/dagql/idtui/testdata/TestTelemetry/TestGolden/hello-world index 0914ac15bb..8d2416ad56 100644 --- a/dagql/idtui/testdata/TestTelemetry/TestGolden/hello-world +++ b/dagql/idtui/testdata/TestTelemetry/TestGolden/hello-world @@ -9,10 +9,11 @@ Expected stderr: โ”‚ โœ” connecting to engine X.Xs โ”‚ โœ” starting session X.Xs -โœ” loading module X.Xs +โœ” load module X.Xs โ”‚ โœ” finding module configuration X.Xs -โ”‚ โœ” serving module X.Xs -โ”‚ โœ” inspecting module X.Xs +โ”‚ โœ” initializing module X.Xs +โ”‚ โœ” inspecting module metadata X.Xs +โ”‚ โœ” loading type definitions X.Xs โœ” parsing command line arguments X.Xs diff --git a/dagql/idtui/testdata/TestTelemetry/TestGolden/pending b/dagql/idtui/testdata/TestTelemetry/TestGolden/pending index 92e611c4c4..53b9d1b949 100644 --- a/dagql/idtui/testdata/TestTelemetry/TestGolden/pending +++ b/dagql/idtui/testdata/TestTelemetry/TestGolden/pending @@ -5,10 +5,11 @@ Expected stderr: โ”‚ โœ” connecting to engine X.Xs โ”‚ โœ” starting session X.Xs -โœ” loading module X.Xs +โœ” load module X.Xs โ”‚ โœ” finding module configuration X.Xs -โ”‚ โœ” serving module X.Xs -โ”‚ โœ” inspecting module X.Xs +โ”‚ โœ” initializing module X.Xs +โ”‚ โœ” inspecting module metadata X.Xs +โ”‚ โœ” loading type definitions X.Xs โœ” parsing command line arguments X.Xs diff --git a/dagql/idtui/testdata/TestTelemetry/TestGolden/use-cached-exec-service b/dagql/idtui/testdata/TestTelemetry/TestGolden/use-cached-exec-service index 647a9bb63b..89887d223a 100644 --- a/dagql/idtui/testdata/TestTelemetry/TestGolden/use-cached-exec-service +++ b/dagql/idtui/testdata/TestTelemetry/TestGolden/use-cached-exec-service @@ -5,10 +5,11 @@ Expected stderr: โ”‚ โœ” connecting to engine X.Xs โ”‚ โœ” starting session X.Xs -โœ” loading module X.Xs +โœ” load module X.Xs โ”‚ โœ” finding module configuration X.Xs -โ”‚ โœ” serving module X.Xs -โ”‚ โœ” inspecting module X.Xs +โ”‚ โœ” initializing module X.Xs +โ”‚ โœ” inspecting module metadata X.Xs +โ”‚ โœ” loading type definitions X.Xs โœ” parsing command line arguments X.Xs diff --git a/dagql/idtui/testdata/TestTelemetry/TestGolden/use-exec-service b/dagql/idtui/testdata/TestTelemetry/TestGolden/use-exec-service index 037fd85ba0..2333d5462d 100644 --- a/dagql/idtui/testdata/TestTelemetry/TestGolden/use-exec-service +++ b/dagql/idtui/testdata/TestTelemetry/TestGolden/use-exec-service @@ -5,10 +5,11 @@ Expected stderr: โ”‚ โœ” connecting to engine X.Xs โ”‚ โœ” starting session X.Xs -โœ” loading module X.Xs +โœ” load module X.Xs โ”‚ โœ” finding module configuration X.Xs -โ”‚ โœ” serving module X.Xs -โ”‚ โœ” inspecting module X.Xs +โ”‚ โœ” initializing module X.Xs +โ”‚ โœ” inspecting module metadata X.Xs +โ”‚ โœ” loading type definitions X.Xs โœ” parsing command line arguments X.Xs diff --git a/dagql/idtui/testdata/TestTelemetry/TestGolden/use-no-exec-service b/dagql/idtui/testdata/TestTelemetry/TestGolden/use-no-exec-service index abde6a61fb..14f1b4af36 100644 --- a/dagql/idtui/testdata/TestTelemetry/TestGolden/use-no-exec-service +++ b/dagql/idtui/testdata/TestTelemetry/TestGolden/use-no-exec-service @@ -10,10 +10,11 @@ Expected stderr: โ”‚ โœ” connecting to engine X.Xs โ”‚ โœ” starting session X.Xs -โœ” loading module X.Xs +โœ” load module X.Xs โ”‚ โœ” finding module configuration X.Xs -โ”‚ โœ” serving module X.Xs -โ”‚ โœ” inspecting module X.Xs +โ”‚ โœ” initializing module X.Xs +โ”‚ โœ” inspecting module metadata X.Xs +โ”‚ โœ” loading type definitions X.Xs โœ” parsing command line arguments X.Xs diff --git a/dagql/idtui/testdata/TestTelemetry/TestGolden/viztest/broken/broken b/dagql/idtui/testdata/TestTelemetry/TestGolden/viztest/broken/broken index c15f35384a..b505a0bf30 100644 --- a/dagql/idtui/testdata/TestTelemetry/TestGolden/viztest/broken/broken +++ b/dagql/idtui/testdata/TestTelemetry/TestGolden/viztest/broken/broken @@ -5,10 +5,10 @@ Expected stderr: โ”‚ โœ” connecting to engine X.Xs โ”‚ โœ” starting session X.Xs -โœ˜ loading module X.Xs +โœ˜ load module X.Xs ! failed to serve module: input: module.withSource.initialize failed to initialize module: failed to call module "broken" to get functions: call constructor: process "go build -ldflags -s -w -o /runtime ." did not complete successfully: exit code: 1 โ”‚ โœ” finding module configuration X.Xs -โ”‚ โœ˜ serving module X.Xs +โ”‚ โœ˜ initializing module X.Xs โ”‚ ! input: module.withSource.initialize failed to initialize module: failed to call module "broken" to get functions: call constructor: process "go build -ldflags -s -w -o /runtime ." did not complete successfully: exit code: 1 โ”‚ โ”‚ $ ModuleSource.resolveFromCaller: ModuleSource! X.Xs CACHED โ”‚ โ”‚ โ”‚ โœ” upload /XXX/XXX/XXX from XXXXXXXXXXX (client id: XXXXXXXXXXX, session id: XXXXXXXXXXX) (include: XXXXXXXXXXX) (exclude: XXXXXXXXXXX) X.Xs diff --git a/dagql/idtui/testdata/TestTelemetry/TestGolden/viztest/python/custom-span b/dagql/idtui/testdata/TestTelemetry/TestGolden/viztest/python/custom-span index 6de2837d2a..1fb8ba0fb0 100644 --- a/dagql/idtui/testdata/TestTelemetry/TestGolden/viztest/python/custom-span +++ b/dagql/idtui/testdata/TestTelemetry/TestGolden/viztest/python/custom-span @@ -10,10 +10,11 @@ Expected stderr: โ”‚ โœ” connecting to engine X.Xs โ”‚ โœ” starting session X.Xs -โœ” loading module X.Xs +โœ” load module X.Xs โ”‚ โœ” finding module configuration X.Xs -โ”‚ โœ” serving module X.Xs -โ”‚ โœ” inspecting module X.Xs +โ”‚ โœ” initializing module X.Xs +โ”‚ โœ” inspecting module metadata X.Xs +โ”‚ โœ” loading type definitions X.Xs โœ” parsing command line arguments X.Xs diff --git a/dagql/idtui/testdata/TestTelemetry/TestGolden/viztest/python/pending b/dagql/idtui/testdata/TestTelemetry/TestGolden/viztest/python/pending index e2aebe91a4..49cc8787d0 100644 --- a/dagql/idtui/testdata/TestTelemetry/TestGolden/viztest/python/pending +++ b/dagql/idtui/testdata/TestTelemetry/TestGolden/viztest/python/pending @@ -5,10 +5,11 @@ Expected stderr: โ”‚ โœ” connecting to engine X.Xs โ”‚ โœ” starting session X.Xs -โœ” loading module X.Xs +โœ” load module X.Xs โ”‚ โœ” finding module configuration X.Xs -โ”‚ โœ” serving module X.Xs -โ”‚ โœ” inspecting module X.Xs +โ”‚ โœ” initializing module X.Xs +โ”‚ โœ” inspecting module metadata X.Xs +โ”‚ โœ” loading type definitions X.Xs โœ” parsing command line arguments X.Xs diff --git a/dagql/idtui/testdata/TestTelemetry/TestGolden/viztest/typescript/custom-span b/dagql/idtui/testdata/TestTelemetry/TestGolden/viztest/typescript/custom-span index f57912f896..358777d97f 100644 --- a/dagql/idtui/testdata/TestTelemetry/TestGolden/viztest/typescript/custom-span +++ b/dagql/idtui/testdata/TestTelemetry/TestGolden/viztest/typescript/custom-span @@ -10,10 +10,11 @@ Expected stderr: โ”‚ โœ” connecting to engine X.Xs โ”‚ โœ” starting session X.Xs -โœ” loading module X.Xs +โœ” load module X.Xs โ”‚ โœ” finding module configuration X.Xs -โ”‚ โœ” serving module X.Xs -โ”‚ โœ” inspecting module X.Xs +โ”‚ โœ” initializing module X.Xs +โ”‚ โœ” inspecting module metadata X.Xs +โ”‚ โœ” loading type definitions X.Xs โœ” parsing command line arguments X.Xs diff --git a/dagql/idtui/testdata/TestTelemetry/TestGolden/viztest/typescript/pending b/dagql/idtui/testdata/TestTelemetry/TestGolden/viztest/typescript/pending index 6640e9115f..0b7531a0b4 100644 --- a/dagql/idtui/testdata/TestTelemetry/TestGolden/viztest/typescript/pending +++ b/dagql/idtui/testdata/TestTelemetry/TestGolden/viztest/typescript/pending @@ -5,10 +5,11 @@ Expected stderr: โ”‚ โœ” connecting to engine X.Xs โ”‚ โœ” starting session X.Xs -โœ” loading module X.Xs +โœ” load module X.Xs โ”‚ โœ” finding module configuration X.Xs -โ”‚ โœ” serving module X.Xs -โ”‚ โœ” inspecting module X.Xs +โ”‚ โœ” initializing module X.Xs +โ”‚ โœ” inspecting module metadata X.Xs +โ”‚ โœ” loading type definitions X.Xs โœ” parsing command line arguments X.Xs From 8b9fbf5c643285eba1887292a79050540e399955 Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Tue, 10 Dec 2024 14:10:04 +0000 Subject: [PATCH 18/35] chore: prep for v0.15.0 (#9158) * chore: bump dependencies to v0.15.0 Signed-off-by: Justin Chadwell * chore: add release notes for v0.15.0 Signed-off-by: Justin Chadwell * chore: bump next version to v0.15.1 Signed-off-by: Justin Chadwell --------- Signed-off-by: Justin Chadwell --- .changes/.next | 2 +- .../unreleased/Added-20241026-123323.yaml | 6 -- .../unreleased/Added-20241114-115027.yaml | 6 -- .../unreleased/Added-20241114-123823.yaml | 6 -- .../unreleased/Added-20241120-140601.yaml | 15 --- .../unreleased/Added-20241126-203335.yaml | 11 --- .../unreleased/Added-20241207-013627.yaml | 6 -- .../unreleased/Breaking-20241111-195013.yaml | 11 --- .../unreleased/Fixed-20241112-151649.yaml | 6 -- .../unreleased/Fixed-20241113-221407.yaml | 7 -- .../unreleased/Fixed-20241120-160241.yaml | 7 -- .../unreleased/Fixed-20241121-155915.yaml | 6 -- .../unreleased/Fixed-20241121-211357.yaml | 7 -- .changes/v0.15.0.md | 40 ++++++++ CHANGELOG.md | 41 ++++++++ docs/current_docs/partials/version.js | 2 +- helm/dagger/.changes/v0.15.0.md | 9 ++ helm/dagger/CHANGELOG.md | 10 ++ helm/dagger/Chart.yaml | 2 +- .../unreleased/Added-20241109-103555.yaml | 6 -- .../unreleased/Breaking-20241122-121153.yaml | 9 -- sdk/elixir/.changes/v0.15.0.md | 20 ++++ sdk/elixir/CHANGELOG.md | 21 ++++ sdk/elixir/lib/dagger/core/version.ex | 2 +- .../unreleased/Breaking-20241122-121153.yaml | 9 -- sdk/go/.changes/v0.15.0.md | 20 ++++ sdk/go/CHANGELOG.md | 21 ++++ sdk/go/internal/engineconn/version.gen.go | 2 +- .../unreleased/Added-20241109-103911.yaml | 6 -- sdk/php/.changes/v0.15.0.md | 15 +++ sdk/php/CHANGELOG.md | 16 ++++ sdk/php/src/Connection/version.php | 2 +- .../unreleased/Breaking-20241122-121153.yaml | 9 -- .../unreleased/Breaking-20241209-120336.yaml | 9 -- .../unreleased/Fixed-20241119-191420.yaml | 6 -- sdk/python/.changes/v0.15.0.md | 23 +++++ sdk/python/CHANGELOG.md | 24 +++++ sdk/python/src/dagger/_engine/_version.py | 2 +- .../crates/dagger-sdk/src/core/version.rs | 2 +- .../unreleased/Added-20241015-174724.yaml | 21 ---- .../unreleased/Added-20241105-135503.yaml | 56 ----------- .../unreleased/Breaking-20241122-121153.yaml | 9 -- .../unreleased/Changed-20241129-174122.yaml | 8 -- sdk/typescript/.changes/v0.15.0.md | 94 ++++++++++++++++++ sdk/typescript/CHANGELOG.md | 95 +++++++++++++++++++ sdk/typescript/src/provisioning/default.ts | 2 +- 46 files changed, 458 insertions(+), 251 deletions(-) delete mode 100644 .changes/unreleased/Added-20241026-123323.yaml delete mode 100644 .changes/unreleased/Added-20241114-115027.yaml delete mode 100644 .changes/unreleased/Added-20241114-123823.yaml delete mode 100644 .changes/unreleased/Added-20241120-140601.yaml delete mode 100644 .changes/unreleased/Added-20241126-203335.yaml delete mode 100644 .changes/unreleased/Added-20241207-013627.yaml delete mode 100644 .changes/unreleased/Breaking-20241111-195013.yaml delete mode 100644 .changes/unreleased/Fixed-20241112-151649.yaml delete mode 100644 .changes/unreleased/Fixed-20241113-221407.yaml delete mode 100644 .changes/unreleased/Fixed-20241120-160241.yaml delete mode 100644 .changes/unreleased/Fixed-20241121-155915.yaml delete mode 100644 .changes/unreleased/Fixed-20241121-211357.yaml create mode 100644 .changes/v0.15.0.md create mode 100644 helm/dagger/.changes/v0.15.0.md delete mode 100644 sdk/elixir/.changes/unreleased/Added-20241109-103555.yaml delete mode 100644 sdk/elixir/.changes/unreleased/Breaking-20241122-121153.yaml create mode 100644 sdk/elixir/.changes/v0.15.0.md delete mode 100644 sdk/go/.changes/unreleased/Breaking-20241122-121153.yaml create mode 100644 sdk/go/.changes/v0.15.0.md delete mode 100644 sdk/php/.changes/unreleased/Added-20241109-103911.yaml create mode 100644 sdk/php/.changes/v0.15.0.md delete mode 100644 sdk/python/.changes/unreleased/Breaking-20241122-121153.yaml delete mode 100644 sdk/python/.changes/unreleased/Breaking-20241209-120336.yaml delete mode 100644 sdk/python/.changes/unreleased/Fixed-20241119-191420.yaml create mode 100644 sdk/python/.changes/v0.15.0.md delete mode 100644 sdk/typescript/.changes/unreleased/Added-20241015-174724.yaml delete mode 100644 sdk/typescript/.changes/unreleased/Added-20241105-135503.yaml delete mode 100644 sdk/typescript/.changes/unreleased/Breaking-20241122-121153.yaml delete mode 100644 sdk/typescript/.changes/unreleased/Changed-20241129-174122.yaml create mode 100644 sdk/typescript/.changes/v0.15.0.md diff --git a/.changes/.next b/.changes/.next index c777b038a8..003069a91f 100644 --- a/.changes/.next +++ b/.changes/.next @@ -8,4 +8,4 @@ # automagically determined from release note entries (and then adding to the # patch release). -v0.15.0 +v0.15.1 diff --git a/.changes/unreleased/Added-20241026-123323.yaml b/.changes/unreleased/Added-20241026-123323.yaml deleted file mode 100644 index 0d7ac4d450..0000000000 --- a/.changes/unreleased/Added-20241026-123323.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Added -body: added dagger uninstall command to remove a dependency -time: 2024-10-26T12:33:23.212344+05:30 -custom: - Author: rajatjindal - PR: "8745" diff --git a/.changes/unreleased/Added-20241114-115027.yaml b/.changes/unreleased/Added-20241114-115027.yaml deleted file mode 100644 index 3734818b46..0000000000 --- a/.changes/unreleased/Added-20241114-115027.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Added -body: 'engine: add memory telemetry for execs' -time: 2024-11-14T11:50:27.77939-08:00 -custom: - Author: cwlbraa - PR: "8880" diff --git a/.changes/unreleased/Added-20241114-123823.yaml b/.changes/unreleased/Added-20241114-123823.yaml deleted file mode 100644 index 8ee315c231..0000000000 --- a/.changes/unreleased/Added-20241114-123823.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Added -body: 'engine: added network telemetry for execs' -time: 2024-11-14T12:38:23.340204-08:00 -custom: - Author: cwlbraa - PR: "8902" diff --git a/.changes/unreleased/Added-20241120-140601.yaml b/.changes/unreleased/Added-20241120-140601.yaml deleted file mode 100644 index 2edc3d0eb0..0000000000 --- a/.changes/unreleased/Added-20241120-140601.yaml +++ /dev/null @@ -1,15 +0,0 @@ -kind: Added -body: |- - Custom dagger `engine.json` config file - - This new config file in `~/.config/dagger/engine.json` is intended to - eventually replace the old buildkit-style `engine.toml` file that's - currently used for configuration. - - This file can be either mounted directly into a manually started engine at - `/etc/dagger/engine.toml`, or it will automatically mounted from the - `~/.config` location when the engine is started. -time: 2024-11-20T14:06:01.621193876Z -custom: - Author: jedevc - PR: "8800" diff --git a/.changes/unreleased/Added-20241126-203335.yaml b/.changes/unreleased/Added-20241126-203335.yaml deleted file mode 100644 index e09e281cea..0000000000 --- a/.changes/unreleased/Added-20241126-203335.yaml +++ /dev/null @@ -1,11 +0,0 @@ -kind: Added -body: | - Filesync performance is improved - - The engine now re-uses previously loaded data more reliably and in more cases, which speeds up repeated reloads of the same or similar (i.e. overlapping data). - - Uncached filesyncs of large amounts of data is also faster and uses less memory in the engine. -time: 2024-11-26T20:33:35.827404235-08:00 -custom: - Author: sipsma - PR: "8818" diff --git a/.changes/unreleased/Added-20241207-013627.yaml b/.changes/unreleased/Added-20241207-013627.yaml deleted file mode 100644 index 039facb9b4..0000000000 --- a/.changes/unreleased/Added-20241207-013627.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Added -body: Added DAGGER_LEAVE_OLD_ENGINE environment variable to optionally prevent removal of old engine containers during upgrades -time: 2024-12-07T01:36:27.59938702Z -custom: - Author: devin - PR: "8195" diff --git a/.changes/unreleased/Breaking-20241111-195013.yaml b/.changes/unreleased/Breaking-20241111-195013.yaml deleted file mode 100644 index 14d7bbad9d..0000000000 --- a/.changes/unreleased/Breaking-20241111-195013.yaml +++ /dev/null @@ -1,11 +0,0 @@ -kind: Breaking -body: |- - AsService now runs "DefaultCmd" by default instead of last "Exec" command. - - User can override the args by providing "ContainerAsServiceOpts.Args" option. They can also configure the container to use Entrypoint by using "ContainerAsServiceOpts.UseEntrypoint" option. - - See sdk documentation for additional options. -time: 2024-12-06T08:20:21.242739+05:30 -custom: - Author: rajatjindal - PR: "8865" diff --git a/.changes/unreleased/Fixed-20241112-151649.yaml b/.changes/unreleased/Fixed-20241112-151649.yaml deleted file mode 100644 index 618f4fe71e..0000000000 --- a/.changes/unreleased/Fixed-20241112-151649.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Fixed -body: Correctly apply ignore pattern when pulling a directory from git -time: 2024-11-12T15:16:49.67229+01:00 -custom: - Author: TomChv - PR: "8931" diff --git a/.changes/unreleased/Fixed-20241113-221407.yaml b/.changes/unreleased/Fixed-20241113-221407.yaml deleted file mode 100644 index 15dd4679f1..0000000000 --- a/.changes/unreleased/Fixed-20241113-221407.yaml +++ /dev/null @@ -1,7 +0,0 @@ -kind: Fixed -body: | - Directory.terminal API works now -time: 2024-11-13T22:14:07.998787448-08:00 -custom: - Author: sipsma - PR: "8952" diff --git a/.changes/unreleased/Fixed-20241120-160241.yaml b/.changes/unreleased/Fixed-20241120-160241.yaml deleted file mode 100644 index bc40b3be61..0000000000 --- a/.changes/unreleased/Fixed-20241120-160241.yaml +++ /dev/null @@ -1,7 +0,0 @@ -kind: Fixed -body: | - Fix resource leaks in the engine that occurred after each debug terminal was opened. -time: 2024-11-20T16:02:41.381210606-08:00 -custom: - Author: sipsma - PR: "9013" diff --git a/.changes/unreleased/Fixed-20241121-155915.yaml b/.changes/unreleased/Fixed-20241121-155915.yaml deleted file mode 100644 index 0804f2fb14..0000000000 --- a/.changes/unreleased/Fixed-20241121-155915.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Fixed -body: Allow `Container.withExec` `expect` to catch exit code 128 -time: 2024-11-21T15:59:15.645085385Z -custom: - Author: jedevc - PR: "9027" diff --git a/.changes/unreleased/Fixed-20241121-211357.yaml b/.changes/unreleased/Fixed-20241121-211357.yaml deleted file mode 100644 index f5c76293bb..0000000000 --- a/.changes/unreleased/Fixed-20241121-211357.yaml +++ /dev/null @@ -1,7 +0,0 @@ -kind: Fixed -body: | - Fix cache mounts not being included in interactive debug containers. -time: 2024-11-21T21:13:57.27419464-08:00 -custom: - Author: sipsma - PR: "9034" diff --git a/.changes/v0.15.0.md b/.changes/v0.15.0.md new file mode 100644 index 0000000000..73db65ce8e --- /dev/null +++ b/.changes/v0.15.0.md @@ -0,0 +1,40 @@ +## v0.15.0 - 2024-12-10 + +### ๐Ÿ”ฅ Breaking Changes +- `Container.asService` now uses the command specified by `withDefaultArgs` instead of the last `withExec` command by @rajatjindal in https://github.com/dagger/dagger/pull/8865 \ + User can override the args by providing the `args` option to `asService`. + They can also configure the container to use the container entrypoint by using + `useEntrypoint` option. + +### Added +- Better TUI errors, new cached/pending states, duration accounting and fewer spans by @vito in https://github.com/dagger/dagger/pull/8442 +- Custom dagger `engine.json` config file by @jedevc in https://github.com/dagger/dagger/pull/8800 \ + This new config file format is intended to eventually replace the old + buildkit-style `engine.toml` file that's currently used for configuration. + + This file can be either mounted directly into a manually started engine at + `/etc/dagger/engine.toml`, or it will automatically mounted from the + user's `~/.config/dagger/engine.json` when the engine is started. +- Filesync performance is improved by @sipsma in https://github.com/dagger/dagger/pull/8818 \ + The engine now re-uses previously loaded data more reliably and in more + cases, which speeds up repeated reloads of the same or similar (i.e. + overlapping data). + + Uncached filesyncs of large amounts of data is also faster and uses less + memory in the engine. +- Added `dagger uninstall` command to remove a dependency by @rajatjindal in https://github.com/dagger/dagger/pull/8745 +- Added memory and network telemetry for execs by @cwlbraa in https://github.com/dagger/dagger/pull/8880 https://github.com/dagger/dagger/pull/8902 +- Added `DAGGER_LEAVE_OLD_ENGINE` environment variable to optionally prevent removal of old engine containers during upgrades by [devin](https://github.com/apps/devin-ai-integration) in https://github.com/dagger/dagger/pull/8195 + +### Fixed +- `Directory.terminal` API works now by @sipsma in https://github.com/dagger/dagger/pull/8952 +- Fix resource leaks in the engine that occurred after each debug terminal was opened by @sipsma in https://github.com/dagger/dagger/pull/9013 +- Fix cache mounts not being included in interactive debug containers by @sipsma in https://github.com/dagger/dagger/pull/9034 +- Allow `Container.withExec` `expect` to catch exit code 128 by @jedevc in https://github.com/dagger/dagger/pull/9027 +- Correctly apply ignore pattern when pulling a directory from git by @TomChv in https://github.com/dagger/dagger/pull/8931 +- Fix panic on null `Directory.digest` by @jedevc in https://github.com/dagger/dagger/pull/8946 + +### What to do next? +- Read the [documentation](https://docs.dagger.io) +- Join our [Discord server](https://discord.gg/dagger-io) +- Follow us on [Twitter](https://twitter.com/dagger_io) diff --git a/CHANGELOG.md b/CHANGELOG.md index e791519efb..ef16ace7cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,47 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v0.15.0 - 2024-12-10 + +### ๐Ÿ”ฅ Breaking Changes +- `Container.asService` now uses the command specified by `withDefaultArgs` instead of the last `withExec` command by @rajatjindal in https://github.com/dagger/dagger/pull/8865 \ + User can override the args by providing the `args` option to `asService`. + They can also configure the container to use the container entrypoint by using + `useEntrypoint` option. + +### Added +- Better TUI errors, new cached/pending states, duration accounting and fewer spans by @vito in https://github.com/dagger/dagger/pull/8442 +- Custom dagger `engine.json` config file by @jedevc in https://github.com/dagger/dagger/pull/8800 \ + This new config file format is intended to eventually replace the old + buildkit-style `engine.toml` file that's currently used for configuration. + + This file can be either mounted directly into a manually started engine at + `/etc/dagger/engine.toml`, or it will automatically mounted from the + user's `~/.config/dagger/engine.json` when the engine is started. +- Filesync performance is improved by @sipsma in https://github.com/dagger/dagger/pull/8818 \ + The engine now re-uses previously loaded data more reliably and in more + cases, which speeds up repeated reloads of the same or similar (i.e. + overlapping data). + + Uncached filesyncs of large amounts of data is also faster and uses less + memory in the engine. +- Added `dagger uninstall` command to remove a dependency by @rajatjindal in https://github.com/dagger/dagger/pull/8745 +- Added memory and network telemetry for execs by @cwlbraa in https://github.com/dagger/dagger/pull/8880 https://github.com/dagger/dagger/pull/8902 +- Added `DAGGER_LEAVE_OLD_ENGINE` environment variable to optionally prevent removal of old engine containers during upgrades by [devin](https://github.com/apps/devin-ai-integration) in https://github.com/dagger/dagger/pull/8195 + +### Fixed +- `Directory.terminal` API works now by @sipsma in https://github.com/dagger/dagger/pull/8952 +- Fix resource leaks in the engine that occurred after each debug terminal was opened by @sipsma in https://github.com/dagger/dagger/pull/9013 +- Fix cache mounts not being included in interactive debug containers by @sipsma in https://github.com/dagger/dagger/pull/9034 +- Allow `Container.withExec` `expect` to catch exit code 128 by @jedevc in https://github.com/dagger/dagger/pull/9027 +- Correctly apply ignore pattern when pulling a directory from git by @TomChv in https://github.com/dagger/dagger/pull/8931 +- Fix panic on null `Directory.digest` by @jedevc in https://github.com/dagger/dagger/pull/8946 + +### What to do next? +- Read the [documentation](https://docs.dagger.io) +- Join our [Discord server](https://discord.gg/dagger-io) +- Follow us on [Twitter](https://twitter.com/dagger_io) + ## v0.14.0 - 2024-11-08 diff --git a/docs/current_docs/partials/version.js b/docs/current_docs/partials/version.js index ff496f5cdb..1a5eeb3463 100644 --- a/docs/current_docs/partials/version.js +++ b/docs/current_docs/partials/version.js @@ -1,3 +1,3 @@ // Code generated by dagger. DO NOT EDIT. -export const daggerVersion = "0.14.0"; +export const daggerVersion = "0.15.0"; diff --git a/helm/dagger/.changes/v0.15.0.md b/helm/dagger/.changes/v0.15.0.md new file mode 100644 index 0000000000..4512a44ced --- /dev/null +++ b/helm/dagger/.changes/v0.15.0.md @@ -0,0 +1,9 @@ +## v0.15.0 - 2024-12-10 + +### Dependencies +- Bump Engine to v0.15.0 by @jedevc in https://github.com/dagger/dagger/pull/9158 + +### What to do next? +- Read the [documentation](https://docs.dagger.io) +- Join our [Discord server](https://discord.gg/dagger-io) +- Follow us on [Twitter](https://twitter.com/dagger_io) diff --git a/helm/dagger/CHANGELOG.md b/helm/dagger/CHANGELOG.md index 651e2ba044..3f54bf3789 100644 --- a/helm/dagger/CHANGELOG.md +++ b/helm/dagger/CHANGELOG.md @@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v0.15.0 - 2024-12-10 + +### Dependencies +- Bump Engine to v0.15.0 by @jedevc in https://github.com/dagger/dagger/pull/9158 + +### What to do next? +- Read the [documentation](https://docs.dagger.io) +- Join our [Discord server](https://discord.gg/dagger-io) +- Follow us on [Twitter](https://twitter.com/dagger_io) + ## v0.14.0 - 2024-11-08 diff --git a/helm/dagger/Chart.yaml b/helm/dagger/Chart.yaml index 29aee2f466..d46e03ccc8 100644 --- a/helm/dagger/Chart.yaml +++ b/helm/dagger/Chart.yaml @@ -2,4 +2,4 @@ apiVersion: v2 description: Dagger Helm chart name: dagger-helm type: application -version: 0.14.0 +version: 0.15.0 diff --git a/sdk/elixir/.changes/unreleased/Added-20241109-103555.yaml b/sdk/elixir/.changes/unreleased/Added-20241109-103555.yaml deleted file mode 100644 index 10832847ff..0000000000 --- a/sdk/elixir/.changes/unreleased/Added-20241109-103555.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Added -body: Add support for TRACEPARENT. The user will see what's function doing in the TUI. -time: 2024-11-09T10:35:55.353113+07:00 -custom: - Author: wingyplus - PR: "8859" diff --git a/sdk/elixir/.changes/unreleased/Breaking-20241122-121153.yaml b/sdk/elixir/.changes/unreleased/Breaking-20241122-121153.yaml deleted file mode 100644 index 2166a5343a..0000000000 --- a/sdk/elixir/.changes/unreleased/Breaking-20241122-121153.yaml +++ /dev/null @@ -1,9 +0,0 @@ -kind: Breaking -body: |- - `ExecErr.message` no longer contains the values of `stdout` or `stderr`. - - When comparing error values for expected output, use the more specific values. -time: 2024-11-22T12:11:53.934008034Z -custom: - Author: vito - PR: "9033" diff --git a/sdk/elixir/.changes/v0.15.0.md b/sdk/elixir/.changes/v0.15.0.md new file mode 100644 index 0000000000..b670f87462 --- /dev/null +++ b/sdk/elixir/.changes/v0.15.0.md @@ -0,0 +1,20 @@ +## sdk/elixir/v0.15.0 - 2024-12-10 + +This SDK uses ๐Ÿš™ Engine + ๐Ÿš— CLI version `v0.15.0`. [See what changed in that release](https://github.com/dagger/dagger/releases/tag/v0.15.0). + +๐Ÿงช https://hex.pm/packages/dagger +๐Ÿ“– https://hexdocs.pm/dagger/Dagger.html + +### ๐Ÿ”ฅ Breaking Changes +- `ExecErr.message` no longer contains the values of `stdout` or `stderr` by @vito in https://github.com/dagger/dagger/pull/9033 \ + When comparing error values for expected output, use the more specific values. + +### Added +- Add support for `TRACEPARENT`. The user will see what's function doing in the TUI by @wingyplus in https://github.com/dagger/dagger/pull/8859 + +### Dependencies +- Bump Engine to v0.15.0 by @jedevc in https://github.com/dagger/dagger/pull/9158 + +### What to do next +- Join our [Discord server](https://discord.gg/dagger-io) +- Follow us on [Twitter](https://twitter.com/dagger_io) diff --git a/sdk/elixir/CHANGELOG.md b/sdk/elixir/CHANGELOG.md index 658df70735..34b684bd22 100644 --- a/sdk/elixir/CHANGELOG.md +++ b/sdk/elixir/CHANGELOG.md @@ -6,6 +6,27 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## sdk/elixir/v0.15.0 - 2024-12-10 + +This SDK uses ๐Ÿš™ Engine + ๐Ÿš— CLI version `v0.15.0`. [See what changed in that release](https://github.com/dagger/dagger/releases/tag/v0.15.0). + +๐Ÿงช https://hex.pm/packages/dagger +๐Ÿ“– https://hexdocs.pm/dagger/Dagger.html + +### ๐Ÿ”ฅ Breaking Changes +- `ExecErr.message` no longer contains the values of `stdout` or `stderr` by @vito in https://github.com/dagger/dagger/pull/9033 \ + When comparing error values for expected output, use the more specific values. + +### Added +- Add support for `TRACEPARENT`. The user will see what's function doing in the TUI by @wingyplus in https://github.com/dagger/dagger/pull/8859 + +### Dependencies +- Bump Engine to v0.15.0 by @jedevc in https://github.com/dagger/dagger/pull/9158 + +### What to do next +- Join our [Discord server](https://discord.gg/dagger-io) +- Follow us on [Twitter](https://twitter.com/dagger_io) + ## sdk/elixir/v0.14.0 - 2024-11-08 This SDK uses ๐Ÿš™ Engine + ๐Ÿš— CLI version `v0.14.0`. [See what changed in that release](https://github.com/dagger/dagger/releases/tag/v0.14.0). diff --git a/sdk/elixir/lib/dagger/core/version.ex b/sdk/elixir/lib/dagger/core/version.ex index b561f815b5..f6e61c6483 100644 --- a/sdk/elixir/lib/dagger/core/version.ex +++ b/sdk/elixir/lib/dagger/core/version.ex @@ -1,7 +1,7 @@ defmodule Dagger.Core.Version do @moduledoc false - @dagger_cli_version "0.14.0" + @dagger_cli_version "0.15.0" def engine_version(), do: @dagger_cli_version end diff --git a/sdk/go/.changes/unreleased/Breaking-20241122-121153.yaml b/sdk/go/.changes/unreleased/Breaking-20241122-121153.yaml deleted file mode 100644 index 214e50147a..0000000000 --- a/sdk/go/.changes/unreleased/Breaking-20241122-121153.yaml +++ /dev/null @@ -1,9 +0,0 @@ -kind: Breaking -body: |- - `ExecErr.Error` no longer contains the values of `Stdout` or `Stderr`. - - When comparing error values for expected output, use the more specific values. -time: 2024-11-22T12:11:53.934008034Z -custom: - Author: vito - PR: "9033" diff --git a/sdk/go/.changes/v0.15.0.md b/sdk/go/.changes/v0.15.0.md new file mode 100644 index 0000000000..4e34edd196 --- /dev/null +++ b/sdk/go/.changes/v0.15.0.md @@ -0,0 +1,20 @@ +## sdk/go/v0.15.0 - 2024-12-10 + +This SDK uses ๐Ÿš™ Engine + ๐Ÿš— CLI version `v0.15.0`. [See what changed in that release](https://github.com/dagger/dagger/releases/tag/v0.15.0). + +๐Ÿน https://pkg.go.dev/dagger.io/dagger@v0.15.0 + +### ๐Ÿ”ฅ Breaking Changes +- Removed deprecated unscoped enum values by @jedevc in https://github.com/dagger/dagger/pull/8669 \ + Enum values must now be accessed with the name prefixed by the name of the + enum type - for example, `dagger.Shared` becomes `dagger.CacheSharingModeLocked`. +- `ExecErr.Error` no longer contains the values of `Stdout` or `Stderr` by @vito in https://github.com/dagger/dagger/pull/9033 \ + When comparing error values for expected output, use the more specific values. + +### Dependencies +- Bump Engine to v0.15.0 by @jedevc in https://github.com/dagger/dagger/pull/9158 + +### What to do next +- Read the [documentation](https://docs.dagger.io/sdk/go) +- Join our [Discord server](https://discord.gg/dagger-io) +- Follow us on [Twitter](https://twitter.com/dagger_io) diff --git a/sdk/go/CHANGELOG.md b/sdk/go/CHANGELOG.md index 20fa459174..938aa4c1d2 100644 --- a/sdk/go/CHANGELOG.md +++ b/sdk/go/CHANGELOG.md @@ -6,6 +6,27 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## sdk/go/v0.15.0 - 2024-12-10 + +This SDK uses ๐Ÿš™ Engine + ๐Ÿš— CLI version `v0.15.0`. [See what changed in that release](https://github.com/dagger/dagger/releases/tag/v0.15.0). + +๐Ÿน https://pkg.go.dev/dagger.io/dagger@v0.15.0 + +### ๐Ÿ”ฅ Breaking Changes +- Removed deprecated unscoped enum values by @jedevc in https://github.com/dagger/dagger/pull/8669 \ + Enum values must now be accessed with the name prefixed by the name of the + enum type - for example, `dagger.Shared` becomes `dagger.CacheSharingModeLocked`. +- `ExecErr.Error` no longer contains the values of `Stdout` or `Stderr` by @vito in https://github.com/dagger/dagger/pull/9033 \ + When comparing error values for expected output, use the more specific values. + +### Dependencies +- Bump Engine to v0.15.0 by @jedevc in https://github.com/dagger/dagger/pull/9158 + +### What to do next +- Read the [documentation](https://docs.dagger.io/sdk/go) +- Join our [Discord server](https://discord.gg/dagger-io) +- Follow us on [Twitter](https://twitter.com/dagger_io) + ## sdk/go/v0.14.0 - 2024-11-08 This SDK uses ๐Ÿš™ Engine + ๐Ÿš— CLI version `v0.14.0`. [See what changed in that release](https://github.com/dagger/dagger/releases/tag/v0.14.0). diff --git a/sdk/go/internal/engineconn/version.gen.go b/sdk/go/internal/engineconn/version.gen.go index 832292d4cd..a6a4cd1961 100644 --- a/sdk/go/internal/engineconn/version.gen.go +++ b/sdk/go/internal/engineconn/version.gen.go @@ -2,4 +2,4 @@ package engineconn -const CLIVersion = "0.14.0" +const CLIVersion = "0.15.0" diff --git a/sdk/php/.changes/unreleased/Added-20241109-103911.yaml b/sdk/php/.changes/unreleased/Added-20241109-103911.yaml deleted file mode 100644 index 1be028d437..0000000000 --- a/sdk/php/.changes/unreleased/Added-20241109-103911.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Added -body: Add support for TRACEPARENT. The user will see what's function doing in the TUI. -time: 2024-11-09T10:39:11.945216+07:00 -custom: - Author: wingyplus - PR: "8896" diff --git a/sdk/php/.changes/v0.15.0.md b/sdk/php/.changes/v0.15.0.md new file mode 100644 index 0000000000..65d5dbfaaf --- /dev/null +++ b/sdk/php/.changes/v0.15.0.md @@ -0,0 +1,15 @@ +## sdk/php/v0.15.0 - 2024-12-10 + +This SDK uses ๐Ÿš™ Engine + ๐Ÿš— CLI version `v0.15.0`. [See what changed in that release](https://github.com/dagger/dagger/releases/tag/v0.15.0). + +๐Ÿ˜ https://packagist.org/packages/dagger/dagger#v0.15.0 + +### Added +- Add support for `TRACEPARENT`. The user will see what's function doing in the TUI by @wingyplus in https://github.com/dagger/dagger/pull/8896 + +### Dependencies +- Bump Engine to v0.15.0 by @jedevc in https://github.com/dagger/dagger/pull/9158 + +### What to do next +- Join our [Discord server](https://discord.gg/dagger-io) +- Follow us on [Twitter](https://twitter.com/dagger_io) diff --git a/sdk/php/CHANGELOG.md b/sdk/php/CHANGELOG.md index 476c3a8442..687f04a53e 100644 --- a/sdk/php/CHANGELOG.md +++ b/sdk/php/CHANGELOG.md @@ -6,6 +6,22 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## sdk/php/v0.15.0 - 2024-12-10 + +This SDK uses ๐Ÿš™ Engine + ๐Ÿš— CLI version `v0.15.0`. [See what changed in that release](https://github.com/dagger/dagger/releases/tag/v0.15.0). + +๐Ÿ˜ https://packagist.org/packages/dagger/dagger#v0.15.0 + +### Added +- Add support for `TRACEPARENT`. The user will see what's function doing in the TUI by @wingyplus in https://github.com/dagger/dagger/pull/8896 + +### Dependencies +- Bump Engine to v0.15.0 by @jedevc in https://github.com/dagger/dagger/pull/9158 + +### What to do next +- Join our [Discord server](https://discord.gg/dagger-io) +- Follow us on [Twitter](https://twitter.com/dagger_io) + ## sdk/php/v0.14.0 - 2024-11-08 This SDK uses ๐Ÿš™ Engine + ๐Ÿš— CLI version `v0.14.0`. [See what changed in that release](https://github.com/dagger/dagger/releases/tag/v0.14.0). diff --git a/sdk/php/src/Connection/version.php b/sdk/php/src/Connection/version.php index 925e75a285..cca92df9cc 100644 --- a/sdk/php/src/Connection/version.php +++ b/sdk/php/src/Connection/version.php @@ -1,4 +1,4 @@ Date: Tue, 10 Dec 2024 20:13:56 +0400 Subject: [PATCH 19/35] docs: Update viz page with info on metrics and OTEL attribs (#9104) * docs: Add information on TUI metrics Signed-off-by: Vikram Vaswani * Updated screen recording Signed-off-by: Vikram Vaswani * Add text Signed-off-by: Vikram Vaswani * Add text Signed-off-by: Vikram Vaswani * Added feedback Signed-off-by: Vikram Vaswani --------- Signed-off-by: Vikram Vaswani --- docs/current_docs/features/visualization.mdx | 16 ++++++++++++++-- docs/static/img/current_docs/features/tui.gif | Bin 321914 -> 474129 bytes 2 files changed, 14 insertions(+), 2 deletions(-) mode change 100644 => 100755 docs/static/img/current_docs/features/tui.gif diff --git a/docs/current_docs/features/visualization.mdx b/docs/current_docs/features/visualization.mdx index 2a8beaf80e..adbe1bcddd 100644 --- a/docs/current_docs/features/visualization.mdx +++ b/docs/current_docs/features/visualization.mdx @@ -17,12 +17,18 @@ The TUI is designed for rapid iteration, in the same way regular scripting works ![Dagger TUI](/img/current_docs/features/tui.gif) -The TUI is driven by [OpenTelemetry](https://opentelemetry.io/) and is essentially a live-streaming OpenTelemetry trace visualizer. It represents Dagger API calls as OpenTelemetry spans with special metadata. If user code integrates with OpenTelemetry, related spans will appear in the TUI as first-class citizens. - The TUI renders a tree of Dagger API calls, represented as GraphQL queries. A parent-child relationship means that the child call is being made by the parent call. - A red X or green check indicates whether the call succeeded or failed. - A call's duration is rendered after its name. +Error logs appear at the top, directly below the progress report. In most cases, this tells you exactly what went wrong and where without any extra sleuthing. + +The TUI also provides real-time telemetry to give you a complete view of your pipeline's performance. It allows you to monitor: +- State and duration: Get visual cues for cached and pending states, and see exactly how long each step of your pipeline takes (including accounting for lazy effects installed by a Dagger Function). +- CPU resource usage: Identify when CPU contention occurs, such as when all threads are blocked waiting for CPU access, and diagnose performance bottlenecks related to CPU resource constraints. +- Network activity: See how much data is sent and received and track packet drop rates to identify potential bottlenecks in your pipelines. +- Memory usage: Keep an eye on current and peak memory consumption, helping you optimize resource utilization. + The CLI has tiered verbosity: `-v`, `-vv`, `-vvv` (just like `curl`): - `-v` keeps spans visible after they complete, rather than disappearing after a brief pause; - `-vv` reveals internal and encapsulated spans; @@ -30,6 +36,12 @@ The CLI has tiered verbosity: `-v`, `-vv`, `-vvv` (just like `curl`): For additional debugging information, add the `--debug` flag to the `dagger call` command. +The TUI is driven by [OpenTelemetry](https://opentelemetry.io/) and is essentially a live-streaming OpenTelemetry trace visualizer. It represents Dagger API calls as OpenTelemetry spans with special metadata. If user code integrates with OpenTelemetry, related spans will appear in the TUI as first-class citizens. + +:::note +Dagger automatically detects OpenTelemetry resource attributes. By utilizing the standard [`OTEL_RESOURCE_ATTRIBUTES` environment variable](https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/), operators can now set custom resource attributes to annotate Traces, providing more detailed and contextual information for monitoring and debugging. +::: + ## Traces Dagger Cloud provides Traces, a browser-based interface focused on tracing and debugging Dagger Functions. A Trace represents one invocation of a Dagger Function, run locally or in CI. It contains detailed information about the operations performed by the Dagger Function. diff --git a/docs/static/img/current_docs/features/tui.gif b/docs/static/img/current_docs/features/tui.gif old mode 100644 new mode 100755 index de2474a37a2611c7255775967d2e031bd0ede00a..a3736891db90c38430eb774d0ab740e433cf7b65 GIT binary patch literal 474129 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%0Dq zB{%<7kY@Abe0C~=$At3q;=8v_#4{6e;8#CGjPzFF4mK67OojV~1UrJNGa;INQ@)2_ zOBlWja;(={LvLR9P*Dv^(k0if=?K)-5#Y!q0BMIukEdS|07()BD@S+a>>qvYQKIwk z#i!mFoKl#SeRNE`o)z@tqepmjwPbI~r~%bW%Sey?JTCneI0T-*^HuJfO#Td(d!^!U z#vdhq^QB1{n{R-_azU^uGKMD}PrcraKDE2wpsZgW3cBb<}_;@xkoZE}Gs-X2lDWGSP7F$lh4kArH6_73^bI zI#>nCWt2iMPnh%)sAo|z-8@oP(m^o_=FS@T%xjt5!Nq}YjsqNkPJvEt!r|uZ9?;li z#-|VxE6nWkZaoS^h5jR+v~hO_U>>IBg_H;IAM^;F2CKA0AO+JD)~@=+OO1=GO`ja7 zjAbF-KW0FF@4eW=t`D~EVp#2La}&}=8y<1dr8(S~aK~5ka|is)!$v~*3DT1 zd8m=fj5gnCt{!02d6`BVqfrzSUEGnU`RdT}0I5Z~FXZ35;gruik?1f5q2$w?9wCk! z)#tWeR_6*GoYC+#-M$|5p4Tn!s>z+~$d6tTzlBj36Jh?zmJ#;M76LSjGN$Nr1;mK? zb3K+Dv@x~c@tsSG0n9QFTgwsw|JB42RNDifu-m?eNwtF>vTZ5M zR&d24W;1YzJSS|z&V5bj7KIqg^*fo>Hjl`Q4N+f$LBuh)a*bzXNa0>Q&MY-Y4#G+^t%(! zstBM^ew!eLJ8VSIZ2*;|0H}9*n&|qg$;7NUfZ`VswgA0lBg+S(ffh0Hr;M$F03pE= z1WmxSwF&7f^RkmnU?Ga(KcTjqFjALv6^VV)2HbHK1j+%D6@jo0GL0T^J*q&<0&p5D z;NqvdLoNC%5a9Y>lx`wiTlXvhX40<71HX+8MYF$IIqm9-`^X41ph3G!!tUICB1wFFNxUMrepCqu0xy zGSjgGh|)#?ja4oU$JhAXRpG42^b3&ficWXD>TZYpQo^7T=M=qLk(3bbEJl&=;CNyf z>|IbIT~PFeEs0`hFKz+AqA6*85ct*w4Q0C$Jp=tH!Ik>_{5%@drwk#Zf`itwY50P} zPJr5o)=#VXuT5oIlzgCdxetVLz}F)B^^Hqq&H=1)IXaHfFqV#*u56w0x|-L_X6`+} z@5VY{Ce&yaaCZXx+0+aj)^&Q(aIDuFkYH(XfKjQEEwylZi4Fx}w+X4y*r=bPsd2Tg zM|{;!psS@ZOp8r}`J}QU3{N19za^;Ewm-iT%ox~A5UOCdeYEUzsq{m~A@z#&RaM-z0pgOf+8qZHu8(#+U1X&X$MpLl z2fgII)JK<@+XBLZ+}jI08vzv|3BGik$g@Xc&Fv*&PzecKM~6tviS|oyM}<{~bb5zs zbBFpw$E8mlm+2o9Bpz!UKh_O+te^hau=%m^#N#v5Pmj&%J1r$Tt&KZv13G^zp#LgF z;AYzuWzeFQTGy4Kn*43N{7<~*FG>ZluyOLH(OwBo#{uG^ALVdi|0xOG5?MH6&XE_o zDS`7(7fGy^dYuC-Qizv|!DJ@^lQrfTXDKB0$wx|4&9Z5>gi82tCbjmk;tMwB@ed2J z(peX17KxT+|0yN?W}-A-yeFjlBDa&XJK)((Eo}nKgC32*OM!@N-v2RQy=V8g%9rWb z_hdbFGod;eY{Zf-%zY1cN@5=PE?D(j&`3mcF|IE_9&2h9*kPt0)$AC8`W zlePC>GpklxadKk&`KbMPYD zH}{;-H&4$pq|PGk!YpGFF&-c)m?5jy6u!B1W&c(@PbfrDCS&JF(;?9tpKt^7w2<;N&GW6EqCsB^)*YDGYcXzP#ajsOeVSpnDg#FMo zLdKUyw@T}Kk<85XEZ z3K1?ybJnrISs?CDb`(32I4&0Veo^`BUKKnI8j_QUbHIrU^+D z^H@2xAa22!A;A_CSq=vHg>P4;|5IcvhcNw2UHeAc%qDsDISc10YguWXmwNPT0L3Sw zv1bD?ku-cltWH?%KFsKy`OO!wRkl&I{RIm2szd1|gJ{zFSz+1sA7(KYl~FP61f2Yr=v9k**M=!$%S*RtG>-&jbOL3WUr&DBRZ=D<*4U4_06#nd18! zFlll*x3OX&_RKK{OP?Fxa6cAe9O4NF7>=zkn^nz+#R`_Z<8sEl(T`@VDHK}iYvVZg z)D^sW_$cMvJi8?O?xXvH+_OvgA2v*DOpLZn&3}Qp_;)LLhU4!X!I76o2Y@>kcB6va zYli?5D~s;?@2os715HQ!OK?SRd3E;sTcyjsp6tj10oJJZZNdNss93}0Q~z?1%J&w$rQ@hpeR=u7LQn@518 zyGE6MQ~7|Dgp12~_1Z)U^P~{Xw;{6dn$T(+b4v!t=iQ9A;XYGCT#fwEZ=c15Tiw3+ z0fzWm_A*5MeUi^XqRC#P*>H6h-G#)%u7XAb(Q7P)EhfY@c0M;TtyEl)B2##J(UuJd zgaryUJbXo6X0~5tn0URd;*euHoqBm?gdDle`KW(wI6W9uXoy$LLm6Gi6J9^z3oD>y+5&D=ELoH2@}PC_*yA@|DJ(^jm>EGYy<0Q{DifO$grv*S6-LT|Kx6#|GekOTW1@kIkh(Y+2Y=Vwrg>t*H_ zx8WQQb2NGHjCDcyU&2CL|Krw#a%5ldA)H8S@i|8Du)0dln>~517k^lA&{r7ovrTg; zH0(Xrd8mtzR3CXt)haKC*o1)FQMD$s$&=jO7rgS4_pjm-rs@zKZDoG z&Nj`1>%?A*=zj0d<0nlmEB{;UWdz6j0tpbxAb>u%w@XuWbZ1Am=`T?!Ddd_W%3(AE z{Gm>cua5BDi(1#Bjao6;MV?`Smq1QQ3~=fTkC8+mZbgf2PW46b%MZuDE?r{U`TbXw zAja_Pg^mleE5AalY88f8*N_X2tdwC;9Yvb4o3&CDIuo+ww5B_|L2b1pafMS7ZzCn& zC~m6cV01%KvlF@AtAH^%_hm#?YM|*T+`E&i;v5mZSd1j5_6cuWl_ci1B|ak=BE&0O z%gWNKF!~}(Zc>$+_Lez4?=|66E6&_j)c$E{#y~txqOb{0z^0Kcw4ctIJ?N|(M;Ro+4$WK<$H$RY&3mdRhixswGbiz%X*Cyhd~i&qBEDzAt>2d7}7S_nuzNS{%1z634(!Pws1Jp zWKx1pl5p1sokll98hx-4E%cCbM2Hm@r!)ZL)k^f2>3JRuvf#-<)hA$p;R7`fYTm>q zE~8WN$)pi&VGzNk>-WJ$H&gHk?|tP6>fjowoc0)SG@)ZCmN`oRrLs4{PJOJrwsJn+ zlV5*aSaQh(?gMxs5j2n>Xhp=tO$V`?7KY{-$9xEO+XQC%3$q)U!YS_jFxHjxmbS*v zgXC0wslXi`We6#rEX%AJSDNgBSI%NV`h2GZ(`C<;NumX?X?I(J1u)E|gisSNr$G|B zPAl0+iZaa=je~wOl+gjRSjfZ`PnjHY*%=$IQ|}4a&WDMHs=x$(@mXV?HpwtGAt3P$(jLTKS3_=Kt2Js0K2 ze`H3i+pE~=Rrzy_#HAQ_N;h!kAp!u1DO?X|I%`T&as)NdP0+DTK2dOeU{4i+G}Csg zX*W&rx&!{pA;TzWjTY0o`E?DEeSFkxA5Bvl{(8&PVa$IlH#Z(PQJb<~Gz)mW*=pG6 zexYP<<(HOX)PzIiNxV1O$%!V}ZibSZdM&bzC3$&emD}3h-M&ZDF#|^*X)XEOBaI|> z-=Yq=hzU!%xoo~=NfAzIn6>KOHcFS}>tH%$zD#c+J@m9U<^fvAb4agg`&afSKgZm+ zEZ`5kMDT6qJ3|XyV4a$<&97SlAHqV;$dJjJEZ=x@#abn`6lWymg1q5bDY9$l3r>G=}AbAF}4jF!G* z-c3#Yy=YGCDqY?S>^)vY%(N}&GsT;v9jy_f`(($cFY2I#!CW8w>?+MI9-HMj(pTSi zy(7ny{BF-3r;qt>DZP4aM*Ce{Ej)UE!TL7s@eLu8`nNZE*EGJ4e|qri09&)~*^q>XY`W8m0LQbPp^IeM3=fPT*M#q|e3fjb zzl-37|8|Cz`(?Aj$^>~n`HrY>$li@!5#;;5GjbU$mrce9@zeW_YS$%#Ak+k?4igPj z0k49F4}ftqd8aZ$aDh=h7I9LQiKaOh#|{F92?H7aGLOrpVt5^*;8V3*NhxK*QUQL( zQrv*8JFe7~3QhoJ&^bVSfvma{R#UTe%i5BSit2EXEp>egdEPLkijgx0Kve z#q3t)$~G{fs@jnvn
MTWG{Z~>SiE|X^=k`)rog2h{UaGQ);Po4_JbvR5H+?lD9 zq<=dVXJk~k<$}|`uxFuh#)(q=64eKWQ_`JOI-s?A7Ix=O^e#lOtwDcRr zH0U4tq0T!Ax8HmEcY=(a8H%ZAW`^8dA( z(M4wB@^j21_Q+?fF2pw=tW3)&P*txcEalpn`qpGuv9dW+D&pCvcT)eTju$HL^~*Fl z!!s7I};5N4@;9wa-n}9EZDdqgKt3UK`vU6q*8I%>_P3So+d!B22X^E-41|1hFPKls({U5o zzzQTb*x6|Zq+iyT6?w7r4Rz!kcG8+=1!6UoGvZ_+ve61*tKW&+mWICdINP)7@vqqB z^+0~Ku2x$})}iGvZQZjUP+Pq5n84vG^~w2z+EUM|;=@}9pWGno%l*7ckJ5woJq6X@ zj9*dexOcFBRa^b-T!m6+W$edmS!xMOz428)W_BhDqK9OrKMUzu=!Vtn!cD^!_<9(K zj~mo`JXW4Kwfva3*>k^Pe7Fi{hBpNJsfC>t=IgVjkZ!Xo(y@Qjab>0715`*C0u<%1 z1ioXM`I(Jcbs#~c3y#!)ouo>XZ;3>(&xMK=l)$phmD*cNMO_;5_?)9>SGhg+zebz~ z!2QmwwdvPVMilFX?S1R7AmOFMD~~1KKdm1txBizDEh{1O)K@?Kb4m1vwzd7A$_Cyh zyo}QJ)>8|;0(zD{v6n!(Y*eV`)znO*Ch$}LTXt}*E5&o5pqSL`cfHqj17}IR(7kaH6(Rk>pX>P6ls!Xco_etr0?jmyxe!O-DYIkWhA|v=!{T?~{yuPBj ztz4vW#Wd^sWV(|wBdPY2qH^ec+T!`*u)e{++1mAIUC`>wmm2HUlg;9K)~mWNjc4|X zHGk~gQ{?E;YBjQ+%;9|(cNk+wEzxcSenvRTf;r_(Dv*rasJD@%3uWzP+slDfpHjoj zac2>x5AZ}@%=IftfI~oZ*j3Fc?Cfp*OGf9^gbP^mX zZqVtu52}P*_guyVC@j!Q;<=-*tkxmOR)xqU9%E_fyp5;kOjg~rKQavdl(Rv_?GJ1NeR{4kwL*2fjw zxH$l;2WYSf#lGVru|1obw}yj-VD2iCR&;h*7f=AE3hQ8tqE~Xdpaj6y+?_{ZH&U~l zak(%~BpaO;gp-gLTa5TcsAHhQcGkdNr7(OZ?VN5Nu0+VUO3#ExrQpn+Z=B4B7J&Fp z9~<(sO7{UNYqYui5})0<@oZ_?c=~CO(WFf-m&XMyTMlUe!l@7DtSXnPywF1c6y7{} zge9F)&?#p3e`<5o5SWI6pIi1jr&=urpsWy(yh-BZlrdB%QCfh8r%pR>d4q5=BHXYc zov_S)lOKsB5ic>0gmYe}o>wiP%o%1&D;uz1C2|<7Rfulx!aBVI%cVJx^rD_Rm}Mk2 z?&)D7Bt*-&1z66&3N}%@S_h#iA3!qX!4&E~NB~6S(0pvG4ev*^ki6Ep#6Pbgk#8hY zK4cBOwyPP}zXDRRB)O{C(an&I*tCG|QJ~D|E(UKWd{%3aS{>Z7d2s=++)dmk2y4m?_T~TxjfAAw)iFBOl9pPKaQMPu>ROlaq-@MnwpEh=jo6d*A3Wi%| zY+II^I(C)9)>$>!z`AA!Ef+PCx^Dl_3m7<~7LKFxZCaViX;Nq4Bb=!$1Bff#^KOIMS zd_MHpW?rdQNCiN+3S&-h>&duq3`kq+Ovmk4mZnAa<>0r1{0QOw*QdIL5$$AfgGfv; zw?~Y~jY+FUFM}K3^XaIGZP_0A&tZE%;}XcFN^9O*z7;n436Rw-rNXTAQ;;+h#LS1* zqHXTZo*sWTj!OWlat@7{!piO42e7V^q!k^WEX6#Pc0e zam8NlxzwI~DqDgJ;AOy4h7tFfJ}%&5!t}@f^%X)I`gg+;d@_*YUUn zEmBH|J{qc}?;>c{21;c<(+$nhQa7BJY8SZ$jsrsxK|4vvZX;w0nRs9tnUjns^(z$T z|G-h%W(?$kCbbiBW|jJUUc2j0-zoR9s+QdqcA?xB=(|T17luP@IvewUW#wSG8j#%MX81(8!bG=+Ovxs z)tnOaZ65MD`nd~>-$w_ynp)5rQnv)^0n!4rSkHF`WOgc52G{=U*RocH2*ZEQ8BWkV z`E>PXJb!3&yxsH?OWZ|+RVfXisdyxu0lg$lv%*00tg1CdkL!h#XK?6Sn>LoLKsS`+ zecc#`zgz4ETMxFMRI;~~YvWpGnf<#L-(3+Iuux)icF-N_C&WfxbUV>8x7cN!fkE1Y zjp1it#Gi>mGrgJH&5SdPzvz1w&Z2qefEt-SJ~&ERa5{j-wY)k zl0aQs1m5%kFNikY4y2-e=_gG`&+ZB+-ZN3oOs<2t|HAoy<=(LqfqCe`Pq@>V#}2jus5NPR^`M zBuNL4SY9J&?(S50Hx5{g$D3@8@FNr8zX^Qw@0CJ7@hdEXG+gK(4<6c?<%s(^!AKh6 zgz>Ng4vbvmyM0jeU~4Z$9@DS+wMZX%jy>($X%UeO<<)q>g6--Ld~!wV{_fvBl1T|^ z$)C-#Kjh7L+Ye1JVeMX|$FMn$@p;c6^GcJ()#esp2#~-p!iN=#moOM&8GI_mHNfOK zl+riA_2+)4+zN(OL7zG7vX(vFC;7`94-$lqFbY(yFLYAf9a2M|b^5j1P>mO0paGG#QZ2f5BB*X4cNfCOXvjZb&*xd|X zX^e{qrgMUZB!5{4wtS^q2Ym4lkh9THF@DYd#gKe^;vI{z`I3{|2FcGFeCH8YZ)|~)bAZW8~t+pxowOimInmg|ICCrrfaKILifi#hy80Swbg!a?n1W&^V`w^ zLeNsP>_MnrhNw2Jc*$ka_h4=l8DEll(FH!Nd7rc9QTgQ}y+w{zmwKkn%?>uwL)-B=;Z{pZLc6ik_n8V++7$GtW+BO3@qwN=UE=J8S zW!e03PO zUri%0vj|EX|Ca@ha;(0dDJ&AG7W^aOdQMWpou5XLQNhYu<&SF9XQCFL&xg)sqFJ-$ z8jwv|C2BRla@TrdE)soDbjk$h==>NRRvsD!jNoKwA$U`;45@30?Rs}&QGcSht&7hn zmv;7jhVF9c`E~BrmGiQYCsLc3a;ro+zY~a@=bgG zn)$l^zrRq8)k`+a>jbW>kH>4~>CXpQV#^TT{|#r4$dfgv484_Hd00X;KPOu3LGlk6 z9rigY{dapeu^wOSFSJByZmp5x1u=}}|ImMb)l?51(q2Y_&W?@m{0n(+!L@MWdFOk; z+4t*re%w0y5r5}2{p>XF&d+;iKdbNjYCikb@e)Hg^U(N=)z2MyeS7Y;6@N8u?lUeo zh*JOb9r%76V1e{Pl=+q_8T-q`=dd3LG)FQ4>JRHLmowq^*Rw`z#C>hH)6Co+as59U zIQr#UTcnBfy;nPrqo-D-p$VXx5N-@6OWnU})Y<|{2Vn#wMPXoCa5xSfLB|RgjY2Wf zX5569qD1LSOX=uruR(E;)O0aOEi}W3fV(WJZGEXT$i%tR#<(l!CAF`AU~p)7^amRn8&7;6DI0%#PaX`GhYUO~NYHlurO29JFY(9onj06w=`wsq)v zF@reimr!voNj8?FEtLc3XyCJRHt?gWA-1Xzv|1m9n*?XJfV1%9S2W?XE)1imvO)sr zi$50B$vZS88ak-SjD2O?Gp^0Owz=fZ`*$6ld+`hPhtOHo_hw1E?%lPwZ06|je>eVr zXy6wu?IFZ|0F4qc$d-v?C8+>|%pt}kGL(k4yAr-RiCHx=6(d(*%c%F2AT59v0sQ4>96AzB8tPR8b~4iDr$94u16`LxouP@Xxvs0%_;T0U4U@03h`F@ zB#N-W8uS(Su`GPiPgKrG%`n$c>vLYt%_Qttj{dEubFkjYJk*Y|UhN6)X8-dnu2@i=>Oce4)FV9crO7PG`;pi_QS{-1wH3aVjfKoM>mRs*L0hu6XXhuIcjfrB< z3ln4qMHsTIT=Stn_l1bwRSp7!q$_y`_!GHW2(dNOCCd~ovGLSO3Jyp4U(w*`l*t=|@1A`ZSS5tF69FMAaQ zeShOy-}?P+U{~zT%=e$K;zu1OUEe!}#`CvuA+Sk5rh{pvPj7?5&r4m|{=P;&fW=vT z5;=p>LV+XS&+;jY0@G`Jj-zi?H|xC*OnEGD50HJ>{Uytj)-)R#WsuT4al`%r;T$}S z`I9FB$L>{T01LOruQDS|)(#Qu{#rj;=~*eG&^+~-{=<0tFUR7blj~Z0Y4@{+w=T$4 zz)tO#U12{14SIC<3>(}W(be{|U3#8{c~ktfD|RFZ%y*<5!ZkKmm@fmDV&0&+Nd&Gm zq2oZlV^M4V$jWR|3JoVkR@oQGL60PhI~o{YTSK{s_`YEIioEsqLUJKD(C8jz3?B7N zcTKxNzQ#sM6wjst(pb$LRXtc*==@6i4f69hkR;s}reEz4Z5jtA*vq*yG%9>_Ak2US z_RpzeEmKjx$GHZ!l@z#nyOs?5gGk+C8d=Rw=A4*h01=^OT&}?Isqh*Y2}gE8+Y0Zv zt~rVsP@Oo7&b{`&kvi>j-}h*n#rxuACF49SkTbL_8&nWZ6%R4!;5sQX zw6tJ6*0CHuXu?F9cpIe!BJS0)oHC{40Kmo4(Fp{vDrG1|M;QYKP7LJ6(GGejimw$N znpzIUkP1`@Ajh&sAV{U7Bv=fu#2?50F)l1eAHJ<}CPOo}ACeMl#AzwR%q*8EzK=F* zc<1ax7Tdt>P(Ey~z|9SWM43}*KA8ZGT9@JQ;&cKQLV=^iaH-gye6@@CyX(DCz6{ox$6tAzWU*Da$kYR-cTuF_tKLQ&pt|OM+5G z;(s&AOPo3d=FugXW4e=@O7GK^j5A z(T#M8N=d5-2J%t&@V)QXbHDEA*&nd&x1HC{^Elq#k7^$A&S`e`3pIL`Z-!ubLnL8R ziti6uP>6}iMb_!>pCkQnc#*s22mwhW>p@oCA~%hj8!?|D&D6}x#HjOPbQ)%&e`?mp znu$+f{32ngcd<|`U|xVQb+ z|Iy@!XJnQ?j+ni?@a1=0FRU%43OpOnyL}7ry`Rth7Uo_eUv`pnIL{Ld7bz2beE7-) zhyA!FL4)ytz4AYY*QlhNl@oeRSgr5Ah!F2TB+Hh;IONcyb+9vHc*J-(8{5p;tIq=a z2&oh&Y7|sjHq~uz#hyMYArj8#FLqZ zyda)ezCGGwm7Rd^%Y|xRwp&V#n(0w#Zc76<$)GT{?WDNBvZ`pE zL4KNjhVZn%0FR&TAk*Z7Te|GQH@NWMl<8U*8)Lvd|9R1%Knu~VH>7k7e>>~%(c%WT zwk7bt;~B8v9_<^bXrH3dr;`Z_1FGK)ADiwge~nU=^|^WL`Y$dN_V?8DKqym%LWl5S zAGOSxYUy){4l3<3rlJpqLNd@`pQitqHD{Ga<7FLCzA9e~`aumfkSL=kb5IG}i`2h7 zh&Xxhu))pmooDez+-PjTJh8z0Fw&h>Xl{B|?& zbvcsTJW3k{{$GlP)wL}l1iw}+EFgdWe~QJ(khQJzwPJBiSX|>3*NVl-$-#$@@2>rd z=$Hg|58rFW;(z>#{{>n6AI0LDu(*aSlvVU3rIcLUeC`=o^z`;zf5!iQ{f}b7Gc?D> zX^^c(#qm0?+s+Qz{FYQx|hi_>rVFygc#w|1+xk^!(q7 zg*qG#p%w-pWaQ*={ItjfI({hfdU6#P0F!~EIqBk%v`Pt?WYMwEYI06^bu|)+Gl+ol zL-GnlAg$2CN41AdZH~QV z`EY|T$tbWyfffz8-9R43ak5COt$OBJh_8(SrYsRoLW{=c+)$_!3-E%8M`U^zy( z>{y6RANq$Sol$e?U@jdMI>`+~23RyugKOK{Utn{aWd4t0F@p^=*gDFF&_n+qXzG-B zjJFx!K>>zYb)Nk6y#{k4zDQE|mAW}fbr=MCTU3=Ww`T+D_-494HTC*`kE$QU5hkw? zRH_R3XmENYh!l>MC@l?$SprV|SEhg@dfH32!a`@ziwxQ&k_xgK( zccaBEUvs{MMQ(D26?((*_PZ9nPev>9wpbWJcSg*Xkn?mn97xfcG?55~8Vs+5qSX1e zW9UpZ;~!t?(WMC=Q_Do#E6?#pDUwq&;K<0)2liyEGH|?`1e-Yl5*3iU>0yK2Dvwq8 zdAR!&yHg3kNEDW5!4y0If^7IbK}$x31!E#j3a6)lnh9Y+2r_F!yg_@>F5WmfK%I-i z38WO2Tq_ERl%T-k92uWL-4BXG_Ul|R2u;F${9}RAYqVG3cYHJqa^E}koQK?J_xrm#1z=ybkrr@uZii#35bhDDADhghJCF<+#5u}^iMe1nWQ7=x#AF@ z47+g|%T1#1uf{>C@F@!lVbW|%bxIspQ>3^?F^KdOy?N3=@}+82WQ4-Q>;vmDpS)F0 zZUrF`P>NzX83i}0A;(V{Giab^&mVOLv!;MS^$4G&dS_0-YUV<-;VNWTlU%*<>8y0i zzCUs(IeO)?$zIs05?0ATE{@}0ua!w;1lhWd76c6crURqA;`%|aa}fnX72)qPj=z1N z*@A~e8QdDmeyS##KxPy})3SJ^E~IWaA5LdThm7Np2XJHN63Vb}COma>1qdR<30`=_ z`v9UzJrx!`usZQ2F1U=nm(oRQ^GHONx*0B`%Yokw;8L>|g@JpGdDTR@Vm1><>9Pk^ zI)n&b25xV;qWF-{n<3^@cq(4BXe9CLNaKy_1Z;>BYj{lDic5@3Xs}p@MJgXhe`;K)7#)$upQ;PisN0ijl#HShr)x{0=w_5cv5(oYj=f&> z%a!7g&L!jWcYaU9%Ok^-hw5eE3xGIg`B2W*fdYYk^9xh3pCy{!oc7qd*o~U(^ORv z-w6imI_P03vDnaAW#f{s*MsIEv+TSIvpkXpOs9rQ6bW_ZV0tU*h_#R?(cML8OIjf6*1u^Hv7;!AEky9Utkd1y z`PmN*$JqjoUk((;9PhQ}lRSz!=PMS95g7>SvkTcBH#ND*#I<6aTvB63)K~uGvg>UzgUG0At69wZ|I3_VrsT0 z;@hmj91WMfoXl>)EYnV-`Io5NVl1BQu$t8_%|fecG*f($;B2R5$yB|+@9`_z(H7aL zf5Habwg2wvHocj^X%JaVR|P00x>~0Fj<>Y`W&gp#VNm@PoY0_sortW^RvR`|-r}TD z#RemI0I!|z(CLzQ(>fQ2@knbx;s*nvK6_d-LF1Yym!;+uEAV)3prCraSu#%&2i%{! zfEe?YIoSFE#(z9qco}LHr#f2~Y!tX?Zn*N&V$_)bKSMPop;_t;RyhH`nW-?dd{e<=EOn6EoeF@{Jo+OHzS+VF{l|R!BY6Ai)@4uL zzc7>1zkf+YFS(XV@ENPG&+QxoMVasbwIgA9pU`55Nk4RPBV>Fl{rgz+uIWv?{!5F+ zKaWj5GCnB<0!AOCK*zKHo{b@PzL;=By`=tKzJ2rW*IVMh|A<83y7x;4PlTG|NkZ`O z>rtl*PrinytX0-n6?-}Wqu_J^=I!k;(!Th}|5QlW%t^>g4VUxm=XU7^RpgN-f<_J? z`AoI-3-G&WQ8_@{pGNxrV3f$2f;^qHbWZfaFFZ0A`8VD4Z~FClf%4;BFIQthEe*jp zXOWSTkG=7cZ95wFXVGDzDnno)xj4E!tT@yc`0!1gtW>?9OB9Uf1{0X%*CYz(B!F{C znP%qmY#?bHlQxXrIq{QY(q=l2ooGiAf+;O(5U>1T!6raRFk3@Uhl_ zX9$3t4UByfLb7{bO?aFA`xbLtx@GTAcMVAsW59&EIbKK-Ad)P4aO}~Nl)^$Zac3NM z_z<_VR^9d}wQ|XX*h8IoIITydXdMC2^OaCsQX8O&(nCqQ&n1>g+7EH!qPpbM2yq}h zL~9$~7|V2BlU%tYu3N@lpQAPxtZSv2rs^O?ah_5M0Q99~(lC?jn+#QBkP-?Y!GcEi z#gs67n1-zgo z{=-0~8xyDW{p7AQJG#n*GhE!V3u~>Slc68X*md4;73W^cT=Ai%j+xqhs zDb>##oFq35CC#Th07{I23|^KPGpF|?U*0NLtHVKevCUau6CIs?7p>eMoz73%{tf|VBx9?G_Bl0``tUn>8*zKi3BgR8t{%zVcS~qGw%9l5zMw36 z9w#M762x72kKxklr7tugQg%F>^`ARJu!C#Kf*-(w4rzrnqpB0f*ppUAoj?&Bp2HnqL;^xJ{CU=4#y`#wLk^bZ^^c}4NGH21w9!;& zS9#s`{LxJ48pn!0!w2tH?G3P=IbRG1Nc?`BRLTdqhVc9*D-mOMY#A{zSEU@Nd#P*LY?;SG$4X+p4x3J7>*h-5(LmO# z*?si|IUdp$kx|lclaOvJD99*Y<$HG)vh`L+I3ViV9Qa9^Q?q|04mvPBV0Qb;Ec8WA z0Ha>1C!xq^`QZy1?upio5hYont8k}&2j{vE2AM5Do^w!qEv>C? zj-@dGT}ZKEz_1aeM1j~&nHVS-$)z%HYr<|&@w5o@HaaD@kX0DIk4JRd4JI~)V+D74FxCdD9P7g6?d z56n-bowfXu{RNde`t)Yrypn8TV}i&}G1*KtQICNt&3OLc&%% z9@N@j*f3EfbmK?qh~IU*=RAUd>u=ed>i;uEV4EIPm>#yC9(^=DUNk+~J3YNQJ^N>R zj%{Y4mlVd<>DW9OK#1%c;$*~;F_eONTfspG4ZG9eCR~5-A7y?VNNbn=ZCoIH7&eHI zBz$9Chq3*u4zoqeRb#pT-3QU5=n-=>cpR4@UWbqk{0jlm^HZsyMBgYqLLP;9fGm&L zI{&d)u6WJ-o1FADCD>@h`sa$Wyq{mJowva+@b)d-oC(~oTM$uP5Vm>Btr+#TLS<7d z#m%?b1DJ9!mzUizzI1eo{ktfek7T^OOfvA-X;4hde)K*Ql z=-E5kbm0wkjPIkLJI_DpP2^BqqUK)|O$BC zd87RE+J0T~yYj^%IJxiCnuPlrgO@_#B<%KDbRiR^h;LNM-*WZHT1P(ZGYiewDTc+i zguc(wpB=HQ`OyIIZc~Md(^?*gjrZQVgI_ySvsj2w*EG@mAjO^%$crC`<42U_>ZDWA~d38W=v4vEq=4) z@64Du^VWs;1~P5y`{$1(m(emmwyJHmsp4klqBfj>Y;PTL=dDHMSj_c;LWSj779d5r zMOH?^q-G)$7K6bkBVTArWGc2hFjAOLr$%x5ea}!MN4n{<2%!wy&7}4Q-&=m4hf00{ ztBPwlWb{0wYjbJY)o5hOGI$#22h)$~;KG2ScDiF`UjB%32qH0*EZ(m^Ds|ANwq7e9 zUxP-Tqy_$*u(Ob#IeX;9c-z6yegd@c?ESha#X^qoLOT25w9a<(kMY~Wx=D|>KDaMF zq+DeBvSn4c02A4YrL?kPcD0?`BC>DGc#BNdN!>}d0#F-d){ zvSAi2c|E|qY+^D#yfZ?{KBixuZ&hG*`iXU$J!^qgei4mflXlv0J>O_-zj1_0fmqn1 zzsHKYmO+aKTrMeIcW1E#Q{EoGY-%>}A4+?fIvz75OhxM~-RpTM`6Sp5Xj@#eQ z|0&*1|GR!Ae3&?Ul$rMN{meI}Cu?LMK2|hF=YDw4s(4(fUmw)msi>}d3sXk5byIft zCUvtaUApALRw5rN^GUn4v2|P9+(83HRq1wdbv*--+cML0_UM*Hn~S4rx&wlCPQp@G z?Fh|a2X#J3&}~NgwJm@{DXJ{!93tbsWaD4lqz+Ly%TaLC%QIDdQTm?#Uq;H-Sn>$X z1j9`t;;cI%u3!9NyXwg1jb2)9ak}QG*>{e(sV*AzPS~jqUngu;d2b2UAF&dDi?N>< z_a9dFomV}*TIcyj_p!1}f1~{F5$(r~+PfHu4J3CA&`YiA8p_2S$;{BgJ`AF^?D>t; z&N2gKE@!)Jk`VMiraO=cF^MVaq`a6;!*q{4bE$ZiI|mf~&gQHc?iq^i6rjF!?Ap+Q z^7?4meOSXB*KoH)^y`QF(dx^xwPf#4iib>ViGN$Z=GNt+vCskZb<-FCjRdElh3+LY zC`XFSYLbI+5^}0H2=iKpWSj-cXxe36{i->>Aj|tk&uyCm*C~u`HpNZC1C!R>TF!g+ z<(}{VcpQ;)viE3XgpG<(jXKaCf({NruA@&! z1m!4Yi-KCW6)-poY^17UmBWdeH6&0NX)Q!5QyP6X2clJ#8g%rR^pu|JL$05G-ew{) zv0ve7fpZ91+9;Q|RN0sotzcc<;51;cX=pGKTSFm3LWWWmD_4$z=>DD4 z=#DEL!e8)1-*^4i4qePHkNKWNHYv4}qPO-Py{sDD-<29qYyNO38?C;5Qs;kXwp4Nk zqK>%#_sQ2X#vI+xME+n~9mM(fgeTUrm*^OjL+gFc7Po__AY_7485hl;#T5G*5`B?t#eI+h%Pwa0_$Wwx%HnRB?nH#{X>%<0HC1C^i`+!a)e3)mHW zoGu?~ijI!l_Y-0ju0-&VF=}>vY9Vk|1*>lW6MzN@2CTw%og^NdoPoyEkXUzPks$-_ zkubj?dr~W;?i?NlEmFsWU6QUjWJtidnjF}AjxUQ(Y7Q@rO^J1}S;iPfg*$vd)OHLq zLIW_bWe(Otdh5_*oc|IvX=U5haB73va^cC#j>$2>%I@PN&*na`$7#z5IIOr4dR1Ry zFihOwXfPTFYvN+oJ$i&+iFn;IGxIK5!8?0VN9&X6*1y)bIikm^Bure8U}&LbQ9{M*c3x5&AY@TX^Ul;MMJs zaB@P`2)Zwtr6!eUAPq`cJ3fOTEfP8pf=Dd-R{(y-K(3kCZ&5x4K-3(IE<3Tarol9P zMLZ?DuADE~WYyFEa!akPbz``6qYUGIfXkr0rcqIG5e-hqz)h<LXQN7zzKl(qA2e za8v>TQdlNH-C$>W3Vpdm9cw|Ri-!Hmk_Ry#__0khka2Kh|Csp1(QvaN+4*kL9M7Ws zUz9exaS~oR3kL*;mr`H+9Af;5lJZ!z1V6q-&%ZJd)8@d20cwYZUkj6qR(>Q-n1;{_ ziJ;<(rW}y;T}nfb4dY0?Dp(`Ogu5I4;w`)!A|et-uEpIuPsC7YN|VyQ&{Y3FJ@hP) zy64R2bLk?8xtk$7V-#fP_nu7SKKOvgE@LyOsg_tjcDboC*867X_Hxsa#-LXs#XQ6Q zRPf(hZ!nK&R0?^h)$Yp=x2bN)Yt$|GpC-}ewOvT8%D#nm4pp<`LGlluUl-^&yue-Y zM!%T8^*Fmg!_&0Qd%b}(sv0r%AWpAPu%J>qGf@?Fr#y>W;ef%oVA4S(-RC9wdyH#$ zmW7d6Nv-Z~+a&+JFzxx=9`2pHKh`JN#Kf~9j}bB>vO|#mD2y=~V!#>B{9)M(Q#P@@8^=Tr-pjm69_ zDkX-mD=SG%0_**Gj}%;Pv)4TLUHGoxlp?UEt@R?ia=2Rllt*VUQDjUp=kBfEw{(aJ zy_h80#(A1!C04nCr##}`lzL#JXGs&`4467O{$r`<7L9!+GilN}s`^|Y^Vgv4LXkad z-R%wYr-c{w-`%yHUW6^Yq3O6A-B<6@b2UA4qoo|%QDF?}ykCa2M)qZuc z#E++^cAm@=uXrS0+=+R&dHK2&KYD?E-O$LB>}Sa4XFmD)6Pj>dWk_(F(x-b4D`QE<$ zUf|yPvxU!=uPUM?gr9s<08AKCs}ued9}KEuM$oXzzh!db|6J}s|vwb&!T!fKwhC%Z>r7L$CJ zjsDfk;0fl&$|qc>#^1u$28;THQ;pxPr&<EDK>{^!mOpKOfDoO82xl_WWphDDUlXQ({QT zdgq`sS1$UW>fm=?X0QD+Hk z_p}R8h>%#>_&OHKmQy}IVtpXH?P`3HlM?uf^StdVtBx~N3KG=yPdXTftcRPF!5&!!{ z>%ntS1gVOtYgOe+_*G}~hwqIK`>ZU#Uj6H*{MnM#cj|Iieq-_F&yKdf&puD&H+MyT zbuadP33?;{;o{}5zKg!E5k&bd$nB8zb$(b$`4k}3+-4WeMN)FUGK-1?)RZ_uP!!CD z1&EBl&&X7uWE?+I1%@6@Ib5e!-%??k#->icUsqdm(%?Y7OP)VcF@)16u3^X`v_p1% z!L)WR_~R}WHHwL_`}lUCC;|RtxNBiInKOJN+`)GIRpeLp<^O7p-z?t^#6bo12NXGb zqo_2xTA2IY_ytX0jj8!6sqq`f9xwelqzZ{g6gZAP_)8*KN>l`GA=J#l#80!ILe1-CuwkNr$S6ec0^t~H!<4-on= z#I=XjPaT4z@q9F3eiFyZ_5tWHlJe3HW@*YSw#$*oQKz+D7t2xvEBJSdg>uF;pv5{; zZ|?aIE6?}TDED27Fx!bnIu8Hhn_%>3`t3b-5D2XY2Ln#oN-Ep~eQR(!HbNa=T2Rq6 z?7MBB3HG|<+V`viNH3MeBQ0abec@Obpn>GW1G%FhEJ;0};q?b7zTTZ|a^1Dr+V$3= z*c?ISM>7fmpXsqs-}n#hNV?iRt*Eh;J?t`ocWu@aNgCFZ17(|oL~50wEb2yc*WY!T z-f40yffGmI)-O#^Rsa>L5^p^Vu($taHJ-ZJ(@5H1W%aC&?su$Z<|kU2`6admV~z$( z_FQ`^rHb}X3zPiF9MN}p3rn^y=Iit~mUW@FaMHpAENbrED1fC7S>Wu)`s!r@UeO>Jd@ z3<0z@F0-U$6*379D06oER3xEvXPW0(x=NFq)-4PcwpXNn%FP&;rfUR3G9`FfM>5b5 zq%j~hwp%!d9cb?;6kBG1*Jj~^3O2;iqDL_@NySjhF)gDJrFRYAcoZfItKF%sm{nVI z)+~N6vxC>@M~Ex!-z>RB7W`r-!{_f?m~Qm76g+jec-KNG=EEy@W#Os`h|&c6J0-3u zpdx|_CH511E+GMfz}W8BG{fmsKN^J9@{UiaKX#J6qVNYuDMQBJR1S->L{sBP^dfl~ z!{C7Kkg;EUTspEkWKvx!Jp&x+QmSDfr5518sYJk!N$CE9k?>eMNuz+bKQ#DBK(l(l zh$;y52s-kZgAn*ea=}U>^jS<#7&x8c6P!bKYNAE$L+IEH;-AFw0!u=o`2nx?L8= zkP~UNo^ym!^`?E@X<8in$-0#{se|ziJ)?gyEqiORzeqikTU5op;!n>N| zQ6G$Iv&dfSq?*_gNm7){*N#dbgHJJa0;DY-d-EmI7^Remq&gaWZJ{!1(<6Vso~B`X zoP^Ny1?2YXqk5Q&BE!NwYLer6-m-Lyrk5-ml7zt84fG&1M z_YenEAn63z*j#9bV+VJxK~aH&GCbr)>TpstnNTz~VxJx^qVjtfgvFm#73l3L??o!- z){-Ftw(R#vswMDC0Sr&Uz`jeIqq^yg81SA%DOh_zzmUXW!6Td-e}_g*L<&UFg#}{? zw^5Bp$6TrAah_gBMbj~!X?6W~4ED~8GVODU%d;#wtdO#K)5V@P^z{*Xx9y9snFRB2 z?cMjjw}&OIe_q|ka~yW`^54kyUgfVr^APIhY@u^Ls$JL)A95%b>%Br$hK%z7OJD8C zB5`*}zMdxpExdGoNw{9R)~V0PT(51-l^*nx_@d6nDz*K8-?Y+Fv+C9Sw=zh zl<6gbt|ibOx;1u<*6lqY35!Ddc>5AG5rQ$iEZB_KFFn8n&+O(UUC(d@SC+l6Py+&@ z278Uk0rynXb*@WGeW}piLJVHR5qv#bs&6#_m3jYRPPs4p-$P(aG+zmSNX7|6Xv!GehWZ^5`Sv z$w@$1t@6qbeMJDnerZ8h6aeSAC9dH`uHNZk@3wWF*G=KuBu+uLsP3W<3Y|_63d0b* zSe!-4>tTL&bK7bGGO#LE2++9YN^WRwD?X=t+c8Q+2hd2#5azPK787GdlsKi8#M*!b zrX&`bZ8|4`{s!gDJ?lW1{Z-TvkT0} zY&Pki5^Olr_u17XG;0hrb=p@48o&FtgACa(P=xc;cAZxrbx04FY}zkM+hKJ9x(Dt0 zUnTDSYQIO6Fd*$PpprCX>@d73X~f%MbX(F`y2JP`QPM=CV{7gE{*jN)!R@#AJCN>@ zOqmkDFqsGVz`ZSrTRFmdx1a8<1uWM|icd=1DhkvTf5=&Zrxl~jbRTIQjTP)1uovJ> zW80n`9wIA%Fqi_z?C)(w=Jxssw&GFNTr)5?`-h$9z)BQosq}gxVv_JbeLp=bfrSlo z{VThG?v0B!Mb!>g&%Ayp7Zda?CyIQnoGHbH+<@1nsgqM*>3hTOQy3<>&>nI5(AZqruvm1jj9}p z1%ObRfo1DWJ3)Yo4bM=I=45jLYre1fH|Wz$G`e4opnP-;zSMox`-LNc`&PrQs)3$} z*R%~cLBVAdB7+6tl7t6;#c(P^d?)PV;yf7VC=6yoWH85Nnmb|fqo&bu#y5)$X43cu zU(l!`0BGJ?tNGaQJ~&Zy(9jK9iO#>YY^45o8Ot&3 z?6LgsGKno(tmoNdb>f-cH$--Wp1v~6q_B#A8fgZO)xG&u8${_@!t|)zifMp=X@r;q zOV=@kQd_^%mwU$|P^>8Im6&N0s95j={hVyWxdSaJ;T8!fJ!eD22K!)_KzB|=0QZZ;~nu(YxR;W}>1n*C(@Zu(O$2Gm2YA9Ee!yVc5Yo+G? zt<{`(WgbIcY<(HLUZo1*%g5C<(ze->DJAL|rN5LtDiI#*s~Ic&vBYBX%AK(^^rNzs zp_MHcn@V?>2&--8`}}vOgc6~WQgL%l{9F{WYxooj{VGt@5UxRCU+(2MtVT^HP1=eT z9v%_uYz4D%kVkA$C)JmQA1kDjHQ1M5m#zt#DGShaJrpBVqF1So7N?9Lv7FX@Ng4?$ zip7C-W_%E%V#vOnA=PB-tfBw^;CR7N5 zvWqIoG^^+#4oya(H8oDV@t8g#tpH(#Dc8}ptDDGgmB-z>e>rt`jlRI)%#-pPCXcGOIn?J|J8E4QdUKINPPNAY!4F#XHePeOp<6^({1vggOct^h*{g-^xbGWv!F_Dc1-D>0RsqVr zD1j}khe9u(F3`6{{9E}|7+jY2SL3zp86TW33IvT4CnvB#V>ZAr-v+$HL8ujXI4&6x zDawF$up(!Pf<_X^*m$VW_;2P25>?NMN!sahk>z{5xp2U0!+9V9rTNkI1u|sB#ASlJ z5W|q&iZy^>9XRtG4Sbm-bLdA*G2eeU8#$m!1F)!pX6!d6%s}bGI%8ES=DpbUsFmV^++2X7p-Uiv3O3%3$yiXKI=L8JpDK& zspMtF019O`)|Djm_d*RnSc@(NP29JkgG2p=i?XqP1pF?AeTE+i&TcEgHaDc+o+La5X@ZDfYp(V$AkgwYh zHP~(r9soVLA-j6ZlYAShCX6ZYs0uYX8>tJ$V7Y=qi&adMZ=Kg3#0m>k6K4|Ae5zMc z<_E5J?l;n*5;}pd#+!D(8(vNJChw|ZQ)b87!k@!m+ zU;vmN0Ch$p5(7c39xSC;*aL1SfWv!`0jnZQmp-TusXfBq{Tr3oJcz_`1E8CET#+;) zpV5OzM<-nnK!;~3CsdeLFgJSU4=Y2F)@O!KXf;){ZYKoo4nx6zHWz8h=yo<7=jqSS z2gv>yf>aB3$|V-r`SDGFmww1T8T8M5F_@bUO$H$OFzQHV1n1z}dvkkGkOnR8#Xawc zNGaHZW^XGPMS<|pdzw$)FKwSk%3DsS{=LjMTaysC{Pf&{l4!9vtxL(gSK|8b_fAP* zn(RUKO~}=!`kIp8EtO5S>pNu`OboNhUTLe-8o_VyXuAwhCGuz-yhGfswZ8R1Bf(&CkBO8)@pq~p`shD@b2Zwf@z$XkE=96CR5 zqakM0zrwHZ1?T6b`HFY$e#B&JZas$gevNF)waH(vcIYQU zgoPNMCcAL&zTSk7$xQmC1vGG_FSv~<9M4O5)6vlXsvWs=Y?zK0s^p+b99I>{OpCFu z*1eObXv)K7cps&|y@!^;N^u#AzpihXvEzRa+6XmEOIm+oi{#M_4?IwcAod(V&f&CDgp)ymKY%pn< z;uD~$mg8ic_*#8f_oDLC>5AefYWXT7`ijN#gTsG=9NsSR=0f)w?xo(J6s{6CY>;QC zB6ctP{54KgVRM%@@=(1s7+5K{cVaTsGW<%)q)E+-)6SlBiLyn+I<kG$$&$Idts87gN=5M@c-W{AXrm8bt zW?O2hr}uIi;Tsyx-Xt-Zj z_@5Wbxg~sw@-rhQsqM3mmEqeB&i$88de+~r+#3GnB0K0;++$VRjJ=~w1BM(*2(8B*B_{q!rps-M4g(lx;Px;0O&$iAbJa#U$g%y_t|o>WYA4O1U|sidpVNucFvy8`{h{(zw2XJS=_~*1I$Uma;8XYs9)bK^PVKZM(;#_zq6+9PIH3Dl|!4+@-$Vh>HR)>cOKH<*{|6GeYEdAmbCuckWZ89x_I3f zvtqS<%O-HJnB7{uzINg5hpd5L-p5cX*)7yT&`ZRO+nWa2k1Tf?Uz<(u`)B>0`rPk* zWA*b(feYFNqhjHr2k=8?*X91bzYk0ei%y7s?jbfCqoy;l(+^!AGksLabBLEFH}(3j z*M)e0*Hw}0Yw^7hi-z~F2*M&R>GF?17=OK5&JdyePyOV;>bdE=Wy;{Liu~&{^Pg+$ zX>Q?PH~nmcKS5oLdj#Id_7f=E$=`=r$bZcH`Zl%c*+H0vzae9DXGup$q<)AWNVds` zx7DjE_VR14_4i4i?~WOQ7QEF}JB17~2TvQ^##vV8FKoO&>)BnMF1-JeG^KdGdv zQvM>_-2M~~^apM#B7YH0GS@5wE})WpTm>N%(YIh6=#^MJ#qx{%q=L4(U*xYsR^Fka>(&9$WK&VKJ?In zi`3tkH@WXH`OR7oH^bvS8qTiEaO?P>8w@6I##3f4W3K|yPcLkrJEqL3*%?4nD-KfL zji<_AYD}pmcN~zJ!(DQnL&wxo-q)s`jHkl4Zs+aAobo-rxQy;rxyz{e^mpyk|HhyG zJ$y=pr-S&@AzJA$_jJ<4bVOY`aw47LD4hzCLCv4hYywc62^7;keV^?-b*cICQ2U0g zh9JEjW2`oc-VvG4e94I4sIg*j!!sYLLnLp#t4s-Ex;-|QQSb7ET`N;|IkuuU0&H%= zS)h+8$dW$tbs35KxbJ!ZPb12jWvfZ4-ct|%q#AQXpL!@0sg9s3SI!bLi>s)PdFz_U ze3|7Ikb6O@$q{EV6`ZZ_tf9D`dH5^nn@LV_R*G0=TFpRm(XYqO@sXBhE-I@wE_FFh z+@cB-rs<@1jWzl*zg4ST!`{a|y2l)vwr(Wk{y2{`Xa6ueI^J1x-^gOZT|L2h(t<}H+ay@H@w#N=dcw|XNd(O^9)R1%KgwO9yf^a zTQ$ucX9}>035~KSJCC=wF>^48cWDSIx(sssci`QG!1-&G#gIHOU-c=aFK@}w6S@j` z@rq`&I^ujZskz&-_?3T80+N~6NJQ>Fc}?g-Xu!Xk^5IUu6m?%~Cjg0-DOoB#bG6-! z_gmgC|3z+k#D>iBG^FitvWG&J!v$N#C>gQ1a@K9Kmz#6N2op^t1~I^%IrtC!@7Gy!Gt@6vD}BOcx60?Q3CWET~+DgeC3|M zOX6#BT=8+Rs(C+wIPPBVQpbyx^!pvkS#ecB$>>^_?^}T&)-Jyg7=}rQP{Pq+;IcOcWm5IdRL3>yfM@PLS5-pGak>92zKrXn6*oblyx;VOEJx*M z*($*GHz!C(r;;ck*vkDZ)+?|+&c2nGG5AAaO_OQD&+3+m<{}%;xR*nHdy;eK^VIl~nzdJtEGrsa zJN4DW#lg?v zV3R8>k~809v{ag??d318{I5nnr}2?hZBnwu^+NcWR_x%3N2g9-IP=0%-~X(Lg{>6DUpzROAEHLIbqA z1DTq|crj{sfg1ng;$MQDNUH&kX@b)`crWOA8hDWnXOb$9cW>aoVHl9^M!G>tK-vM7F6j~m1f&}ThEC~JX&AaBq#G1z zkWPW2TNoM@=I}pfor`z9XW#6bz4q;cT`_% z4^5#RJyjJ;z9?n0E2LwzTPtMGM&aY{ca#rsc$L_D1o@#uk9#?ZO;0G?`xmt=oXc85g*XBwL~6(Pt%sOz%!5$Occh)$Bg*Y|vc+ zABjJvRB41v&Fa}~kxX4W8Qyx7{D=+cgn>4dSC`>I9w7I)9ZVp&_K%Aj>F z_FU{r8$HgCb`@W4DJSSk(Np->^^T4os*_^vO-D0`eE+`AH;THQ^Sc|)uW*AD=8VnW zlzdgqtX2Ka0QYhFQY-VPOj5NIefegU(SD8BzhYu}#h+9E0DpW{h7B378afbeB{jd( zxe{O5IGwpTTDg4C*;Kk*T@l?rVAxmpxnj{UCpp_WkwTk3@Fzy~tILp4z2pA6<%(>T zU+J{%F*!|o6}@%uItWxhiNEt!l}P_$@?z_Y<&1qSo(jy7OTFZDocYliY`9u^nsYop%X4cGWurX$($;@u63OHuTB7?1faX-lzk0v!KJ0;;%OeC` z`y2o;5H#d~2Ox)pg+nbs?SzM4osT5b89tsJIJh3#0w793&eCeKF8(8|i5&_p#vg%4 z%VuHwZlGM}!ZRS9nzQp|U;?gH&@pTGrM>30 z8j*Jrm3S3HblXDy-^K$DALzk&_z%Ef0VV~7Kg?V_VmCKueSP1PlGFajc=&JKVdsH) z_+Q{5`hS3j2m9dxc=!+VFgf1b(o#`T+1%Xx06aV}5C7Tl{~G@>9ulnVa&0TB9S^%) z`F?sjt@%`+_@AJA@?DkqXcGsE+=m<`^CrqXRsK(o?Ef_$PX3~ULqfyCBO;?dM90L& z#U~^tC8wmOef;z}JtH$KJ0~|UA5l?;zRvRIfz9NRuf(Qk^om{@$6 zmzU?f1ejF&QW$8667fxx(?pxpk|o=P+n7n5gZyf*?PtsU;82lFZj;DS8UYN5gtrxk zHmhhdZvr|eyadk}_ru1cK7VE=WC}=FnZD}v`2a>7o8JzNpkw$1C8?b>Oe;h_i~^fj z+%>qz0vAM#W!o4NiV+IIWxF_kr^BT6Ox)t=SISktyt4$HT>Ouvb6NTVYiGqp)($L=LR55}*QFS;y3;>yU{33)#WgHan zp-ixT;KvM^(hSgAN#mlkorV?-0;z`)XPktk`oDDP{ORgefs*YWt-I>-!)K=cI771iyiQgMi&2 zGyWcC00KJ?2Ass0f^9e_yuZb-3pp24jJfj79L6PV)eKOu-~IP>T%|#Bwc6 z<;nNiivbKFKTU&C89Zf05Mu(MsC(a?9__~`yup&I7$y%zt%R|!n^|BF+COnwnf##U z1v*=mD&;BrV>)GiMQ;L;GQiz?|j*df4pAQwcUgkVoxZ7as`TTJ+;k~+!i*H-OmZ zTnPBU>#XZGRhaL;G5$TX2aHww$yo9)&2i5#M>Vwb(uqexK zA6qaOBj&6ixWm@7;b{(GxL6{l;VW@)lKB`ZF%f)*HApg9bN%Hf$rKqT_m)bA?fdOY z2%9p*^gMG@nu|MY0qZfNi17g%tns+2Mp`sG8QxGrMOvHiHtpcCH*K&iq2w1VlsLdY zs2IPS6wX>Z9FgOVDho~*q{2-a+Bp@9GgE_sS`DED+*>5*@8no-6)}|oO5_vL9(xU0 z`c*YgZF1$uLiQ4Nc>`NMAA96*rLs4(-XwstXcJ;y*MfVzR9v&e*%O|2)Tx4N>$0Ec zBBeaZL!4R+h-I3H0gjm*HOIFUes6ZPNC$D20U)GhPe><{yqBu6v0OeA>Rls(heONM zM!4}kxn5TnPN@~#>ZJq_%Jt}+VSxmU><(s{X?w$2QK4Q*F_{iqN^MJWBOQ%oVrk+K0BYkf~uD_2mq z@a4|cRWT!G`theKWvHegBuoABXV#!;anYYT37RkHdPuWJIwCk#ik!X}E}#XC2^B5c z6Dg#!kL!1@7LpFe*NG9%P!%k&;BtI*YR66&4cq7~6A49yF7*u_KT^&p+TIc;4WpGY zDAgiodxyCuZ3B&brX=h9RoixRGnV0sh@|Sk@d}aLi={jiI!eH4Bb8=E#h%7P^0HC^ z?*r>{>U1ocRSK$n9A18Nh- zFTZ&p23D-SeCVVm9@5{&Bq=TPj6!j>hZ)e;Mr>0v%o^9AcfvA@4#qp~eCJy>On=xw z5+ru7ifNU_J$hdoUFoduenWbv(m)9m;hd|v4OveFp`x@s!M<$$&x4W|+_$a))9~iV zO$sPKrD#v)Y*iXWa8tGLbuWHaTneV3k#t=Y$uaHw1oe;abkCJ$qbx}e`?wP%hwFPGrb1n@1$A~qf|I~#oBvHyod{0}ihWK}7ghOOv&!4G5G|OU| z=y#f)u_v4qO|^PzalfbxuK4hL;!R~9UDoijfwZ$V!c_mhLtAG<;;3Yn|}Kh2hmxJP+SYj@oMILGp^T zJh3>0M?j0`#lA&Jy0{5L2qrNTmqy0dPGNTsI`gKyKqk9k)%HTXQ#z`a*cL6R&K({gt}38FpdelaTIW;%OF?9Rl(Gi<=_ZOq&(YDPy|EKV-_I!;7d zmOjN6%5{(tzDhIAc9Vfg**LsY0!wDmt2tC-7_>dW|J1(R?)*tJJ_O0TK{A>OB{ zt^mAXD+9DHI!C;0UPDgOl7FBLR{9+WU=753)mpNxwng7tvh!4{zitLt9?2OmX7Vcy z?UsjuGsQmnLu{elBUcfUD^(27LvSF9p^sc6oM<^$AJNyA$9A{NK-SqOBEGCXk`^gy zl=h3#PneS#fB$pz6Ba+8cmG>g-6<4mlI?L6fcFxrb(uN_>3Q3LL5IX>Z5@paK-7ai zh_7&KK_M)sEbphx01`p}B8mxMrSz_ER=OwZ?1t%pdP-VRdk0LYm9`+A75N%`Q>#DX z{!*m}==jyYDXrl5oVQ-OGlG1wws(%nVa!j@nr6bnTJjvzivQ)7q1;s}?JY;bT;6jB z$6V47ZzBm$#!Hreu7T)`EB2RGz(kZ%NtEAo6h_=fxQ#wWt0IUr3H}xV@Lam1Cy4L? z8Db^?UjH6fOM0R3fzPG~qd4)C;NW%XW0Y51u_)oTEXAJCG7z-+o{6HxrKUcVe~yJp zP@)q{38FyKa0O&t2l}(oZ!m#0CxNP7!-e;?yw3=8FcCC3 zegI6w1jjxFs9+RUQ}E2*@Xa(hDHKF}1CPEG#}f3fT@ME)f)<3>I{GMT8-ZVL0OOw6 zBNzy)M~FX-6?CC%LhV*10%y>17@<_`5ekt?C-is?gU$pGmiYdj59^`=bA{mH0SdGw zq>&2@Xc!9y;|){!Iir6B|MPV~nG%SXC;oWlM$Y;;5KBShf3oR7&m)q8D*i^#%*c9QH40-uLtU`k;5K z&E<)0dlyDRz)V=t9~q&Iq4xqK&r%OV8zX{418zw{a2i6j9_p|Eh75r6K_v{`#KpfQ z9zghGe#A8<3lIaeS?~2DeHdtN<6J^8gcnmYMG|A?;|L|Vm`M0{#Ki(j>|e>T`=CTha=BVi!4f#`Kt7iddd+BD=GkxH$1fx`ZMS(2*N(uEhLa z7$Y@}Fapf*`kCO$N6Gamjco`s<3cjUB1>I*GOM6+#6F~>nJ%CovsDnps(_X5Nnrtj z7({@*tuWj_Lb9SU4}WOkBMD6G@TzDY72{xQpnM~37A{Wex2o9fls!{625H_DVL6h@vydQ??-8}_0<3Jug1y$Z+H4joevctl1 zHBMH}Y2U}5*UFh{%{^Mo{e7EzN|Sdck#}K~cjcRRlacqQHSgbI-u-PJK%0-okj%$4 z&Ub(TE6QNgn+S6xDd~-e0e}!d<_o&!qEq0~dyoVRFu5O?Z;}d&wxBRrTdbBdc^d-< zu;;2MsJf==p|*dNM4>;45N9G{Iw*j&P>UsHygv(3g%h{H|OQgoM`9!B4RM3|eDR9$} zeEUHnt7$;)kv5zJgsBB%Ws36TLLfcL!wQHJG9^g_qgvk~9z~L(SD_(jd4h)B0uV9O zey}_;iVy-VfBdj$wwweR!HL9=wGZjbFHf+h#-1o6xMI}#4vc#!^dUd>}v&Qq- zGqdbQg34=3?FLo=4Pi4Tp$zjdDroq_IWv6ERmj4V2fwj1GF;Np=m~Ml5Jjk`viHLNGJ(&fq&2| zwCN6#1MeO+?tq-$rP4sOB(Nv}e=1t_LvyiWJh51%J0$+IFp{1WLIh0{hENT)9)`T4 z{M;Pb2NMFquoeO1>cEhvfuQP%82mcAnlqKACaLxgsdfXpYCXx~kDNuT_DvlQ)o<+^ z9haN_X6U&n`h?JlE>Czg2~k$0HVeE5VV*LFRld*clMv9ZSm6bq`9<45ypW{{FKFSD z>dYs~5kb(&^{wjck<`jcxgek7!kt&9a{JZbC0St=^(E{FLSmf;uGA5&Rt}8d7cl z?bpQU*RjD8HpIK_z7GodVc+yt-NUVtfzvcqfcx7BRdYBh}@y@#K+XWlhg;)Bp z8>LyVLO+|!clWOY8^p|Dq0KA|4-1{)9@97y?P_ct&NN}IWxQiLf`YI|Ssvr4?atR#wREUyu6OQC3eFkr`hYoX&O+DXS}>{Ax(c72F_<@V0j`a_Hd^NTXjZKFmUCSf4e_poNwiD5hb~^NatD5w%AEbQJ z;d3ww%NiYX96OVcq6}s{#2__dBU;WT`)dKhWExLHc|9hjTy&2Ve+`o5VQqp;vnx%D z$s|3U;@o-#I8-zpbPTafs4)qJO$L*p2PV4o1A-`$oXlSk=*oe@LwdjK5L{{#k-BOz zg8?%OGTkqI80x)yVjW2+9ZVMCBhr*a)#*H57Nf_E0ghAD$EC#ah1-=KGjT19O;TRRcd~0dZl3 zrkFh=L!=DOzn-6_Wm`?;3!Bn^YRmD}Nj`u1)vvY?@MM8{vym#UBgk}c+iCFDFORN;+%oIy8iVPXb!-6fO)AtVfHP6d+|2-RyX+XHv}0rg=IHI%r?DU zhexe9CA&7I11ZEckTMKg@`Rhu3AbJZZYd>9z50!is-`b$=dy>K7gi=+an4XJ&do}^IKzhQv<(0*sWOo%DWmXGx*V|wBf#&+;ohU zDg zS!=eiTuoBfv2ggfcs=2m3V&hv?iiVH93HT`v4ZI7*iL@ad-+5+7PY|iuQ62i*j(#4 zM61g&u>EcIPEYRS+rOvXxj$KsG016qnU3~tdE3ZbRw-6ant4ZqNNAL44`1UIHS@QP zGOYe|9&MDGJdv3U?3x_bI1PfG1_z%G;-3kf%*O>BGIv|BKVRcc+z)a_kyri3cR8VE z9HGraxs0x|1g)Y29Ty_*F4}TC`b;kjM-Jv?E z?EYAG^l!WB8$V|Tj296;AF~g-z{f|qQZ0H z2DR_V9N%Xv)GTrwI!uvH#gIC(^HlPSS^e_wXVUz6(~zsbIn`_D>*mZ$@rLR6RAjF+ zk+8LNmUV>D1kKjg>nv77W_HV+o%ju#UG}#_v>f|yxej<7Di3)b`DhuwR2@Ib&nvCq zs;*gH%SBip?bpn?eXSPus6T&tf%C-7^O9Yls;<$o)@)YHr{zZ6xApeKbM;md-u_q0 zzvG{DfQ(UFPUpRBP&fK{&qGP+I+@@p)392~L+XSDc9yK_zmkC_a8nhP#-TjZkppIa@5?N+NNsc7%A7T z`8t-RO*gA3_c@Zs#D1cdyYGVE-rss;z0onALcT+M>a7q|c=I^+sMutL?;wT$_{4cx zz&7#V*K9QJy5?8T@A*a^d=6if>a{Uae4;546%osxBT`~(pLhenVL9Y22}%+O6N{l4 zk*gz=mU$Cyxp&H-ZYPzK6TH^O66yOTv6}Sa!mP_n%H`W%*S|$4)Y!Q3^CYm$fuSA;z@h;N9T60nYVH4jEqTwvf32ZEL-@h#7DkxlSHZxT0 z+9^&^;<=%${P4<{y-KqwQ#CU(rGoy0Z$HcqR^E`gov1_EHX9f0+s0QPH`==M$p(#5 zDa|qZ)Kc;(LmzII8sV*a*er7(v10$dIP zaCnvta#wb^zhd)f;2aSekv^B>cM)M7lQ`^n`cvlbzo!#&crqfBujm3qrj&U*MW)rI z?nGu@tICMVA8H4P&KcoZHO{?(-!+D3h02I6T1&mHU$m?2Y*MwXzZ3iAX3qL-#cO#C zYw7)A=d(rM^SftA-M^2;*CTk6ZU79`+Ei zvXcA7S%H!V<&|BMhyQClv@86g!4ou>ZoQ)(cQ>6kO{cn+D69QWHdqq}s~d5v8>KTp zb2{SDgda80!4c-6Z@|mPfiYjDn6MR=+1#hR;^-PS3J(PS3?AB^mdnjE#Iitf%?zC|FIELLLB z#LzPN>?TZpAFA;FzD@6*2lEx!PSaTJUvid>*Z0L+TrEsqB6RFaaVQ=$&znE+S-OPj z^skBQP(c*&{S=W^>Uc>e!b(_;Bv)^Hz8K%-+U zsmYjorJD9*uwE82xG0sH{jiV!PQq$*@uK=2#S{fCe(D7q77xlArOIh)gi<6Vdr0syb1|KH%4|p-4M~O4HpVbB&yHzBWUB^ogtgC!Tr! zfCV|uNg=-@zSXNp?Vq#^nr|OjS+|W+X!_qDnqW(<$ylIm`U2b=3I~wciZ6Jk#DhJH zIApk0bRK-%uMNfg0o-bDd8RX_8cM`ExivC+U#J{c7fIZ4m+~uVYp;+-hKoS1ZCc9P zkz@LOILv&@Mm>5@+yljqawtS;`Ky-dBtORBX*F`pSf5sxwO15^Q!AvD{Su?W$5f^x z&uYqt1vF22xbzT`)XwhsA9#eV45P*7DkVjvpI15jnQ4(Dgp}4Uk#0&9mowPA9cNHH zt@@lF-A%ru9)mfo#S5Y~EGL+=yd<|~n$FaDRrftXF1vlNBZClVbowMAv75x-ls zKHy0u(Gz$ZE%!v37Cz3>6Mhl#!QM8mG_J6+>e3iJt~(eM95F8KFssihSr??(IV;_~ zsAuWtXjZ4U>z3S(7rkK@P=Hy;cTA&EdLWv--08yi9Z!Q)Aw{fR#vsy1Rqx-z=XQ$e z+4s{~O-_HvbRf9qHh-5>R8}aJai0`(FMb%dqMhma{3|JVe92HKgDhs^?RwsaMk7d& zQ!4)B61gzDnbj$uq>apD9u4lbBNp->lkul~Qn#G+sq;=4+2pZQ_@iUQaUA10Zb=9z z)Ute`tEJP~tx;;rGSd*Q7`X-V{UP<#IW3p}Q9V^^l~{YOn6`$^7peCUt;=$X1fiXZ z#4!^+hVGhPU-ez$b-s5o{a6V!Z}S`)D|X7q(5>drSez|qC2eCCCzJP03Y@cWg`{>{ zCrKW@Fewg_E<-f@wpg8cH-<{=^{}#tH#X-$#_nc4u+x#^O!{+?w zH4XkdV(1^uF4gBb=N-GUXo-n1{tE(F_acO|(nM0-{DGycd%^KfyxTCK5uCDO?NKDGA$84ue#ZEHbS%{Shx zc4Ko5 zf}(T;1VsVa>%RZbyZg-SGdsIq-kF`*d;{SFG4soL9>?#Do`J4{qEj*K3?Kmi@!&b5 zHqo)Ts-Mvw5?>pvWcnlPvqWsLPc%jZ3|*wBOZ=zvi-k-)SvL+3SkR z&8xyv3Kl*0^mE;;heED>jJs%QAZ@5ECa-^uQEq{Doa^Hz#_u&t1Ug1CyR>{b0M zt#@31raP@BO5oI0Zd=Hj>8kl#+Kh%7mw6i&xSNrDFIV{3O+^|#_Aqbsb3I6R*}Ly? znk6EqBx9s4b6H1BNmX1`P08I%%0Npu&G~9qfW`Abx8Ir9R}$0%t%b!eNor|`DXPer z>RK9k$z9UGh1jb4T8Kz1$eHWi_6-z~RWdB{v?K?a)!nw8h`7ES@AfCNxuvC^M4GGl zD=n+8;AA2rr!J|jq3CLM$<9dL(KskLLjL+?lbTza1bgEWFM}Lc)7sm%pgJMPQp8HCgVTH<5v=0ex!|0ylQD}X=`g+UtdYjc+lR_vAOwG zK}lOJz}oqS_YJF11^nfU)&_>gmLg*EqGAdLnhrQ+bM+wWi*h=OE~XYn9^#V9*RH!? z$9tHX*=mH@YJ}UV-mwyqQIwEUmXuZzS5sH=Fq2SMSG{X>>smrscyxqUo?f<#{zF%t z6uc49Q!~oJsxQbO*HtUl(X8IrdN9OlAlRhBNB@C~^~*4~U+IyAIH&bwf=^*X=3Hgc z=;7h_rsn3aUzZ04UrbdTWk1aA?s>kt`ek@zcx~-VYxa9$NoiTaP-0RlAu4WvfBW6L zH>C8}U0q#K(eY27l$Abt@~_v`|5Xo)GXO%tsZS#I#ZWMcIE;`=UL>IT3=8!eN(WO| zWxW5xD1;s zr=RFQ5OExBu6kWz_Qde9VN3N~jZKr+htZar`Fi||WG8y{Y^)qm-|yXBEg-3 zCoSlbcZc-q>&mM&ChHvmi5Mq_)*dYJ#ad#WYHwP1Qw!-0B^?FkR!GanNEJJjjdy7 zh)$LwNW|>az`c&R;Rn1g20l|u^sVWkLr_ff4`ZCng|gyoohYswvkS~Q>7Tb^`fLOV zla4_lZOAe1Li}U`2kqj#4)k#lNt;qSh#o*t9w_wPyvc7yiIm1M04QG)Q43%;cIvw) z-owfVxlok*Ia$xp2?yih$MxOg^mtjGQxqOOilUU8z6MZ^;WU}fk4TweQz-h;+;@GP zbXZLAtWKV&u#3*|wU!I7iJvrL*X&ZL<|=j5m6(J>X$kl~Iyo_-CO|`BMy~j!fdydn z3sO4FL^w8?lYTa^00JePWkdlQsRS}79}$QXrq$ndtSDyLbpRe-%U^$L9uyKy3B~R@ zHX_8{`v650zEEUUu5T=kiUJR#xLAlA#94D@z_mzg3b-d%Q zO@l8*0glFd(G-4#W||@h0Oto`xnb=3f=+KsiypdU*H=5Sza=}BEk+t;gzWN=g%+u> zI3X%HsSnpYl{tumU`r?k5`uIofV{P7Bk^b(cl3>QTD0UFigEAV?#32c=Mt*xCh(Eu~v zS97HGz8JxSjsgdvxQ*o{HWcj$Lk)@7FGiu_J$k!Zar@J40$JSMf9^K_aww4h_YYg1 zWZTI~MdV){h$NNz@*Qf<1eOY+pQ<~)zQ^Z#^c#CmmM3|ChGKP==3%23v9y$E0xTX& zzy#^iJU(_<lJ+!mCgR=_1FWIJ&dQ zg<2yDA`+?ZoSg3#vxpy8($^orQuR^cx1f}8DjYYfA4-a!Kg>gU3C5AAju@JZqW1iB ziY@PvekOe%Sy;TxyQWJiv76?h&3SdqMn3&0o#3ubW;O{A+#695mXD5mC7h;d~U@CJW|jqP_#MyTl(9W+-UVZKO+3jvaShec17YQ{|%u%ctt z5;XLK;HemauS)ZpLDMLM*%JCzUrk@bCf0z`9|g&=*o%nZ2lpO5h}7aLyF$q~0rU@4 zLS5WBTcC4(0xbd%U*IcMh7t;nryLt4)BO!L;I(+>FQ8v3X!#2Tq2U397H|lKT`p3{ z-CB#8>WWTw0+$Mo0+*Oc*Ym}iOmzuxz-xTvCBk!BMW536MT;HmCSR}YH&x*(hQG|! z?+dtE6?t6i(UD|1(?1!0Zr0Sj&al*1prz`{;W@9>A9fXI+{{&fWvbcz80_Bs+-vpa z_xcPa#&B8?6y--C^zR1MSuOey{Nz5qD>&kcguMKq>MifUDRwLcu_1hW=bpVRl-bv* zih_^s4t3V01DdVw-TU=ns<0?a1#ya-L$pL-~07_N4BT$>gk4H+|cO4B%rAh1A ziG5*ze>9}PLUI4j*ca~OqhZ{+#*75x6<&_tBl;$dSvg}X0?NN%nx!>nR~Ua4;j6fg zYiWGcHs)HK)$|H~t|@m~)KVqw_n1c!jgRua`kai+*|=}o9lSt*-Ce4S`4JDAihk8% zls=75Xlx7gM!Z_pOz!&i4EoYA7 zg%Ok1#+>mjH|68EQ)#Wu6_>ZY?2q3qOtiMPjc?xyJ$}D*uC0Ce@{WJO@#30ETj%`v zPGHyZhuyTc=c|{$hrB=jcr?-0^K1Nj#PRVbfUcd4GTDvhI9Z}FZSTiS?8YmfEThxg z2Lw&_lI>4Evre`T$xrO1g`RxD(shjJne1m3oU90)nRbj?PwYSHI{7M<-ZAEG@+1HK z$v1_`j){8{KZ=e|R&jKlQwb&qr5vYg`lg*TITHs@l~32r(mQ7>Ob)BttmNY}llXZmNR z;O{}DY4?WpoB!_~Y^4Uu3$T-2~H<&m3n*Bc?t3 zIg=;fl+S)orS}|En4WIfpZ!^w?D^R?dAbvNcDzK_TXi&S`ggzJ>}1Wf_s{&~-=AG) zr@QIBC#$Asf8L+{J(}$O`)l&-@A26gz)FBB5a2chWDtQOmq67{pjjZCJ0hT2qZkyT zm~5h0f}&V+quAS{I2WS0kD{=w(Yy-L{5H`7LD53F(IV~9Vhhm{N6}KOF)|738+BUJeL9zO|v4-uj#tX3~N3mwCaaV%qA&`G2wzJ2@r;p1Cygat?Kq~tW8n|C%gzJfz4IG$Ej*MQT% zx`yHO^u*NExUq?~8qVN;TITNVhOM0wIGux&E;#juhDCvc?~50G-@mVScXv5lbA4J- z@&5h1tNYEg^ek{PHZ-z$G0+c=^&dXG8ykBGPWJkSSHa~WATUHpMF$*_dwRR~_O|91 z=FG3!Uw88S^y$5sxg9w7fB3LKCihxeU-R_xb-Lj-I{LDt^of>^>HPfc4Hxh2?KN-^ zzjHUZv8gFMBBti3hS^3lDUhA)!%5m#t=APvMxufjddvvuCk!iS8b^6B1KgT)n|Hsk)}t{WJ^QslZ*xqB~H= zLms=Ffs0n8cfr%d5pZ(=mlkl%0QU-T{Q&P^cnas zw-p>s@$-e0Pr>w3dbEWSQCa6 zXg7vFBwE)y=0zaNf}|UEGL-mFpIsoy?BWM~J|*8Z4r+Ah424i9`o*Br##j+|7jPr5 zn5Hma{C}phU*P6e@t>vLRr=}kQuxb6_x8+&Wv7)_(r2lXJyIi1QaJWgtWg5HjQJ4(Z)rxBtE-A0FSn z7(Ab^v*0O@jf9Hfpa|BWoJ@d9f0uABjEUaC>q?>Y3%W40KTj0BiOq6?U>@*-GkDvT zH~INC1|WQB(I*0LU$Qc%LbDR__fd`3))9w;h%)`Vga!xwsS8yucV^62dG(^^$^k$y z3{!ON%fp1P!G5kKh3TrAY@fn3sFqyuT57+E*W8CLx;}L333Abg#*#EyEZ{OI7#;5} z0SYyf(nGLQn#Du>)_G7R;eXlIh+=~mHIf4j46E|}dp!Ac%mcp)JS<4|Eb>*)s$z(E z8gH>ucwT&cqehkO%$Gnb7bMLEs5awa>_)R@RS>>~j5w4y8Viv68D7~q(7<^#pfV?4 zhq(j}qL5JDn7HQC=EEaYSZ9Y$Zt{DQ*t_7lTP%AU17$(&dW)v6j zIZ6{yw#kIE6MRbeDkS-(VeGnMq5uU8(P_~0o&TnIdq^gP?9LcKcn0Gz)7D{(Bu?u# zOMdJ0uJ?OsSc7q)BFfbFSS@b1EvxxxP}O=r-IvnPcO&!RnabR;K=Kf2<>qX z#7BR9GzrdYo!InOf(luP)6Opj*MCjHSpa=cG{T83gK`Cq#s_{&@%q zcg}Q)jCL?%gG((_-C~WQ*Y1Y^l};$Y3_=%gCPaH}$^woB-&)Obs50<000BmMrcWXS zTk=qHqX%I83iYBb7ofm{7aR&p07eMU$0ZbX&LSg5C3i_DG((F~1rMQQCB{jnF4G)- z22@;hHTWx|*@bv16i=dHltBdawE-MT6K#&vUZQh;GmO$j-sV&FJ}HTo!bf2OXzBV4FYlNO5u5=Ss)uc=HuNv|Z~}Gdf|_7AJQP8%?!BHns|J zf&e4brQirR!iGg6milON6X|`EuL3Irr7Rt5IuNG)^sPLmbvW^CQek;NGjnS}rON{v z>c&t^so>0zBQz<_z?ACD|Ag&+qV@$tvs?|%&rq6;VG1NRPi4$lQ?zryI_=6M#*(kX z)>%3UA<_Wr1vh#a@ru0{ysV9FT@w;aHi~C>R2G(b{@YTGWMb6gs)iNpAZAGVQD%~O z`6|ZRl5k#X0(eg2WtiTf2?;r@K}h46!?0-dqL%_d)&vGN;@jo$YCZwpW6eNZXEvEu z*wVgGsvoi~w}gTw!sz4}tRc@W)yJr+vT-dr@HMQ2A%LS0fEKl@(Bm&88X+cd3HP^_ zX)xq0pq&7W^%3ji5w&q1=>4>iP$N0&bhOZK05UjBjk+8n>tl7H;+N6*BSdl zUmBscl$imr3$1PFp=%F#E6zd{y3k@(QWqa^-f=tGI)9_(O5_pF!NNBlBpF?P9h+jk z9E2~)tIq>2O9pN>J9K+c$x+~MI~!m=?me;wZUeP|0vXkhcA|rN!03iD5C8?S7mB@& zcvl+DPk>O;5pgTGuo(0Tv(B~;D2P^Y;>oWNX>9CHjYb6~D{4yU`!_Ts=3woOXG-hJ155(Sn zRI?6SV3bx{5HBECLe02L zhQpWQL@9{WEK?Nad^fB4Bw0)X4af{)T@Is4^nlqS#CL!ce?Ke=^*Kp{W^3gVY@f}*jUdNrvUnhQkyl2_WA75go@F8lYdmW4LnhRQ_maEPw^Tr3NAGgM+f*S4S*~fa(!} z%PpC{um-oPqE2YY+{Q%6h72BWRiucjeIMggmNL;xeHKg$NzVQ=%haLtD7y~omUCwl z>R~jm9=CZr;dq_5c)oQmZ77rP1=ek4>g802t z&%uN_0{~djPX{*(w%m&KmsZ6R(_Qp>53AKv57W7^d=c10@NId@Qe$UArCz z(GCi1uq*&wS!aM6N%Ot}9`%{Ne`RwYM&nEVJvDFZ@RXbo-FZoZRQ|;OvvZU)_0nO3 zd??3K=-36AG>p)w7yA8I*fdI75(){yB7xltKdd7IGzfl91g=;DR6qO;2H;jW--8P4 z*9)V-hw-2;`(fe!SPnj+uov=1LN>x^p{VQo(HCr@e%|wb?ic+sAV|0!D!LH;-~geI zi-i!7szkVi83xH4D<;H&1OP`fj6cb}sswXYDmYdr&MGku;};Rt7uAdk5Ecr^zZ%1M zgmGTOxUkARd>FWt5H>m-#yB0{R1%Rr&&|3N?oXlf&Kh%DNDy~~@jKF1U=16v4tw&5 z{^eO)81r6YAS)1*8-4ZB71?O@1Mr?fhI)fCv^%BgJ*~if0W*Mw*O@Kw~(qfZ^O!C@B@@8~E1~hvtr#UOaJafs$vu`>p_N>zNLU5L_ zEk+TG@*^S=82~vVRN4#?AcdC`1O$?@5_y43z85m%Sed5Nj8`yM_qi?C)8gnKYUn;> zgQVNArO~j-_?IFqbE7?i!$Ker77}{`CEj6uw8!fIqn+(=Eg=Viby2+I&nDxi zmqU+zaP%-q1d?+c3y(}nx}O_YFp@(K%p8+BA1`cRMT9xxEc%=tGHK+o2?N1wuuwK2 zStQA`9O7c5LthC-BZ(F}`%`=;+#0Pcj$leKgRmLd%Bi~xY;#)9tO16IL;NVgvBN*jb&wKGyPlBHW%d`tV7J6QGVo-E+f) zWS}PRAw394e{{JLJ4VkJDMJE+mdu&l{8CoCc>fusoD>3s)$r4(jIXX>Ih!sy&t3{4SN!~4A)=Ji`zD-?rz#@9_*l5? zuW%k=;qj+DEP<*d`uBa_fGVh2*~N`AQzS!vNU?uo*^`ax{7P4%NJ(pOsr0)-RS^sK zUA7=BQoG`5p>rv-h}xf*#l`GZ2Z~jPH~67baDO5kNv>8)e$doWrzCxWHVP{0i?k%c z+n~@eDTq4`(H9Jf1^{;evGd~D4plwZEJPas7_lh23}`Dm0|&b|9dG@2FA)ZPw67V) zYZrhgGqI;rS0bv7(Lq-i<=&4XyVaogF3Z!bhf&@ukV0#@q~8yZMJYMcWDeHMG66?@0&jJJwK_=7Xz?XIu+i3 zc&9hj`0N`6&qS4mIO+nXkqlFiS<$x8zB=_N3X0{PMo++yWDkSzpnaVs*kDLB5}1Mn zl=Pm6N^UYhCVp2-?)4tO@6BukZ17^j?SQ$jv$Y!_Lqc#I$|BGR=_x+x3}kkHy5$n$ zZZ=99-S;S{H-e}4%&-5*UWl25FeI6;eCabU?Y|P=9|0j#rIH~kWP}e}ffo7ckACUG zXblH4*GV7Jhar9%Rdxq%j7EyzkqR(}nPXpMY5{0pA*U;Y);>zZSNddpdc_x6wNnS1 zM24OGs0mPV30!j#t4rTj*W7%WG;@m?_q^W z9{w4CDCamJHGVeD6wNa}yY=#RCV(fyPc-SZiKs3bmiJ-fA5M7Rq>g`lJ|;PXw8KGO zUW_ycgmw!j|2&`6UmpAGzhbhF(DXQ)%nh#SZdz0u>#&fFEOpenm z;nS>-rOY<(F(`IT4@O9{a+q^8LWVA%PO$RKy%uIN z?4EP@Fn8^A4*&Rd<_o^&*XK7H=tcd7Z`{OMh0}XF1}S9C$ueN$FmD3G=Yt;4hjh<- z&?~Nv3H$6{$c%}PP@OU!GxZYZ%+VK=P4H&#o6q2So2B|T`@`J37>N-+gWWsqo-d>a z7?u1r7x=Eq2;RWFZ^C?#RgR^&I1z(T#N919?W?rFP*Wi-4xDD z_?YWH@hyXUJxgup?$No0;qG$V3=YNPpxzPW{;uIh` z{0}Uy{BJD&Pp=0g;~H9*LEioG<9iTHgRC3`yI}VO#Nr@378O?nF)@g+LEa6*aS$|v zT@R2`gRK*g5kIT1H@jkgHy{}7(SQuy-q8iDu7DK}keGw@6HRTCdqLst?d>2t2B|to zr9tuza(0lpgW$WUhzJ7ovGGw5VS^QtFJC?d+zSI)GuRW6l2LPU^8rgYV5tPGy{xP( zefaQp`SV8*f?u_8l#)>e;WF4{0YN+ntRH0OfZ!f%oq&Mb%f}yt=^$|iX?RX49RDvYPUr}@QGL^l4+iOGMG%fMoTwS6F!J~Qo>;p+q~(a14d+sBT6y5V zUfT0Py6t94#)oQ}3D%Wd-YBh7$BE~`n!P+o^wOz$T{2~aXKs+$d=#pe{bubMP_HP7 zqTr&cDZeVX_ipVqM}Z!lqtfBWAIg<;6XEi{konVZ({B7n(>jq=wr0@~c}`z#@2a?E z9qPNBQ`Wjrp%G#Xx>Rl`AbkCB8O{?J^eN&!rG93>!fzCF@@Zb;b%KP6#q}_u4?F@Qk%ur6jsKhDGN@Cd~PZ0zr zFfVw(RLIx*kHanp0TW5_nor7;5hqttE zA3N;%k~jrKK?=cn#bH{@`(Bl6JSROI|ANVgVh?pMM~0+btMk145rq?l^q}XYuJX;6 z;Oz#oJ44jcHsZW79K{|+(GcI@-^0FH>s3-MQuDfls;0JCKuo+Pj0#7h7xOXSv^&=% zuwVT%??k$;+lyMPwP%MN#PQq(TaDukzL0vam%zZ(fWH`hMQ9r2C?P@6D6C$xhl)y z8F&hmjS)g08xLuZg7fPWVFDz$P$~{px0hyj#vnydU7&^nOE~60Jn}w)442pMr?bK# z6(2*O9%dS>hJ+aUN4v3RS6(5ifqdi=iP9l=gaS)~pHmL48F!S_gr*jrB8 zM4V(kIu23^fyINSyBhS`J@Lhk*NeLamdD9S?1?>r2Il3UAz>ajP7%L zj%_k_Hj80gCZaT0M>JUWGyG+~3jC1KZ5boQ%a1vUD8Dqs^h?Q>aF&l56B1h1@W=z| z7?0iEczzra(#M2@>Axi~9t@@lXJ|ZS#}R0oaRGDBp8}2R+Cqkz$xs46bnZ!qHjfBj zG=CY7{SUA#l1a19k3AnSa;9}2+EDnjtdzN-Qb*!xO|kmPEAg9&TFTY3Q9Y?V9)Sxl zVySSCDzg(sRI9Q=ikgzC$6cW?lDU-|e`#Jxr8?&Ah|0Cu=n6Osy#P*BjNnvO<;2fz zA229(%dd>P+Z|ZYBgmjN#aZiU41(GEPsOz(O_;9$`MYvCEh3V}tN=5=re%u@S6k^rQI zzG)U|lW0Xu-W?YKn*HB2g|>{N-z0Y&ty`Lmhu^yUUN_+d7eVT_LJaVR1d%2!!R7Sp z0ir#GSHOuxpYsc@eoD@zWd=@nQ*}2-kS?|z7OaJK4Ds>ylPXk z{-*|jb_u84J?hV5E_BtRS(sPy>L=5_3AR;n{^Bp+G2ddLZ{qL~6XW*$Rd;sqRS{Q0D`Kk5?WZvw5fq|We=-Z=qmp- zc~RD}E7m-ZjJQ)cUHh#N!7*W;c=!Z?UI($J9x7arTsJ(M1(r|mIYM;rLZ-07WCaeOZDx#EKVnzm`#YJgKq%?IGXBr^X> z*y%fl#ndgeuNTWTel_>3()t=Wm8~TgQ7oiKY*M>dUa4c#B*%pvCb@M33oL}zwuoEy zkCx!RR~#2x>JG-FRRR5ZBN{9zhSP=^9`@*0$MiP8tTK1x_1$JW{;6uLgA)zI!V5rz z<*};qHKoUACwF;2#Y^P&P*Y7+-l3+A#XKhIEnX(Bc7oW*>n2JPr0cl&FQtz8p#q*AS;47JP;vZcYap02)g%XN6+v!Q+wG z{iV6nBgx|5kTAlZmYl1Qcpx5PL3xax>H(%C{~YFgI&H6rfCzDw-3zI#2xu~yl1I2E(XOY2GPI5u&&HUFyFW%8*`^bBkJcoyVe>;$0MR& z&t^c7zV25D<6dmQa@dq$_*Ee__LVQ+EC|m(3M@5BSfoS?d&G5n}s|j#&ocD4ZeGlr6MbNfI5LJkw23T8U7%(m8M>PcnF7#eu$7XeYxDHG z?%{0oDbFe|1h=!eE!{Mp@zgy?>~wOEKZJUlBYko7Zp8D95Wo*%%Sc8RKp@UjDf9Az zyshCMFaV!fAd+~wLI|@Xm|VuH{xdTzXF1}d{!OSaQZNJOB@JH|Vt-$!_{!M#S zrGET%x0tWxFk@lYV82WTzwGXuZ00-hFDsqqgPh*B-*?`P8xWKn(igU}jTdf72+hd+ z+>#`s@z8BPGY^vG;~wwvGVO2Wqpuec@_2+INm)|%h_;euEQQzjBdgfQ+Q^j-9V z$%RlU3JJ1k5E(|fbe|~)x-FDedZv?x!ntdcfUy3&BFcO!_q^Pyyw@c~(A~U!q0l+^ z&>Oo5uPBr%ub>-H6tP^CXPfa@v3N^3zdcX3tt!8`FaKE*jMNbyt_cWELBmKa=l>Cv8RkC>RLXCHA z!uQLaL|j3he)5*xI=|e0vha?5r?c^;1?EHtuSX$?sXXuU+4Bv3 z@)-Q>9tUp}s9RO?oeh`Xw#&;=B+`mh@`(s)XF!X2Q1XcKNl!i~Rq=e@V~>yuh;QZC zOEo9~i6(RLvX?L@<&l*5>6f6wQ*gs65nf*axrFdV=YvgG!6k&F6!7eKO`lTjAuqc> z2|xl6Bmu%e#n6(+J|t2*AVQBP0n}2!yA7mw9|GwMg-vPqu>rC)3ec z)BPvnCtIYfFCgVx-!3Ew;b5inu2Gb2psDelORn|zZyczu9ixIwij;W!!EU^49RJhE zaF*Y|p$y?NYLYN=KOf2u^6|_3C2u?HJ{aDV*~~l+hSt&pJW`P2J^(?0`8;U$<|(5l z!zS75AF~5$IMkvNpo~i%f7?=V1!3FOlA~GwGr3-(iNsvP%`*l4OeF@DY76MXu)k_} z_@edK2K=^BgNx0xlI6C4f%T30@VG~_EX`lo+b?hcI147)&}_D%XFxNtK4R4m54zrdcTdlTQY_Fib5ntRkckY%d(k)}W0F0iNE zo4enuDnJf4?_Qhf{=^~iwyWc8?;<13LuNDbo@n2@6mru`hIqdOe{Iw~vujHFwkCMJ zYFTZ>lni*mB%GQM+0Y|W$V2m-0q#R?f7-K^!Y}W`rn1=Mz1OpsB5-Nz`6H*kcgl<* z8ZX|z>W(ZS2S;@q(F|Ns8QAT5VWQ%1SbJmmc<_oe8y!HQmH|XcK?yoTZmC1Y(#~FC zL#8LpG-fd2d^RsE#Dm;?#37;~Jse=%$Gkk`N;B*)GZZs6WVbvVcDBW^`xHQt|lH-=v)`{2Pns z2_9;~=C2|wU$9l^`)Yel%Fiz3WTQJ><9 zRP&YvZ}s4!{n=y8oBQHz2r{Qfc3=3%wZ|VfRNvtHOTz_$`c{@xD^d0N#X4!|a{-`7 z;KOCTxMJOV2R}J}iU(L=+`~&ffgPWz);qEf=2#j&qPdqD)RtXT7wwP2?k^yYz@rrR zSmNchPnd`ku0qd|80fiAi>mR=jPYLPpZE15F9$7sJzZkD_T^H<7lps$xb@K&LV|Ig zDb5+`$E*OrmjC)N`-yAXyV);&zjKv8@^~$0-?;L~c|FsF`{AzzL0?Z{#gAXF{r!r+ zCQ=wucEVL1D57-cS=usEaciR-FY>`SHsd{(+ zMC_hT?4r-_F+^^kquXVS+yk+=;_{U?PA4;EosGa>de(?jRexQB*z>4QUxA?%Y_kcR;!1(OI ztoXp>{GrA5Lq+vNtKvhu-hG?i!)s@UY@ZJC>OWnIcb%{Q^eFy$5b@LN)6ZLyJ3ePW z{ndY^asNZ!8U7*fv|u4!0X(t;fPct4h_*ra4&K$uUc&9~Z-Erv&i)2S;X(cm;`o4j zpD{JcWGm7kj1+kq!|>rgSWlbws>)MH91QI zMK?3Bz75_8gU7$t!y#I6j&{?LVBOpF*=_JlSUtoRyrl&%TW70JEsZ??;o4xc8@wt7 zi{9YT=>InSki%&>QN=`|=pO&7Hne`z1VLI)jy!?W~$KZ2WQktgw9&0y7wD{$#ja~d*E3zec3|_}myNwmxH#s-+ zJ1Ph4SNQq=5ngkdOiE01yOLjhL#0GIrr(+BkbX{s9zI>mACO54iFwx8Ng+zf+r+x< z+GyKS@J{#k8TH^-IctXZx|cRfSM)5VHFd*<*B{HV?lknXz1QvRqKfAkN*>kVtubu; zeEE;D0}>D27n!t_y*e`-EO%kN;OcGu`<+(aHf0G7x;nNO-Sp2Jv5ekaI~4iYdb=sP zn?iwSX$bY(D%;`rlW$p%P{k%RA)XF1s+p~7NkIaeZ>b;GSiCn+^SeJ(Poti!dZ_Je z-I2i5I~8X3i!HAHw(!}p#YqFhlGxw8D_DLMZ{-N#0l$zz@L3)&OU!(Wrc>+_pE-jt z8l?q$UUsj~Jn==b`lVRDkSu2}(bCe7NmAU5xvA0RY}~ z>-x6>-yz}E!ny4!Z#(&21DKTC|#3C^&`U_7v!@gnllh%!m8ji=EiT9pPQEk?>fAiwFSF&5Z zSx-hPzpQvoFS^w*B5+)sGXw&s$W=yvn0mG^ebf?LgY>tf*McH2_C=uZ1e76-Xw zt<-*}b1T2#R_FGR==av|{mS3FkJRkzJAeP&lq4M&9e*doyV!jJgkUYH97?nM48V(v z?G3~tIi;-zS=}90``GVoH5710itUfM#2fFw6!P};9~En(`8p~wEY_3>-3r|sQ&`>N z8=(7C`(qM!gW}GVHm3XSl&)Z1vyr~!_QC5#IoiWn3k+YtoQ?ZsBk+I{yuG3QA5ka! zZ^^j(I|WQTFz3Kn0#gmVEdk>VRD_^L1SKOV7D3|%2AHm)=HA{W7=B=$f#KwP*8O3$w zL2C)dB$&HkK!OK6prZt3B`6}n>l#oy{^J&tQ_{f$_kUz!PHsLZ6G4p#Iz&(@f~F7j zhM@8TLj;UWFj>Jg9eFtnD#(xDVhoJ5JZ_pt#Mp&K+4c?x&b*6w{KS1^Iz&rXqo(nu zi-+lluhAI~opydDZyhFqf^~Q*1Po~~^5rfmS=ky8;_OVX>T2t0931S-eTekDWqwIf z8MKF>W(D0V7~x=?gP8^T$A6?MXi>qO2K_1MC1++PLGKA3Aj!xng4Pl=wxI3=MJM=f z0IEz-VoJ#4fXVFr}iHIvAHla3*F6wB=T?|P7AmFGs(@% zwDr0F{HG{K=gZ*XQ*y@jfMBcQat|XD9a{&(#I$SIT`t!(-4Yd7=5B1Pn*qrdpvogaHQsReVMqB|{#o zqN{6k0?Nc~{sha6``E?>h$SqOn&?`BQvNODU*MIm8?M=y4Ro|axi|}C8 z+0*uREq?yEdqpFmJtCNjFniqzqeXH3Pr!Iytvr|S=HNgW#; z^1hY7dv=ZICU9_{F5W)7UHiAZj%G$A#pMcgBn^)OUZ3g_oZD(#)do#K7zCMl&^c9R z#G@}BWhG!Kh3FHR&ROy5uw3IWjSw@LWz>{pVftbwd+x5YjzzZ%K21i`;)#Je6%#+8 zrPN$_WsyrbGfSVjBkO@2BACzaYOBWu6XBgevxl3Widnw0Y!v2?FqsA!c@)9J)#O$mI{4YpN681fS8Cs($v2CjPx729r7-VA zm(ki%(U+d{OGbwmnf#f$ADBOzS9H$v9sN^S)hK-phU%Nwj`OJeJC98EW-(y$+Ffy@w^Uy}bUs|#oNI$+vUwP< zy4eWZtO(ro?gDc2cJ$klYb?8evY_g@=6!yQE3DT3m{9q( z1tvX8`~Xb)n+MbSHwJIa7|Vl6&w7RclivFDpq2fiUeTPxz3q#WHr}C&hR-8z{(S49 zj$BHnh+;KgSS}a;wRkrrbem`-cipDo$CA%I2hE)tmlWb`AS3Gv5pK<6~I{%%tffx2cY$*^T;IV(&{29LlJ z2vjIE1$P+`eWBSId!C@lkZl&tNdf-G7FL6ah&qoZLSRlr7*8&QPR<#K+$EqEh-j%= z9QGmwPKZ-81sHL{mK{L_&LqqeAnbdI_QA2#Q1Srafn}z0f+0xwSY8V<5|E05v+}@& zkMLNyKES9y6*Cv>m+Hzn!p*-MrDB1FvjGIADi0kFQWQ*{mB6P!j*25{ghQhsoSaY; zD?p-QSBRn#K*RWz_A?D^H5d!pqx7-`p-Dm`j62v2F&Z2Nl!uIlHxeLY08q+bF3k9V zi)sy9~Apj{Us(2M=T1o5( z$IR}3WA8oVn#|ty-zU8S54~d|h=7QIs0fxMARUYfwm}Vw3St38#U6T91Bzk?M8$$4 zHdNG5RO~@fu>+!F$2ztd&INHC_srh&`|We~+2{Y_%)6P7FPyArUH5n0*LAPeo^BN0 zoJVNb1VrQqSZ@{x13!tyw;c%vzetPE?nW&;8WUy8 z=6lk{%h)|ehmj*ThUrq+iK3}~BXZIT@+om1lF?E|qE%xqF*=z(Q!p%J_A0`VvBRtz z!A@*@FW{dRd)yF=AY28Atk(*6d6Q$xl{xHnp53SU-6)&s$z}3jl3XFsa8ZiPto(1SvKz63XqE6T%2G5OR~>BB=p{KU=lW$` z5o$DAh}|3$Zf-*mwx`d+p2HJ+hSun>*Wb7FS5x%~ldHxq7o0Hpo!AA=0(k)|`VSb; zqi4T?qCsFHa1iPr;8{&4%h<91K&M< z@(^$bjsx8F?I%I02k3$L05yn)sj&`-2eNzh>M6JnbJn=|2oMLpL;edu2afC0&kYa< zHU!53_tXG*`N~DmAFvMS2jasRHK+0p);Z zz%($RNbC>d126&!L1e%&fEYLtAhtZG1HnLfK(^|dYV|00Ma6L-A(Ca_J`f*pZ`0;{ zz#Yzuz{AGIyI@AZAXpF6+#pRLAs7$<2&e=tw!BOR+yMy@K*PZvgawjvbsqq@11kZV zKv;k{FdA^FcON&P8BXi~x=9g3K~KP|$&pe(lc$duxCaCVX#&0gVnc^}0pdV&{oDp% zcpM?MMe$=7$;W`*fO3l5i6BalW9^lNz&Fs`&VAFtm0+~GTT21OV7JU{S^b@*;I)l~ zQ#Wmm0Q!M00et{EARZ7>edQA<5>x6xOYkG86R3!$1DNsY+f?u)Fc5SJ_5>#)JO~a2 zasm~P9Y6NyRY%w3f9;>YViy?}pF;IbBU{=3^1>!Qr>1aQrqHjpnK5Jg-!5#5tR6+X zNjMfni{$aC8-KpA$zWo9h+!BzczBzJ&kQ1n4CcvuR+(^P=DLU+J#YPaVUzfcW{ssZ zS2KPlr;KF#I6q2QNol3zkK8XhW7K7ey;4@0w3~1dj=yy5(DR$6lP;{eOS=p`S@HSZ z-UHU-VsrGX2@0DX5v?-(^7YfZ=MSz-h>Bfq-X>2U(q|y0t{1mpIJuY-Cs5LU8)DOx zq&G4mOcK&2C&yW&50j>FlaHvn6ZQDJ>KKtCy1qbBne2GR=3$mg)fw*@t74dh)>%Sv z-YaelO*x6lMHryJNwBWR9YUHR>0(2OxCHV8)B1crVAn4*UsGe~X=>#t7Y9=Wg=;$x z*v?FP=h?AS#AXmKg!7*wHhVxduMH%)%}HVwxP8@oP>)l$O&eDhN@_2RIGlfB?EJ^#L?HS84 zW@S;=sN0@fSMa%(OQMRP^n3S}?swKTGGs8=dYWYwCr+MHRz~yar|E2c)2a&>FI~Q( za+Y>oVp4ar;nwXtxzgf|cbl3YwmgzCTOU7r{^I2;SK)uTtFaGJX|Rp)aXfyV+EI)p zgX`}sD>*nzUF^~4QP*R2nZzc?7ly5i;)IF!Mz4?R>7 zvu0!X>rWXF0&MdC!5t300Fgj+)XgRJK35Zo8b=^f|4bxMuKyeR{KqE$pT&{C?{n;M zNaR0n^8b2=|I_yVJBa*!hyS1uuqpQW5B~UnzRCah;p3loIP12YV9=8ih`*Q*Yu4ud zX+CTPWU9@FZ8QVsenH8>Lx+!anh%}3u<8_zOF2uaKCj+|byu&|U(Y;Ud+tVu`S73- zyReDI>0-t*Y{4#k-S+0~yQ>y_Q+>kx{kPwKZzpKn@cA#uB$Cbi<1WkYlX;F}c~aW< zyDSf+o6u!#KI*$H{SrhJ5uL>e?!3z~aH$48jcm(5cd7F(OB230h3eUPm*vxKqCdC0 z6h(X}ig+@944gz_<_51=753msBKAE#WNhEKC8Gf9z5$-7BY{JQpu1`B&<_UF|#tHaUn9@GAw3pkgQ=9WI;J*>1SR3`U*$155j3Itg#%#Ht8)68bGrIJcz#7{LXE`Z6pEUzgT z@n=no(>HO<~0jFeq@Aw9P{FwOg`}A|ikBMU(pcTKT8ig+3 zSX_Q;PX3O_oVAnitKyf;%9d4B#}@6HhWZEmfh^*5j{StM9tY@W?>Yz{!bG>N98F7m4J~t_@Uq2T-_e`G;@(Qv4`dI8~u|{U5*agsx`3 zj#SMwwU4TnvH(*HUk;VM@rRV{Vsw|7*zrsLkg_~W2U~li6W@K*L&n_bV*96vg3`S|n| z6Tl@@1W1w7%D@^;sn+F{Rh_c5 zSw~=QVMs7)JFCx)n*lZyP19~PR)boW5-WTNE|sU2rS}0^9EzTi!LtvY)n~x=7vxIws^fktgd5xITmZpr!VOF_C+Q?^~ey-sy|^?GReyd6Q-CKr0N zefiqK3K=cg32)<*FgavIe82a4gPs&od^$s~Fj}D~kh8S4)%RYPddIf9rVST(^7ME* zdFp$w6WK2cC4yusXJhBZ*Rg&-H7oyE-S0K$$LeBTvBR*aSV*ii))-5RWkw;#x?(x8 zs95R0Y>0pOSH=l}U`4nulTBOq59g>a2HNp5GWtK%9L+9z$&vYE|ExKmZkXgxdGe#? z%%=BU^yfKhSya^WHQ(bStLS;_3)KWy;+_?}bg#O!$CWNRswOyVrse5g943pZ$<(S= zb?l*Bjb4$%hu^&3NpN%M8O@!t=lD~>nTh@2MC1JdRrsv&L#eAPeiQse@P%<7?3D#L8G(2}*8nM05;(AssE#h`(`1xrR3y|5{PG|zNFDlvXab^9i;o!RWV9OL z(xUT-4li~c_8t}mtAlk>FACN|y(s^!<-kfYkBF3FCB;a6g8i=x&bZB?ZWao8AWpD< zs@GC3lS1htv`YM0z5FR%P1t$gtNpg^+Yta}?C3nf0;+O32K+ZgsMA%WyqoOB#*n_NbGc59<5!-hKLv{jgNrSxNZ#Kd}FUnEtFJ z>Q+1S0zb>oy>)bjP=3*2|GB-6(t!@Ux{RZG|J-N)(P78Ok6&KhXGeP-i-lhv8l)CM zEEARk-++3*VEM2p_zbXKShycs25X94gJo5h7cA>vb_(;1NZB2CEM;_d6aMS9xHKry z>!rGz@W)!vDDs~}R3QunLR9MFzrli~r6iY z`NwmpolC>|d1<~23qIYSdx-dXu~Sf@@zbG!h{l4tV+binGZ8xl+XSogm+m3z0lJ6i zKVY+9$EklqMl~8Vtg?UIpke>5LE~t*E?)LigJ#d=BJs}+8YbiC1`XSYl|}o}pdqXOMt-{royrlA3o$Fq zvf_r;&Y$!<&wdZ>bht;Bf7}d!{s~TQu7gL0#cUlLu?FtK(9a8zB!Qa(hX(l*9AIF* z;67P|5D_7SCxH|PnwWTr0{#j-16T#PPXMu*ckf=Jsfvqhqh`!OAJf-w1iG$pO3-Sw zvG0S6acvy?VLBdD{BUSGdWG|XkTk^own&D+ae+UCAP|P`F zQi?D<(2BvFJ{pm*j{3Sv;IDWFPVXBh#f7=>RGhARA{_jP}EwvhC9!ZAzF!L(W8s4@~lVFx#tkTL0AGfah}u z7ms((8SQa&vUlAKI9O_bNPY1xZX`fn2zTZJp>Rbn?iz+c0{{32Ni#|X`$+%@aa zk;JXRxSSW3NlI!aTod$;kdMOsxwz#3cLKmW!SN9G$-4EMa1k)>4M4;aRu=9?z@-7b zdJn->1_;ay4-R#3_D~0e9Gt|slNY8DA~*2ca9P1$cKZMSum9#R@K^W9F^tYyW3)6{ zR9Bgr@~@x!IOj2i&URInQWAM0jaz1ad+uX0yU=s%rh)GC1{2w?pP&11(j4tBPs-7c z)S5W1LDXYZg3kH7(ucym4}Q2u%crwK>k^2)jYqkr4azrFl2P%4WUFPXlg>6>$@j># z2t0N$GI{#CSTQ+8Ia#UDeWrZqEoJtly}Rgo>G+Y?50r_#slJobIF9VYdzSpxuWwZe zbw4{!(57OV4KUMqaQVdXUtc%=wy<3+U{)IGUg+{JxOQ$221U$F5j~WM65Bf6qf_lZ zmTW=WX`Sg#Pu9*MLY*r`FB!6ABFN|&s?aVte37qG=#W4T}{id)1=1}rfd<5P3x8;*61T@ z^jN8mXRfKgKTB(4ewA1ty7lNkk7qvK`DF9rkLq}4t2&;U)@*yuGQID!)~$*alSLG| zXGc79irclK+-c9A?#NGBuf0PfFo&uw<+l)BX#?rLySt~g+dbcN@VxIciJgq}7Mj9z zr&8?&q>jnmek7~kja@IwE>2vqTN1^8YsWM8B=(es$VeY?ZQqW3=G$MVOM12nrB?jW z#2&hCZC$F^(#rHz#rqp~?v%3z3PfDmQ8ByJ;3DDEjhQakcLJfEXxS%|*aTt-KbEGU zJgg+lShwDstwLxgX0(Rk`)FNSb_}c3Ay_FdWlVNDd$uFAGfb$fCoZK$O3xl5Y81)@ z`UlmSiyfgIzdpLFi7r%%kl+qzmsj$Mm$^>qytbn5DGx_6BPw@ z1=R&kKEx5_0g(aqh3Kd>r~#-nP+>?Ost)cGtDijasFGLw003;Zd2`5EpH`KPHX%IRIDv#=d6acJ#bjeYZ zp!G|W#zOj$AV;VHt$!R+fo|o;jv};*JJ*40(02q(aa09f;Oq$g0GEIlQL#`|V6!99 zfEX*<<;W?tyi7q|K|w{J0B$_$4Jr*F24MtrQjtX1b6^I@9#sLw4@m^13=mhf>D3Qa z7PT4m1~nC_QydRa;Shq@TojSMay;(SK|w;PLu_IEq(GEd)J3o?>M=TdNH-vkiNga* z6mH2u4Mw#FgQ6fItBM+oQjH^ZO6IshqCwy)P$tgJ?t=z`M0+{)M?po&M8!qu0Eg*Q z%99i!P{2(PYdN$2VWCPGT@3vTUSVy(x@aFP@$mChHNh$M0W06qRFO zQW`L}G?~TZuA99&r`|Jo8*OkxOYz(u@|d8Lv65@un-w8+w!HuOzdjVz?fgV}$~ubG z=$<=sOGhQFKPjh?-Ir^p_Nv`D{P>ZwM;AICin@68z>_Qe{OxldwrFoBw2eK}l-=Y} zge_r4ZL7W@y1r+^tTg#l7_qwvKZM}#z5Gi=w4;qQJ?b)#m zw(UV7P4kw1UzN!s7em7QQqhqcq9Q_ahFla;@Zd+Ve_O!RPfsS8>~n3oO|jEV66sUL zAL2#7%uX9iEQyR35R=OmJdT>gm($lJ*w$>5taH(>77cpgs9?<@RJo!(r0Bfyu!=H2 zGl>p8U3Y|+-P5AgBT+fLVkT`{Ha)^vxyf9pq-D^IM2~k&DO>kA{&K;>My7XgdsC$; z%}V@4#)$V*F*goyQgLZEVTt-9!-XDRrbi`8hwyL1stmJc7i|`Kq~&B8oRaPOp6vfr zw?A@hc-*et1Y0VaX1!zf0>S#F`^P?x@A^$JM6iw@U0pJ7p0BiLA3YYKM{9Aatkh*E zycikbsADe3bn#QTtgjWzof@a8p% zKFzcKan#eo?amk8oir2ChOUloZYbtd(l6Sy+LIO|2(e_Z^_F%Oo#;j%Zzh~9Q-vDN znYsF)XsjxROI#FrsJhUzJXE}(t#1>0P{R__Ma7 zj-+2sWY#sFVmfV$pQ*66Iow%9 zlqv};a&%B%1&7ael+!sPyYY^?ma?E_Mi=v${c0;U7q%q|_yuflpDLa8ZAmr(1>8}! zRR+h}k{z=O_)~qVO>VcPxLz#KJjJLq|I(H!;!j-K&b6uOinyoG9-j89+8S%OH|hPx z6iNo==_W@8Ft-#6SSC)a^7ky zx(k_L;T?8n(3dwW--;j7#LhNd5AU~*9L}LhwA0+~@2APLimbXv8sB^`G1yMtVZKsq zByAe|%p_?-xuZhweU{cC?KE4hc)vRlsqXiUYpvaP%J02@+)taW>1}o{n-mQfrbT<$ zzK^E*nY_!ZZSf@(V!mehY$4S#fn`&dDEZXHq{u03>o7_`ewDx9Q%NE{C*Lydn%KE8 zdpUM)SBV)`}`hGHO{W`%rrK^ z9MZ61169HBE#Iz9D<%5xZZu)?WdReo*N8K8`JmryrDU#+Sm#{MA~!lOM^@GQg`-{k zfJzBl9hy{^v3zI^Rf;%60E{X9>bxA>E@anWkMDcs|k8^ z>uwosLs{;j0})J0iDY8Rfi>;7_Y3T$N{NdjF-nKdbSd8xow}&zmuSMkdk$NVTgvI% zzluSzIb&LOfF^9cF^{4&kBVUtRq5IoOW!Nn>`oruSw!cLuIl(Y9jMsoQd@rPSBiGh zNWpMPGihVK=nPMFlEG#w8`ExOpiJU7ae zIXpu<;26iHAwd${rV)jQq8?Pu6Th9T9UmvqUS$x^h>%`+FokmO)8+Zw>H|sH^{=Km z4Sk4jig+hIPwoQMkt)OAt(NLq(fSIm>(lR3yVU148C`K*Wj07LVDY2?=Livxu1WC9 z-&0R{)R&(hb<%jngN0ldLQHeM<(xV${9|j`sj;G@$_4u+71Zpgy#H0cq&@ zo~v5~z(XS#E+KdfP=sDEn!M=zq7jUCFq*<>0i(%d725f6;#gaH6I71LMK)AbG$uxLpnNKzB9I1K`z24>AY01H#dm0L+8i0rsF}khz=t z5YRio9ywfG=?E-ONzDMd1J@DV1=WM|LH?k6usUEHC=MJ2LWBHq3cy(a{12W7rh?&t z{cF~)2WjI70P;s`3BV812Fil=)stFaY#agBt>4(;lRkR{=EwU>7wQ**`~m!cd}MXO z=iqk0JiI(`HJBW<53=2}rvxKO0Cku`z;d{&Kw@BaUsrc@tN`A?avW6v@IY}Gg_9$P z0{-DF0g}PwI2r&@5n~#1HWFYDeokFJ9v}?}N5T$_jfNLc99>9ospN1t3@Z>g02NFN zpat#%dOHTddrP`tN`E53cTP_NqfGiBtK^eHP#cxFtS7=l_^MtElZ`2cGV72)gVt+)A+Np^m5 z3dJqjW`IIl&RmQKSOboBaP`+I;~RYDR5LgNt=Q6|2cLF4z&ietiPh$0rgMO+&9Or- z@08DZe&4(|eb#bQ2glz7E6O|ayfmX5Zu)|F8sQq079Sr^a2U4gj?6gUBkfkDiV7cU zD=#DFQ){$@PU{ow`ex@K?)Q$&Hd@%K52{q3HcpX9tjB(z#@aCb>Vrhm%cfxI7TNII z3pJNq&E|g4=+~4gNU>>7vsx3;oNlwdxH-fAaBFj>I?sC};^A_2N9OMnv){RTc4~oW zgjdJFY?;yMp9W@EYj|}G%syScj_TAz%9xe5qs0NGJ0EX~dwf)<*RBOkshj1@FWZC! zc|LnVg7vP}LNDX<=*W1TH!RHQ;ObvOZjsyAF&XH{46>6I7p+;ibB9T!UA?S$JqBh= z&qQ`~WNu9Bn3&!5d~e0aXB`u>JzkX77({hU%f@5ChFDE*6q77F?;y=tK+NYQeRiRf7NZ)iBFGrzdreGJX=}*8`Hi` z@?CwI_yloNZbw(6#~)n{$St-kq!-~KxI7R}NCGA(;Ot-*VyD8;fyIM?3b^_(fG|V> zTL%IFeMMLUuF#yg5a=$XT0KyKO%Dx*zWxwbh&uEY4H76lR8~D@@#14Tv=$o|a;p|v zm_a{;777jBh1^1h(MN&kLS-Sh2rocr)hY`$g$zSw(fokW{!m%;EugOuROqoFX0!0{d3vEU-19cS=4pB#c0s@bg4;m-ve;`f;{f4eX z^8c=U|0n#Hzo_qMsYb{1*VOzh3Sp z>}PRIMp!i8)$BnwapYJV+YWD4*Ig+V<6HbR1+MbIk<3$zQe1N}jr0yzQ(p*bDljpQ_F5o8L$2vh`GLa#uS zXrn^eAaVaE=+FP#e}}*5TW405O7rnl$SLZqZ0-K7XIBc;F{g8@Y)1UqwGFp*BIugb zDc>K+>`XZwEUw$?v&w=`h^WbIYMx!k1DV%%|1qS$!rVI4i2Se{4`g23HSWUUk};f_ zAtnM+KK<_TxOd<6O+zRvtk-nD&qp26-CQ7ls` zDZKoFpv#VFu}o7kFR+ndHgwSCr41jtZtFwQTjNKDyjD+(EtXw6pR&P!OVEj9c%ZUu z!gs%~I&+VDTCDYdMBfTS#%KMY%f3n8UZ)OqOpE;+bor0hv9zB~!*wiE^nXf_r9i-p z|I7!%DgdLQk|R=yqYe-ZCt>wW$&VotXq$R)1e*r4Bgjty*>FO`!5EoN-~;v_@-o6HZj&SB@7RArk|CSid1i&1*@tf{e0>2#XO2OP2-9> zAGoAWho*J6W1{Erlha)ZzCNe5Gh|-Sg(jpK>8fW5o|?&J0`;*h_~-1V8lL?+;Th!s zzdP0jO9C-OCqvE8@R3jyklM$ZA&Z&O`VCosG!LMA$(iFIRtPvD`;52W)+I{wOX@Pm>NDi-B_mlMM@uLVzd*%sK=;ku9lfSc(Y*1YJr>_9CPK z2**I$*sM)E_D+YA10#XQfN;DCJ!R@loDndh0D?u)K_nC(7QP#NXNb>_n;5WpO92WQ zo{`3tTF!$5=5@Y~fzJ!Y3or?L&AwNEoG);{7feEUbkT=vQ=5MU$|7HkXDQIIxp;jM zBpn7I(%&7Uw$C4p8RuVpAr6O;i0$Q_`Mt@gfH;Ey_))^(!NN;K%|(rapN1nzKcA4v zg$MAVgL08Q_nI7w5HxuI#{Ffm4N*)%<4Eja14zct0HdPZphTjc;%R3fH|)gyN1~V3 zwS=wT4SXFJ77%x)p;v!Tuzf|vaTL&=E+SaINy+IrYoK6(E8K^M!Wcwb0ymjqE25}j z8YCn!r+>g0Y_^13FR}N+H28GSrb)q5^qZnAL*Ue^2tRq6glp_hi2hWfD(x_7fuaP(`Vy-YaD7Otl922W3g}4 zf_YW-qOp;{7#wzhD9GEOD38flKeMblAbM%?gLeal%jDNv;iJM$1v$(ujedh;>%O-kVh;my#vd`>5|3`ChxIn?hp#bNF|E##M zG>oK`o*Bk}%-j4I#bu-I2$7zhzT@b^a|d?(brhLgvqFbj;PfAg%cz_s;Y-Z@5967M z&f>CWass)?n%!S@c<;UM#pQLS8O`kI#J77xG){dlE)UQ0c51{4N(rj9;txx(clC5K zLNt`8>TF#c`!LaUBE=~0-I+gH7r|8tG-jT(KzY2gb4cHC6uC6{?2@V4}aMk6*KQr4bg|rsXXI7(ki>!*TZCWOV0d0N3&Nryp*$a z>5jonPC!z0on++1G34^T&1|`=;p`%%!2tfj(>5Bmj>%N6wwP<%!?nIzckxD*$It;q zP13wEk4M+7)#TQD5+Z?T0COf?gFmdf!&{&KxkF9jocKsW^UD zMnO?4+3j$7dyOwINB@}Apr2kajX6s1eLPDmL|79r@BKuEcwt3bwhpbqZTSAP1~q#Q zOc%SW_MUJ{it={%sY{_(*awRkC8HDMdb|_59$glOZda8*+U&2|b4asDZhAesMoi3R zACwTwT#9@N4;!m9+|af2Qgdrz97MrD-4G48$9*MidR&KFB;2}fIx(AcnQ zU6-1INI%PqgxGs?%P^_UW`6x8(RNp5#<2H&j}N2JY?^zNYI59Hg<1zj>0D*n&M>@| z%ea@LV-z5ubnO?KFQuhWRA)4LS<_F8G>UaTibK16{BUcayFXj_CGMC}Wmt&9~IyK9E2w|Br z-HeVfXIH)z)i|O-cJb^P1tp%+R}mKPDby9#J)-9R&NfbXOA@DbHfe~SM&u7tyddgl zR=)L|PElG~QKcGI%km2to6fS{9?z$Lrh19**j!s-a#!F)c56w>Ioq51GRMFBrj{K4 z40l&@sCauzSr)CObV9@V`6u6VYRHf7bn!gl$}!O%8czgi&gEiFn8128rimws7j|I7$6400w_BEF-%a5PJF7l@C6zgz97+U32=0?E^Nqccq z#vr9YTS_H(_bD{3&?Krwo6_7tp2*HxF6ibXDp(j@#Zt%xhen^)+B%FA?=Ia(R45Rk4}UV?ljL2>O*4&_?0(@3@@Q^836CL>Z@*e=_AFU7|? zM(2GRA@&lwCP&LPNBC4~I?J<;FAwI6a%=R8DA2HDc4dQur=@$V?wM4Cz-EuQ`HfG|QAGni%Y7 z^QnT6Z6-d(1_c_di-`wlzAq-4_8^DZQ#nxrAB*Y3wEWubx9ZZ2Q+poXpEk)=aFD1? zq}kum8}MGBZ8g2pY`0Z{`&O+p%pipAjGUvCDYn$j(}-ho8tbh$v*j0 zl`&I3d)@Q9l9%O22Q3n_`pQ_sT2ZzJn`&m#l;}z1llHP8{&>IhLc`CsRNuEb8#XrU zANh1zVqKQ4&ygGPiul)0%$#>_d$_f`aXSJP4&r?KM{6hIfy&6!5#!r5iPcSPU+Ejo z)-08+2w-FGQMm{1=^9tinP4uy~$_sQc_k=e6`mQN`h=>_cp}ZFU zwNEtGa4A3jy^?-2u8P~}bZmUPTf-IuA7A}4nlCTuDtm!{=woM6|3Jg(+Vn^X88%|W z{e0$1-msykiFCq-FuEp{TTM|M^PNm3B9*JD0%dY>kUkNu@AHc7%=Qgemf5nEdW0gu z*hXJt>o3ogJPUc^@k6^P?P*kV^lU%nE%u2#xm>)yhARHB-q7iExDG4@0 zik+j6&}aZ@)^_vCuKaJJd?%uLwRvvjgT+s@wB$9taQ}A2;%kDTiYq;w-e)}@K!mRR zD5<+Yb%pYP$WgG#{?u&2UX@%V%1>>p(%sP{qU7Cx0d47Ps7T=#${m_$%Y6 z@-{=~Ta#fIVwQAq`!a1&k(H84)a4~w|qLJeM}N1&73Cb4$Q z?;lf_@wHh?W#l=MHz}2Taxh4ypl)XpYZZK|6MF-b@KRV$Pz=2=GRptabmDqHnl_8o zowSY?vUQ1ALMu@^T8B;O<#oS!BmO9pm@43$u_i@QR+BZ^)s^h#Lq1SY_-~edn7@oo zF-i~{ja#+QF}FXjiTz>9h`2V_+1vULJj57F5(69QHUdpbBb8b?r->jCK$$Jj_H2xv zp%Y`)-I?yhq$nt}1uO@WSm_u)RlueY?C9oX8JieN5|dg-k}Sf`kf6x8za%qle@%&L zcTJremwL%yRM;qTd?S(SsJXs8cE}D9V;J*|RBMx5bMvFvw9^`F@!Ya*mV|(-DdG{) z=|iWoWxs0E9SOdG)FT((9!1W0(&LC|JdIrNkTI1e8}Htg)GlRl3V6ld4%o8HPML>lb&wjskr#)OPx zC1ak5HtHiM`iNFdp0Xdx^F)19+Au;pP*DmxWMbR97d~U$g)oh{hfJkHU@SLv^W^RW_H!`_TG9$Rw zc2r*SFE;FW*Fl7$yR6u8gg`qfKZPLK%NtTGEn~bV_nY@{{nU}E#@E;X{x+EqrET{} zk3HmWRlbIv9W%Fa!!lyyK$6%YA3aS`4lZvid^^`C#+{y`xzKNimVJDx_4Jh$?l=q7LIkdlp(}6k16O zZl)EOm?$*x=i8Uy6Jyy6#K#|%}w8v&wjUp>X z(abTp*;F*lZrhlV+vo+<{>Qfd;zkTL*{1z$YtN_i!fD%`BDeX=w~ZYuJ0{pcrQkVr zhO;B-6m5h@C}{D-5*A@jEa8PQ$@OFce%Dj ztuZrNdyJWILzg%yqHXu1J(ZHAly#LL*0_=DrsX+*n!e13^ptBb_V3)baMw;Zaw4In zvA>vFSIicg(85e;!tHM7w;pRs;!$Wt>k2=otdH8cK1jeeAPGAfv1NEvd)M^9>oyDH zq}LQ12Heb}4&zet^X#tDgj0#BqFscdBt}3mOF0y2)I%9v+TD~Nrvvv9iu$V_SGlc!^h_tV(< z_O^$&97|BN+h$3dG|rW0KK_ukuwBZ#sne5MM{OQO_ERl#SMdgkwi@p8>^C;s%yPkc z7U8N|POan4B3xdyuCS6a!wBk%mfpin6}El{`%WWENoM$}gHz`n8sks=a%Y8YMwuOt zI;i?^^-X(m=Anp(+o?jznl|d9^JXVRM;LX)JbyCm!jYv>OTriRbhxvfU6)CZKeEuD z9GuVfZ)DS)D1uU&Q?%9ZbB$IUKQjNzlrIac`WGG0bR+C|*qFz>lZt49V?2sxqAy7* z2j+W`T5<6gooKcyT8?rKq0lt(p(_OBOxv}m+8Fdmm=5b zD`gRafdfg~5d>#ko6|>A%|KEa(~UY##ZZu(m=COPRg?{l)N|2M`=XiI(vgXgr#|t5 zul80lHg1@6ok8hAUL=Xee1;2dscKfvCMtCTNd27sj3!P2Id*lU9pSj2maQ@L*SRkp z$;0{lk?C~JMX{#OHS4?J%;8j%RL=8-&@6% z@8B^^WJhfnVWb12FCjm&?Sv?xcYog_a*AhHin)R|KI&lqB3iQhRR2sGTanpIK}bt! z9x2CGDGCGHcT?O;X}WEPQ$uO#1GXA`IrQ7yA$U7^(cQC|cWYM$;2F4ctN29l^wXp5 z$!&{I4|+(6mfDOFcn05g30AQ#HmoeMC-;5Z#t38O?KwxSJij-uZs)q%-p&e)YvV#ONAAiZU0X7Gu- zFD^B1B)17T2k%6>$C0xBq?QkRZJYBtIVYCNbdWM9i?}8cw3s&M->lcp7I6oVGtacK z+O0IB3mJ{ota0S*FBh-;es=&%gWv@2W)9PkH|DbEOSR1FlDd&Kf;qgp%S78H`WvEo z@sU&Q!xmNx$%@5CPF^$(t|iMvjJ_e1F*@r9bUU^CX~Io;+Ds*@;#w5NQKO;F=^`HV zVDOJ}h^vAm!ZE=^z9DTiYl4baB;Zh;Xj7H$iHdrnwB9P>4?QMe#si#+$XycuiV3MXI4?Lena2yG?oXBDlgH&A6J@W}>`BNI%C!%RR zrDs+(vXkXRiruy6e8RAla1+q_2|VlDG*39PoCM1kY%HJ-;~6Q)E_P(#9j-Gjo1b!) z$}T0Gq`Zs(!YCixj~8uqzh%b#)uCG#UcAf}&@L`#-Q0AK8GrxTrTb%=?>{Q3-LdKR z?h{_Ly|?#_WBSSoo{CbUTvET9=-y4rrT>7x&LE+>k&CQt&o5({;?idG= z+KsnMd)}crH8F&gU|A2pXd2CUK}Jn8y-9T#SY5BlGr0d>?dYj2} z#74T9x%n{pt39d3#*;hjP#HbZmbzBT@{(>?SWSx|*j_T41)Eq;@G0LS2RbrxuRC~tsgCq*hvT;1L~kg|+r^yr+&QTHEDZ?~PPca0o!@}bkf zYixZDHeN9~LNQ%R`!vvER5X2W{xgVdA@r9gqeYpm*0aW3$ zkqe%=4&bFi`)SUNmZt+I-#x*qUwW63PrY@yXnFO#7q3Xn1dWngHV3_8 zRq|esH-0moG^f5i^X_%sUP(7mPh+tLV_&!Tny>n;Yh(9$qZdu-qo8e+(>@fg?G0rPNl&yReM!?_grAc39Z>A!CcieSlO?gkn0k%x7C!jAx&3o~moJ5b zzZ6aQvi%B~zx2zlQ(yKxFnD(7OKF#{Wmoj~4gPv~+1K(3dWW`wrpwtqGcf{)cTkYmxqv8$s#grNkOB( zz~xLFA#Z)claCJa8}hAeXY-IWA}D!LuvN&}c!rilVA-9pbq-$`n`EpjlIuB7Hdr-D zS6MZIMlZeO_;|-44<{Y$cWY0YqpYn0x z$Cvj`rFNO{`{FMjrml5bH0$2L0;(YUnN5K?VN`v@Rr)5AY|&%Ok{(~C$;B)dN5(Z( zh#%|pBtBiSepS(%TTv(6pOMwP^pz#UFoRZ87;`N!>uy zy)EuXY0a{2Z8*V1`mp2{17Ey4zCNq4)Gy7;^qF3?x`<$7MN zl(6RFU}d3A=^EojkzF52i92LzIo(KFY;JGVO&(}puHV&}+NePY?97{U-2?Y93j@jp zheGFE8Padu+?$7d^_DF*^^=dF@3f>@dTG~kMCFc!A~)Kl5MPf)FT=RL(mbK2&y$j0 z@2?o1wl$Lo;P`DK98S9G=Iy<-CX=w@5E?wUw;nls=f(u%d84KroxFBJ%7VUe)qa!1 z^E{2VjoB_R5;o*bdo?X>^JKefDlc|L|Hy4?ryPsiF=_qh$erywwjZ0ed*Ak6)Ary2 z;i!G5n5MQR)z-(SALx7&_~w-3Gmbn+ai4kg$@b%~3>M`#%slbyqW< z5nX+R8QNBDIJF|?Y+c~SVvEgD`MRs8gjIHx#^_X4YnMPyCtg@NJ zE4w+vNoV)M_|U7f&JLV^FB^Beb^X0D)Fe7C&YY;Wy|q(MF1Wjh#a%T^@JyW3 ztNd$1YGj5YQuod#*5Ji&zNXyYE~HBJ3SAdhS}c!Nq}b%VKD*=8(y!MXCT#Z~+S;n+ zQ@-27Fio~WQ_ad8z7J7tYgemC3abCObe3~ z@Tns5oXuu~@-{Lrjbb543gb^UveT|g;+-8XGE5s*VNp}*-J3p=JWJS$FvH-Y!BB*C2WJizAi^uK4`EEgzl4bhyAh5Td_lN?F!u1I0jx*N zq9erue-1GbBnJLrp-rDL2N@l^p002Zz5OLf z^S~&Db6HYSg52KOvu8RY)60@zE+UZwvke!c!K%jKB+NM^6mj)3QaG?AVG_d;M7##$ zftYrLISL;XDI8~)j+?FF7h)Rm$dMy(M&Z0-ZV?F^jQ3-(5%wNTe%yEhFBvW@LV;7G zq%eAsFNA}*=fF&F-{F(OqY(5#)EpD|2<5=~Ma~8hDBO_@^A$6g@Tw85zjgPBCLbZ0sQ7^GlvBP z4awUa-jN}{z8Ll`QiI5M!hUvj8-O6-V4rYU;4n22%E8?PFcA?qL|z9YlL+gmqdbV_ zAn1cA4_rodq8qtJq#lsO!u4Xv{lHj_+;u$t@t4q*`3q|Az{+*;kOs#qdi5XTJjh>O z-|9VOF04>#Tq<15goYPzMgwNc|5LY8*LUM5-oLsy`BgIjr15k&bk`{SWM+{(ixzpM&m)!V9Gl>FgV?t73J!*czq_iPyOj+GqJBhS{w=psw!k8*o=Wuhxjw?=*4(NQLqf!Hc}f0buBluI zM_P8W?Q$8((^yb0wGhbjGd%pmrTIDoXM|~|asoZ;>Lf>bZK_i6JoMk7ya4Q9_#txmLVhUJXZy}KJ~Qp zbahMeWfI}>Hx#48Y&Wdx+4Om1cYf}<9Ugn%_g8J9-{R;P`?EbcYuA6?NzRfkAH^rG zI@S}!I(ChZCbuLelFJy!C9DfI>#aTQ?P^kri*)Lh0-961jnpBO*|pi{y-iW0__fvK zR#BC`XMs4^A-qVGd-bZSluhCsDO5Bw(1z|(AQTU?+t2%2k5tsPp{zj_faJ4oR3mCcN0!m?d#{5JQ^m(Eg7=FIdG&A33Ju@0#3n`Akz&hbMQxL4Y?n1l zcJgC=#3p3yX_e-t43*OyM~c$aRquW8i{y|uDku6*g=&z-BTMO^&kdI3AXemwLk;w> zK=PIbgLAdCFuH|f`!s?6$h%q;?zfJ!{CRdI{d)U2#eM#vC5lG+n@h9qCu_x)ix>04 zH%q%e#}c(e~lJFuN^-T%3hL_jEZnNx`%dYuj-yH0NH z7B4U?7h+hiYj??hVb_3KeOAtp;yx`FZKXcvDyHO4n!%WLhdab)>6-yIfz``-ySIw= z|0r(5p%&HhW6?$#+>k*qRi4##N!{qd^4w z`)Fx2C-_qZ^8!4RPZOoSDUF&MTDIL@I7ob3AYNf(tQM`Vt?Bv9Czhq1G^F^G!XATi zr(!vo!ABLLk50#rEVycUYMXZCuvNmFdbKVbo#JUG^!2JN-+n7~vX*~~v3io^vvQCm z-E(q{$JQkFo4Y&7xSTpc&0-&+MNa!=Z;i&@1?O&w&U`i>WRbMi-b9zJPxVijUM+CD z-5{!}m&V(NalY!+I$d`pJ?M=Btr=;pH_mxx=p=2{vb`k@o<{cNcAMSfmbJH_(kH7{ zugB`=enEZ8Mr@6qEyym{_cRLe7@4qg$lD&ZJ4JMl{zfgCoOK1F3_JaMJ@tw59+u*O zF=X-f@IEEt=DA-u^4UUq!7q1rT^(dge&Q7I*pbG>W+rh}KWtKsf8tesPQoEPQepV{ zUMq9<&4hAMUU%O~;?ZBU*QQuy`^8K9Q=+e}2)H3!+s$Wk|D0P1A_F3EPyPPpHRMAL z&x2H9iHDR&TwhajkSpYg9eBUgwhtqPYjo4vb)2*ASQka!e#qV$OuFpk7G>!y5sGu7 zP9)SS*=(T$krk!b)75GcGkdqV=#%39AiI9YwR_A9_(#wX#_c8+)>Z{T`8r$=Xa0EBQqokcV76gr;`kCt!$Ie)4O(Ar_Hr& zsbuWc@x9Hk93ZYu7*WVwn|4+buTV}K)hH3S&%Da`* z-KS^zKRq*F-Z|g;y86rMW&^{X>c_< zCu!vQdvk3gZq-!jBLu~`eodRP5!nyh1Uem;d+_4=u7?Kry?x1b%RD8MreT(Mo;>zf zW;ZzYf0K3jvT?$&&@g=;eSJo*icX6}pGdKhfo3YLyt=ACt>|-H&Y0~MkEp7*J6Oj> zi3hBvXSKSO1|HF5sD;I*U5)u|>}dd;D&7!EH&r@&Johg6(qHM>bkzUKbH6iRZr1K@ zI=AoW);_##K?uoESFm3O=(oPxF{^qWg9affKV>Tf2osa&3Q^;IM6Q zQ)pj@vE9o(K3|y|x-Z}~5v(zU(4uP_YC1h$r*IxB;toQk;qv1NzQanJZtUH%r&0^-xwVo zPh}2it4}OQo9aHEHjg#Jl2GYTGE1P6^cQQ+`0aDAl5F}yR=d(!RLCwTq+{|zg^!+J z7Vei^l0v#5Z_kiIv21?(%bKD;_Gf)( zGB$U9+|5l~r#4C_2J$=PWj~&}y+pHy-)V-JjD-W|n6aoUSWxrc$A79OdB^%Ts#&V1 z{3E&R1LT`}3j_w7HYpz-TdX1GQ-ZaORq=gluIJay4jExCwiI0?%YNNR75y$$I>+Mt zwzZ=4zAP3HPYmcpbC~uLn?jD&k=xBs8eb}cW~ZyzDmW0PMPrHPAUl&3X6?xGDV1nK zO_`87WemL`R()sf=YFAdsvyUKWYxrwbPY)o)tF_Ex9~f>;^#|;Q4#dKexst1x!WIa z+K#ow=MGa2IN{Ir@B`yJ2$uY>w|BHCZSCBfaGHwbV7W?!KIq}IhN&Jr!Va+NSV)Rx zyN*f1-X>^TChCMI>Q^S-olBAW#MhuDYSEAzpXk9uN0}rqK5?NKiS**8EK1ZnkVpyG zn#aP8#uA}ETuQt{!-Qf;6zTnyUc7jQS?VnQY#MHiE% z4u?$@6UZa5l|!WTp&@O&)DqvLoW6G;YTxE`&*Jp0Oq4864{|1?vB=YExu`Z4Ap$n6 zr8SJ!FbPRGF*F8uH6fl$BJUEDFd2$;i1msP3^559p8yTwF11)vzn36AOyHQ1985AQ>S^zksqY7( zK8)=iA6PEXPbVD6z+Ix^hQVqlnBl~R2C#xDc0wvkJWp>nby=;o!j^0m7hCmb+04%l z6UqW2-BvL@TeSyUfD_#(#))cNsF=kH^fMa|Y?}HxTk}o^4R_EE%mHb)-2~rLD^a}O zaHSyk*b2g2DpC_uBu%L#gw5WI`&r?ERrm=WgJ>#Y;frt9$8&H=A zT6G}J3Xi9sqrEyG88pt2Kgmpof&yehZr_5RjmS4?iN6wI+Fez6w<>>d zqRK4nqdl;8$0oFtgGX?k)N2Vw%ZuCseUPwd+Ui55D}%=j@CXspSLAXy5dRQ?rv~D$ z4DdHSTI={!EENszJ%o6|Zqnh_ZbBLta|@w4*W!1W2s0r*Uxh1dEmk>QOarXSlqe06 z>_zl?F}{|LYRBmt@*}Q$3oB!nkC4i4clpj$OjL!e!vwFhB@LM zgD#j5VZ~vEpGy%g460auP9N=aIe307?$igr3?V*WSdbY;D11*_$0X1N*2}@dH=z(^ z%FYEAP7{?O5v`7nRQWVt6QUs#aab5O?s5_5?@+Bwn#dqUNmQ(Nt>EwwlSPX3t*{`X zl#I#@iONLR$`seKc)yLsL1iizi5S<_nMYc{cV%$Bh$A#A&s2&vukz^8AJaV6=sItE1}c1rd2;cMUye6Opr+>)n1G}q z)ZHWU?G7hf@(7=I;;Q4-BNFJ*LHxYnh)}F*EK!oRn$v(Jn*}rriL}DJ5>j2sGz*FO zYhr|WX=*dsgFtaUSXy+dR0_;UF)2U-$-c^DwZ-Yw>6Wv(U6CazDZSefwlf~PRr!FqdI?RYJv?#zUZSZ5q@UuM6Ho;=L zObJ*4HQ*bwB)_XNCnRbK1$omP8RW(22EW$n4-CsDNNqc{+XZLq3VoTX4BoliRCM*L z!&DnQbs|tX+oVj=xxQ?R_KG#7q65KREN=~M9|Mt)!Y24UMq5LgqD2kg_no85G>Y=8 zA`h00GQdP`bmgIUL~7Wk*dswAEB^T}i}6q%BDI}AlO)25MWYu)$!8ijh|XPGym8vl zIk6jZ<)fvJr>G;;ZR6OA_3Z}7+i9k47@>pw7CGP~qhV~m2(uN%5rf8_jB;(&qq9oWY=>9st*A}jz zA(-FzMZ)H?09Qh=B_1+py=a_vWQ=IA4SC$asG>SzXm@BP8hA|8PGem6rNkftp4F6A z=tCJfkH!gHv}6_!jX6`7qGV=mDi(b;aWQ_?2p8Mpqmfs8 zRMu~E?L{Fyz1E%5Hu#I7t7I9nw8%HxXlr;FQSR{c?_?#T{KiPE|LC;?$mzK zL_}8{C(AIA-?%@OhcH2ZG7rBv);C^(C1`RTnKyUJ^xH4#cmD2=g#GUGaAi>oHa;&u z%Pf$ON!$uU)3fqtdvTKhLplsKKimZ~jJLhR~wU9lD!} z=;LHZ=4HKRf`KAmQ#g=Sec7KeuoRI^aiXq3Dml!8{B|JwUew-m1G}ym1bFm2&BUv! zZ@TNyr~)Jn|0iXfq}5R`1$BTA*f{SRDf>>ry*p1V}^bHnsCb~nm5=52_)P|K3oPKzQ4>D1bFbME1;EXvUy2U%(5 z4Yk8k^KtTanN{MoM#3RRAF?nc$?%)kpL?%J%&@9)iYh<32y| zOI)g2F=@uk;pLwA6uyKTBJ3L{Oe-c7#jjqsy<^qxCu^1}M()PfB1%DR(aGR)Td$|; zUQbpRJs}dt)?Zb&H6ch(uzI)8f0A`oNkWLd`c4TvE4xSI+1?^WNiMdU7n#U&U*h%5 zo%xJNcz&c+dH*b{8}UtjF|&;*AzoWtjjq?AWWSfUw!hMeetAhFE!OJdGy-Xe{00<@N}oJ| zD}8)i|5j=|E|wp98o$wr%OxCk>tv7F| z1kz@NX$ekW`p)S6Vf2pSU5>a%i>yJzI3%?qB z-+FWW8WR7ga!*3%_Mx}@oqVk+=7>cTr6Xl}M;2nSs71*;iv__nEPo1}&q~blw z$)07?7DyElGbFEMNixhTCBU@nZM|%XVJX)3z4g%MB;4X^uhr=3Ckp?zGmu2 z>-O*wQua}nV2c!wDd1}!OR&;~M7p}IH-9|*dKul+ww}rK=9pkF2WK`!huSCWlGJg0 zlx;VQyS!6B`_Jr~8pY4;#v@*7c)a;XqS%@t@ z9^>FYZ1M(K zfrvaU*~E^n_wocgXa8_W+B#Y9VP^71E-O8GBQ4WTZlQyzqk=&LS7$~&ho4PsL?DT+ zSv0a4e?TAGB3twOVE`uApHsgGsm0gFI(oPw>6UWck+mVe;adG$uw1dLhcQ{`LivZGwfL8z1s!(aW`V5*ZWdSl3nz?B=^X~DTR7#QHPJbn8!9v%+Y;G7N|3%HhpI3c*=0{>&Okq2(ezy$%P z0fK~X4()(Ds>x<=2p9s-3=A{ynZQ_r{GdsPY|>H!&uo_2Jn+fDNCOuQOf@)Jp3JTQ zdkkDIxDEs(4FWB|S_=pY1q%)QHn6h55(CQ(oG>$U7Fb+Rt`1fixNhM0BqgU!-eDJ& zg)a;J*$f6A8#r)aXo0~7J{%Y@*KWrTjV2zgUk6p2aAF816S!Gm1%WdMRvhFyz?B$W z2ZEUd<_#EWjc204mIDI`+>}WZ4lFvbqrlGtqYhFp!99Xw_sQf8@a@1egQGXF_ZD)4 zc4jPrBR{a9;9wC?g z$Mq+1SBBwe4{k2OiVIB7caPpN-)s4TfK?kiZo<_a943NO1qKy6c$m9VZMWf)OO2D+6;spK{pGg%#B@0%Cjb5XuKAVSs;Ebo{!9+ad~&b%-j;xmRBI(qtm%?`<=RCbOLXOb+_92^0*i=E>xszhya3^PEf$ znl!YYic2PMyI*W0I?U7K4zR)=?C_ts_bDN4%R`%5?cB;AwU&OUJ^r@~7UefxM6W)Y z`^rq%{WwMF7HlV8=`RX-FZJFt5Hq`(<~`-ALNQCKywuszoRwQ_ulDd3}f^xEa1Li5kqeD2gPlAzg3@HH=y1*(jfTl|3#aFFkkMr++%K zn!nPM9qZ@dl1B=x6Q`=Sb#e1n7{_F=(wF+IVhcSQ_0c1hPux}|e?EG|u{8=q z7W%%Hg1O4KGQ<`Ih9u0HFRMd!xGNpA&gI^b7>_CgtIWO@?6b2tkGL;AihVXp{x|=% zh8DlEQ?7rQ>C`aT|Hk8Y_0gUp=|fCGoFqApYes(@A=q@`=*riAizG-hbFrOYjU4?A z<;yOh;Ij}m4L6xR8hXj^*m8?ku4hjR35`C39rAwCt1RvFc45S={tZ5wTK%SL`ded` zyE-@Y?_o<8^uK3ID~&Gie4J=rY!7K@f;m%`tP9Vcl5j}owsd;+^>fVZCEQ-Qw?R+D zXw3gfDYGxW;GUGs#^K;IMiV764fwou+?s#>M0(-TRh6#HHaq^Mcv7MKIi+loELNITDdE>&E99uG25@RneDZ$UC;UD zkr;^~)Ez7sRCdYiE7?)H6(3|6Ead)v?L;PboSIO`ZN0O$zxq8hdWz^F`KGJzQ`4Gt z-&levjXzk=?kb-DN)7Zo<6o=fpxrL@sy>rFq1-)UXlJRovs03m-)}HZkr|aqj>EP* zU^(%2d0CBXm%}-v+4`N5Ys8u~TMmt$qe1a3P0qs>ElX0`FNwSsEGs|_G;#=QU z?(=qg>N`Q2`^u$>isr(YY^FBG(o=oconW4$iR+87fs$^|l+k78gfcxhE!V=KtJ-cl zX*66wz?ni+l2vB(`I943Ze(pwK(w&WR6wjB5lC=^L`;TgN2aqcw|LU!94qWo=qOI3 zvxG`W_R=|xQ+Z4hnazA_7Iaan{{8linJg0pEi^@dN@w|&+B(NFf=FR+|W z)3h2W@gXDw4nLR>TU>R&50A;$u`7!3uMsv9C=oN*Bv)Jlv1I4EFJE>~fB!n$(n=cr zsNL28ZsunBAj?8V@!sz|XoG$vR_$RsSkYq{{M-;B~^?Gl4SksYRQjvjfcLy&I zerRsFQXRFa_wM~KA5My-YIvz`Ll0Fywsd>ctk3HWe)PQQlz3N7OoiLM=RqG&Zyyb3 zH)h^@z4heu*WYS3Uv#_w?%-{MO9ReM##`@yIQ{Y5_^uN^DPICV4}NSt6vl~v+xy@L zByt|VH;cQ9F^s8w645+s6O}FxQ*1u9;k#>-_1s4!7Jq72zFM0y_wqX?eA7_omB_G`@bicw1_gAazKCAosbu zk^Yy)zR7%rpkD$H)E!7WNSc|9>H#?iPc7W^gQ|fH7>HhgXBW=&LHI${37>EUe%otE3AdMgdNcgL}4mMg~KL+#_L>fRB9SA(gV_>n}CsWfP1Y$BQ z4Pu1g?jJNHtm*t(QJN2u6$B)xN7xnu83vLP7Og-urf2Mi}-Hi9J~P+y=YK}NzZ5iCnV zz7DKvfq;Z83Xpuz-ULb#BqAj7Oo~a+PN3)@c?eP*U_l4OB&;ccjD)2wP_To8w*vx0 zKsweo^B{5n7NH=`0%9sAbtA|{P>CQHL16z3dx-Md6z2~z4}yh2AHwz($UlgbfOHDj zj;g3x3mZicN&#{dv?6RKfii?`Fi^rE4hIHqChyDuWeB1jf+*TAZGub!h_3*R2PqLC z3n4rM)F7;CS-Sc|a0MtmkcImSR)R7-TpkXZ5OgDGMbL+^E;gwTCu?487cPVFhN9Bd zpbQ~t0~W$S944d$`6cIq8iXVUkcFTUVTA~!AZ%_y975{D4p*0Y~g??oP8 zO{EA#A7YyDNb|3pr=$l(IlH(T%l2)%*W0 zyocj&qqyo5PEfP!99iZBt2chr40U826(a)FtfNd`@!(92TZ->>VmEU~}c z-b*1_2Q4_;SZ=!3%wefr3oG}D9WNthwf$<1{tD+_)U?_;!LBrcy%Pfm+iGj0K6{s; zg%(;^V;)h4MU-&&YtOUhmXfl=6oXt8=S;UX_9ZS-)ROF1vm>@lj3c%@-CVSr3=z_W zbjK~?UDO0?fhXghM0RG8Ve(6MCnomb^kU;j**9c;R@m+Nv02X^GYzs>QvX|JY~`<64+zQ2Yg-%{S!jdJ7Ou?+XhN89z1Ou3y(M3m61 zP3XPe_E@uAdBxkh5aseh*`3lIs#eGQdsRFN`!32RmHuwGNRQNXL&8_et4Te&8t=cZ zksRyfuICu&`5ubae z;wg@(s=lQ3BNDi!gsf?v%}QaUn1=L zD0+nDxJ&3$jU+Oe%jb5yzrw`vLEo|4RtLD_7DU^g2Sz@JUaWk&g*h7F_fn}{cD;k` zr`ei`FJ)9@x9{9ZO&Ce~QqitDzdYf*7pp7M694@6XXN@3d?J-I8M*F$L^f|Sa-ExX zM80C6lN|6i!zb(VKJVq$NpT4b_0w#{i~6;DgJm)q5o#(1zN*2x$*OXA+MZh+=aPWB z-FQ!qs(~C889h^wtYR-5uRLO7IGUB>FlvXN;vX@W)y@0D>2s~`O7OwV$S*k41M7R* zz(Q+xO`AfolS<$u3M8!`X{ykXpN4}B79Ez5Rgq1yPTn6}R~ExvEl_76n$k0hk=Grj zZ_T@GqD!f!%n|pM(hhklcS`JqD$F(Bi!86d?(V^4;&7m*v!?(W5C^M}1=El~(D+ zyDZAIR`MI$r(F_5lZxRcbyzoBrNkd!spod*QqYI`16Pi(n%jHl>edepLdPS99-}#=$twf(>rL;@A7DIOG}2 z2w!vfiXTrM>|$$#nz@XDz|%d{>wY->-fO#kr|wIg*i3#Q*isYL^2pd)k zcZ`D`xIOrCb>*24S7uGUvpDCoS?TF7QnmCwy^9HIo6nNw*Cuuq43lj>otE1E9|fND zwoe^Q>AE!MNr9*DSqB1d`Rm~NE|cAV3cLfl+2`tZr;a_C`qk29-j6!LO!-kwwNtD= z!)M9=0C67{ns!c)SLDwiWj>78=HKZU$K-_`QgNQN^ageVH5)bl^KuV*=C!6}Le6 zK&C}K$qRW4~0Ivf!Kl6f{;h3 zA_D{n0`1M4XHabeVhVH?s1M+XptB&)5hNQ#E`rzrG6!4q0Lh@*4OA!KH(+=W#RxnP zViutU4i?KN!5ioxkY+&LKyaCu*+MiV2sbFW0c`~$3p(c}*XcpBL1H6FCtz=|R}XRw zv<9dxP(7292jn5_(gOyAm2(hc{sBJ&z(G!eFodmj5M`j1pb`k=5A53mj0DXH`U}Jt z;4~nAutg86>7YqrPaYQLL0f^;>bcYnkP-wS?8!p_CGay?ZvUCdb@2k=E{KT)ot~4o z927SQPgq2UEp!O~GBLLTAZiio30vzR44a#qXPMeSMGow-!+tv~nS+#uurtu(pgkd} z4rD20)Plr@#c~iw0AFF@9M;GomlKFAgmr?thoy8_GUp8Z2Dy+wQ*OPT;C~^&V;~zr zdV`XJXj)KGuvHFH4m3FEDahvnIS)JMAUq+^b}|dw73FS4 zzL^Hm-&!j}(wlxpe|O(r98ECsUt;z%d^VUoCm=NSt^TOMK~YyFY=5ZV=+E%kobb~8 zl!JSH{30GZ*U=pc*70iTV zDTaS5WBVEXoqUNeC}C!6DwLAK66DLCgk}g7j-DMB7~;{-pK(spRuW2<8WX%_9Mn74 z*dNuHASL^r@b-PNqQP4Jh4abjo%T*bv-ijB<$`mQ!z!ouhU4CEMUgI7S9S919Tbmw z)oAWoBWR|DGWw>|<}Jnzbsdl3Cr$G+Wlrn4^x#=DPOB$JF)Dk=a)i zx+GlY3B-1RulAl>5-pY8zf{eqr&D*A#~;q6cqC zQR{EvL-?$WKC#51Itl?fM~ITFq})CkU=U@F;i$UQl2 zSMOZYojTf0xkx^UdyXedtEesXp)nN|J9p~;bEVFv?hcJ#l{!c8=YQ(E#6+R9dfKl_ z9j?3l1Dcs*g8HnCfUJ>=#`R|T$44>(CAAO6`Qc_6Z?lq)P+SI6FU?D=JzIa8g@x_5@SrQgMn#zZ$qCgF|ttAb@Nx#8_jLGO5JXG^Eg z?dkE{`fjgKvP|FE<&yWoce$1BWrqGem;6q@+gBUItzGWYJ8R3EsHV$h#+!P2o8H&u zi7tz&NiLVAV(SicyO*2gosv7gE-PQ0Rc>Bk)oSbg`$5uHzhlj5SE9E5UN9_KVR_Nz zs&)_&wd+?{kH}3%n^NIRYcw5Mpe@8jC}c;4WKYUF@U^)w;V(RD2B;0^vR5NP!ga&KyZMJ z0G$E85`ZbtE}&Q7b%%eo|NH+?;e0s~lUU&U>{#BmIic6Cf?EmCn4NA%Wvw!v1=kM5GyGS9Mm=VGRyfN{21M6?$ z#C+mUzAxPyOLXupYpP&=7Qr}mT7Q!LSb8U)h3+&ZF=nk|B_%#MoI2yTb7#CZI9xOJ2w(;_KYu*X(3>M55HS+n z&_wLn`t2x{bX|@U(sp)etZ#T)&a{jl7GK{;b13|?{I3&eySHdnH@VwC=F_^pOmoKc z7*P^MYiGz@saxK~c1lkFIeY!T+k7D#mNq)~=lfSW&vm}Re-XYOUS0*^#Lds16!7NA zg%!rUlbb}fMECu#0gNPc zeFJ<0bOs{>g9bztj8_OWhIxmvh0z9s7)BnLURVSd<`IM-q_Ki<1bPWE-jn&?For;G zVU}T9s~e&Kdjc~A5zMk@!6ya2CouIO?%`tsvk#vF81TvQpPXX&oiI7A@Wq%c%7(E8 z(hJ`Z_`Lk*Z_EGjai&bL5ObVkp4_cd&x|oREUt`ktqwXdaC~F$tF7mUYd5{%$u(heCU_{+c#h}O@g|Su-QvXaz@sH{J+O6r{$pRy$cDt zc*);t=bMD2vI;MEB|Cyb^WVM!$t^jjxzn(zxW2M%&!69bL%oD63#BlogrWPr$#1~x zQ=2Lmsww6WX1;;idH4pDjwf%kdzg$9ks=EIl~0cEgc3#;i$szuO|Bd+7SW_+e&v(v z%;dyAw-k6Y;lC;=dtmY#u$?w`T$V}3x-iQmiK+jokodp)2tYvjFUI+Yb0ZYT5o#y@|jypZK%U;X3t*lXV*tA3bY&2{Usz4d~+Z}b|@^rs*Ah%Gj`!rW5kUI zl<8X(*9A4*s9mwZQz}T^YQxyd7x%04-r4H@@%r&2kF%eG9(YS=xQCxTwV_U4Kd7@Z zyTn;=tzqr84710VmKcX#8uDyC+keQH_K9@Rd~&jWoo%PVE2%^@`^#iO1~`loJTx$0 zU>v}_z$-SH0S>bU0|kHiFjFuTlYiJSLGXhI{{PmVTBE(|P8E=(&-AB-)00bpkTZ;lvD79Vhs>YjfWVE%KmTH-uU+In#Px^tZ|SpTDlTj$h$*B}%AIzOH+8T_-2&U%al* zpXt_@{&VvGKfkWAhgn@ynJjrxf{?TKf(m|wzX*3Nadn&>!sZ_%l&`t>rOfcw@!*b( zYBN?FRhlN51=0UKNfcEk8iRD^C7S*_xoLvonq_s%h#@$4arLrV;8h{+&F@QaOh8C=i23rWg4CDcTC<0{!EgL|001g3P0ZIfg2JZd=r~v5! zssSrau*C%-0RU_uP5@S{0M!6-0W0ojHO8+Bd)Qb4R0Grm?(!io0s8I%y}*dQQKvsYi0dTUJ=L~@X(3kO(GcE9gnSq;r05d?F;Bp^m6HqJg6v5d7^a7*@ zfD<4bu*x7H0T>lf9H2g6q(R*Vgc(3~0#G0L`-7|k@Yo=S0L((*H$b5v*Z`Ol1Q@{D z6M(46jv+unaO)2U3iKdACSXO-`T;9VP?H4a*0#6=h)Dpj1VQuzcW#1kgeGSQQ2=Zf z9`PH<0zgOL5&HTs1zr^p7z(>n{r!D_jsPR&A3OxhRj^qFkq@9Xp|KhG5b&q$oPDr0 z1$A(MwKi^w2iOB98SIw9`WgT#NMe8w7VsqK-;Rq<1bnq+8y{>@X#Ic$1t>8AGzILc zqOuY!Mu;eYPa9ZkfQ2Ae00-nJ_I$+fPx@|fVX}VG#Nn-0YnZ!y%B^E06GGm z1YIFeF9Hz-;QzrQ9W)|cxX_i7nh8t}01|{NKnWDoi$ItGfG)seu>J*r5Wbu6%VE}R zNBEw?=W2wG zCxE!}KX-YU+2-vYx3=lEt;JuXQ*nQn%L)`e z!}9N4MY;nQ_Wc>RF3OAE{oVanfWe{yqq&0E_GOQ+daUt(edzfwT(s-p61$2y>%Kgh zY>J~(X@WoP!2eZ%!B+pB1bY*65uZ%?*;RDVFHHfXL7USQr^>c)sh?d%saE_p6AFCjhX|3(efCq=1v3vV>oMBUnPE&Z&{<=m)fnJ8+bOIK zQxd)I&P_oxIZBshoLRFagV(7ZeO4aTTO9Uzh<+aktjK z`LikR!;3fP5!Gm1L{f_6Elk_YNA@nt!?gq#b)&bPl{??=#Jo9zcDtD-A?+8VxJK`~ z3oL|41`Z?%7i|QWH8TuP7iutKXyysXM8DszmvSeqWVhMVizU$bv_ylbB}raJMsjotFx8rKzSp-WRL5dN~Z>-y{a zbv=gH4ox9B6pPf(E}9`Wm`Y>ukw<00tLA&#U&L)2S!KO_<22zgj;$$8sQLKx;;e~p z?)FCxHPB{}Ef?oFuF}C4qI7LJ zvkSI~(SlraZL-pGc8Yrf!80IPp0qq&&N2aG;D=c4vG_ceNGbgQywWMAyQD^uF{dBJ zF_D5%DYWXAu|h&H_1t2_A|lgW>F(YKW%nH=v8H(PlT_tJL@a-m#R)3`k0YeJ2OvXI zqFYkT%N5gU`F58g@Ss(ZD~Qp$MqyQgg(>TEua}lv)KyL3n+Cm^KZXJ{#1V;Pnh3ip zxyqc}?zT)?{t(46oV^)Y+OTO}l)fkPf6MPpER97^UX)=Ols3zvE~^sH#sQ76M``x|Wpk6FAkLkcu$S5q60G|bQ!7bz;vPIev^ z(r0p4;FcniF%QnL%Ty4B*HAchj`W`JcKx$+`7`SH?|3xoM2r)LslJ@ ztinX?VYAMLO1XX7{oJBkk;J!8%xdW*L9b`)TS#6HV4k#~C7mB1uEqjH<2PoZFAV@nw%5NOCJghz zMP<^4kv4gKYM@U7QQxzRDPgt-b#A?dD*wn`+x*CIR_PU5as7@*{`0%S^Q^ADjzX=B zo2wYfNQr50jK&iR-&bSA?gXp`=i46_D(Nyw##r&F{6I0)fWszlPcTPDt0ERJ;j7gS z6FI_2bm%|_lC{M(-zzhWH?tEoYB6s5SBb?G{%u*p!|4^c=<$3+i(CXg6lvo{-;tKJ!TG zXq6S+l{~_SYKs*4F*Z7#w&})UjX$bZ$C2{TMXjrmpO4Bo{9gFccFgfXK-cW~-gFLo zx&&7sHO^)RS+;3tolQ>&Aky<6oMpvLi5pol6$SaHU3~lF;MUcLA}+5gYq+w>_|-Q5 zgon>tCtA*4Ao*_=QvJF+wzJ`lj}&cd;vR;{5Q_Hhc24IcbNJqfnrLS%HKj2?|^fh zi3-2)k~tA%M76{vx_A7b@|P0lEVrLS^x8p|+0nXT2ZSO#^Y_z8b5U+4%{{Qg`arT( z%MNUW64j9O>SO{0B!qnoLue>+XWD^=sBW9-;45YhP?qCp7CF(M)$87tW@qw`4ymYre zAg>$lQg3c2aM@%Cg3T9^mJ2DxB69OPk~~YB+?Iqz&)w2MJTIENSiuGJqO3&7Lu5za zFZaxXJO#%zYiXy<=kf5}7t*qbu-eL{s|?f6i?)0n z*fU{?ZxPbw^W1LH&_Dpbqrv2X^6p0m+^7NpgT8C)>|HY5spR4;@`!~x6Bl(a{L;PW z$EU0vEQuLnDySw!gI)atIm)MIOy$QBL-&kT?i!l-6c%K%mzYh$SeE?posRDW4>`M$ zOAgU0n^-3x^$DB}1X$?aPu19e~^Oatu!8%#T2r z<_rTJ%cU-ONFcr<5SI$sXSOk&XiAZ+Wve4h$sh3$TEz0@sqDv!^WvW6nYiqdFwNnn z7>i(Ovf~E${Hq0xMTVD6rc3Pa+^L$HpKZ>#6dHD!RelY)<7P^8W%mYpUcec+fvl#QrLCs zaO%w>G+y-B0Oi`-4@TIPZaGw0b#Q4PI>^Dto)zmI%_fCf3GD32yv;qj=}3HdLPf}9 zdF>}_txPUCup!XKFfW;tXBw2g*$R&rQT%IBvI#UXkchEmL^jdQ6<-uo7Q9u6n1>}p zL+_>IE7z3ojab(hKEL2u{0++X(*f(g`clhGaBUuADRCjHCB*-Z7Kjc8x!}bO%Su;R zr`{xoOtg_$d~5?=wLyebL=;0quaLe9xYs8ala^Jkg8i>5*ETEg&wWk8sN<% zlcJHEF1|YmKiXkkV&HW`^%ycahIo}oP`T3;Ph5j3{FW=8DnhzUe6z6lj5li8iuatZB(@zRdL8TDdUW7u zb;1|otS_aaiW=I;!Rkf6rD7+n_BgVr-KQ-q*+R!c35O+6+4TT|%?Z-ofG?`yUWRx9 zlbna>q&_Jx5ha+FC*y{zoT(#@9P0}@>S2E3m;|caP%n0^ezYO~H;JW%6I&XZEAtOP!~YYbZ(2?#ZYB&AhEvRES1l!DJWObWG`JI*+rq)TNXR}*9)LaS?+S()-AK1dYe z5RXpztlNlKjaD0oj7Ml0Pl}k(e7w0ClWDZy7Fy0HS>~dJTqMUmxvAjfdviE5r$2j$ zQY@Obt#1ls*tX8GC5|*L(rHeG{0x2zHqv;i!KQ6ZvGcYAE!t79e{XOTos@lg(q}bR zxrHo0e0={g8;?ykc{aGb?tG%=$*{GN{=G@FlP zp4@uIH^=Q%#thp}2hWz;gsoiL{Pff*By0>Mlu$y?B6P}q!Un%6x3T9@JBU+}A?^A58U{1pL3o~=fQZ4O zW0|LJJhZuf=B&)n>6VVux5*WEFS_P_jt|7QpRvSeE;5P~$gL1zWD|@$j=W5XYKU+z zhcm|z8g%Ae|DECmq01tY8k6wgxzZ{sN)<_vgoq(TYqqo-oNdRV36iz*uyKaTl!2H*#p*>JLVhVcN*s1``z9lvXc`RU^CS5;1aiQ_PlDB z!)UnOWQg#*glxk?+O=r^^RC5Ntw=;A3z6OgB3(UrFxDu2PUOWcU3KKpF85%ZJ%n;! zI>#fz87563Y-XRg!@9Um3adNhtZ#JO1thpIRAO8i*}cCod#ifK-LK~%M7+H4)Ps(h z_swvYm`W=qNZ^|K8@kiac3*WRKV%|36KQOC{yFveJl)Gw_T>xibx`L)s-1W5ID@1~ z_OQka#&@=5;SVKy_5|bSI>Ic3T~)ztM46uX609ap17_;O@FJt(qog(>KSY8OO`KJR zKihzx=VJ@f8j59!YfKz#)x@@?6sIw<6HSbH;B=f29~-Uy9jBiYztp}$9uean9TMws z>UW$JzmGqBP2*l4QXnuUX5urJ;B&9w%I9QKLXzpB*HypwQDm;y-kLwvpkGe6kKA`X zg3!+(P@c871|fR)9XynEgVN_$CqlXV6TPJ3e7?&Xi)d4oZcWL)AyL<7woYuO?n5oU z7PU^@lu!GfDI+bC@)w{Ip_GK_?buzikfOo}=|;o1qYugR;s=I9Q9M4+rnY`wDC5>} za>hJ``?XR}xOWboyHg0O^WX0X?@en`9xVMn=Tq=t<;>ZTbbj2!^w>PTye*ktj+NC* z?p}U3NRnB%{-8nQy1T7c3|eNcJ3SEj>8$ek_@NrvAuicB@?rV)lp%4o!KJBpGi8>Z zs&4B$bkEN0Uj4dzw}Y$i4Oi<9-J5=G&S1&Z`(xFbk7f=rFUJoYx<5XZd1-3Jki~FF`DE)U*#*#Ps{aD)qzC8Y61hi0sl4hTVu_ z(a2YszZmo?VCtn1Cl73awgSBazy>502rDo`psj#50ks0}1mFj}4Nxd>KH#Q6F@eTG zo-9yUK%~Ga0s8@81Ud_l6)-A*QUIa=G6CNLWCdmkhz=kwz*=CjlROn5D3DrUw*ce- zqXInzMhFBKur5$rz^lMJfl~rp1WX9L5a1}lT_C%Y$QI}+&`f>u>SzW5iAvOSm53nxFf9DfkOmt3oO{dLIo_?f$akH5!_WE=m5n5 zfx|8%EY*Rp1U3!WJ%FnLKLZ#B8V%$axG!K@psIjZ0kr}Rg?kg&+k?$K@KQ6gm%*Vf zIH#~p0nQGXL<{T|z(Fyr@xht|gvJIfaRqb@uoDOg=K zaJ8wuRW|1zz;%kDeTw1Vfa{hri?!=#tiAuM9DYk*zIQX}XJRbu=Y78(d@9x<4e>9X z{&iqm(d@&^eEmR_#Q1+5*#3_bWB-Tc@c-Qf1 zISvKvR7Kd&%bFA9w`!xVp=_y@m#d&GZuyt&^4%Ms8)O!0l|@v}$i9?aMU2jP&OK(_ zzh>u&@`>l%`;>7su4dPH&-BzQC#+{}ZO_XwNt~3`(0ar*OtUGh) zy&d`TIe`pUlGJ&VKoYtdXz-x@l2H{hXE0T-b@L;Mb62>dQ*Pc9sK=NP`6hXvTuHjc zG|x}zr+H>n%VvFZJ~p=!A*r>E9%P0skQJ7nyJm;hp1GRotTGazjdfh9ks!@AlqAC<#MpHcF8)r6tKg)d#aXk%2y~U{V9SlUXA~ zK_wfT&Yg|8OjIpS&~8OYXkm}}D`Ry1?hI7Qlp*M&j&hujE6c^0(^ze*aFk8g*-3h4 zXR^9BizG;3&ZmiJJ1dacL781BV5QmvD2Ih(Ox`vf^nSn<$@lHy%j;-Tk96)F#`G{3 zN3&AP3Cjf3A)6cEtcXgwBqQ20m!3^F>#XEIx;ac84n~UR%6wUx4oQ!Q6keuXjCHzx zD4xWU^@Cq=?-A1d#6q&B6eUTABl1m^)_1G~N}HM4=zya{vy~uw|NByUbPDTX$WA1X zN1ZW=ENgBr60{RF(z=XqKT9A*zQG8>F3pT|f?TC}WKZy_* zp%M{~%k4GSm>4BvM0%sg|RbJp{o z@}70pI^X->{Nb84Ys|gNwfA-XsEuBP2a!HbLoLd$Yr8@Dj5NaBljp`JOb(KcVm5W# zWjf)oi$g>ym?%;3bZIe>PDqN3ntKl~RH_OyvX|EGpAhRlYWx(V&z<$HyME#?5C}3w zp2Qt#h8e-n4)>nM3+u{oz9-7Pyue&@tCIe3=hvA?#@C-`i*gyI1f7s6Qg|Z%9O(=~ z+I@6&M!YsDn~MyCXX+7>_zd;S zkF=UgbR^5D)9r_GjGhi14CO5n*?3vR=ZQl-wY9a_&V4ctIL~_kMLGa(JTU+zj29{8kM` zqYZJQd!GB*?`+hl17j^GDr63ZQ-;lQrt7!{FgH4Q>G&pRZnO|EQh4E)?Rd`Uz{wUP9t*+FP!+WdsPhY?t^l5szhW^Y{bvs>;wQxbCmyA=+T+bC3N2Bo4@RsH-*BKhR> zV7+#xIZJd|_xAfO--IuTij+}HcYhEE&*Y6+yXT(P^{n6=hUP9_jv2kfA+5!i=;L`_ z%Te_p^!I8HJ0a1J>pAb%claH}Wjkj9Ppp!`Q=^GR8k5Pi5D#T#e+i%MI}oHyls4>J z=S6x5MHmRqb*fl2NS*dBN6bC<^`bWWbcod3^_UOW_vBiPDn5yy?ZY!c* z7fr}_@ltx4OvJ6Zkeymqm)ic^>$S`3TPs#mB&+Y=S^aq2q@){UMHOccpJm`o9=fxV zS}=;eoJ({tH<8@NIL`J>t290752}<_7peM4DO=On*BnT*0ehuLYPPMn*FMUO2+NSD z5i|W%?czM?l&m=wqmPsE=m7j`WT8AqCmY*hpf`nGB*e&mc~GWrF%q(Zfh zr>FalSR(XP7-;K6F}KQe#@mSbS#QhupUtC5b!uP zgC!Z1te~;czRGU|5NH`92$qF4%sFjh})&cT^0v?3#y-_%VVpaBZ+} zFk+Cz^6m@_oqTf~vK)trVA)^Nc=xFl(?;uz~O<@R+b;@JFzUsPO#g+8j9o z1Bi|ZyeAqxsGPv1Vtrn2tkB?qXM}x&7lW09gM($ebg30)2SyTI8#HKOxZrBxywIRQ z(*%|lC3E;e7(Mt(cu#C1!4si<1Aheb2+x8R4_wTjn^!QNsOrF?!m`0s!l=R_!dIft z($LTVdkC`w=K{Y2D+im2A`IN9^NNXZg>YCfP}pdKNi5nn2elV$vY`coRVX+|wEN)T zVD3;zk(XIeR6&OYO&0hs6kE`0k@s0(!BAbvUOx-_QK+<_$#SSB7A<|Z;h<}{yRPRu~n|EY>%Z-v7fv~B;Qy8WZIS)$C=|MT?FkJjeY zqPN7l`pb2HR<~nXS+=42?1;a$HsOqH2z45>MH=<@&2*l=fg@>>Ec|0L{jfb>#H7s< z%AJw)=?vw8d7||lKb%qf$>jllmcI0QyL2)2PW`gikJ?v#N>d}!D6QhO*tfrLF8$`5 zsmN;k;9*oz4pm(kw0M2E_V%LJN9vy)d|i3^^DE0xDx2=*r6rLzDV=+D@6r;r z;9`OX#pk7TXLvbokJl}OEDXufJPb#RlWvrU4&->Z4;{@x{yAH##1$xs6Yi>s) zf1hYn=>o5kLq+HGtiS2XlrMz^5kvSywm|1aexyV1jB#;+Ozlln!kiyoK-F-x>R>3} zh^h?eS95$Hq#m-|KInDux(+HURTkH(vs)5=iTbIg=wt>%BxBm#_+H|zd&H`!({_C+ zX{mVENb|b;1Y-$BDOb`+y}+?HYSr1dv%}>15PH&7_hBY^lV%w^ejabhrB4z(Cp!B1 zhN5no`wK#taho^GQ`+nkeNMwQn7T31**{%f^UDM31R=>HYOTrRsm<)=0zpV{lBe0i zHELJ&cJ*@zrrB@TpVCui;W6$NWhomC2Yetr&>rv(U?hCJOWNZdl9G({Fg&I@EoWP6a}gS(y=ZJ z^u~w`5DlUMssrRfJpgtP2cRB9MKBJgb3k}N{SS(1y9AsE2LaE~c?96g(H;x}BnR4q zQ-JV5e((rjA5;a*{}b>rGy~?NG6~F=55$1{a@Ysv1Ni~_sBp@6Zb3%!!6OJ!P64O{ z0{>B#1Q*CzK)zCofgvV--~!Cn(9pyr5OjcbB+vm!0mDy_0!E1FU1HXU-Zkcs;0R1I zF~Y*V8dNMX{WBlwg6ZGo8>_JOihecd1ADe3?cAUcX&f{%1CVSm~7i;4*-7NyqUY2TuY{RQ~;m zCS0`p%RdhvZh$sOTXVx=q)zA95PDn=f?C> ziNa?sPX?EKxv#)L^s+pz-BXpJVoMT&8_Abn9!MI&6A?pnc#@H4q>~RuTD^>vrqPD^ z@m^P^Fh~)F>L`1?WoLwQyXRS^NJOY|U&n;BdGrYwEP9og!6_R!yu3Q0euJlOI3b#= zZe_cu_I~-|+X|$Hu%qmiv$kBlvwy(sKd5&^8<6h!esORKc!(uLU>BDB0YUNwB6-Gv z1%7B+gc`V*1eC*0J{I5sgOGy2J%AhF1<%ew&Ei{=my~}*3^577Mj#2W4l76iKz!qX zGN2PKZ30dKZcx_%8AKAmG(Zq=2`~k40}26@phbalKsJ2-KsKO+d=w8<0geGHfDFJN z%;f)hulb*snvq!m0r2flm=uD{0_|_$JdhUl1egZAg{a1xd>{f`LjZjM`T$B$*T8>Z z8tw}qz5&0W+zq__k&*;>$=9jmyHwb~O8q?-0D6Fcz)kl+%N@WD#RgFr5zJisYpAiS&hd*OXFNEX-&Uz-jH)eUlmRgzdjcx~pTTqpYyQk=Kru*j0Qm5OfNO*)U|Ym1 zh*Z!nN4x?HfCL063Q9t+9D#^DACb4_QIkhFf)YCN5%kc(bf7a(39JgZ=HCOh|CV~E z7~%NH^OE!VIu45-v{vuExRLk!($zn#hJ@?b5qta`{#CBwO(QC3IUSUJ|1#IOWo$e) zNz3D>zZA)1Th+MKoaKLqS#ADS!HmA4FR*hZe+e%XdH1_G8804u{UXP3MIs$a9S`r%d}ATX1*a>gk^!QaX11?QrP-GMN3B zcL)Bf>V0uqZcHN6fAhf9!-0(p91r_la&O6}Mmg4IQKvh8TfBLGgrfq%h&g{g^6o5e zvDXOKWi*zdRj@#Lh${*AwB)Y!EVX)L2|cs@TSq;2c=tL!FR+SKq7APSoHiYDr%`p7 z>qn8GJh5!)IMunuGQpKaiI;s;w1e#g!jGe#Z821?(K@YOBL(tLfjW3JafB6y9R`om{-G&e4}FS(`5L6D*E zwBGSD*Pm$QYb7_5`cV;5F`w-yY2=U+>4z+*;f4&#H2R<|;pLe=Q$im((!}|MvgU5G zhhebhUBD8@V!I2(fFg05hSulyF$qIzB-aQaDaM242b)st2p-YwfCUkK63KVVlI( z*wl){&B8%Vb~l|Kl;KGirl+lIB!-+8vd)+C2~(Zth9l{+J{>hL&CNe0vjjcDE{dqa zzn%B(l(yE|6;_2N@wtl8PyBo%C|(4?aObr$=t9!2Ek@NYhtMOW%ruIKv02e5v$%@h z`*nd~+Wl!m)k~Xn-l&L5N9hRY{t{33pLhY^hCLZlcz#pHI-ZJfx4W-e>t&~w0=iqD ziK2aLMwg7xGncvDZ1qiZuN*pvicfWojWiA_m3Bj{fFrX(02(+`N%f7pw} zvd%xOM#?voF>jIYNXmCAF|+|;LEM7!pdTO}aKQ(IHRuP(25>j%Qhv@6j0w7g41g+t zegHW_Dq!XY-h@a1g+U%b550*?8Vs;0<27!WK`dI8aft2N|PGD^?EOZ4VJ-8LB~So4fCfgfrNn0fuxaZ7>E`K8we`7n1MHho`DL2 znSy|k4;UeSpm3l!pl6_zAZc(~=-)$R|L@QI!~cOF%&x=Z3wfe+w)(&Gq(Wf{K{Dnf zMg6Oj;EWM`foLx!>+dJQca7h)FsRJ`(4vQb%;lC_@F*-rw$_iGPx&_W(*uSy#8WnH zf1CvO8og2?&ZecQTh3~$ubz7$l;*9|-Ch0k%8!%a4;*STC@QY`@;7cXeTXQbA?4NY z7b6WmH;YJ`ZJ<|l`QS*=sSN*7EI_1ElwdAa|XzLTKSNMS??ojC1zDAvDq zN&X!E@AIg?!0Dd{crkncY~r>*Koye*m<8NaNnRa-2{X>*qGp3>11{@A&0>s?X_b7A zglJ=xc!s>~({X3D{CNeOjm6bg9Pfn@z)9Y+LyJ-A!Jq*39!y}4)Gpn!>&Gp99N@j% z^JC>4vll=vL_WkhW?3)=xWS981i~1aAHy+Bz<|Smm;VqH1HJ!>#{aEQ{BPng@c(}b zivI}?gWCQd6#o@bvHQ>GMW~xE5|t%figEvES2cFgI(pJOPyfr^|2Z5BWq)?o`VAW; zf4i)+R-3-{&&xWSEtO2|^;P%%aaCiDI>X42YGP(v_qW~uf{_e8e-&5i1^H#28&(?r zl%WQ<9zJ^9-Sb3jyu*{J+xzNu|4(n;`fH6)qfl9j13&+`s!>V~Cv^Bhje8n@(7Vi?Upseh z@Py-cGkI}s%FhNBJVR@%7u~~@#;ScJW*lR7pcw%0KdK=C zgMR`SP!US<{|a{fn;H@r`)^{`zX!Pf@2bat0$KkLul|Zx|4skQIK{JFXTsVUb+9t# z_1QS9Yl*RslPlk*z8#cFIN$}{|z3O=ISt&cI?H#4)AzrAxBH^K-G!*ABV@n7pkfe$IrB! zzi_ej0)?fakb9}4^ZJdO5{j}mwfWZXhsQ#$_4GY`_WXs7;ooJA{E!IukCQt1_7FHh zH$dEAT8B9%KCNfZdocxudHZvii%JA;yTXjYiNUnMgTe5?v%xjV2d{8iGnP-_KRpI#WfB%0!jdN9z?R#n?n{(suhv#lkUQoDt z%FhmUZE$kV;EnWf@1aH!MmPH!xfHj9zu(mlJE$AaCWVcLyE^v!9PqQtXdYK;Wcvt5qHuI- z8FwN{29dAOz)Z8!QRJr)rWsN;Z!-Imx$0B>3-=n^P~m0W?f1L%^)ko zTgo@2EWG)9v0I-n?p>i|>{1&cc=y95We<_hN|^YY!8x7H#1@*-@2rMT0Az+K1AZz< zK|llerQrvU_!GZ*q`a71V~PQ8!-Ej``5|A#2ZE6SepmP~@tNR@fQQE?(AanmUl4wT z2&XY~M}-A5dVE$0Trs%!@}7iG2BQSbV(?Q39b!O$EE9nNvehwyv6#qXGUC9WfM>>p zQ+)B2A>=?ji7`Eh7V`pp5%{d|ZDQJvj{*}1ydi-+0FRJiID$_S9}&J0d`*eT(=boR ztRF=g3^g#y$IB2H`lC;S5j?IyV#WbeflvX{e_WKq*++ZF(Wp#e7Xrl{IEtcebCI;&fJZW5gzzv1)H4S6NTcC=aBmJA55&Ny zitiC0CKg4&Rd|sOgBWN6P};?7EAbO|_wdD53FcE6zTjdpW+Hg*!gYKozE&$6$OR8a zFCjj5ba#-XA`L>efwRiUJn*7M?#9_zuE6a}BnN;aWI`23W5jn}Az{L!Yn@%I@n#81 zW*Efay)o3wkYvD*0U7+FR{%7SSO8%FS%}i-M^D1%hC4Z!86mSl!Dw1W5zcr`PF;sL zGw^U)@`bM357*wme+TLBf~X~!Nnwr#RK&9xY1!ecQq%A@#?AX{CI$IEdG+HxHXPtv zdFcV(O^G{x5snVg1p=Y;`){4c1>-#o47o5Vo3tVeeTDKPi{S&;bo4Gc))Jb%CE;XS zz|z%TvtpB)ZjKI~Ghvw+{Uki7Hox@Ps32VP^gu8cvF%{g{su%f5LI}*4Z${MMkvz7 zRy9q}-+?zgW^F1*tTJckk(RaKxwmdIojP?XgK8{U6igY(q*0sS4>e3+qFq! z@uR@#7wQu?*iRi=^j@N_W83S_{Pj|Y`Q&mT>v*caEw{RYAT3&E*cpYSr%j9h-t>e% z&fOtt&7ZT9U3$-DndXhjhv$8qYj}~P_DroCxcfq|E^YlV#W!CUtk==~8demZtU=!BslD!@l8f*OwQLGL$KbZCeg|Ys%V^^NOjmxBx!I z;=%^Q=WCaCxGbnBZP1Juzwg~b(qv4Kh9LH>b!(6oRiCDrq4s&f-Ll|-K8LvNPMafim4Wx^i+@IoF7?arcLQY^y zsi$HM5l5pfqVqU3uB{O{bi8nxfOiWwk~e9R8D)imYV!!Xn@Pt-e)POK3YOZu0aA~v zPl|?c^?;o-M z8$~kSy3CO_aX9sp`bL{qj`kAQhc5=3MhL1dZ&wiHrZyL>l~KB7x(g$`I`lJI2|sgN z&O8oJGVty$-#|pkB*TcR9Q9CkORJOr=-QZL*Az0m$CP&0Z0Ao-rsSBPc@WGa5+iO{ z6P**oj__xMP9ASw8s1}6)uiRPq~W=8FjHUJE@?kG@uP(#ou))vr(JqF{^(IcC9J>t zl0xvvI=Y)ARzRwh**0(UkH4TtyJ!k z%XD-CWj<0g>0Xk?jd?*^5ddDP(|DNV_Rogo|MyR}=aq9Ta!At)LVnJik5jlg90 z099s4seKplM!%SpF=FZDc?wD1^wy_8Y-)FT+l{M+{1@=q| zq3S%)rB0nt>&5Ds- zBCYg@M*Rh?4JR28-K`fJ{VnQN1-ay(UcX7A7wIX@ojqBib)=ITN! zr`jauhCMK!knMh}dLr*={=@#upLgbd6$^?&O?)1il3qrW3z7qHec9i5WPj{ZK6|@B zM^$u4qf8-&KZ!6U$0sI_Ae6|Q9R1Q9LMUBa)&I<;nL}8Tk-V|C6dM)U)w~QIF~W%b zrjI^I*u`}d3T!Ijt11dKpF~e!6Rby_4PuQ(ZKZ7&X=;X&s8BE7lh%zsc0&%1*Jw^9 zI()5}r8roWXJ|IxZ@A2G!p=luJyn(JMt?$3KC*RxB17tvumT{B)S||Fj`4j_nB5(` zUrNb5*Znj*hB8+z@j(wOuA3V`X6zrsuplZ$RU1y%^2SdMo3f9ZZDZS~Pwk#yz)52V zwRIRg5NicecvH6D3+9DtwoYOtF!;3^#Bc}pj1;euv_4H@Rb57y?&Q!7p(S)?WV*up zm*k=uMZB(?rY;l-v6L#Kc55tLHDvPDWu-;DT{HLdA8;n6Q1Rb6&rd(fw!nRm-K{z6 zD`C7dJ~xk4C-UZ(|9C#_QvZ`}tG;=9X{i!-lrtKp=;RCySG~-qn-O&KryOQNx|g(< zHGwVKOP?c3Ot^iL=q8emsS(2?BG_IPY07c_>m?70YN(9{^RF~3hzD@8OSoGX4~qEK zN{J&}nJ=?+J>6WbmTfLrb>OHIN*{-5UWdn!A4EH%1vLhJ{S9e7crIwPH z)4rU%%aFM?yq-CbcPH@K1Y+f_9W!-mznpou>+Ry#S0pQgBaODCFsw6(E~l@~mDK2u zdyQv4n4|Zt%U~Nlq0UP&Tgux(FDa)m-{&(j66kj{^DD*$NQTt%ROW>G5Z-b3S|UfC zp^%CkDnE-+zlw5WjkUx*;c;5`2HsgVzl@M&5>=iux^tBo(-J)pnjEKk}BwS)HN)XX?C)c zk)Ry-B90fp&NMtOWKvRBAE61n(}*hieA48pXQ&$y6UN-^{qUI!tJa`-%;%c5zjh>T zS=nCjAk)%HKm_QsyUpI`pYQIw%NSA5Ke+m*n8hdVKUV%yAGH47vO^&c``5Ufj(1y{ z-Y4d2h-rq*IkY1umAa@SzW1na?7w&ax6h@aNhNwsB1IiK#$yXSp;ZXM=a*MAoJDj8Z!tG$xl#dxVI0CROgkK+ z7h*dlZ~xrtg-IcGE2Fa)s2B&X_{`^;6U$x1no*>E6nTosC_FxIwpn69d4>vw8%)M} zw5m4BqUqJEH9J?~t@q}Tlo#c((zA-gVWh$P8QpBCu1 zlIMKL(BxHVt~uv@*jJ8+Dpf162DsKuj0uBO#R(nm-Xv9@%)V$wszpT8RH<{xM3PvY zWwd%Ti+99i1|Y6x7R&S7i@Ul zs%P6uehei?u!tX*cG$#pTMpT}@;I3o(Vb3v$CSh=b28W?c!o0w)@aZ4=){cWEJ9%f z+3!lK+|@JWjB~CkSU1>Fu#iQkxsf9|gk3ayM2bSWfb_Venk=Mm3MG&DsphrjeE*zN zz$S|7i#fKdaaxGpn7f;uSJIWTH#Bem*1WPiWVDp25vf=twB8w)_Q7?W;gl)%-2}&^ zm?|jF*t%t9u1i}tYn8Erax=;7<`B1-eMvNHDcakdS;?FBvWcNm)-S`!QMLqwS+Th1_o-tZ2$znH=fqc@yA@3&bgMU&q-yPx>)eqk?V4DquUF{f^(s*1Sw z-33%JP1L=`Tg;B==JrddZo|nT?z`iJyRF>3-siW~OY-ZP>a#cN0~0Tha7wTefXmTEA^q z3bAKI`8wO}`%<>gzeFx@P<{JSSygB_Mq!-Y`@qr5$4wftZ#hK%{-))97xxINTGK4e(OA(hBO^?917e+lpJhzaas1l=NYx|0$)noYl` zPnRAxP(5<(DIwdgmd~dxWoxc`Rk7n2^$Pxhp!fsZe$hOCStDO`B=cV7n_nsiUXeV} zzIQW@CKxg%=c%_ZI;tMeQfoX)=v7fiRnfz$m|@{NJHl9}s<`*7l)qJxdev&9sx`u@ zwN_Q@?5G}cs#^bk_0VtCJiQvDQ8gxEHKwa-%y-mSoT{<9Ut{yF##Zl`{itJ(VaJ>Y zR~>WRam+p7*j|D{M)=3{Xr^`1RtYKPPg4gKG`$zs#+I-(tBOYyuxdYOdFrVx=y0b! zJ;uME6q!QkMBLYEi(fUg zgIUezelR3cu4t^fe`4(^t=H2g8CKKI^l6E&;NlSRfJH2~q^uZ4u2&@dd5gQ>)fe0+ zi^3XI;u}KWHRv~LuMw-4hpBej8Qh9Dxce@9ncgY)FhcsRYElGiY5b|U_ zlu=}DnCdpmp|UX5<}1T41*q=LQg8o8niU#ZHX)QZuChGUb>*mAjq!+|$vHH$?}L3# zi#$osIrJTIESjN-_Z*X^um&X=5gM@Lw#nIuUNWRNe~%M&(tt9vit5DIpK@&YOe0c9 zO5H&+#}joQ15{lk+?!JBn5yDeI~=KYrh!u$xiZCR{Nc|N&oP5!terBIAgb=^MsCCm z^|rH-y{6sY$Zb+;VTVGA&o;lkO-kQos)5_i&}o`{N5wW%t3YR^o<>GN6Qd+2N0GSl zZF9XX2W`7K>6bcux{-`g-LgTb5_Fgu;ngx@ zSz}+OX>S1OHJ1#qa+)9RG|_l?u$tr8z~*Q9XIF8Zri~|~aG&A>d2UeC#ii)X29Jt$ zQkPXXT+|B!YP?46FLFPWUgsetMoT%m#B{>eHFKFOJ^teEDw=}^=f#do$2HDzd&Wz> zNFGTHmC#wX4AOS?!CE(^Op3XLIYr2D=)b(ulTC=?o7dHiT&OHoZR2S{ox}j` z?ak=dLNe8!)P5-ZDS)(;5|;=(*ufS2PcrmN^XT-ZbOZ3{Py&c zlskQ2@r{a)NLX(_RF&YEDq0gymeBK~Kl#M%gwOo|!<%?yONF@&c&SBsiXS z=c>;w{erH7_FFrxNs~CDBnkbKd(;BDudP?C^zzZEcbRr~K4jDnA5f%Hs5IirQG@#l z2E@2;w@i=RT1Qg%jK9D0>2#^)#PSJbVdm_%2{SIQPT4p3urq4cE$+M1N|9mp`@&9V z-n^WaGx6c0wB+zBn~x^>Exy+`Yhd_nY6+)f3N=|8J?lj@HU8ouA>Fr$NRZ9?Y_M2E zaGxiNSP^$WFpfTP@}i!79Dy{8;8RMTF5+x>tX$2C|22Gv>CBtUXGxt&NqY({zNdYE z&xV=g2<4e3yE{MrL~1{Jd{ujf{iEocj3H&AIE_)QJ=06TU)WL& zZSLo^xBE+KokS~-O(P$EnyERlm(fU}@t2GjouX5o(yO1AJI|ubYOoZ|A_kN@K5we1 zThw*Fr|MacO8mvBM^En`pP96z@8>g*UEe%xTp4!i_TpEAN<rOSvJNX1 zY$vLg{PcOryJx9vA&tTxRmdWWPdsCG(qGHi3R1JpHY>NiA-R<-B94`FjOIiTkC;oI zm{MPt$Ic;V9N6%3?hbl^HnDB!E9r=AYQdAZ(3e~4Uyqzfj`;0miOo`t>Ln$&StX30 zZaXW;mXM=_^n+6ByhpF!Y<^i>+4n5-C#oS^p}S3C^wWu{O9&}tO4ysa%9MvQ-Vick z)xZP(p*Q_DSCyya5$QbZ0$9wV$&qd-}dz;cB$&{9xyuJFY`-1za}?p{khI@r1#Q~#K7$K4Ntzl{@C>8 zz}GPoRD5PR^naRP|55N>e~y$mxbr<%^>aihc|G=XOE$54K56&%jgmEo)~L8)+)KgR zEZtqJsf`T7D&^iSoh#18wwrxjJ@Ny6*prpK%Lz-C+p~%t9V} z(>=n6uM|2luRQ15l_R%DJ^oNV=5_cb_8#+RZbEjR>}7xAw~E28?+gJ|fq##vQds=t zTQKK4XV~_O6F+SlNsf>E_3rF0WpV$r*_+a5t6EAa7yWelg9l|Qzu~F`A)30H`G#*- zwVSF)?AGDf+j29-1Q}JawR0j7tV_|+=~kUqq(|grbQ8P)z1c%84;GkI%=M8BEz+0K zx_wmbXd_p0?U;lyo8le({bk`6Dpxn;c$-dQROjB2bFYT0wsA#{EWZx!HoL|gu|D;1 z0z1g)e4gII8JngDSp@CX9PW7JtF4hJm-ZpmX~Wg5)*7CFTTnWmTZ?kk#sX| ztdwsuZh4UA`dS{}@XcAVBCDO4bdSHm=-JNn%F^n~?uU%rEL#0M-nZ$!I7__0KeCqP z;6BjsLegYj%iA86UdX3LMKnC~D2tX+Rn)kIQ$lFjsX^H>bMK804*E5{S9VnqDXY_E z1*RT5Do+-smf_|Bulsya#BECFUW2~9M{V{bw&k!j9PF>}vwVK&=s|H|t+GgySCy6( zk)xaA&tuIXiDMl#??$b6ea~)xeWC4opvp%!Ph>Ti^?uSMB5#yU!#bw*$Bt{R;^tlK z4blD8dB>}c+?YaC4bM~=Lp)KuJJH8!>eP_=byGuTXMS>IS-opoe``tT{G)kV)l$Qa z3MCN*VarBqYEmEF(VZv zT~fm8GUp$6n0x=%K-M&S&ybm09%;rh?6o3SbR|q`4slEv{bcIBo8fU0bv`Efb&=V_ zvRvonnw8hj$yYokBYa)`=49pzt|a$v7;Bmm{&ajLn@Q6UEovwVxuHFO+rsjO1v{2r za9g-*`a@|h&C^eIf5)od++OV3SRSf0I*VVIwosDgzUTmJfBDHpomA>y6Jlp%V`;x< zV@QRui;3t9>-z}FP(4F*guo1;6p|;bOQH;d*ajD;koO>ELB4{H8`fNo9*@ILB-S+1 zYeOc1dsHZcV4)wiHSG5z`az{6fXLRmcOj$M2NatPt%nH-`x zc`S!$4XrU`Y>32=z#-5=M2B`WvNr^Eh~JRaA&^5vck|YDgmwtt&<;jihv?28&szrs zBde1iOG9*rw5h%QGTwVfEQf6sWN*mru-%Bz4#Aa!U?Nuf5ELz2F%@wgA}eHd2;@-5 zLo$cN4r$!g+p7^uA&{FnClKi!S}lm~+HS5wjD(B|N!18zSF9Exy2Ba`62Z)@Tm*Os z3lX_x=d5dOy@;Jf9AA&ce{>bf+izARj zY=$&0`QlwYDmE&sj0( z6Coi(3&CM*Ac8Sua?Mwg5p?0{IizLCDYLpiA`(MR7P0k!jhh!zF*^r$R3k0yJ)$a3 z?yrnN^fl6bT;S5xs9xg1dE{XT#`vKNa85u_GY7SIq+i$pMIMHC=~rLvS$X9V-c-do z0lb}x&N!Ojs4w7z!1&lyw8gQ|Ijgwrk8Di(dx1>;ER$lS;6M2^+kfg+rvKUg*x+bzC%OL$5)6$?iz!NCh34+&%W#bOp2PByVav?A{xyFK+#K|MztR&>I7Dd{W(ObV;W@J3c`oqgd7k2=?)cs|4-Bd6k}*F>e*9j!KL< z#+{0bwT$Ui1x)?;aG^GBf=7p&5}t@+sQARZ_iQch=(s{it;j31eFMUyv>q$TRmNzm z%(G6aO2oO*)&##sfg$vy80fb+Oh}!qHj;3>VLO`DUUXa# zMU$zxQ0FfbIzJ0dn3#=a5^88{frT7g#%o-S%Z#7vQ6J@3>Aek8Z&LIy5NnW znX4b&?8(?PjSgeKWq$8-_LIrnKJC!GIU@;jeR^@65n-tEd%`1mu zWh*Y=%*!46YL;&~Lv_R=lNowPBAG z1KR=RTtxt_w4uqk(aNH?-zxwnKA&+}VZ;h)V5GR*(V*4?Y4=6Kbc zrr-KRBHb!c*xqR}Ik?yJ>z77yh$59MajgMT<=_6;!M!{N$DqPnZu=Uv^tE zeZ5WGkb*M7m;>ZOqp}%XzgF6mw3b)}`VN+OwzHkl)pe&6j1GI}3|@6pA4iq0c_GGC5O#`VYK;tjeevDKoupQL6j>eXYvsNq3zbc>*tyXGvsX$+ z^<4 z(MIv%feeOVu~&}i#+YIpD;wn(J}zO*!c4(By1&4eWq(ziI`_cSldnB1%_T|_X(A)? z?#YkiC1-a#=B69?jZ>OT$w+Q9Tt1aO_vg!!E0d=g4ivqbHP=bv$8+9k(P-gQt3Xta zX*s03jlV#>P?R?4E#j3w4069Q{leaXB;%_NesQ|v$PUI%xo55`Y7ob8;Ou4+Gj zqqpuA@~%OEcG{?is`SC#8zmB+t6ND$OIrG1d9czRf8eSgAV2eqP(fp*htP(xRfG>34@jC#7G@ zA)|(QU%B!or*3Rh&-$2CMh|!U9UuMVT>RRtCKdg4t0Rx7ji@M^B~C~%pr}@sgrAS zNL`3}2xJIzD0*CF`cs(0EPa<6Sn$ zbJWZr%pu0J9)G}sD4Ms>=HsGPh;F|`Zw;y(MgQ>G0odM$RL9vG+zx;?hk<}Lhm(Ug zPrvsDPhCQoL%(~?j!o-&4J8h34pknDOVFZB|Cp76@Wsx{C;DDl{HG+xn|D8YyuS-` za|c(PZb3y&x<4Ai{KukZvJjV6P`igbhhYD=~|gGA%8TL zb2L)vz;gNdEvI|SW3EytZ9fXEKj{;-u4jiU9F3^UT9#ja>?=2NcG|0$@wWBd^CQy& z;@Bn;wv(EQoz+Jsxz`_@cXVm*oVI{ZVZJol$P)$=PA2*+C}$<`zUIuINkl6oBj39eFJ0*yIP&=aNeXV@}-F?@P?M#h7?3^fYh%O|=k} z!I;%SQv@zbs^)PLEm_jQK<|~22UC9YUdnoRe{8);PXgh((<^8#ZGFx4wZn9CibVQ` z$wlekRD)+v_IMrG0o3gL-QgrtoI#m{ou%~DUx^7`31 zMiXy&GSwmmj0Db`&HE(p&&W0l6{l`3b{!~jmZTU?ts;vR-7Xat7fqi(e`1(#)Vx#* zo~R%=Wc0Ib`fdv(ft>cNa_{l8TFL~=e7l~mQa79`+@h^oG1F(IY36R9F;y+o0srqLvbToiTz|7oEM@Z^&d=kE zk9KLb@WwrULXQzNDf?Ijnfj&R?J8l%(4)T}CN7)4N^-`x=Tza@PuKI+&vBw8znGS z7%X%4Tt)jWxZ8DRh-ws(bNtg2uXicJ!;Nb5tbALC1}~YkkQHIy4N!u+Df%v&K+X9@_fD; zO~;e&Ta}g*pC9EB`shN9Z;t;vi|ecA4tef((fv3#FR86}+uufD(4Rl*;eHr_#r}{cx=XEDG)g<$~>PY~AxEvoRpU z-aV#Tpinf&L7tdKSy;JX@PuMGCQ9IB5FqFa3tYHDgAo;Y3`B~t5r__VSJ3Z<;(&qx ze`4o->U2No2<++O{s6XRL5ZlMgB~$#!XOC)J1ZQn37?A|I(Qh99dIK?W0*tXiVn)= zkR%W+D1f7o4oU}QLEWG>4(6|@jKO#dqbplSKDZaF8=ygqy3j^PqkK6|7fp{q_Z-)6 zFpC7if|+~!Gf|7i^amAhFeEq`GzA6*F`m1agcAWENoWm70FW4p;TUCtd%?FjSs-tq z&tEhNeQ=yX0PBK^A(9}1K;7WjrpqfZ@x%cf^vZF~1_XPU`!U8 zvlUbf5(c}XQI1+VC=@MzP%)S`=BRA$o+?l=s^w65KL%lLJ|JY&$wA1dlULR)1qu5t zN=AhorE=^VgPg&-QRVfhmal4ijKe-_I-g={29gIw4W!XC zI204U4z6F4?mVqBRk|qGWC)JrjIibV6w)7l)gH1_zq%sribBl zhUj)WrBC>Rj5MiG4qg;&Zu@i0oSaQ89gU)Cc-jx@dX}9RUpL{L8+x}ZzW4Ky-eYGJht+=i zn4);@>gqiWT@U;}E!18@Rm%xko&MBp*eb>^`yZ!~zUDpi4B3+@xKRDRCBbMp^PzyM zA)4hUlvVE_CQgW&oz9$U+G3gQ%4><8yUDR5_sp;5K_)G_3k|b|*svl5S68!3bM6^r z%q*mj;I$eOF`WYaAw6~yDqnahVln%|@X#$52fsdEx$)hdJ%Mbksl&FfJ#g_!o~HP~ zX1{swHOp6Xlid1trG9?7kZnDWyriHxujT=pCLVs?fEXCaT}UMM<`4wGA)Rly!Ih-) z*dJ+xCDEZ;PB*mZm{d4<(M!JbfL9)0fjxMWaP-z_Ij}#F${VNa9buPlQ%ohtaUXd! zHc#9nXlz#U3XZ$K#L%{c$}6eTSjV(zA+nbevXVv)^+5@Rwe@}IgY}(5RWAhF`b*O_ z)~eDgq!~jjI@s5nD7OvPy8g10e?TG5Pj?i(YDbRQoXam&6;sD+BrShuCNW&irZ*EB zWb&O{Q!cr#@#~Op{#BGkhl^W&JK$E64CpVhy>88GB?i+-t|2>F19*?xGLLpO_D8cP@z?b#4ZtR;axf_ z*{)g7@v|K<#F{GARrPS200k;a}h&g7)Rhljf78q)2^3~@q&w^#!t$y&L$u5YzLPXkBX4hAuvx$SY37Uo!ySXBUrmp84v(2*xkGJ>`B5!$k%n)?4kEmpIlhq~ zbQNW!XO*6J^u7eOhVX93;e>^^crsPw$*J19ORMWio>fVyX7$&zXERlo5ke7djMsq_ zX%Bttz4f}C6&DJX`d9AM7GnGoYslK;f*J4H>TlfBxGY?o}e~z@7!mu+g zSBO^g3zjaR7d}?{1#i&`BNYQr1(8f!6z@h7JB8w3`xmy}GWcn}RpJn}i_}`#R`p%+ zGkO%1G)68rIX}Bs~Xe1lXq(K2V8eN3EuC~Uaqv8M_-~W)A9^zA@r*#)66UF zM^q@8+xm+s5p!Jb?-VOp9n+ii+l3Tv!O%~HY&`KGg3yfeb#S&NKHc&mvM9k>ev2j> zN`rY84;zW_l`3;STd%1pdC9j)y0P<3vH6EMievl@5#@nQwLKIs4M()_FBob_yF_l& zNYOY~f^O1Eb939?nLJo`xb%cUMQ59COY(6m>HF{2B zTH#dJ;_g-Z6#4qD@fimviuz!_|YE z%`%6sjIOL+mJ}bb&^T|)wLIp?r3K$!(8NcwUMejgcW0H+h@^=1(ln9knCGJA%ORHY z2dMjoCIniDQh4#MvI?rdJw>Oqfa+SupC)~^uXPAfd-i$;M~xQ#(f!V;1ss8L<7{zi z>Cxh}3xsFPSdFc7S4PwgGj+2iEZ7;Ew5|LF8>;k-;$AD!z7`uM#N43_MDV0K{3D@8 z1owQ#Jf<5Y%ub<~3MjG+u{7M(Ktu;qD)c=pOH;;$<|KERKvlufBjeQGa zU(+N+md3uOv4v2!WD7}IQq7E|u{IOsPNDaQ_WqGDFPYA^aM zc?faK4NCkk-Uolj%P@+9xM3yx}@z`trWdapmUH*-tUGMK#@@w4a?f zyn3Tz@39xUe!W3WfZhcqKEv*Zn6F%Vr{}i&br(+dpG}%8*g) z6DaBw?gF*@`r`RCaycii8^7fug@EXJ$>FFZGnrsYF)^;B`nKO!qB8C2jd?2GY{5)6 z{0p`}c}m16D(OeZ344U-P2RK45FxFjH(WZ$J?~;Pd6tOWoH$B`Uq7$Dl=T;s(lKw< zHpNPkJX1wAwR22JR}ymB|P6EJTw-Bm-<5-bPcN>{Xrf8aS;Y zQ$WA#cF4;;>E!UC&rK419OLmEG^QToPRE%qaIu+a*C<4qx+~6=>vzT03rQ##r6G~= zVq`=Mhaw@!WeUkK4l#~Xw=PItIc=TYtQJYfiBL$kNQ$#fN+GuiW*X!66!n0T00W); z9ozYRd2{p7Ggb-|npEE_{0I((@x|}#*l;rnY5KbV$!deta~jI+sm;2Mpvh!hvW;-j zXyV|$z^%PW=2Jlq-F6?R0qm;Q#dk}tWdJ`%p=hf zG&|-CX4Z^^t~!V;panTf@bkd+z6ecT5KZD)XG%&Vqe@EI61IZQ!xFB3PO6L?X#>(9 zk06db3MV1R2j4&t4$;JjvNu8m{gAj-j_`pF)cUAg{2^~`3Fb0`KKSyU%+ z_L{-jM$fa?+XE@2vFb}~Bm9IE3SrXFXAiV2)K+hHJwBgI~k6H%x~C(^L~bs|ADY!<@X zcB90fK;Y+~UvR?0O))f5@#yQkFay#UH&%qBCO%h;PH?SPMV6nq zmmSWM;)Rz(>g%`-d@EL~ghPrjI~L1Kx8g84h`Fy)q=cXhPpN!@sA6cT+$PDzdPTWK z;z3_jBN<&m5b}4(X&OJ5i@+POZ~CA?!@1A1YT;HmzQ&t2&qbg@`5d z_3jFeExG)Nbcw27gF)fx)B?O;RY7%C_;A&QU3$sY0x`ZQaLZ6C?lDJzK>@UZ@XoGk zL0!(dj`uu;dw*T6BnrJ(pR`cvQMP~^_|hH~^C>TzL# zI*eDHVgrS*TfLS^P$y}`zrjhePdwnD90fGR5VSSIHzdE|i9GV<4v)nGf!CK`T16PW zN+oQrlM-3vn;GJ5C-bjRNuxu&A2{o3c@T52Mr&SVzJu7z=41MhHZ)YiAUmgA&jW-546E<-@i04LbO^J#;VoV|U*GcuT`3oj+`-Z~qg>HK?MO>uu zek8Y;4c|=eh>X%`jtOf%`n#D?BWf_k9pHC)ubtzK*4Ae~QJEe5*eRay)rmTUd~>*8 zklo6iV6Qg$p?#_!PZmIey@Z7k?2Nted~S5>UV+~U8-Jojh3)G&3n%emk-WTu@oba@ zQr}6><;_507jJXflf*wzkRkQ*j(Qml(ln32mmwbX0UVavuCU0D<(xbDfiO3LU%c6s zEx_AIMJNu4Cmkcnz?Hj^a!#3G>JjN7?l1}l5ZeQ6bUl`!MovfQ_)S#QR$s1E`fbIpF7qoSLVaAs3{SKS2B zQCw_J157844)Hfr*DXZ}7O{!HIO~?Csu@PTDQ#t_RSsb(ig*KA_nwT*)A`z>c;B;$ zG;RJdWZidUT^of|G;sfXrqs77RI|lFrD&}Z|`>z>!J@$SuYSdcWDs`KKJvPPtk-QEo zhupSTt73C4F7RvnqUy<{FGl@KF8$5L{jZG%?j#OabmFlK#7%zff0RkTCkI!JS}JH* zES0aKt`hC{P~=lzBAaV6sw9`H_L%ZWY4zwMi;}*}ANydx*^Dh;gg+6)i|B=u3^cdE zVC}Z>2w0M})+E^t^f-E7QezXisU+v(CvL^t94iseNds(sC$}8eS<2+MmPS zMImiid1UE3qPc!_|1i&{_1%GWL)h4)9Pds-)Q~!#wIj^#YEv7?rfLoM-e!-#k015rtaFaQ5ZJz#uu-&xNQsl-t3cg zG8`T>ivI?gbYrTzal2acmEIx>uOp>(xr4ZLka)qUv3F~ube2@n5U&n756{Bz^Lc1f zd0TTZSP~yX#rDhuu$Wa7GTaDsEXbs$pZy7S4dEZ^noVK>Tc<@`&c+qz4N!J{Yz@5Rm$mXfLhwF$K zHdePo(rnmMnSSrY!aA=bL>byTWC|;@0Q>MfTkJku=SNzy%arRU8Q6)LD88O!#PtplET15SaPETv! zE*+B>rScUpi3wCk*&&|BI_@J>Bq&Nj*o0KY{*)(A{N(eglldv{+NXJ+h1rPt394|g zu*%4)SCH6+MX8sI2=Z!4VSdBOg&+zcflPRL{#F0YSJ*}DmT(fPSta)T+wLHb#9Pjv z&65R(1C#%rJaK*w(=msTU+>)hohkD!|Bee!T_i5YQ%<0~rh`wL%=J@R@G%9~GeqcO zM{kq;w#ffBVVmG-%3I0+AE^`FXHC+f2VzY39Q*6Rd@*}oa%ejZ6TN_;H(*Il4mo@G zN(A`|?i^37mnyh5ZbsGKa9yg9K`3>6U-1{GR5IFu_CVYfRyn)7F1aL0#ApFbnhTQxAfoKM&x3}cmw z@M$5}I+~x~=JTQb^%hEQ`Zw z-e662+_}x*#&m3^3t}D;zoBV$of|9-u3Mcv@0#wP?{jHK_b;2pu+=f0+Wjx@p7Z(< z@uL0cDo)0GIcnz4kx_ZJ_fPu?N!QGI8gq&VZ>9b>OSOPPH^*ps>->>M{CaEad58GP z4;f^mjp;JdQ$xJzc3g-=RPPERCq#%Ar}L;`efQD{Hu~X(sNBlwta2<#F_|^{bxMlq zx;Q2JJxD^O^srHsJU>6-*HBuy&V5`pYo?>3J1uTT^^B*L5cO^&zriK>iZ_p(w3^;r zi@ZcQingm%eD9G$UXLeX=pompx^Gutsj2zSID-KB8+222Et2gZNLM;5OwSxaJmfOu z(X^S|;W2Rw#PgbO5=W(MwyNZWBQL#wI61s;;N6o<7XPkQMZqa`C;3vIvP9Q1RS{$T zYgEB=dZjEI6jSoOquPg8&V4KyOIs(aLJT5~7Jc3Oct?D61;3iAvs+%nF$-QqjladO z@n>6%hWlI2DgFoV|DcKVZ!KT5OBe9bmyMW;Wt!vPMtEl$hf*6V^pI%kY4WxmE=@VZ z{<>N|her1{`^3IXaewZdZ(o}~k$Ql9N*@_Q3BwM2DGDh?OLF zBy&x)_I}yeOdFdPo!7#2*R6#?lI{hH_(FrbWLEKdWT--L6P8?F;PB(=xb3qjs41mS!cCrQT5O5zm<)VQ77dWam=_M(#vNQ<;~Mj zE1RXi-xebT%J0P;(D>u|_?goN=9ehn+1wo+x*O6Lo}Srr93?8=NyO3nR6l5AJw3XI zu$vHvkDGD|iIzMC^;rV50a$_Y;P9c$)yY4lg69>IjV7awk)9c`eXv5`Cx;eBBS*2G zd)fl^%_T>MQn!Skk<=?G-nH;a?`B*QhKyi)bvQU~-%gS<*)&WVMo3A?q%Y=df%P0j zxW2%Pq9?;tL}B<<5iEA`91>V(qPSV2Z=pkkEpE_dKepqt%OvHR334qnB$kVt!9 z8NSc()w6_I1*U6&;3;y4MwI|E$G4Ywq!KIfjJ^d?WROnPQAIV$Jf0q<0s^SJO1pAI zM?GirZ%iu9nhd3B5?7hTn@K$UnzS@C_H-mi0dM$*lC}G0c!nsxq9pv$m^3MC~(gV`vg zzDiUz9jhC(`}UY9IGoCL7@w(Cbg&dzPQmjGZ#QXCDpyF^Q;STcN+edx`60+(e{~l! zPYw&A$P1qCwdfCjo90yPFTzVnb~hp++oR|h9LddwRF^ifC@+3TRc7<5h#itJ=o)C!-ZSx}GV^AFt!Lya{`%*$y%4-5k=B^{TS(prAWcv;WHm-<9Jjc*C&H8f96X=>YXU;xf%5QA(yXci( z(-9)fl)4mewJ!U_S=aCYE`u?xm;jBOH}7%Rb`H-+?r_(CJzo zmlpEJ&ZCd#UY&}J62 znar-YJ{SK`GrRfrEH}wruS?$6abg*FskJR_{-DaAvpeGa?rynzAp1~TfXojMACbRN znMaM*%bkqtt?F5&uup2PH>*V5wb~t>chP9Cy8C#a``zgLrnbFWvE%)Fa0d(S7zJsc z86VhZb+G7ZTaaG!_=CvQgT=3n_H7*}yd7^E+m==((jp%pr ziX)yDX2$RD-BgyZP1Qa2x?jPf9l>BOe@cB_mzlWJqbKQ26B4vNjA-A(kH%0dwycQm z%}5v>cKfb=^y|k7o3oE^5DvArJ(rTp5YyL~G8Z7no>eR;!Do>oqP{rH3x|2No&LMO zU8ViA)GMjmE$OxES5=1?_!!CkRo53fLe53*xaV=-&T7%|r1W!^IEwEwREfBjFAR?q zS)uFn@9N%qe58!a$xXZi6M;EkU57Z)HeK&|8YY_^o2bRoMq%eL2t%m&+4_y~-5Y)8 zCuS4h*1n7HJhXY?u+q^jfIV^xwtk5}`9|Vk9kRiqV{{^>RIsZh8J|9MxBA1N{&K2* zRl}9(YhNcm9sa&0Q8jF;q~dD9cL$9Jaalf^wtY7Fpi$>QX~Zv z;+>J^sS-1Ryc(miMHl=2JvyQ7nDzH%n{QZ>?j-GPxicSW>Ul3xBGG2>LkLMuD`b^I>mhQKcTf`YG4~E<_ z7ByuRiM0;SxPi4{IOrqiDGU?~s}V()LQt{@V!=Z3452hA$*45cs%RZUI0}W(432)h z8%eajKa-AyoAjb1qMBdi-H85e z=wH6!O`btRz@3EF#-MV?Lm^xVa)>sID>R1A%@$N=q0{N;cX-5+hO#Kci;?V6bd($i z5h*cd(o^|ZEGcS|J_%XKV=ZEhhJ}#(Vls!gUiW$84(b2b& zh09_IRN8%4#AlV!k(MFiYZel0V8me>PT>hzcpfgktbtQWNt_+iPRN2&-$A5|Imk>B zfY)>Hd&eJaJQtS)G1^%;oRLOhtYYYT%u1$)G2fgi~05SZ0LPt5<_2lOeb=jks-I;-`(cE?a)%f3#lTgWvnKNuI7v8yvI=JObv0m^%&|i z3s1n?d7m5Ez2c_y6-}ZJis&W)~(9ej{1wxkKpZ6?~Eb^?%%%I;VThQn`9PkDE7(-yWTBtp;7gaI5HzIzB@ZaMA3U0T(ZMr2n2w=m5@|+-mP6~-k477h>MQj~ zEThvY+^q%qM&C24bjg^gQJ)m|$+&H1!gO5lF3yI`ZVs#V;?7ho-B)_Vs6|iqC;VuW zD}s$utD`@tq8UnH{O7QK1tOaZu*Phxe}~~oskYbQj(*9`0gsy-1N2`Ve0twF%Z~N* zL#f-ZZzl)FG9NAz_qx!P#o@cng0``YTXo~ZEzAfG3O}dt@Dp*cZX~t0qnHa3B4Hzp z(JJBSRTPbQmnE7fmC9OXaFTtHDI&JuVek=&s?LnT*BMEsCy#CSFz2GvFS4dZ=re8x zZ(VcFIpw^4&6?wrSYFs5eLwRPY1?U`mn_x`?cm+!hp=)}%x!T-D7w$!Q-Pd9($1&6 zYE=$%pEAsi5ofmGZ_6S*^Yy}G#YLR@v|{CEF=`@#v)Q8;)D1&DGrtPfeghMtR z9=IrijY)nTs-~`MlJzqx<4@1)hNgf^@A(&L>y`=xL+$VXx?!{|K#!2aN0rRDz7za8 z&59=MjX5xraJ|`0!{6t_j=OtrC0d!?Pnl6UFP2a*hC942OQMc<#=xk6r5bhPIH6#b zp(ZX8f|H@5dP-T`B(yxmk4c@&b_xz~^<@q`-=U8-I99+aEWkgcE8tVaNIw0)gHNIg zXL%7LeY&AI+i!}B2qLK57vJcCJSI**=sOX5NYegWpOws6727zqfg?^*r~(EbD@lKf z!4XC-;6jUUVJfFWG!p0H=?FhUKZ&EWU*sp=l#Q#%&zO3jW`flT_JF#-^jpC#QLj>d z+dnwR%8MYAqSW2y$5|a*coyn>!G|;F_;JzXjLtCRECWL&N%N^|$ewH_sq1u*dWn!AvMS;)CuVn{&rkNq z!zY7hJtVsKvArjqS9IQFUZ5Y2m>iOmiPqXb?490QO_5Y!Qj;;%SNy%AoN9)!PiaLZ zTAp31%SAWHomRw8UrBJR%vDFC=+(@CQ*V4+8|5n!I6?&|IdL>joKBmQx9*A1PS|jf zO5Z}oq~y@+jY}1)^FL0NmMHrjtWal8MXutaP&-c8+;R(!t8pnB;#q2u>KRU7P^5xY2?V8HNykLdmSqsR3!MJ3 z#g7%NA?3)g$_Lf^K2t8?RdY*Cvkoqf&GQs2e!gY2GZ$SiUvt@4`Ho+D&w4~^vw3O@&E**-MeuUP`YAmT}eD4*Sr^Uvt3I!}{zCwIB46JyH#6o@A)#VKL zMjRgPev%?iMex4ioL_M>aj}}1LvOw|pWc}5a%8z+Q2Wf)YrHLJZiE@6e^a_4zIZgg zaNn6AQu2lWhtLEOX%cH-py!}=Cs5YV+w!}?`gf!I@1}jfug4zI_u74Yv@RvGRpLV%%i6G1A-hHFhnahv|H-zd zBfmRU5;ac(m3m>JmG&(C!1Znqo9k9FKd3T^`t7UDX)aR9tw$!e zx$RJKyCZvSYR~x0KEvY?{(C>~dv;>w-KD>0jwiY?TM8OhW|jZ;ukL%p|98Rq){A>b zpWi!17J9e+M7*2G@wBssx5WBVH_pd*>vdlJ`}^K%ZoqNX_KkOr*1qD#BM2HRZnMCl zCZPocy~l?9I+J0!BgSTNhRPC95jC2tSLi+|%g4;LarU=4rLxIccznUnh9&C0(<0=c zvVETX!S~5kxhg{(vlD_FLcgg#Dz`hMz5o3;wI`L%mz=MJepes4Y#EC_`tFgk^;PWy zx$8YgYHaIuWM6!ISFbU8PRl;@n{DjOv#Zv_MaG6B5fcq@r4lbIYwSb}SAeW+>)znE z>Lo94@h9j!e)rUTwRrH4$=^S}etiA>d0R-VfpP2^pGeC~0*N0PV$XfQ`<(D%COo*a zlOgowDTh%wtT>f`&CeTS?6sVeI&tB3{-b?ME6ws58*VPkXKs3w>UmwIv+V^2Lp-#MxBd9UPA!^6v`LUnJAoR2dWHE?Ac*xfJB^bEbBw0g!Tp>Pjt!fuf?@CasC=9)+cIjNgFSW{&^sVYu7mE_qtE;MSs@Gh(`AhvWw1j9} zX?m8RQES(f_O!r_i{N%O_Ps&zF2%oZ!s-IQ^zA!!dsA4EORL$=@N2HPV7DejTjNvF z_?ur>8eZ^+?GLzZqNH_hMtw=+=KDv>n#E&XXQc{X-24!9eYCVtIpv3P{MB21@-;He zs}Fg#x{gabY&?K^We|Cjci-Om-G65?^6q@ewfDRw5!oxz_#1ucN{_3ORO#xW1*OcI zRP^WjWx3Y>jVEo_A#`q3xulORX{DbZx0$(f!1*Rx^Cello%gEA{z#<>F1lwMRM! zP9{3{v<${1jxXc2Zxtk#B(wNlQGb4a<{?I5)>5Nb z+h4gs->J>S){k!2SethE#de?nDk-jgH-6!$N$86|c5d5lw4XTor$}(swbyLQr!H)x zk=(4fP5x6?Lh8-xoUFvR)UPQviNTNkTIa1d66JHYj=v&%Oa3su!^cj120y0!vhSvx zmd$~(4^#Y|!9C)sp{Wh6{`_0=ZgZJM9Q61-cJ`O(#_}ru6W2HA<4(p|nmkiU7U;Sl zBqDEBQur=WSU3Pz)6%(3?+e@I$wY2j%T~ehq2&CJe(}K`_4Z$)PK9Gd{w$UEl6S2$ zmtU1HQ%Q2SGum1ine%7pmG-HMhs&RHWXfJmMPF*0*t9_H@{-|gzoe2^qH0@$-TS%g z-qkOO`#e6PI6vdI7>sdF20!uM^XX>%-GEPmOh3(WwT-%Gmj$%4i+}PMb^k2#R6iJU zpxaC9PT8HuO=$@q9ddH{^`+&ivLl}Al&v^y89cgs`j02u}JmKcJ-Zp){ibnH`VN3QTOOpAF0o6 zx*TMzvAXMV^+?mTrYjLgHN0P`kKTCHRC~BxWA|5pk9k6?td9=!4k|qjpZ}mfuRbK@ z-cozk>1y>uorjXo?~dMg4674cIcahO9ZYl*LaCcXilna~+@TD*t)1Cqj4e4NJd#<&*P1F%kQLZ>@VS zZ&$mQ=2PAuwLGaEdWr4zFnr(B%!_u{mHG}zz09rQeZXTV*l+&E|9Dnw>#rq`Yde)| zE*zN~Ql7tB67Vp3|1XuG_d9nS3rhW#^>|=LciX|!i-w%=jj^+5-gxHA%+4|xs`s}W zdY(MPrBm6UF=MrP`09x_p`~XhJMFg}u4rkc4bl#K%75K8+?mqIB|G*&taZ8B<>JBh zSt_%}JL9uy8i#a#4EWFdrI?G&XS&xLixzHpb8(N+kNuCd z#0zzAm1JAHygHuhT>R$S;`aR?OD^RUp6;KF75gsz#PRKTLE%T;J*+evpFNk`1WsPN z(f=#>rQ&k8@e5Vrt9K!o+lBjuu7A63_)vxCRpYCjXUSbE;^78dEu7^FT{Vek>(^a9 z(!C|qyKVJs$N60@a}wK{_m=&5K3ud@H(Gf5(cpJ$=D6Mz<#cr9rH9|R?~XsXVxM3a zKQX`YZtO?vZH5`D&nf0Ep$(cxmz_g1mTnw(`_$uq#Qk};*UhghCMeXun~(m%zI6YE zeF0Pia27x}K+UX8gaa!CEEs@PKo|l3154j)d@Yc&0N}u`H*nRk-v<>)FwzHwM?hBt z01cG3s=6+WfCIA&1Q}pZfRe$?I-q30kwNDX5M%%}0b2wR*&1vOC>fAtz?T6v1~@ek zWB`HzTn3aDP+fqS0X_zN*+2W*&&L5MJ8&=#h%?}@0Q&;s47f93%>dB?mDj>FiI0I}dCBp|8G@#4?Jp;H5`kOLyeb>k`Xi%DYpA6{Pq1Z$K$AB^eVjEz$ zko`_;tQnwZz?uPQ28~4kngO&8B}#y618W9&7rgAO z0O19M6o6&`mjTfRpc!yvJDhgGI0-OlfR6zz2Ba9!WPp!Bi51XcYfVW2f&o?r+%{wE z12AQPfB`!OtUQ2Y0A~Y-1%wxXZ!k^*KsIz*0c8f5H560;H~6VQnh*w<*7qdohd1=RtGi?5TT4A<$b z&)q;Dk}5Gdy8M$I%Gqks|DSF2XEd+=Cr4Y!vL^Bex4eE{-@LY<`d8?#W&J?e+BQ17 z@_z2&!j+5fbD{&>S3jQF6%dO|9Mm>heol6|Kl-Zw!j6}EQJff;Hy7r-XOEVy4nNs* z6e}7$#c*ubV?$RzO4>}LeAXHp{jU4VlfcQLdWJb>^92!*-T3>yw;|&D%o+4MfLn1<#v}2j>)? z*)PIxjuuX!qGi}sbEP=7&F9L*l%pM;NrTF3^op3zggfq@8TCb9MR_psRdzqu{S31Kk2jJNS4=HJ?qsTZsV!H z2|M1Jv!Bh{x*EgmZ>9EpGF7ETp->Hi*r+RChXqh}GlhAZ5+(K)Z?gZ=5pdFK$w+F4 z=>WQ8fclgCMB7Z`RJo014F20m+ZZB;*jmG{*uU+nFqA0iVxkV3qMA=RJv5Z3mSS;6(&Fy?3dl_%)>>Tjm*Laqn3vGLo7>Dosf9^F-yqvfEu@JRg_!rs2f;=(M+ zo8Ky34IxE7$g@~yI_#gv|4dE|okh*(|7B$vvCua3N@!6b-Ry-nHq!3aTnJlFkgu3M zlZhdHw&jeL>zN)A%Gx2@$5%_nWt^T+qBSiZ5J{X2YX z?wjXl*ZsGTnel1TRC^lH)RicebNw5*<7Cx(KVZ8wz1R0Jgc!a~OK**mT{%Q?&F(u1 zZ?2y(`b-v9#UPp#-J}>=81{xQZVR4HU@In1GpR#@+U9AlR5{`GES^ohU71gYm=aIO zzgKggv?tjhXc71w0*TGwc4gBIw+@<-#D%7uHW~4F`VQc8wX+j3((+J;rmA{V#;il0 zo9#M?dt}axvk0lTw-JEK7BLycERpzERM8XcEi1HG@%wVfT%5HoKbFnCSZ0PN2&rpX zr1KmIbkf|rg)!ws=2xXF^U~>rNuG2kCa>qhJwaQ+k7N-^JTZUN5=nd|g^Ryv!P-KC zBBp%Y_>A}m7Msqec&Nf0&qMIHPAc9(ex5{c{_D#|4WV3+1vsR64ls$Q2+JDym6`nSG~g)ADQYw(R+#^JKk-9_@*9axMO2vo8#y}_tNdA(TQ zYfQ*>L^2!8F#`7_Ue>iUd^_m;RD6wNpQAs|S28*4okQ6BN6EB@=TJU2G_LzD`)7pY zY^8ghey2EBu|sv`3B$IUq$ihOpK`hW`_du(oEvGro!aFCcDvl}?o6U9L~+G`urN|5 zMbTf84_|S$a(TmEf20l#Cmy| z3iQ!fGgqQ^M7v!UZdR8vyMJKQwaIE7cb(!dPd=sEKkrj+zR6>Hy4qqN$-UEVC#q*Y z-=whSgkq*Ty>u{MH!$bB{GE0JBhrqEqVxWo^`&?gm`X0yu?T_wGtYDHXm)KHB$jvR zm{KgZ<`*)3+{rwH+|J)@BVCX#xn-)!nuH9^B zk=1yORNZFc*yB$lB4qCh%6mO(T`6waSZ;B^miA{f<=cFxy4tm>Z$H?7R|aqUJg7fK zj8l?3)zfEUs+}`8aW+qImSyYhFLXln^`O}oWj&{BW)F)=ni&@Ndc$!7!8m3q_o+vD z2b2X&>(zzq1ZQ)R-dSbCpZB$EMs8uJqjUGnyh?8|P&|45{;@`H%M|i1g-}QPfDO-2 z@h%3Pr_{f7;VRwX{{8XL&aNoS#%JPbiaK|-{B*7JrQT&3?Ye^R zeTLesV8wEgqW8)>s@+PUt5@1(wJL$n#ii%6%FmovljN&#`BE76Sn;t3s@bvpO3pnk z#cL>4{N8g9BGTie)IKY-TlQ#wK0NXJh4sxC8)EwBW9t;j|2x}CL!|)|v-w}y7BVSB zC&;sq8KHm?Ab!B#ft82JR!F!ImjLL8gxl110D5X5PeIZFXdVJA#0Q|&0aAy|d!Zr( zk_ZG4NFp%wdaf)uInCQ;r!{m8K|qG63psZ!Oz8sYzrZGE!aY;g=`D83Q$D=*%s0wgjtBRYk3yJEaYNHwGf1% z9RboVq*rK7fK&_Bpb%*x*g|rLgbSGwQY}PU$g_|-_eaFQLjh7Pv?f4(f`^ywTCj!g zgtbTu@f=buBwUDfP-6f+L=bGD(E+lpp^+8T3_%iyU<>gUQticxOHiBup?fXWLcE1~ zBZ#z+;vv;Sl7+ksi5RjiWOInIkY^#uLhZpnB?s<75JI8V;GaC}>ATh_1ep|)ETmV6 zt`KG+nZ_p^hX4y53{a2&^#)L51W6V$ECgHVIe-8Qx%l;b3iKSnR2~!wLAqb70EIjY z6`&Alq2a*LX%CF#LAHh53dIIcbpVkT8igRzLRyEOBdB(OR0|7vkZ>W@LUjQYBtW)> zEDYIJ*UAOLEM!>7v(WIl7HJ{OLVE$kSglP)YmpWnWH65hr9xY5+@SXgdJ8OV&7fBZ z-fB?wxt4QFDnlUW!ov&VEiB%_YwTZ@2EJuXI4-ZXdXoM#3q8}FB)VC>r?Ot|UN-sv zE!+OD+Mxe?wpI7(YlPY$+R-;@c1>@dRC_dpK8JR8_wvS=)Rm%zvIq5nkN>lKInf*? zvh}9NqwvYrxUXy3HvRDGe`YVIyIE@03KIJNvkKkTc;KE~_FLx{12-DpR^~5i?UqV- zJvUhCQnUMceWUHD^;Krj_SWm4CX94HKYftDW&Y)VW-r@X*0Sxxwi{pnnZ3N=*nac- zhp~pRmk-+SYr!tK*fx{5ve+~&~b`(OaD;D&`rUgVIS=y7qAN~ zv*)c((@1ip&ZFP0{y)?PMLuws?a_hSp!k)Q*p5;|?hTExyv|$S4%tLnO&_+}x+I@z zTQmC2$K|u@AshF%dAh|m>i5gx!LVUzteLByc4iN{Zo_!^OVK?Kqj_B4p4(sJaItIK zwDGwYB8yh%&Xz}S4OXi-BvxDWQsu%kb~UQ*ef9La_6^e`TWn48UaR`O5Nts7`$>(D zoOyrFl^b}SHi7OJP!`ZT*bW72ff{HiT>;&J*Ebwbo=zSI;Q&PdAA-+6SPQ5XjAufh2`CPn zR^XEljnbf}15Xp-v=VpJ{Rm?hNB}gw=^GkDrwS-0$T4^i%!{wt51eAw>Uy9~2Yd*e z;Gh0z-{3U|`mg|rnOSoq zupDrv|9TRfU%++1iolbg%xBGwz>2_-K$QP`ds(}>{M(Aaht|$4;6vaUp!MKJU@&WL z1U>=Rm8RAM;6~s>YYqgq4fX@&KmRqJwYgU~r+__x<-j2Yd<&cv7GWoa z&I0=Z6oSAG`;QXYI5Cw;DLAfc=0Efdhf@teFs)7T6Cs92EP2&9B{6z<$7l zz<%KT0`{|ZLV*ofNEL8n0ULm6RyglKt2HDExSxRWfa`$wfbl>F9@q@rOdxQ8Q9(lv z+(2|KoWOp-Y`~4cLcqGfY`|%tLI>OhB1ptR7ceupzrhIwTn7>f6z@QtG?)#z3uGF& zpFn>O*bMm17TcZRG~hQ-Ee&P^c?H^X*3Kp{z6v%2w-;z3U$YswnIt}#0=Ev2a)EhO z=*EFfX*i*PyJ+c|fxE!j1m@l0egXw`;4a%d_x;OS{#_WoW-X<6GQ_3d_xIM9K_lJ& zFKaOiGyR{l$v@U|n%rLN+np|LfBo`!L-2pC_ImAX0@gCfG0#|ARQ|_W9^7pDFj^O|b~c%4Ir!nlgVyHHYu4f&ayfg>N_nH! zLfmTv)kQ4eFmD_hAk|_X?2fbOMq~l&{xId!`t#o8;Ae*&%c9*vQu283lD`{x?nvzw zHNSsr>dVFYKWAu0f&~02#CuZ>(nV`+r24atneUrw9O(&ukkZ=wzKPnwB~SEaa%;`b z&DzP{eZ3yrO!}E?#I@b?_0Ck}6OJq`1(UoefVRoiF3-jz&4 zL|F!J&ljA-=blfz?q-&ZU}*@Rp{(wjx_`0zRGGBfJ`zLScGr4d9!*jQeCN-ZyOi7{ zkz2{1!*iP3<2`n}Rn6hMbQ~i5g4%VIGm_wvXU;{)t+l!ss^NgDq?n(&EgJT*zE`>C zF}yvBC|>t`k;YUJ4_&lmKe z`(CKGbLQre;KklE2iDKC2@+|rBb)nCJ5c$AhH_yLnqE<~aYs<~jZH7T-kytpquJVp-43c~XNnnvO94Ce6mKa1M%99WC= zAiW@UprDY_p|K1E733C_7{qeJ#;ss1Ab6n4AdMiaAiZEXaQ22vGe|p#H{^5Z0L{$t zh2t~`6%>X-ttWJwf_Q^SL(c!F@J#m~6$eEGi3O1cQ3Q8_tPWZZ3JPipVIG7QYWYEZ zK{cTj6twWs<3SMS3m5l+?(PeY02=|ffx|gyAsl)Q3@!iZEgMM$;e@OUVh`^NcsjwE z9JKcGl`GJ81_B9{pm24j(A+T9wQ77o%Nw4m-F>Y(~i=HJ%V z3J(nsY|vL|F9XR3kp>5b#~s|clT%pmWN=T-hbDh`-+|;q6)6ZUh%~4*xD7lFKy?49 zJ>`@Hh0^q_T)?44Bs2;}vO$T#fk7-mQ$f+elR@%f1{>Z8P=p3ubnr}o=KySD zgD}Gv5#aV<`=*vucmhCs89W%F_8-(59xrhDh6Yklaqxdo^vewqAoegN051Y~^?-H2 ziZ%%O+Hy9iI4C;EIXoW$`Wvih3jvlZ;mYdU42RkmlV zjmLcrA}Yq!TVdHK^Si??=g!CIaIg*h>;uH%XJJg9f=yvHmA0n?A{%Riy~$Jy)qxEg zqpm7i(J60V%KB-?W^dM@tEgDi1ZA||6ew^xN>FjXO%xANyLi??_WHsBp1uFw2ym33_%Wzku^w!f zEk7w#iNSZS&+W>pT85P{b0i7$I=t!G{Vkp4QjwJ*XT*;7NQj+^R@olwd~%rJ8A%Kf@ zkb6kB&QQmBgmevsIA-RgAP9Zc_dS1KNMF?@Wv+$0%DU7k3$)V=XZ1{wx2H*(Sr-qBakQ8fukQ$m`2uVrs|zFvFi=_Dy{ z@vgK`Ph%ez2767t1XqQZ#!P%VthQivoHte5mu1F2+#Mx%jmi{?(3h&Ta-iXq$R;Gh z{qtBg^SoW@Rn+T;pAnFf>|O7xsv>;1*LV^Y!!U*<*R8b}i3J8Xv4t{J+y2*Xs95ip@Hfura2c*3sAldC?U{>>W7!II=KC+}D&F z*@pLJa>)@nsa#=bx;06HmD3|D;z{Sqb3$I%4Ib5BHmwz0;8vZK!{%`cLroSi%ET%7 zPn}d;N3zI*zu>;O5oC5Ko%aoy3lqg$UoeE_vSE@fX&BSp(`hl~0kXFjSQ7G!X*+x| z)`lOa*R93|2yOl&FZxpagdws(*x%MA_=|-#feDBGnHcF;aVeeEad$Ky5oLsexkD4W z@u34|lD_q6B7tmPan%#t8#}nTuyQEI>L zUt6r-Qc8IX#=1(w{n1)Ly?Jpg?YgZXVcnK{?B^$CiPFknWmO-7kcsakL4x5%SAC?I20=pmjx zgYLYj75{&ccIW?4|Np=EAM>1jjPV@%T4P_+AZ2gHPH0Gy=rxu?q#>bF&DceZE$tzq z)o776jU{_ES|n6RC2d3d>O5ZW_xJNXmvcEkp8kZ2xjnev?l&?}=&8cv8r&8ff72a< z0L?J2hjj>tBuG;@GFiR=^rgASb@9nZb@LVwxbwPYS@#$(?f>~nNMhOPi4K3hxbQFT z!mYo5wlLtaIyPkoM}T{QF;*4O=Y&`RQzAe$j|rRt1WsIIrT1f=22m^-lZy98-h@Vb zH+nocH1hc*5aYkKe9MTm?8ITyJc@8gjtxJLtR^C3r!fjBm4)@#u23SZ!2=;TonXZE z*+25IeyKj}tbl++dTp~6TwtO477)PM;6*HqTnhqv;BCDsAznjOjJ%u86$J9hfsDL1 z9Ji3H>dff*PB=Rdei-N}8x%g>=Q6;_9~~!XycEmIW2(&g+I1HRaRFd}SEO3#?=34J zMTaeklOcl6 zlxEQLo^{DoXuYJP9^1B&EipaLRC2wA3?>+l^`qFwQ?PU8sTq%A%Rq%W-gw5pjKZ&@ zbe`hi#fSB3vf)r(_Csh#H`sDf73g(=%ig5;G;g^whMm%cK?mYrge=X{~`ypH%X zNo=iNq8sd3Ei-G=c2wxWkM{Uwf(g!Kc5RaX`17*d^VW@v2s-%#ou&b zA0va&%*v_`6%4OqbeK19KPtOf-E&kAA+(6e2|QqP;OU3v@2gLjO$hgu)4@aOIx7g}YuYkrS^oIyQX=!-!rg%f+(uoE61fTycnt&JU33 zm2;7j!a9L0f7Zhr2DYkabEgbEwwHDLeZ636pu~B$z+O*>@6ajmv{2<^2>17rj2>bB zSs*s=O0SvKsv}x82xR`YBWE`$1yRL2k9_fa?P*NBr!;64@~97&!3hUgdS(^aYD~;M%I0v7^%6FKmYj_D4S8(sEh-* z%=rKWB)bH>`he9v)V56!`p>V?k6X0z0zdws;Qq{X?}oR1GDTk43H-JyQtmhb$K}7x z=B-A+dJ%2zvd>-OF2LI}LfkE{%_TMPsWE($dcl*_&Hso9>sjEgA!-sWe~ziKc_IZ* zPu*&WZd#sI`=27*0IE zM8hQOH0U%dctX$sH9U}E8j}(goU^e9Z5F1;_N2&;<38tLm}@X{Rcwqf%`Qzb(Gcki z*U@31TZ7Uzr=)3}Oyf3ZYGAVUBbl@btPBHepEm$I-M8Z=0x3A)!UQzFbAEG-m2`VZ z3K2US5QmT z>wTSiXHEPbdD;(mjGitn6VUQwm;pS>0Uol!g)T&mo@N!&a;+9uWh+VWFWJ}*Y2gt) zkSoEjWS|4nh0P=o$05G&$ry$c*M{g*BlLO8f;ef2nJ35tIdL{<2QM3|P5PVSYjt_a zUn02uJsl@Cd}~C19D`!L(6G7Uer4fwZpqAWVY)mG*HmJkNL}lW7PiQ5jzM{O#ar_- zQ%PXE4Vpfk>+FfHwf1+P56*k~85|Br^MY0GjHfp}N}TgVL&qJEMC2D?1!H@T-;eT* zx#ZYxE>#;`uL6A{!w8;TH3z3_85b;uWSkEqp=Sm<;NhujCIszxL!3GCxr z1xN_4<9UkG1+7BLDh8>bd1XpfBFP7_g2GJ4w^_7Oa$3fX)7XYcX9Kajer0vhEA8lptrA@hWds`piEut`1= ze|$-$VPeJFe6!Fu6#(pyu+4*`Tu?Db+hF{AFvxM#l z`9UEi!G&_u6_qzZuP`vT;e{Q>!o6sXE~SF2esWob%r3EGGk0NpG$;dWk~nF$Ost#; zsRS}_%gPFg3ferN{5e{a1B#YvWIx7IIA)n9E=g+9fK{o0$^Jc`Tlss6UfLb4F;$7J z#(owB-C$4&pPY&r`rn8<)JP1$VaEZT$(wPE*s~CSuid6Bf3|N#D z1}2Pw$>WhuF|f=?hyJy`a{lKYA3Aq85wnd+GL$0UyfCvu%Iwbt<79=W5`qC^`Pj_4 z@zckC8=|XC1Oqc?B^29_>Wx1LxKN=rlYvX2ul=iN_)yB8Va+qO&1-1AlaK>_*6<>I1Ip%g!KiJrldQQ{+a3Y6Q{ zsr1|53|Vs>7mgT-uWt)Sw$C%O(*0X<54UWa!0tPvx>_XTKBF2gy>4J3`w!rLczAQ~ z+biD>-}-s|7S#fA>%RrkwN+TM-_9uA(-0f_%c%;))G;ybw;0uIlmA^_%P&_*Z&N+e zrhcPMbF6K_?>2^JyN*M9D)e z;V{IaiPIP${b|(&~rVr?b zIrKEzs|zetvlCTA=T~)?&~Hz4>lSHtmWK9R+^$#R(_<~fn6kQs{^~wAR4dIwIO*Lu zI+Dc1ePrnJH>#(H_cfgD8=}Kw8(G>zN}59A#xW(P1tY`)k>i{=c%zrl){ia0`Ce&x zl-SFh=#Lmc+Xi|yn)=Vi_tyHL_kMTcFpS96y#x%SwVF<`{3ho=dqteA4CS=LR>sVmU3@%6TMWRI>bi2yZyf1}{>JqS;uVKs& zzt&;z@`ov698`Z{m~uw2FwA5{bhwz62M^$NLF!)zu^I zE<++0wDl;klYmATU{szzTiRy5G_MrQ^h7orPam^_GGfCPfPkhYKasC!Aia zdWN)7HGzVXSY|ZIU+uF0<~t}|KTnqlw1sd39bYO*mVLP#=mE9}*#cy^k_hJc39Sv| zPqT2oEPMnPXU&{^wQ6z!+kdvqM45?Q!CxM+_C=)il-us9%VQc@qL*O_m)tiGbs zf&jvK>UNIY7ml-b*Q*5_y21Dq$NXi@zJ7Hc!5t60%wHrtV=2!&O~_$hRcF5znt*=i zEt7{@Nip4R^ILe3i9vViT$B(}_Azex-GEzz21YkZz!`UKd6 zP6!p=g$;Uv7rgZFpVoM$xBW++kvV8A;(Xb$;iaQ1(RLpIX@og>OVq?jDXSY z5s#*TMVCn%GW}*c{qmQLcWlt|S^xY*`uGTDyUW11!@Kc@x>cN^RrEnMu6~fkEVhAW zYGHu#$8l4^fy`>G=eEfUMT*auF@X%?&Kj0Q(?^4ejaUmrl>xL+=Wh(M%j(s7D5&HS zd!9yoej^RUa|>s9bk|AiF8`B?l|S3tV&elHy1VJXaLyu}+Nv886uc3%n9iqCz0-=K3qwp{ZQoE$F~)=quxpo_Y@y5<>D-d zkEi862TXQ;NO*ACLh{b99+k-}QU^{{fn0Zz878n zQs+|!TRqrYwO(z2_b6Pnfo`?tn&s#kCIH&b@LmOW31A)IXt&GS%Lj3t^(QcXWQAab zDkckLX<$RuSR`#E6EFhQjQBcy$I<|kDJlO6Wg+Pgbr{w2R%E(^_#1h=@s&j~M0Fz} zeWJJA6hq=k!?oM7S|@cL9f(@lzMvRg9|$Y<$~!#wQdKw5Pqb^|gTZi>p&7p+zW0#Z zudUoil{Q^^msAY3gR-ez)KDf6(2m$`|M~eq(u-9UTCa*0?OeJDEX4NdMIEuC@Q;x^ zjK2$=quTEtSJ)AnCJ@h?q)1FWs|K4IJf6f8*7FAu)@7eqijv09YYhocH65Lv-%OvF zI;CE{s*!d$Ci(rNn|p{0*Z)qNdwJ)$$MN-lc6@#Rbmy&SyTVP7FYgt&xkq>Kaj20@ zOE}*{hrvX!S0z#E5UzNb*HU#NZ6*g8AOeT-1E+0PDO~e}b zp4lp?x_3iQmhd+vd)D4mga zUTTaJ7Zc|vaGUC)crVPM8yCCZ>zSH75*b-5Js6Tdt;9z?0)*@#hr@o?j=vM@Rhx6d6YN2| zagT3xR)sbh z(A^I;WgyQ~J@ZR#%!BQR5mHTsHZda2IIk>Jo^Nnmk>8))5V~nYR_IXaSaz1XQFK|# zUB$52d0pooekqRkb0RO!&)AGMC!WL5js;D=+Vf{;tnNZ(Ng${>-lsl;o1RUWbW`ze zr&r%q)$z%;vsVM9OnlX?t2p#T*3R8VX&*#j;hVs!_kN^Yxg0x2_8RK|dD#5^yOe*q z{*aBWn5eEcmmC z=Pw_8`nG*reNyZCw~gISJKtYP{rK!7^GPLGS6iVrUa85S+*>%!n5b9Zq{yX-Fr>OX z&B?`r_kwX=r<``VJfCoYE4zh?-?fHC`gQh%nNZs`$|%5J&V++F*m#^S z*f;#Qy6jI4TQiCAlU~<(m_P4wmp5ZrUOwvl!m25u%+*E4;ZOJk+u+hyKH0G*0~qj1 zxV#{**UquC?U-g;$4`7>UcByv!LbZy8-XwQkp@W9rLE76rG~FG`rJRm4>zAzD+4yw zp!w5SThCg%-=B^ivf`QO&Y z@AlpK61k1%$J9=ufRSxp(?LK&xt3RifR2-7I8`ygUQ*|(gv5+3TJw-a=#_PMKDZHe zF3!@jfcCA^)-P%QgCif+D^rsOiNA(3NTYA=F8C(`u`~ie&W1Ivd@$GHY*nP~fi`Rq zj~pBo#aJdHC;(2j_F#vVOLaX$1fwQ{03d`d#9V`nk_ugoZc1(LXMii`%dUc}70i`ub&fZsCTh9!|k&V9l#N zgU5@}y;3`_elnm|obks9v*eBl)Vf=`pD4ErghiJs=2xAY&^%Bj5KUi>Qwu-q={4gC zepFQN|J4@$yv?NW?zR)=<*Um=P5k%HygGN%)kxtlrM@d+skXKaKR!|va#;r_*F9dp zTq$GSQLlLs746 zqq7P=Oo1~ke*Mfw#Ev}c{oe2$S*%XYk)^V{ny zruttxgXnqcubOWjpQUz^+@}`rJ9A=O^SY|GP1=0tzJk#4QEX&03k-$B+wiHUKJ43~$_sYy*8k6ew5NCk+sVaviQ5WBec+wGwRiWN z&yepKTVQp%WaWzC}n8Wjn@4sEiJGyQf^J zxET)>_>+4%DVORTH*Z=qI`X(HrTOyB%?YWaqt6McEw>#Lk}5~XUb|m8{5XEGYUB>x zTRWfa7<%fsq^xrNmmvcOU9FGrAMJehI^*%J`A4SGgl7AvM2|FE^4$gLD}Sc0oHMv7 zvnX*|?Z~s&nCLG@9!t0T{=P9aVbkUKH=(KYA2ellDh0p6c9vwdbSO*4>A< zzR+K|p#4cj4`s$8cPPYzdut_UuJqUcz3{P zRT;h9Wo;O{@>J@?FWx~%hc`dXTW($7z3pJgjklH+J8YVsOk61&3yq(*Z5{fZQvUeQ zdU`$Y>GswXt53T=rmnHNeuJ2L>Ppyq$IhffvAdJ|6g1XsnLF?xzcks>?dJQT@mRe{gKaB_Q^R)4<6bU=M)+%Yq)&t zh22|=9B#hpUb*!GE2-aa=5Lh-U6!0(?j-8JI<02+tL)a*xMj~So}A2V znp`J-vt1mf-uS%3?zjE&t5z4@zIA*s+Da>I{$P4wrr}zBUSVonQT@eM%o2ThAIF(f zCz*#FFW6t7=eCU$Tv4noYL>tC!{yc=7pK3URNg8yK3Gv-xvCY!i?wQx#^0|~RJ`{3 zqNC)xSmTJ3MtS?R#`1@e;_{2_g^><&IF~4FTiuF0`jo@{PuI+*md)3_xRyL3Qi<{-OXP<0vBS=8X3m|X?MCGb^c=*u z-m)k9ojX>sTn4UUFI~%)=~(&jvIS1gO0(@9YF{lb3K(-}GQCDlE?PR!qE>sl#){P^ zwAUJ2hI{DxO29HWe4XXvJa@HGJFwlaljT?2E|s~l{YP1b|7dYmqfb=3F3$Dq z3QzJt>lR$Ek4!fj@3AiMnl{_zwG}%zx#MGIcUZ`+)XaTW)XMBKucs^6>E*3Q-??ma z^^`r^+lcjiW9qtJ@5ZYRyCZs?_BT8;LR~5X`%I{wyUuz#`*_UAcpo>jz478^9ksXd zq4mnow=F}xa?jdWM%nCp&~#z!cAUe-cuhG>p+jl^?Iu@4SDzJ(TDNV5%gy86u9aUA zMz-D>@VE}I)4L9I2FlsTTXoegy{c(AqC3zYIM8=#fSK&`t#6?JT|fV@&t2S|J}T)y zy#d<)#+};#=?%c8UAQ<5r4Jm3g(TqnMp3*qLW!$&i-av|T~ z3$o#)Y**Lq{gnsddaP}3;L>D2xF_rLb{qR*q{rZ9x2{+?DQjOE?EO3m4$H!wS(mFD z;M6Q!m^HSxb??~(yOBob%Zw~-R&v%t76jV{5CU#Z-VUn_Z~_>v6>p45fYu4Ze5R!n z1UQh%K*R*464XW>UIEYqL6-zusZbt490Y|FG@}qW!s-B|Qjju1Ed?PG#7d`6pMgsC zpU8jv5Rm-9hA^~}P$WS&33(JWQ&2fUGj+1Q9=f4zJAxp6f^zD~gkYJSeQQ?=L{d=1 zLd^u76ofWVNZot93vLAG<`u#g>%TL{0q)Rx!deC#eT1?JY9?r%IBB^MI>C)V=$pKK zRzp&>y?Z1&jsv|CgiDFr0-=BuUEx7ARB<@!zigT_00B&UibU@JczzIXv+Gx092&E5fxBi!D!ui90JFZ)HK`pvEC=5~^ zXg#6gfnW#9ovYWbLYf(W{ubyr7VF^D_6ychh7 zJDIw@Wkz0`Vuc&19SAcr#S?a7|I-_Im&VqG!)WV3kMsR~dR3mXeHk&v8y?hBE8RmM za`qeN1$cyHkMMN5kE!fQI+xZirV(@$GuUF~whWAH*MD*6-dOyhtNm9R|H)jrlJIxM zoa9kc4mou|hTAwa`;6g_@+Rn3&7!n`lwOfTY9dulT^AW(11&>Kn6Tv4mFFn*E%my4|S;?1IxL6uI z40W?sUb21}^>TxxNVYmcn2Pvs6AJM+gE__6_k&NviE73YBNoD>lyT%;>-Mir=v|#j z2{S4^NcIgbQKqLcB{;j`R5c@m%9W7msRJ@5SE^hwUvWtMuIsxq}YpRzm+9-U^Nah}ie@{FNPHG~%2 zebffR8W@6XMZG94O=Zj@bEm-I%-Q3CHq{surOodDw(TZDtQ| z8eMZmvBE;EOygE%V+=?;4=T$^dB;`Be85)i-yfe8%|<0SjC%}ok?Tal=i8yrO#)A8 z;PzdoZ!uaODaj{d!XDhzYO^V=AbF8P#7JyCI;d{p``BOmcKYCe%629Ckc>X}HcLjt zh$c~!c?-dMBUU@GIP&i6=r%_-z_^-et6z>=8g)6$+J0Vju$esTBfLkTALA^csZ}aI zRJK?@xUV28cE(q@qP6VBmgs`}?VIqVOvN3td^dI+n*4;M3V2^xR<7XNTM@QGAde%3 zGhD}GE=k+Dd}h#d@(-qvqcvMd1A`1F$!u@x!#C`Eqgl4jy9x~@T4%163h&FlJmdcb z8-5S{M&168@T;a^3Vk*H&qC85%DtAR?Dts4U*|cOWOI+Jre^5JdjB$3Ql0SOqFO|O zg#|%X+8M!IaB?dfw}YWBNN+P;_tRK9!~wH`gN^npM~<-*@=ycJIEomrcAn=?qu*__yc}@+hCI@NeLgE0K85$$0d<`V z-Sze^RhJ>-ogE5}h#1CWq;b2XOxz_gz#H{oed~b+X*^zu%g5Pcp<*Fc2&rvp7c zCoL;`2R7P$Iw&bTxuo9f&ZdyEgQcZ)*nkVZt-N!KpCpsyND6-E%P%fAjqP0#ft39T z`*d{Zw}FG>WJW>qgT-^dS2>kjn7?;-bJP}+asOIX?D^&vy!j`e2In=Wj+HI>toP+o zkK-GiOw8)!%94XV8*mi|@0fi)k+uYlRqjNGY&w?{x5v0l>Xqhhl8wM!ZLog;za<#B zou_tuQpGrBOM;oLv6@={ZbHc z>~m-RrE5#q)@YYkqe`Xq^8v2W73w`iUefC51S{F&cf4G!OGN@#Ywep_q!o0_&@8=F z#<@3>o_24?_6~p5zCQD)(Hk|(qMixXaTtp0KK$=Josh+=JcA7J;0}gcNc39dYgSN} zL&mj6HhtVFbK%*{-^QD?RXvGKGt0kCs_6f*Ciz60_~iQ!M5sOp1~#uO=ovmydb*7{ z*zyY%m(6a{1`j3;yW@yuWOH! zXDtB#2HNAC)vXMDo^XubDDaI}*FF5iHE-$Vrp+C}9}35&H!edTcb>Pl6>$E^f>t}Qo&md7mi(cWEVA(F0T z0k%b3&z@)^u2*sTT9O_4mm2*uResrHB|!c5+>KGeyTwZwjrPmGOUjtdtsI!ZUyU;O z7L59392qy#+4E{;>CC~3PZuzT3uOjY`F%R1dl65-$==<3_tUXoHyHn4Ckmdi`=15z zE&qwl|E2LTCBkS2<1S2q|E2LT&cVP86CjLIP{+fJ2lFrt)iBikm&3#02faLuc`#bT z@(+yDFm=Nm2qQO)*)Wm9U_A3F@6@T&u%Zh2HcVxZr9<2e(;&>xcZYVt3<)bhP@}{C z5)|k#9KuBR-y#sC>oBRNrtOA79j4P`wK2E4QWhM+9(KN*4v9Hvkh z1!4SyVGmYRJ8ySbvV7nX7TBn1x!M9zJPhZMvBQ?v&y;r9DD4^C3ERUky+hs(Sv`z- z@CjhL$OcMzm@3blJqJBLEI7fI5xkz0khE%B%1-#QXui@6V=yG}P^`n|5=^;}&%+!G znK=xWFg(Mg3XMF>auB@3L@H|L!I%nzCB*x^eLZCdBVh`K4-FWt;iCiIYWeqyN>c}v z?64FBGbfxXhxr!18vcvrgR;t(xN@RmR>E#lOgslV^u~3wMJD)kf)6hEx`C{oKlBFXVc3F$A^+j%Za57N>vNFL!v_d_4Z$FN;Nam+ z2?18ieUh%<+0pmZ&Uamc%ZA>lYT?SAutWz9`{?N74b>N6oVH^7WemTAMXZU<7cy6D zb+Ph%9D5qFdV32O_@uJl<_BlO_uPNQUbhLhY+=6^hH5C^)9+5euATShboc%^DCJ=T zYSWn;osq|OdTh4a7sNWxUGZ`&r18yR74QuOA5;H#Y<2@cs?(vp7wY;enUQ_}o|5q`j!u|~Kd?1=<0fO zTkwDCwnZVU_OjPDab=1Gc0(Em_E(=>PJFH&+MPJv8H2ab{B2DC$krsDSn{xd=Vp+T zqJZpHEuJXK%qQypzTX}3BD0ww@7H1$zA+~}Kj*LawM%avczf&#bl$qoa|0N9a>8A7 zfR%Q6i$<+1>lu3#`vilo=h(~&8uae}^byhliYozPUFN9R4eZy~onFKES}=TBV}7iy za{Egq%605_bEXzQMfRx6!h35b4mxcei!5KbYsVMCOjGpWt{>#7BLX6VjysbrOBtYF z>9#sJy?sfww}C*But_teCp?=fn^Br)8lLU%3dY!+9HZ^4P#uEtgCMr0NvDg4>VTmz z8F_-IrYi^rCB<@%`-R&KU#i|$p=~gz-Dro1bwNo<=Tv}!4sOy}uk_&tpJh9YULA-U z`TWv%Ev@{O^EyktJM1kXwF5`&jBO?5^7)K*_F>;kbQ|2}(voAEPmCqU1tzXqz<69$ z{}_?Jcd%xkonGug+|h#%bIc-U-qcrZjLKrI4}Dp(X*0sP!^+ouIOEc&Jino#TtTZ$ zs9>XB-mgiV*daVe)cPtpi+ov&?(lLtgo+kh$jmf=a`hS5iIRDA$U59q*eqXn8qIsA zj_Y@>U<8`8!|g_ndlXo79&yKQeqAD>(XZ=xw3r3r*cY7-`L_lo?kp8!*2PKN8a52S z@xv{{O)4{Qdr8hP{meMGdv-ls?EG2&;d#~?TCJChmO|hu*J9Z(7C^i5hVZ6ghsOP` zJxYofTx2vlC;OK5`&4+@uGv6rcU8H$x?_pED9(i04m{fF#0et@ESod>@{VlA6mm<(5nEH;9>D6IE=zH79vj z3D(%NJjc%c^$qYf$thnY=_DhtOVarAfCEG~SG2T+7zmj(UHX zEgi8!KBQIBb&~Xi8%sz=>n3|^g9EfPJ3V!-)LqP9VrkHGc)~gADmoB8w?E*NrcbhM zsgudn)*D&9Msn@FnbcKF_RBmsT_`^w?{9Qa*;XIK=l5?)c$r%LZZBOWU_d3J_Amou z=->H<9`YgTU{Kpe--oexQj%6?1_|oF46Ie$Q6xF~9Y)pn#Q8hBettR*WE)sSZ%Kyw z=PHtKgR@GXB**S^HM+0C)zEuzZ_o;CxGLXmS>ND?eJ)B2*;6K}H58A)I@xO^EF(0D z4{U&bC^y_A+Iy9pt&Y;Ev~~sFA<9-WoI-Kc-lgU!zh;Q1qrr2*F0jPYI2irN24~-T z??<#pIt>dDR{|o!n_Q|PsH}y6TU3S#(J7HSTjS5^K7ZayDZf382wTR9>~3X#V|3j91)9%)FYIgi+1GP(=ZEl7=o;;raNKIDP;c)m-Oz zjuk2cjX$43P|YUzfGqM5=4jlV^C?~tGJd4->j+oSL~~w~5vrp(h2~m=I9gojBpFA} z4ae}aJ%U{rQ{1zxcI~39bOvx7Zf9I`#geD?V@PQj5IT<4FPuQsBt}3L1q**O0EvME z<_?%lrZ!m9!o*RS6O?~!I;vR$IfRE%tYWlKQlSN~PH64Qq*7lP8FDt4V0j=w%LLn%ec|+)eT~MMmC7>4A6X(cEi3sT z<8)faN-fNAhf{d%ji5X$W~jhK6vT)NVzT?h{Bz2eY3Vdjat;MDBs(By)PqAL6hSfr zoUN8#II?-d_vn8Jk6SFKchk-jZ$O$`W9IpLT^MK&xxf#zH3WYtuSpGWNv<>rMc%t4SXfcp`vu(3+(EVSJ0AP#gH3L^bDpOO8Dbou2x; z<%+Q@1voH(5$dUghyp32V;55@CB!BUL{AM?IB14Riih*|PoMRoW5EJlno5IrUN7=4-T^@Sg9 zRg`mR_A6QWjNQBc{$1&wqafDEW-wicDA7A`iL!R9`ImV{IGcdbZ@3p6^ujW9;dner zlz>domIZ|$2Y{{$E$r_ij%y4^$Xf=<4Y77eubMbE5 zGR^iU4HLl<{yMj9_hFOVKCD>Rsfyasr?4;yt4+v$z zWeF#H<1E?32n}iR#j!~X#CSP>lA$mwemF-roEDM#&&VfaZYn1wEmvVsZbGysZ8&%L z_gubeUWQFxR&ZWUT3+6PyuB@Xg~NG8^WXD?st{G=;}fwPc*v6>c`VOoA)6G&*)y*! zZ=p{=E0#UWLF>}?deVv80k9D3#Inc=bn+n~-jH3;Y(qEY5=`g?%517)6?&CVh~cQw zCJJ;c3U4(ieJfd>cu^S#*9f~doS$Y~EYk>JXtUuOV) zp1kZ2p+XZJ;FPDFDlkLIlqLkO7s@4;=(Lr%j+e-W%NR@S>wGs5WFe&YAYo^q0`AFv{<_0LB&#W0hNx?i&fygL6aDuQ%v8sy%Nvf zZ+?|)E~aygD+0IEIlKzH!7|xIfbtY~jAJzw3GOkuXT)*>l+-GwoZ(Zx3c(&er2$p{ z!YA#PkOWK|+h_udh|t3x%&!hR_a&qWA4}li zcLE}gN7R5L(r##zShnH^jgv_dNQw1~{eb^3ey_GYRA-Aml@bMfN>c#&fmFGkg;M&e zaDqd$wo1nu#Dw99_~YyuSbrhef{E@&@ujG2>{_!Jfb|p;K7XM&hRc-0Vi&zeH>75T z5bMv!zGR__eBuC#-^eY9BZKW#WaeIs;h~!1NOBGx?^}fiaH~}*zvmDnb-J&)?oB$|X&t9bt_@fVy{^Vo6nJodyt>Xk@!UFe9aVimHL0ZO^m z1L3tslzM9lwp60F{aXF5)5rk38ar=+(d1~Cfn(H(Lqz&vN9JLq>B!Y5>u$U`EGC0? zuOsH%BfBe);HppEu|@BZaf7z#!`P$4wrE~2x?GGy60sObxGaX!Wr#NQ0s}^ce?9gg zQ?^S)YaJ)r@hEdbaFR!nwL@K4vKKhyxpA4E5^&;y-X{k2>_KSl@PtH~N|mev7guDM zEHB0>z`x9TtSd29nV;6i#KRg^kQ9sc2g*D^VWBwD`SA?rNF+uq(iVjar}Rl=FSKa@Chj&kCuQts znqK@pZ+q_1j&q2=oQO-=JuY*bY1aj0=HON{mx8sp{rJ1YyH>dOQ{pUX%QkwO~f0{QzzwBuIajo&s z&qi$1P1toM6o@GOBAQH-yeWF|G+m7sxQ2_BolOmXf>A*U8YtnX>9z`q%&0f&^QIhU zfx9uTgSWs5#$DA1&;5`t!tiK>YW&=?3bm>;IF` zM%-91PB@whzYg1Fo6^??1kS86$xev@!k94hf(D9UI3TsEv3~z1LK}t5DZ0rsuVCz7 zX@>fn390YISd5&iu8ik8T?h$-@Tw$WdOc`XB0)Gs1 zt^tj^fr~we_?p!ENfhiw1Xw6gR3kp&l5rDVym_;3Ai)LOnfbSOBPGN=KInBO63atN z7+@LpBoa9%K;b&miI_dI?RvYf3Be)qMc%251d2ykAa$ zV13XU4hi=lSv3?@Pd}q&mdqGy-{jm*2yb`IX$PYN=F|?$^jPb7G>}Q94sNLv45qvUuLJwk7WAMaIi?NxFY6~SQICUZj+l|d2}p;*KhOS1LI04Ylz>-754)n^T{k#A%FHru?L9=i@ZYzF&^J<2e7)#_4u|&>t%=ZAzBAUkF<>d zi(JY@SBR0%RRobkZ)Dg|^wYip20cgTak4CU!hMVgurXC9(!^wAArj<)UWg~HS%eNq zx^K@J9X$FdmN67{&M@;PdVvb;O`eqR+6Kn^`HmwS?-U4`NDK$Jei3^9DN1FWR|(Jj zmg@R-AC;`XE zqvBEZ3G4?Js=>LiRI>3{{XruAp4=EotwgR}D%Z}GBOXE1MQzwNtlu(pxiA(d3dHY{ zNT}>62{n*3c=yK`cEQu`JNTJbK=A`8P63T?P;JLOSj<+-?#;$G?=O0PXYK5BtcC2p zabiA4cBw4Lmy{#3lOEDZKjRmO1#ZsKf;=vhCwY-4kwyGvU6``=eyFqG)Ub(sX9ljI z>&aXBWy+ZtHxqLIE1ba|~#7hat_-nv>vTyz{_U`?~zUE-1IS49x8L!o! zOaXlJ>8v8Nt6Hy1&Cys1&Xxi89Ui4N$p&Q8e}$oc|0H9~lX2!xN0Y|gh2t{M#)PlN z8y8F{te;RhHh~+YDmI`bG)qM~O2iN;Xc5)|5c%sqX>9A`YY^J7c8l)Wo}W40fc|Ar z+eLE7Rg@sU3rprlbMY#|V!8F>O|+!9<|tM?E`P55>Un=V9>)94)>c0>CK}Z+M_oM8 zJszUW$3Xk;{V3KX(AwuierUG)ft^^Ui-A5JFP2+43z)M(@QH}XC~q;p!9y#gvwx1h zS8bZw_m|MjMD}vbV)OC2qB(*9dt_dO-Nft0Y7^CsQDeDJs>1!Q;+|kJvQh_`b4KHO z31%W(?%W)45V!5wi0!?_{&Sylbv|PUaVHB$!`{EiKGx$t*IOK>^$XD-Oq?^9`*c(D z3sxZW&-0OW^N+$le!b%RkI!+`o{21*|4OR{?dJ?)ub>kN=+thb*B@q3^KjjP5BVQI zNI#4L`;UqdABlnqO@9*Z{I2HKkN81KkPv+>N)D(bi8vOIP}ApC)T0?Mh!dB7>_dNz zpQBA+NL9oTHqrDY5+V*cD#lD4_#mPIc?q7?foTK4fs5?h^R{@;cU~7bZiRW^^Mg3c z#|?gTCjG?GcSSOHJ(^!5)%8QaEJK4O7rW+(i)i4hgcQujznU+8bL;Q>JulQ3qaPVE ziT7n2PE4v`H9^(2kA+OUG&MbhFz0?iu8E&O~c|xL?6d@f@ z0oWN_9)m}k(F2aah_qA!6)u!Q$OZE5$2bB@-8~JdT ztRW{+_VJZSuRTo+AEBfOeUHwAGg5|Yz9J@_O6KadH<0h0w4PQv z8+?J7AKab+dv3sV9BHwB$egUFxNI=0lCXe%h1?ESl?M^n{ku45iDenm4w9EJgBjv^ zkR^XjkHF7%VFCvq+%TUfK(ZPm?=2nXvt=?B4AdMr;o)kg$K(jtohjmmh2&+aPCfcA zxmkBwRNr-W|NIxo-^yM1&)@W)U*11oKI|LT81cMRv)tn-PJVo%N?UzxOjX9&ew~tU zc09a5<~%8ZU}-L8BP(f^H1H(GY8pqfBmoN8!~qEVG`P#qMOh4>dJ0r^$jROhm%%Yw z03usemQejsezM9n3+Z81YY@l`z-|ZP9IzzK0BH576145~#Ik&EuK#NdS9xg%Bevm9 zU1h4g4Z^p25PH!U&;mV)32FYsfndPI?~nLt^{UEg{$E`#Wg)@u8qG@5xFWg7hgp}m3u3cv&6$|_`A<3xRJGO zBjudQQ1v@gt(Ww;PtoK{TowESOKy*YG>a~^xU4%J`?iiXbuYx^C1?}VW40*b&PxaF z^W^Lp{aG3Qd^x9dhTQTK#qM^ob(I?rwYvU|8*y4ZzhGLPuk3V6-N}dm8e7!}T=Pv? z=kJbOboOJ#RBTfAF(L;kCXG5?u48-V>Xr74B;2^Ye&t?I<(lz*H(q^OSIuZO(f~_~ zA{I;Aik)t(Fq{6dLEHAe@UfLkQQKs}z>BRnTKkuOGy9yGEOg%6Ir>0QTvB&(NBr40 zqu1how$e1-XgD>k%q2#=wojYLHEd0LQS9OLxKyi%FghkyCp!A} zxZiSR;grpzhyk`;>Ob?`ot5tkb6sEHY?z+F2PqnAa|U~Jglei{3MM8SLlw7MCWm9s zO}Aly6!<1+YcFkJD^b{l2dcF)*~~Vav+!W%@SxormJ*m_@U2AkatPSV-Y>+edPb<_ zxo)(qxH>?ZV_=INdW2_R>U7gSQo^w8*+d1d^7xY87n)~DZx<4NehpJ2@sJYZKy;de8 zL1@K|ay$&|E-T`%XF8Gpj@;lRcafd-M2cYTAOJQwdn<}xZj(*x$pqjjsv4)r4W`>1HwM%ADS5r9Mbl24%af}R%Nogrw@M;O$sYci zAU&C)!C>V>LL8{Rn{ zUov-uZ>`8{8Vg%N8%Ih)Yqi#qs$B5&!X*Z(?Pdizd0W3+TL1U{rm#ch@lgZxD)9u) zIr6KrLeBWwB9Vt1xsrB$zq5+Hz6Oq;z(kTrNJy}rf>w|-{y`ENiQy8kOtXDAq#Jp1 z4ObRtCFWU7Tzor_O*)p0Xw{S|G9#H+-{)NQf04fA?zM?QcejP}*w*YWk};P=P)zSF z`m-SZ<~COz?Z#j$zh3{pE{N|O*n0He1#!DHWwylA&<;!G2aS%;1(;XAJ7e6gd?zT( znWt5d`!hWJHUVpcT4G~3Q`ISS^_TQ*YRH2Q{=4yB0-j4=LjUW1#^!)g zzg=I(8r5Ej*C}SjA>C@a4D$U8U89*pEp;|GPj*GTTY1vv$^6S+*SmhPjhT<2PrQt; z{<)G+c~zCH6x7W!E=ak#6^0>^->J&NT_+7)B8;!T9_UaD`k*{R@X5g8mPank-;PfE zbcCe3=H|ZfzL4lwNb=^;mp_wV*eu$$S=fmfwhQ~lMVNa#nX?g3;A{6o`rWH(U)xuz zeM6_QR_YC55~IYKPW47V*BwvF>&5AB)se}oU0;t$-@mqc^*s5u@$g6Ems;Ie?W6jF zuE}7sS_jwDNkCN0P)0A6ZDwYc@w>Jb;41Ck`wRS%tImeo&4ruv6fHw4m;H)hl3FC6 zmyu+mCo9-iD^#?NO1h3OnHTbJOT;(aW?y?*BLO%bKe*X1*KWuH! zmGdOK2jcKo6B>?j;X?BVoY;? z8H5B7SD*(G)D%M#8<1W=eF4!0DhWXz2FU?563}2kN`baQP{*Mk@myPii#rR{7m#7V zje#;kDC&j&LXaQ8ih;IYSWyB=27G2v9r}lo!AJpN21FVVut8!0kp`3%sP~5U-k{(x zuw}rX0hb087qB%zp#eh%T798!68xFBZ(o3#0-6eVH6d#w!F~ZF1soM@aBsk@ z21~?*VFNl1)JB4W0x}HvHXwUIi#(_@Pyi1q4yY_(-GFHWo=jHuKJZMy#sL=vG#fBg zz?=b<1)O$J*}=?#%1ID%z>5aQJ2$TYjCXKdpbQc!BoCGyUK!{CS`H{Q;MjoE0)@OF z)l5x22I&Qy8Spwll>zzuKxr9N>w?MxeUs3%3t~K|*WkK<0|T}UXfvR=fFT2R(D&^k zSSkW<1gvb3UO+(sLq2lj3h0CXQxC}uie^~Yxr8Nv`U2(*C^3IDbr5MlHGzK0KMu^l zlSLUI_JCm?f4&#A5K}vs=;Q7Ce0M@OBsfLT#tY^Q3>|?a14cLaEuf}AZ?8RjEr>4A z&kHt7x*!xR?$-(JP`e0b3wYh2zCe3#V@M%%WI`WgnLiIy7LZ|}-w}!)q2duv1EA9} za@o2+6GzbLm^$;T!-=6;M{(H*8<)um;Wq z;1B@B6}S;tY;5ml<>h4I&a!Y1wh#QzDobxRs-+ycU0B_hs|c$||3hW*JYV~tRhIvv zIsS0z5?#kX&G9vcE#c-&7pA|&wBdJ;yP~sew3Nv|d^!8}M=blQ`Li}6Br9OcfP{DZ z*~gcXw+x7R55=rc-(qz0x61AGo5v+3PH0!yR22?D*CWwxC)E3j=cq9&zPJZfX#)s~*T6=p%$ZW=*!nQa6)cd;muDaDdF44Yet-gbC>9ZgoT~g%)J%T@Y zu(%}6Vu{B?q+xMi*QI}&<8!_)tSh@wS(N@#Lp-glH0fe$@st6Mv#Wedsnd$; z+8Gv2Qua9Oi?0$*sDDQPo+qZKaJnqAG^JSjUTDO+LmSkI%mX-)r@w!au1mO!ZrjP1 zM|Z#f8g%UJW6Hl>kF!+*-BYvGdDgFIYlLowuWCzHZ+dmSY{RKnbrn1QQCYGKU)R@` zZhC#PzV6iPQw?peU!QIqSTNjta@ox1XutO1Q*X|8ehl1vuA6A|w$b3P;FAgllzp@W znwj_8=2OpK7jD^qU)#iK`1L?T6T)#FX+7DBk?qhe6n}SNmVe!3?VG<#-bJ1`ZuFsZ zSDW{T%imw5p1S<=>zfa0DGyQ#JMe_xMIyn+RKp%^v(Do43(y?zE4CtbzQ6dgQPF^5 zA~oicSMrcds|Ky1cu>7cwJ{i)!?NLxjx~4zWAc$-u@zj^pAJ9SR-XiQ5!4^ z$9+w>|4cBYxXN~rj>mj+XRTB3>tyOKlPVk>e|Yw}js2y&3)v}~f$tkr{dsYsGKbk$!Z@Ozf zmqV>lyy`JverP@~#-~R4-r#`s#rgb%yc*Rb)60q&?=@tb2ALlRi^UXYl%&_NJn;sF z9+h~Z_DP}(Y9Q_Ups(N;FWmW2qnnl0CJBU$>bROaXIoCuj|~NCD>e!}9Jso583F>f zsc@Cs%>Jz|f#Yo1>-@2#ecP-3S8m8r(A*@ch|CdOgEi1qE!A=hW_>KvL|Tfivqq^i z`8m1BF`XlgSe)L#s$PQ@o490>rd}}XQiN?Z{8j=+7kR=$oe^iba|l!aF=a)Hq)RzD z1&>HtE=V-W)*f4@LAJ1S8sxM*p7IPbp75^+bAfq{m zrTR}~yq(s}puKhuKZN?Pepc0S$s>xUsn_4~{CuE!eV7#VyjI8~Ckfpgf_eAVg_BmA zaR&xg^q#_63y6fp&JMAxOnICuhk?YP_i z5aG<T_@rfpCL&NF2JLr0) z*Szivg`0#=5>%sKh^{ z(X7?TtQ{8aU0nMrbj>coB8{)FCAHm&6)`FY%uHT#~c zt2X07G4ly|8?WJMPeJx96Fj1vmoHtW{hp$+TSy=M&L6V%CS0(0GJPt2Rwm>1D!swG z`O8BX80K~VzD%7P+o*eRIu{AFW>(}en&sMO%iBJr)OGu!OH4d1|+qqT6osD61bM1zn#{toZA7$imNwTU}qY{f)Ut)jmM+>zgv+Pt6?@MW zsTcamMj0Fl5yZxmw|;pDp6AtTyD z_^LHnTV8EaD7BupdAsz@gJ`FFr0jRz$D+OFP3k+_(44!$IKOCm2ftU7Pn+7Mc6+x@ z5b8R>x2`uReL*w*jy6Z6NfyRQ6k@HpsM^kSw-~df-_bn-s5%#G;ej@9&+u0?T=Ogh zXSPk56;-1rEoj18F-W+1d3&48NL#LAQ>Iv9hB{Aee_&R8nf^dDnn=r5Wu+;Y?cP$B zo&IsRGjI8>@7cl6Qn>#Il_mXr`WinBVFW4Z$obv0`;!JbueTRQa>Tn4N_S5Egqi|b zx>R2pnb?b^BgDDACxdcz5^YkRq0=)AR|VRkEH2T^@u)RQ97M}--j~ZzNwDhX5In+T zMdgkT(kh9wO);p_AR5=oBWnEf;Lw@Pztgdwr%Us8mGO+pS)EMN z{*J0~K`r6G?I>Uug8fh+>BrhTw;yfd$#-KFm}}ey3aEBFQBfKNQ)tZFR3D8+P(X-iw zF zsMf2Ja0+cOFv|8C`f|$K!mrd{6P>Xw<$|8~Pt?TyiJG1;z#I2()P$S~=dutrA#;N9 z577VSvjDCj;KBg}bT}4;^MJO_Bq-a5@Cktsreh#8Kt6=X1X0I-l?Q}I$d(WnA3o#5 z6b#(HLhNj6YMPsS4N((vCgf5$B!El^3owudbN20rBw1Zk3-Q&IVFQQ65Jw?cLTZIL z>fyE0(8L<{UZ!4WLP~t|<^`lg$iT*nZ6Gm1jD*_*h@%inAuGZ>0mM#-ln@A^-XG#3 zT-(B07FICJJKBu2=nu!aVS6k;UgNeHeG3!(WRVrq8&ItXtN zEa40TvM3~ZIK6;inO_tJVHKu(V3Gi`+`vFT99qDs^Zw;2kene8LvDoF38&i8b?tDB z@#xV+U=Rngbh$qdt}kr70wH$75ycV*H`sfDSPPy15GG-E4WcF_KscYM`)4vY0~W{N z9s`apU}XT-0U**t;B;CW3#S@zXaVOI5cVKaLdfLadkujQk|*3++_-TqYT0_2Mewup zhZG85B_MoSx%$JY17uV?|0& zErrYpR}FC6pl|Wd9XK2|!`%gJ6K!s|4B-%NB(^w5LHLBU3FqPtW-gE?AywM>1jE5O zBuS2A$e$x~E7PTLa}Lun5L3OaeUsfcL#kX`SY^AIxy^N>iP4g^j=>CL2Zo9Le;qad zrvcvoh??3SQU7(+bRHhO_P-7A{;yXPeTu99jFjCw2TL+O1WxY6|5%baZZBS%{3mMu z_mQ$IT%7oe>+aK!M1PiK5(Ap|!>oYMg{0@bO3#A-9VxrDuZjQvwj}ePM#{P_X#X=( zrgE?0e;O$}JNt3=&gm82@*jVGn|nrjA&E5q{skjtPj6jWHrs>VfBBS)m)9>&CF<5s z@{=~YEJ{b+^sAg-`o>IUDsHHs%2M4iJC#k(`gedgW;#c|u6}x-aog;4E@MFdS)L`9 zQ{ac}s2-(Q!2qxGD~~TMH-q0XGle@g@?e11NjsgHtm@}yM|zwrbRZIxYMI{{EktoL zkAiSh$g(6Sk?d!I6JNDN*EtHCP{)eAkiu5;eNnD?0Q*XYrbFA<3#1nYe+|+mBf=qBVpJ&vypU)NTpEp zboz8cN(OWsu`*y@J)0o9#v=daSUjXw@*AB_EYP5(s0$Lq%JZ$I8( zWOwR%dtJA@!Lo_I>*Zl@Z$)&Lu;lpqu%y)P52>Z7G<&B92ZSXi$<88fD;LSOdiVx@ zZdozz_lSUuSl+ct3TzItX7O8;?o7DR9z`xy%p8@zq>{6GtLv$yGltHaY!*Uf%;m2A zHF6(IW4YWSubD*Ejr~&DMs8Al$t(%`NZaYfYmW-2@xH?}8cwOpiFH(_kIJf4Sl%~_ zqwSY|tbBhD%rKZ-EWE5&I_htuZYOTy+@|0#@_|CwQuvT^Mq{#$c)uF8BC*!f9LauC zGFlp8SA;K(0@kj4l_}H5d&A6M&z4lIx>9(Ba#*Qw{?o;$=x@C^6XAY~G_^L5`GlF+ z%-G_=1zF9;z4_X!NL9z2@H_XVTe3}_*kcvqryZ*rCglPmJPEnx%%afRbg}_wkLl>q z%va~MI#(WZb{Ry|2}1heo<&Zmyv#JqWv7Oy%73Pt{EnhcntbSiThQ!rUer~)Y24hC zW!FIsf~2mq9$Te z{xaodUR}fzx1$-`7h#S&4<1zWb@X_yhA(kBZlHqp&x1qKS{12T`B^!S{kPnU)> zChRiyNEaSl5vyU#|BThRO7*hsJMY7H$idNmDES;cDb!orcSz#C3S&``cY1A+=4DII z3iA1zR>Olzi+Ch$v(f9k-NhQ%U3$*fFBFlaU3PwzB`?iMT0nTJmB(b1)R-i`i1*u1 zCz*MSxfnaLx2LuW=Q!xJ()>1$xs`tYltALuE8&jiNm}!<*A(pz)yqFlGAbPs({nbz zDndlocF6|THAVjQ6I(Xg?is{xxUN|H{PT%1Gfj53*I2dkmwFH1Q~n39kJT;t0=@a= zD-5bzvLd%>7)h}D2biKK>f-(g7L7c+ z`R1F%7(Mhp#uY=bJF<@SP^oCO3va$y#y$DL&?enVj0_nG(=$5E5_8FIeWVlQt~tgx zW+K>x?$rj~4+aBhT2^sWo=07-FLDA_8{}FY4|?!mK}=VuNDJHaRIW&1t&Lz9Tm%}c zV=VFs`=S_Tsy-N>X)`n>nfkq#F4-h-_nDSH{Jl?qdDFgwvSIo735}SbraX-og^jx+ z8!U$B!*~3mU0CAcRXx@uRHEt_gw^&d(a`m8bcL7B+|cE#oi8zvR?t?7l-Ry&(3aq| zEcwTKoxCIG%l!PAJNB$9l1w~sy3;{;V*Y!kMvR+B^i`jinVl1tsZHmbq&Ev~c4o9n zSH&G6{Uu$nF3IP;kKmZubcmCEFnzy~Kt>{bc6(GD{Qwb(w=2pf->}duPiv`n{J1)^ zL>Z}a^C(@!Z&~3yGe*9DmZc><WZTyc%kUwM!i28?20ZZYr;}4kvlLDCnfdZBSr2>`$lLDCn zgaVTSjRJ=Pv;vSCnb-ig0+0f+{$W+%Q(#gcQ@~Gnzks(7Ak%-(gx>&@!fOZs8oYx5 zw8HZTz$uU^02&}Cw5$L*LIn+wDXeb+%mR4A8^^l!F(wRqpivk>f;R|YPnfrY_X~I; z0UEt|^9DSH0Gt9*0?7i6!ixrwEHEh`E!+aba^bsoFM%R~OabWNX#?IVpeqL6GJrA1 z?v6qq4m^lN;K%;=b0Hh8}J%CAp zMgjNWi3HwX069%8nQ$iy2fsk3Q1t^h!Z4Y&Id&^BDbOe!1;Yp}fG4a`0aL>x2oUSi z)saA^P?!Tu>Ke5TXcShn;F;qe6!l;MiozkVr866V6i^O0v?-(zz;pQ45D+LlGXZ-7 zu>yX=V+zpd9|DDaEjR=Q@Prd!Kv7`NoPu=#x$tHIe0|WL3uFo$3U}6jhOpok7^bn7 zGT}8O5AI>1aR@-tz|;=#6UY=MyZ}hywFvkW;1tLdC^cJ<3s}0$+zpr%;MB-`DZG_H zc@Dgx0I@;`4p8c!hnTYRiq^JPd-ghjRygJbN(BZ7nEmG&<>n+*3;~M5F)zG~z=H@} z^1}EPobhgTje)%^C`tmJ1xke*UZ7MP(`E2V0%Q&Nx!y4ta22L>t5#>jB`-XY0EYsT z!ki&6DKz#twM7E+!cz#KE5Ix~lmOMjp_2_QjYV8A#Rluou!~0KruttRE_A6?NIc4>l+XvLASjC6scsVaBew@57%pkNryRD9A z^^W8%nzs`kQzE#(teU%jf3$!^xro}~?>EwgN_LwHc@mB}vvrdO`=rYa|GGMoj|5$R zb+XxeaP2pd1QTH*%H}nte49V*802&mOJb6Y^mIbl5LY?Zl{-DLzu-D$3uiy z9@lN#(#(7bxHOM!(GPPa@b8yN;c75VP#aKD+Sk>5Kvs|mEiPE zyYHPdOMY7q%V-h4UMR`4(?+zra#vrHn|~zNru)O#Ujb+4OuLO$GFf?@;XY>0TC5`5 z%(6(;e(6$e9(2y-sda|;3O{%J3HR^ecUzY`*~^Np*zBxe?GmxYa?7cZ8?rk=uo(HRYxJgsoO#hCiPp99D$*i>+;(Kwnz#v!(r!On;<~@+xy|Ez|0kq(zQU&pQE{6e z+uVFdd+AS+oMWC|Jhm&qqqudR-Fzz`zDlp^D6Kx>-mW(1D>k(S&JyCaDef2bTrV=S z)_-nw6XlNCdfd@-`Qdx-^r}7H{kQ}N_iN_@zE+%zj@tE|>}xW5hdRHOeedS8j}EMl zApvPW0`B$}|1BByp?Cq0nRLeMmwfVc*`shl*_qz2Z|S;NN5WXprCXgT^LciMEC%Yj z0t;W5Jx8&2eHta!G_*}S4x4j?VifK~D-!CMs7^VpE|XT4$7iAegLoZ(k$AXEx+-S+ z+Jb(w17G_Y-5pQGM4a!-v7FcQNY&)HS@#)+e^^|1zFNM0@V|NlF@ZRR;ifNy)TkEX zZ12!?2wR7=(neAHtj~T0+>Bw(M+$>ZrS3c9S_HDB^B&Giip)C?gGGDZ*>>s2qCT3Y zi|&s?ov%%WWz^##jEN%8E-#Hj7lDN9wd+q3ii(ZzuQQ6KD2}YkD9-33k0|qz;Gac~ zw!e=vPRjI$DO(t?`JJOy@W0jId^$8SRA=3O?PmP0W-EVL5w**6_=2&8?z-*>yL;D^ zmKxR~7|sa?1*}(QMKk^J%3SP=Yd3G@PMB+?-MQ~6or4ZHoue;AYP(7|a>;$o$51s7 zhQvq5jDXL6#=Iz&sbL|B%tRCzOc(cy=q(BDD&2P>>?h+|E04<}6cZ1bOO+V0ZIxK< znje<8m+4PpmE7TKsK)AA{-``JjV=tdCD_m?0`n??wmE^N%wL(5iEjC;g#puIm2HX z_f8?O;vo#zEIshw8%ywizP(w(x3~2FAe{f9dHewqAQKQd{umnIYyg=+e;ptSa0u`T ze3=8HfS-QwE`UbhiyD0Wg2oSUEx^G5CIKJ;fLY313Ln(~IfB-30GR+tz;FQGfF3-+ z1E3)InFjEHZ)5Ot2{gqpcZ4r$00w|1uYFax?f;3F1b72ps62~?WE zXFR|d_>sMGbw~TyIQrz13s!j^9isD z5D3)k0W1Mj?B=b3uWRr{4Y&n9wry!008jyv0oJl|W&)03pDifhrP!76209 zM!<$8j*fsmKqDY&fII`A8=))(KBobSK$#w367-Y6=QN-}UP@KtBn5zyoaqzNNu8KfnX{a0v1SjCKNy0kQ(0z$ZqiCO19}oj_u1 z9oPKPKLBQ+rR0wR0;UJlmFOE=gWv&317HJ?17PE8v%=Hbhi%LL55nQFG%Ooz8G{Ta zl7*@%8#f9nopXq0PLDiwoCGjaKen$v8!F5*BbD_TwvrW2QlzG_qgwJvR)JZu7Fyh6#L5u6i9KGw zLn{YsX;y)lht*|XN|tJQ3`KuW|M~W&PMx^McjqvVlzApaMIejy^LA6Y<|F<%^S6lR z$V_kk(G}8>cg6J8$%bM_m;07&Jff&ZZqbkNCbBipuoP`ofqxT zz~qMf^X=^l^hL;jc9NLK(EG$NJH9G$WU2JN$Wkj8e~dIEOnK9(urj*Kz2_Uo<1eO= zOSY&umGt{t#0f)lkoq7QZTw`Ve4cqQ>97Eq>&ab%lTYTXcA%n!T;LAmTV3}?YVaOP1~=t%$zdKZ2DHZsIcvka^JZth*U&J07UtrV?&Mf*9Ghn#iaYH`+Nbt=vwPo5XWY1qt8x$yY9D?ilHQIA``ea_ zWqi8vyR?vChmnc19L0utkBBR2`=Uz4!?iljVF`w?09}2ujwm-{&NSGz#LfFU=Cx$MKg zK_=Z$oCcF8y*Y2b*DIAfhn02L*Brs9DvlthtBd1*GA%vWPEr0G6>$7ZG3HsO)8VwnJ0O7?&a% zG;Y>UuloJ@;j+^TjTPswSv{FuW$Y9txr0$Hj|90HpRLN>oDohJi>$;^rp3wh1l=Ms z-pZIJ$E)l{Jp_1`8y)8~5k{UwJ*dBhVo8xb&LhnGFT|%28 zhLhexEHBfJ+=q|qaAkB<5$zDJi-`wOgDBmrbgC)~%W~3vLCW0K?Z5Y@3cI@#40l|F=K29#(>*psyia~<&%x#nb2P*jatT zk;J{VXl`nGu)a7#ZRAoSmuo3s>qbgkgm5Q-NUafJNOr1o-=u*#`Vd?P>Ym;@H;dj5?d-=pv5Au;X=x9z8}*G@A#m!R6U z80myZf^a2qL|M+I8JTP_$QwlOjL(o}v4qcPk_B`!xhHq{{S;^Y}Tj?4R2osfwst0Yrqhqk9Sh9P6s>JwaoF}+e8sYkHq zQL-F+>oZjx=jyKrA}jQDUW}rW{98CQ1RaU}J&5id|FQTl?8H(pQ96FmS)9x?MJ6?E z_HB2e4uq0r%Q=!yQIS{Mqvwln5f^YJ8O8C9!~`|ZFVa$}WZ=AzB_(lqzsky;(! zjl7QWTX?kjBqkxtFA^iOR(=x&CKYJn~)5l=b<>`h{w-3s+-% zo2J4$2sYnE!?HM+aS{JO3{)C%g_>Vu8ixvJn_kP{ zIGN1Kkty22?|r8h6a`De)Ts$hyT{c6s8J**e@2T8?l+h*P)?OPUgnzluPDj>~n7X^! zgG*xaq>DUyrHTA6XSO=#^7SpFZXNyF`pZswxhh#6uaUiMrs}TarO#-WfUwbLM+RH! zdi|TOFD*4cM-j!{Q&Q_+jSdLtCHHpS`^3c?qmyHo*5&AX-8ryJ0smB1vNxo)oKV9okdU`F zXdxN7lx=fOZb|n`K|}#9U~k)v|FI@_09U$j3R4N*s z@nIer+J&;OH2m2_zeH*;25~_tI|+#GoGJMZ#f`0|P+nNO;F^hQ6cGwD^~#HkD3p9* zOt!8w!jy34Ca)?cq>r$iQA$`DxrVuFGdU%WjMx~U%66#3Mm3-NEcaPYkCP?l95H|X z0mYLC@^nZ6Dby=0G%BT3Wgc(E+;ghW%Yv5MOh#Ihb1!t{<_kDj7KToj7j=*jc3$m7 z>OsY_g4sNE0x~-5b2S>Z6z;2!Ad;&|)ogUa1C?Rpj_9LDN5JGG-Tkuf)P+NHx`A%R<8gh%G|#T$`Nt%pf&IqutVR}3%|4yL-KXoByDI3*MX`?h%Qu`T{5B1naHno3}syKag&fwV3 zAXIl!{8jl;J9)9DZZfij|2L&FkHJS8h3j|(8bb_^VrcAWsry+bY+^ng=Rc{T+fAW0 zV%!kP>^V}tQ0#0eWo6%iY)e!IN=2@#sL{!V2_$p2r&luuuGh^O)U8(Nb_QvAQI*Pr zs_pf~)Y}Kj+bbo0R$`u2GYo5%vWdzv6csvdX=RDA0ktHdI+`q*hEf7`{%J~)6stl# zw=adFl1HjZ{;>qY4h29Y{nZZUtT z$?kA#%Ha&#y{!v+=p7+)qeeSy1nD-Yz!u`K+96lVE6VlDbQ5smLS)3?$WIcD*DSrO z5m6E%eO743YoC*zXeuIR--xqj9BL>(eKFY1XcCFOAQnkK=qkbyM!fb(YY?k21hhPl z*Id)e{Y92|P; zZX>QUTK@9S)1udMeVZEARW%GfP?$~#T^9!HgQqVYI&XOCyx~Kf=GF6zhstUwS!S~g zc0r|Cb)F!{Yj$|py!2NyQ>Dep+pYq|Ij6RG9B%Qt)Z+87W%;ibwo0qNeQQ8S>+00j zpu?@fms&#~wyyit%28H-=rv(x;ds;E89UZzr9u_g85nUD)b59L$D z7jNaQP~|D4+-~5rI*PqJWOuX=-H@#+l*`)OiJPLpk66Pmg+h&vJ-p8BkdBPa1kr-0 zn3N{^vPypPq1be)L%!%T)(j)+m-R(YOHW_?p^ZG>EaOPW{Ox{ud^7sZ2z5uoj@+PK z*?b8ryizCFeK++oD$-f-?jF2xg<8>h&Rt!`?F!LM{dr-clt}$OX35pN%v<-aeOyik0b+RyMod+#oPbUJpeG0me|+o#$JHRG`T zn|G!5T`lf48S1&2+faT-;&Ek{xHJN7U;=5*UMynN7=|6OEx@f0>m^1MC(JJp@D1h| zxk?NyUyB{E;T820o6zl=dnM-(DWQZIgXlS;w&j@)W^(hvMq=5U6?>)ilk+-$KGzLo z?#VXRRoP&(aa2c#jX5xf+cvslYlPk!Dprti{p6!dk<~XkLorvaZq(IZ%}mnIsqR54 zDFU|G`nfKod+2}$a&Cy&WQ@AT((Oj9N>m3sJ`L?H?$n#V!9RWTfl{udD;i2gu7slQ zBSf!mVnd^75AG&1XT3#Q@8w$?A{{SBm)sN^k0ai~Vnz~s^~{G1&ooLVb`vkq^}mGL zL^bQBHQ1QQBcWTR#Lo{lXd;sNBQZ7Bu`4m2D~Iu{!TG|`&3CK^797y@UY)EvA-C)~ zq1Co)%?INrZG|hlM;nGy@_MY+N^ddl7vzp5b+!>=(VhO{pSaYW#y7|G9s0HsutNJw zckF9_`A%6b$I`r;@k{op-ZrTd3+vWV*p#{2iJN$b zU^U+xMh{Ht9v&0v92i~xDfZr1V@%=*ZdW5tmhkX4exi555`7fs5S+jcEka(`4Pw~_ zxT(hm2gdVu>qXEpUL!cN5b<(-d^OU${m$JREfdA5N2L6oe2`fG_TBc2ecoN#=z!Wd zgq#N@-j~L_uau14?Hims=zAvb3AWp}PiI^*t;08e?1s_9tEc+iZ;rXE-CeP#&G5ZW z{Mx&7BbTaK`4T#NiJ5FMt91|V>wL(#)A{_#cs>5=H_93uV)I02q*WSgjXFY08G;`# zmSl9_K^VG`DDv#84s)){T@vw3d+)M|ZJDS53*xwGw|dJ6^C6#AL)ZR2i(!N~&}mrHyFdF@wB0-9_C7SUXy)1R%i*14eHm*X^sjx= zf2mreGiik`+5be#?7bb;&(ue0*efhP^v=r8>5z~yY8du02m6~#o#(t$WaU4w=G-0N zND{-|>V~hF9Jdl4Uh5x=HQkFv306$(t2n*C(&Dh4G;dSXQHWsY2vx&``0ks(?yg5r zY~eMXNHmnT@FDLn6w^q4p8lk_G@<`R$d`rVIfG6kVzzh9AY`X5kYWnBEDF#fa3% zM}pa{uCw~?=ta-U-L%sFq4D*(7rw07jYx0}?YP7>pCsZPJr+F%6uU=>m z_SGa-8X;ike)ZYN$US|nxIn0sA$ro03k%T+8tWAZ-8wZv3Zu&sf3|gEDoO5*&l=me z{MD9cdFw^D@gTM>?7hn0SjOKLw9oGrqs{K+a0J}VL@-#Yr6MxI#o_{~Wk`2F`~k-M z!V%^zS}vAieUc?cJH!)z#$aA!vP1~cl-e>_L}%rSDJPeBG-(a+w6!}Ac``7(}&t@Zw2=+5nko$<9}`VZQsb{Y2&7`L5~z)v1-LT&=Mh5<7Eb8 zBX|6tZMMR2~)Urv{5 zp`1{cMkjOW2w97wjx;jO5vT4-jI!|(j3)A3tHAy}7GcSjEeYO2|2Bz37W2Lu(i>Hi z^bNbqG;6~u#k7=7+U26fXk1$B#qQPzlBcF*5EEJYRWNPG*uHdi~RE=jR;{ms_ulN-}Mm^m*Ls_9{!KEhwVE)p|`-j>#EY>MW~H zg%>`0!1BYRU6bji_~7(Bz5`~)erXw=s~~TQa;0qjoAnR+dvJQRFuL`uJlpW=ZMnRQ zkKeW<6y?TloJ=3G-w~gH$s!R3H3X|X>hlJ6U(l%u9!3h8#jVvrRgbpbS-X=igJGI= zsYIN5rCXt#W;^{j4L9k=AG(Vm+gEPBE_9FMd=&m4!MSf z2;N&XaB|X7`_SRLJD%o$GhtVw+$=&5fgP2hELS;`gAqKSpKe+jlW=~!rQ%dKr5eFg z$-9jh3%T;sx_$993! z2cx?FX)IZ~YnFdAZqc41S%LM#Cp&IrsK_HsK7RUlYPMSJ?22?v?M5DdZQYT;JY}Tb zZfT5S?zLY8Y4q4iiQ~b@ckC=4!4EOXURb`e5V2^%8eutD>Lw16Nae`=`k}rsK&n{S zkmxC=G=U*>9$)(P!YwT=qjJ~PGo{-21O%t*f!7NXiR*6BHCG{19=3~5FrRxZ!!i|u zgcz}wsput^Q^B%xB6OEH;<-5x^{HGYF>ul=#7OW?aoAuG_Sy(Iq8E)!DQ}^mo2n?!2d#)|(UVE?*OsDV!O8{e&m-79;z@`KizH^6TRg zFVuGhF^STZN~OC;3+%~x%#SU2)Cmr2t z`zls9kbxp8qs4ZA?H(3u36RYox*ogQ6g^*g!6EC=)@AlFJ&g<|QFro_?|aMrt{Xr?tEmyf5xptVF_W5`(jqBsBynOH9#k+z$Ydp=$`(PKT{v`~;48>wTz z=KAXK^9TE5H&|U-GrVKG`QOG8`{2>i@s<;=ahq0M3LbA8Z#|b87aL_C@?d~N9tujp2F;)_J>@C-erv&0 z=y$j1jW}k4+d&zuN$qu8I=5FPUk6#eJ395%o-Mp%HDSjLZ(J7P#r%h*Pnvb+B%ux&)jGyrpWDST!T;^mGr51EzIW^zV+GQ zU)-;_Pr1B9@o7}6H6m%>G{_7o2O+CJ}jH9+i3Chaai2Nj?& zL+={$H&ynS^d-Be!fo6(hZ?QE`mMRq46geOLJe0Q#On)ROBq*^keGA{P6D1X*4@5H zkt-oP?_`n_jx4UfBTwWI59`sb7zgcc9-G4<&?UO;JFj77*T+&D?G;KL?|rySKM`UK zByk>08dC$KN8}(@jXWiUO^Imkrd&^ZpS#xQNJ4gM9VV{nLH;(*2Oe$9m}|ch#gv$)R?sC# z32c0&M8Ht3@@qwbb%UrpsWO88zLEIyRoW?x1Bi#K;lHk^qZbl5AN@nlwDX5o0xXy0uk$FlFFfNl#L74jw~ zVJFJ9{&h^$!B@D*U0uHj;iO}1?MkY6QXFl($`#C9X{aIsJB}9cAyTkUL6NIYJr^#n=kJsvznUhc4UN^)y@8 z>|;t&nPM5;J&}lcyvy!*Q5h7!uJ(b zV`9=}8xJWldh1wRozMLkMJ@jK3=D^m%jFy3k+O6rd|9ihWeJt$7Osj!P_LLb4Comb z>QrRu{^oA`&HZm|-FY~aZ{YX+YgS|J8tYga`RkS167Jpn2qGf_>S6dM z13v5b52S$LfQFUQbh{I-E9xj6vB_wSD&xXI;TpLS!jNhum9acvfZh|eA-^s( z7`Q+`On@viw~3L{Ze(t|WKFk8pkek`|J1P-;Vs!c%{djZ*W?l{kf(rV(rew@n?87_ zuv9529_?g{npL3`Na6AVADpX9k0K}Q-jqa; zxxyO__H|t74n?615CV;ck85FvA_O)nNhS_?V#eP4qe{{9yX_-5i38?;f8V0V?Bm#W#w*YkwMS$8&t<2L8GZf&<}AQ-{%}YF95j zmr4^?p+fCqOzTuW6(h+tQGztY<3N3-VD(y7ms&STbm^kf zopFwqb0bH3=_EdLZi9zQE)Uai_xT)1H}>wkL`U)vl>2`5Zna7|Y_g2gukAak?!c$f z-+jl5a>@CScW1`JzNBltec{fDF2jh^)_bPSAO3od+tqYD)1j+=*z(UcGZKbMLNANg zzJck_Pxc>a&cJZ<2oaMuKX7Z47&;O;+$xa0qH-p3$mz#+LDhn}6g}Wd;3yQPI&%S#heU7GE`%&^mVV!Pu!6W2YC# z62Fd}!Hm;I#uOB43UHP#Sa-6P-?h4sSmoDcG>mSa*Ny17A(NfdgKjIbvo0tY58y9yXOBn351 zEE=!`2mv7N&u3}wlpayr^`zS9rvrmH(%4V}(; z{9^x))#;}}bsD(IxpDevYxQ4K0c#>86(@jD@|{ZF|7(YsPn^If%s~e`fzNlV=XZgR zLptUvQj%0V7mC!m>!Yx@sV_ncQJb9Liw$1GdeveMvbk_&sDo>m1nsogBJ_c>B_DU8Fl%Eq_q|?-*}xgVkBo1_PG zoejOf(~tNZI_E}4t5kDuVF-F?$W>yP<=#%W+I$i{#pGG8*k22&5Yl*XxBS%ge7@*9 z=w$GKO{GmFx*zK%jtjiV?HQFK3OH4Lsc`4~z>up~9K_&MM3MFj*na6msEhtN;EFIWyKdL-3@nS&Wf zod7A%Kms#&O(BLDohk2teqsO#kf8H;9J+Spkx~bv48g6!kSStF*A^Ezu(q~YBh=fo zLK74$_t3W+^i`mYbsR9wDCqLM;WcBrAOX@N+mk#XSxMZ@i|Gz&SobJQJRQSaLs}Lk zdpe|i=l`^>`RU<{@UCwk7@?^iILt9$E=$5nP+D^MaB?^f!)!eA`{k!%+)B5mfDH~E z)`-4>frLqDg)~+f0U=IA8xxRGgfzlhk_$1_mi@+sgtUdcc9SM)Y(`=%T7xLS+ZV_Bh0PQND|h(Xq4e_jHo|JCLyH_P|_S0Z}&0Nx5t!ruAxe~!)g&1O41*x z3Ovx{=}UgC5#OgCQG}C(ZMOWt7w-{#8>SWjIPc8bZkE@Rw z-_LUB5`<|b+x$7}Jw8SVZiop(OrM?ML3cg+6zc6%z$;&9RXUYJ#_e3jm~iBF`eK^{ z9UQvp_ft|g$ZfphkQ047!)5od$1 zNB*!&2_U9v$0ae?ND923C?im={BvjrD;5iFD+51moJ}a&pl{unh>Rj77aRPnJeUBQ z#z{+o%cbdc+i};%5|~7$V}H^#0gdD&7qgG~zdmbe%_{aiS@J!;jEmm99amM#tzeC^ z?vI{r|JBI_p#*sDb3wiO$%g&>16DcPNwLgvB+X-Unr`K!l5uQ1?)XkTd;YuQY*kt9 z3FWX$cO3qduAgAyHfvNiw<@BTqvAPtH_?jY2(eAXL%AG-I94&lnBN`i_qf+%mu<*q z@;=$wRnxeLv)eKwM1_{ILNi=}X{pDI)6|2`-W>WGYzrZIAap3o3PDc+LEtPmzXLLK z7%5sNc|D!`>lm-yxaL~WMZ`MQy7UTsJiKd_8b<#UAlpEDs+N;|FvBBjx<5Tbdn`i1&G(Z}x>FR|nG zJ;SG~8&h*IXl(7*lU6jttR= z9QHe!=8@9F_L%0=S{ZN7TYOk{QJfrprD|V|4?iS`kP@cZf<+pn6KCsPmE+w4PO96^C0I32;vZ6DvAWzn$aL4;j)OlF2%x7`EGo z#7H*sNQ5dcJ-fQ zJGPQZ0@-jpC6#*edcT}We{T|>>37`?`7GmzCN@=*uZ%;5(t02WL0qFJK#j`ut&@%$ zMKpZLH3#}>SEc-eXWf-rWFR^p%!N9tT}Gy0_m?^3yY__U(!?pcWPZ!j+K@UQr90PJ zq1c6`1{beYT8t0-35d)Oqahi6?fk1e#W^=s_nD9Qxm2&%M!#2RAnE3ajgx1xEv|L& zsAs?vu@@C@FH&fpe1Ez{q0T+?s3x;z44wOsgTGa9=hCdY_b42t0Tpj@h6RsnSf(o+ z(m>=kK9G0>3o=i|)whg#NqQ--Nj=<-^M3!#r>E!x`S<$^a+`I2e ze(L-xQ+UY&DReSI#@d%c?|N}sWskao+M)b&JY?O)cn>5;$^3v9x_YZ9@HLlX;;-}} za5!}EofZ@uwrC?Ywu6JA37#qx=P#4;bwOYiv^XNI|8doJ#(#9(tvd)`ORR!Lvb7DV z3rPF;jJjRst-}@PGoXbeKJCqw`)o)+nmYg!L9&s@sA{knXg8PmpaSoX5C-*(a%FQd zvdren1!UtPCR%yu)h&v26Tc&5!e+mqiTn|-wGiN2Lz!RaTO(H}ULIA6-;MH}-&gQ5 zkh=2`X@O^7<0AoRm5OMTk87IldZBceaL8rt{tdI(^fql>Y6HYRpUV9vP6^papb4hA z6-+-Hkd`5UKg@IXJcYj=9$3Sg69~CDbFIMUacStcU+AGX zk;(G*KpUp|;_hbMX9vd2?Yi=VPw96Me(Bv{!ua!pn^`>^q~Hu4vL+rk3dQq&v=Dql zPebfRXRH$*fcqETZtn}aI+L&MUQwNZG=@v0v{_La&$rPw^|ZH$^+&y$#M5EfW|91> zriD6#nCNa1rzn9iw@x|Hn{gIb{{)A*$-8POt+S8LFb+Q`LSwU<1GlxS3p*f z%eGe~jr44B*QfZkd}VVZo?NzsVztfzRd5@~NxVod8=eStSXJe^jGQ5ed_Cyg_Jt)u zd?r^P5fr@95B}BCVke>LTe7K2v^=feT>JA2GOYN4^IDZblv5MR=7xKq{Lkb(9UlJ5 z&5Nc*e!wzFQpx)4nrT~xRVHO9L*2013OTdju12uVNoj@SO<@Ux8PNXjH2cGG!91jI|=AVp`;>Zaseecf(;Q8vV_Ku*ow8)PmTp6ec|sZOP1Er%d9wD37b zl!3%t;-TC1QpH0ws(E}VULhQ3uXBW_<5#?A*SpN5=I|(DzqzJ1?UX~x1DZcdd#!tK zk|N(8NEk9FAPs)Q+&1Li`$W-ozu|YzV)s2B%JjNjl)SY>-d8>p(lAC9L$&k+DtnuOtN4 z@61XciT_h4f*toY{+}lRFy=w?GdXPSHOFsIhV%*td-jD!%at9gJ31a8iX$Bk(f3~6 z5_3H~W$DR4ZSc}v*@!&L^>1!*4p3wCl(~co$0z86?9PwL({oSw8f#qi8TOep^qAo+QyuVmD^1=F4$=*BdiCQzMKZ7uW z@$jMG6e2$#A8JwVeO$Wj$InBYX~)yc<`3Hfn9{?ov>DO1yEc`PvFDawt-DH_lFCAdgO*0zO~-GyBc}M zsN;?1_uJ3!emwS;#<$Y&{qC2$pAxr>XZ|}LD%7=>vfE@%=*H#)ov!tqGbRi2JAVu~ zZ-F*@&tysG#*fFxy1tZbnJk;{{5f*2YomI%>3ioJKVRJJ`r2^DbR}TtuZia}>){Ts z()LFoi5tX0c{TE+9gT?$G*u_ySOO+pB0`raTvzFvw@vr1wwKm!x_r_2TJ>0Nr`Og` z`$t`8EAO>@bl&lM;jG#7I+@kgPw#$DIo=a_wNviLhk-x0ubVD!^TiJ2gi7kw((o(f zJrUWW2AtSV2vcMYtx0T3_es(3@1QYr?`B)zn0z>MC0ftj-jSf|*3XBxV{T22#uK>` ztxE#=l_r&kA^4vTDT3C5$v-w~6d4f^E zi+JDG%S0WsfQk10TaE#!o>Fn2c~~i67xId}f9b}^MXA|bty^#OUYBZDZ^>`pQ!d+M zt=Dix|CWE-`2fQ(N&bgr5iiQOi^}X8CCgH2HLU>@99=EH2fcx7j-re3(S@QQF21t} zl^(82x`@JKL=+tXIl_)~!E4=w-yABP&Ogl29PL9(*$87RGjS;bE!mJRQfa|Wp_MG^ zi#10x@yp~d7HsOEg8qeav&nhwJ$72p0v!KVOf9@L?ULVpVctZu%E-S;*Gv9aE6&U< z$i7wNAw+&Rm`PC`LX1mQITaAay@JdM0sBAC^U5e< zelG3C2CsXT`gQetrv%}!!Nv(e(Q1mZFXdzEl(v18=XWYKj0}lGhPWq=ME~{m?ph4l zRYQ1PRG}bOI6?@z5Eab~#Dsjz z7EBQAT!$ex<yO3v$AXXMs$L|xSZ>b!)~mAHqsxt~L0B^I^1 zYPSu_8VOWKCx$p{s|x(A<>66sLi(wHd%Ng2bk34S4JBj2XEy)EravNyX$!Ao#8~zm zWv!9D@427&)@IVkD6Kqv+0)!uCn_IO(P3||t!+@_ve(D56Fn-<{-OJysklwnp8Z+H zXBkrEqbBuH@%Yl>LCr;h&sVedyo%d@n2)xPGOrs@^{t&jxKclsFz>julKBNxk-makTa6g-iw zdKTW%qZ}^~y#1N7=}UEXZ0SAGi0e!B33anQUT^OPe>kYUa-~H5WVK&D&()qM@{JO& z-HwZxD^waFIec+85Jchcq|(|&Zg#mPDLGw7kOk1)YHZHP!XXO!Wx_{Ub6={wwXkwv zPsti#S103p3|*dv)U#(|_gD0vC_Fg+0w! zyhc4#_^p1Tx&E|K&G?{qXU^fgoYjsl^)vSKcY5kZBX^9;)ST>kJGrFx!0Awf&&o`5 zc+>mY$%nEp5?A}oN~(h_sG^GM8wE#NsU^5Adfg9hwM84jUa#0 zQF9PLh3%kC-xtiH%13Zy7i_FW(7OVW2zt?Ww0S;lvT}e-oN>$7tK%uz(f6dvyJEFc z;!~F1{O6K#-NEZMdDl-RRvpxgoXmK?enD+x?(KEa$l5(`zlB|iwO4bgIJ~(O@|}70 zgG^*jgQ9!$>IUnC5Q&pDyQ4d_H4M~TDc{Ctg35)U36;Nn@?Lw`Lz zesonRR(Zam9CNP*mY8d4s_Bza-bAkad0+c_&wEmA)Gx2A+n(&;ao=t@SjYYAdJfpr z`uOQ}`Ku{IIDXQlT4G)mjn3SO~U)M zMBJN14r+;pG>IP353&pxs*4&U9bsv+A4AyWV{1){+%#mNmZ&?+$wNvCeISj@H$Z|74*kLL4U&_h;Y~ zOnlMyM0XD&Hf%;VwOQq?_ULalFSoU{{nTeOO>R*G)?|eV_FAk%xrqO)PlT*sjI8P> z?VaC0$NF+4eY>TsyG8x$ksLBir28SrlAYjQ4o9w~x0t8{T_flBrV<*vMfmuCtFmMk zRUun{MISlyN^@{AbK5jWC0o7y3k zIa)N0$)4D8InDQSJAYQ})Ne80uDxrTd3drK?~vIxLPzJ5w+(RwrnUIT$w8Xb<644H z;D+T1-R4jP;S^GM2znHIjOs#{p`}wo6|5Sxqw#noyV8bfPqPoS@LA}mS6YALK(_bs z8XQdyox!?kb8JKU2*!?zw*QO8u2t?sRyn+f9L-wX&$LPi_0aaU@HwFP|B{=vS)!*> zp%#XuElOP*?e)Ch3&k-CgoJd}?<)49HOPqJe)B*j+LA7~l%Y#P13a*hqaE@M!r&m- zg$Y%n`1+4~p|;2ej$pz&lp+R|+((xVQ{O}~cY&9exbl6EeKA$y7&;Ee;6u~EB0PD3 z+VYJqjDs}5vA6JCrC!uZEOj)UKnRzkEXP;&4OM(m54Q_YrbDN?!2>|Cb_6v3EnNS2 z@8QtY#M+RZ+tV+EN>tUx6zRnmeizlJhD|MDB`k*e2QH0cBu6|&yi3PY#2E9F5G?sBQdq%;4 zwz0)w>Tf2AjofTfN&H9g9As?lU}p?vQfj2?^^uA1&I!5xRKi0>47{ z+VTtPh6vG`u0)~G08|$x2Xn_G3C(Sael0f+Z^}fn9vXFBk|CN zh&yzBxa+9{#>+|eaN&;Y-)%+A$%oIocT_!>5o|0zj1=K#7RKckVy=;~!;n#CkLb8X z-1(RWLokNH5pbZZF1o2}SYJ93nZxF6vxXo#x#X$FR79l3sgK8#HOq9`lg_r(%uhB) zTdX|!So%Zg%3DpuT0;o5v+97+t&o!+zA{u{q;g2gNKm6A>sOojjL*t`q0X6H|1C&7 z?OLyYqa*NFw;m#O8d2UXZgS(TPsaBOeT4P1v6smAtAg%{b#`y>6vdnL>@>Nr-+6zx zNv~CB?>>_U?wt<~nmi2Ye0ap9??h+c8I%6h&i=C|15ai0?#)Vmdw;Lcc4MSIYn)^DY-Q78umDYW-~?n;~b6m z&K*JZk1c$=*_n=JJikC|6a zAM2Vv*~Psrad~Rzgizak?YEPY?bDy$K5-V9k~y=o^US@cW-p(s&m^tBJ=nLgb@$VE z>$!QeP({;oeD^-z3wrnTkI%g6m%`n*QccHxMjVVht(*w9!g=Gu$OCsytS`N|Q+VXy zy)%fL7?YwXzx%0pWw*|vqXB&=6!L%UFkT3PG;q*=vc|sw6~Jl$&lXq=zzZuX3Ch0^ z2!vaJI{+&cI1WJm0pK5plgAh6~LSV>j7-2_ypMA>4^bo z0`SFv9R{{f08Is84&Y4yumeyXKzZ1uM*(aHP;LDK!hzfY3|nAf06q+$V?gfsM{)qO z0}va4@Boz9exG1~cc`fC0_H7nAAsmlS62^258!+O72@A?$~{h3;BA4p z0ayyab^yQ&KpsHx04piLwg8F;;B5g;@#@tCkTn3t0SFJ^bO6Nz_#FW90E7pCzj_d>;N_gux-I~%D>T+ z9Xs^_X$x!)pm+en1CSzs@Bmr|P&qDD1OvGPAYx!Q1uUk3xfDQh07C?L902S9Fb6<7 z03Qa{Q;f~bz-S8CN&!yCzv&b}kbtceFr5N4F`#k)L=3H0403!p48$b;Mb{J4O04oOc4FGNY+fDiZjivx-127x_+5mzH zpfqmWI?~-A3oI}|Y>d631O5Y$9RGVg1pr}y(%9!{+1wrlG>!X@;sB*FH8ln(4FHFM z8I{B&FR;O59Tt}|^VQF6f5hQqU_b>R8vh1VfDvXD5(^+@z>on)BRbXvOs9aklwC3Q zzy$*+*gr=Dm>R&*__v-CYZ(S~Fff_|7E=Iq3j{GBg#qCffEvKU4X648BkXWw3@|nH z;vD`t8vmp)d;NWYy46rKBxx7}P^{8D9pD=OOV%jsPQnSP?eA~&yKjL!VQ|U1sp3JV zkPvqa{pd_;4&QF3l+ClU#$*C4tH!OpxTipV7jg!7v-)ukeB}RQhlN`0;mVb`Jnnz> zd5xUVQi4&`dzyq|lUl@{R`mgr&;5*lc38-HQJ0ei>XU84Hr=Z#+#DPB@lP@_>Y^*t zc?ExY{$5rbP?Ibt4Nz7f#A1UXThr#4*yJ+BjE+h|4|#CVE|>ZXW<&M<-x zAs`8&;xRUpPe6f1)fkQ8qa3syO|lr38ug=W7Z}abL0ibNb>2X1If_bM96MbePi9LZ zgQ5m0L!@4*XraaBDe|HS3R1!l7Ua!uaQqOO549BJslrmMZt^1>D}BcejTrf($W^7` zbI1`KJzF3bK|a9iYN${E<)`kom=s=6+7Ih(&M?t-MGnaaJU??YfgBlX^;5c%n;N!~ zUrTXB|Ma3f_iU;ELa4krRQQ$7TnNTLT*O2MVWu^Axfp1uq(C3WNXZa zaw(z1p$-`|7i5iIJYG+p{TeoAovQ6pOL-vC5=u#Av}jPWKW?Njlib2rTQOm|%PD7` zD3+1&0x=p?l8kT$`7BS2CiE`0rGfHk(xskq%9P|#Pd0M-MAr3;QR_k-)yLQTk*frz zJ1J(KOnqiFPk~P4uaUc6*AI7t(CTp$eTWxo3&LQX+Qthan#%@CrbpV4*~Sgz1_;Wc ztO~g3P_*=8bUMr)?}d*G?c(@gxC7}U4Jf~|%M@;ionFk%y@QPvIhwIS?omXyP07) z9?~JNXJbfdZFML>EW+Xbb<3{?lThX0$VEu%HhTf%m_1yNx_%)(@{(jsoq3I~Ej$l7 za3xSGx3?rvteGl`xngCm_4K&yPT)LUwUY#SODxkS$-{uU&!)9h427w09dd zaE?nlmT(iJ+Q6uGhG!H$9~&n}h}>bU9kE4o6Dh*|oN1}y<9T<8za=V+FB5MNAAQ*K zB@$W2C;lm!l;vkvA|{->*e5$h#u-5~;>?xCR0DNu{FVzMR1$|r<6wP(z_V2WX>K?hcF@8Iu~RZlsV8}d#Nb+9(J5IW%eg!E zA_NuKaTVm?VA#osmd`YoqBu>QpWOA)ROD!o^PXk4IVVry=8)YbmlM?~mny&y;gv;% zO`(rHtLVoC8>_sUbNjjuYd#sO)UC039OfnD-LessTWeDmp77=33}1~wpUsp1WQ}Fp z8l$m+C$Sx0F0Ws-Ee4*JmH*wfLzjQm0(4$Dd6MIOkY z8QdlKWSAkn3xwa(ZZg-81jI$V_n-+ol!L9qA8F4fw-Dr8A2(+4-ybR+B`BOetp!C& z3FA-n_K7eeT0433<|Jr+$a0nF(&PmZcUIrRWnBL8=vhYD@rND)d!RW4RKi5Ja<7vp zYv=qS`h*;@p}$xhNz~FuZ}p2&>Mr_ezirnHd@O(UCYzrcTt_G-o{Y3E?RFJ3`63Pl zS*Dd!p7m%LOYEp4|^!c6kLW zyQ5!_7+OVUAG|Wxg++<8w};-Q=nfg87f|b|^P>8Pi_-+P?dqacL*Oy9on7S)ZVuoBt1yL)Bl zy*4iI{A^Nt(eOjm*^^2~!IbZ|$_2Fe?Y@&8PTg*-AU>x%=F^Ew3JSA>(fc~*t~T$@ z827;0Esb@5Rm@Fskez|(Zk2tT&O3tVcSa<^j-kSPLkVzSqS9yHLP732B3xC*Q^z)` zMnHu~1CiOFwXcLsEqK=bkORg&R+LznD-O|J1xCc}$#B`MDFmlsb5p|G;p^QJOcgWU z++^gIED52L43$Y?oLOfLl1FlPp}G~r0<f{XE{8d$i@#z-&n{>!@y?vi_kK7f1`dl>^wd@s z9*MhIWE7H{JsGE*Kbq~6>-`~BAh+=}m){xeELzP5E}nz$R>8Wu2WYpFUu_+S7xW1F zI;!kvc|5sEH4Ig5{5fKiny?GLT}}-@4_}wF6=0}~u3Ot3f+_u0&CzgU672L&w_q9H z^Nh)rt9EB>uYWwAS2Q6d8m1}vDNq894F%smV7wrvnKt>XiX7h7yaTO7ppWVEA>^qx z@P}ub$u@#Ex^Vh!gRj;*(SAFTc&+&K++g!P@xj=O&MzzuO$n2}x3FzLn@(zR$I zbfBJHx|XYfSl4skz>#D=$Dnro6cL1(bdw){ZUG&qNb(3*3y|J75GAP(L+Pir0$E1oBCXihf;5sCS8GV8J?4;m|9H~p=S-yctakF zpx*@-~sWX z4V4m+z}+95VL1gD?_#ZzQMEE(EYehk$}LAZ=GMzqWBkYlfD6LAf*=+uiP|2-!e&bOZGFQNmRr=-}{K7*n3V{?F z$s{2T)aqTuG6c>*G^A`@W!;q|ofJzJO>dC)B@IufRdD~b;Oe$kph?RFiF#yrebx^Fb zT#WXm3oOMeXK>}E_Kb#Ep+h}}@TU&AHpYNTyWx_{>>tIqp4%&*dxO+{W3V?Dmt>1boZ4Ak*hCVfNC-u2 zvCWKnFClzR75+8`4um35oIJaWtvM+-ari9stn(3(R8p>D?p154H3%KmiuTLQt8I<+ zK2i}B2|;=Cv(V%qjCFtz>{}Sw#v{MlIu=X77{t$sf?MZBcxCxy%Ak{XT2PJ!bjjN- z*kh3sLc-zjJe1jbPUUt*X5_wlq29^!s9c0tBLZAT;vPoS@yCezSt1eB zQu3i4f*PLux{KLTY^uB!VAJsOsWeeZY7Mn+Rd8E2|Tsy?@txmj#uJyMBJG=eL zn@)tn^~w?I^Dw9V5Z(_jXM5{s=&jKDZisVBO6tD3<1rq5DF)$nX_p|=s%_~ltT(jt zL}pvUqc+rRoA#+*ooimg_(Eb6Bs@}J{Vl{c3%00j&)VAyLAR|tAFNjfe6bKLesuKG zox2|D75h&;)bs1LcT92&J|us%gS))r+J}zD`jXI7ede-VsPaC3zjp4UxB1FFPyJ47 zpu!!G?sV~X#<_L&8<#(D)W@eN^+5E)JX#M3xxq}U&M|e^C%-fMLwA4S+NUuvfsvf_wx(QlPc|({Dk!0(w5MUjg9?k{W1AAlZRF2C5o} zS0F|K$R4oufL^^)Sp_;6fN?>B19U7<^)FR~fNlm-73h1QYXR346dO>(^z^9!s0CF} zlVk(}8jx*4xC2oO1hiA9nLwTeo<2Zwf#o{;js=)qkP|_U1N{w@H;~{!F#}x-u(lsQ zEP}iS1Y01|0(=(qF%Y#tuLDgCq&bk%>lGGE6)!Iyr9>y&-;x}ya3?{xVItU`@q%}hD_m@k`0Co?UV30RK zQUj~cAZLN92{ydISQQvr0NoD^PJ@C6z}aV$i6F;;8VT^+z|ejF)Y=U8LEr*|MhX%o zNLV1v+1guxvI>GKKxV;U6BwBW;SMaLG}dYt)u(c;}@quJOuS``SX8R zFvxcx1_A>YXtThs1#u5dEC8VxbUZNd0PtKuvV_~qw?&62@tVbPx$HjjQ$|SXI z`>S=Sd4Cr(mA~4&y;J@=4U!WZ4T!4a7>ivDj86OG`}T=(mHJkt&)P4$8r*QtmYVT`Z!{Iy(<(<$Wp;sdZ>|0|37wtU-Vk9gpgYLuUv4?-0D@K*axU#wV z^ z+l5I`4t!QS*NFT2{<3?GOuibmzWKeg$JY6<)z)IU4X(=Il(!F8ydR`3kyivVSHiem>l`}yW={_L_vo$5QGRP*U~|k&@2r-f*Kvnykm>cM zWWL`o+2Z5D*P0v&+k|B=2Oc*bY2z`yc>Xr_K>y>1m;*XDC_DTYw5f7#C)oE)Ur1$B z$5ygd?srbHzWyLq1%Xvm?s_=N5j`M)dcwKM%?48re))MX<*( z*)mBM3rjAhn>;(N%u`-XiBEl6JNI}8^g=LZdk){@()_>N7XD{EzhAV0_~&+KtZh?3 zDOkTJRmfXf+bQ!_rYZPGb1n_tNR*%0b|1&=-i&AK>DT#KDjC510+pUxo|9Au4=PHr z@-*6UmgZZ858!($t2FIM^-w90s;*=z2SP;3=22_D!=Wj#(!zQSXanI$5MftrCNPH;{~^DRo}Mr-I%J!|vr)i5Q{mU|K~mLe+wNe55Qczd~j8z>n$XXZbm-N==a3?)nek9F3_q zczo6V#NhLipBpt~{<{C$fRyVci;6uj>gxEV#6MKKwhg*g2G3+3;IH>U)!axfnkO!k zttg`zZp_j7Yy6HX)IC;DQd&lc{CN@wY$~oA+aJG1=htx8kj+oPu^_}F3t ze(`zekzT{x984ravZ(S&ba;_s2IIL%*wcAIChg_Il6$E>dZh;n2H2eFwgs_`Pe>?yMV*UjZu8DZVaWNR^q9jd+}?R&NDY=tvfN(mz`4wohsUF; zx?6K)&%aGs+!3Jbb!}G3HcRv;P$0>b9 zb7?*#6i?d6*TpVJaaLlTUXmk%!c{)h$%pM5xS@#z7pc_cj~0$nKbM3D|LBx;tC`>D z^lt9Reha@7f1JZm+Z!qx$B2RVxI3W0w+Yf0oIc4B?4iT)Wv{|z?GGAT${hYq|LRSQ z%@OVqtiG-n7PfAmscXq})=I5B(cP$hisDu+9Ia$W^eWIB7gH0>6}9}1rI=CjKV2!_ z5%@;%YlOf!AuUD!5=X3&sjtYq+i61T;o9>RSot?rHPy&Tf_aqu)YEGf(T9e!kPZ5tW9HW z>r<+J@nvP;J8%nc)ncQ`aJhS0{<6W@LPwiJ-s?q|I>*b zQNuikqB0shTnaZcnwLEp=r~iVmZ_nVJsu}=t`^zgo*u1C_#&1A!(?Byb%$JPp18d>P5 zS0~LvXf}xl&ocL5AsMW9?PrY~GtkQLZF!m=()Sv;v?nI?&?4D2F4w#AEi_wRMhf@$JediSbW>i&re+R~i){c;wV%TqMwl^DTCL%Ud^Mp7 z{H5{qQbNWR5BM+cynnoPU_9QbNZ8W`t{=|`m?((+Q4l3w7;RV><5?IRUl>6=IjKl4$6=t7XrT2!;K~Q zArLcY{#ir{8H;c*8XUN^HVzBJkcz`)6*`0(xrjla)Ey8SGw?PC1pn4iUT+d#K^f{) zBRo-tiX?J%u}d0l{MDl%Wg@IS9K?&qA~=|vBZ#wWI4c+;tl^9uF7+AW1&1$Ta?3^r zU||PH41stv0nbjr2_(KY2vQE^;#o(ZqbH;i(d)N;?b$qGjhM?0Zt^4)mm^onFc$;n zL*cAVIZrBxrJ+J@?sQ@fR5-h{v z2_o|NHX?YyF;g~L*8wFRz@p3jFXOE%!*(Mo-<82$@SY6Blzcg63t#2zRfTda=R@#B5aFnzBfRC@NFpz)n>VZx z>~xpPPkOieawDVakTWRxiF0bca6gQA)QBu0BT)b%g>YUDD02vkjY4|BkZ~09D>rnd z45{vmxkt3;k3y!EL1@4F_PTmhIS(Gj(CCmAd%I*Kmo9iG;c)ZdQ6i8hJ_^!fKnMsc zPQo_A{||d_9uM{2_m974pJ9g2*t0bv*&8AvHG}MGNJU9wE0szm(V`hUQA3jUQ4&%i z6^h0hQlVWXN`*GGX*+%|IoG+*eP8!|UBCPL-}mwOp1=C-l;v?-y^aHTK-~ z+$(Dg7mgG;M8v|a0GFr=7{j?MEL#eqP9kIL28i)ycVxT#0_m&KE|Pb ziAIJjj3#1fVdy9geQ!BV>A>S8INo6K#lZ_4L(HBJ|EVO)G8_pjmo6pZwTOE##Ct=+ ziB2Ms$C}oByzn9tU-WZ3kCU82m{Jo>zW-1T;$I4tz6ijG7hWcCss18q8G|FWDdqTH zhiYjOxbO?_uFwg z(kR}hR9^LJ{j#gq4_`%yv0Q@fW1$!kesd48en>Y(b_Au=(e8uh^2+YLDJwa-hjrj!N^3~jG%n1AFdP0Di_ zT~0O?n;us2*{yzNTD`SVO;{*qJwzn*5(-O7tHjd7hS*s#Wep2mRjNJmlB{5awj|+p z@-g{v?fDqMP@VRZ$(3Uml4fJyA2lOBGH$!VKGJ+u6?b_xrY5N;XGj~fF*qfc71}Bfd!b}W?qW&)q7t^Q0N*Q( zXjpy8nQ8LygLp&KV@shSvNpSgAZ+^()`Bpqxrl(zCB%i8vA`yWSj%JIgMLRn6t2>R2F{yP0{4u`@ zqLAP%AWIv!6B&rS?vzzKb^wz;;!4}?jBRG2$p+Y+5=Ixo^L~|7_sBJ{NZmh|ZtIaM z7$g@(V=H-5Bn-D?$aEftQ{>YNcQ>2O#^eyL{mtbqVuW$Xb&}iBJVfGDlX&8>tM^y! zmLee>6SU{Fc8cj8Jd@ULgR@ONN)4|eiMF`Xp=*ZH)^#GRkr;3!6+5EMDcisE(f2D- ziKsfott;OHOZH$j?Wl`7`+#JPDT{IKYLs0X591guh*e1E(yYU&JRXCTao3H3=Af#5 zn`qW7l2<$N#P)kD@8`Qi~0-5AT$odvs6AAg_4Dj70aIFrKzw4Foed?GAay{^2AL{~+*qwtRyvXO8u3ThMN;Y-~Y- z1yL6AjG*R%a0~h+NVy>2g7^v&9VoaU=0V62@{%A=g8m8-OHgn@l=WE}0OBr)sUTs3 zz6;VX1Rf!T2nsI9v4w?2a2FLcP7rHv-fRWI70#A{6j~|S3>i$&j3MU;K}8UHH*Sss zdDXz!5>#8rIf6h7IY&@BLCpm{74%n-S3!UT@ffa~fdmWEF9aSztZitl2U!=+eofpa z1MwJ?U=WEx)&=&atc3$!AU#3^ z5>kzDaSRTMLGTb#jUao2{0TuwkdqDO{I@~M+SrksAE?Md_5Pr#qw;Y66kdWh&{oo=Pq#8lq25}d1ix6py zth)>P?s0MM&6Rl|27|B)k;a5)AK|(V>SW$*R$YJ7|8VfsAWM8<+I;yrar681%L_VAI`1=B-dbL`FyG<0>rqz= zga1%c6ZTpcc`0`k-5`_PG(9Y5G;kE9;}o|TV(Xn`Laq(|J_mNzy(IH#_Q)e{ebRzg zrlI117invlbM7}^VqHyqt~39>ip57eapvmC{L0Y}b&~vrXZ&xf8aAXAWo^6TyJz*f zlg7c_GY@X>eSaU~Fq7vWIaBuB#6Bm)1-esapMRQ{Tf2YoEpJV?29-AF~>Z zNMaXrKRzj4;@E7s_Qxkeb^Z9k)15=8!SK_)yN~A`32h;EZK0A>}b{=_Lu$_dpUp1^G~F%1H;cyt8h^=cjiFfKHmDIr4#4Cd{!2|%$8Z#^zr~dQU6s= zaQ5m~2Sf79F3s5XdadDb>iEIaGa2U}GIwW|*6E&kTgHx79`tHHq;NL-P}76X3yj_*V~@vX zZ;W?W>E2uCbtl&Q{bgR_?)Oz^(s$pj)U3Vn{_3Y&mlte%uQ~NYNkG}5(^a3zMne*! za@bHUbz1RI9o_QnP(9{kG~A%DBy6}*WmWNTlls=T!`E3!MkCES2f{{L^iCI#v>IJ* z^CIis{MccwUA_414Xf8s$z=@FGtXL6jLRb*1;?j2A=$H^I?o!%@jA?LH$UC=K1|*M zN~*@od&F7qE^t?@1ts;-#-|ntr=alVcJSqQU!470`^vfayCYwoM#-)U?u;H+QtQ0N zj4SHb%Kpzv>a1fwT0c$Z9=H5_War6e-rrvx-qdd<^qtZ_!E##5)U1)VRq+RgF4sF{dlcMixa=fU+p;qtDMP-- z_gXK(WVJ|wnco;* z3Q>7E>>+JeyJo_#q>971LTi(Qdxm9VYqQ-~nbh06Q1pGy?+BUa_(K0SH)iXZFN*O_ z9zv~1cV|0MTazPW`1V0w#qmG-_UO7VrNxffQ3b4`hAoT?E$6gRrixiN$n zMM7+N*y6Rx2x;*UkrR$zSd|&1SivC@@y$!R%=pg*C+%jJG!Hx-Ik4{eNiTMffa%_g z>mcNtDPI!eLj`yOM@ZdN(zb@2#<>|R;K=pF;e0+Gru-0)h*Jb|81qPf#N9s>>V(&+ zJ!rD~>Ddpq#F1DaSnxQMS1n@;A}m;NB1S;t-@hHZ)ZieEDUmARc*Ok~TAb$Ek-GHL z36+}#j+U(*d$xT#$y!duQ_VU>hawCTXBWD*1lL|e5vQh24c#4@Eb?>hJ4G3u>b})L z^v9`Bx^)iC3pBiF$5a(P4*0(IJn%hlv)SjuN4fgmr@M3tRUHbwZw@-dcFCPv(@->R zxM=Z#%4VuiQD=|JnWgXIcnJ>TytV0P{9e00sOtKBF6!nP|F5kNYQBFyFJKh&DQ^0n z*q8O~1v#?15^OS+n39xU%+t~GJ+O|OZ&GRJP^HDZ*`!mttZabuq@AhIUtZ=*P|=%n zqUhcpV!6C(kq@m?ogA^8a53W@etx`g+0jW~g6b+9wbJ_T3i;y8N>|o-+&UzhFK(&i zv|U%A2U7ZG8lBx%YPa@NIQIUF!xin?HFl|Mo@NP`1Rmog&%ANPbb9T6El<(Ijk0C_ zii`%z@lhg*xzQchf=6kelh-TXU!2}{=~}uJ^>=%OI8MYSp*WOCnDN`vo?u~65djMJ z>~-7(`2yx;KGV9ja~p6a;8}129f%kZD4<?>#49mfB0T}bZ^1$r| zP6ReQFtw*oAA+?EJ~t36;9S7htgIb?;=y_Od9HSF{vDVakP)D4K*WH-0UHVmoexw6 z=oq;5;DR?aHUP=8o5uy>1{OFt(_qi{^v44^f~E@4y-Sxa0YL*|0yHo)ClGvbplsl9 z=btVBs~a3~|3G&jAkcn^-Yx{51vCv96Hp#tKv0-DdU92IW@XkC-3ox|M&mzpTGYE{u?3|&j_A9(H>EmvF1thI1yvnr>eV@{hf%(C`!if zvfli=r7fl5`ZpqW=QQsm5V4Czzlm7L>cBJqxIF)Mu@W-KS$<=}(r#Us!$0@*O4P>* zBKG?(tNUo6ur68N(7&z1v{iP`f4V&XtuXnP*nYRBM^*X2oq};9R(0{sgOZ>d$2_iF zdiS_u^PBFQS1x~e_M3?Pd3k<;21`Q6F%P&MpI?13fk9RfNAaq!eEo2EA$yFcHAEc! z*nel543{&0dH$<^IA=;?3TgP`n`g4wjRGl6Di2SYKC}uh&(C~WhYYD%h=JD`Ct~04 z;)r+>2S-+n?C(u73TfAbk<>*W_rabl?taS>jHU7KotKQzdWnua(yRfljOV)s=9 zRJMXjUxu@8VPB^EZzATX|MG7{%rA1_Z$xZ?i^HiV56+Q+m0_Or1NC+blD!{r7)A{# zoHf-0tAe*osdQn{pX#?9Pkw$cpOf^wksOkuW1zogc3Rdehy8f=Y3@P3b$h;INEbGV zmeSREN;X7l&|&v_@9TLbW@$>HZh2Gg4HP-w``)3e+@kR2y#MEDxgr*GEp~3sq#p`p zjOZ!6GZII`LuDGCHX7xGlqv5n#rj^!DBb8)t~);=-rU5scV%7*XPvpZ)a9YbwW7k8BeU7!v#{L*_(JXpLQepxfUU3s!{Q9%2SyISI)E&|F5oX9FCZqM zC&2MOcPzK=;-XU{n6L0L>0+{a*p})7FcB0rc<8 zQPE!jebnvpKLK<_NpJlGK$pI_F8WUZU3ua4?SBc-Hxdf|D?qQfb+z*2>-Ll50A2O@ z&G@E#YaF0^>UV#cyrAalHvs4}D{j|}1N4g<W zv|Xp7_NOcN=De71Sd%3{cs~wGcTjTi-fI#)REvkV!}|6;Ot<1uCVNKrx#Nf&0b+0l zLLx^ivzoX;a~fUjeaQkLqQng7`d3ywz!Awrk&sATty=O=BmF%!~eon0Ri<5 zXM(H)+T6#F?*KS9M??cE=^0r73T%norpLCN89Becp$_ot?c3LVeLax01W0=I>N#NC z@bDYJ7Z9EX2VVlR0QA5&zb0%G5H7$A(6#_L;KO_MAqkKI`lle)m~Zp|kqhJ-Jrhg# z6hX=vPb#|1of$D-&&&#-O5bAEyr$LM3qh{WHaRx0nU&-XXW-%byG^E#ePsw#RsqZ4 zO9q(?G%vtYNJ~OY5z>PYS=_TX6T~t=6Hw(K?g+6@z!!imiR2n!7JTHnCr*NH2y#_f zSs9=qU?0F7gcalBlK}Vx!UO?6T2U_d(Dv~|(i4PFqf1ho+`Wj=2n zh>S2`0Ok%I52HG{8`h@Bp|0pdn=nAj>wJ^SCb-=sb)K7y|&x0KNe3K>UF( z0|)}b!U6&F41f&a3}6%{8EgXp;sDApnPAAlaGDrY6FbMmCINc`z$ic}pff-=z#^b9 z3^`ak#=-RIESOQJwf5BDRLAvn{ zCv;Qfg8pcJ(sJSS?c zD{3H4@)K~fL-V5-<4J9B8$r=1tByl+5WhN_@aq(kl4(nhXW~n>1S&E|wIs@f${~pY zmoI#Ma_uh*0)zNTUz;dR&l4)q8#Blhd3ppQ(bGx;Cw3XUpE z4rq9DegpsS+9~MX6c(?6ZPl=DZ9zl+BE9&O@E6;{1cFaF7 zeN#Yfxb@-3m;j0$@$Mlw23Z9f4SV*A;H{6@NjL>KnRxifQCI?V=Ow9AWDcExDn{|y zb2~$%lqMCNzjV2xvg(Ruh@3pSc(uNvvFW-9M^%(gYQEjx(RpVDPF9&%clYs=r`^xk z#OFPIFJHax9~gY|_TBprL&GBdqy9^$2q7ldylq>FGs& zEpmK8Hap0KhWiZ=WcUI8sbc#51_=0)0Th7XP0%4=h7%t!eAuwK!gdM_5cXJDK|$~v zr$b8vV7-LjRB&y98NzoCUlDwbz`o%7fprc(X5K?2%Y^k0%v3-SV0S>?;Kv2uEo{Z`gM&>HJ|y_Op=$$sBTyYc2l&~-%ID-}2kaDh z9W2tY*-kgJ1uhC?51;{bKKNpxEdshM5L)m)VeOnSzrk|_#DT9D2v~T8H$Vy0YQSms z@pFYT4rq$N7y;b?L15!GVb21u8aNW{$*`Y;9|>>+TQ{u7X6Dv_An?u%__&rXOQ1>v zwmMkLK#YNif{qAp;{XT(c?NC<^a(6sJBRtORKxfGw7Uy11rQ2|D=e!CseXXM&`g=o zAb_}TiC(;Z(?Y;Rz)HXxXt+RS2Bc6!lUab9uo6SP2%16giVoPTUI2s~{BYG~rKkK0jGwT{f({LcKJld__%p2 zhIewna)uS-zhj0@cEu^1UNqPLYi8Jbq;SYt(akpummHFj|DTv4*vWVME4}fnX%!vi z6DsDPOY+>Arc=ZB2n+)5{Kt~aXvw1qv=4L8!5f#)Kbuf7RV0(Fmz2NLYpeKkN%q51 zjTX5j3X`4wu_PbO^i<|K?PS>w#GE`8B` zU%hcVIrrX{CH~uM$C;r_q)*`Pm*aNwxsXXK4{cN$XNHwos|yO74rTH{#dN>ayRu{b z!f`uUM{%p)rW+f_?PN3az1CHE+&VyefKg?&_DpaXZ=Y zZApXD+P9_6U?)dur?#d0_&k49mPfR6Js<;4r zxy))&vztDVMPWK;-F4ShzGx?;k`AVsd4{r?v1lQGQKMotJZ~s(J2S6UTW67JtG1_A z#O7OSjODx=)2|z~-r{L1~ayYt`=SYkG$FZAbH`qb@U3G|X@0`UEViER<+TETnoCxR2Ia$0; z&#twE_Aie&QW7lec>*38wagyTwX+dCcX_nxvd(R@J;A1JlcjgEYq`ojqFO={y`h$L zx`!KUiL6QlOk7@x1pmAmi<6yHf@|X_8GXQWuTkdC=8|@_$KqGg%@e1H+(kINRAH$A zhZA2ANZ}zbM(*Bh*sfN!@B{^sjKWi819-?_3P&_gB4jnGI9b(k_io36m3s>kZGMuu zwC@bHGZ<-looABJ?}f&BXD4&=ls#cr?P7`gy|kxXkvXqk%USwKiXBM%u=5gu<` z6i)6kCMe+bO<8d(m%P!y|>!6$RGOBnGu7SW#* zhrD`8)2|lFA1t zg7&1FR-$Q+8&mNv&*ct}HnR7Wrfo>=WmvG1?lAf&LqW;!!cW_Df0K!-(>^vVIz9Up zP7>X|PxEtelCAgp4Xmd>{6~pqH6us&vW_oH)@jBI^z}|_6>BH!9DGDbXEpiYoDnJtZU*&c&-yCCWOYS*BSWf&n|0PTquQS%HWMS4>-G zjfvQ70l}h~i>b3PVzZdC;h_Li7!eu|u@LQH9hoSHG`%GZ2SEad%oJ!fqZ2Yc9Aw5O zYCfq&lUd0!H5_co+vlox3zAI8UX;ZZ^>A!`na74hclO`oDxViQ&bqIKh4s}b-p!#H zw&74f-wE{-dP#=l=iUXb`&k2Gv~W_a^wMxGC3-zk-rH2l+&Pd{QGqwHX3}vH2whK3 z;DlWu3X}I2uT*qqokOYe4!LrKfd)kb&jjZkvCI8J?dIT3rM8GeSpK{wP6eBZD-UAu z<*5ofO!`g-VL0M9sfyc4v7sj|kPl<(;gS?#GhUuBkcbBLMBFjCzH=eAh9M{UzHQ{l zk_1~L^rh>;HL2js)i;e~s-+gkA|WML$5{<8zMSAAf4HkJ-;#9V_QvdwM+W>>**u$c zJKE&tvC*F^t*ULXU3hOXktE%&@>Q_FE5ijP(0*UMzs zBPF^35z$T*{uoD>AQi+?!13apwK)k$9VxydA?+wWHU427el_N7nx}gUcbfA@1^Qe+}(?;u>97kW#O1_`C^ub z4_U^T`&jrhK+RkKNw2}3#yIMUa)N22@uxK@mW!SjBX}xlkV^7O+rzqK>wGM(A~be1 znk6Jljxq7GlEQ=pvL`|FZX2JXrc)<>j*S$;15mI^lZGQTd0v{E+=r?M*BnbzNp*qB z^%blYtU9|edFny|fy#0wo86o#TBPiwQ^pB5UoFHOiQ-10? zLMuMDl`WLPb0mSU<+~vean(XuppwOr@`AIOQiE~3n{%3G=9iN3;Wnt4g~Bm?@+J(K zh*-EUGMr1~z&+79JY|J3jD#FGxFD(yV_Hz<4IJ8hJnl!e0D?3-qB~n$G%dfVus?U`_(Y!Qf;zI zLp8^G=XV9nc{yOp)jJLj7w+`Q95lVuRz9 z?_!Km(I&(<8)ab~;b!Dy!O|w_oik+5V8S!u47^Zwi-@7X@g@WaRSJZxUg~Qe=~xNT zk3z(AJXYweT1-Jg!m!Gshv-73~^Yt$)S%&H)6c5>_tpE&WnHIB^~oNiak*g?V( ze@(+~EAPDHv_Ug+=cCIzpH9O_{4gmLgSU)%nG`dyg!gs{w!MT(FJ%;v&=OYYSmU}~ zV-9h6c4FOWW*%>cZxkji!jUtm{Y_Ll+w)3O((`FpSTc@)v&@IjGd$_%$)poj>@=1I zS%~7CF+C1}JRJVvI)RiC@REp5V@Ou8OT!8OV;V*qBI`WZr06X0W7Fzb*n@Dh+bZdZ zoj&KKU?5xielpg{rcs8|Z&{d33a|>?O7IP(Rj@Ff(Z#Kztu}%!@B&MJXjJGt3ci+l zk-deKLC;w{sU{rz=#23M@nr5+VkxbLNA2QaCnbyor zDg=88r5SWn^ky-3`5|_&BIW34O1MhQ-6g4~RZw9?>aWD4bMRdDn6v2xpWP~4sR*UL zU!tNEe6boQZ1SuWbuP8>`YKunh0K#mL&#uA8gXdW9Nr8LnbMxQ(+W$GP&^BRgITao z5+_SiqjMIV*TZDn33JG3F(<4%8N0J+IU#p90k?}(i^uVaQ(2VRL->Y*T|_3~5E~l_ z_YV0cL!_e566rJv^`69X@1%qK4yKb!WzLtFJ-|ZlwoBnlrHa|u@kxhH&cb{zE>h8w zU4oWz*bHB1`|VtrO_8)RiODL#mg0d!CA2MzI5wz+*2Bh1F}mwXDeqy*#U3YALR{!g z&X(*Y4^s~arXLCsk%Xd6=F)j$8M2o263KRW18G@8BDs)Fp@g)2M=!u~w<4R8&~WjBh8g__P>NLbZsLJw&Vgws2?)>rzM8Ze>ZXjxEY#E` zL%?~2RGhfbGq2R*1aX*>hfdOiin6z*TvIJBF*sBHeQ{B1(YdAAV*_+N8(S03A$Odj zd!DpBbke5lpncwT{@TkSi)en z7x&G=&cyL|DV;m}y~wzTX;VVW7yHq1WTl>bB&IB7m8l5vME(KwUbJ&4+lX7Hdj^X_ zsrUey(J}EMB9rljk6Hh~Wxmr*YPA<@rmVBLredU6sCmepv zb7P-GJv7@oYFGFUHk0;eV5VV2td+?!EMwnb>YXW5t1UAzlv~I# zR~171`r;(%$rhYld$lr+nfUUa%lf92*l<#3i(&v`?^3H=fg@(O7jF=f%f#z4uT&m+ zTzTwArC6=%giTf6va0;;RRxEuiVo}N4&f$a%XPGjS9ef-dhkoxSlJI|`PwT}xdfAv z{gX;5=eJsleqbt+{*-s~ zsv}KnXE%Sfz?)#MA#HAbo9m@Au9LaVq~5ICWH-Or*fR-!GLK-&hbQsqtCnUT8p_Ty za*InN*#4}q=(Dvp!ZM1RBsSOyzuDLK&A#zbHz_UXm=Wf5q~V7dUb?*zwNrNtxs3jUY}W<6fQ+UOo5j= z=fSsT!rZR)b&NK0yNxu5L|hf_b*q+I+HHY0ZG6{!)qUF!B^;Zz5BgivE^P~bzfDR= zx_dNwX-)Le1KWtqXQwT(jmJ_WVxE!5wE7Pvr5$vf+cX z=3{&2pKN-S#W#6%bv7a@5aimhnf|lacki6L{!PgImy7qjoZN<8O4?pE?HILpyFX=z zvx!{8k{$k!`{JBqUM0m0Iw7j$K-$g3K?>TCoHox0v+kjDBxoq;y-tV+NzGjfd0PI5{&QF^pSbp6;*iWvl|5p-R)6<2j5-~Y+S^ak>VN-!NBiX% z1~*2$iabqeWIc7K>|UGM0&0}#Eq!cP%;4oyGPyklbBFO8sRYqIf^aA4_6CCwX!G(1 z<^nNiL(;GO_is(G8IzNZ#{z6OWa_$)Nc^$SF&|2Kcdr9~dt48#a3*)=PL8G7y& zZthTl9%epicMuCxz8sM90h=oJB-N&TYtB?$uv7W`^-1T03G8o5U%RQo;UnjRjaGk_ zt|gJ%gMZf7ocWL=O==Ay>^KVjXCiup3fap6^;EHay(x+ z?$NM~Ar6Q{D0Ausjsu(98>h*pF8zk%FHn!2Fj@v>f{q-_?6&^L^Q7pNG2YUeW%zV_7gAnUXl9A@pDm8kE@qmQR! zDMVRfe~>73cLGl_+xBpzaYHS6c;u4{`=x`Gyo#x7Zgx*lHF|!F#5>TFa2RE>OOSZo zoy+?sU7~UBipK)3TWgIum^O&)&iU7-k~kz;tPJOmdiEvhDM^-HiDB48uDsbEddlW#y{d}mU8Cx_OC-#ug3hia*5=|YLPCBIy@}{wYO8fFTE>q(w z+8YE!6=y_14Jxc;mVr+$ixRFPiE~J0H_J?pqViA2ifIzZSbkQ9<21FvT13E?jO;Ef zsxmm!L3Wm;y9+ksWi+3JvXJeuw2e)wT4k}xT9J40g2{2}nXH7-fLNoZ- zWHK)Bz?5nE6@j~_bqB~Vy#KISI45UYCtmu~3};zm=ceW$ z5!X&A7?o1}piHP>JBOsUIiKy@H#aT%Rhqlww<&Cy0BV0i__5}dvgzHa$&RXPzJ zJ=La1usJdjp`$-P-CZ)>HZo42Qb&GdXf{PwfBoy~txMWhAKePlVEO{t`LcA3mda&)m=Nf-y&f769gAWcD z7%q?lfGQvaDB#^74=x0=owyvtYHrLuyU=G5~ z3-A*mtO;Hu+{FO@5gf_AqAV~C;XngCZ3oo^Fe1kt$qz|jN`g-ZrX(1V;PHVqxzO7W zVz1y%f+Gng9hj2f<$;3AzlMM7c<*pc8}f{O>{9r%(Hb|kos6OJTY@cHj9fZNmXW1m|UJe!>#LU1HhO#L5eGv5kYY*z6&?ts% z7${3E(|TG0uK@VzPi?^9XETxp3^h6yxzXeZT(Je zSs<96&;_06Vz;aFCD?FK{)GGom~rmmF<{bxJqPaactr4bfDm#U|LoA&$IT@IyXndO zH`%RLKOZt)1O`bHW zCoM=6Xomks&tPr|9P^UKaq#0kgWnFFr8#E`E>;C8Id`{BICS;u7@v^LqH8Aq*)y25 zPliA4bFoLb_$XXDweTRXnt6cLfH*M9YPjCHyRC%Ad)JBYFVuN}I* z^N13M>!#z`t*#|^JZ3E#&u$&N?7eWomhtSC!PiATC~e-76v%D`hHmNzQTCrcp55Bb zSo|;`rT4c(H}7Cb&g$O|o&LS4r;cX-cIZMDBxtNsn{eoKNtS*anVZHPI_pn<5qEw& zbTSQ3v4BhebK&#fIdu0@aDxRgiyXkATOYCp9J*}^Hu$q+gM-E8_^E6E=Fnv_SZ~it z{^8J-wat9<_CmX(;k)v?<5wykt~~SZQt3waVlwlSqRg^xJbJ&LDH!3A<<%v|i%yh< z)^X%Lw$w=zEfB)V=2~T9QnT}>UsGrJwO^IXRrs(>0hPoO=`UGa>XfVO`YV}JezF!d zhSnc!`us&H(5_8^WrR0&5DvTc;yF0HdiY&O71Fxrm>T|KujrQ_0(^)_+Sy4xJg&TiUlZ7ls$;8_d1#)@UUdeT9&nf8;htOU+W zo%=X0Q9k|@H)yJPy1ioXShWRro$RNX+)y>|nLX>JBP`rzJlL`Mmd&cZ%}&~==e!+( zs>Nv|Y1EiGGm3dU1KpQ6K`Z@iph%8(&;*-ID||0{gW6*<+8MZdku_yFMr6~?j+eEo z-=5WILP~(5p-7IGf>ZWVi zjYMTa;UTVhXlC-;v#h7Pk8$&%9J(@(WMbO*gxHBE;?ay?Q)e5Kz`BDE=NrgoxqQ`Z zmn5cfaGE|W*D;51Y>Ng_%E^e^^2Ep~8L zzCJ>irZ)t=_)aAnl{LnNBGA#CRg~=J-L=QLzW)4I9l`f}0kAJV^1S+03%3AO;=lTPjRGhaN3(OJun zCayl|vaQ`dHvS|oq(52TGa6e|=9Q(@;ozk?$+;*3Q4;+6oc~zKd@^-dyFnqD#XJ!| z?Ob0Xt8g;6{9DEfR>R>bEr`o&iH%KWr?()9a^oz_U$r5DR4QR$W=?S>3$?jE+*#Ik zV-DN*>|=fPKJJJ=B)94dQ>TL{F_-nanORPVhHV)skx`ZMVk6{-s)0KT@0+a-E5yavg#Kl`fwtP*oSA za1C{|V{lRW8XW;`JJodFcagfTf^m#O^K6;e-C-(uB{JNne2O&6Qf(;J4d7bL*N2X6 zxL?PIdd|1Ag;{`c3R`w&dHCX`ejd}=;C%DE;LaUEc^xU6 zFux>Lxvht6Gy0FG^Q4xI)~TFZM8u(TdQxz`hLUTQdY#FI=+OrHnuqmDQ%qBR>5W#_ zhAzSM;tY+v-~{d@%YYr3+0|{Q=^1&Bs+RJZs_R$*7X8jy?!m&LwrL)^$s+mZlmv%p zmaDFFvZC3`G{0{wmu}}A+sv1{BOXl+dhhbmBuRuqWyYHE!|Hpvue*e3MkJ|s1-E#B zId|~UlpT#1?Ecsx*OjpUkov50`=76|fYkVQg{#hD*|Od^wrY!PhQ{#~r!yEItU8lp z@?E^YuAZ+JeCO2s!7xU#2(MYfQaC!pb`}OTL2bf+b|`DC?aNja2@>~9LG7V(|OCeR3r1uUgLU zAL>reJFNBL7FA1alXI_X@U^!4&f2|Y?}X*s^?t>;mu~#!zuBzC#h}!zW{I^>dQk*Vu>}gH@3&Z*1&Vq(8j;Ip^!m`=`scKkU)eBCl%suzBy%KiU58 z!0tp-V#1KsMK*xHbCjt><*j%7#22DSx=fNHU`wIl#UcOI+ zAyo`J3oK%A#Sh-ZhSzN-(v`5hz@7z*04y)C*G#M=mo8t1x3Yn#!%hLq1u%Ko zP+;$XRRxv{*i9ff2Yu_y)tewf31LMjF-BkSk~D9H=VpLl!}{R4Ed^EvNG-zF0K18& zw-YR75Q&60z~PRb?{YVYAWp;!$CHG`Ya?pfVV8uYU&-Zgh!M_o^oD%_wuZS&Lg2k? zSmhuh2wMXz3$QTS`G;M<9Sw;)SUh2I7*87pjTfe2L6|Yu9kv5l4PYsN7$KzlY`p_v zBY+hWHUh}$LEIby<&fNimB(dmv>;(AaDK>G!iz9Ty`TSy?Q7K{-#HEZD9OKN`#RCN zWE`G^*K@BsRonLWrpEa5E~^(x>CW$=i{-Vl$or41`Fm;2$hipRFSbx&dC+1{x3&I9 zY3)iz(fo^4!}K6gAw z)DmpLoX??<$HP8Cc;01YsCU4lV7pl6%7;1Q z&%5}CNQqu%;}=Ext~_5o{=7?!;_D-{Q%RPyP?<@MU*S@dp&p-3N>g}aB@2?Cs8Gg9>>HgXe)uXS@e5m>P<;{m{ zi1KfqcPXtur&ELoGuXrw23`F`OVj+Rh-0Gek(oi9Vah&YfqMEE&A8AJHp9i>!qto$ zDz!U0rRnRS(Y;DkQfH?!+ccKSY)%{Ta+B_J*(l$4>VmJ!j(eY-Rw$QWbXi0QxA1kC zUXJj~5LPEG(j#&gN&8@5?;3IqkkqDvu@at)^3IJs1@iLPj2_)mIOs$24eX%eF9y`R zen%xY=hd*XqPcB8=9f6lh`ooiQYFvLK6kGSXFz7EUHdH-H=ttqni6DcNMT~eO8R>+DjNw&|Rv+6n4d_lZyQjc+FckJ5$!86)A>=VZ>O~)L) z+?zG$J7u|P`$)KoPR(t4igxB)nZ`KLACqm9Jo{BjDac)f9l4jr3c-Bsf-N)cXgXoa zm51%q-<|D0F89mr$h@I%n-04ODS;VIdE>BNW}dAfm8`qf(G@ zrQ`jUWuKCjm|l(XX&bes7*UyVQyfmt<|8AX9a&c^9y4;l5mY#`9JWaREh|Z<#h&FQ zrV!d|EhCn;sZz?CMLX74^=0xofKZ4I|Y?+@doX&&vBjFk!-}GOOg~=BU3nP z$<)k|E4$4*S#Itwx`y8})@}MYO-!Q^@Vbna!SI$G|F0X&@t}{N?QaFzt zZ@^NKFv$3^IMPo(aYb zH^lT!wiEKL8FIIb0*}3#1~JQHTYcRc`SpEN5RRHxz=nnpPDDX zLBvI7wei#*4l7e2;G~Ig#gXyYmiEIUg%bip9dUs?J9pkK1Ch3_;5-fY#)0&secxEJ zVjj6Nm>cn!`2>HGRb$(ts^H}nPhX;Q{bI6POLRtG>Z$V6#?EUj>cAsVxH}ANkg9zw4RRvWF`iWM-G9 z{`pY$c#LzE`wP{_qfJ(~OlvX=UStmC=uehDXy>@NY~SaHwlQbjGB;cZPEgols7Nxh zKlDUSe^o;(#Z{V~^*>xLk@VT#aMOB5f#@h5d)SgK!<=zV8 z6AU`ea9iIpn@x41$i8I9(Kd`L+jx6f#|3+(!v5HYm0HRE%|q{JXF3x2ol4Q=9QM(x zFD*Vq(^I-X5xuJ4>{q$J*z&kOti(V0 ztZdnA@y{Hssb4_O8dg;MhYv}5)%v>W*qXjitQMGINag0bL7MN$p)XM z8IAT(Cv`Su6fB$hVJ6jSZ|D2ES$W+mDVN$7Dd?JVWj5~C*?jP3 zag<%f4Xo^s?OHzXlgk4FH=q2pgJpg`n!8>mQ~Y8_KQVfQi*9Vn($mm#oSwXYbItx} znY?4t!ya?K>WgCjm?1VEqjDLkyo2`3t61*V+-%{-_}RAFHm@u8%^kUO@~%dIz@qJr z-SZy{r2F1WWn8JwHTK+n_30rb+J4uvbKxb~dn~(qKi0@U6Xlugf3z&hfXkY?s7R@y zC}1pkapmB>Ye(bn7(A-v6x3wYZx0zp0$b$w0eiH-UrUg#d&76`*5+wCE&m^1Zypun zAOC;9ui4kS+NYGJMWxNOpxsPOo3@EcQkjwrk|c!Ws%aUO8k81AC1i;aB?{9<8zz#9 zm=cmLgsk1y=li|ybMA9~=luShKRRd5{Ly(mUa$A#`D`STr}{U;roRXDGM(e1$PFem0&Miz; zZGzr%T)uo6JfQ~wv>w}n<$xj_3WO*!p`$rE%GX_uN3$o<%LM5a6gz8CXP$h~nDCcC!za=)`Lv5eE_vBk7tuskz zNliFv5TO`@CRPU6{b%O?m#o#16kF54FFA*vA_fGt?2CMldz;bA#Quk`xzY_NtK3<4 z!ra4U8+QZZy)EK!_1dFnPz8twwF8;q_IviNp58c+ziwsL zx28t3;LOMuhyRyV3@#O!8T$@BPrR-ky*;Gy1E*d8kPcw+!5vLoea7FM*7V};wXckD zZJirO(nO=F>*xKN7Kl$#PY~)fKThSHXg$5N;^+2v=eI3-e!TqK;&(&U+h6MZ$139( z9NWNY&9`li^9bSFW@_$s60oOBzFUm^Y{RIyCeJ;;*le7;esc*cCutK=iZ6zs1s*%yv9F$X*h$-7gU^6Z~wt z7hVgsVY zi95-QXkS)}-PFlaGZ16N#>42$m+$n;golZ6Wn+YZ=WVD;b0~#0`zy&DRcfA?vl5V) zcvySTSYw~*h{oia%bob5s@u-%gHuGm4yaYm3AVPTng% zR&`jpO#N($x>m@h&HcoMXHOiRGc7uE5fc_xlb$}Mn})hW=e^=#H>m_?UX|slpiBr` z`nlsufy+`zmgh1`YOezK-yaDFuOCm7jkrI;#Rd_6Kfc+5qCBXG6K^WqQQVw zE1`^3(+afZRtR(f$XbC(2FVaO(4Of5Eg(%}0|Pw_5v$EiCmkT!{&$Yvn?-VfGhg5O z`){5^6>9=_Xsd{9WME!`JVW_-t%+18GH%|xs>b@Bw-?%4Z(Q;JyUjT1q{OsmyR7is z&a<)gIXB*(-9NZ#N0h(W-|hWDYw9-ds$YG>_DRICbLWTG3wy*hUk=v2xb$DC59c)O z^IkoksXCtM9Xxm5UxZnZeXs#DIY4(wFBYoWekR!_+mtC3wgayTZ<0`nCe2_wO#?8` z{%v3zu$puPO2GFyKurdz#|a>alH#05a3@%RlPsFD2QqfzkRN0R;%ZHPfm2jlRqVcx z$A1C3gwMt=1+orcOBoo#Vxlw=>O8U7xc^K;!}-k{=vuWWW*c7E4o+RV zxGlcpaMts~i^XkLW(hQ9?XlEqg(zDCprz$ylaWS;1SG$(h3&U#t$3BQlQ=9Zt#u9n zJe_;SY6YvJw}ge@m~jBTflvs1(S(!_3}mC=C<(!VMUL%e`s>6c#*le|TUdCsinnBe z5vvt`y=NGlTcwM`1#WO|ez6;QZ9=H-39R47|2F|*W`WDrOM)#f5g|*M*>TJ6UOKrXEd$eAR@kDK{^arcg znh=*Puhr9-RL))z6-cQ5dawnL5U`<0YX@AR5t>HBdS$&e1b}F(1iGA5%7(g(0WB>j ztmZWK#;p6;Hc=@y!N~ShX}Qfm!}7;*(b|McEPd#T=c1?VpcyddT+z8{Q@ZQKoRPOn zja5%UoLS6(>+bHkxcY+pAVb|bVz&e;Ogpgr>1nMp-A^ei#N{=Qxg5=ffz=O=lyrxg zuIgEVsY@%ub+w!QY&1_Pw93Rt)}JUjRS;?vuX`VQ2kXfD;##5K?qZS(^fU#9)0G=bFLd@12XPs>00iiax`4Qj<>Vy;{pv`X%j( zK3Z9__-#x;8K*y9`DE<&3&!@FLp#o??=L*K#b<-hn)*5O^rFqE)Ye;Dy;>n4v)v70 znFj^M6=Ag`!qdsNuZax9N-WO11H2Z~2r;cVFElySOCl6|ABp0%OfBZfZqQU+p+N|t z0bX`bTxB9XH#+P{d)8YIprY1|7Cx^D_T^Vouw59VKm6be>BVF-d7H|J_(45Mip^xa zSpQoi?8%B5!2*jiPpg(8UUg%Qq%J{peaY%Nzk~booGe5>ap$&G4YULEEz6zD=F^YN zo-DKF=WKgFq-I=yXX4~G$SwS-{=C%-_SNDq56Xp^(!=LJIX#;ONWra8d-oU0Sq@D( zt^$GPL5PV3u5e)tqtc2XcBOEXtW*1;InXV-k1v@WZO(ae094|V<`%esIM)blLfd@G zvkv%Y6{deUjXnOJ;ZShd>R>6Ts_=p|*uG$B0iqW!#b-WU?UAO=yNutRO8C3Z zYc$Ku?YP!s-(#O;%$$d-Hv|p9&Wkzrr&g?)+dg>w*N%ffR`pztp`4tXkX+{EL_G?V z9WJ^lKZN#Y7ihOCpGMqwd(|BReTVh-B)g-Uqj-_5DjD04QM(0{D5^+4RuiWa&VHFu z`J_mm`-3UYVi&*&F76-E8;L)%L;l`+=CR6~F(y zVJqH{W&6)m&-**+6>#HW@%@?8j(^|s3T_OX@&9&i&EKie2R8<<-T!uR@85TP#pa>A z{@?45{e3S8XdZcT|9hjOj-AFZPPL5fH=I}l-1%fP7E_$8_e|fHyu(d4rjVqXF`cE` zlw$Xgv<5KgsAplUZ+#GLa}h5KX=0o1|0zn*S2?A9iep&Nno%=Gq#Vdxa#c^HQjq$E z8R+~@2eWJCqMFYI#$60jv(oiP5et%a$+vaJF$_6^p{+)~6hAP$wk$&NiWDC=lMF9n zFtNcUSlatY@jO}OM>?l<4j=j@0}8Fg*vbFh4z^6rVj1B1CSAW@UYeC{?a(Ngg`hGg zm=mX`e^9c&q?m(t=l&roRaer|4ENy2_Mh4XpOD}lRl+Ca`!5!n5XX>jPhhnsyvAfq zJRo}l$GjqSy<{9AZU3)bNSGY=@3hij_P&u_O3#U@G`&=VR-o7pdx#@18Eyp zotL4Gw$w`Y-G7s`RE&9ysAze@CK4$54kk2O$%6$J!^{tD7z1d2?<@GL@&4&mTd!(l z;;YgzwMqn&b&ARG7KRd85SUb}bO-FA>EU#1Qx!6mFqPS8LF}($!pcSjutW<>_HVAW zT2!gDaxOG;6+>xtQ|68;A^kJZXUBU>q4$IE-sz1#cH66>aDNggXQmY<`M8gK`a%i) zqg83!?v-OyGF=7Av{soX)(V5Ro?v9y0A&a|sc*r?g^RHqJ`sZe zSjr8ME!YEq7u$eWPp0WZ5sCPH5A#r`2-gpGj)Q0^lgGmp@=2Of=cX(&NQgaVgWIhS z??^QE`(hZV59k1T(1cZxP;6xL_p}*Th0x#fbKbJ|WBMs)B=i{} zE6Bj(K;iPU`YC+!2|0bUjHniLWa+T+f1=Iqm7z@HA7g5{oI)N?#z7)%ltQjlAIj4SgnoP3#ph~XR@6dfFygzRMpu~0sofXC^TzqW%X zOQ0z`_`_`eXFK?47o5y4NcCVT%;{lYEP%Ua^>fs7jI!siWl_hbX}vPV;%R(Kg2KXS zYKxRQb6P)}rEo<;eKW0))|RtWmV0%A@Es<%n%Fu>ci~$}D$_(0FjH;}NbB zfB_TJUj_7GqAAA4+RX-&MxL={Q4nCk0>+itc|1I!QfGQd<{PJyx&Y2)($W5* zS|X^L1Jr#oJRTyg;Zrv8D6UMnLPqW6(R4fZcS>;Argz^&_M}MgjZ9F^B%eI3QhMWT z1qI|vaJftp$r|1R$Q@#Ox|n=IQbw7?*6=B`FK4UD$S2R~?_-fSv*{^F_VIz*0*c*b zhw}|nxw{s^wbP_@Cg~Q7yy9{xHjv`OrMZ3KBs5O}=y|XU{tcZmXEMHGvAI@pD=dtPh-BR-0=I$4j6a z-f&MROy2~BiSknHv;vw{#;I`fLQ^)*b?HH;p{ zO3Jk5<4so-sIr{81|6oCczh8psCRP&sLRU3taQN6XMr#tKA8=VxxxF=6&CWym?~zN2ixEN}3JzHUQ5OC_jzhX2qikZp|K;ww9@Qh^hGgyQd`!sN~y=x9XPPunCMODxGE-k9X8zP-#!c}Y#D#zlO)b2Dq zMnJ_$$ptcU1&f?Ki{H#7-hJo=Ro;J310SEoG>GYX`ncCjxV(~n(~RPipx9G+3j;m) z;``ux-i3=SF1Ap6yiX5%PmgfWwY^fNH(u0%I*0Je%9OyT#foxvVkQ0B^pUic1Bz9U!X~ACf9_(H zy0DzC#~IxRoZur~FiGAeb^=GrJ8XI%m(f7^d+0c=N4L@`B^d4kL|T-mp@jI-5VNuZ zwv<8}*sy>PB;ocO{vfG#JlF;~I>GU>fMxxV zyAn`F{VU|GXBk(BT=QOx^(&C*n}w0seh1y)GGje8)L)zjIv#>oh-Ef4r< zhv*gs?eKb@l!TB)?YKdFCYl-Hw_ zUa@ge0%=T)!D!jN8-0$My7yGMaV(|f14L@)-=EY*u;$<_6M?!E(s=ST$%EN&>Tf46 z`>_|xl;kdQ0gbX3D6 z7?7V&lh4ZUTNg=9E6CdVH<&xvZqAopdr2Kat zejk&JlV5NjZ6^0a6=_Ok5pcy#2MjdwnEP~f`6A5c$Jomwb#-KHf;jeOM{N8E8Z>bI z=F`|pr`r**NX(^0fm#Dth5wj*8M_@dz2^dfB7Y-0Y^XMA2-`}3DH-w?!1?rN_S>+N zJiG576c54V8L=WW7={xtgl$lWT&luMfLJ4^>d4*Ou-&TqtD68OP)R~}TJBrF{rIA_ z31E4Nsv<8he;#n_e2cYuw!dg=)Q)-}(^Qf?!?JttS3GXn)qsf_RrH}gm{#cp``1c8 zU_O74kDeZ<+pPr(59GPho7Ahkpxxsih1GAjdaWM!g@4_95n4%1WXm=!L@Z_ackFb) zqIF0}J@T9Oho~wHhrj<+Hc9qlz)j3&sS*touqo6!8n}h4=6%MT*lOQTd@k+7woccW zfq8#b(lqwctM1FBMCq`R?=;zpxX%N2dkmjSo!b8%b3XDlX4`A5-n+)*ue+1p zZB5N@&i~%IzbyrcJA#aN< z?_Ln#>aF3K%1TK)5A}sprSWd;@Klf=PI-mk2SyCX5`To`wA#JozG;=Z1RAaSpVHfZ*fPw~tuH#xADy*;IrnSb z*HWI#F<`8X0qFujTl3P54HkQX>EUYDQ9~iX;7D%ryYApr%XQd`CpGa}h6@c-?%|)b zJW4z5jb|5HLl||7ZON>v)-3hk$>&#J(MR&;(FcPbEieIxjRMc%#G8GV0H5MYWx2<^ zG$%Jm^Vs)x{#nb7xamWWCTo!zABcWlGY6d4}jD5bF& z!uB2CKaAea)?NEA<=3|lFYcbuwekGfJC)|>QM{bucxHasil){|pa8|5ZMopxO1fow zqt;cJ+I6?J#dJau;TE#^7;1(aQ-rl^LU5g!k~*WO3Fj9oC@lfZ*7>h_mHJ~q+zJ4J zB?XIOPSOz#`oohjR<(qkfj2+w-=6EzdtRSP@Zz;X6cq~Mr~0%1fHO`Ih2UKn>;h&X zW0Qy)UMtW@nCd@Oq-tqJ%3Gb(zo0@@3fKWIe{o5zggKo*Z8~B9&Y#f&sa3BS-X{Xz z_j?&fOzM*sluLU0%x%4t?I)Q0pzX9hW*4u6Y3Q&;BO{Y(xbBdfXh8OikaNJM7vpzg?9*HVjrXJ;(+8hL|NrRkWMgO6q^ABTkR!z_2J{yy##w89TBN6W_R zY+@K_z7+K!BuvsthAl9GdObI>keIl zlY8LH<@$EQJ+{D0?*La}DL5Qn-)#(u{cQ|{E{4&f}j z^1#D!OT&}c<}LjRt@taxKi-MkZoI>)*(@S*8xipY8qlWVn6w+id)U$lrZ= zx>LCZ8J_cREixSnynQpcK>K!Ed+*lIcOE~_Q22XG%*I@sBk}>>j*U^5Av0sLQ3bmb zxcC5DBi=A(frw4?XC>`e$$V}qDxK36`7V2Wg-;s3BGebjGK{%Vl;9>;^+whfdeRtP zSHn%~VM11HuY4}L|A5waS@tqqG@NP2)mQHqd2*wbi<-DbOZpE4WJIf;vU4{L>Cai! z5v|_PcMYR$IP3d_3+@*7Rjht*v&Ed*!t!v`6|67k9)ME#4^26||C>U8=h8 zVu=bV1|+qvK=*hycCM9(*I+#z2q&I%D$G;-__I|jgPmt7)!&`c5wKvXy>GPoqmsLQ zebh)qSIhhn(~Xg%MBrhuJ##De_B21Aw}OMLX*{Fo+LZ|$E@wUpO*q`e-Qe)}y1%KB ztVkU;%&cYMG^UBiKte0%X*^oOLCDx-42}s0m=q$)SzS^rU_xn;RX#ufDK&|O%%Ldv z=G|=!Cs}EW@4e$XQ$c=Bs~0jTeC5-%2P{ZT(Mgf3vY6#zg)FvX+*cKTd~e{m39OIVwH;8r*D@g5nOelhca8 z6tS(E(=cQ?0H=2rV%7JA^E__oR}PNTsaAa!wEFx7EqaPuoA41EDQ=aKDmBuXjnQh& zp?B)(wR0RbgcK%kS~9`(IiO9U*s%}=uPBuwWyE%~ypqVMtV27cgH6YQyNL&84MvI& z;T1Vc)IuX`(L1?1xc-G>a)XY9*GEy-H*rW#IH|#)^i(YU=%UPf^J*Q`2JVDBx$&g) zB5hmGd`Q4wsyb3WD*BO0;JZR<{LVn`Zy9ld9gkrugs!b*JXJ-AvF8r_8`+~2BZZoN zEA@mQT2-YBGv{pu8Ptqvl5m2fFw&H1K7Z;N-8m%X05@*u;+80d^ItEgsIrMo@}}w6 zg%KnfWa6>Z@4J6?^7P+L#bHS{r#4m_#YwhA!g`r=heNF}|1N2(>lH5Gwd-S~bFR9E z9K_f5$LR-ur<2z1y05TmxMx-4ME2;*bbGOMn}^76^7$GSrw(?}tj_X6Yn8Q{p2)3h zW7ev)6^(zt?3C&{e<|4K^CaANUHnBP7v!@U&qFpTC6cr=H=kpE&e7~G$V#gD6dL*? zF6$&^Tr1Y>OIkkx5a(5L<5`tAOctLvin|z;i<{Pml9^bcES;8^a%c)@9J933g;0De z3eSj2;dH967)uZJ9ltIkH{Z#xbgJl#hO#jTQ;pa^zeiCaH{pqxcmVn(+h0vs&Q z%4Ns7Rijg@?(P|ExV7WruF-dEiF=1SU3S(NkG|jFxp(C8t(}e6oR3hOZ1*O(=(_e8 zPlC`G108br>RZn~rUpFgrw+y42$X%=zs#v`>+$5M`w<@xEV7??;xX&7a>ew~wJ9mu zFMc#P|3!)~6_AZ&Gw;lQIh>DM?~a@9x!r!|==Z7Ey@}U*Bcq$XmJ$ENZ(TGe{b2g9 zICn$K#I~);-jviIhwk2-ezallLbDT3zgyk<>QfN1KI5|E?_=`~D!PS^Lawvi+@pPjA0) zbij1n>Pvuv#2Jej_=bc60wax<0IXnSQ8J_|FVbhF<%rpot85_~pk3f9CfJAT6dzV1 z%NN!PmzxMd=E%82u7dn-t;;#eoc$P+w1+~#Hz6g|mWdIP2r*@0nPO}mx+&9qpjNup@fAcBWlKRw_=-@blTi3Q*QsD-+tiT&C2$LRp`bC^2u5M{g1&gMaJGY|-FaVz)vCoPGty&7 z4L=aXWK#Kjn`zy-Qhj@6ViWKMNPSqvnVfTH>q!=q=NMR^!a(e%mnfH{$MD^Gs_rXN zTy`o+wp=}*GlaQ0Zgv}EemJbdr1`ANgsX|;U8k8gk36@jl^u>r?YraL7Uel@5OPye z8h1XcOzvoRz_FKOy>`VhW?wqRKlR)>a95ajm+H!W_p)tAx!2sW6`q+Fyj~o;)pNxy z?JD;t3-32@&B9KzA4W5uGOYmsJ~NYoF}Ou3$&+k5XfA}B9#Ww%F5f@01~gQJ*IE@a$N6~tM=Y=tjxUj zw<^*r8TH=WuCXXPqCVTX#ipUq+W5WQT=VkTc^5o#UHojgpT@e*+g`TM>!7~$x*gtY zy0Q0}uq)q*J6hK9>T9o*+gpz5Yg46DbG>^1bj>o+F59JwJv4O&P?REuUKqPcm!e*P z6(BjV-$Pr!0UV+)UOr38Au-arH(vS+_dMk*&22ch=$q?u*>VdZ3oWfibZRO3T^Nvj z@1fJZk1Bo7rw%tSM0aZvJQfgztkqJ&daBlrouRBS7 zE-NanwcQAbUAL3EY+3@kV*)JB_kK?C{V@>GNt1SU+Z!_AaQgrmri}Yi&hTYYef{2O+G3kM1e)0sI1S#(7`KT z%Qnp%N;cO{zpYD4VUGPd!{ssUOS(=)8MlcTS-k~rF(y%7b^PH>?d_@Bp zwCK?QqmD#_(_|*;0XuB8)==k0#oCI0Ojr8(qr$`PVA`IW%fshgjS%MWHFNm$8l!DU zF^=ROcxBSF;KmCpTr5^jJIU7H3rK2M*{t1uCC`VSd2v^v&$gRB$9Kre)pXZ&nj-_N zoz+HSZ?1l-a>>KC?<%gnxV@dY!#DHFihn7?r|Dtrd$+M41{($*HoU{`?Y~yRS3Di1 zY#fE94yBbfr71A)oC-YLxUY=B!|2o^RGIE~dAcKf&`*aF0;geRbkUZj^VC4aS*7`8 z<&&Q=Dt3=`BRUNs(DE$|bY0uGot$ez=_55A9AgwfnzER|y)-x5hPzpDt3BS|-O>XE0~_qgFv$+z|wegPLOM%F&O>%872&oFXJ zT|itzyW^k1sdZ1j+hKfI__gVZzYi#W?xb0H-Fz3St68XMYSP*L_O_<}3(`Tw!uGr( zHzyl9ueZf<*g1r}+_$_T@?PBY?!6;j=C`8!T*@0pj91F9jJ^2X;PjTtAAkDX&=qkX zJzIb82Kh06!IYdr7=ypF$m(OtOU6_@##BSb)MCffcaCXfjWLdnX`UX_Y8;z)XH0u= zOy_mfyQvmGB;CmC=1+r=zS`z7AO6p}gLwY9k;{u&lXNqY;_{|+)8iJx%4oCuiWY)s zBbPdZiy{+7nv%)6A9gi!vk4GG3RSi!IF~@$LuoTpWA;ZIPkzN-IQ|idm@dCS&m_Bi=?=8jP=|ewxNLXsY%J>2z3>g5#P>vjY)P3fx)us()TI9{|N>>p9dj&*PR-2;?aI#iJ%LK47iYBcZLm4@S>eQ zFVZ=3oU2g4$yi~M@0MZG1<^tJ7oI(>7DG?QIIp;=%>W_-lJ|Tve|}DQI6}S(0YS`i z62@I@Bjjz&|1JQvv3-+o`$~*wrLX%!1^q*@eSFvSgGc;@8B1M6(Kq%R8 zD8zr~;HFMxL|2mSC3*uMr+w0*c$6T^*lFgW6P4N?^~z9@o5$H|Q(%XsvD5Twu}-z5 z*cnqz6|-v>3q$%m^2a+bjF{%{g%lWR4kZX(O1JGs%xcqpEoetP-gZR3zvEE@4FQD& z%z|lL>3oC=L-(I6^~J{BT_QShzjWhwnk-o{ZcsR!Z+y!#xX*4X2Yx@d>H=wNYyn*! zt5b5p;v}M!aLN7{;><>0`hTq38GpPi+Y2G`9}6K~W*;J4QhUH}2%J57a8Ma}vg!Qv z-bEn{Flj;y`W-K{TYC-%$}+SbQ9`uWl%cOV7$k7SBfX4?lPQDVi=>_`0h0LT|L9pZ^3jy9UVmtGYg%HAk!XyoJ)b9}>E<6sOPx zDS2UjAQ1O7WKRIJ(06YdKks-b*rRYsq&W9w@`C8!9z`4jC=UrG%22(> z3yuWqhGxREu~m2F zAL|E~&D>8^hdcn9vgRBJTU@(qL$Vqw)sUn=kla~R`MKg}*5N;&j)c(G>w?%_I~~p( zsuINHanhlLMR8BQLy|jeV$$IJnYhR+ProO`8|~Crdu6|05z9=^DM6UK6u)MDv)m6f z8A$v5Z)pz<_lq*TDzj5qBRL47(v>$yWo*+Z0lih<49+UqtiFt|J%E|~w(|FmD%G9A zI^lcf>sXN9L(_qf1loRgc}Q(KG%3xI#B~lqg-b<6%YNv-{hlM3Ff&evc%@})Hx+M-FUMCqtlA7FIaBgX*?^rX0QjmTb}9r zkVPNh(FYUgL$jTo&Xk;n!!}(M`H)hj3cr^Ymv z;e{wL5JAHB&Bl|E$)ENOyRk2J3k4I7CTaI>#J4R?=~%XF{t!Yp!T5@HKU}(RKsRU0 z<~l}cSG`Lvct4c?aaLhSJAm|t{tKJ5)92qAPApfrR`cc34>Bd&oVKo zwukMhNubdfZ(r$)v`I=pwz3OJC+n-*#Yn3R{6Qcsl*j%Wedi!}mSkejCX=%_ybh|B zLLT>PSDaZZT|49~g3rkR{6DcB-t&^M^35 z=LulC@sb;^EO{>JvFj_Ur}HHWV{EqgWK_p0Vj7atWU;z6qdC5MU9eADkM?aZG4j)P zYT(?eEAbzGEq*^#zhQr-&)%sQcdzaG`tif>rPK1ZY?Vdvf9w*^UEgB7_2VD=naPJ| zR$hw#>+t>k$hGaCKK^x_ogTk?WYN}tPQPZRo?O}b>7VnT*)MM%UD`V5^6$^DA74Lx znp=iI6uZiO$JqTD8@H(OZ~#M+shcs96Eex`$snB`Y;OV_K328|X6rs26j^|pv~aCu zNtt-#^_|rRm!wNQst;%!yzClE&=(D-3ociC2U|)JEI#P16;{Df;>tYYx9Jrc+a6>^ z3{eawZ(kYp4Q!HGtq5-{yU6QNbTJqIhRteTS{W zb*Niu6}jGh^$FUqtl<5GsiJD_$GbNi$8Q|V5JYemE+|?PQMw>_P4#+}V2>DPy8d=U zR9Q}66O@k(FyM$3?wMGW+Sh%5l>+|m> z$M0w!>2}|Be6|c0g{=Ru>RBXiOAY?!bo#0*gL^h#Y`#O73Q`owLY1|>j;=hV7|Pmu z;pgDpSkQ_ycuX>t3|9i@m~F1O3r-|9m78$L4c-aR#A&KC1mX4oB!g&QKHX-d;EjA% zyJh{JHP^Az+?;@SzN&NA52?Q)6>xZC!aiebIdkbIEY**M~g|q~(bsw_fq~oW)IcSAFcR zi1#Ty-}5ywa6xYVC1}!lh`ZDd$9i~f=-1Twmbbg0+QLL>=;bZ#$e1_e_zFS+_WyCINA9f#Fpyo6~ z1IHMEav?e$GK2x)kyK@8%*((}@-3m`3#B6~clv?68n9AtTvy3CE2-3(dJm@G+4kgQ^lrkQn!r~0m z0ES#undx>d>%lxZqEaY7kj{?=4kkGm#u7wjl8+5$NmVTqiHl-BXgmwOV|~FYKb<6p z@5=Fu?u?oHM6Woq-J!!S_Hyp_mXpjDaCebqf5AH2*P8M!L9SKD&s*o*QF&YwyH?)+3P(b(2b zcz^d$B`-5er?pC9_oN$>5{LsVedVH1Gh^4loS>`Y+LqOw#~nIy(cFF?!1u5{XC+)( z+CvD(1D&ggsb!^jC%vs31lqCSu zT?!IT;jz95E0Dn^hp`aNWIhP1ZBwP9hMkzXS%c$AF&)#0c;CipPEg-QO?(#c5EF;j z^fc49&Rw1OQq}HkyuZRW%EQ$4TDVYE!we!4XZy9ZU)5x>+GC<`qju9y1hI;Xll=@{K*F9zQ3FK#5IOMdx>$*`U`Ga;(@z8CG|(~ zAeLG`thv2|s#cPtPGDnv6XXPaueKmQ6V{qm1dPeCuq$!%opCRzUql&Bx0p}LWu25I z&$evUF~oSzc0!91c!#O7N-ZKmC8x4ghk#^}J~lDqQ+efE76U~-lkAPO6K%~x9@Jkp zsD2f%S5dP$#Qid;momxB^ zH-~X@R7{lJu_#{+uYnPjf=RBi5y!$`U|`%XSnBCYLr8D9QVnmR_Ak{e^@wKbgV$U} zZDRjGY5MT}I|=(2xyEllxn>khFKOzmxRJ5O9m|mCPzmDU+{$6S&EIXV16ZJS{`~!2 z_rD(B{%nIZ%SmR=NUBn-5S-0XGwwp#gSdX_&UOIkH#G&_Vv!sf(P|1DA!L0JXJMn` zG%do>-i#55_lgWKa%p6Q9YTn!#nJ@ZadIcX)NGuVwf3 z254*@X%RZjdGl>^b?fZ*nc;}Ya&3L>g(j!mLO<;p%63GR@8*D9B^O8r)RaF=`qCvqoc1zpL++t7{lp%K`3%6*>&LJw1Z7Tuy$O?38B%XT8nk4o3fX2 zT@7V!F6G@NV;O)gB`0;@OG?p5N}Me;^}Uw#`|ah1T@ezRolojcxYnxGm3d1y-DlB*^z+$HXGFr>y~bf zEi9(WdKQA26SIzinztVjAsZvd`{w>{?U1{+< zS{;%)3|OI_Gmw=$V_wILmK|$7hn~8JVyvcHof9&c=FsBgYPSj36A8G5w&NWUz4~9C z|GSPDE$`IlSDz492la7QByiP3@CsA%J3pB)W)SMp5d)y4RdtbBrHlb8T9vRzR8c|) zHio%sf^B;%{dfe|dOYJ|E$qp{cwJ>Wh0SFHnH!Dn8ze}FX47K4`l!z!pAG~s(6hyi z0N!B`F75o8gD-F8y)T}u>dY}L6q0f@p$87U!lzjSy4oF^$#Bc45G;Y%5W2%%B} zGfmSaG9npOd~`tNVbBEGOZ9*l%VOSHVn_8)ZPj=`F}b6|v9GP%T$m7nu~FrkX$#$$ zr&d^>a+`Q)xv^83TR2b9{#)mM#x~d8JF0UMUZn=V;_+Wy*_S>6kOd|}H(I+EH%AM% z+#rdQatfN7XjAu^=N|`s3+L*V=zCUM97%4n`5`9m>rqp1$FI5OsS*E(%jWo9q zI&Mi7jA6US-(kpyJjQXVEGW1px|nRGJ`P4NUC<#7?mW3;xu?m5 zknWuc4AYg7416B~m~2=Z5X0G9H7kewPJ#|d+dE9LFAZbY${0EACC>2nn%Laf;nUIK zJFVmCz~xCZg`r^aii(W~CTezz^+_2j@6*5qL#@=K05w>eq$M9Pb^}7otLc8}t>%;I zmNmjFNUi9wfR~@;D06j=6I}j_vCtOgVf2BtHg7)mAO;Ca%rr?#gX1{NmKU}cTGeOf zFsmFM*@|5?CfD!rE-1jf{aEFyG2^-@F3px3Y2K9vo2S9yxmtf}t>e&VR2V}pUYEqN zfTbBl(VkxE+FcOTa@O7sX9b^JFyPu$aw2-X*sSL4mzl`|!rRZE70S+S@5BGTh@|URwCmV0heA7|*X7_vp+t)^*$=FpKl5&5;zT=}_g&9ye zck}DhKGF=|KOI|lW)QqP{bw?i)N!YkGXt5KD_EH;Q(o>+Kfiqv_XI8H zSN{R(&x+l&(-iZnJ9Jv#b*#CWe@DqY=l1K3oSL@kCg57omC5F3$w7m}ptsXgjvDnKpWO~a)h>m_GAPRz4CsRg0=7n5%|1OpM&Vj2k z2{dY5$-@`NmVaz;==wz1O1^n9E6!_FNz-2*&zWKGD8qlwk>S`M6H3_M)6I^CcYe!p ze}6wdIId?^$=2Gu*wTNtU zsXpf5?e`Yj`+V;`>%+2ZdI7u7wu^j<7cm*o#)$b>M#H1k-*H}4xoF9aIa*(hnP&+B z`!ff}l|p3@+=Z?bXlS_lhKOe>d1*xCG)~QG-oEbS5#(+mD#EbloM7-x5tkw)@oDQU zcvyEc!h}?9!#0iWTx!i{EjN&_nHL{Yioedn79-l{;X{YE@sZDD(dU^&L@1G}bq%Pm zyftk$Y#Ab595`eXJR4B<#inH7rpGu z-!W1nqPUaa_mP))ADwPAxQfD9_$dWfD4X9A`&W)5IChxsx9*%sggUL2eCo;9>*+7Q zfVW==J7mPakAw1f`MJ3<#_)RSUDn`G0_q z+IJ~zIH){>2%8XjD4j z_TY*ux#We^o{bG>w9gT!dn|p_@2A()j+5L z|EErFo}R>! zNed1Dw=d@sBRi}$aH|89cz+lF9+~?V{$l%Dq8i`FJ;WZj%CB=(=Ht*JwTL6zM{Zo? zxOA;)b=&x%&Lc6TIOyml+;CCdPR^v-+MjBzGhf?=5It2Kc@jj+z6)`s^#TKRdl5N- ztngmR#85eMlmWs)K1sUpLCH4k>R9Kjc&1PxLn@tY1T73c=P2+}pYiv);SsarlHN`% zIP~^oMmRTjH@wwHZNtLs9gbd#zUtuFwcWyN$;a}@+W<+#CMQ2D(EA~d$lOa!PJL7X zb*+xJP#1r*CSTZ5d*hos@5h#1-1YWcv69`*AUlV$3h{?so?OEO>e6jL6caHBxepSQ zF>>s=G23xF%$S~e$G#cM zWiM`OS7~ZhL*U`Uic6KHmr}}wvpa=cA!I_sB_kkVci+CBhruph_;^ySsY#wJoZxs^ywni|mj6Ed_buoPnk2m#bWaRAQU%%WczefVfr+0h#!{+b0^OI);<Ww}KsrGco{n>**Z+Gt%mwWE#;j6p(eVoV1Qn0c! ze^K*^Gvx%Ix!=W(j#oGQ#&~4j|6Kl{)5xEs)2|u9Y1&(OXk>+(R9o^A_UsATqlcO^v28p9WRsQCSZ`_l9ZBgfr`Wegnbej&odG*ZsO4x2eY85xiVfu4LQdq3PZ1NS*sw?4Q@F zzh5erOvzntKVx<&rnm3#i5WN;<==(#=FINt%YXgnsaOVD?)MO48+sdcyC9LvBWi`& zhvF?KVHZ*#osRrG*UR^qZtksGBK12f=`!;Lo!TLHbB#{fCUu=a5IpWfy$o4OSK*&x zVUs^t%lTM72Ja7#flI#$Cbq<32Hy}&xL<$h-oqeHW?~R0FOhe3i@myaqE?YxE0;QQ z++=g`_UKkr{mx+BDRcC`Oc|qi>dKqE$Va;SeZF5DLfq^^ZZhf}$j%sZ3fMqdouQ;d zl0(KAZkh;FLqU)5gEC5!Lx^J3wCHF^F%KCo$v{$yW#P;GBS>zb4J5T&CODYFEk$UF z!Z{=4#ok=LD7xx#h@2 zy0I+ggg%7Zchy*Pt>5@ngx|fyjfI!@N}~=wItAkqH7$z{=sAgyf9#;?rUiqLrq0q3 zCzuJ#rseaKz_rnWCoV7s201S-ErUpk0SBt$qF9?lUot$i$Kgs5{p66i!!mHoowt0A zW4rso=`_AYE}bExgWPW<$9aayhnohA*P={N%!kY~Ri+PPmx(ZdM_w+!ePjZXw#sg@ z{y-Jk3ieDR@YYE2s5Li7Qw!I-L$_82bqf7DH43uYRsY7 znO3_0`TF>ngSNiC_WhIn ziyhA%Pv2@A%12NNXrbkljJ%m9He7&ii(`@mxLi0<<_v#^w1JTayI;5~^rkz`h2nWb zMaUD4;1_53Xcir4?p#EE3=jY}Jp-@dZSdehF`AI=9pvRya{r)|3+*&kgZVClY6+MjgC( zvS$9^^(S?H1kMDx>)E?7zbCwcG?8vb{>+Y!%Zf)@U$)Eb)A4?7TjWich13gbji;{< zm-Tph<0LzMGsZ*iye~VOYng#VcT~@3x~+M!>0q2xI)sSSuJ>!SaS6SMD=H7a=45@| zci-8QBK7Ix&3BuX_**Ej;JwE#BM$Sp%-Jw=%~RGK|3idIM9pkG$<$3Ux`!W`H%x!X zV)s^{t9wxQ6{04;+@l#LQkt-~FGw(73`YR5Y1Hs#Q0|~D1L~caVGmoJ+Wh)D=<}IG zj(@xasnsns*um&`W= z`C&sTFO>}+DLg|>*S^1dONs5ev3z=FdmAQBfeEk}sJ!C;-T;GP(54u;NI$q}iie$^ z9{eusMeS{6!-T|VkW_IRA)l48OK+BU*KNk``Dd`G7&g{ti6&gNjy7rN;{Vo-B*?=~ zn}NAmOmQo+Kw-AE-W;K@%xafLVUAP$oKUs6wX$uu+2D{4blILs)(c40|;xca*xZ1}e9`bk^ zbRv6v-bSJ%I9BIkyQBQBsN{j83s>kfzw7FT!v^9dYby?gDXPp$JkMlvNoq=gOOjd) z<%|#KTjT4yzI5)5Ul`TVOJY*9qFHBV*4-XkEttSYc*yf`sB)rPY$!Ivu(qcB_4vGj zI?8PUb*P|HxY58cVJtIG*PV2m-(l|)x8&jYGa8gk`Bz%GHhQ+2KK*<`0>o|G{!|#k zbA%(bkHqkzkoXV{5RydaVMf5=iW5XNxtnQf6 zvTP6^93$%^_c9N}E%&|i64*?G(jeNo#f*l57L&WB{a~rOAV4`4gH9eL|lG8=qfC zVu!x{&q@6W0p0)aAfEZ3llpX~bTrH{4~B6gV9-VoipZ%BJg2`lAHI<_%}eLIv(yx3 zAvINTpBx)k9J%Ve+xMyc@NGCvBbK*(e&XTRCygO((bhgQO4p7JG<;Bxxe*aE^Ylx9 zLUo(t1*rx3a@o71Z@LRoWIY0~R`&|Rzg~{jD(c76EFk<+kX0;9okX(A8%cvHtY1(9 zQ*GKfFd3dIi*}nf0!*h5X_38e0R}? zlB$*8A}LB37S3I%XB$Ub>OJcqwtp1fd2>>&u_%&veo9hoK-Fon<=lz+y=k3;X5V9v z=A8XR7A$@}_As(E73ccy@6FqR-wj0UTo;z?)3u_S2e;M(k1{9RwL+px$Q_I|^u$k+ z3k111z#*HF7x+SE7j!pd={J@%%JR``Fi5x;hg;;saWcSb>HGa^w>-)Qm`u~iicd1a z(55m3C6R=oT4Y2&!?IxDD}s3+hS$J%%QdZrjeO~%#Fn)cJm*~v=D9a<^TCG2+3O+2 zUf>|qqxo88;e+<6mUwU=8Pe>!)Nshw99^vo9^^)?We)lxy zJkR=sNRw-&zRYHIkLW6&w*DQ?JMR4}CjRW$+mms{yUza_aot{FYgY6-KmPL4Q}P2l zX!q2OcRH&+|Gd8>b#c(X^vaP7l?k)YqjA296q)X~LhXN0E0EE@$7#7Ln_i^f=C-tF z0*voEHCD2eg7*E58L(_Bl(ZBT?7~Ro@GwZ&J?-_VwA13Db!t3hk-cZ%C#8%Y-lb8N z{s6{(XQIBG)gzKcCFMg9OH(^GKvFp0NJeh6;p|p$)KjGvc%kFKvF53_1BSxuibQTD^O!PS9!`qYx!#Ak6?VZDD%@Rj^@bf-8Kg|e~uuX1pBKXiA=*m zbOBjN$b1-AL0U`6Bp|sKA0dPq9nrC9aW^yEk))&a98>5*;aA&QSVDwzwWH|>rLGtA zNRPFs1oP_~6A|0_wH6(gFWJz$ycJ)U06sSu6c|8^)#S%;c?|kc`CJT!gwH1xnFqkD z*91x<5qn1B)$r)O4wHA!LUEr_d#`Ths*W`bBQ-|}l>%F)XWE<#rjLC_RtpHGPWF^W`5I^_J$v#09M))>ZK#$SE z11iCf&@}_Hw`riDn;c<*4ms0B8Z>pvMkOA!SnnIv`3Q|DaNr#b+^5IkT9znr9MpCw zWFf>nfBqo+5S@RnOe>1wOX8oW^Jb86@^WBnRo9bx5HZ3X?Sp**fe z9s}#ksAoM%UV_ZDzM$MkaZ41q)<;?QmWlPbL^_X1T(@XGSMjUmV&2+q-Marjc zD1DRtQ752ARs60nqGdo(4T@EtY-0?$F-W0I$p+Ltw@PCDxozhq_32p6pKY3rm@GAR zrmelEldamHFIog$ZIL)_iJRIxzG{?dER9c;ll1Ur5QPpK zcQ;FogJJ1EAqM=FyBRLf5LaV3@WM3b>&Xa6>Y5&fL?T70v0aa|9l)pneg<#D97>G?8L(YPBkXbA z_I%%5cu219Ee?-7NX6_CH4%4xPf|Z!K$r?1sUmH^89Cq9xDWmevat*Fqi7CX13a>2 zd${Ynt8@3%uw54!-s%k0c28$2f+|m%$RQs;4+Q}OOHz3BP zxnJ9~NAODw7dt!mu0iz3ka9`QZUDj{A}ChvHr-!#IbX zZjZV)g7xzG{z=TZJt5}LC*!$Ame)w9|af5(u=UXkv8Khm?0 z)JsS3lO?wKX(7A~^qp4@{G5YX(G|}z5G8F|{tSLC>nPYUNF3|`;kKeM$G@?^F515S z*eXeqj@046`akmtsOZeFF&%u+UF*1zC+Ju%@+nuHA5C4s-XKwK{CIi;;se(%;LVUD ziLEbl8MTjrBGHBNg9L|aE5pSCWGvybB=}VhKZAm{NARX(Tzhr9Rpv+_YA$xR$FizP zK8_~BexGlT5C&r!jzhRMQ2jorcslgk|`JI{3<|*A+pYaDWyBA8tH7W zkHhbC;&2R%EC+^!aM={-5FPQ5k+v7g2;$t?+;n%d%&?otAX{d_*qM*mxA(CTrX&Gh zHvBi`aI%5LA^prrxEYcXj+0N5>v7L4%RX!58aWsS6A8c60k^m2!9F8Z?1S13VGqO^BrnIu7mM+I0O=8gE=$^%fbAIMPz_B-PLBSu7mp zD3He9a=@7bUux^ zJ0vT4fP*w=!yleTFz#T2x$$+K<&X9VhO)7?bWG7Kzh_I=utv8+gohe`k6zPz6MkjK z+dQ&8V8?kfjD*g&M9$r+G#cu$??a+V0%L{9Iu01VfpDQ?K0<=xs(lcn@4ltR-O2I; zItUBxg1;R2UkDrSV`ze6}MUD?gD+*OiV z%&78Ntg4QIt4O|)VOQ#^sd-3t%R7?3_~=@(FFDxdqUdQn45Sf9U~N1ghlH@kl zYB_)PecaWpNwjn|7RfPDqJ;OqzIHvuA>l^WVlKS*m-e<5qv@IC^_RaEiE`Oe5QYfD zNK+5vx={O5auD>83h~@C$1>}aP(P+_NMX(lHac92Ib)_CDJLh1=2Y}0LGx)XciJmK z0~4j4MMOh1VQ8Ua=Y~~&jwoa^t<=U5!~`JLP*H-2`Uesa8@dRiT*S>?`tY;iWv2$m zr($5TLLvbCAW&_jf68Kbj&Y+DBpc$U)C@TO32YP=!Am4z+9=)Fz|M>RbgmXO3{u#< zQxN~uQ5dOO>~1xT(Q$67VF!PsgUCaPscKY>fC2^UNW!Yn6;Xj@g0ws8DOwrF$+U=G z`-qr+$C+U@wc0@4P!1W%1>aGiQNi&D_B$j4 z8PDZIvQZ`^9Y?xAY; zbQD>8AZJ_6s|v;)u&mf6ELLD&IHAQhj-??tjdf_h`%tvU+E=@Gz8{2fVMePOF1|4i zeUD>&pQz&lF7FR`#)X+eP2>bb4cDk&Z$wel$yzr4loa}Y86u6&BhKZ0wSTnBWN*}c zs${CJ9vegQgXAm6)Za{{O^h(uyzm3AJnWYT9-tqWAp+aah;@fv(at_&^wKNU!|%<@ zM)_6?)l1#4Fo)=9CAP!%;-?kND(V{@@~Bosld#gWFcoekD)9D$E4Sa2g#mEp5V+F z_m?Z!;6d7+ky*pd#i5@hwMc(i`;hWMVl}{jm8WLT6$`zs!U#mH;V$Wna3C8ts)GkQ z_V@E)bF&hEsN5fteY7Z*I6OV5p`bA&r0}s`=CWa?{kEyn5Cg6T1zkJ_1#`i#$*AW} znD`E;Em}91esq$J80Mg5DgLgfzPrAnhbNIu%!cDmA&x!TI(4d6`2F}nE_9Usn#@V2 za(_Ld=UDrlBM0Rxr?+mKX6yR?N~~PIJC1GMiB#dfmP3GFcz!h7YJ|eOz(EgN{843( z*z-19nV*e=FwopZStNvoE4g;DX=rI-QLE6AK1fx7Z*IgD@1CC)Y2xua6#wj!h1Irn zuDlPc53Eo{^31Q*+){qDq(_9-lj=g4zDkvvPfLGsu7&|iOR1Ys0JFvBN>Ql097?sQ zaEcbASB3|&qPOf{uOBF+;8Hq>qe^aj&^sgaLTNC@4oL{WKzNvfwcZ*(#Xb7)-WD`U zb$sx(CLK!16)z_DvEkC#EA1yFgqkK;!8_*Sm$=qcbp#e~e)iXUQFzky74en z=|#g!Qj77Bf)!?>kV+AhfP#_KUYi#T@W~OCezXS(!uv+{Y^!_8q@k{_Tcu;Qm*~`^ zkk*VRr1yb>yo_5vm|!fTM`zwaJ$?~3Nd19KQ#2@(je`rXGx!n3u(^o#HziWXrq1%r zoE3rNcZ7FJ*t|)cjVa|O4@yAAkWfQx57cv(Ys;ezlmLhq!{X;@!i?k63p3@B4ua3urf^gIk^NF)Fm_y zV}+C-geZp-@ybu;dsP6rk<+;;A$>lZ?Q#vimv?L>Z=fd*@8}A7I6Z zbZRr4PzfAHL>-Kj#W29~h@L|`Q3&3X=C;i~p&}X0ccGT)5-j$%p%)q&@?xd_Sbnk- z%BnVq>Dl^l=O8s9)SHF90MoiaGaI`W^(d#DpOJtL=?FOe@*)2#$>!T7Jhlg=q4Y~l zSUgq4Dw?$VOlu_qkCq`+(yd)JxQg-UQ?;>FZ6&xh?G3M128!LWrz+VF&3Y^S>GoDt z_t({16e=osrCZuX7>V$peV)19=)ZISXw@6zE?erhzDQ;en7dj{Q+b|x`;x=O2JV}) za<)6<(ES;4b6$J>^uZl@;mTq9HgC&j3KaYxq0vsXI1EDf1}H)~@h*p`yyMEW9d!F; zlNB#4r^^cpZS9&)s$e*_Md!KJm)&@x!H_~qj2AAVzEw%BcME-n^E{DTyx*AHhJ_kg z_9|ckAe;od){l;+)MQ zW$73^OA#%-?!Gf{I=EhTFW8>`J?ZUarv8Y=Apy9gr?ot7ky8EVgo|BRg1%fd1a(785Q9Y7mE5sxZ-Fby15X)JWLXUBU0i#(@-`C= z!z)p7_B=2pz00VaB`cv1h0EE3@Z63Dq<7&J5tms(>2)X>LuP9DjFVPRETSop%1^Va zwM4V?C2qG>Ag)LKvcou%NQMk&s`u^jba(4I#$4!;X~o|mu+46%u zdD>Mj-@&AA+CSxvtO_bmRvwLK>neVyWJYU#rW#>3(8@)}vA9-mmk`Xwd%U;g_7&3* z5!^^IQk+{0(YuA{;rO96(IPBaF3i_pru192=yjiTK~BwS8aTG!7Q%x`S9Io%`33Y2 zx_f;60Y6178)iR3MQJcbZj2J4815p3kz_=JrTyPABp*LzUQ>ocjtBPg8&F_Q1~<*W zJ-7k;;$ZNj|FpSTSvtIegHp(%Bc&h+f!4x6R$I{c?dB@y(|3H|oE4GKx)D^~jU`A^ z3J=xZNZq(LON%zT-xU5C{g$uf(3F!M%D6{b1>D7t(0I(fy%sM_?wdbxr^gvt6yNJp zI5Q#sr1R$u{{(&rJI{ecTOb{Zq5@0{g1#X=j^;+gCb>34i2fJ2W+RvYn_+4YO*{Hq zi)Z21aCfA^APm!AVZcuxN%!yLomD$*GVKE;9ox?4`Fo#Tym07B#;|P(T8jsaXRd(O zDOW^lLR{h8LAKkn%kDpmA7(U9RVi#j3h^vnZ}88EH|0v*Ig1vvat7KigUC<%l$~?C zj6XuZI=~N)5$&Bw&$@ks843GqMF~KYyQPnkLcOF+IvoTwk0nNTuNgFPv^4sQd9k8j z%EcZe^LE3GqL~t3xB?~}96r&hNWt`7Sl@k=bLXa)Pu>3K&BnfLIleTlmt%(m1hUqT zJWrL(HvG{=Xr9A7tj;j*xM5-3vGMiGpD4Y%6P%wrMpVTp^hV@K4-Uo~RiMG;xGIMu#_X?f2!U;Ao z5?j`HoQ>x>qpBHlH<#aBpY}T4s97x@w(eIE!J=?4ud$vUl=+%ryn9i#=4&p0ngH_@ zN>ybpxg|pO!6h-X< z<@p1z85nIqPX@HvzbvxRZlEgw7y&qIz*PX`0-zPtHI4s;7mR2CTLAC^kQRW;4EO>d zFnI3s1LhiV7y$aLt!n|GH!zYP*ks)0OrSpl`3qQ0;+>A-2w2;KzINI8;}+N@&K#@;5-0P8cg4}vT*@!0}v7b2EF{{G|(OZ@&J&v zhmRfr^8qLj8d|%7%mCmyAU^=o0T>7o(e40P0R96|AOQYQd!-KW4ghTcPy-+u0099k zIiN8B_5sk$z=#0yLuKt@z%>AM8VGd2eCWK}2}lPEFsSF&E#N!=SpsMbg(ZOiXlABm z0fzyw41jCME20C60e}xpHzR?@@OB{$kPcC|`T(U3cmZI&0qq(%3_xQ5>H^T&$}Ut4 zjUNa60x%o^yZ{6SK(IY}atvq&DFZVAuyfjL4Fm=?J&Uy;xj;?;uH27=E+8-fX#t>Y z0CND?f`hX)AP%fU;(@4e=guAAEdWa)r@$Y$3czFlgu>w~cYx^z`~*#7YeN%Lz^(x# z0k8=`O8~Cia&$ZJ69B}v+r8wfoeth zS4fCTJw!PONCZP$PgNarVCtP5`v9=-@#&MU#%_Q<05F2SwcC;F4{7be)=$DLbgTi7 z05AeasqiKT11BpzyZ*C<czGaAX0+=Z^$0~v_S7g&jg%@;zy>8$Ks&0bTK zxa;#X)-A5Ja&BJvn_@-9xW@CPNM=r9nMs>YGo#n4NaTC(HMZ@d>u5AWX>=31I>>{FLr(;HULHhCD#gCLO14mPeeW zjxH+hDC)VRggzIo>!L*y40ck6yxm6BpeDvBcBCQWGDTf{Qz_Nesd7{wNseT_M(wEF zv|P&Qz4bzPfM4f6N;%9$Q_v62kcWrST+kEHZ~P4I!nW)j5;=JUc@EvhHiTkdnBk=$ z@HpD)h}66x#1N~+LQ}$49n=`?En}!qXuh4ABQ;JD4&7_j@c@-Taal%QfMdbT6OIYB znMZ)qi}b^tdj$co=Cd$tTjY{?X(k`FqgDV?LAdJbL2B;3PfgVIUyXL5!Zck}Xr2QP zY(|cIm_uU-x|1&aiYERaTvrrp+uKOty3Cc6(Cd%|1L|rpTFX$ zQW)Fcb?fp@JL`-vsLaN)S4mi@$|{E4BMs%Q<1u(E3DmN;<-`OYyN0LY>|l~V4Df~m z$b7_rukFeY`~lNinD8bBSlN$(3aE!IS zPFKv9m=z@s5^ELekka4T-DVIwe>i!g1aIuEj7qc5$@?r{gQRHj#qMPKu9o6vrzo5T zMoO)7Jc8?6wuOd6P6Vy$ec_AOwFoC%f(Y!8@%mKdZxS*GGtA-qA?(lSH~q zUvst33d5hqeZDNf0y76U?d035_G27tV%Iv1wv@ zwIWg;XB=X&j7n@U{2+@d4Inf>94$*tF?fy`x7{KSpz;!N?doRrTP&0 z^)fDtH_lPSAq!n>Z8bl8n8Hzgn*-jmN%&~k?>E6aON%v71Mo{D6|z&D7;dDIT(dW(1exVTR7 z9pS_CWpLn~^PN8&0)^aP%Rf_}jH_1lo13x{Oc}%YoS7E+?vx$?Z_P4#3qhYvtRCP; zpE&a8zR8hxyhmtlrk1ZLo!)emMu#a-Z=E2-=vhi1ank(e*6mMAlI4rrNpk)0UB1zF=^gnsp`2CQm5{?}F5IfPT1psiAkv_9jd=BJe-w` z2aZ|YKf8Ox?6{^yVS;UVW#NH6A+N6HZ|yaeBzf=bdpm;WbiT+iP5$SfcaUHQhsSw6 zP3kunv$vyLYt`(RGam(X~fmTZN$-)bRwJM&4cPXZJLMJZ% zSxb6nkDokQSbt9*iY`6=mS^t|>aNPqiR#!1rt?(y?!Oy0wBvJsl!YdKy;4b2?EiBJ z^K;=>?C+QrYvjZCQaS!HYK& z0h>xWG56JLT%!HKm(tJT*Iy$|MYU7x;CT7hWcs_I=MTRh9Q%Cz1mo?r;G^vyPxk)( za&i0j(%whEUO)f){oeMU^@2yg7x!-en%@5VEIbPSuQ*o zd5T9pyibpOF@{rR&y#({V|Ixr5K9sPPoE5LO}-|dQRf%M~x;Gow@}Fm=LE`43spO6Uhu`JVAH$cds4xVvVsgT`R7Iw z2HC{9hIojT`OBO2kjR=G#cyLo9YR?G%fh&1DNLg{c3CR=2TPDw-^~&)+YztP%0jg6 zLXG;8E)aHgvUd5%Aae>oCz(y^;*UN#E+4z}f`UTDD<1u< z7?G$PGp-!>seF}OIdP$Ks@Zqqz`F z{2OaT>#9P=5oQX@=LS@{ViLyhMG7)4!fLhE$$JFJI_;2;y}$=v))Rrn39F2p7swpNZ2rf@B%&@r_zMo#kGW)_PrO!?Fh_jacYPkmdSqN;N5stpzHii z4+lJ~#MuT9x4x?To#`%0c$nxYTpcoGh1dItAC<>P?ic#LNr&*x#kzQ@?>BZ3F4exr z&qxwVg8~q(Da2j_U1 zkX7qp-9mwm!Fe)lA%#0<>L{yM4xnOuh@%H&$w+ZD&4=OxCuAeKvQHd2uvFv2n8q8~ zci3vT!@J6Ms*05TyuHg6RT+kFn}v|Da)W*N{tf8O=(&JE{LC)Ajg3E&eDB*`M;T_l z7%Y(Z>JD6`^+5}5HP-m9Y9Q1Sxc)NW&$okTrs)Esf#hmjixF{WmV2*i_^xC3Q3|<5 z2@lSB5v%`cMr;S%Rdx_+`iXB&&Z;_qzbPSfJNd2#pJUTB-m4^JV4UEOK6GdIA=&D% z`)5cCNTY+`(xn3a_r+UMi14Jk!zbEvL=NC&yR$d|V*xFu_0Nt>~WJJxCrdRrFciRH)S<) z)c&7|-OLqL_if*p>=Q!SGySNI>KsRc>{X&)1pb6HahDN!Sf7{_(oYAqk}hx#NSAX++bgNfEoI< zKi%8Aq{Gyn5b)%RB;lT#aQ_N{ynEnv5}_%D*xW>5@kSR_+^*&q+VSgI=#g%*(Puk$ zC$H_#nQ$a5d_1pBZYyyVfBvMkqpo|&^tt4$+4^I%RbL{D{~?)aUr=%N-NvvawQUDs zSZ;Pip!JL|A0)!ck_lB4^1~}vjEbs{xOR=+6COrfAIYaamuKd{L&h*41~IE8JIJZk zjbnihN5r>VS#nMU&oH6eB`-XTg*!o>H z`T~xuo;z**w`Zr@{Ny_uMMCjigbkz_31PmDIxRIb{Giy4iM~L>Yq+#UUWPoYQKP?R zF5O|aZJ(BrH7?TBo+)#x=&ESHGCd%+L6aaut`unB;G3kaG`6hy+tNB^S7`K1Q^a|s z^}4?=Z04~n_iAp2RjgL4J+bI8cxyuxD1im9;Ptt1HPX8&-lsxcuMT0G6{zE8Y8gc? z5aB3Zf{xsI>*Q4$*Jj`yM9-R=E!B_}KAlLEd5h1x(y^0?FdeB9^*@&1a5_EE)D<_S zXO7o-!vin$$-+W;e2^vyDS>Y{%TLH#%AN}-M`@QyB(KTxeAF4AO0Iu!7LBg|BwXd0&Z*%;qhH1I=JD};byfvy#afHfJy+j+8*g~xlM z_NozK4c3;ixhD12@4ieS!oO-F{5V0mX;`dv!1I~#G2Eb1VflRx0!9-Lw;;Ut$1e$# z5wtfXsBh6RRx1Lm^y|-ejID=0-HD8PyS?`LrZ~aVS9sdo1<-?8Vz#umrWYQjK1?eI84G z)T@c>Q>pe_H~)M^p;`0A>%Ny<=H9J0x^HpSvD^2LiWADjqlE8yq?{*ih4B!WFsY+E zHx*icLL)z4CkUmkZTM%9`7Uh?eZZf4z9rH+rbEszvUp(}_*~kVAah(OZ1R_#pOD(x z93zJC<>4_eW{&h5e9!ZBoO*>pK-IwZYBTfas0H!GJ7FnJnKZae-$~-J?azdsQ=j35 zza7Y<0s)@`zK!hj5wnv@Op}_qN|zVTgi$+yfUN20r&X4_sh?IHOahE5!NicWf6}% z@9(LyhKU}*t@dE=688L4G2@;S|6JJccv^`oL9aK~&bIJ)S_C`Y`jq)G|K{$;8b;!> zUN0{1uw2WQY*>0r(Toy)d-o6@vzPaMa~?x3?#%d^gZ0U*n*9T>x^k~z{;;=tP7dgr zo_fRe%wOR(A2Bm{n8Fmq-`!r8p8wtW`(53mVG9VV)x2}AO%6*%Xv(%wcy?xt)C$Hg zt94>Dd)MWE>&&-U3R)nwtq8n)nEzX5cp+V=1o6K$Ymj9?kO7SXL=O-*Ku-XH<;B!V zkZ4%v1AtNt8VhJIAJ(!!y#a~i^5t4kOF+5-@dVTukVHUx0XYTa7tnA(W;t-s0aP7J z8!Ct`puK?V0zwLCGN7UW=o-`&P-e_2<{(62+Xi9h4Op#j+@R1bK-d9E2gIC%0ikZ5 zwjhsyo&z!k@S8zl02v3AmdlOdAl(Fq?FH#(`h6P6H9*1!tp?N;&|W}g0uVK5H7hF% zAYXt)1Ii4@G9bkOc>BNk1;i6jWBws<9UU2>pd=j*0!>C0ci!4 z8Ng}(PpG-p76~d1=rf>4fj9%o3)_hz}U=*mH&w| zptFH8V{H0wmH{v}2r?BlhyUATB4gZj^ejM`0X(+8r3;|4AM_=FPzIcAP-(8;j0AB8 zBpM)LgG2*@46w05r~!QjR2o2EC#8CWP?PJFXd9LYS`C1%LGJ=_29z1Az!=cg2l^KXL z>UI{6pAz;QN&s=j*>JC&f#d&_nXYtdp~Wq|5~Ux6IgA+TXtV@|yR}|668oQ#7^$US?a{bYG!$ zcRBj!Qt|Hg<~R3}zJ7c&c<1uHDtk`>38UZ^4hN0f@*C=C{kP1NnkKe1bVKmTSdYYw zL8=jQ*!KB<#5UQ!QF(5eTLuv_Ip$>e&YV8%$$@|IgO?`$55zGqbT5 zw-!IWd;Vy9edRAoi3`e%5z!E>(7;XOH(27P<872?Glchr&Sr`qYMA|RnIUB<&1K7% zgwEwC)iuoJsE2GD2 zwJbV+=mGZZ(-%z{yusHf9Xj*Zu8yY~?^6-m;p^JS`$2^jinN>YZdjM~;HNs$(pd`a zrnfdI=S=3`Q)C?e!9SM2&c_hI3unaKM_p+udM0apU#LfPIj^wK=to|(7xv7iQ_~Kg zmBKM;Y95|b*Xnqa7OW6BQoqzP8_@+bH$|&La&!iNQwaE~u=JJb+7_Bn+Mv+N2qX7e=xs zQFi`Ci*W7T&Cc<1!CP+-A1YrgAJuFZG?#Dv8)tKvc*~GR^UBn-VT#ovOx|HLjA=7E zo5$A=Tk74n2|QifIrL2C)(QI;a>(C%Zl}xtvtk(X?ymbOKIE2?(`whPl{e>yS$*|x z@%IwyTY~a*zNpK#8-Z&kWTnFkd`uVzJ?HJcJ;v_c@h+DW-S6S^Fgm z3G$Or4S848T+dzdgmW`GRdXO;2Gec$ODQM9UPCH~DUeMn>vyd4F6p^h;O#0eXhh*H zwtE)-c;N!M8p6ub@uNOpFLL<@*6tq`iZ~gJQ~(1fh-m@`vc6WX`yQ~D5l`bE4}kF{ zO;Y5=x1XQ6P9 zDVvu`xJKJO_G3lmo3%<#jrKsZW=RqY)z3E4c1jEsJGK>-7B@O4rWEeYiY?~<(C8xO zAqrLW$v#gGeq-8JSFlo-E*thi^|ZaG$`bPdP6MRV%d-f zw%P>}uiDd;^3(&SeGU_!h28zuER?2F&R_HT!q7KT>W6HD&Sec|9vCc~;G&rL#jAwv zUim8SaG>HpRejiAr)X>hwSR!+Y4D0vl8`O%Df#({{M<{$PU_KbLkiE-^d1JoPXzev zS?SwXzqhN0Ukysjoqqf4`yCFhIr_B2%$(#_N54~ZZ0X?4g2`6r$l2!j`rR`VZXd3W zKhr3Yb#s467rRH8B$h%WeyioBR_|Uuz0hrRMU(UGem8E_rTN#}G=`zs zuWs!_kGgloe<1u+>E$3NJr%#*yY<(^TlJaMCqHribGJ@rk*LR8vNR+1CDSsx6B|Eg z1wEb4P&%KxLp1x)&M_&15VDJx+3K{09sPoP8*Fy^i z_kM0ai_X7UvFNyHGW~Nn>1}ZFm9+h>Nzdd~)9fyN<*!kb%6LSoj=g{p7uA{W9YIm` zsufq;zp2zdI8?WJ=DLttKxFNUDgnECq)r=6B!PU{xnEGwp)I4hgKY13+a?%i<>EL0 zGPln5+!fg{r=a;q$6vm_?ikuqu=!D;N5!^Hvq&vn?;p851&k0cF)}3?3-x`HrTIrr zbQ62A!pecPHW81L->xZg1l}`50s{^%?&>Cl8PYVuwO96wsWqWEx0KUvYM)mpdyLdm zqQyfCH>Kpi?Bl&pE{bjn?3g`fzCT~FYAI_|(%_%w>?vsdFsp@sN1=Uo2emDxX=b|L ze0yNCyfYGSdr7(vn)phK#Swq;_AdAjB+>5kGN^*{u~MT`jeKJ|8sV!Zd*L_mYJ-@v0v7? zj@G{N$N@puHk(lAuNSz|&?zzO|Do>9} zr{@{=k zTjo zl5szyG;_7=0+I9T!(ylUhV7|Cgs}ZFDylzmnIyOQK={@5!|J~_NwT1!hGP~4hvRg-3Ss%A66vv~-BtCtC_Zn~r)e)(PRp|qY z>a#@65DWYQN9eO8IUhD8QGBqFoD4^5K@{7@{*K@-xF_D;8IP{sIc*AiM;%mdruI=jZCA~ljp zk=lh1V#QjI;MoVheu4Lw8M%+aG4$ZZl*5`d+NldESu-$ij8>2Yhc7ou@?wwRiOHDi zmNrMLU0hm@qL7auhS3 z(e0E$Y28Gwa=X@LO18JL&fLeyTJP;V^;1 zkuw)U0%SbH?=PTH6lnc?I^tm<%u__u(!lB@ivwobe6$o9!M&E%b|N#NI2BJ^r%!=y zUd+DrVD~O*=VSCkro?qf7>A6`Fa{}9ZTgfaA-c@7LoQIoC(znt$cT)=G7$#5 zoW8~=H8$F;np8LNq=Mh+%=>tViSdH69OO1@`6--e%QVVD*&I00Vs?~io(DPP?Kqeh zQjizglo$3eZ|~Q<2)UC{=I%#2veB)Gz{zZLT55UmNl|vXcTg(Q_OR$zqy5=v6Bc+s zJRPT``rL_rdpcjP_!veh02QR#WQcfDtfo<1fNU+mE?^SOVHvZ7MR(NrO=_iI3obMr z^7mbN%v?I@;EpU4*H0b!O&5uc=B67bPwvPm!sIExTsncy_CilW>ry0Ha@(B7r0!ml zzvq`BjL1d?soF}A471}Kcb!f_prEYN$or0+%cPMxhyl@vXw#w^`S$Uaf#8Rlq!##1u1 z@Dk7Sp`L6BSgTltUHt8$j%1o-lNU#6PEsQ;S6$s@o3zw+j1kITV%U$UzZ9S!D*Nl8 z{Dd=XUU)#W`aEj#{5E&BrGgaUNX(Q|A*~g^&Z1DJx+L#nNgSf&nO2&-(gjV=|k}NE7ibTBoO(A}M#dBF-Ybs^$91%AMzrjO;$C%iSAMi!s@->9G3XN9dgTJ*s*XfOsCr(h{Z*KKRk%Uoo5jfu>?@UXS8JvIG)zSx z2+|b-4bwbS#orpH0Ac`?0U!pT4f$ub1O5Og1ON+w6@bBf-Fo}n!eD?k0Js47;y0<7 z7zbp-nrhQGlJKWh3cv!u2!AL9Km?#K3Ah0O5rB#SZUEY*@4lpg+0(@QH~IjC0RRL* z9spkWLq+}&3BWPvE_Q%R034x5F$F{-ATR_#34kv^w-itaU42V1=>y&Z_y*uA07QVA zD!>RCnb|ixVnF>9K#72Dt^ij2K@-|~CV)=(`Y{3e0Q30YF~y%UDQH0gy7KyCDxfRZ z+xD4QSOIVWiltzz2KWN-8~`Oi^AyxP0mK080&omKY(NkQ2nnc>0({Zk-PPBBcV|dA zXfNI$9^4%kWntwADy5(n`Y(tAkz!~KXa?XI zfSf!8Z}w8x1CDXG_fFE$EdZW?x@%fi;GecBKpB4s2H+k58C|K{`v+ox-Y$R`oQH1! zPy)o`PstPj4KVK?;rgdM{{q^kdPY>hGyu&2J=3fcTLGd0Ra3wv0Mh_fQ_w61SYxg4 z4#1!Q*6`o76_5=;IsRY`fGGgSFtTIR)YgXVanC#+RMQjzPzK-?({Gba*ZBfk1!%_R zfbD-c20$F3g8HX+3Oc8j?ty@2wDlZlY>5IW12jzkR838syzI9{{XrQn>wW%|Ozi^q z0Ehv4!NF?-I4PR}%>aZ1pbS99Iy*Z6%>XC^R80Z00N?@;48Soo*O&o(VWv+51Os$S zLFe}m!~peDKrleV6yS@^R=$8^0GdHHbhKUL1RADh&OZN%V+7qc69Wy?|1*vO8m1@K z2mGU9`ge}8V%>iab9z=X`Yi+2#R^4xMn`7bZ`>v7ZN^YWb>uSE ztYG`XrV6RE(nP$LlVqlp_dr(EiSg<4RGOGQ%Far{tAy$_XTLSo=0Wo0hLsX%mlM*F z-3-ewcV_vSKSekEN1LGn@x z%EYwX2=v3og41VOQ@vEwt?y(PE4imhoI7l&#-edT+h45DZN~dtgajd3mlTTqv&!|2 zDLEAdpO>ZP+%nu%LoZupKN`F!c{)#~RQisuM8-O;t(TQC*@BCX-P&kH+b$D@oH|p7 zqMU1MzoxyeAKIU$2DKk{(e=qZ>~&>Zam3NA60ry6dp8s^N_1%VnI-2OA7RxlFqDPA zPueaK0XNllI~4C2+D$o*fI-C)^$~mAi5EN}PN!%z2)7;N4fZ zV^@P;xvYXg$0;?lVH``aNQG7E{;Wqp4yki2*uBESsW`EHFP zGF`Git86hyD%lpHp&9=3Q^C)92-3eefS4Ie(f<{wZp0ES&0f59ymPMMy^UY*E&b&m zA4kKNe=f~jUHnwufaSr*j}fxn)Fkv3Hk?kTNoceRznd}A^v54H zk!-r-H=p9?c(ao;v-0Z})BJQiSep zou>=Sadi976CFy*<7tb04eL4Sh1Bw|8J_RzrQSx0Lr>QzNi}rKS#7_VFf#=>2EEg; z@Gp)bKid7DI7VFnR@Td8j3q^skilqXz6( z&lzr2RlBovJ7eFFic>;~IxfmSJ-0^r*s!yNsT|E^DA>nV?uCQRuDm7VX`jm<&+4pb zYpLxXQohxDfzsv4x5i4U^87C_Jj{FXBd?W7x50|7bG_0lN(x0AKQ ztWeHSfxYy)RYBzrb#ughPuE=3XTK;5*a!OrwO>ZkUcYTmlMG*tKK~B=+O||k=Bj#o zpvt7CZ`C!~me1TPbcdn_yu|9Zmo=q76G|P<9V80of&*!H8STV&TK!_T&5Ht4^8+jpp1XY|R~C*9?@F0AO|fnQ#B=x%nntCeWT z#5$?A810IP`Cde96i%vaY@<*`4Ru70V{SKmt5WVjPs^y;da^EGSzjH` z)sdJ=95&N3HKCx@(vPFR_^N$Z>q);?;d`7PLssx{&XkMlQ5kK&BWM1B;};do+;v&h zAfSd?N`O|LL}&SrMEVPlH>=hr^_n8C9!so_e`)uQqi6%fCel6ym(4*vg!jT|X7V|WCpqi&Sa@G%vW(Utr{Sn3jbjQm z4t1j}B-r*J!Hp=sV_V1cGIqkjtV`~q4(^u04-C(w9&_TPuc1&!a!Nlbyw`;{<6a6` z51hVasuyPLqnX+zW!P)Lb*k-;p_iJ!xUBd=*q)JdgA$;#LQa; z-4=%z1h^~tX^N-F8p|3N9Btm7{pd4p%`l-iYe_^WR*fr};#ha>YNBJeRw;!9q*Z=5 zTJLBoqvY5?cg+#&Nt(8rF%`0)AO1z;4w>58t#5oHG*KWoM&N}W+j(dZs0*2Ic6 zXuN3No9*-gtfUg@_&{yF!HD}s><_%KU?MKOrNE9s*QdX! zygzaI{+`cv&Ohy|Tu%>u>HH!~wA>PTs|cgfqS3XH_wH5bz|EaWPk%)I+F8;sH1N8JWkjvU85-p2$0yUr<NJ>ViqD+~ zdFsV7@Uww2C=nqqBzfgpeM4hY^Yt4yTW$$j+in+wB^0ah$jz zMna}C%wCpFWmEjGXtrxjoKD%C=@ZE9gMc(F^ zS1(R7leJ#v2j}g2SrAfs>1AP9{i~Nn5uI8yr}mBPnmHZ&^3u#17e|KREMza3;b-bn z6Vbet)Y)@sx)5?hy5pQ?N%rby7S5oG3`L)i_{I^@7Eq`nrzNx{A!Ij$b}3%wfGtwA zs(fdprYeJT87DtEgipz;;^0gs(k_awQDuQgE=$Ol&q(K!XKMx=b>7wu`|N&uZEQ!y z+xqdC*KZppl6BrSPUr1@*ECyN@viwz{p)wv=R1qGiuDiZ=*O|4ziJgYa1wR@$j#n= z$_-E!AS*yzd=w7Rg}B{wxA&iN zbEBjC&Vxsf$Dcg?EjRrrg0g}Ldg}F?w|~jaja4h<$dKaV_aA@Bjjd&jW*ZNU{8KBi zOCCdd!Ia73-xoeZ$H#QeVGvSg|G4mpF@Uo8>{f}~zbD z{;S2&mFwjp8iXb01@y%kAi^Yd>d&lye8nm2TJ-C~3cnZGTu&6yk6$y>f9CdaoiF}g z??3$4^Z5VAa?|*~BsU443q}mqYi1!O56d*;5mxzCC{YvA+^mu&JSkApu$r4CDEXG} zBI;W4(PH``a~FxorGZ2w70u?BC9G5uh^Ev{aFLfk2q6e5Xuh4;wRd0bN=r{L?5@W3 zP`C($CX*xF{#=eFf`b?w*ubbl1EHf@U4Cr_gZ!_>1ZW7bFF-edq=17D&O4A4aO8oc z0H*@ZDLB9XI{V<@0}l4*?Ay@(arXb+!T-;v{$EEPh!T(vAXz|6!0`w20+1RI0U#ql z2f)DxQef*qjXL1HJKSUI4!3O~8~%75P#7ybyS=sh05D0w;yj+_0L5@)IQ&rz9X(T^ zd;c4X#=rYt`Yk3%q&-T^4*G9-mn)fwRd@nP{_6kWUD`X&iK-J*^*aA4CcwMglEsYu zLrkWoM>JqznxfW=KVq`@u|*fHL`JEo8hrZ8yU?qcb+Tv^)g1CRR_kB4$LW#EX~L=K z*jdJ3-o-ABpuV+;jFNNwhj&S3=JLr*h=Zg2=_oY{2|*-ZX6wbjZjawoV|EaZxSap* zdzXKfl&%Iw0T1-;x0oEL-toZVcS$L{~wDL z4~ecFp9rnF@eXRQ9T-XryY}`UI)eIRO16U;Ncx|q1V{3J_xOXqs( z--&d6a2@@eG4rke%P(<)a7z2R1)i(+$==dMp^SAGhs!^u^@TQ!U-=>;cC>4{=4-lJ z#ps**@1n=<&U|eCnR)N^mme+5;v`Kox^GAP+YQd$ZI}cxd z6_VGsSmz%amsVKb-1BJeo3Mh8rOT$>6}uuTuHUuv_+w=M`kj#jb8|9^`&X`}rStpS z^CwpWl~XXDg4hhqrtY4bo<4mHR;+;Z3&dl8dbgl7{P3@o3(TpYK?_DzQ*%3zJb`2g zG-APk3kE$f%LWGRvR>=l(a{cOJuvU->05vx3XHj%wrmGwUl4SGzzH;T!QK@x=7Rbx zh?+n>7i@+B;nURAGZ2Y^qzZI!LE{!=QJ}C3aw)LzWb*k_kmrFc>gLVsAhiO^MzXSV zLAV71DqDLu6I0uuZJ}VW*48t--QH$sOa&R(y?cGRC-OmLWp3#JvZ5zXAA#W;baO$` z79?W0y{Yp?(A))w9ZUsawgw?tPtP52sKKcO1z%wOr`{xie5<$j z4){*z7H$Kn81VWa{Q}!mK!^Cr3y!6Y4T!`Jc0UFa3xF9H%gTU0fcy-ccTf&qyK(!T z>NZd^4%oIHs0z>%&<4IU7*8=;3(yFdI{db{fKD*8pd1vGL9PaZv@J~6tM%dFbPqi| z3?ekJ!o|ybix2lW2;o{fV?eG3IEquqf$h6C*an0})OY#v@{^w}f=CZ!hhSU*J_fXq z!Csf}Xit#Ty6jB=!COX7keQ`bbwfl{b1%qf4-ZT^IBo#b5pX1+VGP{K_H(tMvK&&@ z47SGrl>=#_uQ2qmM8)}k{PwDNLZ|EY|BV~SOnV>_@HavM zHu%S<_e&+@QQh(ZV1ug3+dN4fpQX>;s&tO*Uz=NA+|A##dV7~vz;rL)4*2-yk54bO zG$NM5ny%Z~w%l|KZdy69x z3I9_+_`k&s{_*Lp|AbNuV=-)P`?eQsw+mh}$ch$jy)R~USct4{<)2*UUdTialv4d= zhP$<)%^m|q!W~VF!j(5AjycBWs|+bTOV~!(5Iy3YC8HZVO(Qv4RShBb2Hc7tx$-5W3%%dl#sp8zGNm=Po(Z;@i4 z97$Q^OLi+<8AIR&^IWcoFxrD9E27kzs7aLKYhS{+QCPV6nw|lK*!Vz&ZKLo zmq2YEkZd8)_*8ueq9GiFigjSLH#LL8Is-8U&;?3FPbeWFn~Gf>tHqF~>t?4aLSzAS zIo+!YY(f^w!YI2WHM&{$n=PyKt_<{_O4l12*3JTNu8OgY`i4C+)?6akXXy3cP`OKO z&%G}^xqoL%lTiegA!Ll3)LPvQaoc)KZdln~p|)Bric&5cAtBXne2Iw8ba{XCYgE$* zg35`5lKJ{+*rU4zZpQL>sQm2;Z;v-4H+uo zuHpjyR;a2+;i}5ztt?yRF~T-tN1KqTJd6Y+j;vN&yK$0FY zI?mctd2X(^Nsk~b?S?5#WVR`wvvBGZ1K3$L5pJFD?0L=>a*p7T%Og6d)YfG&Hq4Ph zxnotaAF#-Qpd$tfJj3WFm*{hzr{74?jjtB;tu>b{9FpSM-EZn=3q11Pp&+bTL@Vb< z5G1jQF6PRFjm`K%E2tb1tOr|2*H(l_K|%IpgbIO4kjP?DOPL%oIs$uu#KWjEQjl;- zscGLUDq)gE%w?hs$Zf;#Sjk4DV#2!KQCqVJ3N+0`6U=Q4^Q>s2DZNU~3ln0>jfSGC()|J!?dfo-$+F&dMfALkQZJ6R3%v$v-`rD` zsm~Cpj7+0zV?lz(#t_8l4fCRIy zmIsSPxa#eV$Z9!Sz9no+kZQtbhuig1HgYII*h*I(9?QojZe|N17a-g@JWCjDOBN?l zFG5tK^DEkgP_bgAt@`@2&w2rRd(Jf==NUzEC)9({rHdjA9Q9Siv(Sn9& zcGAe_^OLC&3c?dMwvAnz$y)e5Ay9j()UzcA&HNf+WYu%Y=P*vGeQRbod7Ai&!aIyn zPTfN;xsE=Vq;=*KmZp~_nX;opfz-B^Ludxi78*f5PhM?Ei5t%AtSc3%nM-1@FObaJ zAXnEcl?W;U?HK4uy3*aemu(*aA#*a)mx##7FvoHlWT`Sh{!U=R^Ou0ayfgV|WYaK+*MK~pq|dt{bL<|zK! zv*!RXH-8p0%nacje>k>hXKd5!C*N#2>fa>km56(EsC+~ccb1#%631z z-%_(=cvy+Z@^;+HVse;F2v4G;Wdv`f6BIn9R?E|D$Xtyjfdq=)ntV3&TdX+b8BC(e z$Oyh;q=G`_t-2*^1TdrPR+nXu%q%p`fjA+U_AIkDv!d<{1{1 z9)@{4H6TU|5+S@$%W6eK*J5n4M+{F^NfGF9D^pl03O$%5d0Y)X8xep}5;`3L`(I?m zeF;6J0oM%(z2OUEfEb)u!=A-tnuGwUj5I_dvkm1UUoLwHef$3ClGW z_6x!5bs&Z}9-<|0j5~3tNBR(jiS!mAXz<~whNuc6(%c9xP=!d#Opz`1^7RZ+rwDWw z-t4$<>Pb!5Y9KJj@pkiii*~z?hTm17QSixxj-Ifj72C?_od$6tsbCEDxg&nyrd2i$qcU zj=V&$t8%TfaL|14^OI3LO$fa1$RM(=M~FQcAY?CXuZ$3VLM9~F;S?Y8sE{3-5atBwvb!1`4mr6)D4ohbVf0Tn z%{-(f3~4+nmB~iq;4|{YxIBK2GEvBP0+xw@esA=dhZdF3$#@_OStR;5iG}$B-Q{ZG zTn7GWzH~Yy!u7xOrC5YdT@w~b=pl>ceY?b$FF$8dUgBR~8dqLcSYF;-e)&=P6=9{g z9EtD`7`ZG&pq)hSxy?$g2HhMD)in4ZBtovbh@@$)BwoHPZxP&1l!1`ZA;b+;;WDii z{TsDvlMGRjh`0!1^_;|`^2;@C2Ay;8lQ_68w1S#exuRI>R1JJqLfg{BaQIufZ?^7z zi>pd@@P+||6vIc^UB6jaVoBamd9eZ;gf@q;p>Qt5&|kr>5?08)n?tlC2a$@Ajt8&e zVs*vhEAj3~vH8p5?pIW96T=ZT(IkCwG70;*nhOsDfhe`3>uNq0O4pTL5lyTUD~4>p6A?O9sCdJcb9G1}<_JT=$MTwc5iDJ_RhnHr zE`McH1#C^O405@$EglYcuixxzl$~AgS#epUwJy>Ho~kDvxDKy7zR_))F_wmHZw

NZtS77_}@9OpwI72UNbXn8N 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 Date: Tue, 10 Dec 2024 17:55:21 +0000 Subject: [PATCH 20/35] Update v0.15.0 notes (#9161) * chore: fix typos in v0.15.0 breaking changes Signed-off-by: Justin Chadwell * ci(gha): remove custom env injection This logic is already handled pretty cleanly by GitHub itself - see the list of default env vars: https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables#default-environment-variables The original logic is also wrong - since it tries to get `${{ github.github_ref }}` instead of `${{ github.ref }}`. Signed-off-by: Justin Chadwell * ci(gha): avoid setting non-existent "paths" event Signed-off-by: Justin Chadwell * ci: fix daggerverse pr creation Signed-off-by: Justin Chadwell * chore: fixup typo in gha module example Signed-off-by: Justin Chadwell --------- Signed-off-by: Justin Chadwell --- .changes/v0.15.0.md | 2 +- .github/main.go | 15 ++++---- .github/workflows/daggerverse-preview.gen.yml | 8 +++-- .github/workflows/publish.yml | 4 +-- CHANGELOG.md | 2 +- modules/daggerverse/main.go | 29 +++++++++++---- modules/gha/examples/go/main.go | 2 +- modules/gha/steps.go | 36 ------------------- modules/gha/workflow.go | 2 +- 9 files changed, 43 insertions(+), 57 deletions(-) diff --git a/.changes/v0.15.0.md b/.changes/v0.15.0.md index 73db65ce8e..1afb76ca38 100644 --- a/.changes/v0.15.0.md +++ b/.changes/v0.15.0.md @@ -2,7 +2,7 @@ ### ๐Ÿ”ฅ Breaking Changes - `Container.asService` now uses the command specified by `withDefaultArgs` instead of the last `withExec` command by @rajatjindal in https://github.com/dagger/dagger/pull/8865 \ - User can override the args by providing the `args` option to `asService`. + Users can override the args by providing the `args` option to `asService`. They can also configure the container to use the container entrypoint by using `useEntrypoint` option. diff --git a/.github/main.go b/.github/main.go index 6640ab974f..d85d9a1652 100644 --- a/.github/main.go +++ b/.github/main.go @@ -163,19 +163,22 @@ func (ci *CI) withPrepareReleaseWorkflow() *CI { TimeoutMinutes: timeoutMinutes, }), WorkflowDefaults: dag.Gha().Workflow("", dagger.GhaWorkflowOpts{ - PullRequestConcurrency: "queue", - Permissions: []dagger.GhaPermission{dagger.GhaPermissionReadContents}, - OnPullRequestOpened: true, - OnPullRequestPaths: []string{".changes/v*.md"}, + PullRequestConcurrency: "queue", + Permissions: []dagger.GhaPermission{dagger.GhaPermissionReadContents}, + OnPullRequestOpened: true, + OnPullRequestReopened: true, + OnPullRequestSynchronize: true, + OnPullRequestReadyForReview: true, + OnPullRequestPaths: []string{".changes/v*.md"}, }), }) w := gha. Workflow("daggerverse-preview"). WithJob(gha.Job( "deploy", - "deploy-preview-with-dagger-main --github-token=env:DAGGER_CI_GITHUB_TOKEN", + "--github-token=env:RELEASE_DAGGER_CI_TOKEN deploy-preview-with-dagger-main --target $GITHUB_REF_NAME", dagger.GhaJobOpts{ - Secrets: []string{"DAGGER_CI_GITHUB_TOKEN"}, + Secrets: []string{"RELEASE_DAGGER_CI_TOKEN"}, Module: "modules/daggerverse", })) diff --git a/.github/workflows/daggerverse-preview.gen.yml b/.github/workflows/daggerverse-preview.gen.yml index f77641329f..03018a4e3f 100644 --- a/.github/workflows/daggerverse-preview.gen.yml +++ b/.github/workflows/daggerverse-preview.gen.yml @@ -3,8 +3,10 @@ name: daggerverse-preview "on": pull_request: types: - - paths - opened + - reopened + - synchronize + - ready_for_review paths: - .changes/v*.md workflow_dispatch: {} @@ -180,9 +182,9 @@ jobs: exit $EXIT_CODE env: _EXPERIMENTAL_DAGGER_CLOUD_TOKEN: dag_dagger_sBIv6DsjNerWvTqt2bSFeigBUqWxp9bhh3ONSSgeFnw - COMMAND: dagger call -q deploy-preview-with-dagger-main --github-token=env:DAGGER_CI_GITHUB_TOKEN - DAGGER_CI_GITHUB_TOKEN: ${{ secrets.DAGGER_CI_GITHUB_TOKEN }} + COMMAND: dagger call -q --github-token=env:RELEASE_DAGGER_CI_TOKEN deploy-preview-with-dagger-main --target $GITHUB_REF_NAME DAGGER_CLOUD_TOKEN: dag_dagger_sBIv6DsjNerWvTqt2bSFeigBUqWxp9bhh3ONSSgeFnw DAGGER_MODULE: modules/daggerverse + RELEASE_DAGGER_CI_TOKEN: ${{ secrets.RELEASE_DAGGER_CI_TOKEN }} shell: bash timeout-minutes: 10 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index aad4a41535..c2c2710265 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -192,9 +192,9 @@ jobs: - name: "Bump Dagger version in Daggerverse" uses: ./.github/actions/call env: - DAGGER_CI_GITHUB_TOKEN: ${{ secrets.DAGGER_CI_GITHUB_TOKEN }} + RELEASE_DAGGER_CI_TOKEN: ${{ secrets.RELEASE_DAGGER_CI_TOKEN }} with: - function: --github-token=env:DAGGER_CI_GITHUB_TOKEN bump-dagger-version --to=${{ github.ref_name }} + function: --github-token=env:RELEASE_DAGGER_CI_TOKEN bump-dagger-version --to=${{ github.ref_name }} module: ./modules/daggerverse # TODO: daggerize provisioning tests diff --git a/CHANGELOG.md b/CHANGELOG.md index ef16ace7cf..734038b506 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ and is generated by [Changie](https://github.com/miniscruff/changie). ### ๐Ÿ”ฅ Breaking Changes - `Container.asService` now uses the command specified by `withDefaultArgs` instead of the last `withExec` command by @rajatjindal in https://github.com/dagger/dagger/pull/8865 \ - User can override the args by providing the `args` option to `asService`. + Users can override the args by providing the `args` option to `asService`. They can also configure the container to use the container entrypoint by using `useEntrypoint` option. diff --git a/modules/daggerverse/main.go b/modules/daggerverse/main.go index 2127fb2ecd..36666862ec 100644 --- a/modules/daggerverse/main.go +++ b/modules/daggerverse/main.go @@ -2,12 +2,13 @@ package main import ( "context" - "dagger/daggerverse/internal/dagger" "fmt" "strings" "time" "github.com/google/go-github/v66/github" + + "dagger/daggerverse/internal/dagger" ) type Daggerverse struct { @@ -62,33 +63,48 @@ func New( // Deploy preview environment running Dagger main: dagger call --github-token=env:GITHUB_PAT deploy-preview-with-dagger-main func (h *Daggerverse) DeployPreviewWithDaggerMain( ctx context.Context, + target string, ) error { // make a change so that a new Daggerverse deployment will be created daggerio := h.clone(). WithNewFile("daggerverse/CREATE_PREVIEW_ENVIRONMENT", time.Now().String()) - branch := fmt.Sprintf("dgvs-test-with-dagger-main-%s", h.date()) + branch := fmt.Sprintf("dgvs-test-with-dagger-main-%s", target) commitMsg := fmt.Sprintf(`dgvs: Test Dagger Engine main @ %s daggerverse-checks in GitHub Actions ensures that module crawling works as expected. Should complete within 5 mins.`, h.date()) - // open a PR so that it creates a new Daggerverse preview environment running Dagger main - err := h.Gh.WithSource(daggerio). + // push the preview environment trigger branch + gh := h.Gh.WithSource(daggerio). WithGitExec([]string{"checkout", "-b", branch}). WithGitExec([]string{"add", "daggerverse/CREATE_PREVIEW_ENVIRONMENT"}). WithGitExec([]string{"config", "user.email", h.GitHubUserEmail}). WithGitExec([]string{"config", "user.name", h.GitHubUser}). WithGitExec([]string{"commit", "-am", commitMsg}). - WithGitExec([]string{"push", "origin", branch}). + WithGitExec([]string{"push", "-f", "origin", branch}) + if _, err := gh.Source().Sync(ctx); err != nil { + return err + } + + // open a PR on the trigger branch that it creates a new Daggerverse + // preview environment running Dagger main + err := gh. PullRequest().Create( ctx, dagger.GhPullRequestCreateOpts{ + // TODO: this should actually be the username of the original PR author Assignees: []string{h.GitHubUsername}, Fill: true, Labels: []string{"preview", "area/daggerverse"}, Head: branch, }, ) + if err != nil { + // FIXME: this will stop working in v0.15.0! + if strings.Contains(err.Error(), "already exists") { + return nil + } + } return err } @@ -181,10 +197,11 @@ func (h *Daggerverse) BumpDaggerVersion( WithGitExec([]string{"config", "user.email", h.GitHubUserEmail}). WithGitExec([]string{"config", "user.name", h.GitHubUser}). WithGitExec([]string{"commit", "-am", commitMsg}). - WithGitExec([]string{"push", "origin", branch}). + WithGitExec([]string{"push", "-f", "origin", branch}). PullRequest().Create( ctx, dagger.GhPullRequestCreateOpts{ + // TODO: this should actually be the username of the original PR author Assignees: []string{h.GitHubUsername}, Fill: true, Labels: []string{"preview", "area/daggerverse"}, diff --git a/modules/gha/examples/go/main.go b/modules/gha/examples/go/main.go index 0e704cb5b3..407699b887 100644 --- a/modules/gha/examples/go/main.go +++ b/modules/gha/examples/go/main.go @@ -44,7 +44,7 @@ func (m *Examples) GhaGithubContext() *dagger.Directory { dag.Gha().Workflow("lint all branches", dagger.GhaWorkflowOpts{ OnPush: true, }). - WithJob(dag.Gha().Job("lin", "lint --source=${GITHUB_REPOSITORY_URL}#${GITHUB_REF}")), + WithJob(dag.Gha().Job("lint", "lint --source=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}#${GITHUB_REF}")), ). Generate() } diff --git a/modules/gha/steps.go b/modules/gha/steps.go index f0e7fc0271..a83d8677ca 100644 --- a/modules/gha/steps.go +++ b/modules/gha/steps.go @@ -3,12 +3,10 @@ package main import ( "context" "fmt" - "sort" "strings" "github.com/dagger/dagger/modules/gha/api" "golang.org/x/mod/semver" - "mvdan.cc/sh/shell" ) func (j *Job) checkoutStep() api.JobStep { @@ -65,29 +63,6 @@ func (j *Job) installDaggerSteps() []api.JobStep { } } -// Analyze the pipeline command, and return a list of env variables it references -func (j *Job) envLookups() []string { - var lookups = make(map[string]struct{}) - _, err := shell.Expand(j.Command, func(name string) string { - lookups[name] = struct{}{} - return name - }) - if err != nil { - // An error might mean an invalid command OR a bug or incomatibility in our parser, - // let's not surface it for now. - return nil - } - result := make([]string, 0, len(lookups)) - for name := range lookups { - if name == "IFS" { - continue - } - result = append(result, name) - } - sort.Strings(result) - return result -} - func (j *Job) callDaggerStep() api.JobStep { env := map[string]string{} // Debug mode @@ -111,17 +86,6 @@ func (j *Job) callDaggerStep() api.JobStep { // For backwards compatibility with older engines env["_EXPERIMENTAL_DAGGER_CLOUD_TOKEN"] = j.PublicToken } - for _, key := range j.envLookups() { - if strings.HasPrefix(key, "GITHUB_") { - // Inject Github context keys - // github.ref becomes $GITHUB_REF, etc. - env[key] = fmt.Sprintf("${{ github.%s }}", strings.ToLower(key)) - } else if strings.HasPrefix(key, "RUNNER_") { - // Inject Runner context keys - // runner.ref becomes $RUNNER_REF, etc. - env[key] = fmt.Sprintf("${{ runner.%s }}", strings.ToLower(key)) - } - } return j.bashStep("exec", env) } diff --git a/modules/gha/workflow.go b/modules/gha/workflow.go index 60dabf0b59..468e55e85d 100644 --- a/modules/gha/workflow.go +++ b/modules/gha/workflow.go @@ -180,7 +180,7 @@ func (gha *Gha) Workflow( w = w.onPullRequest(nil, onPullRequestBranches, nil) } if onPullRequestPaths != nil { - w = w.onPullRequest([]string{"paths"}, nil, onPullRequestPaths) + w = w.onPullRequest(nil, nil, onPullRequestPaths) } if onPullRequestAssigned { w = w.onPullRequest([]string{"assigned"}, nil, nil) From 180573cf2a1359a7ce371f92a6b6d5fdde62c5a4 Mon Sep 17 00:00:00 2001 From: Connor Braa Date: Wed, 4 Dec 2024 12:33:13 -0800 Subject: [PATCH 21/35] improve ./hack macos cross-compilation interaction with int tests Signed-off-by: Connor Braa --- .dagger/mage/engine.go | 12 ++++++++++++ .dagger/main.go | 12 +++++++++--- core/integration/suite_test.go | 15 ++++++++++++++- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/.dagger/mage/engine.go b/.dagger/mage/engine.go index 33ad762f0e..01e2451025 100644 --- a/.dagger/mage/engine.go +++ b/.dagger/mage/engine.go @@ -133,6 +133,12 @@ func (t Engine) Dev(ctx context.Context) error { } fmt.Println("export _EXPERIMENTAL_DAGGER_CLI_BIN=" + binDest) + + if runtime.GOOS != "linux" { + linuxBinDest := filepath.Join(binDir, "dagger-linux") + fmt.Println("export _TEST_DAGGER_CLI_LINUX_BIN=" + linuxBinDest) + } + fmt.Println("export _EXPERIMENTAL_DAGGER_RUNNER_HOST=docker-container://" + containerName) fmt.Println("export _DAGGER_TESTS_ENGINE_TAR=" + filepath.Join(binDir, "engine.tar")) fmt.Println("export PATH=" + binDir + ":$PATH") @@ -153,6 +159,12 @@ func (t Engine) DevEnv(ctx context.Context) { } fmt.Println("export _EXPERIMENTAL_DAGGER_CLI_BIN=" + binDest) + + if runtime.GOOS != "linux" { + linuxBinDest := filepath.Join(binDir, "dagger-linux") + fmt.Println("export _TEST_DAGGER_CLI_LINUX_BIN=" + linuxBinDest) + } + fmt.Println("export _EXPERIMENTAL_DAGGER_RUNNER_HOST=docker-container://" + EngineContainerName) fmt.Println("export _DAGGER_TESTS_ENGINE_TAR=" + filepath.Join(binDir, "engine.tar")) fmt.Println("export PATH=" + binDir + ":$PATH") diff --git a/.dagger/main.go b/.dagger/main.go index ce1998a996..61b802b021 100644 --- a/.dagger/main.go +++ b/.dagger/main.go @@ -300,13 +300,19 @@ func (dev *DaggerDev) DevExport( }) // FIXME: get path from the cli file (windows is already handled) - cliPath := "dagger" + hostCliPath := "dagger" if platformSpec.OS == "windows" { - cliPath += ".exe" + hostCliPath += ".exe" } dir := dag.Directory(). WithFile("engine.tar", engineTar). - WithFile(cliPath, dag.DaggerCli().Binary(dagger.DaggerCliBinaryOpts{Platform: platform})) + WithFile(hostCliPath, dag.DaggerCli().Binary(dagger.DaggerCliBinaryOpts{Platform: platform})) + + // this allows our integration tests to plumb built cli binaries into containers when the host OS doesn't match + if platformSpec.OS != "linux" { + linuxCliPath := "dagger-linux" + dir = dir.WithFile(linuxCliPath, engineCtr.File(cliPath)) + } return dir, nil } diff --git a/core/integration/suite_test.go b/core/integration/suite_test.go index d0f248b3d1..a062438b2b 100644 --- a/core/integration/suite_test.go +++ b/core/integration/suite_test.go @@ -10,6 +10,7 @@ import ( "io" "os" "os/exec" + "runtime" "sync" "testing" "time" @@ -244,12 +245,24 @@ func daggerCliPath(t testing.TB) string { return cliPath } +func daggerLinuxCliPath(t testing.TB) string { + if runtime.GOOS == "linux" { + return daggerCliPath(t) + } + cliPath := os.Getenv("_TEST_DAGGER_CLI_LINUX_BIN") + if cliPath == "" { + t.Log("missing _TEST_DAGGER_CLI_LINUX_BIN") + t.FailNow() + } + return cliPath +} + func daggerCliFile(t testing.TB, c *dagger.Client) *dagger.File { // This loads the dagger-cli binary from the host into the container, that // was set up by the test caller. This is used to communicate with the dev // engine. t.Helper() - return c.Host().File(daggerCliPath(t)) + return c.Host().File(daggerLinuxCliPath(t)) } func daggerCliBase(t testing.TB, c *dagger.Client) *dagger.Container { From 654799bcb11234371cc1a3ff956877d0e5fdec81 Mon Sep 17 00:00:00 2001 From: Helder Correia <174525+helderco@users.noreply.github.com> Date: Wed, 11 Dec 2024 10:04:14 -0100 Subject: [PATCH 22/35] shell: allow positional args to be interspersed with options (#9163) --- cmd/dagger/shell.go | 155 ++++++++++++++++++++------ core/integration/module_shell_test.go | 48 ++++++++ 2 files changed, 166 insertions(+), 37 deletions(-) diff --git a/cmd/dagger/shell.go b/cmd/dagger/shell.go index a9c9c8c466..c12e967e49 100644 --- a/cmd/dagger/shell.go +++ b/cmd/dagger/shell.go @@ -457,7 +457,7 @@ func (h *shellCallHandler) withTerminal(fn func(stdin io.Reader, stdout, stderr func (h *shellCallHandler) Exec(next interp.ExecHandlerFunc) interp.ExecHandlerFunc { return func(ctx context.Context, args []string) error { if h.debug { - shellLogf(ctx, "[DBG] Exec(%v)[%d]\n", args, len(args)) + shellDebug(ctx, "Exec(%v)", args) } // This avoids interpreter builtins running first, which would make it @@ -470,14 +470,14 @@ func (h *shellCallHandler) Exec(next interp.ExecHandlerFunc) interp.ExecHandlerF st, err := h.cmd(ctx, args) if err == nil && st != nil { if h.debug { - shellLogf(ctx, "[DBG] โ”” OUT(%v): %+v\n", args, st) + shellDebug(ctx, "โ”” OUT(%v): %+v", args, st) } err = st.Write(ctx) } if err != nil { m := err.Error() if h.debug { - shellLogf(ctx, "[DBG] Error(%v): %s\n", args, m) + shellDebug(ctx, "Error(%v): %s", args, m) } // Ensure any error from the handler is written to stdout so that // the next command in the chain knows about it. @@ -512,12 +512,12 @@ func (h *shellCallHandler) cmd(ctx context.Context, args []string) (*ShellState, } if st == nil { if h.debug { - shellLogf(ctx, "[DBG] IN(%v): %q\n", args, string(b)) + shellDebug(ctx, "IN(%v): %q", args, string(b)) } return nil, fmt.Errorf("unexpected input for command %q", c) } if h.debug { - shellLogf(ctx, "[DBG] โ”” IN(%v): %+v\n", args, st) + shellDebug(ctx, "โ”” IN(%v): %+v", args, st) } builtin, err := h.BuiltinCommand(c) @@ -564,7 +564,7 @@ func (h *shellCallHandler) cmd(ctx context.Context, args []string) (*ShellState, // entrypointCall is executed when it's the first command in a pipeline func (h *shellCallHandler) entrypointCall(ctx context.Context, cmd string, args []string) (*ShellState, error) { if h.debug { - shellLogf(ctx, "[DBG] โ”” Entrypoint(%s, %v)\n", cmd, args) + shellDebug(ctx, "โ”” Entrypoint(%s, %v)", cmd, args) } if cmd, _ := h.BuiltinCommand(cmd); cmd != nil { @@ -576,7 +576,7 @@ func (h *shellCallHandler) entrypointCall(ctx context.Context, cmd string, args return nil, err } if h.debug { - shellLogf(ctx, "[DBG] โ”” Found(%s, %v): %+v\n", cmd, args, st) + shellDebug(ctx, "โ”” Found(%s, %v): %+v", cmd, args, st) } if st.IsStdlib() { @@ -614,14 +614,14 @@ func (h *shellCallHandler) isCurrentContextFunction(name string) bool { func (h *shellCallHandler) stateLookup(ctx context.Context, name string) (*ShellState, error) { if h.debug { - shellLogf(ctx, "[DBG] โ”” StateLookup(%v)\n", name) + shellDebug(ctx, " โ”” StateLookup(%v)", name) } // Is current context a loaded module? if md, _ := h.GetModuleDef(nil); md != nil { // 1. Function in current context if md.HasMainFunction(name) { if h.debug { - shellLogf(ctx, "[DBG] - found in current context\n") + shellDebug(ctx, " - found in current context") } return h.newState(), nil } @@ -629,7 +629,7 @@ func (h *shellCallHandler) stateLookup(ctx context.Context, name string) (*Shell // 2. Dependency short name if dep := md.GetDependency(name); dep != nil { if h.debug { - shellLogf(ctx, "[DBG] - found dependency (%s)\n", dep.ModRef) + shellDebug(ctx, " - found dependency (%s)", dep.ModRef) } depSt, _, err := h.GetDependency(ctx, name) return depSt, err @@ -639,7 +639,7 @@ func (h *shellCallHandler) stateLookup(ctx context.Context, name string) (*Shell // 3. Standard library command if cmd, _ := h.StdlibCommand(name); cmd != nil { if h.debug { - shellLogf(ctx, "[DBG] - found stdlib command\n") + shellDebug(ctx, " - found stdlib command") } return h.newStdlibState(), nil } @@ -656,7 +656,7 @@ func (h *shellCallHandler) stateLookup(ctx context.Context, name string) (*Shell return nil, fmt.Errorf("function or module %q not found", name) } if h.debug { - shellLogf(ctx, "[DBG] - found module reference\n") + shellDebug(ctx, " - found module reference") } return st, nil } @@ -705,34 +705,109 @@ func (h *shellCallHandler) functionCall(ctx context.Context, st *ShellState, nam return st.WithCall(fn, argValues), nil } -// parseArgumentValues returns a map of argument names and their parsed values -func (h *shellCallHandler) parseArgumentValues(ctx context.Context, md *moduleDef, fn *modFunction, args []string) (map[string]any, error) { - req := fn.RequiredArgs() - - // Required args in dagger shell are positional but we have a lot of power - // in custom flags that we want to reuse, so just add the corresponding - // `--flag-name` args in order for pflags to be able to parse them. - pos := make([]string, 0, len(req)*2) - for i, arg := range args { - if strings.HasPrefix(arg, "--") { - break +// shellPreprocessArgs converts positional arguments to flag arguments +// +// Values are not processed. This function is used to leverage pflags to parse +// flags interspersed with positional arguments, so a function's required +// arguments can be placed anywhere. Then we get the unprocessed flags in +// order to validate if the remaining number of positional arguments match +// the number of required arguments. +// +// Required args in dagger shell are positional but we have a lot of power +// in custom flags that we want to reuse, so just add the corresponding +// `--flag-name` args in order for pflags to be able to parse them later. +// +// Additionally, if there's only one required argument that is a list of strings, +// all positional arguments are used as elements of that list. +func shellPreprocessArgs(fn *modFunction, args []string) ([]string, error) { + flags := pflag.NewFlagSet(fn.CmdName(), pflag.ContinueOnError) + + opts := fn.OptionalArgs() + + // All CLI arguments are strings at first, but booleans can be omitted. + // We don't wan't to process values yet, just validate and consume the flags + // so we get the remaining positional args. + for _, arg := range opts { + name := arg.FlagName() + + switch arg.TypeDef.Kind { + case dagger.TypeDefKindListKind: + switch arg.TypeDef.AsList.ElementTypeDef.Kind { + case dagger.TypeDefKindBooleanKind: + flags.BoolSlice(name, nil, "") + default: + flags.StringSlice(name, nil, "") + } + case dagger.TypeDefKindBooleanKind: + flags.Bool(name, false, "") + default: + flags.String(name, "", "") } - if i >= len(req) { - return nil, fmt.Errorf("accepts at most %d positional argument(s)", len(req)) + } + + if err := flags.Parse(args); err != nil { + return args, err + } + + reqs := fn.RequiredArgs() + + // A command for with-exec could include a `--`, but it's only if it's + // the first positional argument that means we've stopped processing our + // flags. So these are equivalent: + // - with-exec --redirect-stdout /out git checkout -- file + // - with-exec --redirect-stdout /out -- git checkout -- file + pos := flags.Args() + if flags.ArgsLenAtDash() == 1 { + pos = pos[1:] + } + + // Final processed arguments that will be parsed in the second phase later on. + var a []string + + // Convenience for a single required argument of type [String!]! + // All positional arguments become elements in the list. + if len(reqs) == 1 && len(pos) > 1 && reqs[0].TypeDef.String() == "[]string" { + name := reqs[0].FlagName() + a = make([]string, 0, len(opts)+len(pos)) + + for _, value := range pos { + // Instead of creating a CSV value here, repeat the flag for each + // one so that pflags is the only one dealing with CSVs. + a = append(a, fmt.Sprintf("--%s=%v", name, value)) + } + } else { + // Normal use case. Positional arguments should match number of required function arguments + if err := ExactArgs(len(reqs))(pos); err != nil { + return args, err + } + a = make([]string, 0, len(fn.Args)) + // Use the `=` syntax so that each element in the args list corresponds + // to a single argument instead of two. + for i, arg := range reqs { + a = append(a, fmt.Sprintf("--%s=%v", arg.FlagName(), pos[i])) } - pos = append(pos, "--"+req[i].FlagName(), arg) } - if len(req) > len(pos)/2 { - numMissing := len(req) - len(pos)/2 - missing := make([]string, 0, numMissing) - for _, arg := range req[len(req)-numMissing:] { - missing = append(missing, arg.FlagName()) + // Add all the optional flags + flags.Visit(func(f *pflag.Flag) { + if f.Changed { + a = append(a, fmt.Sprintf("--%s=%v", f.Name, f.Value.String())) } - return nil, fmt.Errorf("missing %d positional argument(s): %s", numMissing, strings.Join(missing, ", ")) + }) + + return a, nil +} + +// parseArgumentValues returns a map of argument names and their parsed values +func (h *shellCallHandler) parseArgumentValues(ctx context.Context, md *moduleDef, fn *modFunction, args []string) (map[string]any, error) { + args, err := shellPreprocessArgs(fn, args) + if err != nil { + return nil, err } - rem := args[len(req):] + if h.debug { + shellDebug(ctx, "preprocessed arguments: %v", args) + } flags := pflag.NewFlagSet(fn.CmdName(), pflag.ContinueOnError) flags.SetOutput(interp.HandlerCtx(ctx).Stderr) @@ -792,7 +867,7 @@ func (h *shellCallHandler) parseArgumentValues(ctx context.Context, md *moduleDe } return flags.Set(flag.Name, value) } - if err := flags.ParseAll(append(pos, rem...), f); err != nil { + if err := flags.ParseAll(args, f); err != nil { return nil, err } @@ -864,7 +939,7 @@ func (h *shellCallHandler) parseStateArgument(ctx context.Context, arg *modFunct func (h *shellCallHandler) Result(ctx context.Context, st *ShellState) error { if h.debug { h.withTerminal(func(_ io.Reader, _, stderr io.Writer) error { - fmt.Fprintf(stderr, "[DBG] Result state: %+v\n", st) + shellFDebug(stderr, "Result state: %+v", st) return nil }) } @@ -933,9 +1008,15 @@ func (h *shellCallHandler) executeRequest(ctx context.Context, q *querybuilder.S }) } -func shellLogf(ctx context.Context, msg string, args ...any) { +func shellDebug(ctx context.Context, msg string, args ...any) { hctx := interp.HandlerCtx(ctx) - fmt.Fprintf(hctx.Stderr, msg, args...) + shellFDebug(hctx.Stderr, msg, args...) +} + +func shellFDebug(w io.Writer, msg string, args ...any) { + cat := termenv.String("[DBG]").Foreground(termenv.ANSIMagenta).String() + msg = termenv.String(fmt.Sprintf(msg, args...)).Faint().String() + fmt.Fprintln(w, cat, msg) } // First command in pipeline: e.g., `cmd1 | cmd2 | cmd3` diff --git a/core/integration/module_shell_test.go b/core/integration/module_shell_test.go index 53e22b208e..5ecbfb4b4c 100644 --- a/core/integration/module_shell_test.go +++ b/core/integration/module_shell_test.go @@ -2,7 +2,9 @@ package core import ( "context" + "fmt" "regexp" + "strings" "testing" "dagger.io/dagger" @@ -572,6 +574,52 @@ func (m *Test) DirectoryID(ctx context.Context) (string, error) { require.Equal(t, "bar", out) } +func (ShellSuite) TestArgsSpread(ctx context.Context, t *testctx.T) { + c := connect(ctx, t) + modGen := daggerCliBase(t, c) + + for _, tc := range []struct { + command string + expected string + }{ + { + command: `with-exec echo hello world | stdout`, + expected: "hello world\n", + }, + { + command: `with-exec echo with tail options --redirect-stdout /out | file /out | contents`, + expected: "with tail options\n", + }, + { + command: `with-exec --redirect-stdout /out echo with head options | file /out | contents`, + expected: "with head options\n", + }, + { + command: `with-exec --stdin "with interspersed args" cat --redirect-stdout /out | file /out | contents`, + expected: "with interspersed args", + }, + { + command: `with-exec --redirect-stdout /out -- echo -n stop processing flags: --expand | file /out | contents`, + expected: "stop processing flags: --expand", + }, + { + command: `with-env-variable MSG "with double" | with-exec --redirect-stdout /out --expand -- echo -n \$MSG --expand | file /out | contents`, + expected: "with double --expand", + }, + { + command: `with-exec --redirect-stdout /out -- echo -n git checkout -- file | file /out | contents`, + expected: "git checkout -- file", + }, + } { + t.Run(strings.TrimSpace(tc.expected), func(ctx context.Context, t *testctx.T) { + script := fmt.Sprintf("container | from %s | %s", alpineImage, tc.command) + out, err := modGen.With(daggerShell(script)).Stdout(ctx) + require.NoError(t, err) + require.Equal(t, tc.expected, out) + }) + } +} + func (ShellSuite) TestInstall(ctx context.Context, t *testctx.T) { c := connect(ctx, t) From 796de0f90302b96cfeafed0f5991ec8971fa9d76 Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Wed, 11 Dec 2024 11:20:02 +0000 Subject: [PATCH 23/35] chore: update release date for v0.15.0 (#9166) --- .changes/v0.15.0.md | 2 +- CHANGELOG.md | 2 +- helm/dagger/.changes/v0.15.0.md | 2 +- helm/dagger/CHANGELOG.md | 2 +- sdk/go/.changes/v0.15.0.md | 2 +- sdk/go/CHANGELOG.md | 2 +- sdk/python/.changes/v0.15.0.md | 2 +- sdk/python/CHANGELOG.md | 2 +- sdk/typescript/.changes/v0.15.0.md | 2 +- sdk/typescript/CHANGELOG.md | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.changes/v0.15.0.md b/.changes/v0.15.0.md index 1afb76ca38..2114c79270 100644 --- a/.changes/v0.15.0.md +++ b/.changes/v0.15.0.md @@ -1,4 +1,4 @@ -## v0.15.0 - 2024-12-10 +## v0.15.0 - 2024-12-11 ### ๐Ÿ”ฅ Breaking Changes - `Container.asService` now uses the command specified by `withDefaultArgs` instead of the last `withExec` command by @rajatjindal in https://github.com/dagger/dagger/pull/8865 \ diff --git a/CHANGELOG.md b/CHANGELOG.md index 734038b506..62ccbe6c67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). -## v0.15.0 - 2024-12-10 +## v0.15.0 - 2024-12-11 ### ๐Ÿ”ฅ Breaking Changes - `Container.asService` now uses the command specified by `withDefaultArgs` instead of the last `withExec` command by @rajatjindal in https://github.com/dagger/dagger/pull/8865 \ diff --git a/helm/dagger/.changes/v0.15.0.md b/helm/dagger/.changes/v0.15.0.md index 4512a44ced..335312c2d0 100644 --- a/helm/dagger/.changes/v0.15.0.md +++ b/helm/dagger/.changes/v0.15.0.md @@ -1,4 +1,4 @@ -## v0.15.0 - 2024-12-10 +## v0.15.0 - 2024-12-11 ### Dependencies - Bump Engine to v0.15.0 by @jedevc in https://github.com/dagger/dagger/pull/9158 diff --git a/helm/dagger/CHANGELOG.md b/helm/dagger/CHANGELOG.md index 3f54bf3789..10e95c730c 100644 --- a/helm/dagger/CHANGELOG.md +++ b/helm/dagger/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). -## v0.15.0 - 2024-12-10 +## v0.15.0 - 2024-12-11 ### Dependencies - Bump Engine to v0.15.0 by @jedevc in https://github.com/dagger/dagger/pull/9158 diff --git a/sdk/go/.changes/v0.15.0.md b/sdk/go/.changes/v0.15.0.md index 4e34edd196..5d24a64eac 100644 --- a/sdk/go/.changes/v0.15.0.md +++ b/sdk/go/.changes/v0.15.0.md @@ -1,4 +1,4 @@ -## sdk/go/v0.15.0 - 2024-12-10 +## sdk/go/v0.15.0 - 2024-12-11 This SDK uses ๐Ÿš™ Engine + ๐Ÿš— CLI version `v0.15.0`. [See what changed in that release](https://github.com/dagger/dagger/releases/tag/v0.15.0). diff --git a/sdk/go/CHANGELOG.md b/sdk/go/CHANGELOG.md index 938aa4c1d2..b2481588a5 100644 --- a/sdk/go/CHANGELOG.md +++ b/sdk/go/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). -## sdk/go/v0.15.0 - 2024-12-10 +## sdk/go/v0.15.0 - 2024-12-11 This SDK uses ๐Ÿš™ Engine + ๐Ÿš— CLI version `v0.15.0`. [See what changed in that release](https://github.com/dagger/dagger/releases/tag/v0.15.0). diff --git a/sdk/python/.changes/v0.15.0.md b/sdk/python/.changes/v0.15.0.md index b86166d2e6..c483b3d599 100644 --- a/sdk/python/.changes/v0.15.0.md +++ b/sdk/python/.changes/v0.15.0.md @@ -1,4 +1,4 @@ -## sdk/python/v0.15.0 - 2024-12-10 +## sdk/python/v0.15.0 - 2024-12-11 This SDK uses ๐Ÿš™ Engine + ๐Ÿš— CLI version `v0.15.0`. [See what changed in that release](https://github.com/dagger/dagger/releases/tag/v0.15.0). diff --git a/sdk/python/CHANGELOG.md b/sdk/python/CHANGELOG.md index 15b1554da8..801a698fa4 100644 --- a/sdk/python/CHANGELOG.md +++ b/sdk/python/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). -## sdk/python/v0.15.0 - 2024-12-10 +## sdk/python/v0.15.0 - 2024-12-11 This SDK uses ๐Ÿš™ Engine + ๐Ÿš— CLI version `v0.15.0`. [See what changed in that release](https://github.com/dagger/dagger/releases/tag/v0.15.0). diff --git a/sdk/typescript/.changes/v0.15.0.md b/sdk/typescript/.changes/v0.15.0.md index 6a15b48bc2..7bf09e4a96 100644 --- a/sdk/typescript/.changes/v0.15.0.md +++ b/sdk/typescript/.changes/v0.15.0.md @@ -1,4 +1,4 @@ -## sdk/typescript/v0.15.0 - 2024-12-10 +## sdk/typescript/v0.15.0 - 2024-12-11 This SDK uses ๐Ÿš™ Engine + ๐Ÿš— CLI version `v0.15.0`. [See what changed in that release](https://github.com/dagger/dagger/releases/tag/v0.15.0). diff --git a/sdk/typescript/CHANGELOG.md b/sdk/typescript/CHANGELOG.md index a979f59065..a560726a2e 100644 --- a/sdk/typescript/CHANGELOG.md +++ b/sdk/typescript/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). -## sdk/typescript/v0.15.0 - 2024-12-10 +## sdk/typescript/v0.15.0 - 2024-12-11 This SDK uses ๐Ÿš™ Engine + ๐Ÿš— CLI version `v0.15.0`. [See what changed in that release](https://github.com/dagger/dagger/releases/tag/v0.15.0). From 10a23b5de1f4b3396dfd0e5940120e2d06752aad Mon Sep 17 00:00:00 2001 From: vikram-dagger <112123850+vikram-dagger@users.noreply.github.com> Date: Wed, 11 Dec 2024 15:41:50 +0400 Subject: [PATCH 24/35] docs: Update code snippets for services API changes (#9113) Co-authored-by: Justin Chadwell --- .../services/bind-services/go/main.go | 5 ++-- .../services/bind-services/python/main.py | 3 +- .../bind-services/typescript/index.ts | 3 +- .../create-interdependent-services/go/main.go | 14 ++++------ .../python/main.py | 18 ++++++++---- .../typescript/index.ts | 28 ++++++++++--------- .../expose-dagger-services-to-host/go/main.go | 7 +++-- .../python/main.py | 3 +- .../typescript/index.ts | 3 +- .../expose-host-services-to-dagger/go/main.go | 2 +- .../services/persist-service-state/go/main.go | 4 +-- .../persist-service-state/python/main.py | 2 +- .../persist-service-state/typescript/index.ts | 2 +- .../services/service-lifecycle-1/go/main.go | 4 ++- .../service-lifecycle-1/python/main.py | 7 ++++- .../service-lifecycle-1/typescript/index.ts | 2 +- .../services/service-lifecycle-2/go/main.go | 4 ++- .../service-lifecycle-2/python/main.py | 7 ++++- .../service-lifecycle-2/typescript/index.ts | 2 +- .../services/service-lifecycle-3/go/main.go | 4 ++- .../service-lifecycle-3/python/main.py | 7 ++++- .../service-lifecycle-3/typescript/index.ts | 2 +- .../services/start-stop-services/go/main.go | 4 ++- .../test-against-db-service/go/main.go | 4 ++- .../test-against-db-service/python/main.py | 2 +- .../typescript/index.ts | 2 +- .../cookbook/snippets/set-env-var/go/main.go | 6 +--- .../cookbook/snippets/set-env-vars/go/main.go | 2 -- .../features/snippets/debugging-1/go/main.go | 6 +--- .../programmable-pipelines-1/go/main.go | 2 -- .../programmable-pipelines-2/go/main.go | 2 -- .../features/snippets/services-1/go/main.go | 5 +--- .../snippets/services-1/python/main.py | 3 +- .../snippets/services-1/typescript/index.ts | 3 +- .../features/snippets/services-2/go/main.go | 2 -- 35 files changed, 90 insertions(+), 86 deletions(-) diff --git a/docs/current_docs/api/snippets/services/bind-services/go/main.go b/docs/current_docs/api/snippets/services/bind-services/go/main.go index 7996d88e8f..044fdfa770 100644 --- a/docs/current_docs/api/snippets/services/bind-services/go/main.go +++ b/docs/current_docs/api/snippets/services/bind-services/go/main.go @@ -2,7 +2,7 @@ package main import ( "context" - "main/internal/dagger" + "dagger/my-module/internal/dagger" ) type MyModule struct{} @@ -13,9 +13,8 @@ func (m *MyModule) HttpService() *dagger.Service { From("python"). WithWorkdir("/srv"). WithNewFile("index.html", "Hello, world!"). - WithDefaultArgs([]string{"python", "-m", "http.server", "8080"}). WithExposedPort(8080). - AsService() + AsService(dagger.ContainerAsServiceOpts{Args: []string{"python", "-m", "http.server", "8080"}}) } // Send a request to an HTTP service and return the response diff --git a/docs/current_docs/api/snippets/services/bind-services/python/main.py b/docs/current_docs/api/snippets/services/bind-services/python/main.py index bd1f28e729..cc410f6b9d 100644 --- a/docs/current_docs/api/snippets/services/bind-services/python/main.py +++ b/docs/current_docs/api/snippets/services/bind-services/python/main.py @@ -12,9 +12,8 @@ def http_service(self) -> dagger.Service: .from_("python") .with_workdir("/srv") .with_new_file("index.html", "Hello, world!") - .with_exec(["python", "-m", "http.server", "8080"]) .with_exposed_port(8080) - .as_service() + .as_service(args=["python", "-m", "http.server", "8080"]) ) @function diff --git a/docs/current_docs/api/snippets/services/bind-services/typescript/index.ts b/docs/current_docs/api/snippets/services/bind-services/typescript/index.ts index 598ab62c3f..e9d1691ef0 100644 --- a/docs/current_docs/api/snippets/services/bind-services/typescript/index.ts +++ b/docs/current_docs/api/snippets/services/bind-services/typescript/index.ts @@ -12,9 +12,8 @@ class MyModule { .from("python") .withWorkdir("/srv") .withNewFile("index.html", "Hello, world!") - .withExec(["python", "-m", "http.server", "8080"]) .withExposedPort(8080) - .asService() + .asService({ args: ["python", "-m", "http.server", "8080"] }) } /** diff --git a/docs/current_docs/api/snippets/services/create-interdependent-services/go/main.go b/docs/current_docs/api/snippets/services/create-interdependent-services/go/main.go index 8baa6bee4f..1fd4b87318 100644 --- a/docs/current_docs/api/snippets/services/create-interdependent-services/go/main.go +++ b/docs/current_docs/api/snippets/services/create-interdependent-services/go/main.go @@ -2,7 +2,7 @@ package main import ( "context" - "main/internal/dagger" + "dagger/my-module/internal/dagger" ) type MyModule struct{} @@ -12,10 +12,8 @@ func (m *MyModule) Services(ctx context.Context) (*dagger.Service, error) { svcA := dag.Container().From("nginx"). WithExposedPort(80). - WithExec([]string{"sh", "-c", ` - nginx & while true; do curl svcb:80 && sleep 1; done - `}). - AsService().WithHostname("svca") + AsService(dagger.ContainerAsServiceOpts{Args: []string{"sh", "-c", `nginx & while true; do curl svcb:80 && sleep 1; done`}}). + WithHostname("svca") _, err := svcA.Start(ctx) if err != nil { @@ -24,10 +22,8 @@ func (m *MyModule) Services(ctx context.Context) (*dagger.Service, error) { svcB := dag.Container().From("nginx"). WithExposedPort(80). - WithExec([]string{"sh", "-c", ` -nginx & while true; do curl svca:80 && sleep 1; done - `}). - AsService().WithHostname("svcb") + AsService(dagger.ContainerAsServiceOpts{Args: []string{"sh", "-c", `nginx & while true; do curl svca:80 && sleep 1; done`}}). + WithHostname("svcb") svcB, err = svcB.Start(ctx) if err != nil { diff --git a/docs/current_docs/api/snippets/services/create-interdependent-services/python/main.py b/docs/current_docs/api/snippets/services/create-interdependent-services/python/main.py index bc110f5a4a..e07d8963e9 100644 --- a/docs/current_docs/api/snippets/services/create-interdependent-services/python/main.py +++ b/docs/current_docs/api/snippets/services/create-interdependent-services/python/main.py @@ -11,10 +11,13 @@ async def services(self) -> dagger.Service: dag.container() .from_("nginx") .with_exposed_port(80) - .with_exec( - ["sh", "-c", "nginx & while true; do curl svcb:80 && sleep 1; done"] + .as_service( + args=[ + "sh", + "-c", + "nginx & while true; do curl svcb:80 && sleep 1; done", + ] ) - .as_service() .with_hostname("svca") ) @@ -24,10 +27,13 @@ async def services(self) -> dagger.Service: dag.container() .from_("nginx") .with_exposed_port(80) - .with_exec( - ["sh", "-c", "nginx & while true; do curl svca:80 && sleep 1; done"] + .as_service( + args=[ + "sh", + "-c", + "nginx & while true; do curl svca:80 && sleep 1; done", + ] ) - .as_service() .with_hostname("svcb") ) diff --git a/docs/current_docs/api/snippets/services/create-interdependent-services/typescript/index.ts b/docs/current_docs/api/snippets/services/create-interdependent-services/typescript/index.ts index 1a94d1b719..6e75a69377 100644 --- a/docs/current_docs/api/snippets/services/create-interdependent-services/typescript/index.ts +++ b/docs/current_docs/api/snippets/services/create-interdependent-services/typescript/index.ts @@ -1,4 +1,4 @@ -import { object, func, Service } from "@dagger.io/dagger" +import { dag, object, func, Service } from "@dagger.io/dagger" @object() class MyModule { @@ -9,12 +9,13 @@ class MyModule { .container() .from("nginx") .withExposedPort(80) - .withExec([ - "sh", - "-c", - `nginx & while true; do curl svcb:80 && sleep 1; done`, - ]) - .asService() + .asService({ + args: [ + "sh", + "-c", + `nginx & while true; do curl svcb:80 && sleep 1; done`, + ], + }) .withHostname("svca") await svcA.start() @@ -23,12 +24,13 @@ class MyModule { .container() .from("nginx") .withExposedPort(80) - .withExec([ - "sh", - "-c", - `nginx & while true; do curl svca:80 && sleep 1; done`, - ]) - .asService() + .asService({ + args: [ + "sh", + "-c", + `nginx & while true; do curl svca:80 && sleep 1; done`, + ], + }) .withHostname("svcb") await svcB.start() diff --git a/docs/current_docs/api/snippets/services/expose-dagger-services-to-host/go/main.go b/docs/current_docs/api/snippets/services/expose-dagger-services-to-host/go/main.go index d0c554098f..a36e57c06e 100644 --- a/docs/current_docs/api/snippets/services/expose-dagger-services-to-host/go/main.go +++ b/docs/current_docs/api/snippets/services/expose-dagger-services-to-host/go/main.go @@ -1,6 +1,8 @@ package main -import "main/internal/dagger" +import ( + "dagger/my-module/internal/dagger" +) type MyModule struct{} @@ -10,7 +12,6 @@ func (m *MyModule) HttpService() *dagger.Service { From("python"). WithWorkdir("/srv"). WithNewFile("index.html", "Hello, world!"). - WithDefaultArgs([]string{"python", "-m", "http.server", "8080"}). WithExposedPort(8080). - AsService() + AsService(dagger.ContainerAsServiceOpts{Args: []string{"python", "-m", "http.server", "8080"}}) } diff --git a/docs/current_docs/api/snippets/services/expose-dagger-services-to-host/python/main.py b/docs/current_docs/api/snippets/services/expose-dagger-services-to-host/python/main.py index d645d8b435..5ad547d89d 100644 --- a/docs/current_docs/api/snippets/services/expose-dagger-services-to-host/python/main.py +++ b/docs/current_docs/api/snippets/services/expose-dagger-services-to-host/python/main.py @@ -12,7 +12,6 @@ def http_service(self) -> dagger.Service: .from_("python") .with_workdir("/srv") .with_new_file("index.html", "Hello, world!") - .with_exec(["python", "-m", "http.server", "8080"]) .with_exposed_port(8080) - .as_service() + .as_service(args=["python", "-m", "http.server", "8080"]) ) diff --git a/docs/current_docs/api/snippets/services/expose-dagger-services-to-host/typescript/index.ts b/docs/current_docs/api/snippets/services/expose-dagger-services-to-host/typescript/index.ts index b4d9b20ffb..4046b8f02b 100644 --- a/docs/current_docs/api/snippets/services/expose-dagger-services-to-host/typescript/index.ts +++ b/docs/current_docs/api/snippets/services/expose-dagger-services-to-host/typescript/index.ts @@ -12,8 +12,7 @@ class MyModule { .from("python") .withWorkdir("/srv") .withNewFile("index.html", "Hello, world!") - .withExec(["python", "-m", "http.server", "8080"]) .withExposedPort(8080) - .asService() + .asService({ args: ["python", "-m", "http.server", "8080"] }) } } diff --git a/docs/current_docs/api/snippets/services/expose-host-services-to-dagger/go/main.go b/docs/current_docs/api/snippets/services/expose-host-services-to-dagger/go/main.go index 43f3cfbdda..a5fded5a10 100644 --- a/docs/current_docs/api/snippets/services/expose-host-services-to-dagger/go/main.go +++ b/docs/current_docs/api/snippets/services/expose-host-services-to-dagger/go/main.go @@ -2,7 +2,7 @@ package main import ( "context" - "main/internal/dagger" + "dagger/my-module/internal/dagger" ) type MyModule struct{} diff --git a/docs/current_docs/api/snippets/services/persist-service-state/go/main.go b/docs/current_docs/api/snippets/services/persist-service-state/go/main.go index b3db98821a..63b6f6982a 100644 --- a/docs/current_docs/api/snippets/services/persist-service-state/go/main.go +++ b/docs/current_docs/api/snippets/services/persist-service-state/go/main.go @@ -3,7 +3,7 @@ package main import ( "context" - "main/internal/dagger" + "dagger/my-module/internal/dagger" ) type MyModule struct{} @@ -15,7 +15,7 @@ func (m *MyModule) Redis(ctx context.Context) *dagger.Container { WithExposedPort(6379). WithMountedCache("/data", dag.CacheVolume("my-redis")). WithWorkdir("/data"). - AsService() + AsService(dagger.ContainerAsServiceOpts{UseEntrypoint: true}) redisCLI := dag.Container(). From("redis"). diff --git a/docs/current_docs/api/snippets/services/persist-service-state/python/main.py b/docs/current_docs/api/snippets/services/persist-service-state/python/main.py index 08279ca88a..b392d0e23c 100644 --- a/docs/current_docs/api/snippets/services/persist-service-state/python/main.py +++ b/docs/current_docs/api/snippets/services/persist-service-state/python/main.py @@ -15,7 +15,7 @@ def redis(self) -> dagger.Container: .with_exposed_port(6379) .with_mounted_cache("/data", dag.cache_volume("my-redis")) .with_workdir("/data") - .as_service() + .as_service(use_entrypoint=True) ) # create Redis client container diff --git a/docs/current_docs/api/snippets/services/persist-service-state/typescript/index.ts b/docs/current_docs/api/snippets/services/persist-service-state/typescript/index.ts index 785e5bcd8f..a3804d3786 100644 --- a/docs/current_docs/api/snippets/services/persist-service-state/typescript/index.ts +++ b/docs/current_docs/api/snippets/services/persist-service-state/typescript/index.ts @@ -13,7 +13,7 @@ class MyModule { .withExposedPort(6379) .withMountedCache("/data", dag.cacheVolume("my-redis")) .withWorkdir("/data") - .asService() + .asService({ useEntrypoint: true }) const redisCLI = dag .container() diff --git a/docs/current_docs/api/snippets/services/service-lifecycle-1/go/main.go b/docs/current_docs/api/snippets/services/service-lifecycle-1/go/main.go index ecca184ba3..43eb86fdda 100644 --- a/docs/current_docs/api/snippets/services/service-lifecycle-1/go/main.go +++ b/docs/current_docs/api/snippets/services/service-lifecycle-1/go/main.go @@ -2,6 +2,8 @@ package main import ( "context" + + "dagger/my-module/internal/dagger" ) type MyModule struct{} @@ -11,7 +13,7 @@ func (m *MyModule) RedisService(ctx context.Context) (string, error) { redisSrv := dag.Container(). From("redis"). WithExposedPort(6379). - AsService() + AsService(dagger.ContainerAsServiceOpts{UseEntrypoint: true}) // create Redis client container redisCLI := dag.Container(). diff --git a/docs/current_docs/api/snippets/services/service-lifecycle-1/python/main.py b/docs/current_docs/api/snippets/services/service-lifecycle-1/python/main.py index 575760fac1..b653c38063 100644 --- a/docs/current_docs/api/snippets/services/service-lifecycle-1/python/main.py +++ b/docs/current_docs/api/snippets/services/service-lifecycle-1/python/main.py @@ -6,7 +6,12 @@ class MyModule: @function async def redis_service(self) -> str: """Creates Redis service and client.""" - redis_srv = dag.container().from_("redis").with_exposed_port(6379).as_service() + redis_srv = ( + dag.container() + .from_("redis") + .with_exposed_port(6379) + .as_service(use_entrypoint=True) + ) # create Redis client container redis_cli = ( diff --git a/docs/current_docs/api/snippets/services/service-lifecycle-1/typescript/index.ts b/docs/current_docs/api/snippets/services/service-lifecycle-1/typescript/index.ts index 840ff11992..e56986c3ce 100644 --- a/docs/current_docs/api/snippets/services/service-lifecycle-1/typescript/index.ts +++ b/docs/current_docs/api/snippets/services/service-lifecycle-1/typescript/index.ts @@ -11,7 +11,7 @@ class MyModule { .container() .from("redis") .withExposedPort(6379) - .asService() + .asService({ useEntrypoint: true }) // create Redis client container const redisCLI = dag diff --git a/docs/current_docs/api/snippets/services/service-lifecycle-2/go/main.go b/docs/current_docs/api/snippets/services/service-lifecycle-2/go/main.go index 12b9fb8c4c..ed25c0ef79 100644 --- a/docs/current_docs/api/snippets/services/service-lifecycle-2/go/main.go +++ b/docs/current_docs/api/snippets/services/service-lifecycle-2/go/main.go @@ -2,6 +2,8 @@ package main import ( "context" + + "dagger/my-module/internal/dagger" ) type MyModule struct{} @@ -11,7 +13,7 @@ func (m *MyModule) RedisService(ctx context.Context) (string, error) { redisSrv := dag.Container(). From("redis"). WithExposedPort(6379). - AsService() + AsService(dagger.ContainerAsServiceOpts{UseEntrypoint: true}) // create Redis client container redisCLI := dag.Container(). diff --git a/docs/current_docs/api/snippets/services/service-lifecycle-2/python/main.py b/docs/current_docs/api/snippets/services/service-lifecycle-2/python/main.py index 353e209ba9..8f9ac0fd58 100644 --- a/docs/current_docs/api/snippets/services/service-lifecycle-2/python/main.py +++ b/docs/current_docs/api/snippets/services/service-lifecycle-2/python/main.py @@ -6,7 +6,12 @@ class MyModule: @function async def redis_service(self) -> str: """Creates Redis service and client.""" - redis_srv = dag.container().from_("redis").with_exposed_port(6379).as_service() + redis_srv = ( + dag.container() + .from_("redis") + .with_exposed_port(6379) + .as_service(use_entrypoint=True) + ) # create Redis client container redis_cli = ( diff --git a/docs/current_docs/api/snippets/services/service-lifecycle-2/typescript/index.ts b/docs/current_docs/api/snippets/services/service-lifecycle-2/typescript/index.ts index 91a8b0a5b2..47b54a2eeb 100644 --- a/docs/current_docs/api/snippets/services/service-lifecycle-2/typescript/index.ts +++ b/docs/current_docs/api/snippets/services/service-lifecycle-2/typescript/index.ts @@ -11,7 +11,7 @@ class MyModule { .container() .from("redis") .withExposedPort(6379) - .asService() + .asService({ useEntrypoint: true }) // create Redis client container const redisCLI = dag diff --git a/docs/current_docs/api/snippets/services/service-lifecycle-3/go/main.go b/docs/current_docs/api/snippets/services/service-lifecycle-3/go/main.go index 16266c5e6c..30382dbdc6 100644 --- a/docs/current_docs/api/snippets/services/service-lifecycle-3/go/main.go +++ b/docs/current_docs/api/snippets/services/service-lifecycle-3/go/main.go @@ -2,6 +2,8 @@ package main import ( "context" + + "dagger/my-module/internal/dagger" ) type MyModule struct{} @@ -11,7 +13,7 @@ func (m *MyModule) RedisService(ctx context.Context) (string, error) { redisSrv := dag.Container(). From("redis"). WithExposedPort(6379). - AsService() + AsService(dagger.ContainerAsServiceOpts{UseEntrypoint: true}) // create Redis client container redisCLI := dag.Container(). diff --git a/docs/current_docs/api/snippets/services/service-lifecycle-3/python/main.py b/docs/current_docs/api/snippets/services/service-lifecycle-3/python/main.py index 7bee468bc5..caf0e14a61 100644 --- a/docs/current_docs/api/snippets/services/service-lifecycle-3/python/main.py +++ b/docs/current_docs/api/snippets/services/service-lifecycle-3/python/main.py @@ -6,7 +6,12 @@ class MyModule: @function async def redis_service(self) -> str: """Creates Redis service and client.""" - redis_srv = dag.container().from_("redis").with_exposed_port(6379).as_service() + redis_srv = ( + dag.container() + .from_("redis") + .with_exposed_port(6379) + .as_service(use_entrypoint=True) + ) # create Redis client container redis_cli = ( diff --git a/docs/current_docs/api/snippets/services/service-lifecycle-3/typescript/index.ts b/docs/current_docs/api/snippets/services/service-lifecycle-3/typescript/index.ts index 2c05e866b9..dd852b0797 100644 --- a/docs/current_docs/api/snippets/services/service-lifecycle-3/typescript/index.ts +++ b/docs/current_docs/api/snippets/services/service-lifecycle-3/typescript/index.ts @@ -11,7 +11,7 @@ class MyModule { .container() .from("redis") .withExposedPort(6379) - .asService() + .asService({ useEntrypoint: true }) // create Redis client container const redisCLI = dag diff --git a/docs/current_docs/api/snippets/services/start-stop-services/go/main.go b/docs/current_docs/api/snippets/services/start-stop-services/go/main.go index c123e3921e..b38c634e1c 100644 --- a/docs/current_docs/api/snippets/services/start-stop-services/go/main.go +++ b/docs/current_docs/api/snippets/services/start-stop-services/go/main.go @@ -2,6 +2,8 @@ package main import ( "context" + + "dagger/my-module/internal/dagger" ) type MyModule struct{} @@ -11,7 +13,7 @@ func (m *MyModule) RedisService(ctx context.Context) (string, error) { redisSrv := dag.Container(). From("redis"). WithExposedPort(6379). - AsService() + AsService(dagger.ContainerAsServiceOpts{UseEntrypoint: true}) // start Redis ahead of time so it stays up for the duration of the test redisSrv, err := redisSrv.Start(ctx) diff --git a/docs/current_docs/api/snippets/services/test-against-db-service/go/main.go b/docs/current_docs/api/snippets/services/test-against-db-service/go/main.go index b9038da4ef..49a6fb6a13 100644 --- a/docs/current_docs/api/snippets/services/test-against-db-service/go/main.go +++ b/docs/current_docs/api/snippets/services/test-against-db-service/go/main.go @@ -2,6 +2,8 @@ package main import ( "context" + + "dagger/my-module/internal/dagger" ) type MyModule struct{} @@ -15,7 +17,7 @@ func (m *MyModule) Test(ctx context.Context) (string, error) { WithEnvVariable("MARIADB_DATABASE", "drupal"). WithEnvVariable("MARIADB_ROOT_PASSWORD", "root"). WithExposedPort(3306). - AsService() + AsService(dagger.ContainerAsServiceOpts{UseEntrypoint: true}) // get Drupal base image // install additional dependencies diff --git a/docs/current_docs/api/snippets/services/test-against-db-service/python/main.py b/docs/current_docs/api/snippets/services/test-against-db-service/python/main.py index 71befb44ca..705f18e8f3 100644 --- a/docs/current_docs/api/snippets/services/test-against-db-service/python/main.py +++ b/docs/current_docs/api/snippets/services/test-against-db-service/python/main.py @@ -15,7 +15,7 @@ async def test(self) -> str: .with_env_variable("MARIADB_DATABASE", "drupal") .with_env_variable("MARIADB_ROOT_PASSWORD", "root") .with_exposed_port(3306) - .as_service() + .as_service(use_entrypoint=True) ) # get Drupal base image diff --git a/docs/current_docs/api/snippets/services/test-against-db-service/typescript/index.ts b/docs/current_docs/api/snippets/services/test-against-db-service/typescript/index.ts index e2211fd53d..4e3e6af276 100644 --- a/docs/current_docs/api/snippets/services/test-against-db-service/typescript/index.ts +++ b/docs/current_docs/api/snippets/services/test-against-db-service/typescript/index.ts @@ -15,7 +15,7 @@ class MyModule { .withEnvVariable("MARIADB_DATABASE", "drupal") .withEnvVariable("MARIADB_ROOT_PASSWORD", "root") .withExposedPort(3306) - .asService() + .asService({ useEntrypoint: true }) // get Drupal base image // install additional dependencies diff --git a/docs/current_docs/cookbook/snippets/set-env-var/go/main.go b/docs/current_docs/cookbook/snippets/set-env-var/go/main.go index 9e1ab357ab..ec04d44c75 100644 --- a/docs/current_docs/cookbook/snippets/set-env-var/go/main.go +++ b/docs/current_docs/cookbook/snippets/set-env-var/go/main.go @@ -1,10 +1,6 @@ package main -import ( - "context" - - "dagger.io/dagger/dag" -) +import "context" type MyModule struct{} diff --git a/docs/current_docs/cookbook/snippets/set-env-vars/go/main.go b/docs/current_docs/cookbook/snippets/set-env-vars/go/main.go index 4c44df552c..c237c0ac5a 100644 --- a/docs/current_docs/cookbook/snippets/set-env-vars/go/main.go +++ b/docs/current_docs/cookbook/snippets/set-env-vars/go/main.go @@ -4,8 +4,6 @@ import ( "context" "dagger/my-module/internal/dagger" - - "dagger.io/dagger/dag" ) type MyModule struct{} diff --git a/docs/current_docs/features/snippets/debugging-1/go/main.go b/docs/current_docs/features/snippets/debugging-1/go/main.go index 29304a6954..3e44b56a14 100644 --- a/docs/current_docs/features/snippets/debugging-1/go/main.go +++ b/docs/current_docs/features/snippets/debugging-1/go/main.go @@ -1,10 +1,6 @@ package main -import ( - "context" - - "dagger.io/dagger/dag" -) +import "context" type MyModule struct{} diff --git a/docs/current_docs/features/snippets/programmable-pipelines-1/go/main.go b/docs/current_docs/features/snippets/programmable-pipelines-1/go/main.go index a44b671d77..d96c06d351 100644 --- a/docs/current_docs/features/snippets/programmable-pipelines-1/go/main.go +++ b/docs/current_docs/features/snippets/programmable-pipelines-1/go/main.go @@ -3,8 +3,6 @@ package main import ( "context" "dagger/my-module/internal/dagger" - - "dagger.io/dagger/dag" ) type MyModule struct{} diff --git a/docs/current_docs/features/snippets/programmable-pipelines-2/go/main.go b/docs/current_docs/features/snippets/programmable-pipelines-2/go/main.go index 2e1ca076b3..2853e817d7 100644 --- a/docs/current_docs/features/snippets/programmable-pipelines-2/go/main.go +++ b/docs/current_docs/features/snippets/programmable-pipelines-2/go/main.go @@ -3,8 +3,6 @@ package main import ( "context" "dagger/my-module/internal/dagger" - - "dagger.io/dagger/dag" ) type MyModule struct{} diff --git a/docs/current_docs/features/snippets/services-1/go/main.go b/docs/current_docs/features/snippets/services-1/go/main.go index cc2b63d01a..63468b44a2 100644 --- a/docs/current_docs/features/snippets/services-1/go/main.go +++ b/docs/current_docs/features/snippets/services-1/go/main.go @@ -2,8 +2,6 @@ package main import ( "dagger/my-module/internal/dagger" - - "dagger.io/dagger/dag" ) type MyModule struct{} @@ -13,7 +11,6 @@ func (m *MyModule) HttpService() *dagger.Service { From("python"). WithWorkdir("/srv"). WithNewFile("index.html", "Hello, world!"). - WithDefaultArgs([]string{"python", "-m", "http.server", "8080"}). WithExposedPort(8080). - AsService() + AsService(dagger.ContainerAsServiceOpts{Args: []string{"python", "-m", "http.server", "8080"}}) } diff --git a/docs/current_docs/features/snippets/services-1/python/main.py b/docs/current_docs/features/snippets/services-1/python/main.py index a43d6732a2..75821d3a1c 100644 --- a/docs/current_docs/features/snippets/services-1/python/main.py +++ b/docs/current_docs/features/snippets/services-1/python/main.py @@ -11,7 +11,6 @@ def http_service(self) -> dagger.Service: .from_("python") .with_workdir("/srv") .with_new_file("index.html", "Hello, world!") - .with_exec(["python", "-m", "http.server", "8080"]) .with_exposed_port(8080) - .as_service() + .as_service(args=["python", "-m", "http.server", "8080"]) ) diff --git a/docs/current_docs/features/snippets/services-1/typescript/index.ts b/docs/current_docs/features/snippets/services-1/typescript/index.ts index ba04f8a688..ea9a09aee3 100644 --- a/docs/current_docs/features/snippets/services-1/typescript/index.ts +++ b/docs/current_docs/features/snippets/services-1/typescript/index.ts @@ -9,8 +9,7 @@ class MyModule { .from("python") .withWorkdir("/srv") .withNewFile("index.html", "Hello, world!") - .withExec(["python", "-m", "http.server", "8080"]) .withExposedPort(8080) - .asService() + .asService({ args: ["python", "-m", "http.server", "8080"] }) } } diff --git a/docs/current_docs/features/snippets/services-2/go/main.go b/docs/current_docs/features/snippets/services-2/go/main.go index 49d1133e7b..045549a4a1 100644 --- a/docs/current_docs/features/snippets/services-2/go/main.go +++ b/docs/current_docs/features/snippets/services-2/go/main.go @@ -3,8 +3,6 @@ package main import ( "context" "dagger/my-module/internal/dagger" - - "dagger.io/dagger/dag" ) type MyModule struct{} From ba70be4ef8c2517bf9b683ca49e565cfaa771cae Mon Sep 17 00:00:00 2001 From: vikram-dagger <112123850+vikram-dagger@users.noreply.github.com> Date: Wed, 11 Dec 2024 15:42:55 +0400 Subject: [PATCH 25/35] docs: Update API docs for TypeScript SDK improvements (#9115) --- docs/current_docs/api/module-structure.mdx | 2 +- docs/current_docs/configuration/modules.mdx | 22 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/docs/current_docs/api/module-structure.mdx b/docs/current_docs/api/module-structure.mdx index 9c9bc54137..e5ff34c7a2 100644 --- a/docs/current_docs/api/module-structure.mdx +++ b/docs/current_docs/api/module-structure.mdx @@ -267,7 +267,7 @@ This can be useful to add a few requirements to the module's execution environme -The runtime container is currently hardcoded to run in Node.js 21.3 (although this may be configurable in future). +The runtime container is currently hardcoded to run in Node.js 22.11.0, but it can be overridden by [setting an alternative base image](../configuration/modules.mdx#alternative-base-images). [Bun](https://bun.sh/) is experimentally supported and [work is in progress](https://github.com/dagger/dagger/issues/4368) to support [Deno](https://deno.com/). diff --git a/docs/current_docs/configuration/modules.mdx b/docs/current_docs/configuration/modules.mdx index 2c9ec3c31f..b4a2cf91c3 100644 --- a/docs/current_docs/configuration/modules.mdx +++ b/docs/current_docs/configuration/modules.mdx @@ -150,3 +150,25 @@ When a package manager is not explicitly defined within the `package.json` file, :::warning This behavior however should be considered a sensible fallback, and not as an explicit configuration. Since this default can change, we encourage you to configure a package manager explicitly. ::: + +### Alternative base images + +The image to use is derived from the version in the `dagger.runtime` field if it's present. If this is not suitable for your needs, you can specify a custom base image in your module's `package.json`, tailoring the SDK to your project's needs. + +:::warning +It is recommended to use this feature only for advanced use cases such as adding bespoke environment variables, authentication files or operating system packages to the runtime container. Ensure that you avoid deviating from the default image too much, as doing so could create unexpected results. +::: + +To change the base image, set the field `dagger.baseImage` in your Dagger module's `package.json` file. + +```json +{ + "dagger": { + "baseImage": "node:23.2.0-alpine@sha256:ecefaffd4706c5879af52e022fdb8ea30cbd6590e2a30d05347790d690727c6c" + } +} +``` + +:::note +Currently, only Alpine-based images are supported. +::: From 8566d034c2863f93671c425705a604cd7c5f15eb Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Thu, 12 Dec 2024 03:37:03 +0000 Subject: [PATCH 26/35] Improve releasing during v0.15.0 (#9167) * ci: fix flag for helm publish workflow Signed-off-by: Justin Chadwell * docs: fix accidental dagger.io/dagger/dag import in more places Signed-off-by: Justin Chadwell * chore: fix daggerverse bump with semver parameters Signed-off-by: Justin Chadwell * ci: update to v0.15.0 Signed-off-by: Justin Chadwell * chore: bump internal tooling to v0.15.0 Signed-off-by: Justin Chadwell * chore: update RELEASING Signed-off-by: Justin Chadwell * ci: update code to account for new v0.15.0 changes Signed-off-by: Justin Chadwell * ci: generate discord notifications in releaser module This actually means we get the right tag here - since the tag properly comes from the github release, and these two operations are strongly tied together. Signed-off-by: Justin Chadwell * ci: Bump Dagger version in Alternative CI Runners Signed-off-by: Gerhard Lazu --------- Signed-off-by: Justin Chadwell Signed-off-by: Gerhard Lazu Co-authored-by: Gerhard Lazu --- .dagger/engine.go | 11 ++- .dagger/go.mod | 15 +++-- .dagger/go.sum | 30 +++++---- .dagger/sdk_elixir.go | 12 +++- .dagger/sdk_go.go | 10 +++ .dagger/sdk_php.go | 11 ++- .dagger/sdk_python.go | 12 +++- .dagger/sdk_rust.go | 12 +++- .dagger/sdk_typescript.go | 12 +++- .dagger/test.go | 14 ++-- .github/actions/call/action.yml | 2 +- .github/dagger.json | 2 +- .github/main.go | 2 +- .../_dagger_on_depot_remote_engine.yml | 2 +- .github/workflows/daggerverse-preview.gen.yml | 4 +- .github/workflows/docs.gen.yml | 4 +- .github/workflows/engine-and-cli.yml | 26 +++---- .github/workflows/github.gen.yml | 4 +- .github/workflows/helm.gen.yml | 2 +- .github/workflows/publish.yml | 67 ++++++------------- .github/workflows/sdk-rust-publish.yml | 10 +-- .github/workflows/sdks.gen.yml | 42 ++++++------ RELEASING.md | 2 +- dagger.json | 44 +++++------- .../features/snippets/debugging-2/go/main.go | 2 - .../features/snippets/secrets/go/main.go | 2 - go.mod | 4 +- helm/.dagger/go.mod | 17 ++--- helm/.dagger/go.sum | 38 ++++++----- helm/.dagger/main.go | 11 +++ helm/dagger.json | 11 ++- modules/daggerverse/main.go | 4 ++ releaser/.dagger/go.mod | 14 ++-- releaser/.dagger/go.sum | 32 ++++----- releaser/.dagger/main.go | 60 ++++++++++++++--- releaser/dagger.json | 10 ++- 36 files changed, 315 insertions(+), 242 deletions(-) diff --git a/.dagger/engine.go b/.dagger/engine.go index ade7c5bc21..ec56caa3f8 100644 --- a/.dagger/engine.go +++ b/.dagger/engine.go @@ -163,14 +163,13 @@ func (e *DaggerEngine) Service( // only one engine can run off it's local state dir at a time; Private means that we will attempt to re-use // these cache volumes if they are not already locked to another running engine but otherwise will create a new // one, which gets us best-effort cache re-use for these nested engine services - Sharing: dagger.Private, - }). - WithExec(nil, dagger.ContainerWithExecOpts{ - UseEntrypoint: true, - InsecureRootCapabilities: true, + Sharing: dagger.CacheSharingModePrivate, }) - return devEngine.AsService(), nil + return devEngine.AsService(dagger.ContainerAsServiceOpts{ + UseEntrypoint: true, + InsecureRootCapabilities: true, + }), nil } // Lint the engine diff --git a/.dagger/go.mod b/.dagger/go.mod index 14f9c7c08c..5314566b00 100644 --- a/.dagger/go.mod +++ b/.dagger/go.mod @@ -2,18 +2,18 @@ module github.com/dagger/dagger/.dagger go 1.23.2 -require github.com/dagger/dagger/engine/distconsts v0.14.0 +require github.com/dagger/dagger/engine/distconsts v0.15.0 replace github.com/dagger/dagger/engine/distconsts => ../engine/distconsts require ( - github.com/99designs/gqlgen v0.17.55 + github.com/99designs/gqlgen v0.17.57 github.com/Khan/genqlient v0.7.0 github.com/containerd/platforms v0.2.1 github.com/magefile/mage v1.15.0 github.com/moby/buildkit v0.14.0-rc1.0.20240603193914-3d789eb740a9 github.com/opencontainers/image-spec v1.1.0 - github.com/vektah/gqlparser/v2 v2.5.17 + github.com/vektah/gqlparser/v2 v2.5.19 go.opentelemetry.io/otel v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 @@ -26,8 +26,8 @@ require ( go.opentelemetry.io/proto/otlp v1.3.1 golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 golang.org/x/mod v0.20.0 - golang.org/x/sync v0.8.0 - google.golang.org/grpc v1.66.1 + golang.org/x/sync v0.9.0 + google.golang.org/grpc v1.68.0 ) require ( @@ -42,6 +42,7 @@ require ( github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/sosodev/duration v1.3.1 // indirect + github.com/stretchr/testify v1.10.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect @@ -49,10 +50,10 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.27.0 golang.org/x/net v0.29.0 // indirect golang.org/x/sys v0.26.0 // indirect - golang.org/x/text v0.18.0 // indirect + golang.org/x/text v0.19.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect - google.golang.org/protobuf v1.34.2 // indirect + google.golang.org/protobuf v1.35.2 // indirect ) replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 diff --git a/.dagger/go.sum b/.dagger/go.sum index 6c13d106ae..d624521376 100644 --- a/.dagger/go.sum +++ b/.dagger/go.sum @@ -1,5 +1,5 @@ -github.com/99designs/gqlgen v0.17.55 h1:3vzrNWYyzSZjGDFo68e5j9sSauLxfKvLp+6ioRokVtM= -github.com/99designs/gqlgen v0.17.55/go.mod h1:3Bq768f8hgVPGZxL8aY9MaYmbxa6llPM/qu1IGH1EJo= +github.com/99designs/gqlgen v0.17.57 h1:Ak4p60BRq6QibxY0lEc0JnQhDurfhxA67sp02lMjmPc= +github.com/99designs/gqlgen v0.17.57/go.mod h1:Jx61hzOSTcR4VJy/HFIgXiQ5rJ0Ypw8DxWLjbYDAUw0= github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= @@ -18,6 +18,8 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -48,10 +50,10 @@ github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERA github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/vektah/gqlparser/v2 v2.5.17 h1:9At7WblLV7/36nulgekUgIaqHZWn5hxqluxrxGUhOmI= -github.com/vektah/gqlparser/v2 v2.5.17/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/vektah/gqlparser/v2 v2.5.19 h1:bhCPCX1D4WWzCDvkPl4+TP1N8/kLrWnp43egplt7iSg= +github.com/vektah/gqlparser/v2 v2.5.19/go.mod h1:y7kvl5bBlDeuWIvLtA9849ncyvx6/lj06RsMrEjVy3U= go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 h1:oM0GTNKGlc5qHctWeIGTVyda4iFFalOzMZ3Ehj5rwB4= @@ -90,21 +92,21 @@ golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.66.1 h1:hO5qAXR19+/Z44hmvIM4dQFMSYX9XcWsByfoxutBpAM= -google.golang.org/grpc v1.66.1/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0= +google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA= +google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= +google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/.dagger/sdk_elixir.go b/.dagger/sdk_elixir.go index b965d3ee95..a751068e0b 100644 --- a/.dagger/sdk_elixir.go +++ b/.dagger/sdk_elixir.go @@ -100,7 +100,7 @@ func (t ElixirSDK) Generate(ctx context.Context) (*dagger.Directory, error) { // Test the publishing process func (t ElixirSDK) TestPublish(ctx context.Context, tag string) error { - return t.Publish(ctx, tag, true, nil, "https://github.com/dagger/dagger.git", nil) + return t.Publish(ctx, tag, true, nil, "https://github.com/dagger/dagger.git", nil, nil) } // Publish the Elixir SDK @@ -116,8 +116,11 @@ func (t ElixirSDK) Publish( // +optional // +default="https://github.com/dagger/dagger.git" gitRepoSource string, + // +optional githubToken *dagger.Secret, + // +optional + discordWebhook *dagger.Secret, ) error { version := strings.TrimPrefix(tag, "sdk/elixir/") mixFile := "/sdk/elixir/mix.exs" @@ -155,6 +158,13 @@ func (t ElixirSDK) Publish( }); err != nil { return err } + + if err := dag.Releaser().Notify(ctx, gitRepoSource, "sdk/elixir/"+version, "๐Ÿงช Elixir SDK", dagger.ReleaserNotifyOpts{ + DiscordWebhook: discordWebhook, + DryRun: dryRun, + }); err != nil { + return err + } } return nil diff --git a/.dagger/sdk_go.go b/.dagger/sdk_go.go index 5b8ddcf183..3a314bda76 100644 --- a/.dagger/sdk_go.go +++ b/.dagger/sdk_go.go @@ -94,6 +94,7 @@ func (t GoSDK) TestPublish(ctx context.Context, tag string) error { "dagger-ci", "hello@dagger.io", nil, + nil, ) } @@ -120,6 +121,8 @@ func (t GoSDK) Publish( // +optional githubToken *dagger.Secret, + // +optional + discordWebhook *dagger.Secret, ) error { version := strings.TrimPrefix(tag, "sdk/go/") @@ -148,6 +151,13 @@ func (t GoSDK) Publish( }); err != nil { return err } + + if err := dag.Releaser().Notify(ctx, gitRepoSource, "sdk/go/"+version, "๐Ÿน Go SDK", dagger.ReleaserNotifyOpts{ + DiscordWebhook: discordWebhook, + DryRun: dryRun, + }); err != nil { + return err + } } return nil diff --git a/.dagger/sdk_php.go b/.dagger/sdk_php.go index c00ad52c5f..b9c23c279e 100644 --- a/.dagger/sdk_php.go +++ b/.dagger/sdk_php.go @@ -102,7 +102,7 @@ func (t PHPSDK) Generate(ctx context.Context) (*dagger.Directory, error) { // Test the publishing process func (t PHPSDK) TestPublish(ctx context.Context, tag string) error { - return t.Publish(ctx, tag, true, "https://github.com/dagger/dagger-php-sdk.git", "https://github.com/dagger/dagger.git", "dagger-ci", "hello@dagger.io", nil) + return t.Publish(ctx, tag, true, "https://github.com/dagger/dagger-php-sdk.git", "https://github.com/dagger/dagger.git", "dagger-ci", "hello@dagger.io", nil, nil) } // Publish the PHP SDK @@ -128,6 +128,8 @@ func (t PHPSDK) Publish( // +optional githubToken *dagger.Secret, + // +optional + discordWebhook *dagger.Secret, ) error { version := strings.TrimPrefix(tag, "sdk/php/") @@ -154,6 +156,13 @@ func (t PHPSDK) Publish( }); err != nil { return err } + + if err := dag.Releaser().Notify(ctx, gitRepoSource, "sdk/php/"+version, "๐Ÿ˜ PHP SDK", dagger.ReleaserNotifyOpts{ + DiscordWebhook: discordWebhook, + DryRun: dryRun, + }); err != nil { + return err + } } return nil diff --git a/.dagger/sdk_python.go b/.dagger/sdk_python.go index aaf29200e9..bd794a3798 100644 --- a/.dagger/sdk_python.go +++ b/.dagger/sdk_python.go @@ -135,7 +135,7 @@ func (t PythonSDK) Generate(ctx context.Context) (*dagger.Directory, error) { // Test the publishing process func (t PythonSDK) TestPublish(ctx context.Context, tag string) error { - return t.Publish(ctx, tag, true, "", nil, "https://github.com/dagger/dagger.git", nil) + return t.Publish(ctx, tag, true, "", nil, "https://github.com/dagger/dagger.git", nil, nil) } // Publish the Python SDK @@ -154,8 +154,11 @@ func (t PythonSDK) Publish( // +optional // +default="https://github.com/dagger/dagger.git" gitRepoSource string, + // +optional githubToken *dagger.Secret, + // +optional + discordWebhook *dagger.Secret, ) error { version := strings.TrimPrefix(tag, "sdk/python/") @@ -184,6 +187,13 @@ func (t PythonSDK) Publish( }); err != nil { return err } + + if err := dag.Releaser().Notify(ctx, gitRepoSource, "sdk/python/"+version, "๐Ÿ Python SDK", dagger.ReleaserNotifyOpts{ + DiscordWebhook: discordWebhook, + DryRun: dryRun, + }); err != nil { + return err + } } return nil diff --git a/.dagger/sdk_rust.go b/.dagger/sdk_rust.go index 365caa3ef7..f911702c20 100644 --- a/.dagger/sdk_rust.go +++ b/.dagger/sdk_rust.go @@ -92,7 +92,7 @@ func (r RustSDK) Generate(ctx context.Context) (*dagger.Directory, error) { // Test the publishing process func (r RustSDK) TestPublish(ctx context.Context, tag string) error { - return r.Publish(ctx, tag, true, nil, "https://github.com/dagger/dagger.git", nil) + return r.Publish(ctx, tag, true, nil, "https://github.com/dagger/dagger.git", nil, nil) } // Publish the Rust SDK @@ -109,8 +109,11 @@ func (r RustSDK) Publish( // +optional // +default="https://github.com/dagger/dagger.git" gitRepoSource string, + // +optional githubToken *dagger.Secret, + // +optional + discordWebhook *dagger.Secret, ) error { version := strings.TrimPrefix(tag, "sdk/rust/") @@ -155,6 +158,13 @@ func (r RustSDK) Publish( }); err != nil { return err } + + if err := dag.Releaser().Notify(ctx, gitRepoSource, "sdk/rust/"+version, "โš™๏ธ Rust SDK", dagger.ReleaserNotifyOpts{ + DiscordWebhook: discordWebhook, + DryRun: dryRun, + }); err != nil { + return err + } } return nil diff --git a/.dagger/sdk_typescript.go b/.dagger/sdk_typescript.go index 08df888656..94230f0a00 100644 --- a/.dagger/sdk_typescript.go +++ b/.dagger/sdk_typescript.go @@ -166,7 +166,7 @@ func (t TypescriptSDK) Generate(ctx context.Context) (*dagger.Directory, error) // Test the publishing process func (t TypescriptSDK) TestPublish(ctx context.Context, tag string) error { - return t.Publish(ctx, tag, true, nil, "https://github.com/dagger/dagger.git", nil) + return t.Publish(ctx, tag, true, nil, "https://github.com/dagger/dagger.git", nil, nil) } // Publish the Typescript SDK @@ -182,8 +182,11 @@ func (t TypescriptSDK) Publish( // +optional // +default="https://github.com/dagger/dagger.git" gitRepoSource string, + // +optional githubToken *dagger.Secret, + // +optional + discordWebhook *dagger.Secret, ) error { version := strings.TrimPrefix(tag, "sdk/typescript/") versionFlag := strings.TrimPrefix(version, "v") @@ -228,6 +231,13 @@ always-auth=true`, plaintext) }); err != nil { return err } + + if err := dag.Releaser().Notify(ctx, gitRepoSource, "sdk/typescript/"+version, "โฌข TypeScript SDK", dagger.ReleaserNotifyOpts{ + DiscordWebhook: discordWebhook, + DryRun: dryRun, + }); err != nil { + return err + } } return nil diff --git a/.dagger/test.go b/.dagger/test.go index 6adc9f330a..7d07abd928 100644 --- a/.dagger/test.go +++ b/.dagger/test.go @@ -85,11 +85,10 @@ func (t *Test) Telemetry( WithServiceBinding("privateregistry", privateRegistry()). WithExposedPort(1234, dagger.ContainerWithExposedPortOpts{Protocol: dagger.NetworkProtocolTcp}). WithMountedCache(distconsts.EngineDefaultStateDir, dag.CacheVolume("dagger-dev-engine-test-state"+identity.NewID())). - WithExec(nil, dagger.ContainerWithExecOpts{ + AsService(dagger.ContainerAsServiceOpts{ UseEntrypoint: true, InsecureRootCapabilities: true, - }). - AsService() + }) endpoint, err := devEngineSvc.Endpoint(ctx, dagger.ServiceEndpointOpts{Port: 1234, Scheme: "tcp"}) if err != nil { @@ -321,11 +320,10 @@ func (t *Test) testCmd(ctx context.Context) (*dagger.Container, error) { WithServiceBinding("privateregistry", privateRegistry()). WithExposedPort(1234, dagger.ContainerWithExposedPortOpts{Protocol: dagger.NetworkProtocolTcp}). WithMountedCache(distconsts.EngineDefaultStateDir, dag.CacheVolume("dagger-dev-engine-test-state"+identity.NewID())). - WithExec(nil, dagger.ContainerWithExecOpts{ + AsService(dagger.ContainerAsServiceOpts{ UseEntrypoint: true, InsecureRootCapabilities: true, - }). - AsService() + }) endpoint, err := devEngineSvc.Endpoint(ctx, dagger.ServiceEndpointOpts{Port: 1234, Scheme: "tcp"}) if err != nil { @@ -358,7 +356,7 @@ func registry() *dagger.Service { return dag.Container(). From("registry:2"). WithExposedPort(5000, dagger.ContainerWithExposedPortOpts{Protocol: dagger.NetworkProtocolTcp}). - AsService() + AsService(dagger.ContainerAsServiceOpts{UseEntrypoint: true}) } func privateRegistry() *dagger.Service { @@ -370,5 +368,5 @@ func privateRegistry() *dagger.Service { WithEnvVariable("REGISTRY_AUTH_HTPASSWD_REALM", "Registry Realm"). WithEnvVariable("REGISTRY_AUTH_HTPASSWD_PATH", "/auth/htpasswd"). WithExposedPort(5000, dagger.ContainerWithExposedPortOpts{Protocol: dagger.NetworkProtocolTcp}). - AsService() + AsService(dagger.ContainerAsServiceOpts{UseEntrypoint: true}) } diff --git a/.github/actions/call/action.yml b/.github/actions/call/action.yml index 67276649f3..7d3cc60c9f 100644 --- a/.github/actions/call/action.yml +++ b/.github/actions/call/action.yml @@ -13,7 +13,7 @@ inputs: version: description: "Dagger version to run against" - default: "v0.14.0" + default: "v0.15.0" required: false dev-engine: diff --git a/.github/dagger.json b/.github/dagger.json index f7c40b58cb..8f45c4890b 100644 --- a/.github/dagger.json +++ b/.github/dagger.json @@ -1,6 +1,6 @@ { "name": "ci", - "engineVersion": "v0.14.0", + "engineVersion": "v0.15.0", "sdk": "go", "dependencies": [ { diff --git a/.github/main.go b/.github/main.go index d85d9a1652..42c7bab4e4 100644 --- a/.github/main.go +++ b/.github/main.go @@ -9,7 +9,7 @@ import ( ) const ( - daggerVersion = "v0.14.0" + daggerVersion = "v0.15.0" upstreamRepository = "dagger/dagger" defaultRunner = "ubuntu-latest" publicToken = "dag_dagger_sBIv6DsjNerWvTqt2bSFeigBUqWxp9bhh3ONSSgeFnw" diff --git a/.github/workflows/_dagger_on_depot_remote_engine.yml b/.github/workflows/_dagger_on_depot_remote_engine.yml index 7131777429..515741857c 100644 --- a/.github/workflows/_dagger_on_depot_remote_engine.yml +++ b/.github/workflows/_dagger_on_depot_remote_engine.yml @@ -15,7 +15,7 @@ on: dagger: description: "Dagger version" type: string - default: "0.14.0" + default: "0.15.0" required: false ubuntu: description: "Ubuntu version" diff --git a/.github/workflows/daggerverse-preview.gen.yml b/.github/workflows/daggerverse-preview.gen.yml index 03018a4e3f..e68ecd4feb 100644 --- a/.github/workflows/daggerverse-preview.gen.yml +++ b/.github/workflows/daggerverse-preview.gen.yml @@ -17,7 +17,7 @@ concurrency: jobs: deploy: runs-on: - - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-4c' || 'ubuntu-latest' }} + - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-4c' || 'ubuntu-latest' }} name: deploy steps: - name: Checkout @@ -47,7 +47,7 @@ jobs: # The install.sh script creates path ${prefix_dir}/bin curl -fsS https://dl.dagger.io/dagger/install.sh | BIN_DIR=${prefix_dir}/bin sh env: - DAGGER_VERSION: v0.14.0 + DAGGER_VERSION: v0.15.0 shell: bash - name: scripts/warm-engine.sh id: warm-engine diff --git a/.github/workflows/docs.gen.yml b/.github/workflows/docs.gen.yml index 21600ac963..19f13141a6 100644 --- a/.github/workflows/docs.gen.yml +++ b/.github/workflows/docs.gen.yml @@ -19,7 +19,7 @@ concurrency: jobs: docs: runs-on: - - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-4c' || 'ubuntu-latest' }} + - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-4c' || 'ubuntu-latest' }} name: Docs steps: - name: Checkout @@ -49,7 +49,7 @@ jobs: # The install.sh script creates path ${prefix_dir}/bin curl -fsS https://dl.dagger.io/dagger/install.sh | BIN_DIR=${prefix_dir}/bin sh env: - DAGGER_VERSION: v0.14.0 + DAGGER_VERSION: v0.15.0 shell: bash - name: scripts/warm-engine.sh id: warm-engine diff --git a/.github/workflows/engine-and-cli.yml b/.github/workflows/engine-and-cli.yml index a71f0899c7..ff2b8200c6 100644 --- a/.github/workflows/engine-and-cli.yml +++ b/.github/workflows/engine-and-cli.yml @@ -22,7 +22,7 @@ concurrency: jobs: lint: - runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-16c' || 'ubuntu-latest' }}" + runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-16c' || 'ubuntu-latest' }}" timeout-minutes: 10 steps: - uses: actions/checkout@v4 @@ -36,7 +36,7 @@ jobs: function: "scripts lint" test-publish: - runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-16c' || 'ubuntu-latest' }}" + runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-16c' || 'ubuntu-latest' }}" timeout-minutes: 20 steps: - uses: actions/checkout@v4 @@ -50,7 +50,7 @@ jobs: function: "engine publish --image=dagger-engine.dev --tag=main --dry-run" scan-engine: - runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-8c' || 'ubuntu-latest' }}" + runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-8c' || 'ubuntu-latest' }}" timeout-minutes: 10 steps: - uses: actions/checkout@v4 @@ -61,7 +61,7 @@ jobs: # TEMPORARILY DISABLED. Context: https://github.com/dagger/dagger/pull/8998#issuecomment-2491426455 # test: - # runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-16c-st' || 'ubuntu-latest' }}" + # runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-16c-st' || 'ubuntu-latest' }}" # timeout-minutes: 30 # steps: # - uses: actions/checkout@v4 @@ -71,7 +71,7 @@ jobs: # function: "test all --race=true --parallel=16" # upload-logs: true test-modules: - runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-16c-st' || 'ubuntu-latest' }}" + runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-16c-st' || 'ubuntu-latest' }}" timeout-minutes: 30 steps: - uses: actions/checkout@v4 @@ -82,7 +82,7 @@ jobs: upload-logs: true test-module-runtimes: - runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-16c-st' || 'ubuntu-latest' }}" + runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-16c-st' || 'ubuntu-latest' }}" timeout-minutes: 30 steps: - uses: actions/checkout@v4 @@ -93,7 +93,7 @@ jobs: upload-logs: true test-cli-engine: - runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-16c-st' || 'ubuntu-latest' }}" + runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-16c-st' || 'ubuntu-latest' }}" timeout-minutes: 30 steps: - uses: actions/checkout@v4 @@ -105,7 +105,7 @@ jobs: test-provision: # HACK: this is split out, since these tests require cgroupsv2 - # runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-16c-st' || 'ubuntu-latest' }}" + # runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-16c-st' || 'ubuntu-latest' }}" runs-on: "ubuntu-latest" timeout-minutes: 30 steps: @@ -117,7 +117,7 @@ jobs: upload-logs: true test-everything-else: - runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-16c-st' || 'ubuntu-latest' }}" + runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-16c-st' || 'ubuntu-latest' }}" timeout-minutes: 30 steps: - uses: actions/checkout@v4 @@ -133,7 +133,7 @@ jobs: # # TEMPORARILY DISABLED. Context: https://github.com/dagger/dagger/pull/8998#issuecomment-2491426455 # testdev: - # runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-32c-dind-st' || 'ubuntu-latest' }}" + # runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-32c-dind-st' || 'ubuntu-latest' }}" # timeout-minutes: 30 # steps: # - uses: actions/checkout@v4 @@ -145,7 +145,7 @@ jobs: # upload-logs: true testdev-modules: - runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-32c-dind-st' || 'ubuntu-latest' }}" + runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-32c-dind-st' || 'ubuntu-latest' }}" timeout-minutes: 30 steps: - uses: actions/checkout@v4 @@ -157,7 +157,7 @@ jobs: upload-logs: true testdev-module-runtimes: - runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-32c-dind-st' || 'ubuntu-latest' }}" + runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-32c-dind-st' || 'ubuntu-latest' }}" timeout-minutes: 30 steps: - uses: actions/checkout@v4 @@ -169,7 +169,7 @@ jobs: upload-logs: true testdev-container: - runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-32c-dind-st' || 'ubuntu-latest' }}" + runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-32c-dind-st' || 'ubuntu-latest' }}" timeout-minutes: 30 steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/github.gen.yml b/.github/workflows/github.gen.yml index 73f266f18d..41a7703ce1 100644 --- a/.github/workflows/github.gen.yml +++ b/.github/workflows/github.gen.yml @@ -19,7 +19,7 @@ concurrency: jobs: github: runs-on: - - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-4c' || 'ubuntu-latest' }} + - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-4c' || 'ubuntu-latest' }} name: Github steps: - name: Checkout @@ -49,7 +49,7 @@ jobs: # The install.sh script creates path ${prefix_dir}/bin curl -fsS https://dl.dagger.io/dagger/install.sh | BIN_DIR=${prefix_dir}/bin sh env: - DAGGER_VERSION: v0.14.0 + DAGGER_VERSION: v0.15.0 shell: bash - name: scripts/warm-engine.sh id: warm-engine diff --git a/.github/workflows/helm.gen.yml b/.github/workflows/helm.gen.yml index c81d495b82..a8f2ebadd1 100644 --- a/.github/workflows/helm.gen.yml +++ b/.github/workflows/helm.gen.yml @@ -49,7 +49,7 @@ jobs: # The install.sh script creates path ${prefix_dir}/bin curl -fsS https://dl.dagger.io/dagger/install.sh | BIN_DIR=${prefix_dir}/bin sh env: - DAGGER_VERSION: v0.14.0 + DAGGER_VERSION: v0.15.0 shell: bash - name: scripts/warm-engine.sh id: warm-engine diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index c2c2710265..14a28091fc 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -19,7 +19,7 @@ on: jobs: publish: if: ${{ github.repository == 'dagger/dagger' && github.event_name == 'push' }} - runs-on: dagger-g2-v0-14-0-16c + runs-on: dagger-g2-v0-15-0-16c steps: - uses: actions/checkout@v4 - name: "Publish Engine" @@ -63,6 +63,7 @@ jobs: AWS_CLOUDFRONT_DISTRIBUTION: ${{ vars.RELEASE_AWS_CLOUDFRONT_DISTRIBUTION }} ARTEFACTS_FQDN: ${{ vars.RELEASE_FQDN }} GORELEASER_KEY: ${{ secrets.GORELEASER_PRO_LICENSE_KEY }} + # TODO: move this into dagger function call - name: "Notify" uses: ./.github/actions/notify if: github.ref_name != 'main' @@ -72,44 +73,34 @@ jobs: publish-sdk-go: needs: publish - runs-on: dagger-g2-v0-14-0-4c + runs-on: dagger-g2-v0-15-0-4c steps: - uses: actions/checkout@v4 - name: "go publish" uses: ./.github/actions/call env: RELEASE_DAGGER_CI_TOKEN: ${{ secrets.RELEASE_DAGGER_CI_TOKEN }} + RELEASE_DISCORD_WEBHOOK: ${{ secrets.NEW_RELEASE_DISCORD_WEBHOOK }} with: - function: sdk go publish --tag="${{ github.ref_name }}" --github-token=env:RELEASE_DAGGER_CI_TOKEN - - name: "notify" - if: github.ref_name != 'main' - uses: ./.github/actions/notify - with: - message: "๐Ÿน Go SDK: https://github.com/${{ github.repository }}/releases/tag/${{ github.ref_name }}" - discord-webhook: ${{ secrets.NEW_RELEASE_DISCORD_WEBHOOK }} + function: sdk go publish --tag="${{ github.ref_name }}" --github-token=env:RELEASE_DAGGER_CI_TOKEN --discord-webhook=env:RELEASE_DISCORD_WEBHOOK publish-sdk-php: needs: publish - runs-on: dagger-g2-v0-14-0-4c + runs-on: dagger-g2-v0-15-0-4c steps: - uses: actions/checkout@v4 - name: "php publish" uses: ./.github/actions/call env: RELEASE_DAGGER_CI_TOKEN: ${{ secrets.RELEASE_DAGGER_CI_TOKEN }} + RELEASE_DISCORD_WEBHOOK: ${{ secrets.NEW_RELEASE_DISCORD_WEBHOOK }} with: - function: sdk php publish --tag="${{ github.ref_name }}" --github-token=env:RELEASE_DAGGER_CI_TOKEN - - name: "notify" - if: github.ref_name != 'main' - uses: ./.github/actions/notify - with: - message: "๐Ÿ˜ PHP SDK: https://github.com/${{ github.repository }}/releases/tag/${{ github.ref_name }}" - discord-webhook: ${{ secrets.NEW_RELEASE_DISCORD_WEBHOOK }} + function: sdk php publish --tag="${{ github.ref_name }}" --github-token=env:RELEASE_DAGGER_CI_TOKEN --discord-webhook=env:RELEASE_DISCORD_WEBHOOK publish-sdk-python: needs: publish if: github.ref_name != 'main' - runs-on: dagger-g2-v0-14-0-4c + runs-on: dagger-g2-v0-15-0-4c steps: - uses: actions/checkout@v4 - name: "python publish" @@ -118,18 +109,14 @@ jobs: RELEASE_DAGGER_CI_TOKEN: ${{ secrets.RELEASE_DAGGER_CI_TOKEN }} RELEASE_PYPI_TOKEN: ${{ secrets.RELEASE_PYPI_TOKEN }} RELEASE_PYPI_REPO: ${{ secrets.RELEASE_PYPI_REPO }} + RELEASE_DISCORD_WEBHOOK: ${{ secrets.NEW_RELEASE_DISCORD_WEBHOOK }} with: - function: sdk python publish --tag="${{ github.ref_name }}" --github-token=env:RELEASE_DAGGER_CI_TOKEN --pypi-repo="$RELEASE_PYPI_REPO" --pypi-token=env:RELEASE_PYPI_TOKEN - - name: "notify" - uses: ./.github/actions/notify - with: - message: "๐Ÿ Python SDK: https://github.com/${{ github.repository }}/releases/tag/${{ github.ref_name }}" - discord-webhook: ${{ secrets.NEW_RELEASE_DISCORD_WEBHOOK }} + function: sdk python publish --tag="${{ github.ref_name }}" --github-token=env:RELEASE_DAGGER_CI_TOKEN --discord-webhook=env:RELEASE_DISCORD_WEBHOOK --pypi-repo="$RELEASE_PYPI_REPO" --pypi-token=env:RELEASE_PYPI_TOKEN publish-sdk-typescript: needs: publish if: github.ref_name != 'main' - runs-on: dagger-g2-v0-14-0-4c + runs-on: dagger-g2-v0-15-0-4c steps: - uses: actions/checkout@v4 - name: "typescript publish" @@ -137,18 +124,14 @@ jobs: env: RELEASE_DAGGER_CI_TOKEN: ${{ secrets.RELEASE_DAGGER_CI_TOKEN }} RELEASE_NPM_TOKEN: ${{ secrets.RELEASE_NPM_TOKEN }} + RELEASE_DISCORD_WEBHOOK: ${{ secrets.NEW_RELEASE_DISCORD_WEBHOOK }} with: - function: sdk typescript publish --tag="${{ github.ref_name }}" --github-token=env:RELEASE_DAGGER_CI_TOKEN --npm-token=env:RELEASE_NPM_TOKEN - - name: "notify" - uses: ./.github/actions/notify - with: - message: "โฌข TypeScript SDK: https://github.com/${{ github.repository }}/releases/tag/${{ github.ref_name }}" - discord-webhook: ${{ secrets.NEW_RELEASE_DISCORD_WEBHOOK }} + function: sdk typescript publish --tag="${{ github.ref_name }}" --github-token=env:RELEASE_DAGGER_CI_TOKEN --discord-webhook=env:RELEASE_DISCORD_WEBHOOK --npm-token=env:RELEASE_NPM_TOKEN publish-sdk-elixir: needs: publish if: github.ref_name != 'main' - runs-on: dagger-g2-v0-14-0-4c + runs-on: dagger-g2-v0-15-0-4c steps: - uses: actions/checkout@v4 - name: "elixir publish" @@ -156,37 +139,29 @@ jobs: env: RELEASE_DAGGER_CI_TOKEN: ${{ secrets.RELEASE_DAGGER_CI_TOKEN }} HEX_API_KEY: ${{ secrets.HEX_API_KEY }} + RELEASE_DISCORD_WEBHOOK: ${{ secrets.NEW_RELEASE_DISCORD_WEBHOOK }} with: - function: sdk elixir publish --tag="${{ github.ref_name }}" --github-token=env:RELEASE_DAGGER_CI_TOKEN --hex-apikey=env:HEX_API_KEY - - name: "notify" - uses: ./.github/actions/notify - with: - message: "๐Ÿงช Elixir SDK: https://github.com/${{ github.repository }}/releases/tag/${{ github.ref_name }}" - discord-webhook: ${{ secrets.NEW_RELEASE_DISCORD_WEBHOOK }} + function: sdk elixir publish --tag="${{ github.ref_name }}" --github-token=env:RELEASE_DAGGER_CI_TOKEN --discord-webhook=env:RELEASE_DISCORD_WEBHOOK --hex-apikey=env:HEX_API_KEY publish-helm: needs: publish if: github.ref_name != 'main' - runs-on: dagger-g2-v0-14-0-4c + runs-on: dagger-g2-v0-15-0-4c steps: - uses: actions/checkout@v4 - name: "helm publish" uses: ./.github/actions/call env: RELEASE_DAGGER_CI_TOKEN: ${{ secrets.RELEASE_DAGGER_CI_TOKEN }} + RELEASE_DISCORD_WEBHOOK: ${{ secrets.NEW_RELEASE_DISCORD_WEBHOOK }} with: - function: publish --tag=${{ github.ref_name }} --github-token=env:RELEASE_DAGGER_CI_TOKEN + function: publish --target=${{ github.ref_name }} --github-token=env:RELEASE_DAGGER_CI_TOKEN --discord-webhook=env:RELEASE_DISCORD_WEBHOOK module: ./helm - - name: "notify" - uses: ./.github/actions/notify - with: - message: "โ˜ธ๏ธ Helm Chart: https://github.com/${{ github.repository }}/releases/tag/${{ github.ref_name }}" - discord-webhook: ${{ secrets.NEW_RELEASE_DISCORD_WEBHOOK }} daggerverse-bump-dagger: needs: publish if: github.ref_name != 'main' - runs-on: dagger-g2-v0-14-0-4c + runs-on: dagger-g2-v0-15-0-4c steps: - uses: actions/checkout@v4 - name: "Bump Dagger version in Daggerverse" diff --git a/.github/workflows/sdk-rust-publish.yml b/.github/workflows/sdk-rust-publish.yml index 89636b94a1..6c7ac063bd 100644 --- a/.github/workflows/sdk-rust-publish.yml +++ b/.github/workflows/sdk-rust-publish.yml @@ -5,18 +5,14 @@ on: jobs: publish: if: github.repository == 'dagger/dagger' - runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-4c' || 'ubuntu-latest' }}" + runs-on: "${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-4c' || 'ubuntu-latest' }}" steps: - uses: actions/checkout@v4 - name: "go publish" uses: ./.github/actions/call env: RELEASE_DAGGER_CI_TOKEN: ${{ secrets.RELEASE_DAGGER_CI_TOKEN }} + RELEASE_DISCORD_WEBHOOK: ${{ secrets.NEW_RELEASE_DISCORD_WEBHOOK }} CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} with: - function: sdk rust publish --tag="${{ github.ref_name }}" --github-token=env:RELEASE_DAGGER_CI_TOKEN --cargo-registry-token=env:CARGO_REGISTRY_TOKEN - - name: "notify" - uses: ./.github/actions/notify - with: - message: "โš™๏ธ Rust SDK: https://github.com/${{ github.repository }}/releases/tag/${{ github.ref_name }}" - discord-webhook: ${{ secrets.NEW_RELEASE_DISCORD_WEBHOOK }} + function: sdk rust publish --tag="${{ github.ref_name }}" --github-token=env:RELEASE_DAGGER_CI_TOKEN --discord-webhook=env:RELEASE_DISCORD_WEBHOOK --cargo-registry-token=env:CARGO_REGISTRY_TOKEN diff --git a/.github/workflows/sdks.gen.yml b/.github/workflows/sdks.gen.yml index 7286cd19da..6ff2396c48 100644 --- a/.github/workflows/sdks.gen.yml +++ b/.github/workflows/sdks.gen.yml @@ -19,7 +19,7 @@ concurrency: jobs: elixir: runs-on: - - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-4c' || 'ubuntu-latest' }} + - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-4c' || 'ubuntu-latest' }} name: elixir steps: - name: Checkout @@ -49,7 +49,7 @@ jobs: # The install.sh script creates path ${prefix_dir}/bin curl -fsS https://dl.dagger.io/dagger/install.sh | BIN_DIR=${prefix_dir}/bin sh env: - DAGGER_VERSION: v0.14.0 + DAGGER_VERSION: v0.15.0 shell: bash - name: scripts/warm-engine.sh id: warm-engine @@ -190,7 +190,7 @@ jobs: timeout-minutes: 10 elixir-dev: runs-on: - - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-8c-dind' || 'ubuntu-latest' }} + - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-8c-dind' || 'ubuntu-latest' }} name: elixir-dev steps: - name: Checkout @@ -404,7 +404,7 @@ jobs: timeout-minutes: 10 go: runs-on: - - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-4c' || 'ubuntu-latest' }} + - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-4c' || 'ubuntu-latest' }} name: go steps: - name: Checkout @@ -434,7 +434,7 @@ jobs: # The install.sh script creates path ${prefix_dir}/bin curl -fsS https://dl.dagger.io/dagger/install.sh | BIN_DIR=${prefix_dir}/bin sh env: - DAGGER_VERSION: v0.14.0 + DAGGER_VERSION: v0.15.0 shell: bash - name: scripts/warm-engine.sh id: warm-engine @@ -575,7 +575,7 @@ jobs: timeout-minutes: 10 go-dev: runs-on: - - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-8c-dind' || 'ubuntu-latest' }} + - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-8c-dind' || 'ubuntu-latest' }} name: go-dev steps: - name: Checkout @@ -789,7 +789,7 @@ jobs: timeout-minutes: 10 java: runs-on: - - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-4c' || 'ubuntu-latest' }} + - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-4c' || 'ubuntu-latest' }} name: java steps: - name: Checkout @@ -819,7 +819,7 @@ jobs: # The install.sh script creates path ${prefix_dir}/bin curl -fsS https://dl.dagger.io/dagger/install.sh | BIN_DIR=${prefix_dir}/bin sh env: - DAGGER_VERSION: v0.14.0 + DAGGER_VERSION: v0.15.0 shell: bash - name: scripts/warm-engine.sh id: warm-engine @@ -960,7 +960,7 @@ jobs: timeout-minutes: 10 java-dev: runs-on: - - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-8c-dind' || 'ubuntu-latest' }} + - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-8c-dind' || 'ubuntu-latest' }} name: java-dev steps: - name: Checkout @@ -1174,7 +1174,7 @@ jobs: timeout-minutes: 10 php: runs-on: - - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-4c' || 'ubuntu-latest' }} + - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-4c' || 'ubuntu-latest' }} name: php steps: - name: Checkout @@ -1204,7 +1204,7 @@ jobs: # The install.sh script creates path ${prefix_dir}/bin curl -fsS https://dl.dagger.io/dagger/install.sh | BIN_DIR=${prefix_dir}/bin sh env: - DAGGER_VERSION: v0.14.0 + DAGGER_VERSION: v0.15.0 shell: bash - name: scripts/warm-engine.sh id: warm-engine @@ -1345,7 +1345,7 @@ jobs: timeout-minutes: 10 php-dev: runs-on: - - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-8c-dind' || 'ubuntu-latest' }} + - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-8c-dind' || 'ubuntu-latest' }} name: php-dev steps: - name: Checkout @@ -1559,7 +1559,7 @@ jobs: timeout-minutes: 10 python: runs-on: - - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-4c' || 'ubuntu-latest' }} + - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-4c' || 'ubuntu-latest' }} name: python steps: - name: Checkout @@ -1589,7 +1589,7 @@ jobs: # The install.sh script creates path ${prefix_dir}/bin curl -fsS https://dl.dagger.io/dagger/install.sh | BIN_DIR=${prefix_dir}/bin sh env: - DAGGER_VERSION: v0.14.0 + DAGGER_VERSION: v0.15.0 shell: bash - name: scripts/warm-engine.sh id: warm-engine @@ -1730,7 +1730,7 @@ jobs: timeout-minutes: 10 python-dev: runs-on: - - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-8c-dind' || 'ubuntu-latest' }} + - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-8c-dind' || 'ubuntu-latest' }} name: python-dev steps: - name: Checkout @@ -1944,7 +1944,7 @@ jobs: timeout-minutes: 10 rust: runs-on: - - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-4c' || 'ubuntu-latest' }} + - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-4c' || 'ubuntu-latest' }} name: rust steps: - name: Checkout @@ -1974,7 +1974,7 @@ jobs: # The install.sh script creates path ${prefix_dir}/bin curl -fsS https://dl.dagger.io/dagger/install.sh | BIN_DIR=${prefix_dir}/bin sh env: - DAGGER_VERSION: v0.14.0 + DAGGER_VERSION: v0.15.0 shell: bash - name: scripts/warm-engine.sh id: warm-engine @@ -2115,7 +2115,7 @@ jobs: timeout-minutes: 10 rust-dev: runs-on: - - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-8c-dind' || 'ubuntu-latest' }} + - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-8c-dind' || 'ubuntu-latest' }} name: rust-dev steps: - name: Checkout @@ -2329,7 +2329,7 @@ jobs: timeout-minutes: 10 typescript: runs-on: - - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-4c' || 'ubuntu-latest' }} + - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-4c' || 'ubuntu-latest' }} name: typescript steps: - name: Checkout @@ -2359,7 +2359,7 @@ jobs: # The install.sh script creates path ${prefix_dir}/bin curl -fsS https://dl.dagger.io/dagger/install.sh | BIN_DIR=${prefix_dir}/bin sh env: - DAGGER_VERSION: v0.14.0 + DAGGER_VERSION: v0.15.0 shell: bash - name: scripts/warm-engine.sh id: warm-engine @@ -2500,7 +2500,7 @@ jobs: timeout-minutes: 10 typescript-dev: runs-on: - - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-14-0-8c-dind' || 'ubuntu-latest' }} + - ${{ github.repository == 'dagger/dagger' && 'dagger-g2-v0-15-0-8c-dind' || 'ubuntu-latest' }} name: typescript-dev steps: - name: Checkout diff --git a/RELEASING.md b/RELEASING.md index e18943e471..724e53a193 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -220,7 +220,7 @@ git commit -s -m "chore: bump dependencies to $ENGINE_VERSION" - [ ] Push to `dagger/dagger` - we need access to secrets that PRs coming from forks will not have. Open the PR as a draft and capture the PR number: ```console -gh pr create --draft --title "chore: prep for v0.13.7" --body "" | tee /tmp/prep-pr.txt +gh pr create --draft --title "chore: prep for $ENGINE_VERSION" --body "" | tee /tmp/prep-pr.txt export RELEASE_PREP_PR=$(cat /tmp/prep-pr.txt | sed -r 's/^[^0-9]*([0-9]+).*/\1/') ``` diff --git a/dagger.json b/dagger.json index d289e9dc6d..eefce4657c 100644 --- a/dagger.json +++ b/dagger.json @@ -1,22 +1,19 @@ { "name": "dagger-dev", - "engineVersion": "v0.14.0", + "engineVersion": "v0.15.0", "sdk": "go", "dependencies": [ { "name": "alpine", - "source": "modules/alpine", - "pin": "" + "source": "modules/alpine" }, { "name": "dagger-cli", - "source": "cmd/dagger", - "pin": "" + "source": "cmd/dagger" }, { "name": "dirdiff", - "source": "modules/dirdiff", - "pin": "" + "source": "modules/dirdiff" }, { "name": "docusaurus", @@ -25,58 +22,47 @@ }, { "name": "elixir-sdk-dev", - "source": "sdk/elixir/dev", - "pin": "" + "source": "sdk/elixir/dev" }, { "name": "go", - "source": "modules/go", - "pin": "" + "source": "modules/go" }, { "name": "graphql", - "source": "modules/graphql", - "pin": "" + "source": "modules/graphql" }, { "name": "helm", - "source": "helm", - "pin": "" + "source": "helm" }, { "name": "php-sdk-dev", - "source": "sdk/php/dev", - "pin": "" + "source": "sdk/php/dev" }, { "name": "ps-analyzer", - "source": "modules/ps-analyzer", - "pin": "" + "source": "modules/ps-analyzer" }, { "name": "python-sdk-dev", - "source": "sdk/python/dev", - "pin": "" + "source": "sdk/python/dev" }, { "name": "releaser", - "source": "releaser", - "pin": "" + "source": "releaser" }, { "name": "shellcheck", - "source": "modules/shellcheck", - "pin": "" + "source": "modules/shellcheck" }, { "name": "version", - "source": "version", - "pin": "" + "source": "version" }, { "name": "wolfi", - "source": "modules/wolfi", - "pin": "" + "source": "modules/wolfi" } ], "source": ".dagger" diff --git a/docs/current_docs/features/snippets/debugging-2/go/main.go b/docs/current_docs/features/snippets/debugging-2/go/main.go index f5e4778c29..91e4e83799 100644 --- a/docs/current_docs/features/snippets/debugging-2/go/main.go +++ b/docs/current_docs/features/snippets/debugging-2/go/main.go @@ -3,8 +3,6 @@ package main import ( "context" "dagger/my-module/internal/dagger" - - "dagger.io/dagger/dag" ) type MyModule struct{} diff --git a/docs/current_docs/features/snippets/secrets/go/main.go b/docs/current_docs/features/snippets/secrets/go/main.go index 8ba5db275d..0dd13966e9 100644 --- a/docs/current_docs/features/snippets/secrets/go/main.go +++ b/docs/current_docs/features/snippets/secrets/go/main.go @@ -3,8 +3,6 @@ package main import ( "context" "dagger/my-module/internal/dagger" - - "dagger.io/dagger/dag" ) type MyModule struct{} diff --git a/go.mod b/go.mod index 615d8f60bf..b13074d48e 100644 --- a/go.mod +++ b/go.mod @@ -273,8 +273,8 @@ require ( ) require ( - dagger.io/dagger v0.14.0 - github.com/dagger/dagger/engine/distconsts v0.14.0 + dagger.io/dagger v0.15.0 + github.com/dagger/dagger/engine/distconsts v0.15.0 github.com/dustin/go-humanize v1.0.1 resenje.org/singleflight v0.4.3 ) diff --git a/helm/.dagger/go.mod b/helm/.dagger/go.mod index 149e66c50e..406cadcd0d 100644 --- a/helm/.dagger/go.mod +++ b/helm/.dagger/go.mod @@ -3,10 +3,10 @@ module dagger/helm go 1.23.0 require ( - github.com/99designs/gqlgen v0.17.55 + github.com/99designs/gqlgen v0.17.57 github.com/Khan/genqlient v0.7.0 github.com/moby/buildkit v0.16.0 - github.com/vektah/gqlparser/v2 v2.5.17 + github.com/vektah/gqlparser/v2 v2.5.19 go.opentelemetry.io/otel v1.28.0 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 @@ -19,8 +19,8 @@ require ( go.opentelemetry.io/proto/otlp v1.3.1 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa golang.org/x/mod v0.20.0 - golang.org/x/sync v0.8.0 - google.golang.org/grpc v1.65.0 + golang.org/x/sync v0.9.0 + google.golang.org/grpc v1.68.0 helm.sh/helm/v3 v3.16.0 sigs.k8s.io/yaml v1.4.0 ) @@ -34,6 +34,7 @@ require ( github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/sosodev/duration v1.3.1 // indirect + github.com/stretchr/testify v1.10.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect @@ -41,10 +42,10 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.27.0 golang.org/x/net v0.29.0 // indirect golang.org/x/sys v0.26.0 // indirect - golang.org/x/text v0.18.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/protobuf v1.34.2 // indirect + golang.org/x/text v0.19.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect + google.golang.org/protobuf v1.35.2 // indirect ) replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 diff --git a/helm/.dagger/go.sum b/helm/.dagger/go.sum index 304a861c97..c05a0d2840 100644 --- a/helm/.dagger/go.sum +++ b/helm/.dagger/go.sum @@ -1,5 +1,5 @@ -github.com/99designs/gqlgen v0.17.55 h1:3vzrNWYyzSZjGDFo68e5j9sSauLxfKvLp+6ioRokVtM= -github.com/99designs/gqlgen v0.17.55/go.mod h1:3Bq768f8hgVPGZxL8aY9MaYmbxa6llPM/qu1IGH1EJo= +github.com/99designs/gqlgen v0.17.57 h1:Ak4p60BRq6QibxY0lEc0JnQhDurfhxA67sp02lMjmPc= +github.com/99designs/gqlgen v0.17.57/go.mod h1:Jx61hzOSTcR4VJy/HFIgXiQ5rJ0Ypw8DxWLjbYDAUw0= github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= @@ -17,6 +17,8 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -44,10 +46,10 @@ github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/vektah/gqlparser/v2 v2.5.17 h1:9At7WblLV7/36nulgekUgIaqHZWn5hxqluxrxGUhOmI= -github.com/vektah/gqlparser/v2 v2.5.17/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/vektah/gqlparser/v2 v2.5.19 h1:bhCPCX1D4WWzCDvkPl4+TP1N8/kLrWnp43egplt7iSg= +github.com/vektah/gqlparser/v2 v2.5.19/go.mod h1:y7kvl5bBlDeuWIvLtA9849ncyvx6/lj06RsMrEjVy3U= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 h1:oM0GTNKGlc5qHctWeIGTVyda4iFFalOzMZ3Ehj5rwB4= @@ -86,20 +88,20 @@ golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= -google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= -google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= +google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0= +google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA= +google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= +google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= diff --git a/helm/.dagger/main.go b/helm/.dagger/main.go index 12773ec781..8dd7e2cfdf 100644 --- a/helm/.dagger/main.go +++ b/helm/.dagger/main.go @@ -149,8 +149,12 @@ func (h *Helm) Publish( // +optional // +default="https://github.com/dagger/dagger.git" gitRepoSource string, + // +optional githubToken *dagger.Secret, + // +optional + discordWebhook *dagger.Secret, + // Test as much as possible without actually publishing anything // +optional dryRun bool, @@ -189,6 +193,13 @@ func (h *Helm) Publish( }); err != nil { return err } + + if err := dag.Releaser().Notify(ctx, gitRepoSource, "helm/chart/"+version, "โ˜ธ๏ธ Helm Chart", dagger.ReleaserNotifyOpts{ + DiscordWebhook: discordWebhook, + DryRun: dryRun, + }); err != nil { + return err + } } return nil } diff --git a/helm/dagger.json b/helm/dagger.json index 5efe0781bd..ed7eb1a3d4 100644 --- a/helm/dagger.json +++ b/helm/dagger.json @@ -1,12 +1,11 @@ { "name": "helm", - "engineVersion": "v0.14.0", + "engineVersion": "v0.15.0", "sdk": "go", "dependencies": [ { "name": "dagger-cli", - "source": "../cmd/dagger", - "pin": "" + "source": "../cmd/dagger" }, { "name": "k3s", @@ -15,13 +14,11 @@ }, { "name": "releaser", - "source": "../releaser", - "pin": "" + "source": "../releaser" }, { "name": "wolfi", - "source": "../modules/wolfi", - "pin": "" + "source": "../modules/wolfi" } ], "source": ".dagger" diff --git a/modules/daggerverse/main.go b/modules/daggerverse/main.go index 36666862ec..c282d8151e 100644 --- a/modules/daggerverse/main.go +++ b/modules/daggerverse/main.go @@ -132,6 +132,10 @@ func (h *Daggerverse) BumpDaggerVersion( from = strings.TrimSpace(from) } + // get just the version, without the v semver prefix + from = strings.TrimPrefix(from, "v") + to = strings.TrimPrefix(to, "v") + fromDashed := strings.ReplaceAll(from, ".", "-") toDashed := strings.ReplaceAll(to, ".", "-") engineImage := fmt.Sprintf("registry.dagger.io/engine:v%s", to) diff --git a/releaser/.dagger/go.mod b/releaser/.dagger/go.mod index 0510d7da83..8aca7a48f9 100644 --- a/releaser/.dagger/go.mod +++ b/releaser/.dagger/go.mod @@ -3,10 +3,9 @@ module dagger/releaser go 1.23.1 require ( - github.com/99designs/gqlgen v0.17.55 + github.com/99designs/gqlgen v0.17.57 github.com/Khan/genqlient v0.7.0 - github.com/moby/buildkit v0.16.0 - github.com/vektah/gqlparser/v2 v2.5.17 + github.com/vektah/gqlparser/v2 v2.5.19 go.opentelemetry.io/otel v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 @@ -18,8 +17,8 @@ require ( go.opentelemetry.io/otel/trace v1.27.0 go.opentelemetry.io/proto/otlp v1.3.1 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa - golang.org/x/sync v0.8.0 - google.golang.org/grpc v1.66.1 + golang.org/x/sync v0.9.0 + google.golang.org/grpc v1.68.0 ) require ( @@ -30,6 +29,7 @@ require ( github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/sosodev/duration v1.3.1 // indirect + github.com/stretchr/testify v1.10.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect @@ -37,10 +37,10 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.27.0 golang.org/x/net v0.29.0 // indirect golang.org/x/sys v0.26.0 // indirect - golang.org/x/text v0.18.0 // indirect + golang.org/x/text v0.19.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect - google.golang.org/protobuf v1.34.2 // indirect + google.golang.org/protobuf v1.35.2 // indirect ) replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 diff --git a/releaser/.dagger/go.sum b/releaser/.dagger/go.sum index cc9a58478f..29dbd85d93 100644 --- a/releaser/.dagger/go.sum +++ b/releaser/.dagger/go.sum @@ -1,5 +1,5 @@ -github.com/99designs/gqlgen v0.17.55 h1:3vzrNWYyzSZjGDFo68e5j9sSauLxfKvLp+6ioRokVtM= -github.com/99designs/gqlgen v0.17.55/go.mod h1:3Bq768f8hgVPGZxL8aY9MaYmbxa6llPM/qu1IGH1EJo= +github.com/99designs/gqlgen v0.17.57 h1:Ak4p60BRq6QibxY0lEc0JnQhDurfhxA67sp02lMjmPc= +github.com/99designs/gqlgen v0.17.57/go.mod h1:Jx61hzOSTcR4VJy/HFIgXiQ5rJ0Ypw8DxWLjbYDAUw0= github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= @@ -14,6 +14,8 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -23,8 +25,6 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/moby/buildkit v0.16.0 h1:wOVBj1o5YNVad/txPQNXUXdelm7Hs/i0PUFjzbK0VKE= -github.com/moby/buildkit v0.16.0/go.mod h1:Xqx/5GlrqE1yIRORk0NSCVDFpQAU1WjlT6KHYZdisIQ= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= @@ -33,10 +33,10 @@ github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/vektah/gqlparser/v2 v2.5.17 h1:9At7WblLV7/36nulgekUgIaqHZWn5hxqluxrxGUhOmI= -github.com/vektah/gqlparser/v2 v2.5.17/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/vektah/gqlparser/v2 v2.5.19 h1:bhCPCX1D4WWzCDvkPl4+TP1N8/kLrWnp43egplt7iSg= +github.com/vektah/gqlparser/v2 v2.5.19/go.mod h1:y7kvl5bBlDeuWIvLtA9849ncyvx6/lj06RsMrEjVy3U= go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 h1:oM0GTNKGlc5qHctWeIGTVyda4iFFalOzMZ3Ehj5rwB4= @@ -73,20 +73,20 @@ golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.66.1 h1:hO5qAXR19+/Z44hmvIM4dQFMSYX9XcWsByfoxutBpAM= -google.golang.org/grpc v1.66.1/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0= +google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA= +google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= +google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/releaser/.dagger/main.go b/releaser/.dagger/main.go index 322b86bc71..533cd5f860 100644 --- a/releaser/.dagger/main.go +++ b/releaser/.dagger/main.go @@ -49,11 +49,10 @@ func (r Releaser) GithubRelease( // GitHub repository URL repository string, // Tag for the GitHub release - // eg. sdk/typescript/v0.14.0 + // eg. v0.14.0 tag string, - // The target for the release - // eg. ๐Ÿคทโ€โ™‚๏ธ - // FIXME: what's the difference with 'tag'? Who knows, it wasn't documented - SH Nov 2024 + // The target tag for the release + // e.g. sdk/typescript/v0.14.0 target string, // File containing release notes // +optional @@ -65,14 +64,10 @@ func (r Releaser) GithubRelease( // +optional dryRun bool, ) error { - u, err := url.Parse(repository) + githubRepo, err := githubRepo(repository) if err != nil { return err } - if (u.Host != "") && (u.Host != "github.com") { - return fmt.Errorf("git repo must be on github.com") - } - githubRepo := strings.TrimPrefix(strings.TrimSuffix(u.Path, ".git"), "/") commit, err := dag.Version().Git().Commit(target).Commit(ctx) if err != nil { @@ -115,3 +110,50 @@ func (r Releaser) GithubRelease( }, ) } + +func (r Releaser) Notify( + ctx context.Context, + // GitHub repository URL + repository string, + // The target tag for the release + // e.g. sdk/typescript/v0.14.0 + target string, + // Name of the component to release + name string, + // Discord webhook + // +optional + discordWebhook *dagger.Secret, + + // Whether to perform a dry run without creating the release + // +optional + dryRun bool, +) error { + githubRepo, err := githubRepo(repository) + if err != nil { + return err + } + if dryRun { + return nil + } + + if discordWebhook == nil { + message := fmt.Sprintf("%s: https://github.com/%s/releases/tag/%s", name, githubRepo, target) + _, err = dag.Notify().Discord(ctx, discordWebhook, message) + if err != nil { + return err + } + } + + return nil +} + +func githubRepo(repo string) (string, error) { + u, err := url.Parse(repo) + if err != nil { + return "", err + } + if (u.Host != "") && (u.Host != "github.com") { + return "", fmt.Errorf("git repo must be on github.com") + } + return strings.TrimPrefix(strings.TrimSuffix(u.Path, ".git"), "/"), nil +} diff --git a/releaser/dagger.json b/releaser/dagger.json index c746dd3bd2..498c247e42 100644 --- a/releaser/dagger.json +++ b/releaser/dagger.json @@ -1,6 +1,6 @@ { "name": "releaser", - "engineVersion": "v0.14.0", + "engineVersion": "v0.15.0", "sdk": "go", "dependencies": [ { @@ -8,10 +8,14 @@ "source": "github.com/sagikazarmark/daggerverse/gh@main", "pin": "5a5ab8cce801ad62f2618f50a4e859e2f7fcacb9" }, + { + "name": "notify", + "source": "github.com/gerhard/daggerverse/notify@2024-02-13", + "pin": "d83fad32dc187838c849d4ea8152cc97a46de00a" + }, { "name": "version", - "source": "../version", - "pin": "" + "source": "../version" } ], "source": ".dagger" From 1ebe7f7ebf23047f17d736b2dd724c98b4416000 Mon Sep 17 00:00:00 2001 From: Erik Sipsma Date: Wed, 11 Dec 2024 20:17:01 -0800 Subject: [PATCH 27/35] fix metrics display via tracking by call ID digest (#9171) * fix metrics display via tracking by call ID digest Some of the recent changes to telemetry span handling resulted in most metrics not showing up in the TUI (other than those for services). This fixes the display by tracking+displaying metrics based on their associated Call ID digest, which avoids the relative complication of all the various spans we create in different parts of the engine and associated logic on which are actually rendered in the TUI. Signed-off-by: Erik Sipsma * add changelog Signed-off-by: Erik Sipsma --------- Signed-off-by: Erik Sipsma --- .../unreleased/Fixed-20241211-195735.yaml | 7 ++ dagql/dagui/db.go | 25 +++---- dagql/dagui/opts.go | 1 + dagql/dagui/spans.go | 5 -- dagql/idtui/frontend.go | 71 +++++++++++++------ 5 files changed, 70 insertions(+), 39 deletions(-) create mode 100644 .changes/unreleased/Fixed-20241211-195735.yaml diff --git a/.changes/unreleased/Fixed-20241211-195735.yaml b/.changes/unreleased/Fixed-20241211-195735.yaml new file mode 100644 index 0000000000..c0918e8a9a --- /dev/null +++ b/.changes/unreleased/Fixed-20241211-195735.yaml @@ -0,0 +1,7 @@ +kind: Fixed +body: | + Metrics display in the TUI is fixed to display for all executed containers, rather than just services. +time: 2024-12-11T19:57:35.761154448-08:00 +custom: + Author: sipsma + PR: "9171" diff --git a/dagql/dagui/db.go b/dagql/dagui/db.go index 86ac94ea4c..7611f2673e 100644 --- a/dagql/dagui/db.go +++ b/dagql/dagui/db.go @@ -14,7 +14,6 @@ import ( "go.opentelemetry.io/otel/sdk/metric/metricdata" "go.opentelemetry.io/otel/sdk/resource" sdktrace "go.opentelemetry.io/otel/sdk/trace" - "go.opentelemetry.io/otel/trace" "dagger.io/dagger/telemetry" "github.com/dagger/dagger/dagql/call/callpbv1" @@ -43,6 +42,11 @@ type DB struct { CompletedEffects map[string]bool FailedEffects map[string]bool + // Map of call digest -> metric name -> data points + // NOTE: this is hard coded for Gauge int64 metricdata essentially right now, + // needs generalization as more metric types get added + MetricsByCall map[string]map[string][]metricdata.DataPoint[int64] + // updatedSpans is a set of spans that have been updated since the last // sync, which includes any parent spans whose overall active time intervals // or status were modified via a child or linked span. @@ -259,23 +263,20 @@ func (db DBMetricExporter) Export(ctx context.Context, resourceMetrics *metricda } for _, point := range metricData.DataPoints { - spanIDStr, ok := point.Attributes.Value(telemetry.MetricsSpanIDAttr) + callDigest, ok := point.Attributes.Value(telemetry.DagDigestAttr) if !ok { continue } - spanID, err := trace.SpanIDFromHex(spanIDStr.AsString()) - if err != nil { - continue + + if db.MetricsByCall == nil { + db.MetricsByCall = make(map[string]map[string][]metricdata.DataPoint[int64]) } - span, ok := db.Spans.Map[SpanID{spanID}] + metricsByName, ok := db.MetricsByCall[callDigest.AsString()] if !ok { - continue - } - - if span.MetricsByName == nil { - span.MetricsByName = make(map[string][]metricdata.DataPoint[int64]) + metricsByName = make(map[string][]metricdata.DataPoint[int64]) + db.MetricsByCall[callDigest.AsString()] = metricsByName } - span.MetricsByName[metric.Name] = append(span.MetricsByName[metric.Name], point) + metricsByName[metric.Name] = append(metricsByName[metric.Name], point) } } } diff --git a/dagql/dagui/opts.go b/dagql/dagui/opts.go index 8a4e956b20..9b3291aa61 100644 --- a/dagql/dagui/opts.go +++ b/dagql/dagui/opts.go @@ -54,6 +54,7 @@ const ( ShowEncapsulatedVerbosity = 3 ShowSpammyVerbosity = 4 ShowDigestsVerbosity = 4 + ShowMetricsVerbosity = 3 ) func (opts FrontendOpts) ShouldShow(span *Span) bool { diff --git a/dagql/dagui/spans.go b/dagql/dagui/spans.go index cbc8dcf033..088eac8372 100644 --- a/dagql/dagui/spans.go +++ b/dagql/dagui/spans.go @@ -7,7 +7,6 @@ import ( "dagger.io/dagger/telemetry" "go.opentelemetry.io/otel/codes" - "go.opentelemetry.io/otel/sdk/metric/metricdata" sdktrace "go.opentelemetry.io/otel/sdk/trace" "github.com/dagger/dagger/dagql/call/callpbv1" @@ -33,10 +32,6 @@ type Span struct { causesViaAttrs SpanSet `json:"-"` effectsViaAttrs map[string]SpanSet `json:"-"` - // NOTE: this is hard coded for Gauge int64 metricdata essentially right now, - // needs generalization as more metric types get added - MetricsByName map[string][]metricdata.DataPoint[int64] - // Indicates that this span was actually exported to the database, and not // just allocated due to a span parent or other relationship. Received bool diff --git a/dagql/idtui/frontend.go b/dagql/idtui/frontend.go index 289ac180f6..a3a93eb085 100644 --- a/dagql/idtui/frontend.go +++ b/dagql/idtui/frontend.go @@ -16,6 +16,7 @@ import ( "go.opentelemetry.io/otel/log" sdklog "go.opentelemetry.io/otel/sdk/log" sdkmetric "go.opentelemetry.io/otel/sdk/metric" + "go.opentelemetry.io/otel/sdk/metric/metricdata" sdktrace "go.opentelemetry.io/otel/sdk/trace" "golang.org/x/term" @@ -397,30 +398,43 @@ func (r *renderer) renderCached(out *termenv.Output, span *dagui.Span) { } func (r renderer) renderMetrics(out *termenv.Output, span *dagui.Span) { - if span.MetricsByName == nil { + if r.Verbosity < dagui.ShowMetricsVerbosity { + return + } + + if span.CallDigest == "" { + return + } + metricsByName := r.db.MetricsByCall[span.CallDigest] + if metricsByName == nil { return } // IO Stats - r.renderMetric(out, span, telemetry.IOStatDiskReadBytes, "Disk Read", humanizeBytes) - r.renderMetric(out, span, telemetry.IOStatDiskWriteBytes, "Disk Write", humanizeBytes) - r.renderMetricIfNonzero(out, span, telemetry.IOStatPressureSomeTotal, "IO Pressure", durationString) + r.renderMetric(out, metricsByName, telemetry.IOStatDiskReadBytes, "Disk Read", humanizeBytes) + r.renderMetric(out, metricsByName, telemetry.IOStatDiskWriteBytes, "Disk Write", humanizeBytes) + r.renderMetricIfNonzero(out, metricsByName, telemetry.IOStatPressureSomeTotal, "IO Pressure", durationString) // CPU Stats - r.renderMetricIfNonzero(out, span, telemetry.CPUStatPressureSomeTotal, "CPU Pressure (some)", durationString) - r.renderMetricIfNonzero(out, span, telemetry.CPUStatPressureFullTotal, "CPU Pressure (full)", durationString) + r.renderMetricIfNonzero(out, metricsByName, telemetry.CPUStatPressureSomeTotal, "CPU Pressure (some)", durationString) + r.renderMetricIfNonzero(out, metricsByName, telemetry.CPUStatPressureFullTotal, "CPU Pressure (full)", durationString) // Memory Stats - r.renderMetric(out, span, telemetry.MemoryCurrentBytes, "Memory Bytes (current)", humanizeBytes) - r.renderMetric(out, span, telemetry.MemoryPeakBytes, "Memory Bytes (peak)", humanizeBytes) + r.renderMetric(out, metricsByName, telemetry.MemoryCurrentBytes, "Memory Bytes (current)", humanizeBytes) + r.renderMetric(out, metricsByName, telemetry.MemoryPeakBytes, "Memory Bytes (peak)", humanizeBytes) // Network Stats - r.renderNetworkMetric(out, span, telemetry.NetstatRxBytes, telemetry.NetstatRxDropped, telemetry.NetstatRxPackets, "Network Rx") - r.renderNetworkMetric(out, span, telemetry.NetstatTxBytes, telemetry.NetstatTxDropped, telemetry.NetstatTxPackets, "Network Tx") + r.renderNetworkMetric(out, metricsByName, telemetry.NetstatRxBytes, telemetry.NetstatRxDropped, telemetry.NetstatRxPackets, "Network Rx") + r.renderNetworkMetric(out, metricsByName, telemetry.NetstatTxBytes, telemetry.NetstatTxDropped, telemetry.NetstatTxPackets, "Network Tx") } -func (r renderer) renderMetric(out *termenv.Output, span *dagui.Span, metricName string, label string, formatValue func(int64) string) { - if dataPoints := span.MetricsByName[metricName]; len(dataPoints) > 0 { +func (r renderer) renderMetric( + out *termenv.Output, + metricsByName map[string][]metricdata.DataPoint[int64], + metricName string, label string, + formatValue func(int64) string, +) { + if dataPoints := metricsByName[metricName]; len(dataPoints) > 0 { lastPoint := dataPoints[len(dataPoints)-1] fmt.Fprint(out, " | ") displayMetric := out.String(fmt.Sprintf("%s: %s", label, formatValue(lastPoint.Value))) @@ -429,26 +443,39 @@ func (r renderer) renderMetric(out *termenv.Output, span *dagui.Span, metricName } } -func (r renderer) renderMetricIfNonzero(out *termenv.Output, span *dagui.Span, metricName string, label string, formatValue func(int64) string) { - if dataPoints := span.MetricsByName[metricName]; len(dataPoints) > 0 { +func (r renderer) renderMetricIfNonzero( + out *termenv.Output, + metricsByName map[string][]metricdata.DataPoint[int64], + metricName string, label string, + formatValue func(int64) string, +) { + if dataPoints := metricsByName[metricName]; len(dataPoints) > 0 { lastPoint := dataPoints[len(dataPoints)-1] if lastPoint.Value == 0 { return } - r.renderMetric(out, span, metricName, label, formatValue) + r.renderMetric(out, metricsByName, metricName, label, formatValue) } } -func (r renderer) renderNetworkMetric(out *termenv.Output, span *dagui.Span, bytesMetric, droppedMetric, packetsMetric, label string) { - r.renderMetricIfNonzero(out, span, bytesMetric, label, humanizeBytes) - if dataPoints := span.MetricsByName[bytesMetric]; len(dataPoints) > 0 { - renderPacketLoss(out, span, droppedMetric, packetsMetric) +func (r renderer) renderNetworkMetric( + out *termenv.Output, + metricsByName map[string][]metricdata.DataPoint[int64], + bytesMetric, droppedMetric, packetsMetric, label string, +) { + r.renderMetricIfNonzero(out, metricsByName, bytesMetric, label, humanizeBytes) + if dataPoints := metricsByName[bytesMetric]; len(dataPoints) > 0 { + renderPacketLoss(out, metricsByName, droppedMetric, packetsMetric) } } -func renderPacketLoss(out *termenv.Output, span *dagui.Span, droppedMetric, packetsMetric string) { - if drops := span.MetricsByName[droppedMetric]; len(drops) > 0 { - if packets := span.MetricsByName[packetsMetric]; len(packets) > 0 { +func renderPacketLoss( + out *termenv.Output, + metricsByName map[string][]metricdata.DataPoint[int64], + droppedMetric, packetsMetric string, +) { + if drops := metricsByName[droppedMetric]; len(drops) > 0 { + if packets := metricsByName[packetsMetric]; len(packets) > 0 { lastDrops := drops[len(drops)-1] lastPackets := packets[len(packets)-1] if lastDrops.Value > 0 && lastPackets.Value > 0 { From f1a6f627efa9e92f21daa773e0b011c93103604f Mon Sep 17 00:00:00 2001 From: Connor Braa <3478454+cwlbraa@users.noreply.github.com> Date: Wed, 11 Dec 2024 20:32:48 -0800 Subject: [PATCH 28/35] docs: add cli instructions to cache documentation (#9165) * docs: add cli instructions to cache documentation Signed-off-by: Connor Braa * docs: remove tabs and graphql instructions in cache page Signed-off-by: Connor Braa --------- Signed-off-by: Connor Braa --- docs/current_docs/configuration/cache.mdx | 46 ++++------------------- 1 file changed, 7 insertions(+), 39 deletions(-) diff --git a/docs/current_docs/configuration/cache.mdx b/docs/current_docs/configuration/cache.mdx index ea95f1e6de..a1436a01b1 100644 --- a/docs/current_docs/configuration/cache.mdx +++ b/docs/current_docs/configuration/cache.mdx @@ -16,39 +16,15 @@ Dagger caches two types of data: - Show all the cache entry metadata: - ```shell - dagger query < Date: Thu, 12 Dec 2024 16:48:12 +0000 Subject: [PATCH 29/35] More release improvements from v0.15.0 (#9175) --- .dagger/cli.go | 74 ++++++++++++++++--- .github/main.go | 2 +- .github/workflows/daggerverse-preview.gen.yml | 2 +- .github/workflows/publish.yml | 2 +- .goreleaser.nightly.yml | 27 ------- .goreleaser.yml | 26 ------- modules/daggerverse/dagger.json | 9 +-- modules/daggerverse/go.mod | 17 +++-- modules/daggerverse/go.sum | 38 +++++----- modules/daggerverse/main.go | 55 ++++++++------ 10 files changed, 132 insertions(+), 120 deletions(-) diff --git a/.dagger/cli.go b/.dagger/cli.go index c4b2dff462..052439fcf6 100644 --- a/.dagger/cli.go +++ b/.dagger/cli.go @@ -3,8 +3,10 @@ package main import ( "context" "fmt" + "net/url" "strings" + "golang.org/x/mod/semver" "golang.org/x/sync/errgroup" "github.com/dagger/dagger/.dagger/build" @@ -25,7 +27,8 @@ func (cli *CLI) Binary( const ( // https://github.com/goreleaser/goreleaser/releases - goReleaserVersion = "v2.3.2" + goReleaserVersion = "v2.4.8" + goReleaserImage = "ghcr.io/goreleaser/goreleaser-pro:" + goReleaserVersion + "-pro" ) // Publish the CLI using GoReleaser @@ -42,7 +45,6 @@ func (cli *CLI) Publish( awsRegion string, awsBucket string, - awsCloudfrontDistribution string, artefactsFQDN string, ) error { ctr, err := publishEnv(ctx) @@ -87,7 +89,6 @@ func (cli *CLI) Publish( WithSecretVariable("AWS_SECRET_ACCESS_KEY", awsSecretAccessKey). WithEnvVariable("AWS_REGION", awsRegion). WithEnvVariable("AWS_BUCKET", awsBucket). - WithEnvVariable("AWS_CLOUDFRONT_DISTRIBUTION_ID", awsCloudfrontDistribution). WithEnvVariable("ARTEFACTS_FQDN", artefactsFQDN). WithEnvVariable("ENGINE_VERSION", cli.Dagger.Version). WithEnvVariable("ENGINE_TAG", cli.Dagger.Tag). @@ -99,6 +100,57 @@ func (cli *CLI) Publish( return err } +func (cli *CLI) PublishMetadata( + ctx context.Context, + + awsAccessKeyID *dagger.Secret, + awsSecretAccessKey *dagger.Secret, + awsRegion string, + awsBucket string, + awsCloudfrontDistribution string, +) error { + ctr := dag. + Alpine(dagger.AlpineOpts{ + Packages: []string{"aws-cli"}, + }). + Container(). + WithWorkdir("/src"). + WithDirectory(".", cli.Dagger.Source()). + WithSecretVariable("AWS_ACCESS_KEY_ID", awsAccessKeyID). + WithSecretVariable("AWS_SECRET_ACCESS_KEY", awsSecretAccessKey). + WithEnvVariable("AWS_REGION", awsRegion). + WithEnvVariable("AWS_EC2_METADATA_DISABLED", "true") + + // update install scripts + ctr = ctr. + WithExec([]string{"aws", "s3", "cp", "./install.sh", s3Path(awsBucket, "dagger/install.sh")}). + WithExec([]string{"aws", "s3", "cp", "./install.ps1", s3Path(awsBucket, "dagger/install.ps1")}). + WithExec([]string{"aws", "cloudfront", "create-invalidation", "--distribution-id", awsCloudfrontDistribution, "--paths", "/dagger/install.sh", "/dagger/install.ps1"}) + + // update version pointers (only on proper releases) + if version := cli.Dagger.Version; semver.IsValid(version) && semver.Prerelease(version) == "" { + cpOpts := dagger.ContainerWithExecOpts{ + Stdin: strings.TrimPrefix(version, "v"), + } + ctr = ctr. + WithExec([]string{"aws", "s3", "cp", "-", s3Path(awsBucket, "dagger/latest_version")}, cpOpts). + WithExec([]string{"aws", "s3", "cp", "-", s3Path(awsBucket, "dagger/versions/latest")}, cpOpts). + WithExec([]string{"aws", "s3", "cp", "-", s3Path(awsBucket, "dagger/versions/%s", strings.TrimPrefix(semver.MajorMinor(version), "v"))}, cpOpts) + } + + _, err := ctr.Sync(ctx) + return err +} + +func s3Path(bucket string, path string, args ...any) string { + u := url.URL{ + Scheme: "s3", + Host: bucket, + Path: fmt.Sprintf(path, args...), + } + return u.String() +} + // Verify that the CLI builds without actually publishing anything func (cli *CLI) TestPublish(ctx context.Context) error { // TODO: ideally this would also use go releaser, but we want to run this @@ -151,14 +203,14 @@ func (cli *CLI) TestPublish(ctx context.Context) error { } func publishEnv(ctx context.Context) (*dagger.Container, error) { - // TODO: remove after upgrading to GoReleaser Pro has go 1.23.2 (it currently only has go 1.23.1) - go1_23_2 := dag.Container().From("golang:1.23.2-alpine@sha256:9dd2625a1ff2859b8d8b01d8f7822c0f528942fe56cfe7a1e7c38d3b8d72d679").Directory("/usr/local/go") - - ctr := dag.Container(). - From(fmt.Sprintf("ghcr.io/goreleaser/goreleaser-pro:%s-pro", goReleaserVersion)). - WithDirectory("/usr/local/go", go1_23_2). - WithEntrypoint([]string{}). - WithExec([]string{"apk", "add", "aws-cli"}) + ctr := dag.Container().From(goReleaserImage) + + // HACK: this can be enabled to force a go update (e.g. when we need it for + // a security update) + // ctr = ctr.WithDirectory( + // "/usr/local/go", + // dag.Container().From("golang:-alpine@sha256:").Directory("/usr/local/go"), + // ) // install nix ctr = ctr. diff --git a/.github/main.go b/.github/main.go index 42c7bab4e4..675fad45ab 100644 --- a/.github/main.go +++ b/.github/main.go @@ -176,7 +176,7 @@ func (ci *CI) withPrepareReleaseWorkflow() *CI { Workflow("daggerverse-preview"). WithJob(gha.Job( "deploy", - "--github-token=env:RELEASE_DAGGER_CI_TOKEN deploy-preview-with-dagger-main --target $GITHUB_REF_NAME", + "--github-token=env:RELEASE_DAGGER_CI_TOKEN deploy-preview-with-dagger-main --target $GITHUB_REF_NAME --github-assignee $GITHUB_ACTOR", dagger.GhaJobOpts{ Secrets: []string{"RELEASE_DAGGER_CI_TOKEN"}, Module: "modules/daggerverse", diff --git a/.github/workflows/daggerverse-preview.gen.yml b/.github/workflows/daggerverse-preview.gen.yml index e68ecd4feb..6d6961f157 100644 --- a/.github/workflows/daggerverse-preview.gen.yml +++ b/.github/workflows/daggerverse-preview.gen.yml @@ -182,7 +182,7 @@ jobs: exit $EXIT_CODE env: _EXPERIMENTAL_DAGGER_CLOUD_TOKEN: dag_dagger_sBIv6DsjNerWvTqt2bSFeigBUqWxp9bhh3ONSSgeFnw - COMMAND: dagger call -q --github-token=env:RELEASE_DAGGER_CI_TOKEN deploy-preview-with-dagger-main --target $GITHUB_REF_NAME + COMMAND: dagger call -q --github-token=env:RELEASE_DAGGER_CI_TOKEN deploy-preview-with-dagger-main --target $GITHUB_REF_NAME --github-assignee $GITHUB_ACTOR DAGGER_CLOUD_TOKEN: dag_dagger_sBIv6DsjNerWvTqt2bSFeigBUqWxp9bhh3ONSSgeFnw DAGGER_MODULE: modules/daggerverse RELEASE_DAGGER_CI_TOKEN: ${{ secrets.RELEASE_DAGGER_CI_TOKEN }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 14a28091fc..4e02723470 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -169,7 +169,7 @@ jobs: env: RELEASE_DAGGER_CI_TOKEN: ${{ secrets.RELEASE_DAGGER_CI_TOKEN }} with: - function: --github-token=env:RELEASE_DAGGER_CI_TOKEN bump-dagger-version --to=${{ github.ref_name }} + function: --github-token=env:RELEASE_DAGGER_CI_TOKEN bump-dagger-version --to=${{ github.ref_name }} --github-assignee={{ github.actor }} module: ./modules/daggerverse # TODO: daggerize provisioning tests diff --git a/.goreleaser.nightly.yml b/.goreleaser.nightly.yml index 43e01bc1c5..b98f8883f4 100644 --- a/.goreleaser.nightly.yml +++ b/.goreleaser.nightly.yml @@ -38,30 +38,3 @@ blobs: region: "{{ .Env.AWS_REGION }}" bucket: "{{ .Env.AWS_BUCKET }}" directory: "dagger/main/head" - -publishers: - - name: publish-install-sh - cmd: sh -c "aws s3 cp install.sh s3://{{ .Env.AWS_BUCKET }}/dagger/install.sh" - env: - - PATH={{ .Env.PATH }} - - AWS_EC2_METADATA_DISABLED=true - - AWS_ACCESS_KEY_ID={{ .Env.AWS_ACCESS_KEY_ID }} - - AWS_SECRET_ACCESS_KEY={{ .Env.AWS_SECRET_ACCESS_KEY }} - - AWS_REGION={{ .Env.AWS_REGION }} - - name: publish-install-ps1 - cmd: sh -c "aws s3 cp install.ps1 s3://{{ .Env.AWS_BUCKET }}/dagger/install.ps1" - env: - - PATH={{ .Env.PATH }} - - AWS_EC2_METADATA_DISABLED=true - - AWS_ACCESS_KEY_ID={{ .Env.AWS_ACCESS_KEY_ID }} - - AWS_SECRET_ACCESS_KEY={{ .Env.AWS_SECRET_ACCESS_KEY }} - - AWS_REGION={{ .Env.AWS_REGION }} - - name: publish-install-ps1 - cmd: sh -c "aws cloudfront create-invalidation --distribution-id {{ .Env.AWS_CLOUDFRONT_DISTRIBUTION_ID }} --paths /dagger/install.sh /dagger/install.ps1" - env: - - PATH={{ .Env.PATH }} - - AWS_ACCESS_KEY_ID={{ .Env.AWS_ACCESS_KEY_ID }} - - AWS_SECRET_ACCESS_KEY={{ .Env.AWS_SECRET_ACCESS_KEY }} - - AWS_REGION={{ .Env.AWS_REGION }} - - AWS_SECRET_ACCESS_KEY={{ .Env.AWS_SECRET_ACCESS_KEY }} - - AWS_CLOUDFRONT_DISTRIBUTION_ID={{ .Env.AWS_CLOUDFRONT_DISTRIBUTION_ID }} diff --git a/.goreleaser.yml b/.goreleaser.yml index 2fc1c81ef2..d21c0d4e84 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -54,29 +54,3 @@ blobs: region: "{{ .Env.AWS_REGION }}" bucket: "{{ .Env.AWS_BUCKET }}" directory: "dagger/releases/{{ .Version }}" - -publishers: - - name: publish-latest-version - cmd: sh -c "echo {{ .Version }} | aws s3 cp - s3://{{ .Env.AWS_BUCKET }}/dagger/latest_version" - env: - - PATH={{ .Env.PATH }} - - AWS_EC2_METADATA_DISABLED=true - - AWS_ACCESS_KEY_ID={{ .Env.AWS_ACCESS_KEY_ID }} - - AWS_SECRET_ACCESS_KEY={{ .Env.AWS_SECRET_ACCESS_KEY }} - - AWS_REGION={{ .Env.AWS_REGION }} - - name: publish-latest - cmd: sh -c "echo {{ .Version }} | aws s3 cp - s3://{{ .Env.AWS_BUCKET }}/dagger/versions/latest" - env: - - PATH={{ .Env.PATH }} - - AWS_EC2_METADATA_DISABLED=true - - AWS_ACCESS_KEY_ID={{ .Env.AWS_ACCESS_KEY_ID }} - - AWS_SECRET_ACCESS_KEY={{ .Env.AWS_SECRET_ACCESS_KEY }} - - AWS_REGION={{ .Env.AWS_REGION }} - - name: publish-latest-major-minor - cmd: sh -c "echo {{ .Version }} | aws s3 cp - s3://{{ .Env.AWS_BUCKET }}/dagger/versions/{{ .Major }}.{{ .Minor }}" - env: - - PATH={{ .Env.PATH }} - - AWS_EC2_METADATA_DISABLED=true - - AWS_ACCESS_KEY_ID={{ .Env.AWS_ACCESS_KEY_ID }} - - AWS_SECRET_ACCESS_KEY={{ .Env.AWS_SECRET_ACCESS_KEY }} - - AWS_REGION={{ .Env.AWS_REGION }} diff --git a/modules/daggerverse/dagger.json b/modules/daggerverse/dagger.json index 3f8dfb49fa..bea131f35a 100644 --- a/modules/daggerverse/dagger.json +++ b/modules/daggerverse/dagger.json @@ -1,17 +1,16 @@ { "name": "daggerverse", - "engineVersion": "v0.14.0", + "engineVersion": "v0.15.0", "sdk": "go", "dependencies": [ { "name": "gh", - "source": "github.com/sagikazarmark/daggerverse/gh", - "pin": "68e9daa611183f5334b4059bac6f4aad62da7a37" + "source": "github.com/sagikazarmark/daggerverse/gh@pull/202/head", + "pin": "f47a52f2809f00b514e536ff7822b5cae8e542a9" }, { "name": "go", - "source": "../go", - "pin": "" + "source": "../go" } ], "source": "." diff --git a/modules/daggerverse/go.mod b/modules/daggerverse/go.mod index 8151d07bd4..f0f663930b 100644 --- a/modules/daggerverse/go.mod +++ b/modules/daggerverse/go.mod @@ -3,10 +3,10 @@ module dagger/daggerverse go 1.23.2 require ( - github.com/99designs/gqlgen v0.17.55 + github.com/99designs/gqlgen v0.17.57 github.com/Khan/genqlient v0.7.0 github.com/google/go-github/v66 v66.0.0 - github.com/vektah/gqlparser/v2 v2.5.17 + github.com/vektah/gqlparser/v2 v2.5.19 go.opentelemetry.io/otel v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 @@ -18,8 +18,8 @@ require ( go.opentelemetry.io/otel/trace v1.27.0 go.opentelemetry.io/proto/otlp v1.3.1 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa - golang.org/x/sync v0.8.0 - google.golang.org/grpc v1.65.0 + golang.org/x/sync v0.9.0 + google.golang.org/grpc v1.68.0 ) require github.com/google/go-querystring v1.1.0 // indirect @@ -31,6 +31,7 @@ require ( github.com/google/uuid v1.6.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/sosodev/duration v1.3.1 // indirect + github.com/stretchr/testify v1.10.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect @@ -38,10 +39,10 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.27.0 golang.org/x/net v0.29.0 // indirect golang.org/x/sys v0.26.0 // indirect - golang.org/x/text v0.18.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/protobuf v1.34.2 // indirect + golang.org/x/text v0.19.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect + google.golang.org/protobuf v1.35.2 // indirect ) replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 diff --git a/modules/daggerverse/go.sum b/modules/daggerverse/go.sum index 131bd78080..3294e0226a 100644 --- a/modules/daggerverse/go.sum +++ b/modules/daggerverse/go.sum @@ -1,5 +1,5 @@ -github.com/99designs/gqlgen v0.17.55 h1:3vzrNWYyzSZjGDFo68e5j9sSauLxfKvLp+6ioRokVtM= -github.com/99designs/gqlgen v0.17.55/go.mod h1:3Bq768f8hgVPGZxL8aY9MaYmbxa6llPM/qu1IGH1EJo= +github.com/99designs/gqlgen v0.17.57 h1:Ak4p60BRq6QibxY0lEc0JnQhDurfhxA67sp02lMjmPc= +github.com/99designs/gqlgen v0.17.57/go.mod h1:Jx61hzOSTcR4VJy/HFIgXiQ5rJ0Ypw8DxWLjbYDAUw0= github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= @@ -13,6 +13,8 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -30,10 +32,10 @@ github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq4= github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/vektah/gqlparser/v2 v2.5.17 h1:9At7WblLV7/36nulgekUgIaqHZWn5hxqluxrxGUhOmI= -github.com/vektah/gqlparser/v2 v2.5.17/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/vektah/gqlparser/v2 v2.5.19 h1:bhCPCX1D4WWzCDvkPl4+TP1N8/kLrWnp43egplt7iSg= +github.com/vektah/gqlparser/v2 v2.5.19/go.mod h1:y7kvl5bBlDeuWIvLtA9849ncyvx6/lj06RsMrEjVy3U= go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 h1:oM0GTNKGlc5qHctWeIGTVyda4iFFalOzMZ3Ehj5rwB4= @@ -70,20 +72,20 @@ golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= -google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= -google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= +google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0= +google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA= +google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= +google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/modules/daggerverse/main.go b/modules/daggerverse/main.go index c282d8151e..36bd55b0c1 100644 --- a/modules/daggerverse/main.go +++ b/modules/daggerverse/main.go @@ -17,8 +17,6 @@ type Daggerverse struct { // +private GitHubUser string // +private - GitHubUsername string - // +private GitHubUserEmail string // +private Repo string @@ -42,9 +40,8 @@ func New( } repo := "github.com/dagger/dagger.io" dgvs := &Daggerverse{ - GitHubUsername: *user.Login, - GitHubUser: *user.Name, - Repo: repo, + GitHubUser: *user.Name, + Repo: repo, Gh: dag.Gh(dagger.GhOpts{ Token: githubToken, Repo: repo, @@ -64,6 +61,9 @@ func New( func (h *Daggerverse) DeployPreviewWithDaggerMain( ctx context.Context, target string, + + // +optional + githubAssignee string, ) error { // make a change so that a new Daggerverse deployment will be created daggerio := h.clone(). @@ -88,25 +88,30 @@ daggerverse-checks in GitHub Actions ensures that module crawling works as expec // open a PR on the trigger branch that it creates a new Daggerverse // preview environment running Dagger main - err := gh. - PullRequest().Create( - ctx, - dagger.GhPullRequestCreateOpts{ - // TODO: this should actually be the username of the original PR author - Assignees: []string{h.GitHubUsername}, - Fill: true, - Labels: []string{"preview", "area/daggerverse"}, - Head: branch, - }, - ) + exists, err := gh.PullRequest().Exists(ctx, branch) if err != nil { - // FIXME: this will stop working in v0.15.0! - if strings.Contains(err.Error(), "already exists") { - return nil + return err + } + if !exists { + var assignees []string + if githubAssignee != "" { + assignees = append(assignees, githubAssignee) + } + err := gh. + PullRequest().Create( + ctx, + dagger.GhPullRequestCreateOpts{ + Assignees: assignees, + Fill: true, + Labels: []string{"preview", "area/daggerverse"}, + Head: branch, + }) + if err != nil { + return err } } - return err + return nil } // Bump Dagger version: dagger call --github-token=env:GITHUB_PAT bump-dagger-version --from=0.13.7 --to=0.14.0 @@ -119,6 +124,9 @@ func (h *Daggerverse) BumpDaggerVersion( from string, // Which version of Dagger are we bumping to to string, + + // +optional + githubAssignee string, ) (err error) { if from == "" { from, err = dag.Container().From("alpine"). @@ -195,6 +203,10 @@ func (h *Daggerverse) BumpDaggerVersion( branch := fmt.Sprintf("dgvs-bump-dagger-from-%s-to-%s-with-dagger-main", from, to) commitMsg := fmt.Sprintf("dgvs: Bump Dagger from %s to %s", from, to) + var assignees []string + if githubAssignee != "" { + assignees = append(assignees, githubAssignee) + } err = h.Gh.WithSource(updated). WithGitExec([]string{"checkout", "-b", branch}). WithGitExec([]string{"add", ".github", "daggerverse", "infra"}). @@ -205,8 +217,7 @@ func (h *Daggerverse) BumpDaggerVersion( PullRequest().Create( ctx, dagger.GhPullRequestCreateOpts{ - // TODO: this should actually be the username of the original PR author - Assignees: []string{h.GitHubUsername}, + Assignees: assignees, Fill: true, Labels: []string{"preview", "area/daggerverse"}, Head: branch, From 402b26c68b3649c9e6a34d6f01ede66f6ef3d3c9 Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Thu, 12 Dec 2024 17:14:27 +0000 Subject: [PATCH 30/35] ci: call publish-metadata in publish workflow (#9180) --- .github/workflows/publish.yml | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 4e02723470..f233fde498 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -51,7 +51,6 @@ jobs: --aws-secret-access-key=env:AWS_SECRET_ACCESS_KEY \ --aws-region="$AWS_REGION" \ --aws-bucket="$AWS_BUCKET" \ - --aws-cloudfront-distribution="$AWS_CLOUDFRONT_DISTRIBUTION" \ --artefacts-fqdn="$ARTEFACTS_FQDN" env: GH_ORG_NAME: ${{ vars.GH_ORG_NAME }} @@ -60,9 +59,25 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.RELEASE_AWS_SECRET_ACCESS_KEY }} AWS_REGION: ${{ vars.RELEASE_AWS_REGION }} AWS_BUCKET: ${{ vars.RELEASE_AWS_BUCKET }} - AWS_CLOUDFRONT_DISTRIBUTION: ${{ vars.RELEASE_AWS_CLOUDFRONT_DISTRIBUTION }} ARTEFACTS_FQDN: ${{ vars.RELEASE_FQDN }} GORELEASER_KEY: ${{ secrets.GORELEASER_PRO_LICENSE_KEY }} + - name: "Publish Metadata" + uses: ./.github/actions/call + with: + function: |- + cli \ + publish-metadata \ + --aws-access-key-id=env:AWS_ACCESS_KEY_ID \ + --aws-secret-access-key=env:AWS_SECRET_ACCESS_KEY \ + --aws-region="$AWS_REGION" \ + --aws-bucket="$AWS_BUCKET" \ + --aws-cloudfront-distribution="$AWS_CLOUDFRONT_DISTRIBUTION" + env: + AWS_ACCESS_KEY_ID: ${{ secrets.RELEASE_AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.RELEASE_AWS_SECRET_ACCESS_KEY }} + AWS_REGION: ${{ vars.RELEASE_AWS_REGION }} + AWS_BUCKET: ${{ vars.RELEASE_AWS_BUCKET }} + AWS_CLOUDFRONT_DISTRIBUTION: ${{ vars.RELEASE_AWS_CLOUDFRONT_DISTRIBUTION }} # TODO: move this into dagger function call - name: "Notify" uses: ./.github/actions/notify From a84d7033777fd8a3993a9103270f1ec7f14e4596 Mon Sep 17 00:00:00 2001 From: Helder Correia <174525+helderco@users.noreply.github.com> Date: Thu, 12 Dec 2024 16:31:00 -0100 Subject: [PATCH 31/35] shell: expand state arguments in commands (#9168) * shell: expand state arguments in commands Included a refactor to remove some duplication. Simplified usage of `handleResponse` because: - The shell doesn't use the `-o,--output` flag convenience - Adding the fake `_type` field when result is an object is not necessary since you can add `... | .doc` to get the type --------- Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com> --- cmd/dagger/functions.go | 120 +++++++------ cmd/dagger/shell.go | 246 +++++++++++++++----------- core/integration/module_shell_test.go | 27 ++- 3 files changed, 223 insertions(+), 170 deletions(-) diff --git a/cmd/dagger/functions.go b/cmd/dagger/functions.go index e022cafa06..a96df75172 100644 --- a/cmd/dagger/functions.go +++ b/cmd/dagger/functions.go @@ -526,25 +526,24 @@ func (fc *FuncCommand) RunE(ctx context.Context, fn *modFunction) func(*cobra.Co // from wrong CLI usage. fc.showUsage = false - return executeRequest(ctx, q, fn.ReturnType, cmd.OutOrStdout(), cmd.ErrOrStderr()) - } -} + o := cmd.OutOrStdout() + e := cmd.ErrOrStderr() -func executeRequest(ctx context.Context, q *querybuilder.Selection, returnType *modTypeDef, o, e io.Writer) error { - // It's possible that a chain ending in an object doesn't have anything - // else to sub-select. In that case `q` will be nil to signal that we - // just want to return the object's name, without making an API request. - if q == nil { - return handleResponse(returnType, nil, o, e) - } + // It's possible that a chain ending in an object doesn't have anything + // else to sub-select. In that case `q` will be nil to signal that we + // just want to return the object's name, without making an API request. + if q == nil { + return handleResponse(fn.ReturnType, nil, o, e) + } - var response any + var response any - if err := makeRequest(ctx, q, &response); err != nil { - return err - } + if err := makeRequest(ctx, q, &response); err != nil { + return err + } - return handleResponse(returnType, response, o, e) + return handleResponse(fn.ReturnType, response, o, e) + } } func handleObjectLeaf(ctx context.Context, q *querybuilder.Selection, typeDef *modTypeDef) (*querybuilder.Selection, error) { @@ -624,7 +623,7 @@ func handleResponse(returnType *modTypeDef, response any, o, e io.Writer) error return nil } - // Handle the `export` convenience. + // Handle the `export` convenience, i.e, -o,--output flag. switch returnType.Name() { case Container, Directory, File: if outputPath != "" { @@ -637,9 +636,7 @@ func handleResponse(returnType *modTypeDef, response any, o, e io.Writer) error } } - var outputFormat string - - // Command chain ended in an object. + // Command chain ended in an object, so add the _type field. if returnType.AsFunctionProvider() != nil { typeName := returnType.AsFunctionProvider().ProviderName() @@ -660,7 +657,39 @@ func handleResponse(returnType *modTypeDef, response any, o, e io.Writer) error } response = r } + } + + buf := new(bytes.Buffer) + frmt := outputFormat(returnType) + if err := printResponse(buf, response, frmt); err != nil { + return err + } + + if outputPath != "" { + if err := writeOutputFile(outputPath, buf); err != nil { + return fmt.Errorf("couldn't write output to file: %w", err) + } + path, err := client.Abs(outputPath) + if err != nil { + // don't fail because at this point the output has been saved successfully + slog.Warn("Failed to get absolute path", "error", err) + path = outputPath + } + fmt.Fprintf(e, "Saved output to %q.\n", path) + } + + _, err := buf.WriteTo(o) + if stdoutIsTTY && !strings.HasSuffix(buf.String(), "\n") { + fmt.Fprintln(o) + } + + return err +} + +func outputFormat(typeDef *modTypeDef) string { + var outputFormat string + if typeDef != nil && typeDef.AsFunctionProvider() != nil { // Use yaml when printing scalars because it's more human-readable // and handles lists and multiline strings well. if stdoutIsTTY { @@ -675,51 +704,32 @@ func handleResponse(returnType *modTypeDef, response any, o, e io.Writer) error outputFormat = "json" } - buf := new(bytes.Buffer) - switch outputFormat { + return outputFormat +} + +func printResponse(w io.Writer, response any, format string) error { + switch format { case "json": // disable HTML escaping to improve readability - encoder := json.NewEncoder(buf) + encoder := json.NewEncoder(w) encoder.SetEscapeHTML(false) encoder.SetIndent("", " ") - if err := encoder.Encode(response); err != nil { - return err - } + return encoder.Encode(response) + case "yaml": out, err := yaml.Marshal(response) if err != nil { return err } - if _, err := buf.Write(out); err != nil { - return err - } - case "": - if err := printFunctionResult(buf, response); err != nil { - return err - } - default: - return fmt.Errorf("wrong output format %q", outputFormat) - } + _, err = w.Write(out) + return err - if outputPath != "" { - if err := writeOutputFile(outputPath, buf); err != nil { - return fmt.Errorf("couldn't write output to file: %w", err) - } - path, err := client.Abs(outputPath) - if err != nil { - // don't fail because at this point the output has been saved successfully - slog.Warn("Failed to get absolute path", "error", err) - path = outputPath - } - fmt.Fprintf(e, "Saved output to %q.\n", path) - } + case "": + return printPlainResult(w, response) - _, err := buf.WriteTo(o) - if stdoutIsTTY && !strings.HasSuffix(buf.String(), "\n") { - fmt.Fprintln(o) + default: + return fmt.Errorf("wrong output format %q", format) } - - return err } // addPayload merges a map into a response from getting an object's values. @@ -761,11 +771,11 @@ func writeOutputFile(path string, buf *bytes.Buffer) error { return os.WriteFile(path, buf.Bytes(), 0o644) //nolint: gosec } -func printFunctionResult(w io.Writer, r any) error { +func printPlainResult(w io.Writer, r any) error { switch t := r.(type) { case []any: for _, v := range t { - if err := printFunctionResult(w, v); err != nil { + if err := printPlainResult(w, v); err != nil { return err } fmt.Fprintln(w) @@ -775,7 +785,7 @@ func printFunctionResult(w io.Writer, r any) error { // NB: we're only interested in values because this is where we unwrap // things like {"container":{"from":{"withExec":{"stdout":"foo"}}}}. for _, v := range t { - if err := printFunctionResult(w, v); err != nil { + if err := printPlainResult(w, v); err != nil { return err } } diff --git a/cmd/dagger/shell.go b/cmd/dagger/shell.go index c12e967e49..3068119344 100644 --- a/cmd/dagger/shell.go +++ b/cmd/dagger/shell.go @@ -294,17 +294,17 @@ func (h *shellCallHandler) run(ctx context.Context, reader io.Reader, name strin return err } - s, b, err := readShellState(h.stdoutBuf) - if err != nil { + resp, err := h.Result(ctx, h.stdoutBuf, true, handleObjectLeaf) + if err != nil || resp == nil { return err } - if s != nil { - return h.Result(ctx, s) - } return h.withTerminal(func(_ io.Reader, stdout, _ io.Writer) error { - _, err := fmt.Fprint(stdout, string(b)) - return err + fmt.Fprint(stdout, resp) + if sval, ok := resp.(string); ok && stdoutIsTTY && !strings.HasSuffix(sval, "\n") { + fmt.Fprintln(stdout) + } + return nil }) } @@ -525,7 +525,7 @@ func (h *shellCallHandler) cmd(ctx context.Context, args []string) (*ShellState, return nil, err } if builtin != nil { - return nil, builtin.Execute(ctx, a, st) + return nil, builtin.Execute(ctx, h, a, st) } if st.IsCommandRoot() { @@ -536,7 +536,7 @@ func (h *shellCallHandler) cmd(ctx context.Context, args []string) (*ShellState, if err != nil { return nil, err } - return nil, stdlib.Execute(ctx, a, nil) + return nil, stdlib.Execute(ctx, h, a, nil) case st.IsDeps(): // Example: `.deps | ` @@ -568,7 +568,7 @@ func (h *shellCallHandler) entrypointCall(ctx context.Context, cmd string, args } if cmd, _ := h.BuiltinCommand(cmd); cmd != nil { - return nil, cmd.Execute(ctx, args, nil) + return nil, cmd.Execute(ctx, h, args, nil) } st, err := h.stateLookup(ctx, cmd) @@ -584,7 +584,7 @@ func (h *shellCallHandler) entrypointCall(ctx context.Context, cmd string, args if err != nil { return nil, err } - return st, cmd.Execute(ctx, args, nil) + return st, cmd.Execute(ctx, h, args, nil) } if md, _ := h.GetModuleDef(st); md != nil { @@ -847,25 +847,25 @@ func (h *shellCallHandler) parseArgumentValues(ctx context.Context, md *moduleDe if err != nil { return err } - if strings.HasPrefix(value, shellStatePrefix) { - v, replace, err := h.parseStateArgument(ctx, a, value) - if err != nil { - return fmt.Errorf("failed expanding argument %q: %w", a.FlagName(), err) - } - // Flags only support setting their values from strings, so if - // anything else is returned, we just ignore it. - // TODO: try to validate this more to avoid surprises - if sval, ok := v.(string); ok && !replace { - return flags.Set(flag.Name, sval) - } - // This will bypass using a flag for this argument since we're - // saying it's a final value alreadyl - if replace { - values[a.Name] = v - } - return nil + v, bypass, err := h.parseFlagValue(ctx, value, a.TypeDef) + if err != nil { + return fmt.Errorf("cannot expand function argument %q: %w", a.FlagName(), err) + } + if v == nil { + return fmt.Errorf("unexpected nil value while expanding function argument %q", a.FlagName()) + } + // Flags only support setting their values from strings, so if + // anything else is returned, we just ignore it. + // TODO: try to validate this more to avoid surprises + if sval, ok := v.(string); ok && !bypass { + return flags.Set(flag.Name, sval) } - return flags.Set(flag.Name, value) + // This will bypass using a flag for this argument since we're + // saying it's a final value already. + if bypass { + values[a.Name] = v + } + return nil } if err := flags.ParseAll(args, f); err != nil { return nil, err @@ -893,119 +893,130 @@ func (h *shellCallHandler) parseArgumentValues(ctx context.Context, md *moduleDe return values, nil } -func (h *shellCallHandler) parseStateArgument(ctx context.Context, arg *modFunctionArg, value string) (any, bool, error) { - // Does this replace the source value or do we pass it on to flag parsing? - var replace bool +// parseFlagValue ensures that a flag value with state gets resolved +// +// This happens most commonly when argument is the result of command expansion +// from a sub-shell. +func (h *shellCallHandler) parseFlagValue(ctx context.Context, value string, argType *modTypeDef) (any, bool, error) { + if !strings.HasPrefix(value, shellStatePrefix) { + return value, false, nil + } + + var bypass bool + + handleObjectID := func(_ context.Context, q *querybuilder.Selection, t *modTypeDef) (*querybuilder.Selection, error) { + // When an argument returns an object, assume we want its ID + // TODO: Allow ids in TypeDefs so we can directly check if there's an `id` + // function in this object. + if t.AsFunctionProvider() != nil { + if argType.Name() != t.Name() { + return nil, fmt.Errorf("expected return type %q, got %q", argType.Name(), t.Name()) + } + q = q.Select("id") + bypass = true + } - st, b, err := readShellState(strings.NewReader(value)) - if err != nil { - return nil, replace, err - } - // Not state, but has some other content - if st == nil && len(b) > 0 { - return string(b), replace, nil - } - fn, err := st.Function().GetDef(h.modDef(st)) + // TODO: do a bit more validation. Consider that values that are not + // to be replaced should only be strings, because that's what the + // flagSet supports. This also means the type won't match the expected + // definition. For example, a function that returns a `Directory` object + // could have a subshell return a path string so the flag will turn that + // into the `Directory` object. + + return q, nil + } + v, err := h.Result(ctx, strings.NewReader(value), false, handleObjectID) + return v, bypass, err +} + +// Result reads the state from stdin and returns the final result +func (h *shellCallHandler) Result( + ctx context.Context, + // r is the reader to read the shell state from + r io.Reader, + // doPrintResponse prepares the response for printing according to an output + // format + doPrintResponse bool, + // beforeRequest is a callback that allows modifying the query before making + // the request + // + // It's also useful for validating the query with the function's + // return type. + beforeRequest func(context.Context, *querybuilder.Selection, *modTypeDef) (*querybuilder.Selection, error), +) (any, error) { + st, b, err := readShellState(r) if err != nil { - return nil, false, fmt.Errorf("failed to get function definition: %w", err) - } - - q := st.QueryBuilder(h.dag) - - // When an argument returns an object, assume we want its ID - // TODO: Allow ids in TypeDefs so we can directly check if there's an `id` - // function in this object. - if fn.ReturnType.AsFunctionProvider() != nil { - if st.Function().ReturnObject != arg.TypeDef.Name() { - return nil, replace, fmt.Errorf("expected return type %q, got %q", arg.TypeDef.Name(), st.Function().ReturnObject) - } - q = q.Select("id") - replace = true + return nil, err } - - // TODO: do a bit more validation. Consider that values that are not - // to be replaced should only be strings, because that's what the - // flagSet supports. This also means the type won't match the expected - // definition. For example, a function that returns a `Directory` object - // could have a subshell return a path string so the flag will turn that - // into the `Directory` object. - - var response any - err = makeRequest(ctx, q, &response) - return response, replace, err -} - -// Result handles making the final request and printing the response -func (h *shellCallHandler) Result(ctx context.Context, st *ShellState) error { - if h.debug { - h.withTerminal(func(_ io.Reader, _, stderr io.Writer) error { - shellFDebug(stderr, "Result state: %+v", st) - return nil - }) + if st == nil { + return string(b), nil } if st.IsCommandRoot() { - var out string - switch { case st.IsStdlib(): - out = h.CommandsList(st.Cmd, h.Stdlib()) + return h.CommandsList(st.Cmd, h.Stdlib()), nil case st.IsDeps(): - out = h.DependenciesList() + return h.DependenciesList(), nil case st.IsCore(): def := h.modDef(nil) - out = h.FunctionsList(st.Cmd, def.GetCoreFunctions()) + return h.FunctionsList(st.Cmd, def.GetCoreFunctions()), nil default: - return fmt.Errorf("unexpected namespace: %s", st.Cmd) + return nil, fmt.Errorf("unexpected namespace %q", st.Cmd) } - - return h.withTerminal(func(_ io.Reader, stdout, _ io.Writer) error { - fmt.Fprintln(stdout, out) - return nil - }) } def := h.modDef(st) // Example: `build` (i.e., omitted constructor) if def.HasModule() && st.IsEmpty() { - newSt, err := h.constructorCall(ctx, def, st, nil) + st, err = h.constructorCall(ctx, def, st, nil) if err != nil { - return err + return nil, err } - st = newSt } fn, err := st.Function().GetDef(def) if err != nil { - return err + return nil, err } - sel := st.QueryBuilder(h.dag) - q, err := handleObjectLeaf(ctx, sel, fn.ReturnType) - if err != nil { - return err + q := st.QueryBuilder(h.dag) + if beforeRequest != nil { + q, err = beforeRequest(ctx, q, fn.ReturnType) + if err != nil { + return nil, err + } } - return h.executeRequest(ctx, q, fn.ReturnType) -} - -func (h *shellCallHandler) executeRequest(ctx context.Context, q *querybuilder.Selection, returnType *modTypeDef) error { + // The beforeRequest hook has a chance to return a nil `q` to signal + // that we shouldn't proceed with the request. For example, it's + // possible that a pipeline ending in an object doesn't have anything + // to sub-select. if q == nil { - return h.withTerminal(func(stdin io.Reader, stdout, stderr io.Writer) error { - return handleResponse(returnType, nil, stdout, stderr) - }) + return nil, nil } var response any if err := makeRequest(ctx, q, &response); err != nil { - return err + return nil, err } - return h.withTerminal(func(stdin io.Reader, stdout, stderr io.Writer) error { - return handleResponse(returnType, response, stdout, stderr) - }) + if fn.ReturnType.Kind == dagger.TypeDefKindVoidKind { + return nil, nil + } + + if doPrintResponse { + buf := new(bytes.Buffer) + frmt := outputFormat(fn.ReturnType) + if err := printResponse(buf, response, frmt); err != nil { + return nil, err + } + return buf.String(), nil + } + + return response, nil } func shellDebug(ctx context.Context, msg string, args ...any) { @@ -1366,7 +1377,7 @@ func NoArgs(args []string) error { } // Execute is the main dispatcher function for shell builtin commands -func (c *ShellCommand) Execute(ctx context.Context, args []string, st *ShellState) error { +func (c *ShellCommand) Execute(ctx context.Context, h *shellCallHandler, args []string, st *ShellState) error { if st != nil && c.RunState == nil { return fmt.Errorf("command %q cannot be piped", c.Name()) } @@ -1375,11 +1386,30 @@ func (c *ShellCommand) Execute(ctx context.Context, args []string, st *ShellStat return fmt.Errorf("command %q %w\nusage: %s", c.Name(), err, c.Use) } } + // Resolve state values in arguments + a := make([]string, 0, len(args)) + for i, arg := range args { + if strings.HasPrefix(arg, shellStatePrefix) { + w := strings.NewReader(arg) + v, err := h.Result(ctx, w, false, nil) + if err != nil { + return fmt.Errorf("cannot expand command argument at %d", i) + } + if v == nil { + return fmt.Errorf("unexpected nil value while expanding argument at %d", i) + } + arg = fmt.Sprintf("%v", v) + } + a = append(a, arg) + } + if h.debug { + shellDebug(ctx, "โ”” CmdExec(%v)", a) + } c.SetContext(ctx) if c.RunState != nil { - return c.RunState(c, args, st) + return c.RunState(c, a, st) } - return c.Run(c, args) + return c.Run(c, a) } // shellFunctionUseLine returns the usage line fine for a function diff --git a/core/integration/module_shell_test.go b/core/integration/module_shell_test.go index 5ecbfb4b4c..34b0da1875 100644 --- a/core/integration/module_shell_test.go +++ b/core/integration/module_shell_test.go @@ -94,12 +94,16 @@ func (Test) Go() string { package main -type Dep struct{} +func New() *Dep { + return &Dep{ + Version: "dep function", + } +} -// Dep version -func (Dep) Version() string { - return "dep function" -} +type Dep struct{ + // Dep version + Version string +} `, )). With(withModInitAt("modules/git", "go", `// A git helper @@ -280,7 +284,7 @@ func (Other) Version() string { With(daggerShell("dep")). Stdout(ctx) require.NoError(t, err) - require.JSONEq(t, `{"_type": "Dep"}`, out) + require.JSONEq(t, `{"version": "dep function"}`, out) }) t.Run("dep doc type", func(ctx context.Context, t *testctx.T) { @@ -473,7 +477,7 @@ type Foo struct{ With(daggerShell("foo")). Stdout(ctx) require.NoError(t, err) - require.JSONEq(t, `{"_type": "Foo", "bar": "foobar"}`, out) + require.JSONEq(t, `{"bar": "foobar"}`, out) }) t.Run("stateful", func(ctx context.Context, t *testctx.T) { @@ -620,6 +624,15 @@ func (ShellSuite) TestArgsSpread(ctx context.Context, t *testctx.T) { } } +func (ShellSuite) TestCommandStateArgs(ctx context.Context, t *testctx.T) { + c := connect(ctx, t) + script := fmt.Sprintf("FOO=$(container | from %s | with-exec -- echo -n foo | stdout); .doc $FOO", alpineImage) + _, err := daggerCliBase(t, c). + With(daggerShell(script)). + Sync(ctx) + requireErrOut(t, err, `"foo" not found`) +} + func (ShellSuite) TestInstall(ctx context.Context, t *testctx.T) { c := connect(ctx, t) From c4f683fb6d584349e97372ad40451dd5cc3ad4d8 Mon Sep 17 00:00:00 2001 From: Erik Sipsma Date: Thu, 12 Dec 2024 10:58:23 -0800 Subject: [PATCH 32/35] upgrade golang.org/x/crypto dep to avoid CVE (#9172) Signed-off-by: Erik Sipsma --- .dagger/go.mod | 6 +- .dagger/go.sum | 12 +-- .github/go.mod | 6 +- .github/go.sum | 12 +-- cmd/dagger/.dagger/go.mod | 6 +- cmd/dagger/.dagger/go.sum | 12 +-- dagql/idtui/viztest/broken/go.mod | 29 +++---- dagql/idtui/viztest/broken/go.sum | 54 +++++++------ dagql/idtui/viztest/go.mod | 19 +++-- dagql/idtui/viztest/go.sum | 26 ++++--- dagql/idtui/viztest/typescript/package.json | 4 +- dagql/idtui/viztest/typescript/yarn.lock | 63 +++++++++++++++- go.mod | 10 +-- go.sum | 20 ++--- helm/.dagger/go.mod | 38 +++++----- helm/.dagger/go.sum | 15 +--- modules/alpine/go.mod | 17 +++-- modules/alpine/go.sum | 34 +++++---- modules/compatcheck/go.mod | 34 ++++++--- modules/compatcheck/go.sum | 54 +++++++------ modules/daggerverse/go.mod | 6 +- modules/daggerverse/go.sum | 12 +-- modules/dirdiff/go.mod | 41 ++++++---- modules/dirdiff/go.sum | 54 +++++++------ modules/gha/examples/go/go.mod | 6 +- modules/gha/examples/go/go.sum | 12 +-- modules/gha/go.mod | 9 +-- modules/gha/go.sum | 18 ++--- modules/go/go.mod | 6 +- modules/go/go.sum | 12 +-- modules/golangci/go.mod | 41 ++++++---- modules/golangci/go.sum | 54 +++++++------ modules/graphql/go.mod | 41 ++++++---- modules/graphql/go.sum | 54 +++++++------ modules/markdown/go.mod | 41 ++++++---- modules/markdown/go.sum | 54 +++++++------ modules/ps-analyzer/go.mod | 37 +++++---- modules/ps-analyzer/go.sum | 54 +++++++------ modules/ruff/go.mod | 35 ++++++--- modules/ruff/go.sum | 58 +++++++------- modules/shellcheck/go.mod | 39 ++++++---- modules/shellcheck/go.sum | 50 ++++++------ modules/wolfi/go.mod | 19 +++-- modules/wolfi/go.sum | 26 ++++--- releaser/.dagger/go.mod | 9 +-- releaser/.dagger/go.sum | 14 +--- sdk/elixir/runtime/go.mod | 53 +++++++------ sdk/elixir/runtime/go.sum | 74 +++++++++--------- sdk/go/go.mod | 6 +- sdk/go/go.sum | 12 +-- sdk/php/runtime/go.mod | 25 +++--- sdk/php/runtime/go.sum | 62 ++++++++------- sdk/python/runtime/go.mod | 5 +- sdk/python/runtime/go.sum | 6 -- sdk/typescript/runtime/go.mod | 62 ++++++++------- sdk/typescript/runtime/go.sum | 84 ++++++++++----------- version/go.mod | 17 +++-- version/go.sum | 30 +++++--- 58 files changed, 964 insertions(+), 745 deletions(-) diff --git a/.dagger/go.mod b/.dagger/go.mod index 5314566b00..5da12c99ca 100644 --- a/.dagger/go.mod +++ b/.dagger/go.mod @@ -26,7 +26,7 @@ require ( go.opentelemetry.io/proto/otlp v1.3.1 golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 golang.org/x/mod v0.20.0 - golang.org/x/sync v0.9.0 + golang.org/x/sync v0.10.0 google.golang.org/grpc v1.68.0 ) @@ -49,8 +49,8 @@ require ( go.opentelemetry.io/otel/metric v1.27.0 go.opentelemetry.io/otel/sdk/metric v1.27.0 golang.org/x/net v0.29.0 // indirect - golang.org/x/sys v0.26.0 // indirect - golang.org/x/text v0.19.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect google.golang.org/protobuf v1.35.2 // indirect diff --git a/.dagger/go.sum b/.dagger/go.sum index d624521376..10040609c8 100644 --- a/.dagger/go.sum +++ b/.dagger/go.sum @@ -92,13 +92,13 @@ golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= -golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= diff --git a/.github/go.mod b/.github/go.mod index c8f35151c6..6150316b96 100644 --- a/.github/go.mod +++ b/.github/go.mod @@ -23,7 +23,7 @@ require ( go.opentelemetry.io/otel/trace v1.27.0 go.opentelemetry.io/proto/otlp v1.3.1 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa - golang.org/x/sync v0.8.0 + golang.org/x/sync v0.10.0 google.golang.org/grpc v1.66.1 ) @@ -37,8 +37,8 @@ require ( github.com/sosodev/duration v1.3.1 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect golang.org/x/net v0.29.0 // indirect - golang.org/x/sys v0.26.0 // indirect - golang.org/x/text v0.18.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect google.golang.org/protobuf v1.34.2 // indirect diff --git a/.github/go.sum b/.github/go.sum index 5929f90bb5..e19aa4fa2a 100644 --- a/.github/go.sum +++ b/.github/go.sum @@ -71,12 +71,12 @@ golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= diff --git a/cmd/dagger/.dagger/go.mod b/cmd/dagger/.dagger/go.mod index 20dbef5c41..e8ed49a441 100644 --- a/cmd/dagger/.dagger/go.mod +++ b/cmd/dagger/.dagger/go.mod @@ -17,7 +17,7 @@ require ( go.opentelemetry.io/otel/trace v1.27.0 go.opentelemetry.io/proto/otlp v1.3.1 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa - golang.org/x/sync v0.8.0 + golang.org/x/sync v0.10.0 google.golang.org/grpc v1.65.0 ) @@ -35,8 +35,8 @@ require ( go.opentelemetry.io/otel/metric v1.27.0 go.opentelemetry.io/otel/sdk/metric v1.27.0 golang.org/x/net v0.29.0 // indirect - golang.org/x/sys v0.26.0 // indirect - golang.org/x/text v0.18.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/protobuf v1.34.2 // indirect diff --git a/cmd/dagger/.dagger/go.sum b/cmd/dagger/.dagger/go.sum index cb0bbbff0b..c146adf411 100644 --- a/cmd/dagger/.dagger/go.sum +++ b/cmd/dagger/.dagger/go.sum @@ -71,12 +71,12 @@ golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= diff --git a/dagql/idtui/viztest/broken/go.mod b/dagql/idtui/viztest/broken/go.mod index 60a2c1a6b5..52d6b0a5a7 100644 --- a/dagql/idtui/viztest/broken/go.mod +++ b/dagql/idtui/viztest/broken/go.mod @@ -3,9 +3,9 @@ module dagger/broken go 1.23.0 require ( - github.com/99designs/gqlgen v0.17.49 + github.com/99designs/gqlgen v0.17.55 github.com/Khan/genqlient v0.7.0 - github.com/vektah/gqlparser/v2 v2.5.16 + github.com/vektah/gqlparser/v2 v2.5.17 go.opentelemetry.io/otel v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 @@ -17,26 +17,29 @@ require ( go.opentelemetry.io/otel/trace v1.27.0 go.opentelemetry.io/proto/otlp v1.3.1 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa - golang.org/x/sync v0.7.0 - google.golang.org/grpc v1.64.0 + golang.org/x/sync v0.10.0 + google.golang.org/grpc v1.65.0 ) require ( github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/sosodev/duration v1.3.1 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect - go.opentelemetry.io/otel/metric v1.27.0 // indirect - golang.org/x/net v0.26.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 // indirect - google.golang.org/protobuf v1.34.1 // indirect + go.opentelemetry.io/otel/metric v1.27.0 + go.opentelemetry.io/otel/sdk/metric v1.27.0 + golang.org/x/net v0.29.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/protobuf v1.34.2 // indirect ) replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 diff --git a/dagql/idtui/viztest/broken/go.sum b/dagql/idtui/viztest/broken/go.sum index 6fea81b9cb..c146adf411 100644 --- a/dagql/idtui/viztest/broken/go.sum +++ b/dagql/idtui/viztest/broken/go.sum @@ -1,5 +1,5 @@ -github.com/99designs/gqlgen v0.17.49 h1:b3hNGexHd33fBSAd4NDT/c3NCcQzcAVkknhN9ym36YQ= -github.com/99designs/gqlgen v0.17.49/go.mod h1:tC8YFVZMed81x7UJ7ORUwXF4Kn6SXuucFqQBhN8+BU0= +github.com/99designs/gqlgen v0.17.55 h1:3vzrNWYyzSZjGDFo68e5j9sSauLxfKvLp+6ioRokVtM= +github.com/99designs/gqlgen v0.17.55/go.mod h1:3Bq768f8hgVPGZxL8aY9MaYmbxa6llPM/qu1IGH1EJo= github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= @@ -10,16 +10,16 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -33,14 +33,18 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0vy5p8= -github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= +github.com/vektah/gqlparser/v2 v2.5.17 h1:9At7WblLV7/36nulgekUgIaqHZWn5hxqluxrxGUhOmI= +github.com/vektah/gqlparser/v2 v2.5.17/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 h1:oM0GTNKGlc5qHctWeIGTVyda4iFFalOzMZ3Ehj5rwB4= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88/go.mod h1:JGG8ebaMO5nXOPnvKEl+DiA4MGwFjCbjsxT1WHIEBPY= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 h1:ccBrA8nCY5mM0y5uO7FT0ze4S0TuFcWdDB2FxGMTjkI= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0/go.mod h1:/9pb6634zi2Lk8LYg9Q0X8Ar6jka4dkFOylBLbVQPCE= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 h1:bFgvUr3/O4PHj3VQcFEuYKvRZJX1SJDQ+11JXuSB3/w= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0/go.mod h1:xJntEd2KL6Qdg5lwp97HMLQDVeAhrYxmzFseAMDPQ8I= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 h1:CIHWikMsN3wO+wq1Tp5VGdVRTcON+DmOJSfDjXypKOc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0/go.mod h1:TNupZ6cxqyFEpLXAZW7On+mLFL0/g0TE3unIYL91xWc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= @@ -55,6 +59,8 @@ go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kT go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= go.opentelemetry.io/otel/sdk/log v0.3.0 h1:GEjJ8iftz2l+XO1GF2856r7yYVh74URiF9JMcAacr5U= go.opentelemetry.io/otel/sdk/log v0.3.0/go.mod h1:BwCxtmux6ACLuys1wlbc0+vGBd+xytjmjajwqqIul2g= +go.opentelemetry.io/otel/sdk/metric v1.27.0 h1:5uGNOlpXi+Hbo/DRoI31BSb1v+OGcpv2NemcCrOL8gI= +go.opentelemetry.io/otel/sdk/metric v1.27.0/go.mod h1:we7jJVrYN2kh3mVBlswtPU22K0SA+769l93J6bsyvqw= go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= @@ -63,22 +69,22 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 h1:P8OJ/WCl/Xo4E4zoe4/bifHpSmmKwARqyqE4nW6J2GQ= -google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5/go.mod h1:RGnPtTG7r4i8sPlNyDeikXF99hMM+hN6QMm4ooG9g2g= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 h1:AgADTJarZTBqgjiUzRgfaBchgYB3/WFTC80GPwsMcRI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= -google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= -google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/dagql/idtui/viztest/go.mod b/dagql/idtui/viztest/go.mod index 99016f1947..297d82b8a3 100644 --- a/dagql/idtui/viztest/go.mod +++ b/dagql/idtui/viztest/go.mod @@ -1,11 +1,13 @@ module dagger/viztest -go 1.21.7 +go 1.22.5 + +toolchain go1.23.2 require ( - github.com/99designs/gqlgen v0.17.49 + github.com/99designs/gqlgen v0.17.55 github.com/Khan/genqlient v0.7.0 - github.com/vektah/gqlparser/v2 v2.5.16 + github.com/vektah/gqlparser/v2 v2.5.17 go.opentelemetry.io/otel v1.28.0 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240816180739-2db4ef2c032c go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.4.0 @@ -13,7 +15,7 @@ require ( go.opentelemetry.io/otel/sdk/log v0.4.0 go.opentelemetry.io/otel/trace v1.28.0 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa - golang.org/x/sync v0.8.0 + golang.org/x/sync v0.10.0 ) require ( @@ -24,15 +26,18 @@ require ( github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/sosodev/duration v1.3.1 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 - go.opentelemetry.io/otel/metric v1.28.0 // indirect + go.opentelemetry.io/otel/metric v1.28.0 go.opentelemetry.io/otel/sdk v1.28.0 + go.opentelemetry.io/otel/sdk/metric v1.27.0 go.opentelemetry.io/proto/otlp v1.3.1 golang.org/x/net v0.29.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/text v0.18.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/grpc v1.65.0 diff --git a/dagql/idtui/viztest/go.sum b/dagql/idtui/viztest/go.sum index 33ddc85a84..cf2ff426de 100644 --- a/dagql/idtui/viztest/go.sum +++ b/dagql/idtui/viztest/go.sum @@ -1,5 +1,5 @@ -github.com/99designs/gqlgen v0.17.49 h1:b3hNGexHd33fBSAd4NDT/c3NCcQzcAVkknhN9ym36YQ= -github.com/99designs/gqlgen v0.17.49/go.mod h1:tC8YFVZMed81x7UJ7ORUwXF4Kn6SXuucFqQBhN8+BU0= +github.com/99designs/gqlgen v0.17.55 h1:3vzrNWYyzSZjGDFo68e5j9sSauLxfKvLp+6ioRokVtM= +github.com/99designs/gqlgen v0.17.55/go.mod h1:3Bq768f8hgVPGZxL8aY9MaYmbxa6llPM/qu1IGH1EJo= github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= @@ -33,14 +33,18 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0vy5p8= -github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= +github.com/vektah/gqlparser/v2 v2.5.17 h1:9At7WblLV7/36nulgekUgIaqHZWn5hxqluxrxGUhOmI= +github.com/vektah/gqlparser/v2 v2.5.17/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 h1:oM0GTNKGlc5qHctWeIGTVyda4iFFalOzMZ3Ehj5rwB4= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88/go.mod h1:JGG8ebaMO5nXOPnvKEl+DiA4MGwFjCbjsxT1WHIEBPY= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 h1:ccBrA8nCY5mM0y5uO7FT0ze4S0TuFcWdDB2FxGMTjkI= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0/go.mod h1:/9pb6634zi2Lk8LYg9Q0X8Ar6jka4dkFOylBLbVQPCE= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 h1:bFgvUr3/O4PHj3VQcFEuYKvRZJX1SJDQ+11JXuSB3/w= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0/go.mod h1:xJntEd2KL6Qdg5lwp97HMLQDVeAhrYxmzFseAMDPQ8I= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 h1:CIHWikMsN3wO+wq1Tp5VGdVRTcON+DmOJSfDjXypKOc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0/go.mod h1:TNupZ6cxqyFEpLXAZW7On+mLFL0/g0TE3unIYL91xWc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= @@ -55,6 +59,8 @@ go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBq go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= go.opentelemetry.io/otel/sdk/log v0.3.0 h1:GEjJ8iftz2l+XO1GF2856r7yYVh74URiF9JMcAacr5U= go.opentelemetry.io/otel/sdk/log v0.3.0/go.mod h1:BwCxtmux6ACLuys1wlbc0+vGBd+xytjmjajwqqIul2g= +go.opentelemetry.io/otel/sdk/metric v1.27.0 h1:5uGNOlpXi+Hbo/DRoI31BSb1v+OGcpv2NemcCrOL8gI= +go.opentelemetry.io/otel/sdk/metric v1.27.0/go.mod h1:we7jJVrYN2kh3mVBlswtPU22K0SA+769l93J6bsyvqw= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= @@ -65,12 +71,12 @@ golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= diff --git a/dagql/idtui/viztest/typescript/package.json b/dagql/idtui/viztest/typescript/package.json index 8ccebb27d4..bfbcfbe531 100644 --- a/dagql/idtui/viztest/typescript/package.json +++ b/dagql/idtui/viztest/typescript/package.json @@ -1,8 +1,8 @@ { "type": "module", "dependencies": { - "typescript": "^5.5.4", - "@dagger.io/dagger": "./sdk" + "@dagger.io/dagger": "./sdk", + "typescript": "^5.5.4" }, "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" } diff --git a/dagql/idtui/viztest/typescript/yarn.lock b/dagql/idtui/viztest/typescript/yarn.lock index f5bdadfdb1..9ecd1ee4d3 100644 --- a/dagql/idtui/viztest/typescript/yarn.lock +++ b/dagql/idtui/viztest/typescript/yarn.lock @@ -8,7 +8,7 @@ "@grpc/grpc-js" "^1.11.1" "@lifeomic/axios-fetch" "^3.1.0" "@opentelemetry/api" "^1.9.0" - "@opentelemetry/exporter-trace-otlp-grpc" "^0.52.1" + "@opentelemetry/exporter-trace-otlp-http" "^0.53.0" "@opentelemetry/sdk-metrics" "^1.25.1" "@opentelemetry/sdk-node" "^0.52.1" "@opentelemetry/semantic-conventions" "^1.25.1" @@ -109,6 +109,13 @@ dependencies: "@opentelemetry/api" "^1.0.0" +"@opentelemetry/api-logs@0.53.0": + version "0.53.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/api-logs/-/api-logs-0.53.0.tgz#c478cbd8120ec2547b64edfa03a552cfe42170be" + integrity sha512-8HArjKx+RaAI8uEIgcORbZIPklyh1YLjPSBus8hjRmvLi6DeFzgOcdZ7KwPabKj8mXF8dX0hyfAyGfycz0DbFw== + dependencies: + "@opentelemetry/api" "^1.0.0" + "@opentelemetry/api@^1.0.0", "@opentelemetry/api@^1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.9.0.tgz#d03eba68273dc0f7509e2a3d5cba21eae10379fe" @@ -133,7 +140,7 @@ dependencies: "@opentelemetry/semantic-conventions" "1.27.0" -"@opentelemetry/exporter-trace-otlp-grpc@0.52.1", "@opentelemetry/exporter-trace-otlp-grpc@^0.52.1": +"@opentelemetry/exporter-trace-otlp-grpc@0.52.1": version "0.52.1" resolved "https://registry.yarnpkg.com/@opentelemetry/exporter-trace-otlp-grpc/-/exporter-trace-otlp-grpc-0.52.1.tgz#8b59c93a5833484ba19a7f424632c6ced5ea1d3b" integrity sha512-pVkSH20crBwMTqB3nIN4jpQKUEoB0Z94drIHpYyEqs7UBr+I0cpYyOR3bqjA/UasQUMROb3GX8ZX4/9cVRqGBQ== @@ -156,6 +163,17 @@ "@opentelemetry/resources" "1.25.1" "@opentelemetry/sdk-trace-base" "1.25.1" +"@opentelemetry/exporter-trace-otlp-http@^0.53.0": + version "0.53.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.53.0.tgz#48e46c4573a35d31c14e6bc44635923e32970b9a" + integrity sha512-m7F5ZTq+V9mKGWYpX8EnZ7NjoqAU7VemQ1E2HAG+W/u0wpY1x0OmbxAXfGKFHCspdJk8UKlwPGrpcB8nay3P8A== + dependencies: + "@opentelemetry/core" "1.26.0" + "@opentelemetry/otlp-exporter-base" "0.53.0" + "@opentelemetry/otlp-transformer" "0.53.0" + "@opentelemetry/resources" "1.26.0" + "@opentelemetry/sdk-trace-base" "1.26.0" + "@opentelemetry/exporter-trace-otlp-proto@0.52.1": version "0.52.1" resolved "https://registry.yarnpkg.com/@opentelemetry/exporter-trace-otlp-proto/-/exporter-trace-otlp-proto-0.52.1.tgz#7b68268cd4d46b7d89ee7c97720031ca80919fd6" @@ -197,6 +215,14 @@ "@opentelemetry/core" "1.25.1" "@opentelemetry/otlp-transformer" "0.52.1" +"@opentelemetry/otlp-exporter-base@0.53.0": + version "0.53.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.53.0.tgz#dfe51874b869c687c3cb463b70cddda7de282762" + integrity sha512-UCWPreGQEhD6FjBaeDuXhiMf6kkBODF0ZQzrk/tuQcaVDJ+dDQ/xhJp192H9yWnKxVpEjFrSSLnpqmX4VwX+eA== + dependencies: + "@opentelemetry/core" "1.26.0" + "@opentelemetry/otlp-transformer" "0.53.0" + "@opentelemetry/otlp-grpc-exporter-base@0.52.1": version "0.52.1" resolved "https://registry.yarnpkg.com/@opentelemetry/otlp-grpc-exporter-base/-/otlp-grpc-exporter-base-0.52.1.tgz#e1fdfd979289a87faec1c7cf303100c75e49a284" @@ -220,6 +246,19 @@ "@opentelemetry/sdk-trace-base" "1.25.1" protobufjs "^7.3.0" +"@opentelemetry/otlp-transformer@0.53.0": + version "0.53.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/otlp-transformer/-/otlp-transformer-0.53.0.tgz#55d435db5ed5cf56b99c010827294dd4921c45c2" + integrity sha512-rM0sDA9HD8dluwuBxLetUmoqGJKSAbWenwD65KY9iZhUxdBHRLrIdrABfNDP7aiTjcgK8XFyTn5fhDz7N+W6DA== + dependencies: + "@opentelemetry/api-logs" "0.53.0" + "@opentelemetry/core" "1.26.0" + "@opentelemetry/resources" "1.26.0" + "@opentelemetry/sdk-logs" "0.53.0" + "@opentelemetry/sdk-metrics" "1.26.0" + "@opentelemetry/sdk-trace-base" "1.26.0" + protobufjs "^7.3.0" + "@opentelemetry/propagator-b3@1.25.1": version "1.25.1" resolved "https://registry.yarnpkg.com/@opentelemetry/propagator-b3/-/propagator-b3-1.25.1.tgz#653ee5f3f0f223c000907c1559c89c0a208819f7" @@ -259,6 +298,15 @@ "@opentelemetry/core" "1.25.1" "@opentelemetry/resources" "1.25.1" +"@opentelemetry/sdk-logs@0.53.0": + version "0.53.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-logs/-/sdk-logs-0.53.0.tgz#ec8b69278c4e683c13c58ed4285a47c27f5799c6" + integrity sha512-dhSisnEgIj/vJZXZV6f6KcTnyLDx/VuQ6l3ejuZpMpPlh9S1qMHiZU9NMmOkVkwwHkMy3G6mEBwdP23vUZVr4g== + dependencies: + "@opentelemetry/api-logs" "0.53.0" + "@opentelemetry/core" "1.26.0" + "@opentelemetry/resources" "1.26.0" + "@opentelemetry/sdk-metrics@1.25.1": version "1.25.1" resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-metrics/-/sdk-metrics-1.25.1.tgz#50c985ec15557a9654334e7fa1018dc47a8a56b7" @@ -268,7 +316,7 @@ "@opentelemetry/resources" "1.25.1" lodash.merge "^4.6.2" -"@opentelemetry/sdk-metrics@^1.25.1": +"@opentelemetry/sdk-metrics@1.26.0", "@opentelemetry/sdk-metrics@^1.25.1": version "1.26.0" resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-metrics/-/sdk-metrics-1.26.0.tgz#37bb0afb1d4447f50aab9cdd05db6f2d8b86103e" integrity sha512-0SvDXmou/JjzSDOjUmetAAvcKQW6ZrvosU0rkbDGpXvvZN+pQF6JbK/Kd4hNdK4q/22yeruqvukXEJyySTzyTQ== @@ -304,6 +352,15 @@ "@opentelemetry/resources" "1.25.1" "@opentelemetry/semantic-conventions" "1.25.1" +"@opentelemetry/sdk-trace-base@1.26.0": + version "1.26.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.26.0.tgz#0c913bc6d2cfafd901de330e4540952269ae579c" + integrity sha512-olWQldtvbK4v22ymrKLbIcBi9L2SpMO84sCPY54IVsJhP9fRsxJT194C/AVaAuJzLE30EdhhM1VmvVYR7az+cw== + dependencies: + "@opentelemetry/core" "1.26.0" + "@opentelemetry/resources" "1.26.0" + "@opentelemetry/semantic-conventions" "1.27.0" + "@opentelemetry/sdk-trace-node@1.25.1": version "1.25.1" resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-node/-/sdk-trace-node-1.25.1.tgz#856063bef1167ae74139199338c24fb958838ff3" diff --git a/go.mod b/go.mod index b13074d48e..9bf689b82f 100644 --- a/go.mod +++ b/go.mod @@ -93,15 +93,15 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.27.0 go.opentelemetry.io/otel/trace v1.27.0 go.opentelemetry.io/proto/otlp v1.3.1 - golang.org/x/crypto v0.28.0 + golang.org/x/crypto v0.31.0 golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 golang.org/x/mod v0.21.0 golang.org/x/net v0.30.0 golang.org/x/oauth2 v0.23.0 - golang.org/x/sync v0.9.0 - golang.org/x/sys v0.26.0 - golang.org/x/term v0.25.0 - golang.org/x/text v0.19.0 + golang.org/x/sync v0.10.0 + golang.org/x/sys v0.28.0 + golang.org/x/term v0.27.0 + golang.org/x/text v0.21.0 golang.org/x/tools v0.26.0 google.golang.org/grpc v1.68.0 google.golang.org/protobuf v1.35.2 diff --git a/go.sum b/go.sum index c0659dbcd2..15596af419 100644 --- a/go.sum +++ b/go.sum @@ -674,8 +674,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= -golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= @@ -722,8 +722,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= -golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -754,16 +754,16 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= -golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= -golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -772,8 +772,8 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/helm/.dagger/go.mod b/helm/.dagger/go.mod index 406cadcd0d..45c5b20e68 100644 --- a/helm/.dagger/go.mod +++ b/helm/.dagger/go.mod @@ -3,48 +3,50 @@ module dagger/helm go 1.23.0 require ( - github.com/99designs/gqlgen v0.17.57 - github.com/Khan/genqlient v0.7.0 github.com/moby/buildkit v0.16.0 - github.com/vektah/gqlparser/v2 v2.5.19 - go.opentelemetry.io/otel v1.28.0 - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 - go.opentelemetry.io/otel/log v0.3.0 - go.opentelemetry.io/otel/sdk v1.27.0 - go.opentelemetry.io/otel/sdk/log v0.3.0 - go.opentelemetry.io/otel/trace v1.28.0 - go.opentelemetry.io/proto/otlp v1.3.1 - golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa golang.org/x/mod v0.20.0 - golang.org/x/sync v0.9.0 - google.golang.org/grpc v1.68.0 helm.sh/helm/v3 v3.16.0 sigs.k8s.io/yaml v1.4.0 ) require ( github.com/Masterminds/semver/v3 v3.3.0 // indirect + github.com/stretchr/testify v1.10.0 // indirect +) + +require ( + github.com/99designs/gqlgen v0.17.57 + github.com/Khan/genqlient v0.7.0 github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect - github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/sosodev/duration v1.3.1 // indirect - github.com/stretchr/testify v1.10.0 // indirect + github.com/vektah/gqlparser/v2 v2.5.19 + go.opentelemetry.io/otel v1.28.0 + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 + go.opentelemetry.io/otel/log v0.3.0 go.opentelemetry.io/otel/metric v1.28.0 + go.opentelemetry.io/otel/sdk v1.27.0 + go.opentelemetry.io/otel/sdk/log v0.3.0 go.opentelemetry.io/otel/sdk/metric v1.27.0 + go.opentelemetry.io/otel/trace v1.28.0 + go.opentelemetry.io/proto/otlp v1.3.1 + golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa golang.org/x/net v0.29.0 // indirect + golang.org/x/sync v0.9.0 golang.org/x/sys v0.26.0 // indirect golang.org/x/text v0.19.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect + google.golang.org/grpc v1.68.0 google.golang.org/protobuf v1.35.2 // indirect ) diff --git a/helm/.dagger/go.sum b/helm/.dagger/go.sum index c05a0d2840..0dbd53264a 100644 --- a/helm/.dagger/go.sum +++ b/helm/.dagger/go.sum @@ -8,8 +8,6 @@ github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNg github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -26,26 +24,20 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/moby/buildkit v0.16.0 h1:wOVBj1o5YNVad/txPQNXUXdelm7Hs/i0PUFjzbK0VKE= github.com/moby/buildkit v0.16.0/go.mod h1:Xqx/5GlrqE1yIRORk0NSCVDFpQAU1WjlT6KHYZdisIQ= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq4= github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/vektah/gqlparser/v2 v2.5.19 h1:bhCPCX1D4WWzCDvkPl4+TP1N8/kLrWnp43egplt7iSg= @@ -103,11 +95,8 @@ google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWyw google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= helm.sh/helm/v3 v3.16.0 h1:Si2uwaRq3nxT/EiR4U1sWJE2dysLKQgsrd0agL3dsH0= diff --git a/modules/alpine/go.mod b/modules/alpine/go.mod index ff8dc35445..5647e821a2 100644 --- a/modules/alpine/go.mod +++ b/modules/alpine/go.mod @@ -4,9 +4,9 @@ go 1.23.1 require ( chainguard.dev/apko v0.19.2 - github.com/99designs/gqlgen v0.17.49 + github.com/99designs/gqlgen v0.17.55 github.com/Khan/genqlient v0.7.0 - github.com/vektah/gqlparser/v2 v2.5.16 + github.com/vektah/gqlparser/v2 v2.5.17 go.opentelemetry.io/otel v1.30.0 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 @@ -19,7 +19,7 @@ require ( go.opentelemetry.io/proto/otlp v1.3.1 golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa golang.org/x/mod v0.20.0 - golang.org/x/sync v0.8.0 + golang.org/x/sync v0.10.0 google.golang.org/grpc v1.66.2 ) @@ -71,14 +71,17 @@ require ( go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 // indirect - go.opentelemetry.io/otel/metric v1.30.0 // indirect + go.opentelemetry.io/otel/metric v1.30.0 + go.opentelemetry.io/otel/sdk/metric v1.27.0 go.step.sm/crypto v0.52.0 // indirect - golang.org/x/crypto v0.27.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/net v0.29.0 // indirect golang.org/x/oauth2 v0.23.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/text v0.18.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect golang.org/x/time v0.6.0 // indirect google.golang.org/api v0.198.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed // indirect diff --git a/modules/alpine/go.sum b/modules/alpine/go.sum index 61ebffc116..a66a423bda 100644 --- a/modules/alpine/go.sum +++ b/modules/alpine/go.sum @@ -13,8 +13,8 @@ cloud.google.com/go/compute/metadata v0.5.2 h1:UxK4uu/Tn+I3p2dYWTfiX4wva7aYlKixA cloud.google.com/go/compute/metadata v0.5.2/go.mod h1:C66sj2AluDcIqakBq/M8lw8/ybHgOZqin2obFxa/E5k= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= -github.com/99designs/gqlgen v0.17.49 h1:b3hNGexHd33fBSAd4NDT/c3NCcQzcAVkknhN9ym36YQ= -github.com/99designs/gqlgen v0.17.49/go.mod h1:tC8YFVZMed81x7UJ7ORUwXF4Kn6SXuucFqQBhN8+BU0= +github.com/99designs/gqlgen v0.17.55 h1:3vzrNWYyzSZjGDFo68e5j9sSauLxfKvLp+6ioRokVtM= +github.com/99designs/gqlgen v0.17.55/go.mod h1:3Bq768f8hgVPGZxL8aY9MaYmbxa6llPM/qu1IGH1EJo= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= @@ -187,8 +187,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0vy5p8= -github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= +github.com/vektah/gqlparser/v2 v2.5.17 h1:9At7WblLV7/36nulgekUgIaqHZWn5hxqluxrxGUhOmI= +github.com/vektah/gqlparser/v2 v2.5.17/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= @@ -206,6 +206,10 @@ go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-2024051809000 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88/go.mod h1:JGG8ebaMO5nXOPnvKEl+DiA4MGwFjCbjsxT1WHIEBPY= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 h1:ccBrA8nCY5mM0y5uO7FT0ze4S0TuFcWdDB2FxGMTjkI= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0/go.mod h1:/9pb6634zi2Lk8LYg9Q0X8Ar6jka4dkFOylBLbVQPCE= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 h1:bFgvUr3/O4PHj3VQcFEuYKvRZJX1SJDQ+11JXuSB3/w= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0/go.mod h1:xJntEd2KL6Qdg5lwp97HMLQDVeAhrYxmzFseAMDPQ8I= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 h1:CIHWikMsN3wO+wq1Tp5VGdVRTcON+DmOJSfDjXypKOc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0/go.mod h1:TNupZ6cxqyFEpLXAZW7On+mLFL0/g0TE3unIYL91xWc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 h1:dIIDULZJpgdiHz5tXrTgKIMLkus6jEFa7x5SOKcyR7E= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0/go.mod h1:jlRVBe7+Z1wyxFSUs48L6OBQZ5JwH2Hg/Vbl+t9rAgI= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.29.0 h1:nSiV3s7wiCam610XcLbYOmMfJxB9gO4uK3Xgv5gmTgg= @@ -220,6 +224,8 @@ go.opentelemetry.io/otel/sdk v1.29.0 h1:vkqKjk7gwhS8VaWb0POZKmIEDimRCMsopNYnriHy go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok= go.opentelemetry.io/otel/sdk/log v0.3.0 h1:GEjJ8iftz2l+XO1GF2856r7yYVh74URiF9JMcAacr5U= go.opentelemetry.io/otel/sdk/log v0.3.0/go.mod h1:BwCxtmux6ACLuys1wlbc0+vGBd+xytjmjajwqqIul2g= +go.opentelemetry.io/otel/sdk/metric v1.27.0 h1:5uGNOlpXi+Hbo/DRoI31BSb1v+OGcpv2NemcCrOL8gI= +go.opentelemetry.io/otel/sdk/metric v1.27.0/go.mod h1:we7jJVrYN2kh3mVBlswtPU22K0SA+769l93J6bsyvqw= go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc= go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= @@ -237,8 +243,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= @@ -278,8 +284,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -294,23 +300,23 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= -golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/modules/compatcheck/go.mod b/modules/compatcheck/go.mod index cc022115a3..810a0df664 100644 --- a/modules/compatcheck/go.mod +++ b/modules/compatcheck/go.mod @@ -8,7 +8,7 @@ require ( github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.3 golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 - golang.org/x/mod v0.19.0 + golang.org/x/mod v0.20.0 ) require ( @@ -19,7 +19,7 @@ require ( ) require ( - github.com/99designs/gqlgen v0.17.49 + github.com/99designs/gqlgen v0.17.55 github.com/Khan/genqlient v0.7.0 github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/go-logr/logr v1.4.2 // indirect @@ -27,34 +27,44 @@ require ( github.com/go-openapi/jsonpointer v0.19.5 // indirect github.com/go-openapi/swag v0.21.1 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/sosodev/duration v1.3.1 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect - github.com/vektah/gqlparser/v2 v2.5.16 + github.com/vektah/gqlparser/v2 v2.5.17 github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect go.opentelemetry.io/otel v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240524160931-7c5e64cccc16 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 go.opentelemetry.io/otel/log v0.3.0 - go.opentelemetry.io/otel/metric v1.27.0 // indirect + go.opentelemetry.io/otel/metric v1.27.0 go.opentelemetry.io/otel/sdk v1.27.0 go.opentelemetry.io/otel/sdk/log v0.3.0 + go.opentelemetry.io/otel/sdk/metric v1.27.0 go.opentelemetry.io/otel/trace v1.27.0 go.opentelemetry.io/proto/otlp v1.3.1 - golang.org/x/net v0.26.0 // indirect - golang.org/x/sync v0.7.0 - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240521202816-d264139d666e // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240521202816-d264139d666e // indirect - google.golang.org/grpc v1.64.0 + golang.org/x/net v0.29.0 // indirect + golang.org/x/sync v0.10.0 + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/grpc v1.65.0 google.golang.org/protobuf v1.34.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) +replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 + +replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 + +replace go.opentelemetry.io/otel/log => go.opentelemetry.io/otel/log v0.3.0 + +replace go.opentelemetry.io/otel/sdk/log => go.opentelemetry.io/otel/sdk/log v0.3.0 diff --git a/modules/compatcheck/go.sum b/modules/compatcheck/go.sum index 46476a5bd1..c1b6d4c4ec 100644 --- a/modules/compatcheck/go.sum +++ b/modules/compatcheck/go.sum @@ -1,5 +1,5 @@ -github.com/99designs/gqlgen v0.17.49 h1:b3hNGexHd33fBSAd4NDT/c3NCcQzcAVkknhN9ym36YQ= -github.com/99designs/gqlgen v0.17.49/go.mod h1:tC8YFVZMed81x7UJ7ORUwXF4Kn6SXuucFqQBhN8+BU0= +github.com/99designs/gqlgen v0.17.55 h1:3vzrNWYyzSZjGDFo68e5j9sSauLxfKvLp+6ioRokVtM= +github.com/99designs/gqlgen v0.17.55/go.mod h1:3Bq768f8hgVPGZxL8aY9MaYmbxa6llPM/qu1IGH1EJo= github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= @@ -24,8 +24,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/josephburnett/jd/v2 v2.0.0-20240818191833-6125a15c637a h1:ntNBg8gpF1HRYMOL+a0dZPiRDZqYbL3RcErlUe/A3AA= github.com/josephburnett/jd/v2 v2.0.0-20240818191833-6125a15c637a/go.mod h1:yo16rJLdw5ZSMCujd1aGu6HwfLifPrD/8fsqo3FO7ik= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -66,16 +66,20 @@ github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JT github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0vy5p8= -github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= +github.com/vektah/gqlparser/v2 v2.5.17 h1:9At7WblLV7/36nulgekUgIaqHZWn5hxqluxrxGUhOmI= +github.com/vektah/gqlparser/v2 v2.5.17/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240524160931-7c5e64cccc16 h1:bX+M0VP/ZFleBatrJSIO8g4tvgnsBnC6c6VQt6TgGBU= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240524160931-7c5e64cccc16/go.mod h1:umsZbskVobsDEd6+KuZyvJNMYvb+lJCw8s6MZOS9JGc= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 h1:oM0GTNKGlc5qHctWeIGTVyda4iFFalOzMZ3Ehj5rwB4= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88/go.mod h1:JGG8ebaMO5nXOPnvKEl+DiA4MGwFjCbjsxT1WHIEBPY= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 h1:ccBrA8nCY5mM0y5uO7FT0ze4S0TuFcWdDB2FxGMTjkI= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0/go.mod h1:/9pb6634zi2Lk8LYg9Q0X8Ar6jka4dkFOylBLbVQPCE= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 h1:bFgvUr3/O4PHj3VQcFEuYKvRZJX1SJDQ+11JXuSB3/w= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0/go.mod h1:xJntEd2KL6Qdg5lwp97HMLQDVeAhrYxmzFseAMDPQ8I= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 h1:CIHWikMsN3wO+wq1Tp5VGdVRTcON+DmOJSfDjXypKOc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0/go.mod h1:TNupZ6cxqyFEpLXAZW7On+mLFL0/g0TE3unIYL91xWc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= @@ -90,6 +94,8 @@ go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kT go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= go.opentelemetry.io/otel/sdk/log v0.3.0 h1:GEjJ8iftz2l+XO1GF2856r7yYVh74URiF9JMcAacr5U= go.opentelemetry.io/otel/sdk/log v0.3.0/go.mod h1:BwCxtmux6ACLuys1wlbc0+vGBd+xytjmjajwqqIul2g= +go.opentelemetry.io/otel/sdk/metric v1.27.0 h1:5uGNOlpXi+Hbo/DRoI31BSb1v+OGcpv2NemcCrOL8gI= +go.opentelemetry.io/otel/sdk/metric v1.27.0/go.mod h1:we7jJVrYN2kh3mVBlswtPU22K0SA+769l93J6bsyvqw= go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= @@ -98,22 +104,22 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -google.golang.org/genproto/googleapis/api v0.0.0-20240521202816-d264139d666e h1:SkdGTrROJl2jRGT/Fxv5QUf9jtdKCQh4KQJXbXVLAi0= -google.golang.org/genproto/googleapis/api v0.0.0-20240521202816-d264139d666e/go.mod h1:LweJcLbyVij6rCex8YunD8DYR5VDonap/jYl3ZRxcIU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240521202816-d264139d666e h1:Elxv5MwEkCI9f5SkoL6afed6NTdxaGoAo39eANBwHL8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240521202816-d264139d666e/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= -google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= -google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/modules/daggerverse/go.mod b/modules/daggerverse/go.mod index f0f663930b..9c6ae2dde6 100644 --- a/modules/daggerverse/go.mod +++ b/modules/daggerverse/go.mod @@ -18,7 +18,7 @@ require ( go.opentelemetry.io/otel/trace v1.27.0 go.opentelemetry.io/proto/otlp v1.3.1 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa - golang.org/x/sync v0.9.0 + golang.org/x/sync v0.10.0 google.golang.org/grpc v1.68.0 ) @@ -38,8 +38,8 @@ require ( go.opentelemetry.io/otel/metric v1.27.0 go.opentelemetry.io/otel/sdk/metric v1.27.0 golang.org/x/net v0.29.0 // indirect - golang.org/x/sys v0.26.0 // indirect - golang.org/x/text v0.19.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect google.golang.org/protobuf v1.35.2 // indirect diff --git a/modules/daggerverse/go.sum b/modules/daggerverse/go.sum index 3294e0226a..b1c63985c6 100644 --- a/modules/daggerverse/go.sum +++ b/modules/daggerverse/go.sum @@ -72,12 +72,12 @@ golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= -golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= diff --git a/modules/dirdiff/go.mod b/modules/dirdiff/go.mod index be98e91c47..1c1a6f9ad2 100644 --- a/modules/dirdiff/go.mod +++ b/modules/dirdiff/go.mod @@ -1,11 +1,13 @@ module github.com/dagger/dagger/modules/dirdiff -go 1.22.3 +go 1.22.5 + +toolchain go1.23.2 require ( - github.com/99designs/gqlgen v0.17.49 + github.com/99designs/gqlgen v0.17.55 github.com/Khan/genqlient v0.7.0 - github.com/vektah/gqlparser/v2 v2.5.16 + github.com/vektah/gqlparser/v2 v2.5.17 go.opentelemetry.io/otel v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 @@ -17,24 +19,35 @@ require ( go.opentelemetry.io/otel/trace v1.27.0 go.opentelemetry.io/proto/otlp v1.3.1 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa - golang.org/x/sync v0.7.0 - google.golang.org/grpc v1.64.0 + golang.org/x/sync v0.10.0 + google.golang.org/grpc v1.65.0 ) require ( github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/sosodev/duration v1.3.1 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect - go.opentelemetry.io/otel/metric v1.27.0 // indirect - golang.org/x/net v0.26.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 // indirect - google.golang.org/protobuf v1.34.1 // indirect + go.opentelemetry.io/otel/metric v1.27.0 + go.opentelemetry.io/otel/sdk/metric v1.27.0 + golang.org/x/net v0.29.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/protobuf v1.34.2 // indirect ) + +replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 + +replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 + +replace go.opentelemetry.io/otel/log => go.opentelemetry.io/otel/log v0.3.0 + +replace go.opentelemetry.io/otel/sdk/log => go.opentelemetry.io/otel/sdk/log v0.3.0 diff --git a/modules/dirdiff/go.sum b/modules/dirdiff/go.sum index 6fea81b9cb..c146adf411 100644 --- a/modules/dirdiff/go.sum +++ b/modules/dirdiff/go.sum @@ -1,5 +1,5 @@ -github.com/99designs/gqlgen v0.17.49 h1:b3hNGexHd33fBSAd4NDT/c3NCcQzcAVkknhN9ym36YQ= -github.com/99designs/gqlgen v0.17.49/go.mod h1:tC8YFVZMed81x7UJ7ORUwXF4Kn6SXuucFqQBhN8+BU0= +github.com/99designs/gqlgen v0.17.55 h1:3vzrNWYyzSZjGDFo68e5j9sSauLxfKvLp+6ioRokVtM= +github.com/99designs/gqlgen v0.17.55/go.mod h1:3Bq768f8hgVPGZxL8aY9MaYmbxa6llPM/qu1IGH1EJo= github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= @@ -10,16 +10,16 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -33,14 +33,18 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0vy5p8= -github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= +github.com/vektah/gqlparser/v2 v2.5.17 h1:9At7WblLV7/36nulgekUgIaqHZWn5hxqluxrxGUhOmI= +github.com/vektah/gqlparser/v2 v2.5.17/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 h1:oM0GTNKGlc5qHctWeIGTVyda4iFFalOzMZ3Ehj5rwB4= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88/go.mod h1:JGG8ebaMO5nXOPnvKEl+DiA4MGwFjCbjsxT1WHIEBPY= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 h1:ccBrA8nCY5mM0y5uO7FT0ze4S0TuFcWdDB2FxGMTjkI= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0/go.mod h1:/9pb6634zi2Lk8LYg9Q0X8Ar6jka4dkFOylBLbVQPCE= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 h1:bFgvUr3/O4PHj3VQcFEuYKvRZJX1SJDQ+11JXuSB3/w= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0/go.mod h1:xJntEd2KL6Qdg5lwp97HMLQDVeAhrYxmzFseAMDPQ8I= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 h1:CIHWikMsN3wO+wq1Tp5VGdVRTcON+DmOJSfDjXypKOc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0/go.mod h1:TNupZ6cxqyFEpLXAZW7On+mLFL0/g0TE3unIYL91xWc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= @@ -55,6 +59,8 @@ go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kT go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= go.opentelemetry.io/otel/sdk/log v0.3.0 h1:GEjJ8iftz2l+XO1GF2856r7yYVh74URiF9JMcAacr5U= go.opentelemetry.io/otel/sdk/log v0.3.0/go.mod h1:BwCxtmux6ACLuys1wlbc0+vGBd+xytjmjajwqqIul2g= +go.opentelemetry.io/otel/sdk/metric v1.27.0 h1:5uGNOlpXi+Hbo/DRoI31BSb1v+OGcpv2NemcCrOL8gI= +go.opentelemetry.io/otel/sdk/metric v1.27.0/go.mod h1:we7jJVrYN2kh3mVBlswtPU22K0SA+769l93J6bsyvqw= go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= @@ -63,22 +69,22 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 h1:P8OJ/WCl/Xo4E4zoe4/bifHpSmmKwARqyqE4nW6J2GQ= -google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5/go.mod h1:RGnPtTG7r4i8sPlNyDeikXF99hMM+hN6QMm4ooG9g2g= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 h1:AgADTJarZTBqgjiUzRgfaBchgYB3/WFTC80GPwsMcRI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= -google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= -google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/modules/gha/examples/go/go.mod b/modules/gha/examples/go/go.mod index 7160063a0b..e31e9ebc03 100644 --- a/modules/gha/examples/go/go.mod +++ b/modules/gha/examples/go/go.mod @@ -17,7 +17,7 @@ require ( go.opentelemetry.io/otel/trace v1.27.0 go.opentelemetry.io/proto/otlp v1.3.1 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa - golang.org/x/sync v0.8.0 + golang.org/x/sync v0.10.0 google.golang.org/grpc v1.65.0 ) @@ -35,8 +35,8 @@ require ( go.opentelemetry.io/otel/metric v1.27.0 go.opentelemetry.io/otel/sdk/metric v1.27.0 golang.org/x/net v0.29.0 // indirect - golang.org/x/sys v0.26.0 // indirect - golang.org/x/text v0.18.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/protobuf v1.34.2 // indirect diff --git a/modules/gha/examples/go/go.sum b/modules/gha/examples/go/go.sum index cb0bbbff0b..c146adf411 100644 --- a/modules/gha/examples/go/go.sum +++ b/modules/gha/examples/go/go.sum @@ -71,12 +71,12 @@ golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= diff --git a/modules/gha/go.mod b/modules/gha/go.mod index 68e3661d90..eeb0837d5a 100644 --- a/modules/gha/go.mod +++ b/modules/gha/go.mod @@ -20,9 +20,8 @@ require ( go.opentelemetry.io/proto/otlp v1.3.1 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa golang.org/x/mod v0.20.0 - golang.org/x/sync v0.8.0 + golang.org/x/sync v0.10.0 google.golang.org/grpc v1.65.0 - mvdan.cc/sh v2.6.4+incompatible ) require ( @@ -38,11 +37,9 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect go.opentelemetry.io/otel/metric v1.27.0 go.opentelemetry.io/otel/sdk/metric v1.27.0 - golang.org/x/crypto v0.27.0 // indirect golang.org/x/net v0.29.0 // indirect - golang.org/x/sys v0.26.0 // indirect - golang.org/x/term v0.24.0 // indirect - golang.org/x/text v0.18.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/protobuf v1.34.2 // indirect diff --git a/modules/gha/go.sum b/modules/gha/go.sum index da202f4c2a..d644f7d403 100644 --- a/modules/gha/go.sum +++ b/modules/gha/go.sum @@ -77,22 +77,18 @@ go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeX go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= -golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= @@ -109,5 +105,3 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -mvdan.cc/sh v2.6.4+incompatible h1:eD6tDeh0pw+/TOTI1BBEryZ02rD2nMcFsgcvde7jffM= -mvdan.cc/sh v2.6.4+incompatible/go.mod h1:IeeQbZq+x2SUGBensq/jge5lLQbS3XT2ktyp3wrt4x8= diff --git a/modules/go/go.mod b/modules/go/go.mod index b295210956..5281d04c0a 100644 --- a/modules/go/go.mod +++ b/modules/go/go.mod @@ -15,7 +15,7 @@ require ( go.opentelemetry.io/otel/sdk v1.27.0 go.opentelemetry.io/otel/trace v1.27.0 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa - golang.org/x/sync v0.8.0 + golang.org/x/sync v0.10.0 google.golang.org/grpc v1.65.0 ) @@ -45,8 +45,8 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.27.0 go.opentelemetry.io/proto/otlp v1.3.1 golang.org/x/net v0.29.0 // indirect - golang.org/x/sys v0.26.0 // indirect - golang.org/x/text v0.18.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/protobuf v1.34.2 // indirect diff --git a/modules/go/go.sum b/modules/go/go.sum index c6134aec70..fafeb418ff 100644 --- a/modules/go/go.sum +++ b/modules/go/go.sum @@ -82,13 +82,13 @@ golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= diff --git a/modules/golangci/go.mod b/modules/golangci/go.mod index 253e386328..96e024a8fe 100644 --- a/modules/golangci/go.mod +++ b/modules/golangci/go.mod @@ -1,11 +1,13 @@ module github.com/dagger/dagger/modules/golangci -go 1.22.4 +go 1.22.5 + +toolchain go1.23.2 require ( - github.com/99designs/gqlgen v0.17.49 + github.com/99designs/gqlgen v0.17.55 github.com/Khan/genqlient v0.7.0 - github.com/vektah/gqlparser/v2 v2.5.16 + github.com/vektah/gqlparser/v2 v2.5.17 go.opentelemetry.io/otel v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 @@ -17,24 +19,35 @@ require ( go.opentelemetry.io/otel/trace v1.27.0 go.opentelemetry.io/proto/otlp v1.3.1 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa - golang.org/x/sync v0.7.0 - google.golang.org/grpc v1.64.0 + golang.org/x/sync v0.10.0 + google.golang.org/grpc v1.65.0 ) require ( github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/sosodev/duration v1.3.1 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect - go.opentelemetry.io/otel/metric v1.27.0 // indirect - golang.org/x/net v0.26.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 // indirect - google.golang.org/protobuf v1.34.1 // indirect + go.opentelemetry.io/otel/metric v1.27.0 + go.opentelemetry.io/otel/sdk/metric v1.27.0 + golang.org/x/net v0.29.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/protobuf v1.34.2 // indirect ) + +replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 + +replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 + +replace go.opentelemetry.io/otel/log => go.opentelemetry.io/otel/log v0.3.0 + +replace go.opentelemetry.io/otel/sdk/log => go.opentelemetry.io/otel/sdk/log v0.3.0 diff --git a/modules/golangci/go.sum b/modules/golangci/go.sum index 6fea81b9cb..c146adf411 100644 --- a/modules/golangci/go.sum +++ b/modules/golangci/go.sum @@ -1,5 +1,5 @@ -github.com/99designs/gqlgen v0.17.49 h1:b3hNGexHd33fBSAd4NDT/c3NCcQzcAVkknhN9ym36YQ= -github.com/99designs/gqlgen v0.17.49/go.mod h1:tC8YFVZMed81x7UJ7ORUwXF4Kn6SXuucFqQBhN8+BU0= +github.com/99designs/gqlgen v0.17.55 h1:3vzrNWYyzSZjGDFo68e5j9sSauLxfKvLp+6ioRokVtM= +github.com/99designs/gqlgen v0.17.55/go.mod h1:3Bq768f8hgVPGZxL8aY9MaYmbxa6llPM/qu1IGH1EJo= github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= @@ -10,16 +10,16 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -33,14 +33,18 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0vy5p8= -github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= +github.com/vektah/gqlparser/v2 v2.5.17 h1:9At7WblLV7/36nulgekUgIaqHZWn5hxqluxrxGUhOmI= +github.com/vektah/gqlparser/v2 v2.5.17/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 h1:oM0GTNKGlc5qHctWeIGTVyda4iFFalOzMZ3Ehj5rwB4= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88/go.mod h1:JGG8ebaMO5nXOPnvKEl+DiA4MGwFjCbjsxT1WHIEBPY= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 h1:ccBrA8nCY5mM0y5uO7FT0ze4S0TuFcWdDB2FxGMTjkI= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0/go.mod h1:/9pb6634zi2Lk8LYg9Q0X8Ar6jka4dkFOylBLbVQPCE= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 h1:bFgvUr3/O4PHj3VQcFEuYKvRZJX1SJDQ+11JXuSB3/w= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0/go.mod h1:xJntEd2KL6Qdg5lwp97HMLQDVeAhrYxmzFseAMDPQ8I= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 h1:CIHWikMsN3wO+wq1Tp5VGdVRTcON+DmOJSfDjXypKOc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0/go.mod h1:TNupZ6cxqyFEpLXAZW7On+mLFL0/g0TE3unIYL91xWc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= @@ -55,6 +59,8 @@ go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kT go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= go.opentelemetry.io/otel/sdk/log v0.3.0 h1:GEjJ8iftz2l+XO1GF2856r7yYVh74URiF9JMcAacr5U= go.opentelemetry.io/otel/sdk/log v0.3.0/go.mod h1:BwCxtmux6ACLuys1wlbc0+vGBd+xytjmjajwqqIul2g= +go.opentelemetry.io/otel/sdk/metric v1.27.0 h1:5uGNOlpXi+Hbo/DRoI31BSb1v+OGcpv2NemcCrOL8gI= +go.opentelemetry.io/otel/sdk/metric v1.27.0/go.mod h1:we7jJVrYN2kh3mVBlswtPU22K0SA+769l93J6bsyvqw= go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= @@ -63,22 +69,22 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 h1:P8OJ/WCl/Xo4E4zoe4/bifHpSmmKwARqyqE4nW6J2GQ= -google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5/go.mod h1:RGnPtTG7r4i8sPlNyDeikXF99hMM+hN6QMm4ooG9g2g= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 h1:AgADTJarZTBqgjiUzRgfaBchgYB3/WFTC80GPwsMcRI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= -google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= -google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/modules/graphql/go.mod b/modules/graphql/go.mod index af1e873a08..465dfd8158 100644 --- a/modules/graphql/go.mod +++ b/modules/graphql/go.mod @@ -1,40 +1,53 @@ module github.com/dagger/dagger/modules/graphql -go 1.22 +go 1.22.5 + +toolchain go1.23.2 require ( - github.com/99designs/gqlgen v0.17.49 + github.com/99designs/gqlgen v0.17.55 github.com/Khan/genqlient v0.7.0 - github.com/vektah/gqlparser/v2 v2.5.16 + github.com/vektah/gqlparser/v2 v2.5.17 go.opentelemetry.io/otel v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 go.opentelemetry.io/otel/sdk v1.27.0 go.opentelemetry.io/otel/trace v1.27.0 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa - golang.org/x/sync v0.7.0 - google.golang.org/grpc v1.64.0 + golang.org/x/sync v0.10.0 + google.golang.org/grpc v1.65.0 ) require ( github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/sosodev/duration v1.3.1 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect go.opentelemetry.io/otel/log v0.3.0 - go.opentelemetry.io/otel/metric v1.27.0 // indirect + go.opentelemetry.io/otel/metric v1.27.0 go.opentelemetry.io/otel/sdk/log v0.3.0 + go.opentelemetry.io/otel/sdk/metric v1.27.0 go.opentelemetry.io/proto/otlp v1.3.1 - golang.org/x/net v0.26.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 // indirect - google.golang.org/protobuf v1.34.1 // indirect + golang.org/x/net v0.29.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/protobuf v1.34.2 // indirect ) + +replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 + +replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 + +replace go.opentelemetry.io/otel/log => go.opentelemetry.io/otel/log v0.3.0 + +replace go.opentelemetry.io/otel/sdk/log => go.opentelemetry.io/otel/sdk/log v0.3.0 diff --git a/modules/graphql/go.sum b/modules/graphql/go.sum index 6fea81b9cb..c146adf411 100644 --- a/modules/graphql/go.sum +++ b/modules/graphql/go.sum @@ -1,5 +1,5 @@ -github.com/99designs/gqlgen v0.17.49 h1:b3hNGexHd33fBSAd4NDT/c3NCcQzcAVkknhN9ym36YQ= -github.com/99designs/gqlgen v0.17.49/go.mod h1:tC8YFVZMed81x7UJ7ORUwXF4Kn6SXuucFqQBhN8+BU0= +github.com/99designs/gqlgen v0.17.55 h1:3vzrNWYyzSZjGDFo68e5j9sSauLxfKvLp+6ioRokVtM= +github.com/99designs/gqlgen v0.17.55/go.mod h1:3Bq768f8hgVPGZxL8aY9MaYmbxa6llPM/qu1IGH1EJo= github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= @@ -10,16 +10,16 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -33,14 +33,18 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0vy5p8= -github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= +github.com/vektah/gqlparser/v2 v2.5.17 h1:9At7WblLV7/36nulgekUgIaqHZWn5hxqluxrxGUhOmI= +github.com/vektah/gqlparser/v2 v2.5.17/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 h1:oM0GTNKGlc5qHctWeIGTVyda4iFFalOzMZ3Ehj5rwB4= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88/go.mod h1:JGG8ebaMO5nXOPnvKEl+DiA4MGwFjCbjsxT1WHIEBPY= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 h1:ccBrA8nCY5mM0y5uO7FT0ze4S0TuFcWdDB2FxGMTjkI= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0/go.mod h1:/9pb6634zi2Lk8LYg9Q0X8Ar6jka4dkFOylBLbVQPCE= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 h1:bFgvUr3/O4PHj3VQcFEuYKvRZJX1SJDQ+11JXuSB3/w= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0/go.mod h1:xJntEd2KL6Qdg5lwp97HMLQDVeAhrYxmzFseAMDPQ8I= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 h1:CIHWikMsN3wO+wq1Tp5VGdVRTcON+DmOJSfDjXypKOc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0/go.mod h1:TNupZ6cxqyFEpLXAZW7On+mLFL0/g0TE3unIYL91xWc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= @@ -55,6 +59,8 @@ go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kT go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= go.opentelemetry.io/otel/sdk/log v0.3.0 h1:GEjJ8iftz2l+XO1GF2856r7yYVh74URiF9JMcAacr5U= go.opentelemetry.io/otel/sdk/log v0.3.0/go.mod h1:BwCxtmux6ACLuys1wlbc0+vGBd+xytjmjajwqqIul2g= +go.opentelemetry.io/otel/sdk/metric v1.27.0 h1:5uGNOlpXi+Hbo/DRoI31BSb1v+OGcpv2NemcCrOL8gI= +go.opentelemetry.io/otel/sdk/metric v1.27.0/go.mod h1:we7jJVrYN2kh3mVBlswtPU22K0SA+769l93J6bsyvqw= go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= @@ -63,22 +69,22 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 h1:P8OJ/WCl/Xo4E4zoe4/bifHpSmmKwARqyqE4nW6J2GQ= -google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5/go.mod h1:RGnPtTG7r4i8sPlNyDeikXF99hMM+hN6QMm4ooG9g2g= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 h1:AgADTJarZTBqgjiUzRgfaBchgYB3/WFTC80GPwsMcRI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= -google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= -google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/modules/markdown/go.mod b/modules/markdown/go.mod index f47466cf79..9e17cd2cb6 100644 --- a/modules/markdown/go.mod +++ b/modules/markdown/go.mod @@ -1,40 +1,53 @@ module github.com/dagger/dagger/modules/markdown -go 1.22 +go 1.22.5 + +toolchain go1.23.2 require ( - github.com/99designs/gqlgen v0.17.49 + github.com/99designs/gqlgen v0.17.55 github.com/Khan/genqlient v0.7.0 - github.com/vektah/gqlparser/v2 v2.5.16 + github.com/vektah/gqlparser/v2 v2.5.17 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa - golang.org/x/sync v0.7.0 + golang.org/x/sync v0.10.0 ) require ( github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/sosodev/duration v1.3.1 // indirect go.opentelemetry.io/otel v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 go.opentelemetry.io/otel/log v0.3.0 - go.opentelemetry.io/otel/metric v1.27.0 // indirect + go.opentelemetry.io/otel/metric v1.27.0 go.opentelemetry.io/otel/sdk v1.27.0 go.opentelemetry.io/otel/sdk/log v0.3.0 + go.opentelemetry.io/otel/sdk/metric v1.27.0 go.opentelemetry.io/otel/trace v1.27.0 go.opentelemetry.io/proto/otlp v1.3.1 - golang.org/x/net v0.26.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 // indirect - google.golang.org/grpc v1.64.0 - google.golang.org/protobuf v1.34.1 // indirect + golang.org/x/net v0.29.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/grpc v1.65.0 + google.golang.org/protobuf v1.34.2 // indirect ) + +replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 + +replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 + +replace go.opentelemetry.io/otel/log => go.opentelemetry.io/otel/log v0.3.0 + +replace go.opentelemetry.io/otel/sdk/log => go.opentelemetry.io/otel/sdk/log v0.3.0 diff --git a/modules/markdown/go.sum b/modules/markdown/go.sum index 6fea81b9cb..c146adf411 100644 --- a/modules/markdown/go.sum +++ b/modules/markdown/go.sum @@ -1,5 +1,5 @@ -github.com/99designs/gqlgen v0.17.49 h1:b3hNGexHd33fBSAd4NDT/c3NCcQzcAVkknhN9ym36YQ= -github.com/99designs/gqlgen v0.17.49/go.mod h1:tC8YFVZMed81x7UJ7ORUwXF4Kn6SXuucFqQBhN8+BU0= +github.com/99designs/gqlgen v0.17.55 h1:3vzrNWYyzSZjGDFo68e5j9sSauLxfKvLp+6ioRokVtM= +github.com/99designs/gqlgen v0.17.55/go.mod h1:3Bq768f8hgVPGZxL8aY9MaYmbxa6llPM/qu1IGH1EJo= github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= @@ -10,16 +10,16 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -33,14 +33,18 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0vy5p8= -github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= +github.com/vektah/gqlparser/v2 v2.5.17 h1:9At7WblLV7/36nulgekUgIaqHZWn5hxqluxrxGUhOmI= +github.com/vektah/gqlparser/v2 v2.5.17/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 h1:oM0GTNKGlc5qHctWeIGTVyda4iFFalOzMZ3Ehj5rwB4= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88/go.mod h1:JGG8ebaMO5nXOPnvKEl+DiA4MGwFjCbjsxT1WHIEBPY= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 h1:ccBrA8nCY5mM0y5uO7FT0ze4S0TuFcWdDB2FxGMTjkI= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0/go.mod h1:/9pb6634zi2Lk8LYg9Q0X8Ar6jka4dkFOylBLbVQPCE= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 h1:bFgvUr3/O4PHj3VQcFEuYKvRZJX1SJDQ+11JXuSB3/w= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0/go.mod h1:xJntEd2KL6Qdg5lwp97HMLQDVeAhrYxmzFseAMDPQ8I= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 h1:CIHWikMsN3wO+wq1Tp5VGdVRTcON+DmOJSfDjXypKOc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0/go.mod h1:TNupZ6cxqyFEpLXAZW7On+mLFL0/g0TE3unIYL91xWc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= @@ -55,6 +59,8 @@ go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kT go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= go.opentelemetry.io/otel/sdk/log v0.3.0 h1:GEjJ8iftz2l+XO1GF2856r7yYVh74URiF9JMcAacr5U= go.opentelemetry.io/otel/sdk/log v0.3.0/go.mod h1:BwCxtmux6ACLuys1wlbc0+vGBd+xytjmjajwqqIul2g= +go.opentelemetry.io/otel/sdk/metric v1.27.0 h1:5uGNOlpXi+Hbo/DRoI31BSb1v+OGcpv2NemcCrOL8gI= +go.opentelemetry.io/otel/sdk/metric v1.27.0/go.mod h1:we7jJVrYN2kh3mVBlswtPU22K0SA+769l93J6bsyvqw= go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= @@ -63,22 +69,22 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 h1:P8OJ/WCl/Xo4E4zoe4/bifHpSmmKwARqyqE4nW6J2GQ= -google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5/go.mod h1:RGnPtTG7r4i8sPlNyDeikXF99hMM+hN6QMm4ooG9g2g= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 h1:AgADTJarZTBqgjiUzRgfaBchgYB3/WFTC80GPwsMcRI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= -google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= -google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/modules/ps-analyzer/go.mod b/modules/ps-analyzer/go.mod index e83b784fd9..887e565d7f 100644 --- a/modules/ps-analyzer/go.mod +++ b/modules/ps-analyzer/go.mod @@ -3,9 +3,9 @@ module github.com/dagger/dagger/modules/ps-analyzer go 1.22.5 require ( - github.com/99designs/gqlgen v0.17.49 + github.com/99designs/gqlgen v0.17.55 github.com/Khan/genqlient v0.7.0 - github.com/vektah/gqlparser/v2 v2.5.16 + github.com/vektah/gqlparser/v2 v2.5.17 go.opentelemetry.io/otel v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 @@ -17,24 +17,35 @@ require ( go.opentelemetry.io/otel/trace v1.27.0 go.opentelemetry.io/proto/otlp v1.3.1 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa - golang.org/x/sync v0.7.0 - google.golang.org/grpc v1.64.0 + golang.org/x/sync v0.10.0 + google.golang.org/grpc v1.65.0 ) require ( github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/sosodev/duration v1.3.1 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect - go.opentelemetry.io/otel/metric v1.27.0 // indirect - golang.org/x/net v0.26.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 // indirect - google.golang.org/protobuf v1.34.1 // indirect + go.opentelemetry.io/otel/metric v1.27.0 + go.opentelemetry.io/otel/sdk/metric v1.27.0 + golang.org/x/net v0.29.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/protobuf v1.34.2 // indirect ) + +replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 + +replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 + +replace go.opentelemetry.io/otel/log => go.opentelemetry.io/otel/log v0.3.0 + +replace go.opentelemetry.io/otel/sdk/log => go.opentelemetry.io/otel/sdk/log v0.3.0 diff --git a/modules/ps-analyzer/go.sum b/modules/ps-analyzer/go.sum index 6fea81b9cb..c146adf411 100644 --- a/modules/ps-analyzer/go.sum +++ b/modules/ps-analyzer/go.sum @@ -1,5 +1,5 @@ -github.com/99designs/gqlgen v0.17.49 h1:b3hNGexHd33fBSAd4NDT/c3NCcQzcAVkknhN9ym36YQ= -github.com/99designs/gqlgen v0.17.49/go.mod h1:tC8YFVZMed81x7UJ7ORUwXF4Kn6SXuucFqQBhN8+BU0= +github.com/99designs/gqlgen v0.17.55 h1:3vzrNWYyzSZjGDFo68e5j9sSauLxfKvLp+6ioRokVtM= +github.com/99designs/gqlgen v0.17.55/go.mod h1:3Bq768f8hgVPGZxL8aY9MaYmbxa6llPM/qu1IGH1EJo= github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= @@ -10,16 +10,16 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -33,14 +33,18 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0vy5p8= -github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= +github.com/vektah/gqlparser/v2 v2.5.17 h1:9At7WblLV7/36nulgekUgIaqHZWn5hxqluxrxGUhOmI= +github.com/vektah/gqlparser/v2 v2.5.17/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 h1:oM0GTNKGlc5qHctWeIGTVyda4iFFalOzMZ3Ehj5rwB4= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88/go.mod h1:JGG8ebaMO5nXOPnvKEl+DiA4MGwFjCbjsxT1WHIEBPY= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 h1:ccBrA8nCY5mM0y5uO7FT0ze4S0TuFcWdDB2FxGMTjkI= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0/go.mod h1:/9pb6634zi2Lk8LYg9Q0X8Ar6jka4dkFOylBLbVQPCE= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 h1:bFgvUr3/O4PHj3VQcFEuYKvRZJX1SJDQ+11JXuSB3/w= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0/go.mod h1:xJntEd2KL6Qdg5lwp97HMLQDVeAhrYxmzFseAMDPQ8I= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 h1:CIHWikMsN3wO+wq1Tp5VGdVRTcON+DmOJSfDjXypKOc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0/go.mod h1:TNupZ6cxqyFEpLXAZW7On+mLFL0/g0TE3unIYL91xWc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= @@ -55,6 +59,8 @@ go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kT go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= go.opentelemetry.io/otel/sdk/log v0.3.0 h1:GEjJ8iftz2l+XO1GF2856r7yYVh74URiF9JMcAacr5U= go.opentelemetry.io/otel/sdk/log v0.3.0/go.mod h1:BwCxtmux6ACLuys1wlbc0+vGBd+xytjmjajwqqIul2g= +go.opentelemetry.io/otel/sdk/metric v1.27.0 h1:5uGNOlpXi+Hbo/DRoI31BSb1v+OGcpv2NemcCrOL8gI= +go.opentelemetry.io/otel/sdk/metric v1.27.0/go.mod h1:we7jJVrYN2kh3mVBlswtPU22K0SA+769l93J6bsyvqw= go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= @@ -63,22 +69,22 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 h1:P8OJ/WCl/Xo4E4zoe4/bifHpSmmKwARqyqE4nW6J2GQ= -google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5/go.mod h1:RGnPtTG7r4i8sPlNyDeikXF99hMM+hN6QMm4ooG9g2g= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 h1:AgADTJarZTBqgjiUzRgfaBchgYB3/WFTC80GPwsMcRI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= -google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= -google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/modules/ruff/go.mod b/modules/ruff/go.mod index 5224c69fb3..4ed7b9f578 100644 --- a/modules/ruff/go.mod +++ b/modules/ruff/go.mod @@ -1,11 +1,13 @@ module github.com/dagger/dagger/modules/ruff -go 1.22.4 +go 1.22.5 + +toolchain go1.23.2 require ( - github.com/99designs/gqlgen v0.17.49 + github.com/99designs/gqlgen v0.17.55 github.com/Khan/genqlient v0.7.0 - github.com/vektah/gqlparser/v2 v2.5.16 + github.com/vektah/gqlparser/v2 v2.5.17 go.opentelemetry.io/otel v1.28.0 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240710190201-e8c22e6e7180 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.4.0 @@ -17,7 +19,7 @@ require ( go.opentelemetry.io/otel/trace v1.28.0 go.opentelemetry.io/proto/otlp v1.3.1 golang.org/x/exp v0.0.0-20240707233637-46b078467d37 - golang.org/x/sync v0.7.0 + golang.org/x/sync v0.10.0 google.golang.org/grpc v1.65.0 ) @@ -26,15 +28,26 @@ require ( github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/sosodev/duration v1.3.1 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect - go.opentelemetry.io/otel/metric v1.28.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240709173604-40e1e62336c5 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240709173604-40e1e62336c5 // indirect + go.opentelemetry.io/otel/metric v1.28.0 + go.opentelemetry.io/otel/sdk/metric v1.27.0 + golang.org/x/net v0.29.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/protobuf v1.34.2 // indirect ) + +replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 + +replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 + +replace go.opentelemetry.io/otel/log => go.opentelemetry.io/otel/log v0.3.0 + +replace go.opentelemetry.io/otel/sdk/log => go.opentelemetry.io/otel/sdk/log v0.3.0 diff --git a/modules/ruff/go.sum b/modules/ruff/go.sum index e37bf9ef1d..bb43c01bdc 100644 --- a/modules/ruff/go.sum +++ b/modules/ruff/go.sum @@ -1,5 +1,5 @@ -github.com/99designs/gqlgen v0.17.49 h1:b3hNGexHd33fBSAd4NDT/c3NCcQzcAVkknhN9ym36YQ= -github.com/99designs/gqlgen v0.17.49/go.mod h1:tC8YFVZMed81x7UJ7ORUwXF4Kn6SXuucFqQBhN8+BU0= +github.com/99designs/gqlgen v0.17.55 h1:3vzrNWYyzSZjGDFo68e5j9sSauLxfKvLp+6ioRokVtM= +github.com/99designs/gqlgen v0.17.55/go.mod h1:3Bq768f8hgVPGZxL8aY9MaYmbxa6llPM/qu1IGH1EJo= github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= @@ -18,8 +18,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -33,28 +33,34 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0vy5p8= -github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= +github.com/vektah/gqlparser/v2 v2.5.17 h1:9At7WblLV7/36nulgekUgIaqHZWn5hxqluxrxGUhOmI= +github.com/vektah/gqlparser/v2 v2.5.17/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240710190201-e8c22e6e7180 h1:kohQ8+q76VDzU6Q2D8jTqaWs8n3fhCKhIkTfA/cT8Vg= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240710190201-e8c22e6e7180/go.mod h1:2meBkGt4DIO3b5AyN1N4umHmWcamfMpN0KI8Ofr5+m0= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.4.0 h1:zBPZAISA9NOc5cE8zydqDiS0itvg/P/0Hn9m72a5gvM= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.4.0/go.mod h1:gcj2fFjEsqpV3fXuzAA+0Ze1p2/4MJ4T7d77AmkvueQ= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 h1:oM0GTNKGlc5qHctWeIGTVyda4iFFalOzMZ3Ehj5rwB4= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88/go.mod h1:JGG8ebaMO5nXOPnvKEl+DiA4MGwFjCbjsxT1WHIEBPY= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 h1:ccBrA8nCY5mM0y5uO7FT0ze4S0TuFcWdDB2FxGMTjkI= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0/go.mod h1:/9pb6634zi2Lk8LYg9Q0X8Ar6jka4dkFOylBLbVQPCE= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 h1:bFgvUr3/O4PHj3VQcFEuYKvRZJX1SJDQ+11JXuSB3/w= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0/go.mod h1:xJntEd2KL6Qdg5lwp97HMLQDVeAhrYxmzFseAMDPQ8I= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 h1:CIHWikMsN3wO+wq1Tp5VGdVRTcON+DmOJSfDjXypKOc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0/go.mod h1:TNupZ6cxqyFEpLXAZW7On+mLFL0/g0TE3unIYL91xWc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0 h1:j9+03ymgYhPKmeXGk5Zu+cIZOlVzd9Zv7QIiyItjFBU= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0/go.mod h1:Y5+XiUG4Emn1hTfciPzGPJaSI+RpDts6BnCIir0SLqk= -go.opentelemetry.io/otel/log v0.4.0 h1:/vZ+3Utqh18e8TPjuc3ecg284078KWrR8BRz+PQAj3o= -go.opentelemetry.io/otel/log v0.4.0/go.mod h1:DhGnQvky7pHy82MIRV43iXh3FlKN8UUKftn0KbLOq6I= +go.opentelemetry.io/otel/log v0.3.0 h1:kJRFkpUFYtny37NQzL386WbznUByZx186DpEMKhEGZs= +go.opentelemetry.io/otel/log v0.3.0/go.mod h1:ziCwqZr9soYDwGNbIL+6kAvQC+ANvjgG367HVcyR/ys= go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= -go.opentelemetry.io/otel/sdk/log v0.4.0 h1:1mMI22L82zLqf6KtkjrRy5BbagOTWdJsqMY/HSqILAA= -go.opentelemetry.io/otel/sdk/log v0.4.0/go.mod h1:AYJ9FVF0hNOgAVzUG/ybg/QttnXhUePWAupmCqtdESo= +go.opentelemetry.io/otel/sdk/log v0.3.0 h1:GEjJ8iftz2l+XO1GF2856r7yYVh74URiF9JMcAacr5U= +go.opentelemetry.io/otel/sdk/log v0.3.0/go.mod h1:BwCxtmux6ACLuys1wlbc0+vGBd+xytjmjajwqqIul2g= +go.opentelemetry.io/otel/sdk/metric v1.27.0 h1:5uGNOlpXi+Hbo/DRoI31BSb1v+OGcpv2NemcCrOL8gI= +go.opentelemetry.io/otel/sdk/metric v1.27.0/go.mod h1:we7jJVrYN2kh3mVBlswtPU22K0SA+769l93J6bsyvqw= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= @@ -63,18 +69,18 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -google.golang.org/genproto/googleapis/api v0.0.0-20240709173604-40e1e62336c5 h1:a/Z0jgw03aJ2rQnp5PlPpznJqJft0HyvyrcUcxgzPwY= -google.golang.org/genproto/googleapis/api v0.0.0-20240709173604-40e1e62336c5/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240709173604-40e1e62336c5 h1:SbSDUWW1PAO24TNpLdeheoYPd7kllICcLU52x6eD4kQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240709173604-40e1e62336c5/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= diff --git a/modules/shellcheck/go.mod b/modules/shellcheck/go.mod index 0f98e6c2a3..8f951a389c 100644 --- a/modules/shellcheck/go.mod +++ b/modules/shellcheck/go.mod @@ -1,11 +1,13 @@ module github.com/dagger/dagger/modules/shellcheck -go 1.22 +go 1.22.5 + +toolchain go1.23.2 require ( - github.com/99designs/gqlgen v0.17.49 + github.com/99designs/gqlgen v0.17.55 github.com/Khan/genqlient v0.7.0 - github.com/vektah/gqlparser/v2 v2.5.16 + github.com/vektah/gqlparser/v2 v2.5.17 go.opentelemetry.io/otel v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 @@ -13,8 +15,8 @@ require ( go.opentelemetry.io/otel/trace v1.27.0 go.opentelemetry.io/proto/otlp v1.3.1 golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 - golang.org/x/sync v0.7.0 - google.golang.org/grpc v1.64.0 + golang.org/x/sync v0.10.0 + google.golang.org/grpc v1.65.0 ) require github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect @@ -24,18 +26,29 @@ require ( github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/sosodev/duration v1.3.1 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect go.opentelemetry.io/otel/log v0.3.0 - go.opentelemetry.io/otel/metric v1.27.0 // indirect + go.opentelemetry.io/otel/metric v1.27.0 go.opentelemetry.io/otel/sdk/log v0.3.0 - golang.org/x/net v0.26.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect - google.golang.org/protobuf v1.34.1 // indirect + go.opentelemetry.io/otel/sdk/metric v1.27.0 + golang.org/x/net v0.29.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/protobuf v1.34.2 // indirect ) + +replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 + +replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 + +replace go.opentelemetry.io/otel/log => go.opentelemetry.io/otel/log v0.3.0 + +replace go.opentelemetry.io/otel/sdk/log => go.opentelemetry.io/otel/sdk/log v0.3.0 diff --git a/modules/shellcheck/go.sum b/modules/shellcheck/go.sum index 3e77d8bf59..1f49d52630 100644 --- a/modules/shellcheck/go.sum +++ b/modules/shellcheck/go.sum @@ -1,5 +1,5 @@ -github.com/99designs/gqlgen v0.17.49 h1:b3hNGexHd33fBSAd4NDT/c3NCcQzcAVkknhN9ym36YQ= -github.com/99designs/gqlgen v0.17.49/go.mod h1:tC8YFVZMed81x7UJ7ORUwXF4Kn6SXuucFqQBhN8+BU0= +github.com/99designs/gqlgen v0.17.55 h1:3vzrNWYyzSZjGDFo68e5j9sSauLxfKvLp+6ioRokVtM= +github.com/99designs/gqlgen v0.17.55/go.mod h1:3Bq768f8hgVPGZxL8aY9MaYmbxa6llPM/qu1IGH1EJo= github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= @@ -18,8 +18,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -33,14 +33,18 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0vy5p8= -github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= +github.com/vektah/gqlparser/v2 v2.5.17 h1:9At7WblLV7/36nulgekUgIaqHZWn5hxqluxrxGUhOmI= +github.com/vektah/gqlparser/v2 v2.5.17/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 h1:oM0GTNKGlc5qHctWeIGTVyda4iFFalOzMZ3Ehj5rwB4= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88/go.mod h1:JGG8ebaMO5nXOPnvKEl+DiA4MGwFjCbjsxT1WHIEBPY= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 h1:ccBrA8nCY5mM0y5uO7FT0ze4S0TuFcWdDB2FxGMTjkI= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0/go.mod h1:/9pb6634zi2Lk8LYg9Q0X8Ar6jka4dkFOylBLbVQPCE= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 h1:bFgvUr3/O4PHj3VQcFEuYKvRZJX1SJDQ+11JXuSB3/w= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0/go.mod h1:xJntEd2KL6Qdg5lwp97HMLQDVeAhrYxmzFseAMDPQ8I= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 h1:CIHWikMsN3wO+wq1Tp5VGdVRTcON+DmOJSfDjXypKOc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0/go.mod h1:TNupZ6cxqyFEpLXAZW7On+mLFL0/g0TE3unIYL91xWc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= @@ -55,6 +59,8 @@ go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kT go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= go.opentelemetry.io/otel/sdk/log v0.3.0 h1:GEjJ8iftz2l+XO1GF2856r7yYVh74URiF9JMcAacr5U= go.opentelemetry.io/otel/sdk/log v0.3.0/go.mod h1:BwCxtmux6ACLuys1wlbc0+vGBd+xytjmjajwqqIul2g= +go.opentelemetry.io/otel/sdk/metric v1.27.0 h1:5uGNOlpXi+Hbo/DRoI31BSb1v+OGcpv2NemcCrOL8gI= +go.opentelemetry.io/otel/sdk/metric v1.27.0/go.mod h1:we7jJVrYN2kh3mVBlswtPU22K0SA+769l93J6bsyvqw= go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= @@ -63,22 +69,22 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 h1:LoYXNGAShUG3m/ehNk4iFctuhGX/+R1ZpfJ4/ia80JM= golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 h1:P8OJ/WCl/Xo4E4zoe4/bifHpSmmKwARqyqE4nW6J2GQ= -google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5/go.mod h1:RGnPtTG7r4i8sPlNyDeikXF99hMM+hN6QMm4ooG9g2g= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 h1:1GBuWVLM/KMVUv1t1En5Gs+gFZCNd360GGb4sSxtrhU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= -google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= -google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/modules/wolfi/go.mod b/modules/wolfi/go.mod index 0d295107a6..b7d02cc029 100644 --- a/modules/wolfi/go.mod +++ b/modules/wolfi/go.mod @@ -1,18 +1,20 @@ module github.com/dagger/dagger/modules/wolfi -go 1.22 +go 1.22.5 + +toolchain go1.23.2 require ( - github.com/99designs/gqlgen v0.17.49 + github.com/99designs/gqlgen v0.17.55 github.com/Khan/genqlient v0.7.0 - github.com/vektah/gqlparser/v2 v2.5.16 + github.com/vektah/gqlparser/v2 v2.5.17 go.opentelemetry.io/otel v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 go.opentelemetry.io/otel/sdk v1.27.0 go.opentelemetry.io/otel/trace v1.27.0 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa - golang.org/x/sync v0.8.0 + golang.org/x/sync v0.10.0 google.golang.org/grpc v1.65.0 ) @@ -26,14 +28,17 @@ require ( github.com/sosodev/duration v1.3.1 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect go.opentelemetry.io/otel/log v0.3.0 - go.opentelemetry.io/otel/metric v1.27.0 // indirect + go.opentelemetry.io/otel/metric v1.27.0 go.opentelemetry.io/otel/sdk/log v0.3.0 + go.opentelemetry.io/otel/sdk/metric v1.27.0 go.opentelemetry.io/proto/otlp v1.3.1 golang.org/x/net v0.29.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/text v0.18.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/protobuf v1.34.2 // indirect diff --git a/modules/wolfi/go.sum b/modules/wolfi/go.sum index cd12295fa0..c146adf411 100644 --- a/modules/wolfi/go.sum +++ b/modules/wolfi/go.sum @@ -1,5 +1,5 @@ -github.com/99designs/gqlgen v0.17.49 h1:b3hNGexHd33fBSAd4NDT/c3NCcQzcAVkknhN9ym36YQ= -github.com/99designs/gqlgen v0.17.49/go.mod h1:tC8YFVZMed81x7UJ7ORUwXF4Kn6SXuucFqQBhN8+BU0= +github.com/99designs/gqlgen v0.17.55 h1:3vzrNWYyzSZjGDFo68e5j9sSauLxfKvLp+6ioRokVtM= +github.com/99designs/gqlgen v0.17.55/go.mod h1:3Bq768f8hgVPGZxL8aY9MaYmbxa6llPM/qu1IGH1EJo= github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= @@ -33,14 +33,18 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0vy5p8= -github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= +github.com/vektah/gqlparser/v2 v2.5.17 h1:9At7WblLV7/36nulgekUgIaqHZWn5hxqluxrxGUhOmI= +github.com/vektah/gqlparser/v2 v2.5.17/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 h1:oM0GTNKGlc5qHctWeIGTVyda4iFFalOzMZ3Ehj5rwB4= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88/go.mod h1:JGG8ebaMO5nXOPnvKEl+DiA4MGwFjCbjsxT1WHIEBPY= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 h1:ccBrA8nCY5mM0y5uO7FT0ze4S0TuFcWdDB2FxGMTjkI= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0/go.mod h1:/9pb6634zi2Lk8LYg9Q0X8Ar6jka4dkFOylBLbVQPCE= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 h1:bFgvUr3/O4PHj3VQcFEuYKvRZJX1SJDQ+11JXuSB3/w= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0/go.mod h1:xJntEd2KL6Qdg5lwp97HMLQDVeAhrYxmzFseAMDPQ8I= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 h1:CIHWikMsN3wO+wq1Tp5VGdVRTcON+DmOJSfDjXypKOc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0/go.mod h1:TNupZ6cxqyFEpLXAZW7On+mLFL0/g0TE3unIYL91xWc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= @@ -55,6 +59,8 @@ go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kT go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= go.opentelemetry.io/otel/sdk/log v0.3.0 h1:GEjJ8iftz2l+XO1GF2856r7yYVh74URiF9JMcAacr5U= go.opentelemetry.io/otel/sdk/log v0.3.0/go.mod h1:BwCxtmux6ACLuys1wlbc0+vGBd+xytjmjajwqqIul2g= +go.opentelemetry.io/otel/sdk/metric v1.27.0 h1:5uGNOlpXi+Hbo/DRoI31BSb1v+OGcpv2NemcCrOL8gI= +go.opentelemetry.io/otel/sdk/metric v1.27.0/go.mod h1:we7jJVrYN2kh3mVBlswtPU22K0SA+769l93J6bsyvqw= go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= @@ -65,12 +71,12 @@ golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= diff --git a/releaser/.dagger/go.mod b/releaser/.dagger/go.mod index 8aca7a48f9..7c7cb0845e 100644 --- a/releaser/.dagger/go.mod +++ b/releaser/.dagger/go.mod @@ -9,11 +9,15 @@ require ( go.opentelemetry.io/otel v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 go.opentelemetry.io/otel/log v0.3.0 + go.opentelemetry.io/otel/metric v1.27.0 go.opentelemetry.io/otel/sdk v1.27.0 go.opentelemetry.io/otel/sdk/log v0.3.0 + go.opentelemetry.io/otel/sdk/metric v1.27.0 go.opentelemetry.io/otel/trace v1.27.0 go.opentelemetry.io/proto/otlp v1.3.1 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa @@ -27,14 +31,9 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect - github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/sosodev/duration v1.3.1 // indirect github.com/stretchr/testify v1.10.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect - go.opentelemetry.io/otel/metric v1.27.0 - go.opentelemetry.io/otel/sdk/metric v1.27.0 golang.org/x/net v0.29.0 // indirect golang.org/x/sys v0.26.0 // indirect golang.org/x/text v0.19.0 // indirect diff --git a/releaser/.dagger/go.sum b/releaser/.dagger/go.sum index 29dbd85d93..1a42fe2331 100644 --- a/releaser/.dagger/go.sum +++ b/releaser/.dagger/go.sum @@ -6,7 +6,6 @@ github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNg github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -22,17 +21,12 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq4= github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/vektah/gqlparser/v2 v2.5.19 h1:bhCPCX1D4WWzCDvkPl4+TP1N8/kLrWnp43egplt7iSg= @@ -87,9 +81,5 @@ google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0= google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA= google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/sdk/elixir/runtime/go.mod b/sdk/elixir/runtime/go.mod index eda0c6b21d..edc6669140 100644 --- a/sdk/elixir/runtime/go.mod +++ b/sdk/elixir/runtime/go.mod @@ -1,43 +1,48 @@ module elixir-sdk -go 1.22 +go 1.22.7 -require ( - github.com/99designs/gqlgen v0.17.49 - github.com/Khan/genqlient v0.7.0 - github.com/vektah/gqlparser/v2 v2.5.16 - golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa - golang.org/x/sync v0.7.0 -) +toolchain go1.23.2 require ( - github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/go-logr/logr v1.4.1 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/google/uuid v1.6.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/99designs/gqlgen v0.17.57 + github.com/Khan/genqlient v0.7.0 github.com/iancoleman/strcase v0.3.0 - github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect - github.com/sosodev/duration v1.3.1 // indirect + github.com/vektah/gqlparser/v2 v2.5.19 go.opentelemetry.io/otel v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 go.opentelemetry.io/otel/log v0.3.0 - go.opentelemetry.io/otel/metric v1.27.0 // indirect + go.opentelemetry.io/otel/metric v1.27.0 go.opentelemetry.io/otel/sdk v1.27.0 go.opentelemetry.io/otel/sdk/log v0.3.0 + go.opentelemetry.io/otel/sdk/metric v1.27.0 go.opentelemetry.io/otel/trace v1.27.0 go.opentelemetry.io/proto/otlp v1.3.1 - golang.org/x/net v0.26.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 // indirect - google.golang.org/grpc v1.64.0 - google.golang.org/protobuf v1.34.1 // indirect + golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa + golang.org/x/sync v0.9.0 + google.golang.org/grpc v1.68.0 +) + +require ( + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect + github.com/sosodev/duration v1.3.1 // indirect + github.com/stretchr/testify v1.10.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect + golang.org/x/net v0.29.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/text v0.19.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect + google.golang.org/protobuf v1.35.2 // indirect ) replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 diff --git a/sdk/elixir/runtime/go.sum b/sdk/elixir/runtime/go.sum index 07ad1cc884..c773637ad6 100644 --- a/sdk/elixir/runtime/go.sum +++ b/sdk/elixir/runtime/go.sum @@ -1,48 +1,48 @@ -github.com/99designs/gqlgen v0.17.49 h1:b3hNGexHd33fBSAd4NDT/c3NCcQzcAVkknhN9ym36YQ= -github.com/99designs/gqlgen v0.17.49/go.mod h1:tC8YFVZMed81x7UJ7ORUwXF4Kn6SXuucFqQBhN8+BU0= +github.com/99designs/gqlgen v0.17.57 h1:Ak4p60BRq6QibxY0lEc0JnQhDurfhxA67sp02lMjmPc= +github.com/99designs/gqlgen v0.17.57/go.mod h1:Jx61hzOSTcR4VJy/HFIgXiQ5rJ0Ypw8DxWLjbYDAUw0= github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq4= github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0vy5p8= -github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/vektah/gqlparser/v2 v2.5.19 h1:bhCPCX1D4WWzCDvkPl4+TP1N8/kLrWnp43egplt7iSg= +github.com/vektah/gqlparser/v2 v2.5.19/go.mod h1:y7kvl5bBlDeuWIvLtA9849ncyvx6/lj06RsMrEjVy3U= go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 h1:oM0GTNKGlc5qHctWeIGTVyda4iFFalOzMZ3Ehj5rwB4= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88/go.mod h1:JGG8ebaMO5nXOPnvKEl+DiA4MGwFjCbjsxT1WHIEBPY= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 h1:ccBrA8nCY5mM0y5uO7FT0ze4S0TuFcWdDB2FxGMTjkI= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0/go.mod h1:/9pb6634zi2Lk8LYg9Q0X8Ar6jka4dkFOylBLbVQPCE= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 h1:bFgvUr3/O4PHj3VQcFEuYKvRZJX1SJDQ+11JXuSB3/w= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0/go.mod h1:xJntEd2KL6Qdg5lwp97HMLQDVeAhrYxmzFseAMDPQ8I= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 h1:CIHWikMsN3wO+wq1Tp5VGdVRTcON+DmOJSfDjXypKOc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0/go.mod h1:TNupZ6cxqyFEpLXAZW7On+mLFL0/g0TE3unIYL91xWc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= @@ -57,6 +57,8 @@ go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kT go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= go.opentelemetry.io/otel/sdk/log v0.3.0 h1:GEjJ8iftz2l+XO1GF2856r7yYVh74URiF9JMcAacr5U= go.opentelemetry.io/otel/sdk/log v0.3.0/go.mod h1:BwCxtmux6ACLuys1wlbc0+vGBd+xytjmjajwqqIul2g= +go.opentelemetry.io/otel/sdk/metric v1.27.0 h1:5uGNOlpXi+Hbo/DRoI31BSb1v+OGcpv2NemcCrOL8gI= +go.opentelemetry.io/otel/sdk/metric v1.27.0/go.mod h1:we7jJVrYN2kh3mVBlswtPU22K0SA+769l93J6bsyvqw= go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= @@ -65,25 +67,21 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 h1:P8OJ/WCl/Xo4E4zoe4/bifHpSmmKwARqyqE4nW6J2GQ= -google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5/go.mod h1:RGnPtTG7r4i8sPlNyDeikXF99hMM+hN6QMm4ooG9g2g= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 h1:AgADTJarZTBqgjiUzRgfaBchgYB3/WFTC80GPwsMcRI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= -google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= -google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= +google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0= +google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA= +google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= +google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/sdk/go/go.mod b/sdk/go/go.mod index 0b5cd4ae03..dd9e7f3a29 100644 --- a/sdk/go/go.mod +++ b/sdk/go/go.mod @@ -33,7 +33,7 @@ require ( go.opentelemetry.io/otel/trace v1.27.0 go.opentelemetry.io/proto/otlp v1.3.1 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa - golang.org/x/sync v0.9.0 + golang.org/x/sync v0.10.0 google.golang.org/grpc v1.68.0 ) @@ -48,8 +48,8 @@ require ( github.com/sosodev/duration v1.3.1 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect golang.org/x/net v0.29.0 // indirect - golang.org/x/sys v0.26.0 // indirect - golang.org/x/text v0.19.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect google.golang.org/protobuf v1.35.2 // indirect diff --git a/sdk/go/go.sum b/sdk/go/go.sum index 491b1176ac..a9cc754275 100644 --- a/sdk/go/go.sum +++ b/sdk/go/go.sum @@ -77,12 +77,12 @@ golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= -golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= diff --git a/sdk/php/runtime/go.mod b/sdk/php/runtime/go.mod index 2cd188b771..ddc6ddfe32 100644 --- a/sdk/php/runtime/go.mod +++ b/sdk/php/runtime/go.mod @@ -3,22 +3,26 @@ module php-sdk go 1.23.1 require ( - github.com/99designs/gqlgen v0.17.49 + github.com/99designs/gqlgen v0.17.57 github.com/Khan/genqlient v0.7.0 - github.com/vektah/gqlparser/v2 v2.5.16 + github.com/vektah/gqlparser/v2 v2.5.19 go.opentelemetry.io/otel v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 go.opentelemetry.io/otel/log v0.3.0 + go.opentelemetry.io/otel/metric v1.27.0 go.opentelemetry.io/otel/sdk v1.27.0 go.opentelemetry.io/otel/sdk/log v0.3.0 + go.opentelemetry.io/otel/sdk/metric v1.27.0 go.opentelemetry.io/otel/trace v1.27.0 go.opentelemetry.io/proto/otlp v1.3.1 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa - golang.org/x/sync v0.8.0 - google.golang.org/grpc v1.65.0 + golang.org/x/sync v0.9.0 + google.golang.org/grpc v1.68.0 ) require ( @@ -27,16 +31,15 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect - github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/sosodev/duration v1.3.1 // indirect + github.com/stretchr/testify v1.10.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect - go.opentelemetry.io/otel/metric v1.27.0 // indirect golang.org/x/net v0.29.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/text v0.18.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect - google.golang.org/protobuf v1.34.2 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/text v0.19.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect + google.golang.org/protobuf v1.35.2 // indirect ) replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 diff --git a/sdk/php/runtime/go.sum b/sdk/php/runtime/go.sum index cd12295fa0..1a42fe2331 100644 --- a/sdk/php/runtime/go.sum +++ b/sdk/php/runtime/go.sum @@ -1,12 +1,11 @@ -github.com/99designs/gqlgen v0.17.49 h1:b3hNGexHd33fBSAd4NDT/c3NCcQzcAVkknhN9ym36YQ= -github.com/99designs/gqlgen v0.17.49/go.mod h1:tC8YFVZMed81x7UJ7ORUwXF4Kn6SXuucFqQBhN8+BU0= +github.com/99designs/gqlgen v0.17.57 h1:Ak4p60BRq6QibxY0lEc0JnQhDurfhxA67sp02lMjmPc= +github.com/99designs/gqlgen v0.17.57/go.mod h1:Jx61hzOSTcR4VJy/HFIgXiQ5rJ0Ypw8DxWLjbYDAUw0= github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -14,33 +13,34 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq4= github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0vy5p8= -github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/vektah/gqlparser/v2 v2.5.19 h1:bhCPCX1D4WWzCDvkPl4+TP1N8/kLrWnp43egplt7iSg= +github.com/vektah/gqlparser/v2 v2.5.19/go.mod h1:y7kvl5bBlDeuWIvLtA9849ncyvx6/lj06RsMrEjVy3U= go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 h1:oM0GTNKGlc5qHctWeIGTVyda4iFFalOzMZ3Ehj5rwB4= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88/go.mod h1:JGG8ebaMO5nXOPnvKEl+DiA4MGwFjCbjsxT1WHIEBPY= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 h1:ccBrA8nCY5mM0y5uO7FT0ze4S0TuFcWdDB2FxGMTjkI= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0/go.mod h1:/9pb6634zi2Lk8LYg9Q0X8Ar6jka4dkFOylBLbVQPCE= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 h1:bFgvUr3/O4PHj3VQcFEuYKvRZJX1SJDQ+11JXuSB3/w= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0/go.mod h1:xJntEd2KL6Qdg5lwp97HMLQDVeAhrYxmzFseAMDPQ8I= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 h1:CIHWikMsN3wO+wq1Tp5VGdVRTcON+DmOJSfDjXypKOc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0/go.mod h1:TNupZ6cxqyFEpLXAZW7On+mLFL0/g0TE3unIYL91xWc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= @@ -55,6 +55,8 @@ go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kT go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= go.opentelemetry.io/otel/sdk/log v0.3.0 h1:GEjJ8iftz2l+XO1GF2856r7yYVh74URiF9JMcAacr5U= go.opentelemetry.io/otel/sdk/log v0.3.0/go.mod h1:BwCxtmux6ACLuys1wlbc0+vGBd+xytjmjajwqqIul2g= +go.opentelemetry.io/otel/sdk/metric v1.27.0 h1:5uGNOlpXi+Hbo/DRoI31BSb1v+OGcpv2NemcCrOL8gI= +go.opentelemetry.io/otel/sdk/metric v1.27.0/go.mod h1:we7jJVrYN2kh3mVBlswtPU22K0SA+769l93J6bsyvqw= go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= @@ -65,23 +67,19 @@ golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= -google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= -google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= +google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0= +google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA= +google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= +google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/sdk/python/runtime/go.mod b/sdk/python/runtime/go.mod index 4f69809764..894bdab5e2 100644 --- a/sdk/python/runtime/go.mod +++ b/sdk/python/runtime/go.mod @@ -33,16 +33,13 @@ require ( go.opentelemetry.io/otel v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 go.opentelemetry.io/otel/log v0.3.0 - go.opentelemetry.io/otel/metric v1.27.0 + go.opentelemetry.io/otel/metric v1.27.0 // indirect go.opentelemetry.io/otel/sdk v1.27.0 go.opentelemetry.io/otel/sdk/log v0.3.0 - go.opentelemetry.io/otel/sdk/metric v1.27.0 go.opentelemetry.io/otel/trace v1.27.0 go.opentelemetry.io/proto/otlp v1.3.1 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa diff --git a/sdk/python/runtime/go.sum b/sdk/python/runtime/go.sum index 492161766c..58a68996e3 100644 --- a/sdk/python/runtime/go.sum +++ b/sdk/python/runtime/go.sum @@ -60,10 +60,6 @@ go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-2024051809000 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88/go.mod h1:JGG8ebaMO5nXOPnvKEl+DiA4MGwFjCbjsxT1WHIEBPY= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 h1:ccBrA8nCY5mM0y5uO7FT0ze4S0TuFcWdDB2FxGMTjkI= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0/go.mod h1:/9pb6634zi2Lk8LYg9Q0X8Ar6jka4dkFOylBLbVQPCE= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 h1:bFgvUr3/O4PHj3VQcFEuYKvRZJX1SJDQ+11JXuSB3/w= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0/go.mod h1:xJntEd2KL6Qdg5lwp97HMLQDVeAhrYxmzFseAMDPQ8I= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 h1:CIHWikMsN3wO+wq1Tp5VGdVRTcON+DmOJSfDjXypKOc= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0/go.mod h1:TNupZ6cxqyFEpLXAZW7On+mLFL0/g0TE3unIYL91xWc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= @@ -78,8 +74,6 @@ go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kT go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= go.opentelemetry.io/otel/sdk/log v0.3.0 h1:GEjJ8iftz2l+XO1GF2856r7yYVh74URiF9JMcAacr5U= go.opentelemetry.io/otel/sdk/log v0.3.0/go.mod h1:BwCxtmux6ACLuys1wlbc0+vGBd+xytjmjajwqqIul2g= -go.opentelemetry.io/otel/sdk/metric v1.27.0 h1:5uGNOlpXi+Hbo/DRoI31BSb1v+OGcpv2NemcCrOL8gI= -go.opentelemetry.io/otel/sdk/metric v1.27.0/go.mod h1:we7jJVrYN2kh3mVBlswtPU22K0SA+769l93J6bsyvqw= go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= diff --git a/sdk/typescript/runtime/go.mod b/sdk/typescript/runtime/go.mod index bea51ca228..b0bc905237 100644 --- a/sdk/typescript/runtime/go.mod +++ b/sdk/typescript/runtime/go.mod @@ -1,45 +1,53 @@ module main -go 1.22 +go 1.22.7 + +toolchain go1.23.2 + +require github.com/iancoleman/strcase v0.3.0 require ( - github.com/99designs/gqlgen v0.17.49 + github.com/99designs/gqlgen v0.17.57 github.com/Khan/genqlient v0.7.0 - github.com/iancoleman/strcase v0.3.0 - github.com/tidwall/gjson v1.17.1 - github.com/vektah/gqlparser/v2 v2.5.16 + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect + github.com/sosodev/duration v1.3.1 // indirect + github.com/stretchr/testify v1.10.0 // indirect + github.com/vektah/gqlparser/v2 v2.5.19 go.opentelemetry.io/otel v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 go.opentelemetry.io/otel/log v0.3.0 + go.opentelemetry.io/otel/metric v1.27.0 go.opentelemetry.io/otel/sdk v1.27.0 go.opentelemetry.io/otel/sdk/log v0.3.0 + go.opentelemetry.io/otel/sdk/metric v1.27.0 go.opentelemetry.io/otel/trace v1.27.0 go.opentelemetry.io/proto/otlp v1.3.1 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa - golang.org/x/sync v0.7.0 - google.golang.org/grpc v1.64.0 + golang.org/x/mod v0.20.0 + golang.org/x/net v0.29.0 // indirect + golang.org/x/sync v0.9.0 + golang.org/x/sys v0.26.0 // indirect + golang.org/x/text v0.19.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect + google.golang.org/grpc v1.68.0 + google.golang.org/protobuf v1.35.2 // indirect ) -require ( - github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/go-logr/logr v1.4.1 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/google/uuid v1.6.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect - github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect - github.com/sosodev/duration v1.3.1 // indirect - github.com/tidwall/match v1.1.1 // indirect - github.com/tidwall/pretty v1.2.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect - go.opentelemetry.io/otel/metric v1.27.0 // indirect - golang.org/x/mod v0.19.0 - golang.org/x/net v0.26.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 // indirect - google.golang.org/protobuf v1.34.1 // indirect -) +replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 + +replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp => go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 + +replace go.opentelemetry.io/otel/log => go.opentelemetry.io/otel/log v0.3.0 + +replace go.opentelemetry.io/otel/sdk/log => go.opentelemetry.io/otel/sdk/log v0.3.0 diff --git a/sdk/typescript/runtime/go.sum b/sdk/typescript/runtime/go.sum index c591b4b2a4..7cbbd318a8 100644 --- a/sdk/typescript/runtime/go.sum +++ b/sdk/typescript/runtime/go.sum @@ -1,54 +1,48 @@ -github.com/99designs/gqlgen v0.17.49 h1:b3hNGexHd33fBSAd4NDT/c3NCcQzcAVkknhN9ym36YQ= -github.com/99designs/gqlgen v0.17.49/go.mod h1:tC8YFVZMed81x7UJ7ORUwXF4Kn6SXuucFqQBhN8+BU0= +github.com/99designs/gqlgen v0.17.57 h1:Ak4p60BRq6QibxY0lEc0JnQhDurfhxA67sp02lMjmPc= +github.com/99designs/gqlgen v0.17.57/go.mod h1:Jx61hzOSTcR4VJy/HFIgXiQ5rJ0Ypw8DxWLjbYDAUw0= github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq4= github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U= -github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= -github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= -github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0vy5p8= -github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/vektah/gqlparser/v2 v2.5.19 h1:bhCPCX1D4WWzCDvkPl4+TP1N8/kLrWnp43egplt7iSg= +github.com/vektah/gqlparser/v2 v2.5.19/go.mod h1:y7kvl5bBlDeuWIvLtA9849ncyvx6/lj06RsMrEjVy3U= go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 h1:oM0GTNKGlc5qHctWeIGTVyda4iFFalOzMZ3Ehj5rwB4= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88/go.mod h1:JGG8ebaMO5nXOPnvKEl+DiA4MGwFjCbjsxT1WHIEBPY= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 h1:ccBrA8nCY5mM0y5uO7FT0ze4S0TuFcWdDB2FxGMTjkI= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0/go.mod h1:/9pb6634zi2Lk8LYg9Q0X8Ar6jka4dkFOylBLbVQPCE= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 h1:bFgvUr3/O4PHj3VQcFEuYKvRZJX1SJDQ+11JXuSB3/w= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0/go.mod h1:xJntEd2KL6Qdg5lwp97HMLQDVeAhrYxmzFseAMDPQ8I= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 h1:CIHWikMsN3wO+wq1Tp5VGdVRTcON+DmOJSfDjXypKOc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0/go.mod h1:TNupZ6cxqyFEpLXAZW7On+mLFL0/g0TE3unIYL91xWc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= @@ -63,6 +57,8 @@ go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kT go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= go.opentelemetry.io/otel/sdk/log v0.3.0 h1:GEjJ8iftz2l+XO1GF2856r7yYVh74URiF9JMcAacr5U= go.opentelemetry.io/otel/sdk/log v0.3.0/go.mod h1:BwCxtmux6ACLuys1wlbc0+vGBd+xytjmjajwqqIul2g= +go.opentelemetry.io/otel/sdk/metric v1.27.0 h1:5uGNOlpXi+Hbo/DRoI31BSb1v+OGcpv2NemcCrOL8gI= +go.opentelemetry.io/otel/sdk/metric v1.27.0/go.mod h1:we7jJVrYN2kh3mVBlswtPU22K0SA+769l93J6bsyvqw= go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= @@ -71,27 +67,23 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5 h1:P8OJ/WCl/Xo4E4zoe4/bifHpSmmKwARqyqE4nW6J2GQ= -google.golang.org/genproto/googleapis/api v0.0.0-20240520151616-dc85e6b867a5/go.mod h1:RGnPtTG7r4i8sPlNyDeikXF99hMM+hN6QMm4ooG9g2g= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291 h1:AgADTJarZTBqgjiUzRgfaBchgYB3/WFTC80GPwsMcRI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240515191416-fc5f0ca64291/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= -google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= -google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= +google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0= +google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA= +google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= +google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/version/go.mod b/version/go.mod index b4c820cca3..3f75841e44 100644 --- a/version/go.mod +++ b/version/go.mod @@ -3,9 +3,9 @@ module github.com/dagger/dagger/version go 1.23.1 require ( - github.com/99designs/gqlgen v0.17.49 + github.com/99designs/gqlgen v0.17.55 github.com/Khan/genqlient v0.7.0 - github.com/vektah/gqlparser/v2 v2.5.16 + github.com/vektah/gqlparser/v2 v2.5.17 go.opentelemetry.io/otel v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 @@ -17,8 +17,8 @@ require ( go.opentelemetry.io/otel/trace v1.27.0 go.opentelemetry.io/proto/otlp v1.3.1 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa - golang.org/x/mod v0.18.0 - golang.org/x/sync v0.8.0 + golang.org/x/mod v0.20.0 + golang.org/x/sync v0.10.0 google.golang.org/grpc v1.66.1 ) @@ -30,11 +30,14 @@ require ( github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/sosodev/duration v1.3.1 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 // indirect - go.opentelemetry.io/otel/metric v1.27.0 // indirect + go.opentelemetry.io/otel/metric v1.27.0 + go.opentelemetry.io/otel/sdk/metric v1.27.0 golang.org/x/net v0.29.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/text v0.18.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect google.golang.org/protobuf v1.34.2 // indirect diff --git a/version/go.sum b/version/go.sum index c9e3fee13d..b3c0ba74cb 100644 --- a/version/go.sum +++ b/version/go.sum @@ -1,5 +1,5 @@ -github.com/99designs/gqlgen v0.17.49 h1:b3hNGexHd33fBSAd4NDT/c3NCcQzcAVkknhN9ym36YQ= -github.com/99designs/gqlgen v0.17.49/go.mod h1:tC8YFVZMed81x7UJ7ORUwXF4Kn6SXuucFqQBhN8+BU0= +github.com/99designs/gqlgen v0.17.55 h1:3vzrNWYyzSZjGDFo68e5j9sSauLxfKvLp+6ioRokVtM= +github.com/99designs/gqlgen v0.17.55/go.mod h1:3Bq768f8hgVPGZxL8aY9MaYmbxa6llPM/qu1IGH1EJo= github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= @@ -33,14 +33,18 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0vy5p8= -github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= +github.com/vektah/gqlparser/v2 v2.5.17 h1:9At7WblLV7/36nulgekUgIaqHZWn5hxqluxrxGUhOmI= +github.com/vektah/gqlparser/v2 v2.5.17/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88 h1:oM0GTNKGlc5qHctWeIGTVyda4iFFalOzMZ3Ehj5rwB4= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.0.0-20240518090000-14441aefdf88/go.mod h1:JGG8ebaMO5nXOPnvKEl+DiA4MGwFjCbjsxT1WHIEBPY= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0 h1:ccBrA8nCY5mM0y5uO7FT0ze4S0TuFcWdDB2FxGMTjkI= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.3.0/go.mod h1:/9pb6634zi2Lk8LYg9Q0X8Ar6jka4dkFOylBLbVQPCE= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0 h1:bFgvUr3/O4PHj3VQcFEuYKvRZJX1SJDQ+11JXuSB3/w= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.27.0/go.mod h1:xJntEd2KL6Qdg5lwp97HMLQDVeAhrYxmzFseAMDPQ8I= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0 h1:CIHWikMsN3wO+wq1Tp5VGdVRTcON+DmOJSfDjXypKOc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.27.0/go.mod h1:TNupZ6cxqyFEpLXAZW7On+mLFL0/g0TE3unIYL91xWc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0 h1:R9DE4kQ4k+YtfLI2ULwX82VtNQ2J8yZmA7ZIF/D+7Mc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.27.0/go.mod h1:OQFyQVrDlbe+R7xrEyDr/2Wr67Ol0hRUgsfA+V5A95s= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= @@ -55,6 +59,8 @@ go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kT go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= go.opentelemetry.io/otel/sdk/log v0.3.0 h1:GEjJ8iftz2l+XO1GF2856r7yYVh74URiF9JMcAacr5U= go.opentelemetry.io/otel/sdk/log v0.3.0/go.mod h1:BwCxtmux6ACLuys1wlbc0+vGBd+xytjmjajwqqIul2g= +go.opentelemetry.io/otel/sdk/metric v1.27.0 h1:5uGNOlpXi+Hbo/DRoI31BSb1v+OGcpv2NemcCrOL8gI= +go.opentelemetry.io/otel/sdk/metric v1.27.0/go.mod h1:we7jJVrYN2kh3mVBlswtPU22K0SA+769l93J6bsyvqw= go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= @@ -63,16 +69,16 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= -golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= -golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= From 89b73c7424b0121a6e1a6323f09fb7e446a11ec4 Mon Sep 17 00:00:00 2001 From: Gerhard Lazu Date: Thu, 12 Dec 2024 19:24:39 +0000 Subject: [PATCH 33/35] ci(alt): Add a new type of CI runner (#9182) Signed-off-by: Gerhard Lazu --- .../_dagger_on_depot_local_engine.yml | 3 +- .../_dagger_on_namespace_local_engine.yml | 49 +++++++++++++ .../_dagger_on_namespace_remote_engine.yml | 52 ++++++++++++++ ...nners.yml => alternative-ci-runners-1.yml} | 15 ++-- .../workflows/alternative-ci-runners-2.yml | 69 +++++++++++++++++++ 5 files changed, 183 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/_dagger_on_namespace_local_engine.yml create mode 100644 .github/workflows/_dagger_on_namespace_remote_engine.yml rename .github/workflows/{alternative-ci-runners.yml => alternative-ci-runners-1.yml} (83%) create mode 100644 .github/workflows/alternative-ci-runners-2.yml diff --git a/.github/workflows/_dagger_on_depot_local_engine.yml b/.github/workflows/_dagger_on_depot_local_engine.yml index ee6cbd81ca..402b04f308 100644 --- a/.github/workflows/_dagger_on_depot_local_engine.yml +++ b/.github/workflows/_dagger_on_depot_local_engine.yml @@ -10,7 +10,8 @@ on: size: description: "Runner size" type: number - required: true + default: 16 + required: false timeout: description: "Timeout if not finished after this many minutes" type: number diff --git a/.github/workflows/_dagger_on_namespace_local_engine.yml b/.github/workflows/_dagger_on_namespace_local_engine.yml new file mode 100644 index 0000000000..dd3927a4c6 --- /dev/null +++ b/.github/workflows/_dagger_on_namespace_local_engine.yml @@ -0,0 +1,49 @@ +name: Dagger on Namespace - Local Engine + +on: + workflow_call: + inputs: + function: + description: "Dagger function" + type: string + required: true + size: + description: "Runner size" + type: number + default: 16 + required: false + timeout: + description: "Timeout if not finished after this many minutes" + type: number + default: 10 + required: false + dev: + description: "Use a development version of Dagger" + type: string + default: "false" + required: false + ubuntu: + description: "Ubuntu version" + type: string + default: "24.04" + required: false + +jobs: + local-dagger-engine: + if: ${{ github.repository == 'dagger/dagger' }} + runs-on: + - nscloud-ubuntu-${{ inputs.ubuntu }}-amd64-${{ inputs.size }}x32 + timeout-minutes: ${{ inputs.timeout }} + steps: + - name: Checkout repo + uses: actions/checkout@v4 + - name: ${{ inputs.function }} + uses: ./.github/actions/call + with: + function: ${{ inputs.function }} + dev-engine: ${{ inputs.dev }} + - name: ${{ inputs.function }} (CACHE TEST) + uses: ./.github/actions/call + with: + function: ${{ inputs.function }} + dev-engine: ${{ inputs.dev }} diff --git a/.github/workflows/_dagger_on_namespace_remote_engine.yml b/.github/workflows/_dagger_on_namespace_remote_engine.yml new file mode 100644 index 0000000000..1eb2b4ce09 --- /dev/null +++ b/.github/workflows/_dagger_on_namespace_remote_engine.yml @@ -0,0 +1,52 @@ +name: Dagger on Namespace - Remote Engine + +on: + workflow_call: + inputs: + function: + description: "Dagger function" + type: string + required: true + size: + description: "Runner size - used by the Dagger Engine too" + type: number + default: 16 + required: false + timeout: + description: "Timeout if not finished after this many minutes" + type: number + default: 10 + required: false + dagger: + description: "Dagger version" + type: string + default: "0.15.0" + required: false + ubuntu: + description: "Ubuntu version" + type: string + default: "24.04" + required: false + +jobs: + remote-dagger-engine: + if: ${{ github.repository == 'dagger/dagger' }} + runs-on: + - nscloud-ubuntu-${{ inputs.ubuntu }}-amd64-${{ inputs.size }}x32 + - namespace-experiments:dagger.integration=enabled;dagger.version=${{ inputs.dagger }} + timeout-minutes: ${{ inputs.timeout }} + steps: + - name: Checkout repo + uses: actions/checkout@v4 + - name: ${{ inputs.function }} + uses: ./.github/actions/call + with: + function: ${{ inputs.function }} + version: v${{ inputs.dagger }} + dev-engine: ${{ inputs.dev }} + - name: ${{ inputs.function }} (CACHE TEST) + uses: ./.github/actions/call + with: + function: ${{ inputs.function }} + version: v${{ inputs.dagger }} + dev-engine: ${{ inputs.dev }} diff --git a/.github/workflows/alternative-ci-runners.yml b/.github/workflows/alternative-ci-runners-1.yml similarity index 83% rename from .github/workflows/alternative-ci-runners.yml rename to .github/workflows/alternative-ci-runners-1.yml index ac1989a6e5..acae81bab5 100644 --- a/.github/workflows/alternative-ci-runners.yml +++ b/.github/workflows/alternative-ci-runners-1.yml @@ -1,4 +1,4 @@ -name: Alternative CI Runners +name: Alternative CI Runners 1 on: # Run the workflow every day TWICE: @@ -17,6 +17,12 @@ jobs: uses: ./.github/workflows/_dagger_on_depot_remote_engine.yml with: function: docs lint + docs-lint-on-depot-local-engine: + uses: ./.github/workflows/_dagger_on_depot_local_engine.yml + with: + function: docs lint + dev: true + timeout: 20 test-cli-engine-on-depot-remote-engine: needs: docs-lint-on-depot-remote-engine @@ -31,11 +37,12 @@ jobs: with: function: check --targets=sdk/go sdk-go-dev-on-depot-local-engine: + needs: sdk-go-on-depot-remote-engine uses: ./.github/workflows/_dagger_on_depot_local_engine.yml with: function: check --targets=sdk/go - size: 4 dev: true + timeout: 15 sdk-python-on-depot-remote-engine: needs: docs-lint-on-depot-remote-engine @@ -43,10 +50,10 @@ jobs: with: function: check --targets=sdk/python sdk-python-dev-on-depot-local-engine: + needs: sdk-python-on-depot-remote-engine uses: ./.github/workflows/_dagger_on_depot_local_engine.yml with: function: check --targets=sdk/python - size: 8 dev: true sdk-typescript-on-depot-remote-engine: @@ -55,8 +62,8 @@ jobs: with: function: check --targets=sdk/typescript sdk-typescript-dev-on-depot-local-engine: + needs: sdk-typescript-on-depot-remote-engine uses: ./.github/workflows/_dagger_on_depot_local_engine.yml with: function: check --targets=sdk/typescript - size: 8 dev: true diff --git a/.github/workflows/alternative-ci-runners-2.yml b/.github/workflows/alternative-ci-runners-2.yml new file mode 100644 index 0000000000..594ddba34e --- /dev/null +++ b/.github/workflows/alternative-ci-runners-2.yml @@ -0,0 +1,69 @@ +name: Alternative CI Runners 2 + +on: + # Run the workflow every day TWICE: + # 1. 9:06AM UTC (low activity) + # 2. 9:26AM UTC (cache test - high chance of no code changes) + schedule: + - cron: "6,26 9 * * *" + # Enable manual trigger for on-demand runs - helps when debugging + workflow_dispatch: + +permissions: + contents: read + +jobs: + docs-lint-on-namespace-remote-engine: + uses: ./.github/workflows/_dagger_on_namespace_remote_engine.yml + with: + function: docs lint + timeout: 20 + docs-lint-on-namespace-local-engine: + uses: ./.github/workflows/_dagger_on_namespace_local_engine.yml + with: + function: docs lint + dev: true + timeout: 20 + + test-cli-engine-on-namespace-remote-engine: + needs: docs-lint-on-namespace-remote-engine + uses: ./.github/workflows/_dagger_on_namespace_remote_engine.yml + with: + function: test specific --run='TestCLI|TestEngine' --race=true --parallel=16 + timeout: 20 + + sdk-go-on-namespace-remote-engine: + needs: docs-lint-on-namespace-remote-engine + uses: ./.github/workflows/_dagger_on_namespace_remote_engine.yml + with: + function: check --targets=sdk/go + sdk-go-dev-on-namespace-local-engine: + needs: sdk-go-on-namespace-remote-engine + uses: ./.github/workflows/_dagger_on_namespace_local_engine.yml + with: + function: check --targets=sdk/go + dev: true + + sdk-python-on-namespace-remote-engine: + needs: docs-lint-on-namespace-remote-engine + uses: ./.github/workflows/_dagger_on_namespace_remote_engine.yml + with: + function: check --targets=sdk/python + sdk-python-dev-on-namespace-local-engine: + needs: sdk-python-on-namespace-remote-engine + uses: ./.github/workflows/_dagger_on_namespace_local_engine.yml + with: + function: check --targets=sdk/python + dev: true + + sdk-typescript-on-namespace-remote-engine: + needs: docs-lint-on-namespace-remote-engine + uses: ./.github/workflows/_dagger_on_namespace_remote_engine.yml + with: + function: check --targets=sdk/typescript + sdk-typescript-dev-on-namespace-local-engine: + needs: sdk-typescript-on-namespace-remote-engine + uses: ./.github/workflows/_dagger_on_namespace_local_engine.yml + with: + function: check --targets=sdk/typescript + dev: true From 17b6b7b88e1ba6ea2cd0a2ac8fc4a7c5619f4e1c Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Thu, 12 Dec 2024 19:26:25 +0000 Subject: [PATCH 34/35] feat: shell autocomplete (#9063) * chore: consolidate shell command Run and RunState We don't need two separate methods for this - instead, we can validate it using a similar mechanism for how we do the args. This will allow us to more easily determine if a builtin supports a context input, so we can choose whether it should be part of auto-complete in a certain context. Signed-off-by: Justin Chadwell * feat: add shell completion Signed-off-by: Justin Chadwell * tests: add shell autocompletion tests Signed-off-by: Justin Chadwell * Support function lookup fallbacks This add support for more stuff, but completions for modules other than the currently loaded one aren't supported yet. Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com> * Update tests Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com> --------- Signed-off-by: Justin Chadwell Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com> Co-authored-by: Helder Correia <174525+helderco@users.noreply.github.com> --- cmd/dagger/shell.go | 137 +++++++---- cmd/dagger/shell_completion.go | 369 ++++++++++++++++++++++++++++ cmd/dagger/shell_completion_test.go | 132 ++++++++++ 3 files changed, 597 insertions(+), 41 deletions(-) create mode 100644 cmd/dagger/shell_completion.go create mode 100644 cmd/dagger/shell_completion_test.go diff --git a/cmd/dagger/shell.go b/cmd/dagger/shell.go index 3068119344..b393b3ccd1 100644 --- a/cmd/dagger/shell.go +++ b/cmd/dagger/shell.go @@ -244,26 +244,11 @@ func litWord(s string) *syntax.Word { // run parses code and executes the interpreter's Runner func (h *shellCallHandler) run(ctx context.Context, reader io.Reader, name string) error { - file, err := syntax.NewParser(syntax.Variant(syntax.LangPOSIX)).Parse(reader, name) + file, err := parseShell(reader, name) if err != nil { return err } - syntax.Walk(file, func(node syntax.Node) bool { - if node, ok := node.(*syntax.CmdSubst); ok { - // Rewrite command substitutions from $(foo; bar) to $(exec <&-; foo; bar) - // so that all the original commands run with a closed (nil) standard input. - node.Stmts = append([]*syntax.Stmt{{ - Cmd: &syntax.CallExpr{Args: []*syntax.Word{litWord("..exec")}}, - Redirs: []*syntax.Redirect{{ - Op: syntax.DplIn, - Word: litWord("-"), - }}, - }}, node.Stmts...) - } - return true - }) - h.stdoutBuf.Reset() h.stderrBuf.Reset() @@ -308,6 +293,29 @@ func (h *shellCallHandler) run(ctx context.Context, reader io.Reader, name strin }) } +func parseShell(reader io.Reader, name string) (*syntax.File, error) { + file, err := syntax.NewParser(syntax.Variant(syntax.LangPOSIX)).Parse(reader, name) + if err != nil { + return nil, err + } + + syntax.Walk(file, func(node syntax.Node) bool { + if node, ok := node.(*syntax.CmdSubst); ok { + // Rewrite command substitutions from $(foo; bar) to $(exec <&-; foo; bar) + // so that all the original commands run with a closed (nil) standard input. + node.Stmts = append([]*syntax.Stmt{{ + Cmd: &syntax.CallExpr{Args: []*syntax.Word{litWord("..exec")}}, + Redirs: []*syntax.Redirect{{ + Op: syntax.DplIn, + Word: litWord("-"), + }}, + }}, node.Stmts...) + } + return true + }) + return file, nil +} + // runPath executes code from a file func (h *shellCallHandler) runPath(ctx context.Context, path string) error { f, err := os.Open(path) @@ -423,6 +431,7 @@ func (h *shellCallHandler) loadReadlineConfig(prompt string) (*readline.Config, Prompt: prompt, HistoryFile: filepath.Join(dataRoot, "histfile"), HistoryLimit: 1000, + AutoComplete: &shellAutoComplete{h}, }, nil } @@ -1243,16 +1252,14 @@ type ShellCommand struct { // Expected arguments Args PositionalArgs - // Run is the function that will be executed if it's the first command - // in the pipeline and RunState is not defined - Run func(cmd *ShellCommand, args []string) error + // Expected state + State StateArg - // RunState is the function for executing a command that can be chained - // in a pipeline - // - // If defined, it's always used, even if it's the first command in the - // pipeline. For commands that should only be the first, define `Run` instead. - RunState func(cmd *ShellCommand, args []string, st *ShellState) error + // Run is the function that will be executed. + Run func(cmd *ShellCommand, args []string, st *ShellState) error + + // Complete provides builtin completions + Complete func(ctx *CompletionContext, args []string) *CompletionContext // HelpFunc is a custom function for customizing the help output HelpFunc func(cmd *ShellCommand) string @@ -1376,10 +1383,26 @@ func NoArgs(args []string) error { return nil } +type StateArg uint + +const ( + AnyState StateArg = iota + RequiredState + NoState +) + // Execute is the main dispatcher function for shell builtin commands func (c *ShellCommand) Execute(ctx context.Context, h *shellCallHandler, args []string, st *ShellState) error { - if st != nil && c.RunState == nil { - return fmt.Errorf("command %q cannot be piped", c.Name()) + switch c.State { + case AnyState: + case RequiredState: + if st == nil { + return fmt.Errorf("command %q must be piped\nusage: %s", c.Name(), c.Use) + } + case NoState: + if st != nil { + return fmt.Errorf("command %q cannot be piped\nusage: %s", c.Name(), c.Use) + } } if c.Args != nil { if err := c.Args(args); err != nil { @@ -1406,10 +1429,7 @@ func (c *ShellCommand) Execute(ctx context.Context, h *shellCallHandler, args [] shellDebug(ctx, "โ”” CmdExec(%v)", a) } c.SetContext(ctx) - if c.RunState != nil { - return c.RunState(c, a, st) - } - return c.Run(c, a) + return c.Run(c, a, st) } // shellFunctionUseLine returns the usage line fine for a function @@ -1878,7 +1898,8 @@ func (h *shellCallHandler) registerCommands() { //nolint:gocyclo Use: ".debug", Hidden: true, Args: NoArgs, - Run: func(_ *ShellCommand, _ []string) error { + State: NoState, + Run: func(cmd *ShellCommand, args []string, _ *ShellState) error { // Toggles debug mode, which can be useful when in interactive mode h.debug = !h.debug return nil @@ -1888,7 +1909,8 @@ func (h *shellCallHandler) registerCommands() { //nolint:gocyclo Use: ".help [command]", Description: "Print this help message", Args: MaximumArgs(1), - Run: func(cmd *ShellCommand, args []string) error { + State: NoState, + Run: func(cmd *ShellCommand, args []string, _ *ShellState) error { if len(args) == 1 { c, err := h.BuiltinCommand(args[0]) if err != nil { @@ -1935,7 +1957,7 @@ Local module paths are resolved relative to the workdir on the host, not relativ to the currently loaded module. `, Args: MaximumArgs(1), - RunState: func(cmd *ShellCommand, args []string, st *ShellState) error { + Run: func(cmd *ShellCommand, args []string, st *ShellState) error { var err error ctx := cmd.Context() @@ -2049,7 +2071,8 @@ to the currently loaded module. `, GroupID: moduleGroup.ID, Args: ExactArgs(1), - Run: func(cmd *ShellCommand, args []string) error { + State: NoState, + Run: func(cmd *ShellCommand, args []string, _ *ShellState) error { st, err := h.getOrInitDefState(args[0], func() (*moduleDef, error) { return initializeModule(cmd.Context(), h.dag, args[0], true) }) @@ -2069,29 +2092,52 @@ to the currently loaded module. Description: "Dependencies from the module loaded in the current context", GroupID: moduleGroup.ID, Args: NoArgs, - Run: func(cmd *ShellCommand, _ []string) error { + State: NoState, + Run: func(cmd *ShellCommand, _ []string, _ *ShellState) error { _, err := h.GetModuleDef(nil) if err != nil { return err } return cmd.Send(h.newDepsState()) }, + Complete: func(ctx *CompletionContext, _ []string) *CompletionContext { + return &CompletionContext{ + Completer: ctx.Completer, + CmdRoot: shellDepsCmdName, + root: true, + } + }, }, &ShellCommand{ Use: shellStdlibCmdName, Description: "Standard library functions", Args: NoArgs, - Run: func(cmd *ShellCommand, _ []string) error { + State: NoState, + Run: func(cmd *ShellCommand, _ []string, _ *ShellState) error { return cmd.Send(h.newStdlibState()) }, + Complete: func(ctx *CompletionContext, _ []string) *CompletionContext { + return &CompletionContext{ + Completer: ctx.Completer, + CmdRoot: shellStdlibCmdName, + root: true, + } + }, }, &ShellCommand{ Use: ".core [function]", Description: "Load any core Dagger type", - Args: NoArgs, - Run: func(cmd *ShellCommand, args []string) error { + State: NoState, + Run: func(cmd *ShellCommand, args []string, _ *ShellState) error { return cmd.Send(h.newCoreState()) }, + Complete: func(ctx *CompletionContext, _ []string) *CompletionContext { + return &CompletionContext{ + Completer: ctx.Completer, + CmdRoot: shellCoreCmdName, + root: true, + } + }, }, cobraToShellCommand(loginCmd), cobraToShellCommand(logoutCmd), @@ -2125,10 +2171,11 @@ to the currently loaded module. &ShellCommand{ Use: shellFunctionUseLine(def, fn), Description: fn.Description, + State: NoState, HelpFunc: func(cmd *ShellCommand) string { return shellFunctionDoc(def, fn) }, - Run: func(cmd *ShellCommand, args []string) error { + Run: func(cmd *ShellCommand, args []string, _ *ShellState) error { ctx := cmd.Context() st := h.newState() @@ -2139,6 +2186,13 @@ to the currently loaded module. return cmd.Send(st) }, + Complete: func(ctx *CompletionContext, args []string) *CompletionContext { + return &CompletionContext{ + Completer: ctx.Completer, + ModFunction: fn, + root: true, + } + }, }, ) } @@ -2160,7 +2214,8 @@ func cobraToShellCommand(c *cobra.Command) *ShellCommand { Use: "." + c.Use, Description: c.Short, GroupID: c.GroupID, - Run: func(cmd *ShellCommand, args []string) error { + State: NoState, + Run: func(cmd *ShellCommand, args []string, _ *ShellState) error { // Re-execute the dagger command (hack) args = append([]string{cmd.CleanName()}, args...) ctx := cmd.Context() diff --git a/cmd/dagger/shell_completion.go b/cmd/dagger/shell_completion.go new file mode 100644 index 0000000000..8c2e9b66a2 --- /dev/null +++ b/cmd/dagger/shell_completion.go @@ -0,0 +1,369 @@ +package main + +import ( + "slices" + "strings" + + "github.com/chzyer/readline" + "mvdan.cc/sh/v3/syntax" +) + +// shellAutoComplete is a wrapper for the shell call handler +type shellAutoComplete struct { + // This is separated out, since we don't want to have to attach all these + // methods to the shellCallHandler directly + *shellCallHandler +} + +var _ readline.AutoCompleter = (*shellAutoComplete)(nil) + +func (h *shellAutoComplete) Do(line []rune, pos int) (newLine [][]rune, length int) { + file, err := parseShell(strings.NewReader(string(line)), "") + if err != nil { + return nil, 0 + } + + // find the smallest stmt next to the cursor - this allows accurate + // completion inside subshells, for example + var stmt *syntax.Stmt + excluded := map[*syntax.Stmt]struct{}{} + syntax.Walk(file, func(node syntax.Node) bool { + switch node := node.(type) { + case *syntax.BinaryCmd: + if node.Op == syntax.Pipe { + // pipes are special, and those statements aren't atomic + // because they're chained off of the previous ones - so avoid + // isolating them + excluded[node.X] = struct{}{} + excluded[node.Y] = struct{}{} + } + case *syntax.Stmt: + if stmt == nil { + stmt = node + break + } + if pos < int(node.Pos().Offset()) || pos > int(node.End().Offset()) { + return false + } + if _, ok := excluded[node]; !ok { + stmt = node + } + } + return true + }) + + var inprogressWord *syntax.Word + syntax.Walk(file, func(node syntax.Node) bool { + if node, ok := node.(*syntax.Word); ok { + if node.End().Offset() == uint(pos) { + inprogressWord = node + return false + } + } + return true + }) + var inprogressPrefix string + if inprogressWord != nil { + inprogressPrefix = inprogressWord.Lit() + } + + // discard the in-progress word for the process of determining the + // auto-completion context (since it's likely to be invalid) + var cursor uint + if inprogressWord == nil { + cursor = uint(pos) + } else { + cursor = inprogressWord.Pos().Offset() + } + + shctx := h.root() + if stmt != nil { + shctx = h.dispatch(shctx, stmt, cursor) + } + if shctx == nil { + return nil, 0 + } + + var results [][]rune + for _, result := range shctx.completions(inprogressPrefix) { + if result, ok := strings.CutPrefix(result, inprogressPrefix); ok { + results = append(results, []rune(result+" ")) + } + } + return results, len(inprogressPrefix) +} + +func (h *shellAutoComplete) dispatch(previous *CompletionContext, stmt *syntax.Stmt, cursor uint) *CompletionContext { + if stmt == nil { + return previous + } + switch cmd := stmt.Cmd.(type) { + case *syntax.CallExpr: + return h.dispatchCall(previous, cmd, cursor) + case *syntax.BinaryCmd: + return h.dispatchPipe(previous, cmd, cursor) + } + return nil +} + +func (h *shellAutoComplete) dispatchCall(previous *CompletionContext, call *syntax.CallExpr, cursor uint) *CompletionContext { + if call.Pos().Offset() >= cursor { + // short-circuit calls once we get past the current cursor context + return previous + } + + args := make([]string, 0, len(call.Args)) + for _, arg := range call.Args { + args = append(args, arg.Lit()) + } + return previous.lookupField(args[0], args[1:]) +} + +func (h *shellAutoComplete) dispatchPipe(previous *CompletionContext, pipe *syntax.BinaryCmd, cursor uint) *CompletionContext { + if pipe.Op != syntax.Pipe { + return nil + } + + previous = h.dispatch(previous, pipe.X, cursor) + if previous == nil { + return nil + } + + if pipe.OpPos.Offset() >= cursor { + // short-circuit pipes once we get past the current cursor context + return previous + } + previous = previous.lookupType() + if previous == nil { + return nil + } + + return h.dispatch(previous, pipe.Y, cursor) +} + +func (h *shellAutoComplete) root() *CompletionContext { + return &CompletionContext{ + Completer: h, + root: true, + } +} + +// CompletionContext provides completions for a specific point in a command +// chain. Each point is represented by one of `Mod` prefixed fields being set +// at a time. +type CompletionContext struct { + Completer *shellAutoComplete + + // CmdRoot is the name of a namespace-setting command. + CmdRoot string + + // ModType indicates the completions should be performed on an + // object/interface/etc. + ModType functionProvider + + // ModFunc indicates the completions should be performed on the arguments + // for a function call. + ModFunction *modFunction + + root bool +} + +func (ctx *CompletionContext) completions(prefix string) []string { + var results []string + switch { + case ctx.ModFunction != nil: + // TODO: also complete required args sometimes (depending on type) + + // complete optional args + if strings.HasPrefix(prefix, "-") { + for _, arg := range ctx.ModFunction.OptionalArgs() { + flag := "--" + arg.FlagName() + results = append(results, flag) + } + } + + case ctx.ModType != nil: + // complete possible functions for this type + for _, f := range ctx.ModType.GetFunctions() { + results = append(results, f.CmdName()) + } + // complete potentially chainable builtins + for _, builtin := range ctx.builtins() { + results = append(results, builtin.Name()) + } + + case ctx.root: + for _, cmd := range slices.Concat(ctx.builtins(), ctx.stdlib()) { + results = append(results, cmd.Name()) + } + if md, _ := ctx.Completer.GetModuleDef(nil); md != nil { + for _, fn := range md.MainObject.AsFunctionProvider().GetFunctions() { + results = append(results, fn.CmdName()) + } + for _, dep := range md.Dependencies { + results = append(results, dep.Name) + } + } + for modRef := range ctx.Completer.modDefs { + if modRef != "" { + results = append(results, modRef) + } + } + + case ctx.CmdRoot == shellStdlibCmdName: + for _, cmd := range ctx.Completer.Stdlib() { + results = append(results, cmd.Name()) + } + + case ctx.CmdRoot == shellDepsCmdName: + if md, _ := ctx.Completer.GetModuleDef(nil); md != nil { + for _, dep := range md.Dependencies { + results = append(results, dep.Name) + } + } + + case ctx.CmdRoot == shellCoreCmdName: + for _, fn := range ctx.Completer.modDef(nil).GetCoreFunctions() { + results = append(results, fn.CmdName()) + } + } + + return results +} + +func (ctx *CompletionContext) lookupField(field string, args []string) *CompletionContext { + if cmd := ctx.builtinCmd(field); cmd != nil { + return cmd.Complete(ctx, args) + } + + def := ctx.Completer.modDef(nil) + + if ctx.ModType != nil { + next, err := def.GetFunction(ctx.ModType, field) + if err != nil { + return nil + } + return &CompletionContext{ + Completer: ctx.Completer, + ModFunction: next, + } + } + + // Limit options for these namespace-setting commands + switch ctx.CmdRoot { + case shellStdlibCmdName: + if cmd := ctx.stdlibCmd(field); cmd != nil { + return cmd.Complete(ctx, args) + } + case shellDepsCmdName: + // TODO: loading other modules isn't supported yet + return nil + + case shellCoreCmdName: + if fn := def.GetCoreFunction(field); fn != nil { + return &CompletionContext{ + Completer: ctx.Completer, + ModFunction: fn, + } + } + } + + // Default lookup and fallbacks after this point, which only happens + // when it's the first command. + if !ctx.root { + return nil + } + + // 1. Current module function + if def.HasMainFunction(field) { + next, err := def.GetFunction(def.MainObject.AsFunctionProvider(), field) + if err != nil { + return nil + } + return &CompletionContext{ + Completer: ctx.Completer, + ModFunction: next, + } + } + + // 2. Dependency + if dep := def.GetDependency(field); dep != nil { + // TODO: loading other modules isn't supported yet + return nil + } + + // 3. Stdlib + if cmd := ctx.stdlibCmd(field); cmd != nil { + return cmd.Complete(ctx, args) + } + + // 4. Module reference + // TODO: loading other modules isn't supported yet + if field == ctx.Completer.modRef { + return &CompletionContext{ + Completer: ctx.Completer, + ModFunction: def.MainObject.AsObject.Constructor, + } + } + + return nil +} + +func (ctx *CompletionContext) lookupType() *CompletionContext { + if ctx.ModType != nil || ctx.CmdRoot != "" { + return ctx + } + if ctx.ModFunction != nil { + def := ctx.Completer.modDef(nil) + next := def.GetFunctionProvider(ctx.ModFunction.ReturnType.Name()) + return &CompletionContext{ + Completer: ctx.Completer, + ModType: next, + } + } + return nil +} + +func (ctx *CompletionContext) builtins() []*ShellCommand { + var cmds []*ShellCommand + for _, cmd := range ctx.Completer.Builtins() { + if ctx.root && cmd.State != RequiredState || !ctx.root && cmd.State != NoState { + cmds = append(cmds, cmd) + } + } + return cmds +} + +func (ctx *CompletionContext) stdlib() []*ShellCommand { + var cmds []*ShellCommand + for _, cmd := range ctx.Completer.Stdlib() { + if ctx.root && cmd.State != RequiredState || !ctx.root && cmd.State != NoState { + cmds = append(cmds, cmd) + } + } + return cmds +} + +func (ctx *CompletionContext) builtinCmd(name string) *ShellCommand { + for _, cmd := range ctx.builtins() { + if cmd.Name() == name { + if cmd.Complete == nil { + return nil + } + return cmd + } + } + return nil +} + +func (ctx *CompletionContext) stdlibCmd(name string) *ShellCommand { + for _, cmd := range ctx.stdlib() { + if cmd.Name() == name { + if cmd.Complete == nil { + return nil + } + return cmd + } + } + return nil +} diff --git a/cmd/dagger/shell_completion_test.go b/cmd/dagger/shell_completion_test.go new file mode 100644 index 0000000000..1652124414 --- /dev/null +++ b/cmd/dagger/shell_completion_test.go @@ -0,0 +1,132 @@ +package main + +import ( + "context" + "io" + "os" + "os/exec" + "path/filepath" + "strings" + "testing" + + "dagger.io/dagger" + "github.com/stretchr/testify/require" +) + +func TestShellAutocomplete(t *testing.T) { + // each cmdline is a prompt input + // the contents of the angle brackets are the word we want to complete - + // everything before the $ sign is already written, and one of the response + // options should include the contents after the $ + + cmdlines := []string{ + // top-level function + ``, + `<$container >`, + ` <$container >`, + ` "alpine:latest"`, + `| directory`, + + // top-level deps + ``, + + // stdlib fallback + ``, + `directory | `, + + // chaining + `container | `, + `container | directory "./path" | `, + // NOTE: this requires parsing partial parse trees + // "container | <$directory >", + + // subshells + // FIXME: this edge case should probably still work + // `container | with-directory $(<$container >)`, + `container | with-directory $()`, + `container | with-directory $(container | )`, + + // args + `container <--$packages >`, + `container <--$packages > | directory`, + `container | directory <--$expand >`, + + // .deps builtin + `<.dep$s >`, + `<$.deps >`, + `.deps | `, + + // .stdlib builtin + `<.std$lib >`, + `<$.stdlib >`, + `.stdlib | `, + `.stdlib | container <--$platform >`, + `.stdlib | container | `, + + // .core builtin + `<.co$re >`, + `<$.core >`, + `.core | `, + `.core | container <--$platform >`, + `.core | container | `, + + // FIXME: avoid inserting extra spaces + // ` `, + } + + wd, err := os.Getwd() + require.NoError(t, err) + + dir := t.TempDir() + require.NoError(t, os.CopyFS(dir, os.DirFS(filepath.Join(wd, "../../modules")))) + cmd := exec.Command("git", "init") + cmd.Dir = dir + require.NoError(t, cmd.Run()) + + os.Chdir(dir) + t.Cleanup(func() { + os.Chdir(wd) + }) + t.Setenv("DAGGER_MODULE", "./wolfi") + + ctx := context.TODO() + + client, err := dagger.Connect(ctx) + require.NoError(t, err) + t.Cleanup(func() { client.Close() }) + + handler := &shellCallHandler{ + dag: client, + stdin: nil, + stdout: io.Discard, + stderr: io.Discard, + debug: debug, + } + require.NoError(t, handler.RunAll(ctx, nil)) + autoComplete := shellAutoComplete{handler} + + for _, cmdline := range cmdlines { + t.Run(cmdline, func(t *testing.T) { + start := strings.IndexRune(cmdline, '<') + end := strings.IndexRune(cmdline, '>') + if start == -1 || end == -1 || !(start < end) { + require.FailNow(t, "invalid cmdline: could not find ") + } + inprogress, expected, ok := strings.Cut(cmdline[start+1:end], "$") + if !ok { + require.FailNow(t, "invalid cmdline: no token '$' in ") + } + + cmdline := cmdline[:start] + inprogress + cmdline[end+1:] + cursor := start + len(inprogress) + + results, length := autoComplete.Do([]rune(cmdline), cursor) + sresults := make([]string, 0, len(results)) + for _, result := range results { + sresults = append(sresults, string(result)) + } + require.Contains(t, sresults, expected) + require.Equal(t, len(inprogress), length) + }) + } +} From 196f232a4d6b2d1d3db5f5e040cf20b6a76a76c5 Mon Sep 17 00:00:00 2001 From: Connor Braa <3478454+cwlbraa@users.noreply.github.com> Date: Thu, 12 Dec 2024 11:50:10 -0800 Subject: [PATCH 35/35] chore: prep for v0.15.1 (#9183) * chore: bump dependencies to v0.15.1 Signed-off-by: Connor Braa * chore: add release notes for v0.15.1 Signed-off-by: Connor Braa * clear out .changes/.next Signed-off-by: Connor Braa --------- Signed-off-by: Connor Braa --- .changes/.next | 2 -- .changes/unreleased/Fixed-20241211-195735.yaml | 7 ------- .changes/v0.15.1.md | 9 +++++++++ CHANGELOG.md | 10 ++++++++++ docs/current_docs/partials/version.js | 2 +- helm/dagger/.changes/v0.15.1.md | 9 +++++++++ helm/dagger/CHANGELOG.md | 10 ++++++++++ helm/dagger/Chart.yaml | 2 +- sdk/elixir/.changes/v0.15.1.md | 13 +++++++++++++ sdk/elixir/CHANGELOG.md | 14 ++++++++++++++ sdk/elixir/lib/dagger/core/version.ex | 2 +- sdk/go/.changes/v0.15.1.md | 13 +++++++++++++ sdk/go/CHANGELOG.md | 14 ++++++++++++++ sdk/go/internal/engineconn/version.gen.go | 2 +- sdk/php/.changes/v0.15.1.md | 12 ++++++++++++ sdk/php/CHANGELOG.md | 13 +++++++++++++ sdk/php/src/Connection/version.php | 2 +- sdk/python/.changes/v0.15.1.md | 14 ++++++++++++++ sdk/python/CHANGELOG.md | 15 +++++++++++++++ sdk/python/src/dagger/_engine/_version.py | 2 +- sdk/rust/crates/dagger-sdk/src/core/version.rs | 2 +- sdk/typescript/.changes/v0.15.1.md | 14 ++++++++++++++ sdk/typescript/CHANGELOG.md | 15 +++++++++++++++ sdk/typescript/src/provisioning/default.ts | 2 +- 24 files changed, 183 insertions(+), 17 deletions(-) delete mode 100644 .changes/unreleased/Fixed-20241211-195735.yaml create mode 100644 .changes/v0.15.1.md create mode 100644 helm/dagger/.changes/v0.15.1.md create mode 100644 sdk/elixir/.changes/v0.15.1.md create mode 100644 sdk/go/.changes/v0.15.1.md create mode 100644 sdk/php/.changes/v0.15.1.md create mode 100644 sdk/python/.changes/v0.15.1.md create mode 100644 sdk/typescript/.changes/v0.15.1.md diff --git a/.changes/.next b/.changes/.next index 003069a91f..2a7a9aba82 100644 --- a/.changes/.next +++ b/.changes/.next @@ -7,5 +7,3 @@ # This file can also be left empty - if it is, then the next version is # automagically determined from release note entries (and then adding to the # patch release). - -v0.15.1 diff --git a/.changes/unreleased/Fixed-20241211-195735.yaml b/.changes/unreleased/Fixed-20241211-195735.yaml deleted file mode 100644 index c0918e8a9a..0000000000 --- a/.changes/unreleased/Fixed-20241211-195735.yaml +++ /dev/null @@ -1,7 +0,0 @@ -kind: Fixed -body: | - Metrics display in the TUI is fixed to display for all executed containers, rather than just services. -time: 2024-12-11T19:57:35.761154448-08:00 -custom: - Author: sipsma - PR: "9171" diff --git a/.changes/v0.15.1.md b/.changes/v0.15.1.md new file mode 100644 index 0000000000..24a4eba550 --- /dev/null +++ b/.changes/v0.15.1.md @@ -0,0 +1,9 @@ +## v0.15.1 - 2024-12-12 + +### Fixed +- Metrics display in the TUI is fixed to display for all executed containers, rather than just services by @sipsma in https://github.com/dagger/dagger/pull/9171 + +### What to do next? +- Read the [documentation](https://docs.dagger.io) +- Join our [Discord server](https://discord.gg/dagger-io) +- Follow us on [Twitter](https://twitter.com/dagger_io) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62ccbe6c67..49ebb4bb5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v0.15.1 - 2024-12-12 + +### Fixed +- Metrics display in the TUI is fixed to display for all executed containers, rather than just services by @sipsma in https://github.com/dagger/dagger/pull/9171 + +### What to do next? +- Read the [documentation](https://docs.dagger.io) +- Join our [Discord server](https://discord.gg/dagger-io) +- Follow us on [Twitter](https://twitter.com/dagger_io) + ## v0.15.0 - 2024-12-11 ### ๐Ÿ”ฅ Breaking Changes diff --git a/docs/current_docs/partials/version.js b/docs/current_docs/partials/version.js index 1a5eeb3463..a5e4dbf275 100644 --- a/docs/current_docs/partials/version.js +++ b/docs/current_docs/partials/version.js @@ -1,3 +1,3 @@ // Code generated by dagger. DO NOT EDIT. -export const daggerVersion = "0.15.0"; +export const daggerVersion = "0.15.1"; diff --git a/helm/dagger/.changes/v0.15.1.md b/helm/dagger/.changes/v0.15.1.md new file mode 100644 index 0000000000..176f7eaa95 --- /dev/null +++ b/helm/dagger/.changes/v0.15.1.md @@ -0,0 +1,9 @@ +## v0.15.1 - 2024-12-12 + +### Dependencies +- Bump Engine to v0.15.1 by @cwlbraa in https://github.com/dagger/dagger/pull/9183 + +### What to do next? +- Read the [documentation](https://docs.dagger.io) +- Join our [Discord server](https://discord.gg/dagger-io) +- Follow us on [Twitter](https://twitter.com/dagger_io) diff --git a/helm/dagger/CHANGELOG.md b/helm/dagger/CHANGELOG.md index 10e95c730c..8eba012310 100644 --- a/helm/dagger/CHANGELOG.md +++ b/helm/dagger/CHANGELOG.md @@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v0.15.1 - 2024-12-12 + +### Dependencies +- Bump Engine to v0.15.1 by @cwlbraa in https://github.com/dagger/dagger/pull/9183 + +### What to do next? +- Read the [documentation](https://docs.dagger.io) +- Join our [Discord server](https://discord.gg/dagger-io) +- Follow us on [Twitter](https://twitter.com/dagger_io) + ## v0.15.0 - 2024-12-11 ### Dependencies diff --git a/helm/dagger/Chart.yaml b/helm/dagger/Chart.yaml index d46e03ccc8..f994e31b53 100644 --- a/helm/dagger/Chart.yaml +++ b/helm/dagger/Chart.yaml @@ -2,4 +2,4 @@ apiVersion: v2 description: Dagger Helm chart name: dagger-helm type: application -version: 0.15.0 +version: 0.15.1 diff --git a/sdk/elixir/.changes/v0.15.1.md b/sdk/elixir/.changes/v0.15.1.md new file mode 100644 index 0000000000..dd5d71edc9 --- /dev/null +++ b/sdk/elixir/.changes/v0.15.1.md @@ -0,0 +1,13 @@ +## sdk/elixir/v0.15.1 - 2024-12-12 + +This SDK uses ๐Ÿš™ Engine + ๐Ÿš— CLI version `v0.15.1`. [See what changed in that release](https://github.com/dagger/dagger/releases/tag/v0.15.1). + +๐Ÿงช https://hex.pm/packages/dagger +๐Ÿ“– https://hexdocs.pm/dagger/Dagger.html + +### Dependencies +- Bump Engine to v0.15.1 by @cwlbraa in https://github.com/dagger/dagger/pull/9183 + +### What to do next +- Join our [Discord server](https://discord.gg/dagger-io) +- Follow us on [Twitter](https://twitter.com/dagger_io) diff --git a/sdk/elixir/CHANGELOG.md b/sdk/elixir/CHANGELOG.md index 34b684bd22..ef48cbbf09 100644 --- a/sdk/elixir/CHANGELOG.md +++ b/sdk/elixir/CHANGELOG.md @@ -6,6 +6,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## sdk/elixir/v0.15.1 - 2024-12-12 + +This SDK uses ๐Ÿš™ Engine + ๐Ÿš— CLI version `v0.15.1`. [See what changed in that release](https://github.com/dagger/dagger/releases/tag/v0.15.1). + +๐Ÿงช https://hex.pm/packages/dagger +๐Ÿ“– https://hexdocs.pm/dagger/Dagger.html + +### Dependencies +- Bump Engine to v0.15.1 by @cwlbraa in https://github.com/dagger/dagger/pull/9183 + +### What to do next +- Join our [Discord server](https://discord.gg/dagger-io) +- Follow us on [Twitter](https://twitter.com/dagger_io) + ## sdk/elixir/v0.15.0 - 2024-12-10 This SDK uses ๐Ÿš™ Engine + ๐Ÿš— CLI version `v0.15.0`. [See what changed in that release](https://github.com/dagger/dagger/releases/tag/v0.15.0). diff --git a/sdk/elixir/lib/dagger/core/version.ex b/sdk/elixir/lib/dagger/core/version.ex index f6e61c6483..d50046fb35 100644 --- a/sdk/elixir/lib/dagger/core/version.ex +++ b/sdk/elixir/lib/dagger/core/version.ex @@ -1,7 +1,7 @@ defmodule Dagger.Core.Version do @moduledoc false - @dagger_cli_version "0.15.0" + @dagger_cli_version "0.15.1" def engine_version(), do: @dagger_cli_version end diff --git a/sdk/go/.changes/v0.15.1.md b/sdk/go/.changes/v0.15.1.md new file mode 100644 index 0000000000..18bfcadacc --- /dev/null +++ b/sdk/go/.changes/v0.15.1.md @@ -0,0 +1,13 @@ +## sdk/go/v0.15.1 - 2024-12-12 + +This SDK uses ๐Ÿš™ Engine + ๐Ÿš— CLI version `v0.15.1`. [See what changed in that release](https://github.com/dagger/dagger/releases/tag/v0.15.1). + +๐Ÿน https://pkg.go.dev/dagger.io/dagger@v0.15.1 + +### Dependencies +- Bump Engine to v0.15.1 by @cwlbraa in https://github.com/dagger/dagger/pull/9183 + +### What to do next +- Read the [documentation](https://docs.dagger.io/sdk/go) +- Join our [Discord server](https://discord.gg/dagger-io) +- Follow us on [Twitter](https://twitter.com/dagger_io) diff --git a/sdk/go/CHANGELOG.md b/sdk/go/CHANGELOG.md index b2481588a5..56eb572148 100644 --- a/sdk/go/CHANGELOG.md +++ b/sdk/go/CHANGELOG.md @@ -6,6 +6,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## sdk/go/v0.15.1 - 2024-12-12 + +This SDK uses ๐Ÿš™ Engine + ๐Ÿš— CLI version `v0.15.1`. [See what changed in that release](https://github.com/dagger/dagger/releases/tag/v0.15.1). + +๐Ÿน https://pkg.go.dev/dagger.io/dagger@v0.15.1 + +### Dependencies +- Bump Engine to v0.15.1 by @cwlbraa in https://github.com/dagger/dagger/pull/9183 + +### What to do next +- Read the [documentation](https://docs.dagger.io/sdk/go) +- Join our [Discord server](https://discord.gg/dagger-io) +- Follow us on [Twitter](https://twitter.com/dagger_io) + ## sdk/go/v0.15.0 - 2024-12-11 This SDK uses ๐Ÿš™ Engine + ๐Ÿš— CLI version `v0.15.0`. [See what changed in that release](https://github.com/dagger/dagger/releases/tag/v0.15.0). diff --git a/sdk/go/internal/engineconn/version.gen.go b/sdk/go/internal/engineconn/version.gen.go index a6a4cd1961..a21eca19e3 100644 --- a/sdk/go/internal/engineconn/version.gen.go +++ b/sdk/go/internal/engineconn/version.gen.go @@ -2,4 +2,4 @@ package engineconn -const CLIVersion = "0.15.0" +const CLIVersion = "0.15.1" diff --git a/sdk/php/.changes/v0.15.1.md b/sdk/php/.changes/v0.15.1.md new file mode 100644 index 0000000000..b63788e76a --- /dev/null +++ b/sdk/php/.changes/v0.15.1.md @@ -0,0 +1,12 @@ +## sdk/php/v0.15.1 - 2024-12-12 + +This SDK uses ๐Ÿš™ Engine + ๐Ÿš— CLI version `v0.15.1`. [See what changed in that release](https://github.com/dagger/dagger/releases/tag/v0.15.1). + +๐Ÿ˜ https://packagist.org/packages/dagger/dagger#v0.15.1 + +### Dependencies +- Bump Engine to v0.15.1 by @cwlbraa in https://github.com/dagger/dagger/pull/9183 + +### What to do next +- Join our [Discord server](https://discord.gg/dagger-io) +- Follow us on [Twitter](https://twitter.com/dagger_io) diff --git a/sdk/php/CHANGELOG.md b/sdk/php/CHANGELOG.md index 687f04a53e..1e47e65d22 100644 --- a/sdk/php/CHANGELOG.md +++ b/sdk/php/CHANGELOG.md @@ -6,6 +6,19 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## sdk/php/v0.15.1 - 2024-12-12 + +This SDK uses ๐Ÿš™ Engine + ๐Ÿš— CLI version `v0.15.1`. [See what changed in that release](https://github.com/dagger/dagger/releases/tag/v0.15.1). + +๐Ÿ˜ https://packagist.org/packages/dagger/dagger#v0.15.1 + +### Dependencies +- Bump Engine to v0.15.1 by @cwlbraa in https://github.com/dagger/dagger/pull/9183 + +### What to do next +- Join our [Discord server](https://discord.gg/dagger-io) +- Follow us on [Twitter](https://twitter.com/dagger_io) + ## sdk/php/v0.15.0 - 2024-12-10 This SDK uses ๐Ÿš™ Engine + ๐Ÿš— CLI version `v0.15.0`. [See what changed in that release](https://github.com/dagger/dagger/releases/tag/v0.15.0). diff --git a/sdk/php/src/Connection/version.php b/sdk/php/src/Connection/version.php index cca92df9cc..9abc4e5ceb 100644 --- a/sdk/php/src/Connection/version.php +++ b/sdk/php/src/Connection/version.php @@ -1,4 +1,4 @@