Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add clean command #28

Merged
merged 2 commits into from
Sep 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions cmd/aspect/clean/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")

go_library(
name = "clean",
srcs = ["clean.go"],
importpath = "aspect.build/cli/cmd/aspect/clean",
visibility = ["//visibility:public"],
deps = [
"//pkg/aspect/clean",
"//pkg/bazel",
"//pkg/ioutils",
"@com_github_spf13_cobra//:cobra",
],
)
77 changes: 77 additions & 0 deletions cmd/aspect/clean/clean.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
Copyright © 2021 Aspect Build Systems Inc

Not licensed for re-use.
*/

package clean

import (
"github.com/spf13/cobra"

"aspect.build/cli/pkg/aspect/clean"
"aspect.build/cli/pkg/bazel"
"aspect.build/cli/pkg/ioutils"
)

// NewDefaultCleanCmd creates a new clean cobra command with the default
// dependencies.
func NewDefaultCleanCmd() *cobra.Command {
return NewCleanCmd(ioutils.DefaultStreams, bazel.New())
}

// NewCleanCmd creates a new clean cobra command.
func NewCleanCmd(
streams ioutils.Streams,
bzl bazel.Spawner,
) *cobra.Command {
b := clean.New(streams, bzl)

cmd := &cobra.Command{
Use: "clean",
Short: "Removes the output tree.",
Long: `Removes bazel-created output, including all object files, and bazel metadata.

clean deletes the output directories for all build configurations performed by
this Bazel instance, or the entire working tree created by this Bazel instance,
and resets internal caches.

If executed without any command-line options, then the output directory for all
configurations will be cleaned.

Recall that each Bazel instance is associated with a single workspace,
thus the clean command will delete all outputs from all builds you've
done with that Bazel instance in that workspace.

NOTE: clean is primarily intended for reclaiming disk space for workspaces
that are no longer needed.
It causes all subsequent builds to be non-incremental.
If this is not your intent, consider these alternatives:

Do a one-off non-incremental build:
bazel --output_base=$(mktemp -d) ...

Force repository rules to re-execute:
bazel sync --configure

Workaround inconistent state:
Bazel's incremental rebuilds are designed to be correct, so clean
should never be required due to inconsistencies in the build.
Such problems are fixable and these bugs are a high priority.
If you ever find an incorrect incremental build, please file a bug report,
and only use clean as a temporary workaround.`,
RunE: b.Run,
}

cmd.PersistentFlags().BoolVarP(&b.Expunge, "expunge", "", false, `Remove the entire output_base tree.
This removes all build output, external repositories,
and temp files created by Bazel.
It also stops the Bazel server after the clean,
equivalent to the shutdown command.`)

cmd.PersistentFlags().BoolVarP(&b.ExpungeAsync, "expunge_async", "", false, `Expunge in the background.
It is safe to invoke a Bazel command in the same
workspace while the asynchronous expunge continues to run.
Note, however, that this may introduce IO contention.`)
return cmd
}
6 changes: 3 additions & 3 deletions cmd/aspect/docs/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ func NewDocsCmd(streams ioutils.Streams) *cobra.Command {

cmd := &cobra.Command{
Use: "docs",
Short: "Open documentation in the browser",
Short: "Open documentation in the browser.",
Long: `Given a selected topic, open the relevant API docs in a browser window.
The mechanism of choosing the browser to open is documented at https://github.com/pkg/browser
By default, opens docs.bazel.build`,
The mechanism of choosing the browser to open is documented at https://github.com/pkg/browser
By default, opens docs.bazel.build`,
RunE: v.Run,
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/aspect/info/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func NewInfoCmd(streams ioutils.Streams) *cobra.Command {

cmd := &cobra.Command{
Use: "info",
Short: "Displays runtime info about the bazel server",
Short: "Displays runtime info about the bazel server.",
Long: `Displays information about the state of the bazel process in the
form of several "key: value" pairs. This includes the locations of
several output directories. Because some of the
Expand Down
1 change: 1 addition & 0 deletions cmd/aspect/root/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ go_library(
],
deps = [
"//cmd/aspect/build",
"//cmd/aspect/clean",
"//cmd/aspect/docs",
"//cmd/aspect/info",
"//cmd/aspect/version",
Expand Down
2 changes: 2 additions & 0 deletions cmd/aspect/root/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/spf13/viper"

"aspect.build/cli/cmd/aspect/build"
"aspect.build/cli/cmd/aspect/clean"
"aspect.build/cli/cmd/aspect/docs"
"aspect.build/cli/cmd/aspect/info"
"aspect.build/cli/cmd/aspect/version"
Expand Down Expand Up @@ -69,6 +70,7 @@ func NewRootCmd(streams ioutils.Streams, defaultInteractive bool) *cobra.Command
// ### Child commands
// IMPORTANT: when adding a new command, also update the _DOCS list in /docs/BUILD.bazel
cmd.AddCommand(build.NewDefaultBuildCmd())
cmd.AddCommand(clean.NewDefaultCleanCmd())
cmd.AddCommand(version.NewDefaultVersionCmd())
cmd.AddCommand(docs.NewDefaultDocsCmd())
cmd.AddCommand(info.NewDefaultInfoCmd())
Expand Down
2 changes: 1 addition & 1 deletion cmd/aspect/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func NewVersionCmd(streams ioutils.Streams) *cobra.Command {

cmd := &cobra.Command{
Use: "version",
Short: "Print the version of aspect CLI as well as tools it invokes",
Short: "Print the version of aspect CLI as well as tools it invokes.",
Long: `Prints version info on colon-separated lines, just like bazel does`,
RunE: v.Run,
}
Expand Down
1 change: 1 addition & 0 deletions docs/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ load("@bazel_skylib//rules:write_file.bzl", "write_file")
_DOCS = [
"aspect.md",
"aspect_build.md",
"aspect_clean.md",
"aspect_docs.md",
"aspect_info.md",
"aspect_version.md",
Expand Down
7 changes: 4 additions & 3 deletions docs/aspect.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ Aspect CLI is a better frontend for running bazel
### SEE ALSO

* [aspect build](aspect_build.md) - Builds the specified targets, using the options.
* [aspect docs](aspect_docs.md) - Open documentation in the browser
* [aspect info](aspect_info.md) - Displays runtime info about the bazel server
* [aspect version](aspect_version.md) - Print the version of aspect CLI as well as tools it invokes
* [aspect clean](aspect_clean.md) - Removes the output tree.
* [aspect docs](aspect_docs.md) - Open documentation in the browser.
* [aspect info](aspect_info.md) - Displays runtime info about the bazel server.
* [aspect version](aspect_version.md) - Print the version of aspect CLI as well as tools it invokes.

###### Auto generated by spf13/cobra
68 changes: 68 additions & 0 deletions docs/aspect_clean.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
## aspect clean

Removes the output tree.

### Synopsis

Removes bazel-created output, including all object files, and bazel metadata.

clean deletes the output directories for all build configurations performed by
this Bazel instance, or the entire working tree created by this Bazel instance,
and resets internal caches.

If executed without any command-line options, then the output directory for all
configurations will be cleaned.

Recall that each Bazel instance is associated with a single workspace,
thus the clean command will delete all outputs from all builds you've
done with that Bazel instance in that workspace.

NOTE: clean is primarily intended for reclaiming disk space for workspaces
that are no longer needed.
It causes all subsequent builds to be non-incremental.
If this is not your intent, consider these alternatives:

Do a one-off non-incremental build:
bazel --output_base=$(mktemp -d) ...

Force repository rules to re-execute:
bazel sync --configure

Workaround inconistent state:
Bazel's incremental rebuilds are designed to be correct, so clean
should never be required due to inconsistencies in the build.
Such problems are fixable and these bugs are a high priority.
If you ever find an incorrect incremental build, please file a bug report,
and only use clean as a temporary workaround.

```
aspect clean [flags]
```

### Options

```
--expunge Remove the entire output_base tree.
This removes all build output, external repositories,
and temp files created by Bazel.
It also stops the Bazel server after the clean,
equivalent to the shutdown command.
--expunge_async Expunge in the background.
It is safe to invoke a Bazel command in the same
workspace while the asynchronous expunge continues to run.
Note, however, that this may introduce IO contention.
-h, --help help for clean
```

### Options inherited from parent commands

```
--config string config file (default is $HOME/.aspect.yaml)
--interactive Interactive mode (e.g. prompts for user input)
```

### SEE ALSO

* [aspect](aspect.md) - Aspect.build bazel wrapper

###### Auto generated by spf13/cobra
6 changes: 3 additions & 3 deletions docs/aspect_docs.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
## aspect docs

Open documentation in the browser
Open documentation in the browser.

### Synopsis

Given a selected topic, open the relevant API docs in a browser window.
The mechanism of choosing the browser to open is documented at https://github.com/pkg/browser
By default, opens docs.bazel.build
The mechanism of choosing the browser to open is documented at https://github.com/pkg/browser
By default, opens docs.bazel.build

```
aspect docs [flags]
Expand Down
2 changes: 1 addition & 1 deletion docs/aspect_info.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## aspect info

Displays runtime info about the bazel server
Displays runtime info about the bazel server.

### Synopsis

Expand Down
2 changes: 1 addition & 1 deletion docs/aspect_version.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## aspect version

Print the version of aspect CLI as well as tools it invokes
Print the version of aspect CLI as well as tools it invokes.

### Synopsis

Expand Down
27 changes: 27 additions & 0 deletions pkg/aspect/clean/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")

go_library(
name = "clean",
srcs = ["clean.go"],
importpath = "aspect.build/cli/pkg/aspect/clean",
visibility = ["//visibility:public"],
deps = [
"//pkg/aspecterrors",
"//pkg/bazel",
"//pkg/ioutils",
"@com_github_spf13_cobra//:cobra",
],
)

go_test(
name = "clean_test",
srcs = ["clean_test.go"],
deps = [
":clean",
"//pkg/aspecterrors",
"//pkg/bazel/mock",
"//pkg/ioutils",
"@com_github_golang_mock//gomock",
"@com_github_onsi_gomega//:gomega",
],
)
64 changes: 64 additions & 0 deletions pkg/aspect/clean/clean.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
Copyright © 2021 Aspect Build Systems Inc

Not licensed for re-use.
*/

package clean

import (
"github.com/spf13/cobra"

"aspect.build/cli/pkg/aspecterrors"
"aspect.build/cli/pkg/bazel"
"aspect.build/cli/pkg/ioutils"
)

// Clean represents the aspect clean command.
type Clean struct {
ioutils.Streams
bzl bazel.Spawner

Expunge bool
ExpungeAsync bool
}

// New creates a Clean command.
func New(
streams ioutils.Streams,
bzl bazel.Spawner,
) *Clean {
return &Clean{
Streams: streams,
bzl: bzl,
}
}

// Run runs the aspect build command.
func (c *Clean) Run(_ *cobra.Command, _ []string) error {
// TODO(alex): when interactive, prompt the user:
// First time running aspect clean?
// Then ask, why do you want to clean?
// - reclaim disk space?
// - workaround inconsistent state
// - experiment with a one-off non-incremental build
// then ask
// do you want to see this wizard again next time?
// and if not, record in the cache file to inhibit next time
cmd := []string{"clean"}
if c.Expunge {
cmd = append(cmd, "--expunge")
}
if c.ExpungeAsync {
cmd = append(cmd, "--expunge_async")
}
if exitCode, err := c.bzl.Spawn(cmd); exitCode != 0 {
err = &aspecterrors.ExitError{
Err: err,
ExitCode: exitCode,
}
return err
}

return nil
}
Loading