@cryptotaxi247 / kubo / commits / c53f3c552

chore: stop using go-homedir (#10568)

* chore: stop using go-homedir The `github.com/mitchellh/go-homedir` repo is archived, no longer needed, and no longer maintained. - `homedir.Dir` is replaced by the stdlib `os.UserHomeDir` - `homedir.Expand` is replaced by fsutil.ExpandHome` in the `github.com/ipfs/kubo/misc/fsutil` package. Additional functionality, such as `DirWritable` and `FileExists` was moved into or included in the `github.com/ipfs/kubo/misc/fsutil` package. (cherry picked from commit 4009ad3e5a502518ddc7d48a888707f812ddc629)

Andrew Gillis committed Nov 5, 2024 at 05:45 UTC c53f3c552da77f078f08f945d2f306c36d25f3ee
14 files changed +200 -94
client/rpc/api.go
+2 -2
@@ -20,10 +20,10 @@ import (
20 ipfs "github.com/ipfs/kubo"
21 iface "github.com/ipfs/kubo/core/coreiface"
22 caopts "github.com/ipfs/kubo/core/coreiface/options"
23 + "github.com/ipfs/kubo/misc/fsutil"
24 dagpb "github.com/ipld/go-codec-dagpb"
25 _ "github.com/ipld/go-ipld-prime/codec/dagcbor"
26 "github.com/ipld/go-ipld-prime/node/basicnode"
26 - "github.com/mitchellh/go-homedir"
27 ma "github.com/multiformats/go-multiaddr"
28 manet "github.com/multiformats/go-multiaddr/net"
29 )
@@ -82,7 +82,7 @@ func NewPathApi(ipfspath string) (*HttpApi, error) {
82
83 // ApiAddr reads api file in specified ipfs path.
84 func ApiAddr(ipfspath string) (ma.Multiaddr, error) {
85 - baseDir, err := homedir.Expand(ipfspath)
85 + baseDir, err := fsutil.ExpandHome(ipfspath)
86 if err != nil {
87 return nil, err
88 }
cmd/ipfswatch/main.go
+2 -2
@@ -16,12 +16,12 @@ import (
16 core "github.com/ipfs/kubo/core"
17 coreapi "github.com/ipfs/kubo/core/coreapi"
18 corehttp "github.com/ipfs/kubo/core/corehttp"
19 + "github.com/ipfs/kubo/misc/fsutil"
20 fsrepo "github.com/ipfs/kubo/repo/fsrepo"
21
22 fsnotify "github.com/fsnotify/fsnotify"
23 "github.com/ipfs/boxo/files"
24 process "github.com/jbenet/goprocess"
24 - homedir "github.com/mitchellh/go-homedir"
25 )
26
27 var (
@@ -57,7 +57,7 @@ func run(ipfsPath, watchPath string) error {
57 proc := process.WithParent(process.Background())
58 log.Printf("running IPFSWatch on '%s' using repo at '%s'...", watchPath, ipfsPath)
59
60 - ipfsPath, err := homedir.Expand(ipfsPath)
60 + ipfsPath, err := fsutil.ExpandHome(ipfsPath)
61 if err != nil {
62 return err
63 }
config/config.go
+2 -2
@@ -9,7 +9,7 @@ import (
9 "path/filepath"
10 "strings"
11
12 - "github.com/mitchellh/go-homedir"
12 + "github.com/ipfs/kubo/misc/fsutil"
13 )
14
15 // Config is used to load ipfs config files.
@@ -59,7 +59,7 @@ func PathRoot() (string, error) {
59 dir := os.Getenv(EnvDir)
60 var err error
61 if len(dir) == 0 {
62 - dir, err = homedir.Expand(DefaultPathRoot)
62 + dir, err = fsutil.ExpandHome(DefaultPathRoot)
63 }
64 return dir, err
65 }
docs/changelogs/v0.32.md
+9
@@ -8,6 +8,7 @@
8 - [🔦 Highlights](#-highlights)
9 - [🎯 AutoTLS: Automatic Certificates for libp2p WebSockets via `libp2p.direct`](#-autotls-automatic-certificates-for-libp2p-websockets-via-libp2pdirect)
10 - [📦️ Boxo and go-libp2p updates](#-boxo-and-go-libp2p-updates)
11 + - [Replaced dependency on archived `github.com/mitchellh/go-homedir`](replaced-go-homedir)
12 - [📝 Changelog](#-changelog)
13 - [👨‍👩‍👧‍👦 Contributors](#-contributors)
14
@@ -31,6 +32,14 @@ See [`AutoTLS`](https://github.com/ipfs/kubo/blob/master/docs/config.md#autotls)
32 - update `go-libp2p-kad-dht` to [v0.27.0](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.27.0)
33 - update `go-libp2p-pubsub` to [v0.12.0](https://github.com/libp2p/go-libp2p-pubsub/releases/tag/v0.12.0)
34
35 +### Replaced go-homedir
36 +
37 +The `github.com/mitchellh/go-homedir` repo is archived, no longer needed, and no longer maintained.
38 +
39 +- `homedir.Dir` is replaced by the stdlib `os.UserHomeDir`
40 +- `homedir.Expand` is replaced by `fsutil.ExpandHome` in the `github.com/ipfs/kubo/misc/fsutil` package.
41 +- The new `github.com/ipfs/kubo/misc/fsutil` package contains file utility code previously located elsewhere in kubo.
42 +
43 ### 📝 Changelog
44
45 ### 👨‍👩‍👧‍👦 Contributors
docs/examples/kubo-as-a-library/go.mod
-1
@@ -144,7 +144,6 @@ require (
144 github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect
145 github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect
146 github.com/minio/sha256-simd v1.0.1 // indirect
147 - github.com/mitchellh/go-homedir v1.1.0 // indirect
147 github.com/mr-tron/base58 v1.2.0 // indirect
148 github.com/multiformats/go-base32 v0.1.0 // indirect
149 github.com/multiformats/go-base36 v0.2.0 // indirect
docs/examples/kubo-as-a-library/go.sum
-1
@@ -535,7 +535,6 @@ github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl
535 github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM=
536 github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
537 github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
538 -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
538 github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
539 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
540 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
go.mod
-1
@@ -64,7 +64,6 @@ require (
64 github.com/libp2p/go-libp2p-routing-helpers v0.7.4
65 github.com/libp2p/go-libp2p-testing v0.12.0
66 github.com/libp2p/go-socket-activation v0.1.0
67 - github.com/mitchellh/go-homedir v1.1.0
67 github.com/multiformats/go-multiaddr v0.13.0
68 github.com/multiformats/go-multiaddr-dns v0.4.0
69 github.com/multiformats/go-multibase v0.2.0
go.sum
-1
@@ -629,7 +629,6 @@ github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl
629 github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM=
630 github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
631 github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
632 -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
632 github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
633 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
634 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
misc/fsutil/fsutil.go new
+82
@@ -0,0 +1,82 @@
1 +package fsutil
2 +
3 +import (
4 + "errors"
5 + "fmt"
6 + "io/fs"
7 + "os"
8 + "path/filepath"
9 +)
10 +
11 +// DirWritable checks if a directory is writable. If the directory does
12 +// not exist it is created with writable permission.
13 +func DirWritable(dir string) error {
14 + if dir == "" {
15 + return errors.New("directory not specified")
16 + }
17 +
18 + var err error
19 + dir, err = ExpandHome(dir)
20 + if err != nil {
21 + return err
22 + }
23 +
24 + fi, err := os.Stat(dir)
25 + if err != nil {
26 + if errors.Is(err, fs.ErrNotExist) {
27 + // Directory does not exist, so create it.
28 + err = os.Mkdir(dir, 0775)
29 + if err == nil {
30 + return nil
31 + }
32 + }
33 + if errors.Is(err, fs.ErrPermission) {
34 + err = fs.ErrPermission
35 + }
36 + return fmt.Errorf("directory not writable: %s: %w", dir, err)
37 + }
38 + if !fi.IsDir() {
39 + return fmt.Errorf("not a directory: %s", dir)
40 + }
41 +
42 + // Directory exists, check that a file can be written.
43 + file, err := os.CreateTemp(dir, "writetest")
44 + if err != nil {
45 + if errors.Is(err, fs.ErrPermission) {
46 + err = fs.ErrPermission
47 + }
48 + return fmt.Errorf("directory not writable: %s: %w", dir, err)
49 + }
50 + file.Close()
51 + return os.Remove(file.Name())
52 +}
53 +
54 +// ExpandHome expands the path to include the home directory if the path is
55 +// prefixed with `~`. If it isn't prefixed with `~`, the path is returned
56 +// as-is.
57 +func ExpandHome(path string) (string, error) {
58 + if path == "" {
59 + return path, nil
60 + }
61 +
62 + if path[0] != '~' {
63 + return path, nil
64 + }
65 +
66 + if len(path) > 1 && path[1] != '/' && path[1] != '\\' {
67 + return "", errors.New("cannot expand user-specific home dir")
68 + }
69 +
70 + dir, err := os.UserHomeDir()
71 + if err != nil {
72 + return "", err
73 + }
74 +
75 + return filepath.Join(dir, path[1:]), nil
76 +}
77 +
78 +// FileExists return true if the file exists
79 +func FileExists(filename string) bool {
80 + _, err := os.Lstat(filename)
81 + return !errors.Is(err, os.ErrNotExist)
82 +}
misc/fsutil/fsutil_test.go new
+92
@@ -0,0 +1,92 @@
1 +package fsutil_test
2 +
3 +import (
4 + "io/fs"
5 + "os"
6 + "path/filepath"
7 + "runtime"
8 + "testing"
9 +
10 + "github.com/ipfs/kubo/misc/fsutil"
11 + "github.com/stretchr/testify/require"
12 +)
13 +
14 +func TestDirWritable(t *testing.T) {
15 + err := fsutil.DirWritable("")
16 + require.Error(t, err)
17 +
18 + err = fsutil.DirWritable("~nosuchuser/tmp")
19 + require.Error(t, err)
20 +
21 + tmpDir := t.TempDir()
22 +
23 + wrDir := filepath.Join(tmpDir, "readwrite")
24 + err = fsutil.DirWritable(wrDir)
25 + require.NoError(t, err)
26 +
27 + // Check that DirWritable created directory.
28 + fi, err := os.Stat(wrDir)
29 + require.NoError(t, err)
30 + require.True(t, fi.IsDir())
31 +
32 + err = fsutil.DirWritable(wrDir)
33 + require.NoError(t, err)
34 +
35 + // If running on Windows, skip read-only directory tests.
36 + if runtime.GOOS == "windows" {
37 + t.SkipNow()
38 + }
39 +
40 + roDir := filepath.Join(tmpDir, "readonly")
41 + require.NoError(t, os.Mkdir(roDir, 0500))
42 + err = fsutil.DirWritable(roDir)
43 + require.ErrorIs(t, err, fs.ErrPermission)
44 +
45 + roChild := filepath.Join(roDir, "child")
46 + err = fsutil.DirWritable(roChild)
47 + require.ErrorIs(t, err, fs.ErrPermission)
48 +}
49 +
50 +func TestFileExists(t *testing.T) {
51 + fileName := filepath.Join(t.TempDir(), "somefile")
52 + require.False(t, fsutil.FileExists(fileName))
53 +
54 + file, err := os.Create(fileName)
55 + require.NoError(t, err)
56 + file.Close()
57 +
58 + require.True(t, fsutil.FileExists(fileName))
59 +}
60 +
61 +func TestExpandHome(t *testing.T) {
62 + dir, err := fsutil.ExpandHome("")
63 + require.NoError(t, err)
64 + require.Equal(t, "", dir)
65 +
66 + origDir := filepath.Join("somedir", "somesub")
67 + dir, err = fsutil.ExpandHome(origDir)
68 + require.NoError(t, err)
69 + require.Equal(t, origDir, dir)
70 +
71 + _, err = fsutil.ExpandHome(filepath.FromSlash("~nosuchuser/somedir"))
72 + require.Error(t, err)
73 +
74 + homeEnv := "HOME"
75 + if runtime.GOOS == "windows" {
76 + homeEnv = "USERPROFILE"
77 + }
78 + origHome := os.Getenv(homeEnv)
79 + defer os.Setenv(homeEnv, origHome)
80 + homeDir := filepath.Join(t.TempDir(), "testhome")
81 + os.Setenv(homeEnv, homeDir)
82 +
83 + const subDir = "mytmp"
84 + origDir = filepath.Join("~", subDir)
85 + dir, err = fsutil.ExpandHome(origDir)
86 + require.NoError(t, err)
87 + require.Equal(t, filepath.Join(homeDir, subDir), dir)
88 +
89 + os.Unsetenv(homeEnv)
90 + _, err = fsutil.ExpandHome(origDir)
91 + require.Error(t, err)
92 +}
plugin/plugins/pebbleds/pebbleds.go
+2 -70
@@ -1,15 +1,13 @@
1 package pebbleds
2
3 import (
4 - "errors"
4 "fmt"
6 - "io/fs"
7 - "os"
5 "path/filepath"
6 "time"
7
8 "github.com/cockroachdb/pebble"
9 pebbleds "github.com/ipfs/go-ds-pebble"
10 + "github.com/ipfs/kubo/misc/fsutil"
11 "github.com/ipfs/kubo/plugin"
12 "github.com/ipfs/kubo/repo"
13 "github.com/ipfs/kubo/repo/fsrepo"
@@ -172,75 +170,9 @@ func (c *datastoreConfig) Create(path string) (repo.Datastore, error) {
170 p = filepath.Join(path, p)
171 }
172
175 - if err := dirWritable(p); err != nil {
173 + if err := fsutil.DirWritable(p); err != nil {
174 return nil, err
175 }
176
177 return pebbleds.NewDatastore(p, pebbleds.WithCacheSize(c.cacheSize), pebbleds.WithPebbleOpts(c.pebbleOpts))
178 }
181 -
182 -// dirWritable checks if a directory is writable. If the directory does
183 -// not exist it is created with writable permission.
184 -func dirWritable(dir string) error {
185 - if dir == "" {
186 - return errors.New("directory not specified")
187 - }
188 - var err error
189 - dir, err = expandHome(dir)
190 - if err != nil {
191 - return err
192 - }
193 -
194 - fi, err := os.Stat(dir)
195 - if err != nil {
196 - if errors.Is(err, fs.ErrNotExist) {
197 - // Directory does not exist, so create it.
198 - err = os.Mkdir(dir, 0775)
199 - if err == nil {
200 - return nil
201 - }
202 - }
203 - if errors.Is(err, fs.ErrPermission) {
204 - err = fs.ErrPermission
205 - }
206 - return fmt.Errorf("directory not writable: %s: %w", dir, err)
207 - }
208 - if !fi.IsDir() {
209 - return fmt.Errorf("not a directory: %s", dir)
210 - }
211 -
212 - // Directory exists, check that a file can be written.
213 - file, err := os.CreateTemp(dir, "writetest")
214 - if err != nil {
215 - if errors.Is(err, fs.ErrPermission) {
216 - err = fs.ErrPermission
217 - }
218 - return fmt.Errorf("directory not writable: %s: %w", dir, err)
219 - }
220 - file.Close()
221 - return os.Remove(file.Name())
222 -}
223 -
224 -// expandHome expands the path to include the home directory if the path is
225 -// prefixed with `~`. If it isn't prefixed with `~`, the path is returned
226 -// as-is.
227 -func expandHome(path string) (string, error) {
228 - if path == "" {
229 - return path, nil
230 - }
231 -
232 - if path[0] != '~' {
233 - return path, nil
234 - }
235 -
236 - if len(path) > 1 && path[1] != '/' && path[1] != '\\' {
237 - return "", errors.New("cannot expand user-specific home dir")
238 - }
239 -
240 - dir, err := os.UserHomeDir()
241 - if err != nil {
242 - return "", err
243 - }
244 -
245 - return filepath.Join(dir, path[1:]), nil
246 -}
repo/fsrepo/fsrepo.go
+4 -5
@@ -18,15 +18,14 @@ import (
18 dir "github.com/ipfs/kubo/thirdparty/dir"
19 rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager"
20
21 - util "github.com/ipfs/boxo/util"
21 ds "github.com/ipfs/go-datastore"
22 measure "github.com/ipfs/go-ds-measure"
23 lockfile "github.com/ipfs/go-fs-lock"
24 logging "github.com/ipfs/go-log"
25 config "github.com/ipfs/kubo/config"
26 serialize "github.com/ipfs/kubo/config/serialize"
27 + "github.com/ipfs/kubo/misc/fsutil"
28 "github.com/ipfs/kubo/repo/fsrepo/migrations"
29 - homedir "github.com/mitchellh/go-homedir"
29 ma "github.com/multiformats/go-multiaddr"
30 )
31
@@ -207,7 +206,7 @@ func open(repoPath string, userConfigFilePath string) (repo.Repo, error) {
206 }
207
208 func newFSRepo(rpath string, userConfigFilePath string) (*FSRepo, error) {
210 - expPath, err := homedir.Expand(filepath.Clean(rpath))
209 + expPath, err := fsutil.ExpandHome(filepath.Clean(rpath))
210 if err != nil {
211 return nil, err
212 }
@@ -239,7 +238,7 @@ func configIsInitialized(path string) bool {
238 if err != nil {
239 return false
240 }
242 - if !util.FileExists(configFilename) {
241 + if !fsutil.FileExists(configFilename) {
242 return false
243 }
244 return true
@@ -269,7 +268,7 @@ func initSpec(path string, conf map[string]interface{}) error {
268 return err
269 }
270
272 - if util.FileExists(fn) {
271 + if fsutil.FileExists(fn) {
272 return nil
273 }
274
repo/fsrepo/migrations/ipfsdir.go
+3 -7
@@ -8,7 +8,7 @@ import (
8 "strconv"
9 "strings"
10
11 - "github.com/mitchellh/go-homedir"
11 + "github.com/ipfs/kubo/misc/fsutil"
12 )
13
14 const (
@@ -17,10 +17,6 @@ const (
17 versionFile = "version"
18 )
19
20 -func init() {
21 - homedir.DisableCache = true
22 -}
23 -
20 // IpfsDir returns the path of the ipfs directory. If dir specified, then
21 // returns the expanded version dir. If dir is "", then return the directory
22 // set by IPFS_PATH, or if IPFS_PATH is not set, then return the default
@@ -31,14 +27,14 @@ func IpfsDir(dir string) (string, error) {
27 dir = os.Getenv(envIpfsPath)
28 }
29 if dir != "" {
34 - dir, err = homedir.Expand(dir)
30 + dir, err = fsutil.ExpandHome(dir)
31 if err != nil {
32 return "", err
33 }
34 return dir, nil
35 }
36
41 - home, err := homedir.Dir()
37 + home, err := os.UserHomeDir()
38 if err != nil {
39 return "", err
40 }
repo/fsrepo/misc.go
+2 -2
@@ -4,7 +4,7 @@ import (
4 "os"
5
6 config "github.com/ipfs/kubo/config"
7 - homedir "github.com/mitchellh/go-homedir"
7 + "github.com/ipfs/kubo/misc/fsutil"
8 )
9
10 // BestKnownPath returns the best known fsrepo path. If the ENV override is
@@ -15,7 +15,7 @@ func BestKnownPath() (string, error) {
15 if os.Getenv(config.EnvDir) != "" {
16 ipfsPath = os.Getenv(config.EnvDir)
17 }
18 - ipfsPath, err := homedir.Expand(ipfsPath)
18 + ipfsPath, err := fsutil.ExpandHome(ipfsPath)
19 if err != nil {
20 return "", err
21 }