Skip to content

Commit 6a815f4

Browse files
authored
Merge pull request #150 from Peefy/kcl-go-lib-home
refactor: kcl lib home and install lock
2 parents 7e88a1e + b50e88a commit 6a815f4

20 files changed

+179
-23
lines changed

go.mod

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
module kcl-lang.io/lib
22

3-
go 1.19
3+
go 1.23
44

55
require (
66
github.com/ebitengine/purego v0.7.1
7+
github.com/gofrs/flock v0.12.1
78
google.golang.org/protobuf v1.34.2
89
)
910

go.sum

+12
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,20 @@
1+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
2+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
13
github.com/ebitengine/purego v0.7.1 h1:6/55d26lG3o9VCZX8lping+bZcmShseiqlh2bnUDiPA=
24
github.com/ebitengine/purego v0.7.1/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ=
5+
github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E=
6+
github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0=
37
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
8+
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
9+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
10+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
11+
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
12+
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
413
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
514
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
615
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
16+
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
717
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
818
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
19+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
20+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

go/install/install.go

+15-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
"path/filepath"
88
"runtime"
99

10-
lib "kcl-lang.io/lib/go/lib"
10+
"github.com/gofrs/flock"
1111
)
1212

1313
const KCLVM_VERSION = "v0.10.0"
@@ -54,16 +54,28 @@ func InstallKclvm(installRoot string) error {
5454
return err
5555
}
5656
versionMatched, err := checkVersion(installRoot)
57+
if err != nil {
58+
return err
59+
}
5760

61+
err = os.MkdirAll(installRoot, 0777)
5862
if err != nil {
5963
return err
6064
}
65+
// Create a lock file for installing.
66+
lockFilePath := filepath.Join(installRoot, "install.lock")
67+
fileLock := flock.New(lockFilePath)
6168

