Skip to content

Commit 21f55c9

Browse files
authored
feat(cache): add --global flag for overriding scope (#330)
# Summary Adds the `--global` flag to the `cache get`, `cache set`, and `cache remove`. This flag force the execution to use the global cache, even when run within the scope of an executable. Closes #329
1 parent fa976b2 commit 21f55c9

File tree

8 files changed

+133
-15
lines changed

8 files changed

+133
-15
lines changed

cmd/internal/cache.go

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,11 @@ func registerCacheSetCmd(ctx *context.Context, rootCmd *cobra.Command) {
4444
cacheSetFunc(ctx, cmd, args)
4545
},
4646
}
47+
RegisterFlag(ctx, subCmd, *flags.GlobalCacheFlag)
4748
rootCmd.AddCommand(subCmd)
4849
}
4950

50-
func cacheSetFunc(ctx *context.Context, _ *cobra.Command, args []string) {
51+
func cacheSetFunc(ctx *context.Context, cmd *cobra.Command, args []string) {
5152
key := args[0]
5253

5354
var value string
@@ -80,7 +81,12 @@ func cacheSetFunc(ctx *context.Context, _ *cobra.Command, args []string) {
8081
if err != nil {
8182
logger.Log().FatalErr(err)
8283
}
83-
if _, err = s.CreateAndSetBucket(store.EnvironmentBucket()); err != nil {
84+
bucketName := store.EnvironmentBucket()
85+
global := flags.ValueFor[bool](cmd, *flags.GlobalCacheFlag, false)
86+
if global {
87+
bucketName = store.RootBucket
88+
}
89+
if _, err = s.CreateAndSetBucket(bucketName); err != nil {
8490
logger.Log().FatalErr(err)
8591
}
8692
defer func() {
@@ -105,17 +111,23 @@ func registerCacheGetCmd(ctx *context.Context, rootCmd *cobra.Command) {
105111
cacheGetFunc(ctx, cmd, args)
106112
},
107113
}
114+
RegisterFlag(ctx, subCmd, *flags.GlobalCacheFlag)
108115
rootCmd.AddCommand(subCmd)
109116
}
110117

111-
func cacheGetFunc(_ *context.Context, _ *cobra.Command, args []string) {
118+
func cacheGetFunc(_ *context.Context, cmd *cobra.Command, args []string) {
112119
key := args[0]
113120

114121
s, err := store.NewStore(store.Path())
115122
if err != nil {
116123
logger.Log().FatalErr(err)
117124
}
118-
if _, err = s.CreateAndSetBucket(store.EnvironmentBucket()); err != nil {
125+
bucketName := store.EnvironmentBucket()
126+
global := flags.ValueFor[bool](cmd, *flags.GlobalCacheFlag, false)
127+
if global {
128+
bucketName = store.RootBucket
129+
}
130+
if _, err = s.CreateAndSetBucket(bucketName); err != nil {
119131
logger.Log().FatalErr(err)
120132
}
121133
defer func() {
@@ -184,17 +196,23 @@ func registerCacheRemoveCmd(ctx *context.Context, rootCmd *cobra.Command) {
184196
cacheRemoveFunc(ctx, cmd, args)
185197
},
186198
}
199+
RegisterFlag(ctx, subCmd, *flags.GlobalCacheFlag)
187200
rootCmd.AddCommand(subCmd)
188201
}
189202

190-
func cacheRemoveFunc(_ *context.Context, _ *cobra.Command, args []string) {
203+
func cacheRemoveFunc(_ *context.Context, cmd *cobra.Command, args []string) {
191204
key := args[0]
192205

193206
s, err := store.NewStore(store.Path())
194207
if err != nil {
195208
logger.Log().FatalErr(err)
196209
}
197-
if _, err = s.CreateAndSetBucket(store.EnvironmentBucket()); err != nil {
210+
bucketName := store.EnvironmentBucket()
211+
global := flags.ValueFor[bool](cmd, *flags.GlobalCacheFlag, false)
212+
if global {
213+
bucketName = store.RootBucket
214+
}
215+
if _, err = s.CreateAndSetBucket(bucketName); err != nil {
198216
logger.Log().FatalErr(err)
199217
}
200218
defer func() {
@@ -250,4 +268,5 @@ func cacheClearFunc(_ *context.Context, cmd *cobra.Command, _ []string) {
250268
var dataStoreDescription = "The data store is a key-value store that can be used to persist data across executions. " +
251269
"Values that are set outside of an executable will persist across all executions until they are cleared. " +
252270
"When set within an executable, the data will only persist across serial or parallel sub-executables but all " +
253-
"values will be cleared when the parent executable completes.\n\n"
271+
"values will be cleared when the parent executable completes. " +
272+
"Use the --global flag to force use of the global cache scope, even when called from within an executable.\n\n"

cmd/internal/flags/types.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,3 +265,11 @@ var VaultFromFileFlag = &Metadata{
265265
Default: "",
266266
Required: false,
267267
}
268+
269+
var GlobalCacheFlag = &Metadata{
270+
Name: "global",
271+
Shorthand: "g",
272+
Usage: "Force use of the global cache scope, even when called from within an executable",
273+
Default: false,
274+
Required: false,
275+
}

docs/cli/flow_cache_clear.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Clear cache data. Use --all to remove data across all scopes.
44

55
### Synopsis
66

7-
The data store is a key-value store that can be used to persist data across executions. Values that are set outside of an executable will persist across all executions until they are cleared. When set within an executable, the data will only persist across serial or parallel sub-executables but all values will be cleared when the parent executable completes.
7+
The data store is a key-value store that can be used to persist data across executions. Values that are set outside of an executable will persist across all executions until they are cleared. When set within an executable, the data will only persist across serial or parallel sub-executables but all values will be cleared when the parent executable completes. Use the --global flag to force use of the global cache scope, even when called from within an executable.
88

99
This will remove all keys and values from the data store.
1010

docs/cli/flow_cache_get.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Get cached data by key.
44

55
### Synopsis
66

7-
The data store is a key-value store that can be used to persist data across executions. Values that are set outside of an executable will persist across all executions until they are cleared. When set within an executable, the data will only persist across serial or parallel sub-executables but all values will be cleared when the parent executable completes.
7+
The data store is a key-value store that can be used to persist data across executions. Values that are set outside of an executable will persist across all executions until they are cleared. When set within an executable, the data will only persist across serial or parallel sub-executables but all values will be cleared when the parent executable completes. Use the --global flag to force use of the global cache scope, even when called from within an executable.
88

99
This will retrieve the value for the given key.
1010

@@ -15,7 +15,8 @@ flow cache get KEY [flags]
1515
### Options
1616

1717
```
18-
-h, --help help for get
18+
-g, --global Force use of the global cache scope, even when called from within an executable
19+
-h, --help help for get
1920
```
2021

2122
### Options inherited from parent commands

docs/cli/flow_cache_list.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ List all keys in the store.
44

55
### Synopsis
66

7-
The data store is a key-value store that can be used to persist data across executions. Values that are set outside of an executable will persist across all executions until they are cleared. When set within an executable, the data will only persist across serial or parallel sub-executables but all values will be cleared when the parent executable completes.
7+
The data store is a key-value store that can be used to persist data across executions. Values that are set outside of an executable will persist across all executions until they are cleared. When set within an executable, the data will only persist across serial or parallel sub-executables but all values will be cleared when the parent executable completes. Use the --global flag to force use of the global cache scope, even when called from within an executable.
88

99
This will list all keys currently stored in the data store.
1010

docs/cli/flow_cache_remove.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Remove a key from the cached data store.
44

55
### Synopsis
66

7-
The data store is a key-value store that can be used to persist data across executions. Values that are set outside of an executable will persist across all executions until they are cleared. When set within an executable, the data will only persist across serial or parallel sub-executables but all values will be cleared when the parent executable completes.
7+
The data store is a key-value store that can be used to persist data across executions. Values that are set outside of an executable will persist across all executions until they are cleared. When set within an executable, the data will only persist across serial or parallel sub-executables but all values will be cleared when the parent executable completes. Use the --global flag to force use of the global cache scope, even when called from within an executable.
88

99
This will remove the specified key and its value from the data store.
1010

@@ -15,7 +15,8 @@ flow cache remove KEY [flags]
1515
### Options
1616

1717
```
18-
-h, --help help for remove
18+
-g, --global Force use of the global cache scope, even when called from within an executable
19+
-h, --help help for remove
1920
```
2021

2122
### Options inherited from parent commands

docs/cli/flow_cache_set.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Set cached data by key.
44

55
### Synopsis
66

7-
The data store is a key-value store that can be used to persist data across executions. Values that are set outside of an executable will persist across all executions until they are cleared. When set within an executable, the data will only persist across serial or parallel sub-executables but all values will be cleared when the parent executable completes.
7+
The data store is a key-value store that can be used to persist data across executions. Values that are set outside of an executable will persist across all executions until they are cleared. When set within an executable, the data will only persist across serial or parallel sub-executables but all values will be cleared when the parent executable completes. Use the --global flag to force use of the global cache scope, even when called from within an executable.
88

99
This will overwrite any existing value for the key.
1010

@@ -15,7 +15,8 @@ flow cache set KEY [VALUE] [flags]
1515
### Options
1616

1717
```
18-
-h, --help help for set
18+
-g, --global Force use of the global cache scope, even when called from within an executable
19+
-h, --help help for set
1920
```
2021

2122
### Options inherited from parent commands

tests/cache_cmds_e2e_test.go

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,4 +130,92 @@ var _ = Describe("cache e2e", Ordered, func() {
130130
Expect(out).NotTo(ContainSubstring("multi-key"))
131131
})
132132
})
133+
134+
When("using the --global flag", Ordered, func() {
135+
BeforeAll(func() {
136+
Expect(run.Run(ctx.Context, "cache", "clear", "--all")).To(Succeed())
137+
utils.ResetTestContext(ctx, GinkgoTB())
138+
})
139+
140+
It("should set a value in the global scope with --global flag", func() {
141+
Expect(run.Run(ctx.Context, "cache", "set", "--global", "global-key", "global-value")).To(Succeed())
142+
out, err := readFileContent(ctx.StdOut())
143+
Expect(err).NotTo(HaveOccurred())
144+
Expect(out).To(ContainSubstring("Key \"global-key\" set in the cache"))
145+
})
146+
147+
It("should retrieve a value from the global scope with --global flag", func() {
148+
utils.ResetTestContext(ctx, GinkgoTB())
149+
stdOut := ctx.StdOut()
150+
Expect(run.Run(ctx.Context, "cache", "get", "--global", "global-key")).To(Succeed())
151+
out, err := readFileContent(stdOut)
152+
Expect(err).NotTo(HaveOccurred())
153+
Expect(out).To(ContainSubstring("global-value"))
154+
})
155+
156+
It("should set a value in execution scope without --global flag", func() {
157+
utils.ResetTestContext(ctx, GinkgoTB())
158+
// Simulate being in an execution by setting the bucket env var
159+
GinkgoTB().Setenv("FLOW_PROCESS_BUCKET", "test:exec:scope")
160+
Expect(run.Run(ctx.Context, "cache", "set", "exec-key", "exec-value")).To(Succeed())
161+
out, err := readFileContent(ctx.StdOut())
162+
Expect(err).NotTo(HaveOccurred())
163+
Expect(out).To(ContainSubstring("Key \"exec-key\" set in the cache"))
164+
})
165+
166+
It("should retrieve exec scope value without --global flag", func() {
167+
utils.ResetTestContext(ctx, GinkgoTB())
168+
GinkgoTB().Setenv("FLOW_PROCESS_BUCKET", "test:exec:scope")
169+
stdOut := ctx.StdOut()
170+
Expect(run.Run(ctx.Context, "cache", "get", "exec-key")).To(Succeed())
171+
out, err := readFileContent(stdOut)
172+
Expect(err).NotTo(HaveOccurred())
173+
Expect(out).To(ContainSubstring("exec-value"))
174+
})
175+
176+
It("should set value in global scope even when in execution context", func() {
177+
utils.ResetTestContext(ctx, GinkgoTB())
178+
GinkgoTB().Setenv("FLOW_PROCESS_BUCKET", "test:exec:scope")
179+
Expect(run.Run(ctx.Context, "cache", "set", "--global", "override-key", "override-value")).To(Succeed())
180+
out, err := readFileContent(ctx.StdOut())
181+
Expect(err).NotTo(HaveOccurred())
182+
Expect(out).To(ContainSubstring("Key \"override-key\" set in the cache"))
183+
})
184+
185+
It("should retrieve global value with --global flag from execution context", func() {
186+
utils.ResetTestContext(ctx, GinkgoTB())
187+
GinkgoTB().Setenv("FLOW_PROCESS_BUCKET", "test:exec:scope")
188+
stdOut := ctx.StdOut()
189+
Expect(run.Run(ctx.Context, "cache", "get", "--global", "override-key")).To(Succeed())
190+
out, err := readFileContent(stdOut)
191+
Expect(err).NotTo(HaveOccurred())
192+
Expect(out).To(ContainSubstring("override-value"))
193+
})
194+
195+
It("should retrieve global value without execution context", func() {
196+
utils.ResetTestContext(ctx, GinkgoTB())
197+
stdOut := ctx.StdOut()
198+
Expect(run.Run(ctx.Context, "cache", "get", "--global", "override-key")).To(Succeed())
199+
out, err := readFileContent(stdOut)
200+
Expect(err).NotTo(HaveOccurred())
201+
Expect(out).To(ContainSubstring("override-value"))
202+
})
203+
204+
It("should remove a value from global scope with --global flag", func() {
205+
utils.ResetTestContext(ctx, GinkgoTB())
206+
Expect(run.Run(ctx.Context, "cache", "remove", "--global", "global-key")).To(Succeed())
207+
out, err := readFileContent(ctx.StdOut())
208+
Expect(err).NotTo(HaveOccurred())
209+
Expect(out).To(ContainSubstring("Key \"global-key\" removed from the cache"))
210+
})
211+
212+
It("should remove a value from global scope with --global in execution context", func() {
213+
utils.ResetTestContext(ctx, GinkgoTB())
214+
GinkgoTB().Setenv("FLOW_PROCESS_BUCKET", "test:exec:scope")
215+
Expect(run.Run(ctx.Context, "cache", "remove", "--global", "override-key")).To(Succeed())
216+
out, err := readFileContent(ctx.StdOut())
217+
Expect(err).NotTo(HaveOccurred())
218+
Expect(out).To(ContainSubstring("Key \"override-key\" removed from the cache"))
219+
})
220+
})
133221
})

0 commit comments

Comments
 (0)