Port cache bash script to Go for helper image

`gitlab-runner-cache` is being used to change the permissions, port
this script to Go so that it is cross-platform.

The bash script loops through the paths but separating them with
spaces, which will not work for Windows since it is a lot more common to
have a directory with spaces. Looking at the usage of the script we
always send 1 path so the loop was a bit redundant.

For now do not use the Go command since changing it will result into a
breaking change. This will be done behind a feature flag which will done
in a feature MR.

parent fe278781
Pipeline #49090792 (#7260) passed with stages
in 29 minutes and 27 seconds
package helpers
import (
// CacheInitCommand will take a single directory/file path and initialize it
// correctly for it to be used for cache. This command tries to support spaces
// in directories name by using the the flags to specify which entries you want
// to initialize.
type CacheInitCommand struct{}
func (c *CacheInitCommand) Execute(ctx *cli.Context) {
if ctx.NArg() == 0 {
logrus.Fatal("No arguments passed, at least 1 path is required.")
for _, path := range ctx.Args() {
err := os.Chmod(path, os.ModePerm)
if err != nil {
logrus.WithError(err).Error("failed to chmod path")
func init() {
common.RegisterCommand2("cache-init", "changed permissions for cache paths (internal)", &CacheInitCommand{})
package helpers
import (
func newCacheInitTestApp() *cli.App {
cmd := &CacheInitCommand{}
app := cli.NewApp()
app.Name = path.Base(os.Args[0])
app.Commands = append(app.Commands, cli.Command{
Name: "cache-init",
Action: cmd.Execute,
return app
func TestCacheInit(t *testing.T) {
// Specifically test a file name with spaces.
file, err := ioutil.TempFile("", "Test Cache Chmod")
require.NoError(t, err)
defer os.Remove(file.Name())
// Make sure that the mode is not the expect 0777.
err = os.Chmod(file.Name(), 0600)
require.NoError(t, err)
// Start a new cli with the arguments for the command.
args := os.Args[0:1]
args = append(args, "cache-init", file.Name())
err = newCacheInitTestApp().Run(args)
require.NoError(t, err)
info, err := os.Stat(file.Name())
require.NoError(t, err)
assert.Equal(t, os.ModePerm, info.Mode())
func TestCacheInit_NoArguments(t *testing.T) {
removeHook := helpers.MakeFatalToPanic()
defer removeHook()
args := os.Args[0:1]
args = append(args, "cache-init")
assert.Panics(t, func() {
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment