-
Notifications
You must be signed in to change notification settings - Fork 0
/
package_comparer.go
98 lines (79 loc) · 2.49 KB
/
package_comparer.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
package main
import (
"bufio"
"os"
"strings"
)
/*
FindOldPackagesByFileList find old packages according to package list file.
FindOldPackagesByFileList 以目录列表中给出的包为基础,查找指定目录下过期的包。
*/
func FindOldPackagesByFileList(vsSetupPath string, listFilename string) ([]*PackageInfo, error) {
// 读取 vsSetupPath 下的目录列表。
packageDirs, err := os.ReadDir(vsSetupPath)
if err != nil {
return nil, err
}
packages, err := readPackageListFile(listFilename)
if err != nil {
return nil, err
}
// VS 安装目录下一般有 3000 多个包。每个小版本更新其中的数十个。给数组预先分配一些空间。
result := make([]*PackageInfo, 0, 100)
for _, fn := range packageDirs {
if fn.IsDir() { // we only process dirs.
dirName := fn.Name()
// ok == false means the dir in setup path is not in the package list.
// it should be moved out in most cases.
if _, ok := packages[dirName]; !ok {
pkg := getPackageInfo(dirName)
if pkg == nil {
continue
}
// 目录具有版本信息,但又不在包列表中。这个目录应该被移除。
result = append(result, pkg)
}
}
}
return result, nil
}
// readPackageListFile reads package list file create by vs_layout.exe.
func readPackageListFile(filename string) (map[string]bool, error) {
file, err := os.Open(filename)
if err != nil {
return nil, err
}
defer file.Close()
// by visual studio version 16.8 (2019), the package list file has 3633 lines.
// give it a little bit more space.
list := make(map[string]bool, 4000)
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text() // read a text line.
path := getPackagePath(line) // analyse it, get package name.
if path != notPackage {
list[path] = true // save package name to the list.
}
}
if err := scanner.Err(); err != nil {
return nil, err
}
return list, nil
}
const packageHeader = "Verified existing package '"
const packageHeaderLenght = len(packageHeader)
const notPackage = ""
// getPackagePath get package name as the result, otherwise returns empty string.
func getPackagePath(line string) string {
// each line is like below:
// Verified existing package 'Unity3d.x86,version=3.1,chip=x86'
// the package name is the dir name, quoted with "'".
if strings.Index(line, packageHeader) == 0 {
end := strings.LastIndex(line, "'")
if end > packageHeaderLenght {
s := line[packageHeaderLenght:end]
return s
}
}
return notPackage
}