1
1
namespace GitVersion
2
2
{
3
3
using System ;
4
- using System . Collections . Generic ;
5
- using System . IO ;
6
4
using System . Linq ;
7
- using System . Security . Cryptography ;
8
- using System . Text ;
9
-
10
5
using GitVersion . Helpers ;
11
6
12
7
using LibGit2Sharp ;
13
8
14
- using YamlDotNet . Serialization ;
15
-
16
9
public class ExecuteCore
17
10
{
18
11
readonly IFileSystem fileSystem ;
12
+ readonly GitVersionCache gitVersionCache ;
19
13
20
14
public ExecuteCore ( IFileSystem fileSystem )
21
15
{
22
16
if ( fileSystem == null ) throw new ArgumentNullException ( "fileSystem" ) ;
23
17
24
18
this . fileSystem = fileSystem ;
19
+ gitVersionCache = new GitVersionCache ( fileSystem ) ;
25
20
}
26
21
27
22
public VersionVariables ExecuteGitVersion ( string targetUrl , string dynamicRepositoryLocation , Authentication authentication , string targetBranch , bool noFetch , string workingDirectory , string commitId )
28
23
{
29
24
var gitDir = Repository . Discover ( workingDirectory ) ;
30
- using ( var repo = fileSystem . GetRepository ( gitDir ) )
25
+ using ( var repo = GetRepository ( gitDir ) )
31
26
{
32
- // Maybe using timestamp in .git/refs directory is enough?
33
- var ticks = fileSystem . GetLastDirectoryWrite ( Path . Combine ( gitDir , "refs" ) ) ;
34
- var key = string . Format ( "{0}:{1}:{2}:{3}" , gitDir , repo . Head . CanonicalName , repo . Head . Tip . Sha , ticks ) ;
35
-
36
- var versionVariables = LoadVersionVariablesFromDiskCache ( key , gitDir ) ;
27
+ var versionVariables = gitVersionCache . LoadVersionVariablesFromDiskCache ( repo , gitDir ) ;
37
28
if ( versionVariables == null )
38
29
{
39
- versionVariables = ExecuteInternal ( targetUrl , dynamicRepositoryLocation , authentication , targetBranch , noFetch , workingDirectory , commitId ) ;
40
- WriteVariablesToDiskCache ( key , gitDir , versionVariables ) ;
30
+ versionVariables = ExecuteInternal ( targetUrl , dynamicRepositoryLocation , authentication , targetBranch , noFetch , workingDirectory , commitId , repo ) ;
31
+ gitVersionCache . WriteVariablesToDiskCache ( repo , gitDir , versionVariables ) ;
41
32
}
42
33
43
34
return versionVariables ;
44
35
}
45
36
}
46
37
47
- void WriteVariablesToDiskCache ( string key , string gitDir , VersionVariables variablesFromCache )
48
- {
49
- var cacheFileName = GetCacheFileName ( key , GetCacheDir ( gitDir ) ) ;
50
- variablesFromCache . FileName = cacheFileName ;
51
-
52
- using ( var stream = fileSystem . OpenWrite ( cacheFileName ) )
53
- {
54
- using ( var sw = new StreamWriter ( stream ) )
55
- {
56
- Dictionary < string , string > dictionary ;
57
- using ( Logger . IndentLog ( "Creating dictionary" ) )
58
- {
59
- dictionary = variablesFromCache . ToDictionary ( x => x . Key , x => x . Value ) ;
60
- }
61
-
62
- using ( Logger . IndentLog ( "Storing version variables to cache file " + cacheFileName ) )
63
- {
64
- var serializer = new Serializer ( ) ;
65
- serializer . Serialize ( sw , dictionary ) ;
66
- }
67
- }
68
- }
69
- }
70
-
71
38
public bool TryGetVersion ( string directory , out VersionVariables versionVariables , bool noFetch , Authentication authentication )
72
39
{
73
40
try
@@ -96,66 +63,7 @@ static string ResolveCurrentBranch(IBuildServer buildServer, string targetBranch
96
63
return currentBranch ;
97
64
}
98
65
99
- VersionVariables LoadVersionVariablesFromDiskCache ( string key , string gitDir )
100
- {
101
- using ( Logger . IndentLog ( "Loading version variables from disk cache" ) )
102
- {
103
- // If the cacheDir already exists, CreateDirectory just won't do anything (it won't fail). @asbjornu
104
-
105
- var cacheDir = GetCacheDir ( gitDir ) ;
106
- fileSystem . CreateDirectory ( cacheDir ) ;
107
- var cacheFileName = GetCacheFileName ( key , cacheDir ) ;
108
- VersionVariables vv = null ;
109
- if ( fileSystem . Exists ( cacheFileName ) )
110
- {
111
- using ( Logger . IndentLog ( "Deserializing version variables from cache file " + cacheFileName ) )
112
- {
113
- try
114
- {
115
- vv = VersionVariables . FromFile ( cacheFileName , fileSystem ) ;
116
- }
117
- catch ( Exception ex )
118
- {
119
- Logger . WriteWarning ( "Unable to read cache file " + cacheFileName + ", deleting it." ) ;
120
- Logger . WriteInfo ( ex . ToString ( ) ) ;
121
- try
122
- {
123
- fileSystem . Delete ( cacheFileName ) ;
124
- }
125
- catch ( Exception deleteEx )
126
- {
127
- Logger . WriteWarning ( string . Format ( "Unable to delete corrupted version cache file {0}. Got {1} exception." , cacheFileName , deleteEx . GetType ( ) . FullName ) ) ;
128
- }
129
- }
130
- }
131
- }
132
- else
133
- {
134
- Logger . WriteInfo ( "Cache file " + cacheFileName + " not found." ) ;
135
- }
136
-
137
- return vv ;
138
- }
139
- }
140
-
141
- static string GetCacheFileName ( string key , string cacheDir )
142
- {
143
- string cacheKey ;
144
- using ( var sha1 = SHA1 . Create ( ) )
145
- {
146
- // Make a shorter key by hashing, to avoid having to long cache filename.
147
- cacheKey = BitConverter . ToString ( sha1 . ComputeHash ( Encoding . UTF8 . GetBytes ( key ) ) ) . Replace ( "-" , "" ) ;
148
- }
149
- var cacheFileName = string . Concat ( Path . Combine ( cacheDir , cacheKey ) , ".yml" ) ;
150
- return cacheFileName ;
151
- }
152
-
153
- static string GetCacheDir ( string gitDir )
154
- {
155
- return Path . Combine ( gitDir , "gitversion_cache" ) ;
156
- }
157
-
158
- VersionVariables ExecuteInternal ( string targetUrl , string dynamicRepositoryLocation , Authentication authentication , string targetBranch , bool noFetch , string workingDirectory , string commitId )
66
+ VersionVariables ExecuteInternal ( string targetUrl , string dynamicRepositoryLocation , Authentication authentication , string targetBranch , bool noFetch , string workingDirectory , string commitId , IRepository repo )
159
67
{
160
68
// Normalise if we are running on build server
161
69
var gitPreparer = new GitPreparer ( targetUrl , dynamicRepositoryLocation , authentication , noFetch , workingDirectory ) ;
@@ -172,18 +80,36 @@ VersionVariables ExecuteInternal(string targetUrl, string dynamicRepositoryLocat
172
80
// TODO Link to wiki article
173
81
throw new Exception ( string . Format ( "Failed to prepare or find the .git directory in path '{0}'." , workingDirectory ) ) ;
174
82
}
175
- VersionVariables variables ;
176
83
var versionFinder = new GitVersionFinder ( ) ;
177
84
var configuration = ConfigurationProvider . Provide ( projectRoot , fileSystem ) ;
178
85
179
- using ( var repo = fileSystem . GetRepository ( dotGitDirectory ) )
86
+ var gitVersionContext = new GitVersionContext ( repo , configuration , commitId : commitId ) ;
87
+ var semanticVersion = versionFinder . FindVersion ( gitVersionContext ) ;
88
+
89
+ return VariableProvider . GetVariablesFor ( semanticVersion , gitVersionContext . Configuration , gitVersionContext . IsCurrentCommitTagged ) ;
90
+ }
91
+
92
+ IRepository GetRepository ( string gitDirectory )
93
+ {
94
+ try
180
95
{
181
- var gitVersionContext = new GitVersionContext ( repo , configuration , commitId : commitId ) ;
182
- var semanticVersion = versionFinder . FindVersion ( gitVersionContext ) ;
183
- variables = VariableProvider . GetVariablesFor ( semanticVersion , gitVersionContext . Configuration , gitVersionContext . IsCurrentCommitTagged ) ;
184
- }
96
+ var repository = new Repository ( gitDirectory ) ;
185
97
186
- return variables ;
98
+ var branch = repository . Head ;
99
+ if ( branch . Tip == null )
100
+ {
101
+ throw new WarningException ( "No Tip found. Has repo been initialized?" ) ;
102
+ }
103
+ return repository ;
104
+ }
105
+ catch ( Exception exception )
106
+ {
107
+ if ( exception . Message . Contains ( "LibGit2Sharp.Core.NativeMethods" ) || exception . Message . Contains ( "FilePathMarshaler" ) )
108
+ {
109
+ throw new WarningException ( "Restart of the process may be required to load an updated version of LibGit2Sharp." ) ;
110
+ }
111
+ throw ;
112
+ }
187
113
}
188
114
}
189
115
}
0 commit comments