LEFT | RIGHT |
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 { |
23 /// <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> |
24 class Program | 41 class Program |
25 { | 42 { |
26 /// <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> |
27 public class Options | 44 public class Options |
28 { | 45 { |
29 #region HelpText | 46 #region HelpText |
30 | 47 |
31 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."; |
32 const string OutputHelpText = "Define the output directory for this
build. " + | 49 const string OutputHelpText = "Define the output directory for this
build. " + |
33 "Notice that it's relative to current directory."; | 50 "Notice that it's relative to current directory."; |
34 const string StepHelpText = "Two options: '1' for building the core
library \n" + | 51 const string StepHelpText = "Two options: " + |
35 "'2' for compiling samples, updating wiki and push to contrib th
e new version \n" + | 52 "'1' for building the core library. \n" + |
36 "'3' for publishing on the local packages to NuGet"; | 53 "'2' for compiling samples, updating wiki and push to contrib th
e new version."; |
37 const string IsBetaHelpText = "Is this release is beta?"; | 54 const string IsBetaHelpText = "Is this release beta?"; |
38 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."; |
39 | 56 |
40 [HelpOption] | 57 [HelpOption] |
41 public string GetHelp() | 58 public string GetHelp() |
42 { | 59 { |
43 return HelpText.AutoBuild(this, c => HelpText.DefaultParsingErro
rsHandler(this, c)); | 60 return HelpText.AutoBuild(this, c => HelpText.DefaultParsingErro
rsHandler(this, c)); |
44 } | 61 } |
45 | 62 |
46 #endregion | 63 #endregion |
47 | 64 |
48 [Option('v', "version", Required = true, | 65 [Option('v', "version", Required = true, HelpText = VersionHelpText)
] |
49 HelpText = VersionHelpText)] | |
50 public string Version { get; set; } | 66 public string Version { get; set; } |
51 | 67 |
52 [Option('d', "dir", Required = true, HelpText = OutputHelpText)] | 68 [Option('d', "dir", Required = true, HelpText = OutputHelpText)] |
53 public string OutputDirectory { get; set; } | 69 public string OutputDirectory { get; set; } |
54 | 70 |
55 [Option('s', "step", Required = true, HelpText = StepHelpText)] | 71 [Option('s', "step", Required = true, HelpText = StepHelpText)] |
56 public int Step { get; set; } | 72 public int Step { get; set; } |
57 | 73 |
58 [Option('b', "beta", DefaultValue = true, HelpText = IsBetaHelpText)
] | 74 [Option('b', "beta", DefaultValue = true, HelpText = IsBetaHelpText)
] |
59 public bool IsBeta { get; set; } | 75 public bool IsBeta { get; set; } |
60 | 76 |
61 [Option('k', "nuget_key", HelpText = NuGetApiKeyHelpText)] | 77 [Option('k', "nuget_key", HelpText = NuGetApiKeyHelpText)] |
62 public string NuGetApiKey { get; set; } | 78 public string NuGetApiKey { get; set; } |
63 } | 79 } |
64 | 80 |
65 private static readonly TraceSource TraceSource = new TraceSource("Googl
e.Apis"); | 81 private static readonly TraceSource TraceSource = new TraceSource("Googl
e.Apis"); |
66 | 82 |
67 /// <summary> Command line arguments. </summary> | 83 /// <summary>Command line arguments.</summary> |
68 private readonly Options options; | 84 private readonly Options options; |
69 | 85 |
70 private int MajorVersion { get; set; } | 86 private int MajorVersion { get; set; } |
71 private int MinorVersion { get; set; } | 87 private int MinorVersion { get; set; } |
72 private int BuildVersion { get; set; } | 88 private int BuildVersion { get; set; } |
73 | 89 |
74 private string Tag | 90 private string Tag |
75 { | 91 { |
76 get { return options.Version + (options.IsBeta ? "-beta" : ""); } | 92 get { return options.Version + (options.IsBeta ? "-beta" : ""); } |
77 } | 93 } |
78 | 94 |
79 /// <summary>Gets or sets the "default" repository.</summary> | 95 /// <summary>Gets or sets the "default" repository.</summary> |
80 private Hg DefaultRepository { get; set; } | 96 private Hg DefaultRepository { get; set; } |
81 | 97 |
82 /// <summary>Gets or sets the "samples" repository.</summary> | 98 /// <summary>Gets or sets the "samples" repository.</summary> |
83 private Hg SamplesRepository { get; set; } | 99 private Hg SamplesRepository { get; set; } |
84 | 100 |
85 /// <summary>Gets or sets the "wiki" repository.</summary> | 101 /// <summary>Gets or sets the "wiki" repository.</summary> |
86 private Hg WikiRepository { get; set; } | 102 private Hg WikiRepository { get; set; } |
87 | 103 |
88 /// <summary>Gets or sets the "contrib" repository.</summary> | 104 /// <summary>Gets or sets the "contrib" repository.</summary> |
89 private Hg ContribRepository { get; set; } | 105 private Hg ContribRepository { get; set; } |
90 | 106 |
91 /// <summary>Gets all four repositories.</summary> | 107 /// <summary>Gets all four repositories.</summary> |
92 private IEnumerable<Hg> AllRepositories | 108 private IEnumerable<Hg> AllRepositories |
93 { | 109 { |
94 get { return new List<Hg> { DefaultRepository, SamplesRepository, Wi
kiRepository, ContribRepository }; } | 110 get { return new List<Hg> { DefaultRepository, SamplesRepository, Wi
kiRepository, ContribRepository }; } |
95 } | 111 } |
96 | 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 |
97 static void Main(string[] args) | 119 static void Main(string[] args) |
98 { | 120 { |
| 121 bool valid = true; |
| 122 |
99 var options = new Options(); | 123 var options = new Options(); |
100 if (!CommandLine.Parser.Default.ParseArguments(args, options)) | 124 if (!CommandLine.Parser.Default.ParseArguments(args, options)) |
101 { | 125 { |
102 Console.ReadKey(); | 126 Console.ReadKey(); |
103 return; | 127 return; |
104 } | 128 } |
105 | 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 |
106 var match = Regex.Match(options.Version, @"^(\d+)\.(\d+)\.(\d)+$"); | 136 var match = Regex.Match(options.Version, @"^(\d+)\.(\d+)\.(\d)+$"); |
107 if (!match.Success) | 137 if (!match.Success) |
108 { | 138 { |
109 TraceSource.TraceEvent(TraceEventType.Error, | 139 TraceSource.TraceEvent(TraceEventType.Error, |
110 "Invalid version Number. Version should be in <Major>.<Minor
>.<Build> form."); | 140 "Invalid version Number. Version should be in <Major>.<Minor
>.<Build> form."); |
111 } | 141 valid = false; |
112 | 142 } |
113 var p = new Program(options) | 143 |
| 144 var program = new Program(options) |
114 { | 145 { |
115 MajorVersion = int.Parse(match.Groups[1].Value), | 146 MajorVersion = int.Parse(match.Groups[1].Value), |
116 MinorVersion = int.Parse(match.Groups[2].Value), | 147 MinorVersion = int.Parse(match.Groups[2].Value), |
117 BuildVersion = int.Parse(match.Groups[3].Value), | 148 BuildVersion = int.Parse(match.Groups[3].Value), |
118 }; | 149 }; |
119 | 150 |
120 try | 151 if (valid) |
121 { | 152 { |
122 p.Run(); | 153 try |
123 } | 154 { |
124 catch (Exception ex) | 155 program.Run(); |
125 { | 156 } |
126 TraceSource.TraceEvent(TraceEventType.Error, "Exception occurred
while running. Exception is: {0}", | 157 catch (Exception ex) |
127 ex.Message); | 158 { |
| 159 TraceSource.TraceEvent(TraceEventType.Error, "Exception occu
rred while running. Exception is: {0}", |
| 160 ex.Message); |
| 161 } |
128 } | 162 } |
129 | 163 |
130 Console.WriteLine("Press any key to continue..."); | 164 Console.WriteLine("Press any key to continue..."); |
131 Console.ReadKey(); | 165 Console.ReadKey(); |
132 } | 166 } |
133 | 167 |
134 /// <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> |
135 private void Run() | 169 private void Run() |
136 { | 170 { |
137 const string CloneUrl = "https://code.google.com/p/google-api-dotnet
-client{0}/"; | 171 DefaultRepository = new Hg(new Uri(string.Format(CloneUrlFormat, "")
), "default"); |
138 | |
139 DefaultRepository = new Hg(new Uri(string.Format(CloneUrl, "")), "de
fault"); | |
140 | 172 |
141 // 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 |
142 if (options.Step == 1) | 174 if (options.Step == 1) |
143 { | 175 { |
144 if (BuildVersion != 0) | 176 DoStep1(); |
145 { | 177 } |
146 DefaultRepository.Update(string.Format("{0}.{1}", MajorVersi
on, MinorVersion)); | |
147 } | |
148 | |
149 if (!HasIncomingChanges(new List<Hg> { DefaultRepository })) | |
150 { | |
151 if (BuildDefaultRepository()) | |
152 { | |
153 CreateNuGetPackages(); | |
154 // TODO(peleyal): release notes should be part of the pa
ckage | |
155 } | |
156 } | |
157 } | |
158 | |
159 // 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· |
160 // updated with the new packages | 179 // updated with the new packages |
161 else if (options.Step == 2) | 180 else if (options.Step == 2) |
162 { | 181 { |
163 Console.WriteLine(); | 182 DoStep2(); |
164 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 |
165 Console.WriteLine("========================="); | 248 Console.WriteLine("========================="); |
166 Console.WriteLine("Prerequisites for Step 2:"); | 249 Console.WriteLine("Commit, Tag and Push"); |
167 Console.WriteLine("You ran Step 1."); | |
168 Console.WriteLine("You upgraded the Google.Apis NuGet packages f
or each sample in the samples " + | |
169 "repository and pushed that change."); | |
170 Console.WriteLine("========================="); | 250 Console.WriteLine("========================="); |
171 if (CanContinue()) | 251 if (!CanContinue()) |
172 { | 252 { |
173 SamplesRepository = new Hg(new Uri(string.Format(CloneUrl, "
.samples")), "samples"); | 253 return; |
174 WikiRepository = new Hg(new Uri(string.Format(CloneUrl, ".wi
ki")), "wiki"); | 254 } |
175 ContribRepository = new Hg(new Uri(string.Format(CloneUrl, "
.contrib")), "contrib"); | 255 |
176 | 256 // commit |
177 // if there incoming changes those changes will be printed,
otherwsie we can continue in the· | 257 CommitAndTag(); |
178 // process | 258 |
179 if (!HasIncomingChanges(AllRepositories)) | 259 // push |
180 { | 260 foreach (Hg repository in AllRepositories) |
181 BuildSamples(); | 261 { |
182 var notes = CreateContribNewRelease(); | 262 repository.Push(); |
183 UpdateWiki(notes); | 263 } |
184 | 264 |
185 foreach (var repository in AllRepositories) | 265 // create branch |
186 { | 266 PrintCreateBranch(); |
187 repository.AddRemoveFiles(); | 267 |
188 } | 268 // publish core components to NuGet |
189 | 269 if (!string.IsNullOrEmpty(options.NuGetApiKey)) |
190 Console.WriteLine("========================="); | 270 { |
191 Console.WriteLine("Commit, Tag and Push"); | 271 PublishPackagesToNuGet(); |
192 Console.WriteLine("========================="); | 272 Console.WriteLine("Now... you should run the NuGet publisher
to publish a new PCL " |
193 if (CanContinue()) | 273 + "for each generated Google API. Run: " + |
194 { | 274 "Google.Apis.NuGet.Publisher --all_apis true -m publishe
r -k [NUGET_KEY]"); |
195 // commit | 275 } |
196 CommitAndTag(); | 276 else |
197 | 277 { |
198 // push | 278 TraceSource.TraceEvent(TraceEventType.Error, "NuGet API key
is empty!"); |
199 foreach (Hg repository in AllRepositories) | 279 } |
200 { | |
201 repository.Push(); | |
202 } | |
203 | |
204 // create branch | |
205 PrintCreateBranch(); | |
206 | |
207 // publish core components to NuGet | |
208 if (!string.IsNullOrEmpty(options.NuGetApiKey)) | |
209 { | |
210 PublishPackagesToNuGet(); | |
211 Console.WriteLine("Now... you should run the NuG
et publisher to publish a new PCL " | |
212 + "for each generated Google API"); | |
213 } | |
214 else | |
215 { | |
216 TraceSource.TraceEvent(TraceEventType.Error, "Nu
Get API key is empty!"); | |
217 } | |
218 } | |
219 } | |
220 } | |
221 } | |
222 else | |
223 { | |
224 TraceSource.TraceEvent(TraceEventType.Error, "Invalid step optio
n!"); | |
225 } | 280 } |
226 } | 281 } |
227 | 282 |
228 /// <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> |
229 /// <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> |
230 private bool CanContinue() | 285 private bool CanContinue() |
231 { | 286 { |
232 var yesOptions = new[] { "y", "yes" }; | 287 var yesOptions = new[] { "y", "yes" }; |
233 var noOptions = new[] { "n", "no" }; | 288 var noOptions = new[] { "n", "no" }; |
234 | 289 |
235 string input; | 290 string input; |
236 do | 291 do |
237 { | 292 { |
238 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"); |
239 input = Console.ReadLine(); | 294 input = Console.ReadLine().ToLower(); |
240 } while (!yesOptions.Contains(input) && !noOptions.Contains(input)); | 295 } while (!yesOptions.Contains(input) && !noOptions.Contains(input)); |
241 | 296 |
242 return yesOptions.Contains(input); | 297 return yesOptions.Contains(input); |
243 } | 298 } |
244 | 299 |
245 /// <summary>Publishes the core packages to NuGet main repository.</summ
ary> | 300 /// <summary>Publishes the core packages to NuGet main repository.</summ
ary> |
246 private void PublishPackagesToNuGet() | 301 private void PublishPackagesToNuGet() |
247 { | 302 { |
248 var apiNupkgPath = Path.Combine(NuGetUtilities.LocalNuGetPackageFold
er, | 303 var apiNupkgPath = Path.Combine(NuGetUtilities.LocalNuGetPackageFold
er, |
249 string.Format("Google.Apis.{0}.nupkg", Tag)); | 304 string.Format("Google.Apis.{0}.nupkg", Tag)); |
250 NuGetUtilities.PublishToNuget(apiNupkgPath, options.NuGetApiKey); | 305 NuGetUtilities.PublishToNuget(apiNupkgPath, options.NuGetApiKey); |
251 | 306 |
252 var authenticationNupkgPath = Path.Combine(NuGetUtilities.LocalNuGet
PackageFolder, | 307 var authenticationNupkgPath = Path.Combine(NuGetUtilities.LocalNuGet
PackageFolder, |
253 string.Format("Google.Apis.Authentication.{0}.nupkg", Tag)); | 308 string.Format("Google.Apis.Authentication.{0}.nupkg", Tag)); |
254 NuGetUtilities.PublishToNuget(authenticationNupkgPath, options.NuGet
ApiKey); | 309 NuGetUtilities.PublishToNuget(authenticationNupkgPath, options.NuGet
ApiKey); |
255 } | 310 } |
256 | 311 |
257 /// <summary> | 312 /// <summary> |
258 /// Displays the user orders how to create a branch (only in case it's a
new major or minor release. | 313 /// Displays the user orders how to create a branch (only in case it's a
new major or minor release. |
259 /// </summary> | 314 /// </summary> |
260 private void PrintCreateBranch() | 315 private void PrintCreateBranch() |
261 { | 316 { |
262 if (BuildVersion != 0) | 317 if (BuildVersion != 0) |
263 { | 318 { |
264 // No need to branch in that case | 319 // No need to branch in that case |
265 return; | 320 return; |
266 } | 321 } |
267 | 322 |
268 // TODO(peleyal): automate this as well | 323 // TODO(peleyal): consider automate this as well |
269 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:"); |
270 Console.WriteLine("cd " + DefaultRepository.WorkingDirectory); | 325 Console.WriteLine("cd " + DefaultRepository.WorkingDirectory); |
271 var branchVersion = string.Format("{0}.{1}", MajorVersion, MinorVers
ion); | 326 var branchVersion = string.Format("{0}.{1}", MajorVersion, MinorVers
ion); |
272 Console.WriteLine("hg branch " + branchVersion); | 327 Console.WriteLine("hg branch " + branchVersion); |
273 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)); |
274 Console.WriteLine("hg push --new-branch"); | 329 Console.WriteLine("hg push --new-branch"); |
275 } | 330 } |
276 | 331 |
277 /// <summary>Commits all changes in all repositories and tags the "defau
lt" repository.</summary> | 332 /// <summary>Commits all changes in all repositories and tags the "defau
lt" repository.</summary> |
278 private void CommitAndTag() | 333 private void CommitAndTag() |
(...skipping 30 matching lines...) Expand all Loading... |
309 TraceSource.TraceEvent(TraceEventType.Information, "Updating wiki do
wnloads page"); | 364 TraceSource.TraceEvent(TraceEventType.Information, "Updating wiki do
wnloads page"); |
310 | 365 |
311 // 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 |
312 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); |
313 DownloadsPageUpdater.UpdateWiki(WikiRepository.WorkingDirectory, not
es, oldVersion, options.Version); | 368 DownloadsPageUpdater.UpdateWiki(WikiRepository.WorkingDirectory, not
es, oldVersion, options.Version); |
314 | 369 |
315 TraceSource.TraceEvent(TraceEventType.Information, "wiki downloads p
age was updated"); | 370 TraceSource.TraceEvent(TraceEventType.Information, "wiki downloads p
age was updated"); |
316 } | 371 } |
317 | 372 |
318 /// <summary>Creates a new release in the "contrib" repository.</summary
> | 373 /// <summary>Creates a new release in the "contrib" repository.</summary
> |
319 /// <returns></returns> | 374 /// <returns>The release notes of this version</returns> |
320 private string CreateContribNewRelease() | 375 private string CreateContribNewRelease() |
321 { | 376 { |
322 TraceSource.TraceEvent(TraceEventType.Information, "Building Contrib
release"); | 377 TraceSource.TraceEvent(TraceEventType.Information, "Building Contrib
release"); |
323 | 378 |
324 string releaseDir = ContribRepository.Combine(Tag); | 379 string releaseDir = ContribRepository.Combine(Tag); |
325 | 380 |
326 // Clear existing directories. | 381 // Clear existing directories. |
327 DirectoryUtilities.ClearOrCreateDirectory(releaseDir); | 382 DirectoryUtilities.ClearOrCreateDirectory(releaseDir); |
328 string genDir = Path.Combine(releaseDir, "Generated"); | 383 string genDir = Path.Combine(releaseDir, "Generated"); |
329 Directory.CreateDirectory(genDir); | 384 Directory.CreateDirectory(genDir); |
330 | 385 |
331 #region [RELEASE_VERSION]/Generated/Bin | 386 #region [RELEASE_VERSION]/Generated/Bin |
332 | 387 |
333 string binDir = Path.Combine(genDir, "Bin"); | 388 string binDir = Path.Combine(genDir, "Bin"); |
334 TraceSource.TraceEvent(TraceEventType.Information, "Generating \"{0}
\" directory", | 389 TraceSource.TraceEvent(TraceEventType.Information, "Generating \"{0}
\" directory", |
335 DirectoryUtilities.GetRelativePath(binDir, ContribRepository.Wor
kingDirectory)); | 390 DirectoryUtilities.GetRelativePath(binDir, ContribRepository.Wor
kingDirectory)); |
| 391 |
336 Directory.CreateDirectory(binDir); | 392 Directory.CreateDirectory(binDir); |
337 | 393 foreach (var project in ReleaseProjects) |
338 { | 394 { |
339 foreach (var project in ReleaseProjects) | 395 var releasePath = Path.Combine(project.DirectoryPath, "Bin", "Re
lease"); |
340 { | 396 foreach (var filePath in Directory.GetFiles(releasePath, "Google
.Apis.*")) |
341 var releasePath = Path.Combine(project.DirectoryPath, "Bin",
"Release"); | 397 { |
342 foreach (var filePath in Directory.GetFiles(releasePath, "Go
ogle.Apis.*")) | 398 File.Copy(filePath, |
343 { | 399 Path.Combine(binDir, filePath.Substring(filePath.LastInd
exOf("\\") + 1)), true); |
344 File.Copy(filePath, | 400 } |
345 Path.Combine(binDir, filePath.Substring(filePath.Las
tIndexOf("\\") + 1)), true); | 401 } |
346 } | 402 |
347 } | 403 // TODO(peleyal): Put also the nuspec and nupkg |
348 | |
349 // TODO(peleyal): Put also the nuspec and nupkg | |
350 } | |
351 | 404 |
352 #endregion | 405 #endregion |
353 | 406 |
354 #region [RELEASE_VERSION]/ZipFiles | 407 #region [RELEASE_VERSION]/ZipFiles |
355 | 408 |
356 string zipFilesDir = Path.Combine(genDir, "ZipFiles"); | 409 string zipFilesDir = Path.Combine(genDir, "ZipFiles"); |
357 TraceSource.TraceEvent(TraceEventType.Information, "Generating \"{0}
\" directory", | 410 TraceSource.TraceEvent(TraceEventType.Information, "Generating \"{0}
\" directory", |
358 DirectoryUtilities.GetRelativePath(zipFilesDir, ContribRepositor
y.WorkingDirectory)); | 411 DirectoryUtilities.GetRelativePath(zipFilesDir, ContribRepositor
y.WorkingDirectory)); |
359 | 412 |
360 Directory.CreateDirectory(zipFilesDir); | 413 Directory.CreateDirectory(zipFilesDir); |
361 { | 414 foreach (var project in ReleaseProjects) |
362 foreach (var project in ReleaseProjects) | 415 { |
363 { | 416 project.Build("Clean"); |
364 project.Build("Clean"); | 417 } |
365 } | 418 |
366 | 419 TraceSource.TraceEvent(TraceEventType.Information, "Release projects
were cleaned"); |
367 TraceSource.TraceEvent(TraceEventType.Information, "Release proj
ects were cleaned"); | 420 |
368 | 421 // source.zip |
369 // source.zip | 422 var fileNameFormat = "google-api-dotnet-client-{0}.{1}.zip"; |
370 var fileNameFormat = "google-api-dotnet-client-{0}.{1}.zip"; | 423 var sourceZipName = string.Format(fileNameFormat, Tag, "source"); |
371 var sourceZipName = string.Format(fileNameFormat, Tag, "source")
; | 424 using (var zip = new ZipFile(Path.Combine(zipFilesDir, sourceZipName
))) |
372 using (var zip = new ZipFile(Path.Combine(zipFilesDir, sourceZip
Name))) | 425 { |
373 { | 426 zip.AddDirectory(Path.Combine(DefaultRepository.WorkingDirectory
, "Src"), "Src"); |
374 zip.AddDirectory(Path.Combine(DefaultRepository.WorkingDirec
tory, "Src"), "Src"); | 427 zip.AddFile(Path.Combine(DefaultRepository.WorkingDirectory, "Go
ogleApisClient.sln"), ""); |
375 zip.AddFile(Path.Combine(DefaultRepository.WorkingDirectory,
"GoogleApisClient.sln"), ""); | 428 zip.AddFile(Path.Combine(DefaultRepository.WorkingDirectory, "LI
CENSE"), ""); |
376 zip.AddFile(Path.Combine(DefaultRepository.WorkingDirectory,
"LICENSE"), ""); | 429 zip.Save(); |
377 zip.Save(); | 430 } |
378 } | 431 TraceSource.TraceEvent(TraceEventType.Information, "{0} was created"
, sourceZipName); |
379 TraceSource.TraceEvent(TraceEventType.Information, "{0} was crea
ted", sourceZipName); | 432 |
380 | 433 // binary.zip |
381 // binary.zip | 434 var binaryZipName = string.Format(fileNameFormat, Tag, "binary"); |
382 var binaryZipName = string.Format(fileNameFormat, Tag, "binary")
; | 435 using (var zip = new ZipFile(Path.Combine(zipFilesDir, binaryZipName
))) |
383 using (var zip = new ZipFile(Path.Combine(zipFilesDir, binaryZip
Name))) | 436 { |
384 { | 437 Directory.GetFiles(binDir).ToList().ForEach(f => zip.AddFile(Pat
h.Combine(binDir, f), "")); |
385 Directory.GetFiles(binDir).ToList().ForEach(f => zip.AddFile
(Path.Combine(binDir, f), "")); | 438 zip.Save(); |
386 zip.Save(); | 439 } |
387 } | 440 TraceSource.TraceEvent(TraceEventType.Information, "{0} was created"
, binaryZipName); |
388 TraceSource.TraceEvent(TraceEventType.Information, "{0} was crea
ted", binaryZipName); | 441 |
389 | 442 |
390 | 443 // samples.zip |
391 // samples.zip | 444 var samplesZipName = string.Format(fileNameFormat, Tag, "samples"); |
392 var samplesZipName = string.Format(fileNameFormat, Tag, "samples
"); | 445 using (var zip = new ZipFile(Path.Combine(zipFilesDir, samplesZipNam
e))) |
393 using (var zip = new ZipFile(Path.Combine(zipFilesDir, samplesZi
pName))) | 446 { |
394 { | 447 foreach (var d in Directory.GetDirectories(SamplesRepository.Wor
kingDirectory)) |
395 foreach (var d in Directory.GetDirectories(SamplesRepository
.WorkingDirectory)) | 448 { |
| 449 if (!d.EndsWith(".hg")) |
396 { | 450 { |
397 if (!d.EndsWith(".hg")) | 451 var directoryName = d.Substring(d.LastIndexOf("\\") + 1)
; |
398 { | 452 zip.AddDirectory(Path.Combine(SamplesRepository.WorkingD
irectory, d), directoryName); |
399 var directoryName = d.Substring(d.LastIndexOf("\\")
+ 1); | |
400 zip.AddDirectory(Path.Combine(SamplesRepository.Work
ingDirectory, d), directoryName); | |
401 } | |
402 } | 453 } |
403 foreach (var f in Directory.GetFiles(SamplesRepository.Worki
ngDirectory, "*.sln")) | 454 } |
404 { | 455 foreach (var f in Directory.GetFiles(SamplesRepository.WorkingDi
rectory, "*.sln")) |
405 zip.AddFile(Path.Combine(SamplesRepository.WorkingDirect
ory, f), ""); | 456 { |
406 } | 457 zip.AddFile(Path.Combine(SamplesRepository.WorkingDirectory,
f), ""); |
407 zip.Save(); | 458 } |
408 } | 459 zip.Save(); |
409 | 460 } |
410 TraceSource.TraceEvent(TraceEventType.Information, "{0} was crea
ted", samplesZipName); | 461 |
411 } | 462 TraceSource.TraceEvent(TraceEventType.Information, "{0} was created"
, samplesZipName); |
412 | 463 |
413 #endregion | 464 #endregion |
414 | 465 |
415 #region [RELEASE_VERSION]/ReleaseNotes.txt | 466 #region [RELEASE_VERSION]/ReleaseNotes.txt |
416 | 467 |
417 var notes = GetChangelog(); | 468 var notes = GetChangelog(); |
418 TraceSource.TraceEvent(TraceEventType.Information, "Creating Release
Notes file"); | 469 TraceSource.TraceEvent(TraceEventType.Information, "Creating Release
Notes file"); |
419 var noteFilePath = Path.Combine(genDir, "ReleaseNotes.txt"); | 470 var noteFilePath = Path.Combine(genDir, "ReleaseNotes.txt"); |
420 File.WriteAllText(noteFilePath, notes); | 471 File.WriteAllText(noteFilePath, notes); |
421 | 472 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 { | 530 { |
480 TraceSource.TraceEvent(TraceEventType.Error, | 531 TraceSource.TraceEvent(TraceEventType.Error, |
481 "[{0}] has incoming changes. Run hg pull & update first!
", repository.Name); | 532 "[{0}] has incoming changes. Run hg pull & update first!
", repository.Name); |
482 return true; | 533 return true; |
483 } | 534 } |
484 } | 535 } |
485 return false; | 536 return false; |
486 } | 537 } |
487 | 538 |
488 /// <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> |
489 private void CreateNuGetPackages() | 540 private void CreateCoreNuGetPackages() |
490 { | 541 { |
491 // create a resource dir in the working folder | 542 // create a resource dir in the working folder |
492 var destDirectory = Path.Combine(Environment.CurrentDirectory, "Reso
urces"); | 543 var destDirectory = Path.Combine(Environment.CurrentDirectory, "Reso
urces"); |
493 if (Directory.Exists(destDirectory)) | 544 if (Directory.Exists(destDirectory)) |
494 { | 545 { |
495 Directory.Delete(destDirectory, true); | 546 Directory.Delete(destDirectory, true); |
496 } | 547 } |
497 | 548 |
498 FileInfo info = new FileInfo(Assembly.GetEntryAssembly().Location); | 549 FileInfo info = new FileInfo(Assembly.GetEntryAssembly().Location); |
499 DirectoryUtilities.CopyDirectory(Path.Combine(info.Directory.FullNam
e, "Resources"), destDirectory); | 550 DirectoryUtilities.CopyDirectory(Path.Combine(info.Directory.FullNam
e, "Resources"), destDirectory); |
500 | 551 |
501 var newVersion = options.Version + "-beta"; | 552 var newVersion = options.Version + "-beta"; |
502 | 553 |
| 554 // get the Google.Apis and Google.Apis.Authentication nuspec files a
nd replace the version in it |
503 var apiNuspec = Path.Combine(destDirectory, "Google.Apis.VERSION.nus
pec"); | 555 var apiNuspec = Path.Combine(destDirectory, "Google.Apis.VERSION.nus
pec"); |
504 var newApiNuspec = apiNuspec.Replace("VERSION", newVersion); | 556 var newApiNuspec = apiNuspec.Replace("VERSION", newVersion); |
505 var authenticationNuspec = Path.Combine(destDirectory, "Google.Apis.
Authentication.VERSION.nuspec"); | 557 var authenticationNuspec = Path.Combine(destDirectory, "Google.Apis.
Authentication.VERSION.nuspec"); |
506 var newAuthenticationNuspec = authenticationNuspec.Replace("VERSION"
, newVersion); | 558 var newAuthenticationNuspec = authenticationNuspec.Replace("VERSION"
, newVersion); |
507 | 559 |
508 File.Move(apiNuspec, newApiNuspec); | 560 File.Move(apiNuspec, newApiNuspec); |
509 File.Move(authenticationNuspec, newAuthenticationNuspec); | 561 File.Move(authenticationNuspec, newAuthenticationNuspec); |
510 | 562 |
511 var allLines = File.ReadAllText(newApiNuspec).Replace("VERSION", new
Version); | 563 var allLines = File.ReadAllText(newApiNuspec).Replace("VERSION", new
Version); |
512 File.WriteAllText(newApiNuspec, allLines); | 564 File.WriteAllText(newApiNuspec, allLines); |
(...skipping 16 matching lines...) Expand all Loading... |
529 return releaseProjects; | 581 return releaseProjects; |
530 } | 582 } |
531 | 583 |
532 var releasePaths = new[]· | 584 var releasePaths = new[]· |
533 { | 585 { |
534 DefaultRepository.Combine("Src", "GoogleApis", "GoogleApis.c
sproj"), | 586 DefaultRepository.Combine("Src", "GoogleApis", "GoogleApis.c
sproj"), |
535 DefaultRepository.Combine("Src", "GoogleApis.DotNet4", "Goog
leApis.DotNet4.csproj"), | 587 DefaultRepository.Combine("Src", "GoogleApis.DotNet4", "Goog
leApis.DotNet4.csproj"), |
536 DefaultRepository.Combine("Src", "GoogleApis.Authentication.
OAuth2",· | 588 DefaultRepository.Combine("Src", "GoogleApis.Authentication.
OAuth2",· |
537 "GoogleApis.Authentication.OAuth2.csproj") | 589 "GoogleApis.Authentication.OAuth2.csproj") |
538 }; | 590 }; |
539 releaseProjects = (from path in releasePaths | 591 return releaseProjects = (from path in releasePaths |
540 select new Project(path)).ToList(); | 592 select new Project(path)).ToList(); |
541 return releaseProjects; | 593 } |
542 } | 594 } |
543 } | 595 |
544 | 596 /// <summary>Builds the "default" repository projects.</summary> |
545 /// <summary> | 597 /// <returns><c>true</c> if the default repository was build successfull
y</returns> |
546 /// Builds "default" repository projects | |
547 /// </summary> | |
548 /// <returns></returns> | |
549 private bool BuildDefaultRepository() | 598 private bool BuildDefaultRepository() |
550 { | 599 { |
551 TraceSource.TraceEvent(TraceEventType.Information, "Building project
s...."); | 600 TraceSource.TraceEvent(TraceEventType.Information, "Building project
s...."); |
552 | 601 |
553 var allProjects = new List<Project>(); | 602 var allProjects = new List<Project>(); |
554 allProjects.AddRange(ReleaseProjects); | 603 allProjects.AddRange(ReleaseProjects); |
555 allProjects.Add(new Project(DefaultRepository.Combine("Src", "Google
Apis.Tests", | 604 allProjects.Add(new Project(DefaultRepository.Combine("Src", "Google
Apis.Tests", |
556 "GoogleApis.Tests.csproj"))); | 605 "GoogleApis.Tests.csproj"))); |
557 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", |
558 "GoogleApis.Authentication.OAuth2.Tests.csproj"))); | 607 "GoogleApis.Authentication.OAuth2.Tests.csproj"))); |
(...skipping 19 matching lines...) Expand all Loading... |
578 | 627 |
579 if (!ReleaseProjects.Contains(project)) | 628 if (!ReleaseProjects.Contains(project)) |
580 { | 629 { |
581 // TODO(peleyal): run unit tests for all test projects | 630 // TODO(peleyal): run unit tests for all test projects |
582 } | 631 } |
583 } | 632 } |
584 | 633 |
585 return true; | 634 return true; |
586 } | 635 } |
587 | 636 |
| 637 /// <summary>Constructs a new program with the given options.</summary> |
588 public Program(Options options) | 638 public Program(Options options) |
589 { | 639 { |
590 this.options = options; | 640 this.options = options; |
591 | 641 |
592 string path = Path.GetFullPath(options.OutputDirectory); | 642 string path = Path.GetFullPath(options.OutputDirectory); |
593 if (!Directory.Exists(path)) | 643 if (!Directory.Exists(path)) |
594 { | 644 { |
595 Directory.CreateDirectory(path); | 645 Directory.CreateDirectory(path); |
596 } | 646 } |
597 | 647 |
598 Environment.CurrentDirectory = path; | 648 Environment.CurrentDirectory = path; |
599 } | 649 } |
600 } | 650 } |
601 } | 651 } |
LEFT | RIGHT |