forked from aws/amazon-ecs-cli
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfs_cache.go
More file actions
104 lines (92 loc) · 2.74 KB
/
fs_cache.go
File metadata and controls
104 lines (92 loc) · 2.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// Copyright 2015-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"). You may
// not use this file except in compliance with the License. A copy of the
// License is located at
//
// http://aws.amazon.com/apache2.0/
//
// or in the "license" file accompanying this file. This file 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 cache
import (
"encoding/gob"
"os"
"path/filepath"
"runtime"
"github.com/aws/amazon-ecs-cli/ecs-cli/modules/config"
"github.com/aws/amazon-ecs-cli/ecs-cli/modules/utils"
)
// available for injecting mocks for testing
var osOpen = os.Open
var osCreate = os.Create
var osMkdirAll = os.MkdirAll
var getOSName = func() string {
return runtime.GOOS
}
// rw only for the user in-line with how most programs setup their cache
// directories. Also, this directory could container sensitive-ish files due to
// environment variables, so keep it user-only.
const cacheDirMode = 0700
const cachePrefix = "ecs-cli"
// cacheDir is a helper function to return the 'cache' directory for a given
// application name
func cacheDir(name string) (string, error) {
homedir, err := utils.GetHomeDir()
if err != nil {
return "", err
}
path := filepath.Join(homedir, ".cache", cachePrefix, name)
if getOSName() == "windows" {
path = filepath.Join(homedir, config.GetWindowsBaseDataPath(), "cache", name)
}
return path, nil
}
type fsCache struct {
name string
cacheDir string
}
// NewFSCache returns a new cache backed by the filesystem. The 'name' value
// should be constant in order to access the same data between uses.
// The cache will be namespaced under this project
func NewFSCache(name string) (Cache, error) {
dir, err := cacheDir(name)
if err != nil {
return nil, err
}
err = osMkdirAll(dir, cacheDirMode)
if err != nil {
return nil, err
}
return &fsCache{
name: name,
cacheDir: dir,
}, nil
}
func (cache *fsCache) Put(key string, val interface{}) (retErr error) {
file, err := osCreate(filepath.Join(cache.cacheDir, key))
if err != nil {
return err
}
defer func() {
closeErr := file.Close()
// Avoid masking the 'gob.Encode' error, it's earlier and probably more specific
if closeErr != nil && retErr == nil {
// named return error
retErr = closeErr
}
}()
valEnc := gob.NewEncoder(file)
return valEnc.Encode(val)
}
func (cache *fsCache) Get(key string, i interface{}) error {
file, err := osOpen(filepath.Join(cache.cacheDir, key))
if err != nil {
return err
}
defer file.Close()
valDec := gob.NewDecoder(file)
return valDec.Decode(i)
}