11namespace GitVersion
22{
33 using System ;
4- using System . Collections . Generic ;
5- using System . IO ;
64 using System . Linq ;
7- using System . Security . Cryptography ;
8- using System . Text ;
9-
105 using GitVersion . Helpers ;
116
127 using LibGit2Sharp ;
138
14- using YamlDotNet . Serialization ;
15-
169 public class ExecuteCore
1710 {
1811 readonly IFileSystem fileSystem ;
12+ readonly GitVersionCache gitVersionCache ;
1913
2014 public ExecuteCore ( IFileSystem fileSystem )
2115 {
2216 if ( fileSystem == null ) throw new ArgumentNullException ( "fileSystem" ) ;
2317
2418 this . fileSystem = fileSystem ;
19+ gitVersionCache = new GitVersionCache ( fileSystem ) ;
2520 }
2621
2722 public VersionVariables ExecuteGitVersion ( string targetUrl , string dynamicRepositoryLocation , Authentication authentication , string targetBranch , bool noFetch , string workingDirectory , string commitId )
2823 {
2924 var gitDir = Repository . Discover ( workingDirectory ) ;
30- using ( var repo = fileSystem . GetRepository ( gitDir ) )
25+ using ( var repo = GetRepository ( gitDir ) )
3126 {
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 ) ;
3728 if ( versionVariables == null )
3829 {
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 ) ;
4132 }
4233
4334 return versionVariables ;
4435 }
4536 }
4637
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-
7138 public bool TryGetVersion ( string directory , out VersionVariables versionVariables , bool noFetch , Authentication authentication )
7239 {
7340 try
@@ -96,66 +63,7 @@ static string ResolveCurrentBranch(IBuildServer buildServer, string targetBranch
9663 return currentBranch ;
9764 }
9865
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 )
15967 {
16068 // Normalise if we are running on build server
16169 var gitPreparer = new GitPreparer ( targetUrl , dynamicRepositoryLocation , authentication , noFetch , workingDirectory ) ;
@@ -172,18 +80,36 @@ VersionVariables ExecuteInternal(string targetUrl, string dynamicRepositoryLocat
17280 // TODO Link to wiki article
17381 throw new Exception ( string . Format ( "Failed to prepare or find the .git directory in path '{0}'." , workingDirectory ) ) ;
17482 }
175- VersionVariables variables ;
17683 var versionFinder = new GitVersionFinder ( ) ;
17784 var configuration = ConfigurationProvider . Provide ( projectRoot , fileSystem ) ;
17885
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
18095 {
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 ) ;
18597
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+ }
187113 }
188114 }
189115}
0 commit comments