Skip to content

Commit

Permalink
feat: Add state delete-bucket command
Browse files Browse the repository at this point in the history
  • Loading branch information
twpayne committed Nov 28, 2021
1 parent 219a09e commit 988fcdc
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 5 deletions.
13 changes: 13 additions & 0 deletions docs/HOWTO.md
Expand Up @@ -47,6 +47,7 @@
* [Understand how scripts work](#understand-how-scripts-work)
* [Install packages with scripts](#install-packages-with-scripts)
* [Run a script when the contents of another file changes](#run-a-script-when-the-contents-of-another-file-changes)
* [Clear the state of `run_once_` scripts](#clear-the-state-of-run_once_-scripts)
* [Use chezmoi on macOS](#use-chezmoi-on-macos)
* [Use `brew bundle` to manage your brews and casks](#use-brew-bundle-to-manage-your-brews-and-casks)
* [Use chezmoi on Windows](#use-chezmoi-on-windows)
Expand Down Expand Up @@ -1432,6 +1433,18 @@ does not create `dconf.ini` in your home directory.

---

### Clear the state of `run_once_` scripts

chezmoi stores whether and when `run_once_` scripts have been run in the
`scriptState` bucket of its persistent state. To clear the state of `run_once_`
scripts, run:

```console
$ chezmoi delete-bucket --bucket=scriptState
```

---

## Use chezmoi on macOS

---
Expand Down
1 change: 1 addition & 0 deletions docs/REFERENCE.md
Expand Up @@ -1702,6 +1702,7 @@ Manipulate the persistent state.
```console
$ chezmoi state data
$ chezmoi state delete --bucket=bucket --key=key
$ chezmoi state delete-bucket --bucket=bucket
$ chezmoi state dump
$ chezmoi state get --bucket=bucket --key=key
$ chezmoi state set --bucket=bucket --key=key --value=value
Expand Down
14 changes: 14 additions & 0 deletions internal/chezmoi/boltpersistentstate.go
Expand Up @@ -111,6 +111,20 @@ func (b *BoltPersistentState) Delete(bucket, key []byte) error {
})
}

// DeleteBucket deletes the bucket.
func (b *BoltPersistentState) DeleteBucket(bucket []byte) error {
if b.empty {
return nil
}
if err := b.open(); err != nil {
return err
}

return b.db.Update(func(tx *bbolt.Tx) error {
return tx.DeleteBucket(bucket)
})
}

// Data returns all the data in b.
func (b *BoltPersistentState) Data() (interface{}, error) {
if b.empty {
Expand Down
9 changes: 9 additions & 0 deletions internal/chezmoi/debugpersistentstate.go
Expand Up @@ -54,6 +54,15 @@ func (s *DebugPersistentState) Delete(bucket, key []byte) error {
return err
}

// DeleteBucket implements PersistentState.DeleteBucket.
func (s *DebugPersistentState) DeleteBucket(bucket []byte) error {
err := s.persistentState.DeleteBucket(bucket)
s.logger.Err(err).
Bytes("bucket", bucket).
Msg("DeleteBucket")
return err
}

// ForEach implements PersistentState.ForEach.
func (s *DebugPersistentState) ForEach(bucket []byte, fn func(k, v []byte) error) error {
err := s.persistentState.ForEach(bucket, func(k, v []byte) error {
Expand Down
6 changes: 6 additions & 0 deletions internal/chezmoi/mockpersistentstate.go
Expand Up @@ -44,6 +44,12 @@ func (s *MockPersistentState) Delete(bucket, key []byte) error {
return nil
}

// DeleteBucket implements PersistentState.DeleteBucket.
func (s *MockPersistentState) DeleteBucket(bucket []byte) error {
delete(s.buckets, string(bucket))
return nil
}

// ForEach implements PersistentState.ForEach.
func (s *MockPersistentState) ForEach(bucket []byte, fn func(k, v []byte) error) error {
for k, v := range s.buckets[string(bucket)] {
Expand Down
3 changes: 3 additions & 0 deletions internal/chezmoi/nullpersistentstate.go
Expand Up @@ -16,6 +16,9 @@ func (NullPersistentState) Data() (interface{}, error) { return nil, nil }
// Delete does nothing.
func (NullPersistentState) Delete(bucket, key []byte) error { return nil }

// DeleteBucket does nothing.
func (NullPersistentState) DeleteBucket(bucket []byte) error { return nil }

// ForEach does nothing.
func (NullPersistentState) ForEach(bucket []byte, fn func(k, v []byte) error) error { return nil }

Expand Down
1 change: 1 addition & 0 deletions internal/chezmoi/persistentstate.go
Expand Up @@ -20,6 +20,7 @@ type PersistentState interface {
CopyTo(s PersistentState) error
Data() (interface{}, error)
Delete(bucket, key []byte) error
DeleteBucket(bucket []byte) error
ForEach(bucket []byte, fn func(k, v []byte) error) error
Get(bucket, key []byte) ([]byte, error)
Set(bucket, key, value []byte) error
Expand Down
34 changes: 29 additions & 5 deletions internal/cmd/statecmd.go
Expand Up @@ -11,11 +11,12 @@ import (
)

type stateCmdConfig struct {
data stateDataCmdConfig
delete stateDeleteCmdConfig
dump stateDumpCmdConfig
get stateGetCmdConfig
set stateSetCmdConfig
data stateDataCmdConfig
delete stateDeleteCmdConfig
deleteBucket stateDeleteBucketCmdConfig
dump stateDumpCmdConfig
get stateGetCmdConfig
set stateSetCmdConfig
}

type stateDataCmdConfig struct {
Expand All @@ -27,6 +28,10 @@ type stateDeleteCmdConfig struct {
key string
}

type stateDeleteBucketCmdConfig struct {
bucket string
}

type stateDumpCmdConfig struct {
format writeDataFormat
}
Expand Down Expand Up @@ -77,6 +82,21 @@ func (c *Config) newStateCmd() *cobra.Command {
stateDeletePersistentFlags.StringVar(&c.state.delete.key, "key", c.state.delete.key, "key")
stateCmd.AddCommand(stateDeleteCmd)

stateDeleteBucketCmd := &cobra.Command{
Use: "delete-bucket",
Short: "Delete a bucket from the persistent state",
Args: cobra.NoArgs,
RunE: c.runStateDeleteBucketCmd,
Annotations: map[string]string{
persistentStateMode: persistentStateModeReadWrite,
},
}
stateDeleteBucketPersistentFlags := stateDeleteBucketCmd.PersistentFlags()
stateDeleteBucketPersistentFlags.StringVar(
&c.state.deleteBucket.bucket, "bucket", c.state.deleteBucket.bucket, "bucket",
)
stateCmd.AddCommand(stateDeleteBucketCmd)

stateDumpCmd := &cobra.Command{
Use: "dump",
Short: "Generate a dump of the persistent state",
Expand Down Expand Up @@ -145,6 +165,10 @@ func (c *Config) runStateDeleteCmd(cmd *cobra.Command, args []string) error {
return c.persistentState.Delete([]byte(c.state.delete.bucket), []byte(c.state.delete.key))
}

func (c *Config) runStateDeleteBucketCmd(cmd *cobra.Command, args []string) error {
return c.persistentState.DeleteBucket([]byte(c.state.deleteBucket.bucket))
}

func (c *Config) runStateDumpCmd(cmd *cobra.Command, args []string) error {
data, err := chezmoi.PersistentStateData(c.persistentState)
if err != nil {
Expand Down
5 changes: 5 additions & 0 deletions internal/cmd/testdata/scripts/state_unix.txt
Expand Up @@ -14,6 +14,11 @@ chezmoi state dump --format=yaml
stdout 70396a619400b7f78dbb83ab8ddb76ffe0b8e31557e64bab2ca9677818a52135:
stdout runAt:

# test that chezmoi delete-bucket deletes a bucket
chezmoi state delete-bucket --bucket=scriptState
chezmoi state dump --format=yaml
! stdout runAt:

# test that chezmoi state reset removes the persistent state
chezmoi --force state reset
! exists $CHEZMOICONFIGDIR/chezmoistate.boltdb
Expand Down

0 comments on commit 988fcdc

Please sign in to comment.