1- // Copyright (c) SharpCrafters s.r.o. See the LICENSE.md file in the root directory of this repository root for details.
2-
3- using PostSharp . Engineering . BuildTools . Utilities ;
4- using System ;
5- using System . IO ;
6-
7- namespace PostSharp . Engineering . BuildTools . Build
8- {
9- /// <summary>
10- /// Cleans the current repo from build artefacts.
11- /// </summary>
12- internal class CleanCommand : BaseCommand < BuildSettings >
13- {
14- protected override bool ExecuteCore ( BuildContext context , BuildSettings settings )
15- {
16- return Execute ( context , settings ) ;
17- }
18-
19- public static bool Execute ( BuildContext context , BuildSettings settings )
20- {
21- // Kill processes that may hold file locks.
22- ProcessKiller . KillProcessesBeforeClean ( context . Console ) ;
23-
24- var product = context . Product ;
25-
26- void DeleteDirectory ( string directory )
27- {
28- if ( Directory . Exists ( directory ) )
29- {
30- context . Console . WriteMessage ( $ "Deleting directory '{ directory } '." ) ;
31- Directory . Delete ( directory , true ) ;
32- }
33- }
34-
35- void CleanRecursive ( string directory )
36- {
37- DeleteDirectory ( Path . Combine ( directory , "bin" ) ) ;
38- DeleteDirectory ( Path . Combine ( directory , "obj" ) ) ;
39-
40- foreach ( var subdirectory in Directory . EnumerateDirectories ( directory ) )
41- {
42- if ( subdirectory == Path . Combine ( context . RepoDirectory , product . EngineeringDirectory ) )
43- {
44- // Skip the engineering directory.
45- continue ;
46- }
47-
48- CleanRecursive ( subdirectory ) ;
49- }
50- }
51-
52- // Clears NuGet global-packages cache of Metalama and PostSharp.Engineering packages to prevent using old or corrupted package.
53- void CleanNugetCache ( )
54- {
55- // Kill the processes to release the locks on the NuGet cache.
56- ProcessKiller . KillWellKnownProcesses ( context . Console ) ;
57-
58- // Use dotnet command to locate nuget cache directory.
59- var success = ToolInvocationHelper . InvokeTool (
60- context . Console ,
61- "dotnet" ,
62- "nuget locals global-packages -l" ,
63- context . RepoDirectory ,
64- out _ ,
65- out var output ) ;
66-
67- if ( ! success )
68- {
69- context . Console . WriteWarning ( "Couldn't locate NuGet cache directory, skipping cleaning it." ) ;
70-
71- return ;
72- }
73-
74- // Get only directory location string.
75- var nugetCacheDirectory = output . Split ( ' ' ) [ 1 ] . Trim ( ) ;
76- var directoryInfo = new DirectoryInfo ( nugetCacheDirectory ) ;
77-
78- // Delete all cached packages directories starting with 'Metalama'.
79- foreach ( var dir in directoryInfo . EnumerateDirectories ( "metalama*" ) )
80- {
81- DeleteDirectory ( Path . Combine ( nugetCacheDirectory , dir . Name ) ) ;
82- }
83-
84- // Delete all cached packages directories starting with 'PostSharp.Engineering' but the current one.
85- foreach ( var dir in directoryInfo . EnumerateDirectories ( "postsharp.engineering*" ) )
86- {
87- foreach ( var subDir in dir . EnumerateDirectories ( ) )
88- {
89- var directoryPath = Path . Combine ( nugetCacheDirectory , dir . Name , subDir . Name ) ;
90-
91- if ( subDir . Name . Equals ( VersionHelper . EngineeringVersion , StringComparison . OrdinalIgnoreCase ) )
92- {
93- context . Console . WriteMessage ( $ "Skipping directory '{ directoryPath } '." ) ;
94-
95- continue ;
96- }
97-
98- DeleteDirectory ( directoryPath ) ;
99- }
100- }
101- }
102-
103- // NugetCache must be automatically deleted only on TeamCity.
104- if ( context is { IsContinuousIntegrationBuild : true , IsRunningUnderContainer : false } && ! settings . NoNuGetCacheCleanup )
105- {
106- context . Console . WriteHeading ( "Cleaning NuGet cache" ) ;
107- context . Console . WriteMessage ( "The NuGet cache cleanup can be skipped using --no-nuget-cache-cleanup." ) ;
108-
109- CleanNugetCache ( ) ;
110- }
111-
112- context . Console . WriteHeading ( $ "Cleaning { product . ProductName } " ) ;
113-
114- foreach ( var directory in product . AdditionalDirectoriesToClean )
115- {
116- DeleteDirectory ( Path . Combine ( context . RepoDirectory , directory ) ) ;
117- }
118-
119- DeleteDirectory ( product . GetPrivateArtifactsAbsoluteDirectory ( context , settings . BuildConfiguration ) ) ;
120-
121- DeleteDirectory ( product . GetPublicArtifactsAbsoluteDirectory ( context ) ) ;
122-
123- DeleteDirectory (
124- Path . Combine (
125- context . RepoDirectory ,
126- product . LogsDirectory ) ) ;
127-
128- foreach ( var directory in Directory . GetDirectories ( context . RepoDirectory ) )
129- {
130- switch ( Path . GetFileName ( directory ) )
131- {
132- case "source-dependencies" :
133- case "dependencies" :
134- case ".sonarqube" :
135- case { } s when s == product . EngineeringDirectory :
136- continue ;
137-
138- default :
139- CleanRecursive ( directory ) ;
140-
141- break ;
142- }
143- }
144-
145- return true ;
146- }
147- }
1+ // Copyright (c) SharpCrafters s.r.o. See the LICENSE.md file in the root directory of this repository root for details.
2+
3+ using PostSharp . Engineering . BuildTools . Utilities ;
4+ using System ;
5+ using System . IO ;
6+
7+ namespace PostSharp . Engineering . BuildTools . Build
8+ {
9+ /// <summary>
10+ /// Cleans the current repo from build artefacts.
11+ /// </summary>
12+ internal class CleanCommand : BaseCommand < BuildSettings >
13+ {
14+ protected override bool ExecuteCore ( BuildContext context , BuildSettings settings )
15+ {
16+ return Execute ( context , settings ) ;
17+ }
18+
19+ private static void ClearReadOnlyAttributes ( string directory )
20+ {
21+ foreach ( var file in Directory . EnumerateFiles ( directory , "*" , SearchOption . AllDirectories ) )
22+ {
23+ var attributes = File . GetAttributes ( file ) ;
24+
25+ if ( ( attributes & FileAttributes . ReadOnly ) != 0 )
26+ {
27+ File . SetAttributes ( file , attributes & ~ FileAttributes . ReadOnly ) ;
28+ }
29+ }
30+ }
31+
32+ public static bool Execute ( BuildContext context , BuildSettings settings )
33+ {
34+ // Kill processes that may hold file locks.
35+ ProcessKiller . KillProcessesBeforeClean ( context . Console ) ;
36+
37+ var product = context . Product ;
38+
39+ void DeleteDirectory ( string directory )
40+ {
41+ if ( Directory . Exists ( directory ) )
42+ {
43+ context . Console . WriteMessage ( $ "Deleting directory '{ directory } '." ) ;
44+ ClearReadOnlyAttributes ( directory ) ;
45+ Directory . Delete ( directory , true ) ;
46+ }
47+ }
48+
49+ void CleanRecursive ( string directory )
50+ {
51+ DeleteDirectory ( Path . Combine ( directory , "bin" ) ) ;
52+ DeleteDirectory ( Path . Combine ( directory , "obj" ) ) ;
53+
54+ foreach ( var subdirectory in Directory . EnumerateDirectories ( directory ) )
55+ {
56+ if ( subdirectory == Path . Combine ( context . RepoDirectory , product . EngineeringDirectory ) )
57+ {
58+ // Skip the engineering directory.
59+ continue ;
60+ }
61+
62+ CleanRecursive ( subdirectory ) ;
63+ }
64+ }
65+
66+ // Clears NuGet global-packages cache of Metalama and PostSharp.Engineering packages to prevent using old or corrupted package.
67+ void CleanNugetCache ( )
68+ {
69+ // Kill the processes to release the locks on the NuGet cache.
70+ ProcessKiller . KillWellKnownProcesses ( context . Console ) ;
71+
72+ // Use dotnet command to locate nuget cache directory.
73+ var success = ToolInvocationHelper . InvokeTool (
74+ context . Console ,
75+ "dotnet" ,
76+ "nuget locals global-packages -l" ,
77+ context . RepoDirectory ,
78+ out _ ,
79+ out var output ) ;
80+
81+ if ( ! success )
82+ {
83+ context . Console . WriteWarning ( "Couldn't locate NuGet cache directory, skipping cleaning it." ) ;
84+
85+ return ;
86+ }
87+
88+ // Get only directory location string.
89+ var nugetCacheDirectory = output . Split ( ' ' ) [ 1 ] . Trim ( ) ;
90+ var directoryInfo = new DirectoryInfo ( nugetCacheDirectory ) ;
91+
92+ // Delete all cached packages directories starting with 'Metalama'.
93+ foreach ( var dir in directoryInfo . EnumerateDirectories ( "metalama*" ) )
94+ {
95+ DeleteDirectory ( Path . Combine ( nugetCacheDirectory , dir . Name ) ) ;
96+ }
97+
98+ // Delete all cached packages directories starting with 'PostSharp.Engineering' but the current one.
99+ foreach ( var dir in directoryInfo . EnumerateDirectories ( "postsharp.engineering*" ) )
100+ {
101+ foreach ( var subDir in dir . EnumerateDirectories ( ) )
102+ {
103+ var directoryPath = Path . Combine ( nugetCacheDirectory , dir . Name , subDir . Name ) ;
104+
105+ if ( subDir . Name . Equals ( VersionHelper . EngineeringVersion , StringComparison . OrdinalIgnoreCase ) )
106+ {
107+ context . Console . WriteMessage ( $ "Skipping directory '{ directoryPath } '." ) ;
108+
109+ continue ;
110+ }
111+
112+ DeleteDirectory ( directoryPath ) ;
113+ }
114+ }
115+ }
116+
117+ // NugetCache must be automatically deleted only on TeamCity.
118+ if ( context is { IsContinuousIntegrationBuild : true , IsRunningUnderContainer : false } && ! settings . NoNuGetCacheCleanup )
119+ {
120+ context . Console . WriteHeading ( "Cleaning NuGet cache" ) ;
121+ context . Console . WriteMessage ( "The NuGet cache cleanup can be skipped using --no-nuget-cache-cleanup." ) ;
122+
123+ CleanNugetCache ( ) ;
124+ }
125+
126+ context . Console . WriteHeading ( $ "Cleaning { product . ProductName } " ) ;
127+
128+ foreach ( var directory in product . AdditionalDirectoriesToClean )
129+ {
130+ DeleteDirectory ( Path . Combine ( context . RepoDirectory , directory ) ) ;
131+ }
132+
133+ DeleteDirectory ( product . GetPrivateArtifactsAbsoluteDirectory ( context , settings . BuildConfiguration ) ) ;
134+
135+ DeleteDirectory ( product . GetPublicArtifactsAbsoluteDirectory ( context ) ) ;
136+
137+ DeleteDirectory (
138+ Path . Combine (
139+ context . RepoDirectory ,
140+ product . LogsDirectory ) ) ;
141+
142+ foreach ( var directory in Directory . GetDirectories ( context . RepoDirectory ) )
143+ {
144+ switch ( Path . GetFileName ( directory ) )
145+ {
146+ case "source-dependencies" :
147+ case "dependencies" :
148+ case ".sonarqube" :
149+ case { } s when s == product . EngineeringDirectory :
150+ continue ;
151+
152+ default :
153+ CleanRecursive ( directory ) ;
154+
155+ break ;
156+ }
157+ }
158+
159+ return true ;
160+ }
161+ }
148162}
0 commit comments