-
Notifications
You must be signed in to change notification settings - Fork 147
/
mutagen.go
130 lines (107 loc) · 4.53 KB
/
mutagen.go
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package filesystem
import (
"os"
"path/filepath"
"github.com/pkg/errors"
"github.com/mutagen-io/mutagen/pkg/mutagen"
)
const (
// MutagenDataDirectoryName is the name of the global Mutagen data directory
// inside the user's home directory.
MutagenDataDirectoryName = ".mutagen"
// MutagenDataDirectoryDevelopmentName is the name of the global Mutagen
// data directory inside the user's home directory for development builds of
// Mutagen.
MutagenDataDirectoryDevelopmentName = ".mutagen-dev"
// MutagenLegacyGlobalSynchronizationConfigurationName is the name of the
// legacy global Mutagen synchronization configuration file inside the
// user's home directory.
MutagenLegacyGlobalSynchronizationConfigurationName = ".mutagen.toml"
// MutagenGlobalConfigurationName is the name of the global Mutagen
// configuration file inside the user's home directory.
MutagenGlobalConfigurationName = ".mutagen.yml"
// MutagenDaemonDirectoryName is the name of the daemon storage directory
// within the Mutagen data directory.
MutagenDaemonDirectoryName = "daemon"
// MutagenAgentsDirectoryName is the name of the agent storage directory
// within the Mutagen data directory.
MutagenAgentsDirectoryName = "agents"
// MutagenSynchronizationSessionsDirectoryName is the name of the
// synchronization session storage directory within the Mutagen data
// directory.
MutagenSynchronizationSessionsDirectoryName = "sessions"
// MutagenSynchronizationCachesDirectoryName is the name of the
// synchronization cache storage directory within the Mutagen data
// directory.
MutagenSynchronizationCachesDirectoryName = "caches"
// MutagenSynchronizationArchivesDirectoryName is the name of the
// synchronization archive storage directory within the Mutagen data
// directory.
MutagenSynchronizationArchivesDirectoryName = "archives"
// MutagenSynchronizationStagingDirectoryName is the name of the
// synchronization staging storage directory within the Mutagen data
// directory.
MutagenSynchronizationStagingDirectoryName = "staging"
// MutagenForwardingDirectoryName is the name of the forwarding data
// directory within the Mutagen data directory.
MutagenForwardingDirectoryName = "forwarding"
// MutagenIODirectoryName is the name of the mutagen.io data directory
// within the Mutagen data directory.
MutagenIODirectoryName = "mutagen.io"
// MutagenTunnelsDirectoryName is the name of the tunnel storage directory
// within the Mutagen data directory.
MutagenTunnelsDirectoryName = "tunnels"
)
// Mutagen computes (and optionally creates) subdirectories inside the Mutagen
// data directory.
func Mutagen(create bool, pathComponents ...string) (string, error) {
// Check if a data directory path has been explicitly specified. If not,
// compute it using the standard procedure. Also track whether or not we
// need to mark the directory as hidden on creation.
mutagenDataDirectoryPath, ok := os.LookupEnv("MUTAGEN_DATA_DIRECTORY")
var hide bool
if ok {
// Validate the provided path.
if mutagenDataDirectoryPath == "" {
return "", errors.New("provided data directory path is empty")
} else if !filepath.IsAbs(mutagenDataDirectoryPath) {
return "", errors.New("provided data directory path is not absolute")
}
} else {
// Compute the path to the user's home directory.
homeDirectory, err := os.UserHomeDir()
if err != nil {
return "", errors.Wrap(err, "unable to compute path to home directory")
}
// Compute the path to the Mutagen data directory.
if !mutagen.DevelopmentModeEnabled {
mutagenDataDirectoryPath = filepath.Join(homeDirectory, MutagenDataDirectoryName)
} else {
mutagenDataDirectoryPath = filepath.Join(homeDirectory, MutagenDataDirectoryDevelopmentName)
}
// Flag the directory for hiding.
hide = true
}
// Compute the target path.
result := filepath.Join(mutagenDataDirectoryPath, filepath.Join(pathComponents...))
// Handle directory creation, if requested.
//
// TODO: Should we iterate through each component and ensure the user hasn't
// changed the directory permissions? MkdirAll won't reset them. But I
// suppose the user may have changed them for whatever reason (though I
// can't imagine any).
if create {
// Create the directory.
if err := os.MkdirAll(result, 0700); err != nil {
return "", errors.Wrap(err, "unable to create subpath")
}
// Mark the directory as hidden, if necessary.
if hide {
if err := MarkHidden(mutagenDataDirectoryPath); err != nil {
return "", errors.Wrap(err, "unable to hide Mutagen data directory")
}
}
}
// Success.
return result, nil
}