~hristoast/openmw-validator

ref: 87cd8a2f32f199f4ef2a909fc0ef819d5092b197 openmw-validator/paths.go -rw-r--r-- 2.9 KiB
87cd8a2fHristos N. Triantafillou Represent more things as structs rather than strings a month ago
                                                                                
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
131
132
133
134
135
136
package main

import (
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strings"
)

// Represents attributes related to a configured data path.
type dataDir struct {
	files    []*dataFile
	plugins  []*dataFile
	order    int
	path     string
	replaced int
}

// Do `filepath.Walk` on a dataDir's paths and register found files as needed.
func (d *dataDir) checkDataDirs(gc *gameConfig) error {
	pathContent, err := ioutil.ReadDir(d.path)
	if err != nil {
		return err
	}

	for _, pc := range pathContent {
		if pc.IsDir() {
			err = filepath.Walk(filepath.Join(d.path, pc.Name()),
				func(filePath string, info os.FileInfo, err error) error {
					if err != nil {
						return err
					}

					localPath := strings.Replace(filePath, d.path, "", -1)
					nfo, err := os.Stat(filePath)
					if err != nil {
						return err
					}

					if !nfo.IsDir() && !ignoredFile(filePath) {
						df := &dataFile{
							dDir:      d,
							localPath: localPath,
						}
						d.files = append(d.files, df)

						// Does gc.dataFiles already have this localPath stored as a key? If
						// so, check for an overwrite and log as needed.
						// THANKS: https://stackoverflow.com/a/2050629
						oldf, ok := df.alreadySaved(gc.dataFiles)
						if ok {
							gc.registerReplacement(df, oldf)
							d.replaced += 1
						}
						gc.dataFiles[localPath] = df

					}
					return nil
				})
			if err != nil {
				return err
			}

		} else {
			// This is a file, not a dir.
			path := filepath.Join(d.path, pc.Name())
			if !ignoredFile(path) {
				df := &dataFile{
					dDir:      d,
					localPath: pc.Name(),
				}
				oldf, ok := df.alreadySaved(gc.dataFiles)
				if ok {
					gc.registerReplacement(df, oldf)
					d.replaced += 1
				}

				if df.isPlugin() {
					d.plugins = append(d.plugins, df)
					gc.foundPlugins = append(gc.foundPlugins, df.localPath)
				}

				gc.dataFiles[df.localPath] = df
			}
		}
	}
	return err
}

func (d *dataDir) alreadyFound(found map[string]bool) bool {
	if _, ok := found[d.path]; ok {
		return ok // true
	}
	return false
}

// Verify that a dataDir is real, then scan it for files.
func (d *dataDir) check(dataOrder int, gc *gameConfig) error {
	// Format the path...
	p := strings.Replace(d.path, "data=", "", -1)
	p = strings.TrimPrefix(p, "'")
	p = strings.TrimPrefix(p, "\"")
	p = strings.TrimSuffix(p, "\r")
	p = strings.TrimSuffix(p, "'")
	p = strings.TrimSuffix(p, "\"")

	if !gc.runCfg.quiet {
		log.Printf("Checking: %v", p)
	}

	found := d.alreadyFound(gc.foundPaths)
	if found {
		log.Printf("Path already configured: %s", p)
		gc.duplicatePaths = append(gc.duplicatePaths, p)
	} else {
		gc.foundPaths[p] = true
	}

	_, err := os.Stat(p)
	if os.IsNotExist(err) {
		gc.badPaths = append(gc.badPaths, p)
		return err
	}

	dd := &dataDir{
		files:    []*dataFile{},
		plugins:  []*dataFile{},
		order:    dataOrder,
		path:     p,
		replaced: 0,
	}
	dd.checkDataDirs(gc)

	return err
}