62-
// Install kclvm binary.
63-
err = installBin(installRoot, "kclvm_cli", lib.CliBin, versionMatched)
69+
// Try to obtain a lock with a timeout.
70+
locked, err := fileLock.TryLock()
6471
if err != nil {
6572
return err
6673
}
74+
if !locked {
75+
return fmt.Errorf("another installation is already in progress")
76+
}
77+
defer fileLock.Unlock() // Ensure the lock is released when done.
78+
6779
// Install kclvm libs.
6880
err = installLib(installRoot, "kclvm_cli_cdylib", versionMatched)
6981
if err != nil {

go/lib/darwin-amd64/kclvm_cli

-398 KB
Binary file not shown.

go/lib/darwin-arm64/kclvm_cli

-386 KB
Binary file not shown.

go/lib/kclvm_cli_shared_lib_darwin_amd64.go

-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,3 @@ import (
66

77
//go:embed darwin-amd64/libkclvm_cli_cdylib.dylib
88
var CliLib []byte
9-
10-
//go:embed darwin-amd64/kclvm_cli
11-
var CliBin []byte

go/lib/kclvm_cli_shared_lib_darwin_arm64.go

-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,3 @@ import (
66

77
//go:embed darwin-arm64/libkclvm_cli_cdylib.dylib
88
var CliLib []byte
9-
10-
//go:embed darwin-arm64/kclvm_cli
11-
var CliBin []byte

go/lib/kclvm_cli_shared_lib_linux_amd64.go

-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,3 @@ import (
66

77
//go:embed linux-amd64/libkclvm_cli_cdylib.so
88
var CliLib []byte
9-
10-
//go:embed linux-amd64/kclvm_cli
11-
var CliBin []byte

go/lib/kclvm_cli_shared_lib_linux_arm64.go

-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,3 @@ import (
66

77
//go:embed linux-arm64/libkclvm_cli_cdylib.so
88
var CliLib []byte
9-
10-
//go:embed linux-arm64/kclvm_cli
11-
var CliBin []byte

go/lib/kclvm_cli_shared_lib_windows_amd64.go

-3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,3 @@ var CliLib []byte
99

1010
//go:embed windows-amd64/kclvm_cli_cdylib.lib
1111
var ExportLib []byte
12-
13-
//go:embed windows-amd64/kclvm_cli.exe
14-
var CliBin []byte

go/lib/kclvm_cli_shared_lib_windows_arm64.go

-3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,3 @@ var CliLib []byte
99

1010
//go:embed windows-amd64/kclvm_cli_cdylib.lib
1111
var ExportLib []byte
12-
13-
//go:embed windows-arm64/kclvm_cli.exe
14-
var CliBin []byte

go/lib/linux-amd64/kclvm_cli

-1.64 MB
Binary file not shown.

go/lib/linux-arm64/kclvm_cli

-1.68 MB
Binary file not shown.

go/lib/windows-amd64/kclvm_cli.exe

-129 KB
Binary file not shown.

go/lib/windows-arm64/kclvm_cli.exe

-129 KB
Binary file not shown.

go/native/loader.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@ import (
66
"runtime"
77

88
"kcl-lang.io/lib/go/install"
9+
lazypath "kcl-lang.io/lib/go/path"
910
)
1011

1112
const libName = "kclvm_cli_cdylib"
1213

1314
func libPath() (path string, err error) {
1415
libHome := os.Getenv("KCL_LIB_HOME")
1516
if libHome == "" {
16-
return os.MkdirTemp("", "kcl_lib_home")
17+
return lazypath.CacheHome(), nil
1718
}
1819
return libHome, nil
1920
}

go/path/home.go

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright The KCL Authors.
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
//
14+
// Reference: k8s.io/client-go/util/homedir
15+
package path
16+
17+
import (
18+
"os"
19+
"runtime"
20+
)
21+
22+
// HomeDir returns the home directory for the current user.
23+
// On Windows:
24+
// 1. if none of those locations are writeable, the first of %HOME%, %USERPROFILE%, %HOMEDRIVE%%HOMEPATH% that exists is returned.
25+
// 2. if none of those locations exists, the first of %HOME%, %USERPROFILE%, %HOMEDRIVE%%HOMEPATH% that is set is returned.
26+
func HomeDir() string {
27+
if runtime.GOOS == "windows" {
28+
home := os.Getenv("HOME")
29+
homeDriveHomePath := ""
30+
if homeDrive, homePath := os.Getenv("HOMEDRIVE"), os.Getenv("HOMEPATH"); len(homeDrive) > 0 && len(homePath) > 0 {
31+
homeDriveHomePath = homeDrive + homePath
32+
}
33+
userProfile := os.Getenv("USERPROFILE")
34+
35+
firstSetPath := ""
36+
firstExistingPath := ""
37+
38+
// Prefer %USERPROFILE% over %HOMEDRIVE%/%HOMEPATH% for compatibility with other auth-writing tools
39+
for _, p := range []string{home, userProfile, homeDriveHomePath} {
40+
if len(p) == 0 {
41+
continue
42+
}
43+
if len(firstSetPath) == 0 {
44+
// remember the first path that is set
45+
firstSetPath = p
46+
}
47+
info, err := os.Stat(p)
48+
if err != nil {
49+
continue
50+
}
51+
if len(firstExistingPath) == 0 {
52+
// remember the first path that exists
53+
firstExistingPath = p
54+
}
55+
if info.IsDir() && info.Mode().Perm()&(1<<(uint(7))) != 0 {
56+
// return first path that is writeable
57+
return p
58+
}
59+
}
60+
61+
// If none are writeable, return first location that exists
62+
if len(firstExistingPath) > 0 {
63+
return firstExistingPath
64+
}
65+
66+
// If none exist, return first location that is set
67+
if len(firstSetPath) > 0 {
68+
return firstSetPath
69+
}
70+
71+
// We've got nothing
72+
return ""
73+
}
74+
return os.Getenv("HOME")
75+
}

go/path/lazypath_darwin.go

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//go:build darwin
2+
// +build darwin
3+
4+
package path
5+
6+
import (
7+
"path/filepath"
8+
)
9+
10+
// DataHome defines the base directory relative to which user specific data files should be stored.
11+
func DataHome() string {
12+
return filepath.Join(HomeDir(), "Library")
13+
}
14+
15+
// ConfigHome defines the base directory relative to which user specific configuration files should
16+
// be stored.
17+
func ConfigHome() string {
18+
return filepath.Join(HomeDir(), "Library", "Preferences")
19+
}
20+
21+
// CacheHome defines the base directory relative to which user specific non-essential data files
22+
// should be stored.
23+
func CacheHome() string {
24+
return filepath.Join(HomeDir(), "Library", "Caches")
25+
}

go/path/lazypath_unix.go

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//go:build !windows && !darwin
2+
// +build !windows,!darwin
3+
4+
package path
5+
6+
import (
7+
"path/filepath"
8+
)
9+
10+
// DataHome defines the base directory relative to which user specific data files should be stored.
11+
func DataHome() string {
12+
return filepath.Join(HomeDir(), ".local", "share")
13+
}
14+
15+
// ConfigHome defines the base directory relative to which user specific configuration files should
16+
// be stored.
17+
func ConfigHome() string {
18+
return filepath.Join(HomeDir(), ".config")
19+
}
20+
21+
// CacheHome defines the base directory relative to which user specific non-essential data files
22+
// should be stored.
23+
func CacheHome() string {
24+
return filepath.Join(HomeDir(), ".cache")
25+
}

go/path/lazypath_windows.go

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//go:build windows
2+
// +build windows
3+
4+
package path
5+
6+
import "os"
7+
8+
// DataHome defines the base directory relative to which user specific data files should be stored.
9+
func DataHome() string {
10+
return ConfigHome()
11+
}
12+
13+
// ConfigHome defines the base directory relative to which user specific configuration files should
14+
// be stored.
15+
func ConfigHome() string {
16+
return os.Getenv("APPDATA")
17+
}
18+
19+
// CacheHome defines the base directory relative to which user specific non-essential data files
20+
// should be stored.
21+
func CacheHome() string {
22+
return os.Getenv("TEMP")
23+
}

0 commit comments

Comments
 (0)