File: package_hash.go

package info (click to toggle)
golang-ginkgo 1.2.0%2Bgit20161006.acfa16a-1
  • links: PTS, VCS
  • area: main
  • in suites: buster, stretch
  • size: 1,324 kB
  • ctags: 1,210
  • sloc: makefile: 12
file content (103 lines) | stat: -rw-r--r-- 2,005 bytes parent folder | download | duplicates (2)
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
package watch

import (
	"fmt"
	"io/ioutil"
	"os"
	"regexp"
	"time"
)

var goRegExp = regexp.MustCompile(`\.go$`)
var goTestRegExp = regexp.MustCompile(`_test\.go$`)

type PackageHash struct {
	CodeModifiedTime time.Time
	TestModifiedTime time.Time
	Deleted          bool

	path     string
	codeHash string
	testHash string
}

func NewPackageHash(path string) *PackageHash {
	p := &PackageHash{
		path: path,
	}

	p.codeHash, _, p.testHash, _, p.Deleted = p.computeHashes()

	return p
}

func (p *PackageHash) CheckForChanges() bool {
	codeHash, codeModifiedTime, testHash, testModifiedTime, deleted := p.computeHashes()

	if deleted {
		if p.Deleted == false {
			t := time.Now()
			p.CodeModifiedTime = t
			p.TestModifiedTime = t
		}
		p.Deleted = true
		return true
	}

	modified := false
	p.Deleted = false

	if p.codeHash != codeHash {
		p.CodeModifiedTime = codeModifiedTime
		modified = true
	}
	if p.testHash != testHash {
		p.TestModifiedTime = testModifiedTime
		modified = true
	}

	p.codeHash = codeHash
	p.testHash = testHash
	return modified
}

func (p *PackageHash) computeHashes() (codeHash string, codeModifiedTime time.Time, testHash string, testModifiedTime time.Time, deleted bool) {
	infos, err := ioutil.ReadDir(p.path)

	if err != nil {
		deleted = true
		return
	}

	for _, info := range infos {
		if info.IsDir() {
			continue
		}

		if goTestRegExp.Match([]byte(info.Name())) {
			testHash += p.hashForFileInfo(info)
			if info.ModTime().After(testModifiedTime) {
				testModifiedTime = info.ModTime()
			}
			continue
		}

		if goRegExp.Match([]byte(info.Name())) {
			codeHash += p.hashForFileInfo(info)
			if info.ModTime().After(codeModifiedTime) {
				codeModifiedTime = info.ModTime()
			}
		}
	}

	testHash += codeHash
	if codeModifiedTime.After(testModifiedTime) {
		testModifiedTime = codeModifiedTime
	}

	return
}

func (p *PackageHash) hashForFileInfo(info os.FileInfo) string {
	return fmt.Sprintf("%s_%d_%d", info.Name(), info.Size(), info.ModTime().UnixNano())
}