diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e1153d490..545e830e20 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ determinisitic. - Add `buf plugin push` command to push a plugin to the Buf Schema Registry. Only WebAssembly check plugins are supported at this time. +- Add `buf plugin update` and `buf plugin prune` command to manage plugins in the `buf.lock` + file. Only WebAssembly check plugins are supported at this time. - Add `buf registry plugin commit {add-label,info,list,resolve}` to manage BSR plugin commits. - Add `buf registry plugin label {archive,info,list,unarchive}` to manage BSR plugin commits. diff --git a/private/buf/cmd/buf/buf.go b/private/buf/cmd/buf/buf.go index cc8e61a481..5febab7e33 100644 --- a/private/buf/cmd/buf/buf.go +++ b/private/buf/cmd/buf/buf.go @@ -62,6 +62,7 @@ import ( "github.com/bufbuild/buf/private/buf/cmd/buf/command/mod/modlsbreakingrules" "github.com/bufbuild/buf/private/buf/cmd/buf/command/mod/modlslintrules" "github.com/bufbuild/buf/private/buf/cmd/buf/command/mod/modopen" + "github.com/bufbuild/buf/private/buf/cmd/buf/command/plugin/pluginprune" "github.com/bufbuild/buf/private/buf/cmd/buf/command/plugin/pluginpush" "github.com/bufbuild/buf/private/buf/cmd/buf/command/plugin/pluginupdate" "github.com/bufbuild/buf/private/buf/cmd/buf/command/push" @@ -191,6 +192,7 @@ func NewRootCommand(name string) *appcmd.Command { SubCommands: []*appcmd.Command{ pluginpush.NewCommand("push", builder), pluginupdate.NewCommand("update", builder), + pluginprune.NewCommand("prune", builder), }, }, { diff --git a/private/buf/cmd/buf/command/plugin/pluginprune/pluginprune.go b/private/buf/cmd/buf/command/plugin/pluginprune/pluginprune.go new file mode 100644 index 0000000000..f2dd2769c8 --- /dev/null +++ b/private/buf/cmd/buf/command/plugin/pluginprune/pluginprune.go @@ -0,0 +1,106 @@ +// Copyright 2020-2024 Buf Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package pluginprune + +import ( + "context" + + "github.com/bufbuild/buf/private/buf/bufcli" + "github.com/bufbuild/buf/private/buf/bufworkspace" + "github.com/bufbuild/buf/private/bufpkg/bufparse" + "github.com/bufbuild/buf/private/bufpkg/bufplugin" + "github.com/bufbuild/buf/private/pkg/app/appcmd" + "github.com/bufbuild/buf/private/pkg/app/appext" + "github.com/bufbuild/buf/private/pkg/slicesext" +) + +// NewCommand returns a new Command. +func NewCommand( + name string, + builder appext.SubCommandBuilder, +) *appcmd.Command { + return &appcmd.Command{ + Use: name + " ", + Short: "Prune unused plugins from buf.lock", + Long: `Plugins that are no longer configured in buf.yaml are removed from the buf.lock file. + +The first argument is the directory of your buf.yaml configuration file. +Defaults to "." if no argument is specified.`, + Args: appcmd.MaximumNArgs(1), + Run: builder.NewRunFunc( + func(ctx context.Context, container appext.Container) error { + return run(ctx, container) + }, + ), + } +} + +func run( + ctx context.Context, + container appext.Container, +) error { + dirPath := "." + if container.NumArgs() > 0 { + dirPath = container.Arg(0) + } + controller, err := bufcli.NewController(container) + if err != nil { + return err + } + workspaceDepManager, err := controller.GetWorkspaceDepManager(ctx, dirPath) + if err != nil { + return err + } + configuredRemotePluginRefs, err := workspaceDepManager.ConfiguredRemotePluginRefs(ctx) + if err != nil { + return err + } + return prune( + ctx, + slicesext.Map( + configuredRemotePluginRefs, + func(pluginRef bufparse.Ref) string { + return pluginRef.FullName().String() + }, + ), + workspaceDepManager, + ) +} + +func prune( + ctx context.Context, + bufYAMLBasedRemotePluginNames []string, + workspaceDepManager bufworkspace.WorkspaceDepManager, +) error { + bufYAMLRemotePluginNames := slicesext.ToStructMap(bufYAMLBasedRemotePluginNames) + existingRemotePluginKeys, err := workspaceDepManager.ExistingBufLockFileRemotePluginKeys(ctx) + if err != nil { + return err + } + var prunedBufLockPluginKeys []bufplugin.PluginKey + for _, existingRemotePluginKey := range existingRemotePluginKeys { + // Check if an existing plugin key from the buf.lock is confiugred in the buf.yaml. + if _, ok := bufYAMLRemotePluginNames[existingRemotePluginKey.FullName().String()]; ok { + // If yes, then we keep it for the updated buf.lock. + prunedBufLockPluginKeys = append(prunedBufLockPluginKeys, existingRemotePluginKey) + } + } + // We keep the existing dep module keys as-is. + existingDepModuleKeys, err := workspaceDepManager.ExistingBufLockFileDepModuleKeys(ctx) + if err != nil { + return err + } + return workspaceDepManager.UpdateBufLockFile(ctx, existingDepModuleKeys, prunedBufLockPluginKeys) +} diff --git a/private/buf/cmd/buf/command/plugin/pluginprune/usage.gen.go b/private/buf/cmd/buf/command/plugin/pluginprune/usage.gen.go new file mode 100644 index 0000000000..9f84b1ce9e --- /dev/null +++ b/private/buf/cmd/buf/command/plugin/pluginprune/usage.gen.go @@ -0,0 +1,19 @@ +// Copyright 2020-2024 Buf Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Generated. DO NOT EDIT. + +package pluginprune + +import _ "github.com/bufbuild/buf/private/usage"