Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(306)

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: self review II Created 10 years, 6 months ago
Right Patch Set: david comments Created 10 years, 6 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 /* 1 /*
2 Copyright 2013 Google Inc 2 Copyright 2013 Google Inc
3 3
4 Licensed under the Apache License, Version 2.0 (the "License"); 4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with 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 6 You may obtain a copy of the License at
7 7
8 http://www.apache.org/licenses/LICENSE-2.0 8 http://www.apache.org/licenses/LICENSE-2.0
9 9
10 Unless required by applicable law or agreed to in writing, software 10 Unless required by applicable law or agreed to in writing, software
(...skipping 13 matching lines...) Expand all
24 using System.Text.RegularExpressions; 24 using System.Text.RegularExpressions;
25 using Microsoft.Build.Evaluation; 25 using Microsoft.Build.Evaluation;
26 using Microsoft.Build.Framework; 26 using Microsoft.Build.Framework;
27 using Microsoft.Build.Logging; 27 using Microsoft.Build.Logging;
28 28
29 using CommandLine; 29 using CommandLine;
30 using CommandLine.Text; 30 using CommandLine.Text;
31 using Ionic.Zip; 31 using Ionic.Zip;
32 32
33 using Google.Apis.Release.Repositories; 33 using Google.Apis.Release.Repositories;
34 using Google.Apis.Release.Wiki;
34 using Google.Apis.Utils; 35 using Google.Apis.Utils;
35 using Google.Apis.Release.Wiki; 36 using Google.Apis.Utils.Trace;
36 37
37 namespace Google.Apis.Release 38 namespace Google.Apis.Release
38 { 39 {
39 /// <summary>The main program for creating a new Google.Apis release.</summa ry> 40 /// <summary>The main program for creating a new Google.Apis release.</summa ry>
40 class Program 41 class Program
41 { 42 {
42 /// <summary>The options class which contains the different options to t his publish release utility.</summary> 43 /// <summary>The options class which contains the different options to t his publish release utility.</summary>
43 public class Options 44 public class Options
44 { 45 {
45 #region HelpText 46 #region HelpText
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 103
103 /// <summary>Gets or sets the "contrib" repository.</summary> 104 /// <summary>Gets or sets the "contrib" repository.</summary>
104 private Hg ContribRepository { get; set; } 105 private Hg ContribRepository { get; set; }
105 106
106 /// <summary>Gets all four repositories.</summary> 107 /// <summary>Gets all four repositories.</summary>
107 private IEnumerable<Hg> AllRepositories 108 private IEnumerable<Hg> AllRepositories
108 { 109 {
109 get { return new List<Hg> { DefaultRepository, SamplesRepository, Wi kiRepository, ContribRepository }; } 110 get { return new List<Hg> { DefaultRepository, SamplesRepository, Wi kiRepository, ContribRepository }; }
110 } 111 }
111 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
112 static void Main(string[] args) 119 static void Main(string[] args)
113 { 120 {
121 bool valid = true;
122
114 var options = new Options(); 123 var options = new Options();
115 if (!CommandLine.Parser.Default.ParseArguments(args, options)) 124 if (!CommandLine.Parser.Default.ParseArguments(args, options))
116 { 125 {
117 Console.ReadKey(); 126 Console.ReadKey();
118 return; 127 return;
119 } 128 }
120 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
121 var match = Regex.Match(options.Version, @"^(\d+)\.(\d+)\.(\d)+$"); 136 var match = Regex.Match(options.Version, @"^(\d+)\.(\d+)\.(\d)+$");
122 if (!match.Success) 137 if (!match.Success)
123 { 138 {
124 TraceSource.TraceEvent(TraceEventType.Error, 139 TraceSource.TraceEvent(TraceEventType.Error,
125 "Invalid version Number. Version should be in <Major>.<Minor >.<Build> form."); 140 "Invalid version Number. Version should be in <Major>.<Minor >.<Build> form.");
141 valid = false;
126 } 142 }
127 143
128 var program = new Program(options) 144 var program = new Program(options)
129 { 145 {
130 MajorVersion = int.Parse(match.Groups[1].Value), 146 MajorVersion = int.Parse(match.Groups[1].Value),
131 MinorVersion = int.Parse(match.Groups[2].Value), 147 MinorVersion = int.Parse(match.Groups[2].Value),
132 BuildVersion = int.Parse(match.Groups[3].Value), 148 BuildVersion = int.Parse(match.Groups[3].Value),
133 }; 149 };
134 150
135 try 151 if (valid)
136 { 152 {
137 program.Run(); 153 try
138 } 154 {
139 catch (Exception ex) 155 program.Run();
140 { 156 }
141 TraceSource.TraceEvent(TraceEventType.Error, "Exception occurred while running. Exception is: {0}", 157 catch (Exception ex)
142 ex.Message); 158 {
159 TraceSource.TraceEvent(TraceEventType.Error, "Exception occu rred while running. Exception is: {0}",
160 ex.Message);
161 }
143 } 162 }
144 163
145 Console.WriteLine("Press any key to continue..."); 164 Console.WriteLine("Press any key to continue...");
146 Console.ReadKey(); 165 Console.ReadKey();
147 } 166 }
148 167
149 /// <summary>The main release logic for creating a new release of Google .Apis.</summary> 168 /// <summary>The main release logic for creating a new release of Google .Apis.</summary>
150 private void Run() 169 private void Run()
151 { 170 {
152 const string CloneUrl = "https://code.google.com/p/google-api-dotnet -client{0}/"; 171 DefaultRepository = new Hg(new Uri(string.Format(CloneUrlFormat, "") ), "default");
153
154 DefaultRepository = new Hg(new Uri(string.Format(CloneUrl, "")), "de fault");
155 172
156 // Step 1 is only for creating Google.Apis and Google.Apis.Authentic ation packages 173 // Step 1 is only for creating Google.Apis and Google.Apis.Authentic ation packages
157 if (options.Step == 1) 174 if (options.Step == 1)
158 { 175 {
159 if (BuildVersion != 0) 176 DoStep1();
160 { 177 }
161 DefaultRepository.Update(string.Format("{0}.{1}", MajorVersi on, MinorVersion));
162 }
163
164 if (!HasIncomingChanges(new List<Hg> { DefaultRepository }))
165 {
166 if (BuildDefaultRepository())
167 {
168 CreateNuGetPackages();
169 // TODO(peleyal): release notes should be part of the pa ckage
170 }
171 }
172 }
173
174 // Step 2 should be done after the NuGet publisher generated all the APIs and the samples repository was· 178 // Step 2 should be done after the NuGet publisher generated all the APIs and the samples repository was·
175 // updated with the new packages 179 // updated with the new packages
176 else if (options.Step == 2) 180 else if (options.Step == 2)
177 { 181 {
178 Console.WriteLine(); 182 DoStep2();
179 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
180 Console.WriteLine("========================="); 248 Console.WriteLine("=========================");
181 Console.WriteLine("Prerequisites for Step 2:"); 249 Console.WriteLine("Commit, Tag and Push");
182 Console.WriteLine("You ran Step 1.");
183 Console.WriteLine("You upgraded the Google.Apis NuGet packages f or each sample in the samples " +
184 "repository and pushed that change.");
185 Console.WriteLine("========================="); 250 Console.WriteLine("=========================");
186 if (CanContinue()) 251 if (!CanContinue())
187 { 252 {
188 SamplesRepository = new Hg(new Uri(string.Format(CloneUrl, " .samples")), "samples"); 253 return;
189 WikiRepository = new Hg(new Uri(string.Format(CloneUrl, ".wi ki")), "wiki"); 254 }
190 ContribRepository = new Hg(new Uri(string.Format(CloneUrl, " .contrib")), "contrib"); 255
191 256 // commit
192 // if there are incoming changes those changes will be print ed, otherwise we can continue in the· 257 CommitAndTag();
193 // process 258
194 if (!HasIncomingChanges(AllRepositories)) 259 // push
195 { 260 foreach (Hg repository in AllRepositories)
196 BuildSamples(); 261 {
197 var notes = CreateContribNewRelease(); 262 repository.Push();
198 UpdateWiki(notes); 263 }
199 264
200 foreach (var repository in AllRepositories) 265 // create branch
201 { 266 PrintCreateBranch();
202 repository.AddRemoveFiles(); 267
203 } 268 // publish core components to NuGet
204 269 if (!string.IsNullOrEmpty(options.NuGetApiKey))
205 Console.WriteLine("========================="); 270 {
206 Console.WriteLine("Commit, Tag and Push"); 271 PublishPackagesToNuGet();
207 Console.WriteLine("========================="); 272 Console.WriteLine("Now... you should run the NuGet publisher to publish a new PCL "
208 if (CanContinue()) 273 + "for each generated Google API. Run: " +
209 { 274 "Google.Apis.NuGet.Publisher --all_apis true -m publishe r -k [NUGET_KEY]");
210 // commit 275 }
211 CommitAndTag(); 276 else
212 277 {
213 // push 278 TraceSource.TraceEvent(TraceEventType.Error, "NuGet API key is empty!");
214 foreach (Hg repository in AllRepositories) 279 }
215 {
216 repository.Push();
217 }
218
219 // create branch
220 PrintCreateBranch();
221
222 // publish core components to NuGet
223 if (!string.IsNullOrEmpty(options.NuGetApiKey))
224 {
225 PublishPackagesToNuGet();
226 Console.WriteLine("Now... you should run the NuG et publisher to publish a new PCL "
227 + "for each generated Google API. Run: " +
228 "Google.Apis.NuGet.Publisher --all_apis true -m publisher -k [NUGET_KEY]");
229 }
230 else
231 {
232 TraceSource.TraceEvent(TraceEventType.Error, "Nu Get API key is empty!");
233 }
234 }
235 }
236 }
237 }
238 else
239 {
240 TraceSource.TraceEvent(TraceEventType.Error, "Invalid step optio n!");
241 } 280 }
242 } 281 }
243 282
244 /// <summary>Asks the user if he wants to continue in the process.</summ ary> 283 /// <summary>Asks the user if he wants to continue in the process.</summ ary>
245 /// <returns><c>true</c> if the user to press 'y' or 'yes' to continue</ returns> 284 /// <returns><c>true</c> if the user to press 'y' or 'yes' to continue</ returns>
246 private bool CanContinue() 285 private bool CanContinue()
247 { 286 {
248 var yesOptions = new[] { "y", "yes" }; 287 var yesOptions = new[] { "y", "yes" };
249 var noOptions = new[] { "n", "no" }; 288 var noOptions = new[] { "n", "no" };
250 289
251 string input; 290 string input;
252 do 291 do
253 { 292 {
254 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");
255 input = Console.ReadLine(); 294 input = Console.ReadLine().ToLower();
256 } while (!yesOptions.Contains(input) && !noOptions.Contains(input)); 295 } while (!yesOptions.Contains(input) && !noOptions.Contains(input));
257 296
258 return yesOptions.Contains(input); 297 return yesOptions.Contains(input);
259 } 298 }
260 299
261 /// <summary>Publishes the core packages to NuGet main repository.</summ ary> 300 /// <summary>Publishes the core packages to NuGet main repository.</summ ary>
262 private void PublishPackagesToNuGet() 301 private void PublishPackagesToNuGet()
263 { 302 {
264 var apiNupkgPath = Path.Combine(NuGetUtilities.LocalNuGetPackageFold er, 303 var apiNupkgPath = Path.Combine(NuGetUtilities.LocalNuGetPackageFold er,
265 string.Format("Google.Apis.{0}.nupkg", Tag)); 304 string.Format("Google.Apis.{0}.nupkg", Tag));
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 { 530 {
492 TraceSource.TraceEvent(TraceEventType.Error, 531 TraceSource.TraceEvent(TraceEventType.Error,
493 "[{0}] has incoming changes. Run hg pull & update first! ", repository.Name); 532 "[{0}] has incoming changes. Run hg pull & update first! ", repository.Name);
494 return true; 533 return true;
495 } 534 }
496 } 535 }
497 return false; 536 return false;
498 } 537 }
499 538
500 /// <summary>Creates the Google.Apis and Google.Apis.Authentication NuGe t packages.</summary> 539 /// <summary>Creates the Google.Apis and Google.Apis.Authentication NuGe t packages.</summary>
501 private void CreateNuGetPackages() 540 private void CreateCoreNuGetPackages()
502 { 541 {
503 // create a resource dir in the working folder 542 // create a resource dir in the working folder
504 var destDirectory = Path.Combine(Environment.CurrentDirectory, "Reso urces"); 543 var destDirectory = Path.Combine(Environment.CurrentDirectory, "Reso urces");
505 if (Directory.Exists(destDirectory)) 544 if (Directory.Exists(destDirectory))
506 { 545 {
507 Directory.Delete(destDirectory, true); 546 Directory.Delete(destDirectory, true);
508 } 547 }
509 548
510 FileInfo info = new FileInfo(Assembly.GetEntryAssembly().Location); 549 FileInfo info = new FileInfo(Assembly.GetEntryAssembly().Location);
511 DirectoryUtilities.CopyDirectory(Path.Combine(info.Directory.FullNam e, "Resources"), destDirectory); 550 DirectoryUtilities.CopyDirectory(Path.Combine(info.Directory.FullNam e, "Resources"), destDirectory);
512 551
513 var newVersion = options.Version + "-beta"; 552 var newVersion = options.Version + "-beta";
514 553
554 // get the Google.Apis and Google.Apis.Authentication nuspec files a nd replace the version in it
515 var apiNuspec = Path.Combine(destDirectory, "Google.Apis.VERSION.nus pec"); 555 var apiNuspec = Path.Combine(destDirectory, "Google.Apis.VERSION.nus pec");
516 var newApiNuspec = apiNuspec.Replace("VERSION", newVersion); 556 var newApiNuspec = apiNuspec.Replace("VERSION", newVersion);
517 var authenticationNuspec = Path.Combine(destDirectory, "Google.Apis. Authentication.VERSION.nuspec"); 557 var authenticationNuspec = Path.Combine(destDirectory, "Google.Apis. Authentication.VERSION.nuspec");
518 var newAuthenticationNuspec = authenticationNuspec.Replace("VERSION" , newVersion); 558 var newAuthenticationNuspec = authenticationNuspec.Replace("VERSION" , newVersion);
519 559
520 File.Move(apiNuspec, newApiNuspec); 560 File.Move(apiNuspec, newApiNuspec);
521 File.Move(authenticationNuspec, newAuthenticationNuspec); 561 File.Move(authenticationNuspec, newAuthenticationNuspec);
522 562
523 var allLines = File.ReadAllText(newApiNuspec).Replace("VERSION", new Version); 563 var allLines = File.ReadAllText(newApiNuspec).Replace("VERSION", new Version);
524 File.WriteAllText(newApiNuspec, allLines); 564 File.WriteAllText(newApiNuspec, allLines);
(...skipping 16 matching lines...) Expand all
541 return releaseProjects; 581 return releaseProjects;
542 } 582 }
543 583
544 var releasePaths = new[]· 584 var releasePaths = new[]·
545 { 585 {
546 DefaultRepository.Combine("Src", "GoogleApis", "GoogleApis.c sproj"), 586 DefaultRepository.Combine("Src", "GoogleApis", "GoogleApis.c sproj"),
547 DefaultRepository.Combine("Src", "GoogleApis.DotNet4", "Goog leApis.DotNet4.csproj"), 587 DefaultRepository.Combine("Src", "GoogleApis.DotNet4", "Goog leApis.DotNet4.csproj"),
548 DefaultRepository.Combine("Src", "GoogleApis.Authentication. OAuth2",· 588 DefaultRepository.Combine("Src", "GoogleApis.Authentication. OAuth2",·
549 "GoogleApis.Authentication.OAuth2.csproj") 589 "GoogleApis.Authentication.OAuth2.csproj")
550 }; 590 };
551 releaseProjects = (from path in releasePaths 591 return releaseProjects = (from path in releasePaths
552 select new Project(path)).ToList(); 592 select new Project(path)).ToList();
553 return releaseProjects;
554 } 593 }
555 } 594 }
556 595
557 /// <summary>Builds the "default" repository projects.</summary> 596 /// <summary>Builds the "default" repository projects.</summary>
558 /// <returns><c>true</c> if the default repository was build successfull y</returns> 597 /// <returns><c>true</c> if the default repository was build successfull y</returns>
559 private bool BuildDefaultRepository() 598 private bool BuildDefaultRepository()
560 { 599 {
561 TraceSource.TraceEvent(TraceEventType.Information, "Building project s...."); 600 TraceSource.TraceEvent(TraceEventType.Information, "Building project s....");
562 601
563 var allProjects = new List<Project>(); 602 var allProjects = new List<Project>();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 string path = Path.GetFullPath(options.OutputDirectory); 642 string path = Path.GetFullPath(options.OutputDirectory);
604 if (!Directory.Exists(path)) 643 if (!Directory.Exists(path))
605 { 644 {
606 Directory.CreateDirectory(path); 645 Directory.CreateDirectory(path);
607 } 646 }
608 647
609 Environment.CurrentDirectory = path; 648 Environment.CurrentDirectory = path;
610 } 649 }
611 } 650 }
612 } 651 }
LEFTRIGHT

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