4
4
"fmt"
5
5
"os"
6
6
"path/filepath"
7
+ "runtime"
7
8
"strings"
8
9
9
10
"github.com/aquaproj/aqua/v2/pkg/config"
@@ -14,12 +15,39 @@ import (
14
15
15
16
func (is * Installer ) createLinks (logE * logrus.Entry , pkgs []* config.Package ) bool {
16
17
failed := false
18
+
19
+ var aquaProxyPathOnWindows string
20
+ if is .runtime .IsWindows () {
21
+ pkg := proxyPkg ()
22
+ pkgPath , err := pkg .PkgPath (is .rootDir , is .runtime )
23
+ if err != nil {
24
+ logerr .WithError (logE , err ).Error ("get a path to aqua-proxy" )
25
+ failed = true
26
+ }
27
+ aquaProxyPathOnWindows = filepath .Join (pkgPath , "aqua-proxy.exe" )
28
+ }
29
+
17
30
for _ , pkg := range pkgs {
18
31
pkgInfo := pkg .PackageInfo
19
32
for _ , file := range pkgInfo .GetFiles () {
20
- if isWindows (is .runtime .GOOS ) {
21
- if err := is .createProxyWindows (file .Name , logE ); err != nil {
22
- logerr .WithError (logE , err ).Error ("create the proxy file" )
33
+ if isWindows (runtime .GOOS ) {
34
+ hardLink := filepath .Join (is .rootDir , "bin" , file .Name + ".exe" )
35
+ if f , err := afero .Exists (is .fs , hardLink ); err != nil {
36
+ logerr .WithError (logE , err ).WithFields (logrus.Fields {
37
+ "command" : file .Name ,
38
+ }).Error ("check if a hard link to aqua-proxy exists" )
39
+ failed = true
40
+ continue
41
+ } else if f {
42
+ continue
43
+ }
44
+ logE .WithFields (logrus.Fields {
45
+ "command" : file .Name ,
46
+ }).Info ("creating a hard link to aqua-proxy" )
47
+ if err := is .linker .Hardlink (aquaProxyPathOnWindows , hardLink ); err != nil {
48
+ logerr .WithError (logE , err ).WithFields (logrus.Fields {
49
+ "command" : file .Name ,
50
+ }).Error ("create a hard link to aqua-proxy" )
23
51
failed = true
24
52
}
25
53
continue
@@ -34,6 +62,37 @@ func (is *Installer) createLinks(logE *logrus.Entry, pkgs []*config.Package) boo
34
62
return failed
35
63
}
36
64
65
+ func (is * Installer ) recreateHardLinks () error {
66
+ binDir := filepath .Join (is .rootDir , "bin" )
67
+ infos , err := afero .ReadDir (is .fs , binDir )
68
+ if err != nil {
69
+ return fmt .Errorf ("read a bin dir: %w" , err )
70
+ }
71
+
72
+ pkg := proxyPkg ()
73
+ pkgPath , err := pkg .PkgPath (is .rootDir , is .runtime )
74
+ if err != nil {
75
+ return err //nolint:wrapcheck
76
+ }
77
+ a := filepath .Join (pkgPath , "aqua-proxy.exe" )
78
+
79
+ for _ , info := range infos {
80
+ if info .Name () == "aqua.exe" {
81
+ continue
82
+ }
83
+ p := filepath .Join (binDir , info .Name ())
84
+ if err := is .fs .Remove (p ); err != nil {
85
+ return fmt .Errorf ("remove a file to replace it with a hard link: %w" , err )
86
+ }
87
+ if strings .HasSuffix (info .Name (), ".exe" ) {
88
+ if err := is .linker .Hardlink (a , p ); err != nil {
89
+ return fmt .Errorf ("create a hard link: %w" , err )
90
+ }
91
+ }
92
+ }
93
+ return nil
94
+ }
95
+
37
96
func (is * Installer ) createLink (linkPath , linkDest string , logE * logrus.Entry ) error {
38
97
if fileInfo , err := is .linker .Lstat (linkPath ); err == nil {
39
98
switch mode := fileInfo .Mode (); {
@@ -90,58 +149,3 @@ func (is *Installer) recreateLink(linkPath, linkDest string, logE *logrus.Entry)
90
149
}
91
150
return nil
92
151
}
93
-
94
- const (
95
- batTemplate = `@echo off
96
- aqua exec -- <COMMAND> %*
97
- `
98
- scrTemplate = `#!/usr/bin/env bash
99
- exec aqua exec -- "$0" "$@"
100
- `
101
- proxyPermission os.FileMode = 0o755
102
- )
103
-
104
- func (is * Installer ) createProxyWindows (binName string , logE * logrus.Entry ) error {
105
- if err := is .createBinWindows (filepath .Join (is .rootDir , "bin" , binName ), scrTemplate , logE ); err != nil {
106
- return err
107
- }
108
- if err := is .createBinWindows (filepath .Join (is .rootDir , "bat" , binName + ".bat" ), strings .Replace (batTemplate , "<COMMAND>" , binName , 1 ), logE ); err != nil {
109
- return err
110
- }
111
- return nil
112
- }
113
-
114
- func (is * Installer ) createBinWindows (binPath , binTxt string , logE * logrus.Entry ) error {
115
- if fileInfo , err := is .linker .Lstat (binPath ); err == nil {
116
- switch mode := fileInfo .Mode (); {
117
- case mode .IsDir ():
118
- // if file is a directory, raise error
119
- return fmt .Errorf ("%s has already existed and is a directory" , binPath )
120
- case mode & os .ModeNamedPipe != 0 :
121
- // if file is a pipe, raise error
122
- return fmt .Errorf ("%s has already existed and is a named pipe" , binPath )
123
- case mode .IsRegular ():
124
- // TODO check content
125
- return nil
126
- case mode & os .ModeSymlink != 0 :
127
- if err := is .fs .Remove (binPath ); err != nil {
128
- return fmt .Errorf ("remove a symbolic link (%s): %w" , binPath , err )
129
- }
130
- return is .writeBinWindows (binPath , binTxt , logE )
131
- default :
132
- return fmt .Errorf ("unexpected file mode %s: %s" , binPath , mode .String ())
133
- }
134
- }
135
-
136
- return is .writeBinWindows (binPath , binTxt , logE )
137
- }
138
-
139
- func (is * Installer ) writeBinWindows (proxyPath , binTxt string , logE * logrus.Entry ) error {
140
- logE .WithFields (logrus.Fields {
141
- "proxy_path" : proxyPath ,
142
- }).Info ("create a proxy file" )
143
- if err := afero .WriteFile (is .fs , proxyPath , []byte (binTxt ), proxyPermission ); err != nil {
144
- return fmt .Errorf ("create a proxy file (%s): %w" , proxyPath , err )
145
- }
146
- return nil
147
- }
0 commit comments