[go: nahoru, domu]

Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(401)
Delta Between Two Patch Sets: Tools/Google.Apis.Release/Program.cs
Issue 12767046: Issue 377: New build for releasing a new version (Closed) Base URL: https://google-api-dotnet-client.googlecode.com/hg/
Left Patch Set: minor Created 10 years, 10 months ago
Right Patch Set: david comments Created 10 years, 9 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « Tools/Google.Apis.Release/Google.Apis.Release.csproj ('k') | Tools/Google.Apis.Release/ProjectExtenstions.cs » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 using System; 1 /*
2 Copyright 2013 Google Inc
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17 using System;
2 using System.Collections.Generic; 18 using System.Collections.Generic;
3 using System.Diagnostics; 19 using System.Diagnostics;
4 using System.IO; 20 using System.IO;
5 using System.Linq; 21 using System.Linq;
6 using System.Reflection; 22 using System.Reflection;
7 using System.Text; 23 using System.Text;
8 using System.Text.RegularExpressions; 24 using System.Text.RegularExpressions;
9 using Microsoft.Build.Evaluation; 25 using Microsoft.Build.Evaluation;
10 using Microsoft.Build.Framework; 26 using Microsoft.Build.Framework;
11 using Microsoft.Build.Logging; 27 using Microsoft.Build.Logging;
12 28
13 using CommandLine; 29 using CommandLine;
14 using CommandLine.Text; 30 using CommandLine.Text;
15 using Ionic.Zip; 31 using Ionic.Zip;
16 32
17 using Google.Apis.Release.Repositories; 33 using Google.Apis.Release.Repositories;
34 using Google.Apis.Release.Wiki;
18 using Google.Apis.Utils; 35 using Google.Apis.Utils;
19 using Google.Apis.Release.Wiki; 36 using Google.Apis.Utils.Trace;
20 37
21 namespace Google.Apis.Release 38 namespace Google.Apis.Release
22 { 39 {
40 /// <summary>The main program for creating a new Google.Apis release.</summa ry>
23 class Program 41 class Program
24 { 42 {
43 /// <summary>The options class which contains the different options to t his publish release utility.</summary>
25 public class Options 44 public class Options
26 { 45 {
27 #region HelpText 46 #region HelpText
28 47
29 const string VersionHelpText = "The version number of this release - <Major.Minor.Build> only."; 48 const string VersionHelpText = "The version number of this release - <Major.Minor.Build> only.";
30 const string OutputHelpText = "Define the output directory for this build. " + 49 const string OutputHelpText = "Define the output directory for this build. " +
31 "Notice that it's relative to current directory."; 50 "Notice that it's relative to current directory.";
32 const string StepHelpText = "Two options: '1' for building the core library \n" + 51 const string StepHelpText = "Two options: " +
33 "'2' for compiling samples, updating wiki and push to contrib th e new version \n" + 52 "'1' for building the core library. \n" +
34 "'3' for publishing on the local packages to NuGet"; 53 "'2' for compiling samples, updating wiki and push to contrib th e new version.";
35 const string IsBetaHelpText = "Is this release is beta?"; 54 const string IsBetaHelpText = "Is this release beta?";
36 const string NuGetApiKeyHelpText = "Define the NuGet API key to publ ish to NuGet main repository"; 55 const string NuGetApiKeyHelpText = "Define the NuGet API key to publ ish to NuGet main repository.";
37 56
38 [HelpOption] 57 [HelpOption]
39 public string GetHelp() 58 public string GetHelp()
40 { 59 {
41 return HelpText.AutoBuild(this, c => HelpText.DefaultParsingErro rsHandler(this, c)); 60 return HelpText.AutoBuild(this, c => HelpText.DefaultParsingErro rsHandler(this, c));
42 } 61 }
43 62
44 #endregion 63 #endregion
45 64
46 [Option('v', "version", Required = true, 65 [Option('v', "version", Required = true, HelpText = VersionHelpText) ]
47 HelpText = VersionHelpText)]
48 public string Version { get; set; } 66 public string Version { get; set; }
49 67
50 [Option('d', "dir", Required = true, HelpText = OutputHelpText)] 68 [Option('d', "dir", Required = true, HelpText = OutputHelpText)]
51 public string OutputDirectory { get; set; } 69 public string OutputDirectory { get; set; }
52 70
53 [Option('s', "step", Required = true, HelpText = StepHelpText)] 71 [Option('s', "step", Required = true, HelpText = StepHelpText)]
54 public int Step { get; set; } 72 public int Step { get; set; }
55 73
56 [Option('b', "beta", DefaultValue = true, HelpText = IsBetaHelpText) ] 74 [Option('b', "beta", DefaultValue = true, HelpText = IsBetaHelpText) ]
57 public bool IsBeta { get; set; } 75 public bool IsBeta { get; set; }
58 76
59 [Option('k', "nuget_key", HelpText = NuGetApiKeyHelpText)] 77 [Option('k', "nuget_key", HelpText = NuGetApiKeyHelpText)]
60 public string NuGetApiKey { get; set; } 78 public string NuGetApiKey { get; set; }
61 } 79 }
62 80
63 static readonly TraceSource TraceSource = new TraceSource("Google.Apis") ; 81 private static readonly TraceSource TraceSource = new TraceSource("Googl e.Apis");
64 82
65 /// <summary> Command line arguments. </summary> 83 /// <summary>Command line arguments.</summary>
66 private readonly Options options; 84 private readonly Options options;
67 85
68 private int MajorVersion { get; set; } 86 private int MajorVersion { get; set; }
69 private int MinorVersion { get; set; } 87 private int MinorVersion { get; set; }
70 private int BuildVersion { get; set; } 88 private int BuildVersion { get; set; }
71 89
72 private string Tag 90 private string Tag
73 { 91 {
74 get { return options.Version + (options.IsBeta ? "-beta" : ""); } 92 get { return options.Version + (options.IsBeta ? "-beta" : ""); }
75 } 93 }
76 94
77 /// <summary>The "default" repository.</summary> 95 /// <summary>Gets or sets the "default" repository.</summary>
78 private Hg DefaultRepository { get; set; } 96 private Hg DefaultRepository { get; set; }
79 97
80 /// <summary>The "samples" repository.</summary> 98 /// <summary>Gets or sets the "samples" repository.</summary>
81 private Hg SamplesRepository { get; set; } 99 private Hg SamplesRepository { get; set; }
82 100
83 /// <summary>The "wiki" repository.</summary> 101 /// <summary>Gets or sets the "wiki" repository.</summary>
84 private Hg WikiRepository { get; set; } 102 private Hg WikiRepository { get; set; }
85 103
86 /// <summary>The "contrib" repository.</summary> 104 /// <summary>Gets or sets the "contrib" repository.</summary>
87 private Hg ContribRepository { get; set; } 105 private Hg ContribRepository { get; set; }
88 106
107 /// <summary>Gets all four repositories.</summary>
89 private IEnumerable<Hg> AllRepositories 108 private IEnumerable<Hg> AllRepositories
90 { 109 {
91 get { return new List<Hg> { DefaultRepository, SamplesRepository, Wi kiRepository, ContribRepository }; } 110 get { return new List<Hg> { DefaultRepository, SamplesRepository, Wi kiRepository, ContribRepository }; }
92 } 111 }
93 112
113 /// <summary>
114 /// Clones URL format which expects one parameter of the repository name (the default repository should be·
115 /// empty).
116 /// </summary>
117 private const string CloneUrlFormat = "https://code.google.com/p/google- api-dotnet-client{0}/";
118
94 static void Main(string[] args) 119 static void Main(string[] args)
95 { 120 {
121 bool valid = true;
122
96 var options = new Options(); 123 var options = new Options();
97 if (!CommandLine.Parser.Default.ParseArguments(args, options)) 124 if (!CommandLine.Parser.Default.ParseArguments(args, options))
98 { 125 {
99 Console.ReadKey(); 126 Console.ReadKey();
100 return; 127 return;
101 } 128 }
102 129
130 if (options.Step > 2 || options.Step < 1)
131 {
132 TraceSource.TraceEvent(TraceEventType.Error, "Invalid Step. Vali d step is '1' or '2'.");
133 valid = false;
134 }
135
103 var match = Regex.Match(options.Version, @"^(\d+)\.(\d+)\.(\d)+$"); 136 var match = Regex.Match(options.Version, @"^(\d+)\.(\d+)\.(\d)+$");
104 if (!match.Success) 137 if (!match.Success)
105 { 138 {
106 TraceSource.TraceEvent(TraceEventType.Error, 139 TraceSource.TraceEvent(TraceEventType.Error,
107 "Invalid version Number. Version should be in <Major>.<Minor >.<Build> form."); 140 "Invalid version Number. Version should be in <Major>.<Minor >.<Build> form.");
108 } 141 valid = false;
109 142 }
110 var p = new Program(options) 143
144 var program = new Program(options)
111 { 145 {
112 MajorVersion = int.Parse(match.Groups[1].Value), 146 MajorVersion = int.Parse(match.Groups[1].Value),
113 MinorVersion = int.Parse(match.Groups[2].Value), 147 MinorVersion = int.Parse(match.Groups[2].Value),
114 BuildVersion = int.Parse(match.Groups[3].Value), 148 BuildVersion = int.Parse(match.Groups[3].Value),
115 }; 149 };
116 150
117 try 151 if (valid)
118 { 152 {
119 p.Run(); 153 try
120 } 154 {
121 catch (Exception ex) 155 program.Run();
122 { 156 }
123 TraceSource.TraceEvent(TraceEventType.Error, "Exception occurred while running. Exception is: {0}", 157 catch (Exception ex)
124 ex.Message); 158 {
159 TraceSource.TraceEvent(TraceEventType.Error, "Exception occu rred while running. Exception is: {0}",
160 ex.Message);
161 }
125 } 162 }
126 163
127 Console.WriteLine("Press any key to continue..."); 164 Console.WriteLine("Press any key to continue...");
128 Console.ReadKey(); 165 Console.ReadKey();
129 } 166 }
130 167
168 /// <summary>The main release logic for creating a new release of Google .Apis.</summary>
131 private void Run() 169 private void Run()
132 { 170 {
133 const string CloneUrl = "https://code.google.com/p/google-api-dotnet -client{0}/"; 171 DefaultRepository = new Hg(new Uri(string.Format(CloneUrlFormat, "") ), "default");
134 172
135 DefaultRepository = new Hg(new Uri(string.Format(CloneUrl, "")), "de fault"); 173 // Step 1 is only for creating Google.Apis and Google.Apis.Authentic ation packages
136
137 if (options.Step == 1) 174 if (options.Step == 1)
138 { 175 {
139 if (BuildVersion != 0) 176 DoStep1();
140 { 177 }
141 DefaultRepository.Update(string.Format("{0}.{1}", MajorVersi on, MinorVersion)); 178 // Step 2 should be done after the NuGet publisher generated all the APIs and the samples repository was·
142 } 179 // updated with the new packages
143
144 if (!HasIncomingChanges(new List<Hg> { DefaultRepository }))
145 {
146 //if (BuildDefaultRepository())
147 {
148 CreateNuGetPackages();
149 }
150 }
151 }
152
153 else if (options.Step == 2) 180 else if (options.Step == 2)
154 { 181 {
155 Console.WriteLine(); 182 DoStep2();
156 Console.WriteLine(); 183 }
184 }
185
186 /// <summary>Creates Google.Apis and Google.Apis.Authentication packages .</summary>
187 private void DoStep1()
188 {
189 if (BuildVersion != 0)
190 {
191 DefaultRepository.Update(string.Format("{0}.{1}", MajorVersion, MinorVersion));
192 }
193
194 // if there are incoming changes those changes will be printed, othe rwise we can continue in the process
195 if (!HasIncomingChanges(new List<Hg> { DefaultRepository }))
196 {
197 // in case build fails the method will print its failures
198 if (BuildDefaultRepository())
199 {
200 CreateCoreNuGetPackages();
201 // TODO(peleyal): release notes should be part of the packag e
202 }
203 }
204 }
205
206 /// <summary>
207 /// Doing the following:
208 /// <list type="number">
209 /// <item><description>Builds samples</description></item>
210 /// <item><description>Creates a release notes</description></item>
211 /// <item><description>Update wiki download page</description></item>
212 /// <item><description>Create a new release in the contrib repository</d escription></item>
213 /// <item><description>Commits, Tags and Pushes</description></item>
214 /// </list>
215 /// </summary>
216 private void DoStep2()
217 {
218 Console.WriteLine();
219 Console.WriteLine();
220 Console.WriteLine("=========================");
221 Console.WriteLine("Prerequisites for Step 2:");
222 Console.WriteLine("You ran Step 1.");
223 Console.WriteLine("You upgraded the Google.Apis NuGet packages for e ach sample in the samples " +
224 "repository and pushed that change.");
225 Console.WriteLine("=========================");
226 if (!CanContinue())
227 {
228 return;
229 }
230
231 SamplesRepository = new Hg(new Uri(string.Format(CloneUrlFormat, ".s amples")), "samples");
232 WikiRepository = new Hg(new Uri(string.Format(CloneUrlFormat, ".wiki ")), "wiki");
233 ContribRepository = new Hg(new Uri(string.Format(CloneUrlFormat, ".c ontrib")), "contrib");
234
235 // if there are incoming changes those changes will be printed, othe rwise we can continue in the·
236 // process
237 if (!HasIncomingChanges(AllRepositories))
238 {
239 BuildSamples();
240 var notes = CreateContribNewRelease();
241 UpdateWiki(notes);
242
243 foreach (var repository in AllRepositories)
244 {
245 repository.AddRemoveFiles();
246 }
247
157 Console.WriteLine("========================="); 248 Console.WriteLine("=========================");
158 Console.WriteLine("Prerequisites for Step 2:"); 249 Console.WriteLine("Commit, Tag and Push");
159 Console.WriteLine("You ran Step 1."); 250 Console.WriteLine("=========================");
160 Console.WriteLine("You upgrade the libraries in the samples repo sitory and pushed that change."); 251 if (!CanContinue())
252 {
253 return;
254 }
255
256 // commit
257 CommitAndTag();
258
259 // push
260 foreach (Hg repository in AllRepositories)
261 {
262 repository.Push();
263 }
264
265 // create branch
266 PrintCreateBranch();
267
268 // publish core components to NuGet
269 if (!string.IsNullOrEmpty(options.NuGetApiKey))
270 {
271 PublishPackagesToNuGet();
272 Console.WriteLine("Now... you should run the NuGet publisher to publish a new PCL "
273 + "for each generated Google API. Run: " +
274 "Google.Apis.NuGet.Publisher --all_apis true -m publishe r -k [NUGET_KEY]");
275 }
276 else
277 {
278 TraceSource.TraceEvent(TraceEventType.Error, "NuGet API key is empty!");
279 }
280 }
281 }
282
283 /// <summary>Asks the user if he wants to continue in the process.</summ ary>
284 /// <returns><c>true</c> if the user to press 'y' or 'yes' to continue</ returns>
285 private bool CanContinue()
286 {
287 var yesOptions = new[] { "y", "yes" };
288 var noOptions = new[] { "n", "no" };
289
290 string input;
291 do
292 {
161 Console.WriteLine("Press 'y' | 'yes' to continue, or 'n' | 'no' to stop"); 293 Console.WriteLine("Press 'y' | 'yes' to continue, or 'n' | 'no' to stop");
162 Console.WriteLine("========================="); 294 input = Console.ReadLine().ToLower();
163 var input = Console.ReadLine(); 295 } while (!yesOptions.Contains(input) && !noOptions.Contains(input));
164 var yesOptions = new[] { "y", "yes" }; 296
165 var noOptions = new[] { "n", "no" }; 297 return yesOptions.Contains(input);
166 while (!yesOptions.Contains(input) && !noOptions.Contains(input) ) 298 }
167 { 299
168 Console.WriteLine("please press 'y' | 'yes' | 'n' | 'no' onl y"); 300 /// <summary>Publishes the core packages to NuGet main repository.</summ ary>
169 input = Console.ReadLine();
170 }
171
172 if (yesOptions.Contains(input))
173 {
174 SamplesRepository = new Hg(new Uri(string.Format(CloneUrl, " .samples")), "samples");
175 WikiRepository = new Hg(new Uri(string.Format(CloneUrl, ".wi ki")), "wiki");
176 ContribRepository = new Hg(new Uri(string.Format(CloneUrl, " .contrib")), "contrib");
177
178 if (!HasIncomingChanges(new List<Hg> {·
179 DefaultRepository, SamplesRepository, WikiRepository, Co ntribRepository }))
180 {
181 BuildSamples();
182 var notes = BuildContribNewRelease();
183 UpdateWiki(notes);
184
185 AddRemoveFiles();
186
187 Console.WriteLine("=========================");
188 Console.WriteLine("Commit, Tag and Push");
189 Console.WriteLine("Press 'y' | 'yes' to continue, or 'n' | 'no' to stop");
190 Console.WriteLine("=========================");
191 input = Console.ReadLine();
192 while (!yesOptions.Contains(input) && !noOptions.Contain s(input))
193 {
194 Console.WriteLine("please press 'y' | 'yes' | 'n' | 'no' only");
195 input = Console.ReadLine();
196 }
197
198 if (yesOptions.Contains(input))
199 {
200 // commit
201 CommitAndTag();
202
203 // push
204 foreach (Hg repository in AllRepositories)
205 {
206 repository.Push();
207 }
208
209 // create branch
210 PrintCreateBranch();
211
212 // publish core components to NuGet
213 if (!string.IsNullOrEmpty(options.NuGetApiKey))
214 {
215 PublishPackagesToNuGet();
216 }
217 else
218 {
219 TraceSource.TraceEvent(TraceEventType.Error, "Nu Get API key is empty!");
220 }
221
222 }
223 }
224 }
225 }
226 else
227 {
228 TraceSource.TraceEvent(TraceEventType.Error, "Invalid step optio n!");
229 }
230 }
231
232 private void PublishPackagesToNuGet() 301 private void PublishPackagesToNuGet()
233 { 302 {
234 var apiNupkgPath = Path.Combine(NuGetUtils.LocalNuGetPackageFolder, 303 var apiNupkgPath = Path.Combine(NuGetUtilities.LocalNuGetPackageFold er,
235 string.Format("Google.Apis.{0}.nupkg", Tag)); 304 string.Format("Google.Apis.{0}.nupkg", Tag));
236 NuGetUtils.PublishToNuget(apiNupkgPath, options.NuGetApiKey); 305 NuGetUtilities.PublishToNuget(apiNupkgPath, options.NuGetApiKey);
237 306
238 var authenticationNupkgPath = Path.Combine(NuGetUtils.LocalNuGetPack ageFolder, 307 var authenticationNupkgPath = Path.Combine(NuGetUtilities.LocalNuGet PackageFolder,
239 string.Format("Google.Apis.Authentication.{0}.nupkg", Tag)); 308 string.Format("Google.Apis.Authentication.{0}.nupkg", Tag));
240 NuGetUtils.PublishToNuget(authenticationNupkgPath, options.NuGetApiK ey); 309 NuGetUtilities.PublishToNuget(authenticationNupkgPath, options.NuGet ApiKey);
241 } 310 }
242 311
243 private void AddRemoveFiles() 312 /// <summary>
244 { 313 /// Displays the user orders how to create a branch (only in case it's a new major or minor release.
245 foreach (var repository in AllRepositories) 314 /// </summary>
246 {
247 repository.AddRemoveFiles();
248 }
249 }
250
251 /// <summary>Displays the user orders how to create a branch.</summary>
252 private void PrintCreateBranch() 315 private void PrintCreateBranch()
253 { 316 {
254 if (BuildVersion != 0) 317 if (BuildVersion != 0)
255 { 318 {
256 // No need to branch in that case 319 // No need to branch in that case
257 return; 320 return;
258 } 321 }
259 322
260 // TODO(peleyal): automate this as well 323 // TODO(peleyal): consider automate this as well
261 Console.WriteLine("You should create a new branch for this release n ow:"); 324 Console.WriteLine("You should create a new branch for this release n ow:");
262 Console.WriteLine("cd " + DefaultRepository.WorkingDirectory); 325 Console.WriteLine("cd " + DefaultRepository.WorkingDirectory);
263 var branchVersion = string.Format("{0}.{1}", MajorVersion, MinorVers ion); 326 var branchVersion = string.Format("{0}.{1}", MajorVersion, MinorVers ion);
264 Console.WriteLine("hg branch " + branchVersion); 327 Console.WriteLine("hg branch " + branchVersion);
265 Console.WriteLine(string.Format("hg commit -m create {0} branch", br anchVersion)); 328 Console.WriteLine(string.Format("hg commit -m create {0} branch", br anchVersion));
266 Console.WriteLine("hg push --new-branch"); 329 Console.WriteLine("hg push --new-branch");
267 } 330 }
268 331
332 /// <summary>Commits all changes in all repositories and tags the "defau lt" repository.</summary>
269 private void CommitAndTag() 333 private void CommitAndTag()
270 { 334 {
271 foreach (var repository in AllRepositories) 335 foreach (var repository in AllRepositories)
272 { 336 {
273 TraceSource.TraceEvent(TraceEventType.Information, "{0} - Commit ting", repository.Name); 337 TraceSource.TraceEvent(TraceEventType.Information, "{0} - Commit ting", repository.Name);
274 338
275 bool committed = repository.Commit("Release " + Tag); 339 bool committed = repository.Commit("Release " + Tag);
276 340
341 // TODO(peleyal): think to remove this if from this function. I don't like a if inside a loop statement
277 if (repository.Equals(DefaultRepository) && committed) 342 if (repository.Equals(DefaultRepository) && committed)
278 { 343 {
279 try 344 try
280 { 345 {
281 repository.Tag(Tag, false); 346 repository.Tag(Tag, false);
282 TraceSource.TraceEvent(TraceEventType.Information, "{0} - Was tagged \"{1}\"", 347 TraceSource.TraceEvent(TraceEventType.Information, "{0} - Was tagged \"{1}\"",
283 repository.Name, Tag); 348 repository.Name, Tag);
284 } 349 }
285 catch (Exception ex) 350 catch (Exception ex)
286 { 351 {
287 TraceSource.TraceEvent(TraceEventType.Error, "{0} - Tagg ing Failed. Exception is: {1}", 352 TraceSource.TraceEvent(TraceEventType.Error, "{0} - Tagg ing Failed. Exception is: {1}",
288 repository.Name, ex.Message); 353 repository.Name, ex.Message);
289 } 354 }
290 } 355 }
291 356
292 TraceSource.TraceEvent(TraceEventType.Information, "{0} - Commit ted", repository.Name); 357 TraceSource.TraceEvent(TraceEventType.Information, "{0} - Commit ted", repository.Name);
293 } 358 }
294 } 359 }
295 360
361 /// <summary>Updates the "Downloads" wiki page with the new release note s.</summary>
296 private void UpdateWiki(string notes) 362 private void UpdateWiki(string notes)
297 { 363 {
298 TraceSource.TraceEvent(TraceEventType.Information, "Updating wiki do wnloads page"); 364 TraceSource.TraceEvent(TraceEventType.Information, "Updating wiki do wnloads page");
299 365
300 // TODO(peleyal): improve. Currently we count on that old release of X.Y.Z is X.Y-1.0 366 // TODO(peleyal): improve. Currently we count on that old release of X.Y.Z is X.Y-1.0
301 var oldVersion = string.Format("{0}.{1}.{2}", MajorVersion, MinorVer sion - 1, 0); 367 var oldVersion = string.Format("{0}.{1}.{2}", MajorVersion, MinorVer sion - 1, 0);
302 DownloadsPageUpdater.UpdateWiki(WikiRepository.WorkingDirectory, not es, oldVersion, options.Version); 368 DownloadsPageUpdater.UpdateWiki(WikiRepository.WorkingDirectory, not es, oldVersion, options.Version);
303 369
304 TraceSource.TraceEvent(TraceEventType.Information, "wiki downloads p age was updated"); 370 TraceSource.TraceEvent(TraceEventType.Information, "wiki downloads p age was updated");
305 } 371 }
306 372
307 private string BuildContribNewRelease() 373 /// <summary>Creates a new release in the "contrib" repository.</summary >
374 /// <returns>The release notes of this version</returns>
375 private string CreateContribNewRelease()
308 { 376 {
309 TraceSource.TraceEvent(TraceEventType.Information, "Building Contrib release"); 377 TraceSource.TraceEvent(TraceEventType.Information, "Building Contrib release");
310 378
311 string releaseDir = ContribRepository.Combine(Tag); 379 string releaseDir = ContribRepository.Combine(Tag);
312 380
313 // Clear existing directories. 381 // Clear existing directories.
314 DirectoryUtils.ClearOrCreateDirectory(releaseDir); 382 DirectoryUtilities.ClearOrCreateDirectory(releaseDir);
315 string genDir = Path.Combine(releaseDir, "Generated"); 383 string genDir = Path.Combine(releaseDir, "Generated");
316 Directory.CreateDirectory(genDir); 384 Directory.CreateDirectory(genDir);
317 385
318 #region [RELEASE_VERSION]/Generated/Bin 386 #region [RELEASE_VERSION]/Generated/Bin
319 387
320 string binDir = Path.Combine(genDir, "Bin"); 388 string binDir = Path.Combine(genDir, "Bin");
321 TraceSource.TraceEvent(TraceEventType.Information, "Generating \"{0} \" directory", 389 TraceSource.TraceEvent(TraceEventType.Information, "Generating \"{0} \" directory",
322 DirectoryUtils.GetRelativePath(binDir, ContribRepository.Working Directory)); 390 DirectoryUtilities.GetRelativePath(binDir, ContribRepository.Wor kingDirectory));
391
323 Directory.CreateDirectory(binDir); 392 Directory.CreateDirectory(binDir);
324 393 foreach (var project in ReleaseProjects)
325 { 394 {
326 foreach (var project in ReleaseProjects) 395 var releasePath = Path.Combine(project.DirectoryPath, "Bin", "Re lease");
327 { 396 foreach (var filePath in Directory.GetFiles(releasePath, "Google .Apis.*"))
328 var releasePath = Path.Combine(project.DirectoryPath, "Bin", "Release"); 397 {
329 foreach (var filePath in Directory.GetFiles(releasePath, "Go ogle.Apis.*")) 398 File.Copy(filePath,
330 { 399 Path.Combine(binDir, filePath.Substring(filePath.LastInd exOf("\\") + 1)), true);
331 File.Copy(filePath, 400 }
332 Path.Combine(binDir, filePath.Substring(filePath.Las tIndexOf("\\") + 1)), true); 401 }
333 } 402
334 } 403 // TODO(peleyal): Put also the nuspec and nupkg
335
336 // Put also the nuspec and nupkg
337 }
338 404
339 #endregion 405 #endregion
340 406
341 #region [RELEASE_VERSION]/ZipFiles 407 #region [RELEASE_VERSION]/ZipFiles
342 408
343 string zipFilesDir = Path.Combine(genDir, "ZipFiles"); 409 string zipFilesDir = Path.Combine(genDir, "ZipFiles");
344 TraceSource.TraceEvent(TraceEventType.Information, "Generating \"{0} \" directory", 410 TraceSource.TraceEvent(TraceEventType.Information, "Generating \"{0} \" directory",
345 DirectoryUtils.GetRelativePath(zipFilesDir, ContribRepository.Wo rkingDirectory)); 411 DirectoryUtilities.GetRelativePath(zipFilesDir, ContribRepositor y.WorkingDirectory));
346 412
347 Directory.CreateDirectory(zipFilesDir); 413 Directory.CreateDirectory(zipFilesDir);
348 { 414 foreach (var project in ReleaseProjects)
349 foreach (var project in ReleaseProjects) 415 {
350 { 416 project.Build("Clean");
351 project.Build("Clean"); 417 }
352 } 418
353 419 TraceSource.TraceEvent(TraceEventType.Information, "Release projects were cleaned");
354 TraceSource.TraceEvent(TraceEventType.Information, "Release proj ects were cleaned"); 420
355 421 // source.zip
356 // source.zip 422 var fileNameFormat = "google-api-dotnet-client-{0}.{1}.zip";
357 var fileNameFormat = "google-api-dotnet-client-{0}.{1}.zip"; 423 var sourceZipName = string.Format(fileNameFormat, Tag, "source");
358 var sourceZipName = string.Format(fileNameFormat, Tag, "source") ; 424 using (var zip = new ZipFile(Path.Combine(zipFilesDir, sourceZipName )))
359 using (var zip = new ZipFile(Path.Combine(zipFilesDir, sourceZip Name))) 425 {
360 { 426 zip.AddDirectory(Path.Combine(DefaultRepository.WorkingDirectory , "Src"), "Src");
361 zip.AddDirectory(Path.Combine(DefaultRepository.WorkingDirec tory, "Src"), "Src"); 427 zip.AddFile(Path.Combine(DefaultRepository.WorkingDirectory, "Go ogleApisClient.sln"), "");
362 zip.AddFile(Path.Combine(DefaultRepository.WorkingDirectory, "GoogleApisClient.sln"), ""); 428 zip.AddFile(Path.Combine(DefaultRepository.WorkingDirectory, "LI CENSE"), "");
363 zip.AddFile(Path.Combine(DefaultRepository.WorkingDirectory, "LICENSE"), ""); 429 zip.Save();
364 zip.Save(); 430 }
365 } 431 TraceSource.TraceEvent(TraceEventType.Information, "{0} was created" , sourceZipName);
366 TraceSource.TraceEvent(TraceEventType.Information, "{0} was crea ted", sourceZipName); 432
367 433 // binary.zip
368 // binary.zip 434 var binaryZipName = string.Format(fileNameFormat, Tag, "binary");
369 var binaryZipName = string.Format(fileNameFormat, Tag, "binary") ; 435 using (var zip = new ZipFile(Path.Combine(zipFilesDir, binaryZipName )))
370 using (var zip = new ZipFile(Path.Combine(zipFilesDir, binaryZip Name))) 436 {
371 { 437 Directory.GetFiles(binDir).ToList().ForEach(f => zip.AddFile(Pat h.Combine(binDir, f), ""));
372 Directory.GetFiles(binDir).ToList().ForEach(f => zip.AddFile (Path.Combine(binDir, f), "")); 438 zip.Save();
373 zip.Save(); 439 }
374 } 440 TraceSource.TraceEvent(TraceEventType.Information, "{0} was created" , binaryZipName);
375 TraceSource.TraceEvent(TraceEventType.Information, "{0} was crea ted", binaryZipName); 441
376 442
377 443 // samples.zip
378 // samples.zip 444 var samplesZipName = string.Format(fileNameFormat, Tag, "samples");
379 var samplesZipName = string.Format(fileNameFormat, Tag, "samples "); 445 using (var zip = new ZipFile(Path.Combine(zipFilesDir, samplesZipNam e)))
380 using (var zip = new ZipFile(Path.Combine(zipFilesDir, samplesZi pName))) 446 {
381 { 447 foreach (var d in Directory.GetDirectories(SamplesRepository.Wor kingDirectory))
382 foreach (var d in Directory.GetDirectories(SamplesRepository .WorkingDirectory)) 448 {
449 if (!d.EndsWith(".hg"))
383 { 450 {
384 if (!d.EndsWith(".hg")) 451 var directoryName = d.Substring(d.LastIndexOf("\\") + 1) ;
385 { 452 zip.AddDirectory(Path.Combine(SamplesRepository.WorkingD irectory, d), directoryName);
386 var directoryName = d.Substring(d.LastIndexOf("\\") + 1);
387 zip.AddDirectory(Path.Combine(SamplesRepository.Work ingDirectory, d), directoryName);
388 }
389 } 453 }
390 foreach (var f in Directory.GetFiles(SamplesRepository.Worki ngDirectory, "*.sln")) 454 }
391 { 455 foreach (var f in Directory.GetFiles(SamplesRepository.WorkingDi rectory, "*.sln"))
392 zip.AddFile(Path.Combine(SamplesRepository.WorkingDirect ory, f), ""); 456 {
393 } 457 zip.AddFile(Path.Combine(SamplesRepository.WorkingDirectory, f), "");
394 zip.Save(); 458 }
395 } 459 zip.Save();
396 460 }
397 TraceSource.TraceEvent(TraceEventType.Information, "{0} was crea ted", samplesZipName); 461
398 } 462 TraceSource.TraceEvent(TraceEventType.Information, "{0} was created" , samplesZipName);
399 463
400 #endregion 464 #endregion
401 465
402 #region [RELEASE_VERSION]/ReleaseNotes.txt 466 #region [RELEASE_VERSION]/ReleaseNotes.txt
403 467
404 var notes = CreateChangelog(); 468 var notes = GetChangelog();
405 TraceSource.TraceEvent(TraceEventType.Information, "Creating Release Notes file"); 469 TraceSource.TraceEvent(TraceEventType.Information, "Creating Release Notes file");
406 var noteFilePath = Path.Combine(genDir, "ReleaseNotes.txt"); 470 var noteFilePath = Path.Combine(genDir, "ReleaseNotes.txt");
407 File.WriteAllText(noteFilePath, notes); 471 File.WriteAllText(noteFilePath, notes);
408 472
409 #endregion 473 #endregion
410 474
411 // open the created change-log and read again the notes (in case the user had modified the file) 475 // open the created change-log and read again the notes (in case the user had modified the file)
412 Process.Start(noteFilePath).WaitForExit(); 476 Process.Start(noteFilePath).WaitForExit();
413 notes = File.ReadAllText(noteFilePath); 477 notes = File.ReadAllText(noteFilePath);
414 478
415 return notes; 479 return notes;
416 } 480 }
417 481
418 private string CreateChangelog() 482 /// <summary>
483 /// Returns the notes list of this release. It contains the change log o f all pushes to the "default"·
484 /// repository.
485 /// </summary>
486 private string GetChangelog()
419 { 487 {
420 StringBuilder log = new StringBuilder(); 488 StringBuilder log = new StringBuilder();
421 log.AppendLine("Google .NET Client Library"); 489 log.AppendLine("Google .NET Client Library");
422 log.AppendLine(string.Format("Stable Release '{0}'", Tag)); 490 log.AppendLine(string.Format("Stable Release '{0}'", Tag));
423 log.AppendLine(DateTime.UtcNow.ToLongDateString()); 491 log.AppendLine(DateTime.UtcNow.ToLongDateString());
424 log.AppendLine("==========================================="); 492 log.AppendLine("===========================================");
425 493
426 log.AppendLine().AppendLine("Changes:"); 494 log.AppendLine().AppendLine("Changes:");
427 foreach (string line in DefaultRepository.CreateChangelist()) 495 foreach (string line in DefaultRepository.CreateChangelist())
428 { 496 {
429 log.AppendLine(" " + line); 497 log.AppendLine(" " + line);
430 } 498 }
431 499
432 return log.ToString(); 500 return log.ToString();
433 } 501 }
434 502
503 /// <summary>Builds all projects in the "samples" repository.</summary>
435 private void BuildSamples() 504 private void BuildSamples()
436 { 505 {
437 // Build all the samples projects. 506 // build all the samples projects.
438 TraceSource.TraceEvent(TraceEventType.Information, "Building the sam ples"); 507 TraceSource.TraceEvent(TraceEventType.Information, "Building the sam ples");
439 foreach (string csproj in Directory.GetFiles(SamplesRepository.Worki ngDirectory, "*.csproj", 508 foreach (string csproj in Directory.GetFiles(SamplesRepository.Worki ngDirectory, "*.csproj",
440 SearchOption.AllDirectories)) 509 SearchOption.AllDirectories))
441 { 510 {
442 Project project = new Project(csproj); 511 Project project = new Project(csproj);
443 project.SetProperty("Configuration", "Release"); 512 project.SetProperty("Configuration", "Release");
444 TraceSource.TraceEvent(TraceEventType.Information, "Building {0} ", project.GetName()); 513 TraceSource.TraceEvent(TraceEventType.Information, "Building {0} ", project.GetName());
445 bool success = project.Build("Build", new[] { new ConsoleLogger( LoggerVerbosity.Quiet) }); 514 bool success = project.Build("Build", new[] { new ConsoleLogger( LoggerVerbosity.Quiet) });
446 if (!success) 515 if (!success)
447 { 516 {
448 TraceSource.TraceEvent(TraceEventType.Error, "Building {0} F AILED", project.GetName()); 517 TraceSource.TraceEvent(TraceEventType.Error, "Building {0} F AILED", project.GetName());
449 } 518 }
450 project.Build("Clean"); 519 project.Build("Clean");
451 TraceSource.TraceEvent(TraceEventType.Information, "Building {0} succeeded", project.GetName()); 520 TraceSource.TraceEvent(TraceEventType.Information, "Building {0} succeeded", project.GetName());
452 } 521 }
453 } 522 }
454 523
524 /// <summary>Returns <c>true</c> if one of the repositories has incoming changes.</summary>
455 private bool HasIncomingChanges(IEnumerable<Hg> repositories) 525 private bool HasIncomingChanges(IEnumerable<Hg> repositories)
456 { 526 {
457 foreach (var repository in repositories) 527 foreach (var repository in repositories)
458 { 528 {
459 if (repository.HasIncomingChanges) 529 if (repository.HasIncomingChanges)
460 { 530 {
461 TraceSource.TraceEvent(TraceEventType.Error, 531 TraceSource.TraceEvent(TraceEventType.Error,
462 "[{0}] has incoming changes. Run hg pull & update first! ", repository.Name); 532 "[{0}] has incoming changes. Run hg pull & update first! ", repository.Name);
463 return true; 533 return true;
464 } 534 }
465 } 535 }
466 return false; 536 return false;
467 } 537 }
468 538
469 539 /// <summary>Creates the Google.Apis and Google.Apis.Authentication NuGe t packages.</summary>
470 private void CreateNuGetPackages() 540 private void CreateCoreNuGetPackages()
471 { 541 {
472 // create a resource dir in the working folder 542 // create a resource dir in the working folder
473 var destDirectory = Path.Combine(Environment.CurrentDirectory, "Reso urces"); 543 var destDirectory = Path.Combine(Environment.CurrentDirectory, "Reso urces");
474 if (Directory.Exists(destDirectory)) 544 if (Directory.Exists(destDirectory))
475 { 545 {
476 Directory.Delete(destDirectory, true); 546 Directory.Delete(destDirectory, true);
477 } 547 }
478 548
479 FileInfo info = new FileInfo(Assembly.GetEntryAssembly().Location); 549 FileInfo info = new FileInfo(Assembly.GetEntryAssembly().Location);
480 DirectoryUtils.CopyDirectory(Path.Combine(info.Directory.FullName, " Resources"), destDirectory); 550 DirectoryUtilities.CopyDirectory(Path.Combine(info.Directory.FullNam e, "Resources"), destDirectory);
481 551
482 var newVersion = options.Version + "-beta"; 552 var newVersion = options.Version + "-beta";
483 553
554 // get the Google.Apis and Google.Apis.Authentication nuspec files a nd replace the version in it
484 var apiNuspec = Path.Combine(destDirectory, "Google.Apis.VERSION.nus pec"); 555 var apiNuspec = Path.Combine(destDirectory, "Google.Apis.VERSION.nus pec");
485 var newApiNuspec = apiNuspec.Replace("VERSION", newVersion); 556 var newApiNuspec = apiNuspec.Replace("VERSION", newVersion);
486 var authenticationNuspec = Path.Combine(destDirectory, "Google.Apis. Authentication.VERSION.nuspec"); 557 var authenticationNuspec = Path.Combine(destDirectory, "Google.Apis. Authentication.VERSION.nuspec");
487 var newAuthenticationNuspec = authenticationNuspec.Replace("VERSION" , newVersion); 558 var newAuthenticationNuspec = authenticationNuspec.Replace("VERSION" , newVersion);
488 559
489 File.Move(apiNuspec, newApiNuspec); 560 File.Move(apiNuspec, newApiNuspec);
490 File.Move(authenticationNuspec, newAuthenticationNuspec); 561 File.Move(authenticationNuspec, newAuthenticationNuspec);
491 562
492 var allLines = File.ReadAllText(newApiNuspec).Replace("VERSION", new Version); 563 var allLines = File.ReadAllText(newApiNuspec).Replace("VERSION", new Version);
493 File.WriteAllText(newApiNuspec, allLines); 564 File.WriteAllText(newApiNuspec, allLines);
494 565
495 allLines = File.ReadAllText(newAuthenticationNuspec).Replace("VERSIO N", newVersion); 566 allLines = File.ReadAllText(newAuthenticationNuspec).Replace("VERSIO N", newVersion);
496 File.WriteAllText(newAuthenticationNuspec, allLines); 567 File.WriteAllText(newAuthenticationNuspec, allLines);
497 568
498 NuGetUtils.CreateLocalNupkgFile(newApiNuspec, Environment.CurrentDir ectory); 569 NuGetUtilities.CreateLocalNupkgFile(newApiNuspec, Environment.Curren tDirectory);
499 NuGetUtils.CreateLocalNupkgFile(newAuthenticationNuspec, Environment .CurrentDirectory); 570 NuGetUtilities.CreateLocalNupkgFile(newAuthenticationNuspec, Environ ment.CurrentDirectory);
500 } 571 }
501 572
502 private IEnumerable<Project> releaseProjects; 573 private IEnumerable<Project> releaseProjects;
574 /// <summary>Gets the release projects of from the "default" repository. </summary>
503 private IEnumerable<Project> ReleaseProjects 575 private IEnumerable<Project> ReleaseProjects
504 { 576 {
505 get 577 get
506 { 578 {
507 if (releaseProjects != null) 579 if (releaseProjects != null)
508 { 580 {
509 return releaseProjects; 581 return releaseProjects;
510 } 582 }
511 583
512 var releasePaths = new[]· 584 var releasePaths = new[]·
513 { 585 {
514 DefaultRepository.Combine("Src", "GoogleApis", "GoogleApis.c sproj"), 586 DefaultRepository.Combine("Src", "GoogleApis", "GoogleApis.c sproj"),
515 DefaultRepository.Combine("Src", "GoogleApis.DotNet4", "Goog leApis.DotNet4.csproj"), 587 DefaultRepository.Combine("Src", "GoogleApis.DotNet4", "Goog leApis.DotNet4.csproj"),
516 DefaultRepository.Combine("Src", "GoogleApis.Authentication. OAuth2",· 588 DefaultRepository.Combine("Src", "GoogleApis.Authentication. OAuth2",·
517 "GoogleApis.Authentication.OAuth2.csproj") 589 "GoogleApis.Authentication.OAuth2.csproj")
518 }; 590 };
519 releaseProjects = (from path in releasePaths 591 return releaseProjects = (from path in releasePaths
520 select new Project(path)).ToList(); 592 select new Project(path)).ToList();
521 return releaseProjects; 593 }
522 } 594 }
523 } 595
524 596 /// <summary>Builds the "default" repository projects.</summary>
597 /// <returns><c>true</c> if the default repository was build successfull y</returns>
525 private bool BuildDefaultRepository() 598 private bool BuildDefaultRepository()
526 { 599 {
527 TraceSource.TraceEvent(TraceEventType.Information, "Building project s...."); 600 TraceSource.TraceEvent(TraceEventType.Information, "Building project s....");
528 601
529 var allProjects = new List<Project>(); 602 var allProjects = new List<Project>();
530 allProjects.AddRange(ReleaseProjects); 603 allProjects.AddRange(ReleaseProjects);
531 allProjects.Add(new Project(DefaultRepository.Combine("Src", "Google Apis.Tests", 604 allProjects.Add(new Project(DefaultRepository.Combine("Src", "Google Apis.Tests",
532 "GoogleApis.Tests.csproj"))); 605 "GoogleApis.Tests.csproj")));
533 allProjects.Add(new Project(DefaultRepository.Combine("Src", "Google Apis.Authentication.OAuth2.Tests", 606 allProjects.Add(new Project(DefaultRepository.Combine("Src", "Google Apis.Authentication.OAuth2.Tests",
534 "GoogleApis.Authentication.OAuth2.Tests.csproj"))); 607 "GoogleApis.Authentication.OAuth2.Tests.csproj")));
(...skipping 19 matching lines...) Expand all
554 627
555 if (!ReleaseProjects.Contains(project)) 628 if (!ReleaseProjects.Contains(project))
556 { 629 {
557 // TODO(peleyal): run unit tests for all test projects 630 // TODO(peleyal): run unit tests for all test projects
558 } 631 }
559 } 632 }
560 633
561 return true; 634 return true;
562 } 635 }
563 636
637 /// <summary>Constructs a new program with the given options.</summary>
564 public Program(Options options) 638 public Program(Options options)
565 { 639 {
566 this.options = options; 640 this.options = options;
567 641
568 string path = Path.GetFullPath(options.OutputDirectory); 642 string path = Path.GetFullPath(options.OutputDirectory);
569 if (!Directory.Exists(path)) 643 if (!Directory.Exists(path))
570 { 644 {
571 Directory.CreateDirectory(path); 645 Directory.CreateDirectory(path);
572 } 646 }
573 647
574 Environment.CurrentDirectory = path; 648 Environment.CurrentDirectory = path;
575 } 649 }
576 } 650 }
577 } 651 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b