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

Delta Between Two Patch Sets: Tools/Google.Apis.NuGet.Publisher/Google.Apis.NuGet.Publisher/Program.cs

Issue 12662047: Issue 376: Generate NuGet pacakges for generated APIs (Closed) Base URL: https://google-api-dotnet-client.googlecode.com/hg/
Left Patch Set: add NuGet.exe file Created 10 years, 7 months ago
Right Patch Set: David final comments Created 10 years, 7 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
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
11 distributed under the License is distributed on an "AS IS" BASIS, 11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and 13 See the License for the specific language governing permissions and
14 limitations under the License. 14 limitations under the License.
15 */ 15 */
16 16
17 using System; 17 using System;
18 using System.Collections.Generic; 18 using System.Collections.Generic;
19 using System.Diagnostics; 19 using System.Diagnostics;
20 using System.IO; 20 using System.IO;
21 using System.Linq; 21 using System.Linq;
22 using System.Reflection; 22 using System.Reflection;
23 using System.Threading.Tasks; 23 using System.Threading.Tasks;
24 24
25 using CommandLine; 25 using CommandLine;
26 using CommandLine.Text; 26 using CommandLine.Text;
27 27
28 using Google.Apis.NuGet.Publisher.Discovery;
29 using Google.Apis.Utils;
30
28 namespace Google.Apis.NuGet.Publisher 31 namespace Google.Apis.NuGet.Publisher
29 { 32 {
30 /// <summary>The options class which contains the different options to this utility.</summary> 33 /// <summary>The options class which contains the different options to this utility.</summary>
31 class Options 34 class Options
32 { 35 {
33 public const string ModeTest = "test"; 36 public const string ModeTest = "test";
34 public const string ModePublish = "publisher"; 37 public const string ModePublish = "publisher";
35 38
36 [Option('a', "all_apis", HelpText = "Define if NuGet publisher works on all Google APIs")] 39 [Option('a', "all_apis", HelpText = "Define if NuGet publisher works on all Google APIs")]
37 public bool AllApis { get; set; } 40 public bool AllApis { get; set; }
38 41
39 [Option('n', "api_name", HelpText = "Define the specific API to work on" )] 42 [Option('n', "api_name", HelpText = "Define the specific API to work on" )]
40 public string ApiName { get; set; } 43 public string ApiName { get; set; }
41 44
42 [Option('v', "api_version", HelpText = "Define the specific API version to work on")] 45 [Option('v', "api_version", HelpText = "Define the specific API version to work on")]
43 public string ApiVersion { get; set; } 46 public string ApiVersion { get; set; }
44 47
45 [Option('m', "mode", DefaultValue = "test", 48 [Option('m', "mode", DefaultValue = "test",
46 HelpText = "Indicate the mode of operation {" + ModeTest + "|" + Mod ePublish + "}")] 49 HelpText = "Indicate the mode of operation {" + ModeTest + "|" + Mod ePublish + "}")]
47 public string Mode { get; set; } 50 public string Mode { get; set; }
48 51
49 [Option('k', "nuget_key", 52 [Option('k', "nuget_key",
50 HelpText = @"Define the NuGet API key. If empty the publisher works local on 'C:\LocalNuGetFeed'")] 53 HelpText = @"Define the NuGet API key. If empty the publisher works local on 'C:\LocalNuGetFeed'")]
51 public string NuGetApiKey { get; set; } 54 public string NuGetApiKey { get; set; }
52 55
56 [Option('l', "library_version",
57 HelpText = "Define the Google.Apis library which is used to download the bundles (e.g. 1.5.0-beta)")]
58 public string GoogleApisVersion { get; set; }
59
60 [Option('d', "apis_directory",
61 HelpText = "For testing purposes only. " +
62 "It Defines the APIs directory which contains all the APIs we want t o test.")]
63 public string ApisDirectory { get; set; }
64
53 [HelpOption] 65 [HelpOption]
54 public string GetHelp() 66 public string GetHelp()
55 { 67 {
56 return HelpText.AutoBuild(this, c => HelpText.DefaultParsingErrorsHa ndler(this, c)); 68 return HelpText.AutoBuild(this, c => HelpText.DefaultParsingErrorsHa ndler(this, c));
57 } 69 }
58 } 70 }
59 71
60 /// <summary> 72 /// <summary>
61 /// A Google APIs NuGet publisher which downloads the APIs latest bundles. F or each API it checks if there a NuGet 73 /// A Google APIs NuGet publisher which downloads the APIs latest bundles. F or each API it checks if there a NuGet
62 /// package doesn't exist for the client version and the API revision, and i f so it builds a new NuGet package and 74 /// package doesn't exist for the client version and the API revision, and i f so it builds a new NuGet package and
63 /// publish it to NuGet main repository. 75 /// publish it to NuGet main repository.
64 /// </summary> 76 /// </summary>
77 /// <remarks>
78 /// The Google APIs NuGet publisher uses a local folder "C:\LocalNuGetFeed" to store all the NuGet packages
79 /// locally.
80 /// Notice also the different between bundle and package:
81 /// A bundle is the zip file that contains the sources, and it's is download ed from
82 /// "https://google-api-client-libraries.appspot.com/"
83 /// A package is the NuGet package we use to build a solution. We can store NuGet packages locally (e.g. in
84 /// "C:\LocalNuGetFeed") or use the main NuGet repository at "https://nuget. org/api/v2/"
85 /// </remarks>
65 class Program 86 class Program
66 { 87 {
67 static TraceSource TraceSource = new TraceSource("Google.Apis"); 88 private static TraceSource TraceSource = new TraceSource("Google.Apis");
68 89
69 /// <summary>The discovery URL to get all the public APIs.</summary> 90 /// <summary>The discovery URI to get all the public APIs.</summary>
70 const string DiscoveryApiUrl = @"https://www.googleapis.com/discovery/v1 /apis"; 91 static readonly Uri DiscoveryApiUri = new Uri(@"https://www.googleapis.c om/discovery/v1/apis");
71 92
72 /// <summary>The directory that the bundle will be downloaded to.</summa ry> 93 /// <summary>The download URI format to download a specific API format. Two parameters are expected the API·
73 const string DownloadBundleTempDirectory = @"C:\Temp\NuGetPublisher\"; 94 /// name and its version.</summary>
David waters 2013/08/14 17:07:08 Not System.IO.Path.GetTempPath()? Will make it ha
peleyal 2013/08/14 21:05:24 Right now I don't care about linux, because PCL ca
74
75 /// <summary>The download URI format to download a specific API format</ summary>
David waters 2013/08/14 17:07:08 Document the number of parameters and what you hop
peleyal 2013/08/14 21:05:24 Done.
76 const string DownloadUriFormat = 95 const string DownloadUriFormat =
77 @"https://google-api-client-libraries.appspot.com/resources/api-libr aries/download/stable/{0}/{1}/csharp?deps=0"; 96 "https://google-api-client-libraries.appspot.com/download/library/{0 }/{1}/csharp?deps=0";
David waters 2013/08/14 17:07:08 line length
David waters 2013/08/14 17:07:08 Optional: @ is not required for this string.
peleyal 2013/08/14 21:05:24 Man I thought you will give up on that one.... it'
peleyal 2013/08/14 21:05:24 Done.
78 97
79 /// <summary>The template directory which contains the '.nuget' director y and the necessary·· 98 /// <summary>The template directory which contains the '.nuget' director y and the necessary··
80 /// 'Microsoft.Bcl.Build.targets' file.</summary> 99 /// 'Microsoft.Bcl.Build.targets' file.</summary>
81 static readonly string TemplateDirectory; 100 readonly string TemplateDirectory;
101
102 /// <summary>The directory that the bundle will be downloaded to.</summa ry>
103 readonly string DownloadBundleTempDirectory = Path.Combine(Path.GetTempP ath(), "GoogleAPIsPublisher");
82 104
83 /// <summary>The program's options.</summary> 105 /// <summary>The program's options.</summary>
84 static Options Options { get; set; } 106 readonly Options options;
85 107
86 static Program() 108 #region Main
David waters 2013/08/14 17:07:08 Personal: I dislike static constructors. This coul
peleyal 2013/08/14 21:05:24 TemplateDirectory is readonly so I think it's ok h
87 {
88 var execDir = Assembly.GetEntryAssembly().Location;
89 // remove "Google.Apis.NuGet.Publisher\\bin\\{Debug|Release}\\Google .Apis.NuGet.Publisher.exe"
David waters 2013/08/14 17:07:08 Suggestion: FileInfo assembly = new FileInfo(...Lo
peleyal 2013/08/14 21:05:24 LIKE On 2013/08/14 17:07:08, David waters wrote:
90 for (int i = 0; i < 4; ++i)
91 {
92 execDir = execDir.Remove(execDir.LastIndexOf("\\"));
93 }
94 TemplateDirectory = string.Format(@"{0}\Template\", execDir);
95
96 }
97 109
98 static void Main(string[] args) 110 static void Main(string[] args)
99 { 111 {
David waters 2013/08/14 17:07:08 Personal Preference: my main methods generly look
peleyal 2013/08/14 21:05:24 Done.
100 Options = new Options(); 112 var options = new Options();
101 if (!CommandLine.Parser.Default.ParseArguments(args, Options)) 113 if (!CommandLine.Parser.Default.ParseArguments(args, options))
102 { 114 {
103 // TODO(peleyal): add explanation which option is missing 115 // TODO(peleyal): add explanation which option is missing. Curre ntly the command line utility just
David waters 2013/08/14 17:07:08 Console.writeline(options.GetHelpText()); for no
peleyal 2013/08/14 21:05:24 The output contains the full help already but ther
104 } 116 // print the whole help without mention what is missing.
105 else if (!Options.AllApis && (Options.ApiName == null || Options.Api Version == null)) 117 }
118 else if (!options.AllApis && (options.ApiName == null || options.Api Version == null))
106 { 119 {
107 Console.WriteLine("Please Set '--all_apis true' or the API name and version, e.g. " + 120 Console.WriteLine("Please Set '--all_apis true' or the API name and version, e.g. " +
108 "'--api_name=drive --api_version=v2'"); 121 "'--api_name=drive --api_version=v2'");
109 } 122 }
123 else if (!new[] { Options.ModePublish, Options.ModeTest }.Contains(o ptions.Mode))
124 {
125 Console.WriteLine("Mode should be '{0}' or '{1}'", Options.ModeT est, Options.ModePublish);
126 }
110 else 127 else
111 { 128 {
129
112 try 130 try
113 { 131 {
114 switch (Options.Mode) 132 new Program(options).Run().Wait();
115 {
116 case Options.ModeTest:
117 MainAsync("TEST", TestAsync).Wait();
118 break;
119 case Options.ModePublish:
120 MainAsync("PUBLISH", PublishAsync).Wait();
121 break;
122 default:
123 Console.WriteLine("Mode should be '{0}' or '{1}'", O ptions.ModeTest, Options.ModePublish);
124 break;
125 }
126 } 133 }
127 catch (AggregateException ex) 134 catch (AggregateException ex)
128 { 135 {
129 foreach (var inner in ex.InnerExceptions) 136 foreach (var inner in ex.InnerExceptions)
130 { 137 {
131 TraceSource.TraceEvent(TraceEventType.Error, "Exception was thrown. {0}", inner.Message); 138 TraceSource.TraceEvent(TraceEventType.Error, "Exception was thrown. {0}", inner.Message);
132 } 139 }
133 } 140 }
134 } 141 }
135 142 Console.ReadKey();
136 Console.Write("Press any key to continue..."); 143 }
137 Console.ReadLine(); 144
145 #endregion
146
147 Program(Options options)
148 {
149 this.options = options;
150 // remove "Google.Apis.NuGet.Publisher\\bin\\{Debug|Release}\\Google .Apis.NuGet.Publisher.exe"
151 var fileInfo = new FileInfo(Assembly.GetEntryAssembly().Location);
152 TemplateDirectory = Path.Combine(fileInfo.Directory.Parent.Parent.Pa rent.FullName, "Template");
153 }
154
155 Task Run()
156 {
157 switch (options.Mode)
158 {
159 case Options.ModeTest:
160 return RunAsync("TEST", TestAsync);
161 case Options.ModePublish:
162 return RunAsync("PUBLISH", PublishAsync);
163 default:
164 throw new ArgumentException(string.Format("Mode should be {0 } or {1}",
165 Options.ModePublish, Options.ModeTest));
166 }
138 } 167 }
139 168
140 /// <summary>The main wrapper to run, gets a function to run which conta ins the main logic.</summary> 169 /// <summary>The main wrapper to run, gets a function to run which conta ins the main logic.</summary>
141 static async Task MainAsync(string header, Func<IEnumerable<DiscoveryDoc .Item>, Task> core) 170 async Task RunAsync(string header, Func<IEnumerable<DiscoveryItem>, Task > core)
142 { 171 {
143 TraceSource.TraceEvent(TraceEventType.Information, "=============== {0} ===============", header); 172 TraceSource.TraceEvent(TraceEventType.Information, "=============== {0} ===============", header);
144 TraceSource.TraceEvent(TraceEventType.Information, "Entering Google. Apis.Nuget.Publihser"); 173 TraceSource.TraceEvent(TraceEventType.Information, "Entering Google. Apis.Nuget.Publihser");
145 174
146 IEnumerable<DiscoveryDoc.Item> apis; 175 IEnumerable<DiscoveryItem> apis;
147 if (Options.AllApis) 176 if (options.AllApis)
148 { 177 {
149 apis = await new DiscoveryService().GetApis(DiscoveryApiUrl); 178 apis = await new DiscoveryService().GetApis(DiscoveryApiUri);
150 } 179 }
151 else 180 else
152 { 181 {
153 apis = new List<DiscoveryDoc.Item> { new DiscoveryDoc.Item 182 apis = new List<DiscoveryItem> { new DiscoveryItem
154 { 183 {
155 Name = Options.ApiName, 184 Name = options.ApiName.ToLower(),
156 Version = Options.ApiVersion 185 Version = options.ApiVersion.ToLower()
157 }}; 186 }};
158 } 187 }
159 188
160 if (Directory.Exists(DownloadBundleTempDirectory)) 189 if (Directory.Exists(DownloadBundleTempDirectory))
161 { 190 {
162 Directory.Delete(DownloadBundleTempDirectory, true); 191 Directory.Delete(DownloadBundleTempDirectory, true);
163 } 192 }
164 Directory.CreateDirectory(DownloadBundleTempDirectory); 193 Directory.CreateDirectory(DownloadBundleTempDirectory);
165 194
166 TraceSource.TraceEvent(TraceEventType.Information, "\"{0}\" folder w as created", DownloadBundleTempDirectory); 195 try
David waters 2013/08/14 17:07:08 line length
peleyal 2013/08/14 21:05:24 Done.
167 196 {
168 await core(apis); 197 TraceSource.TraceEvent(TraceEventType.Information, "\"{0}\" fold er was created",
169 198 DownloadBundleTempDirectory);
170 TraceSource.TraceEvent(TraceEventType.Information, 0, "Exiting Googl e.Apis.Nuget.Publihser"); 199
200 await core(apis);
201
202 TraceSource.TraceEvent(TraceEventType.Information, 0, "Exiting G oogle.Apis.Nuget.Publihser");
203 }
204 finally
205 {
206 Directory.Delete(DownloadBundleTempDirectory, true);
207 }
171 } 208 }
172 209
173 /// <summary>Publishes new APIs to NuGet main repository.</summary> 210 /// <summary>Publishes new APIs to NuGet main repository.</summary>
174 static async Task PublishAsync(IEnumerable<DiscoveryDoc.Item> apis) 211 async Task PublishAsync(IEnumerable<DiscoveryItem> apis)
175 { 212 {
176 // TODO(peleyal): validate NuGetApiKey 213 // TODO(peleyal): validate NuGetApiKey
177 foreach (var discoveryItem in apis) 214 foreach (var item in apis)
178 { 215 {
179 var workingDir = string.Format(@"{0}{1}-{2}\", DownloadBundleTem pDirectory, discoveryItem.Name, 216 var workingDir = Path.Combine(DownloadBundleTempDirectory,
180 discoveryItem.Version); 217 item.Name + "-" + item.Version);
181 Directory.CreateDirectory(workingDir); 218 Directory.CreateDirectory(workingDir);
182 219
183 var item = new ApiItemLogic(discoveryItem) 220 var bundleUri = string.Format(DownloadUriFormat, item.Name, item .Version);
221 if (!string.IsNullOrEmpty(options.GoogleApisVersion))
222 {
223 bundleUri = bundleUri + "&lv=" + options.GoogleApisVersion;
224 }
225
226 var publisher = new NuGetApiPublisher(item)
184 { 227 {
185 BundleDirectory = workingDir, 228 BundleDirectory = workingDir,
186 DownloadUriFormat = DownloadUriFormat, 229 BundleUri = new Uri(bundleUri),
187 TemplateDirectory = TemplateDirectory, 230 TemplateDirectory = TemplateDirectory,
188 NuGetApiKey = Options.NuGetApiKey, 231 NuGetApiKey = options.NuGetApiKey,
189 }; 232 };
190 233
191 try 234 try
192 { 235 {
193 await item.Run(); 236 await publisher.Run();
David waters 2013/08/14 17:07:08 Letting my lack of async/await/task knowledge show
peleyal 2013/08/14 21:05:24 I want to do one API at time. 1. The code looks
194 } 237 }
195 catch (Exception ex) 238 catch (Exception ex)
196 { 239 {
197 TraceSource.TraceEvent(TraceEventType.Error, "{0}\t Exceptio n [{1}] occurred", item, ex.Message); 240 TraceSource.TraceEvent(TraceEventType.Error, "{0}\t Exceptio n [{1}] occurred", item, ex.Message);
198 } 241 }
199 } 242 }
200 } 243 }
201 244
202 /// <summary> 245 /// <summary>
203 /// Tests the main logic behave as expected. <see cref="ApiItemLogic.Tes t"/> for more details. 246 /// Tests the main logic behave as expected. <see cref="NuGetApiPublishe r.Test"/> for more details.
204 /// </summary> 247 /// </summary>
205 static async Task TestAsync(IEnumerable<DiscoveryDoc.Item> apis) 248 async Task TestAsync(IEnumerable<DiscoveryItem> apis)
206 { 249 {
207 foreach (var discoveryItem in apis) 250 foreach (var item in apis)
208 { 251 {
209 var item = new ApiItemLogic(discoveryItem) 252 var publisher = new NuGetApiPublisher(item)
210 { 253 {
211 TemplateDirectory = TemplateDirectory, 254 TemplateDirectory = TemplateDirectory,
212 }; 255 };
213 try 256 try
214 { 257 {
215 await item.Test(@"Z:\Shared\NuGet\"); 258 await publisher.Test(options.ApisDirectory);
David waters 2013/08/14 17:07:08 Garrhhh you require anyone running this util to ha
peleyal 2013/08/14 21:05:24 LOL.... it should be a parameter :) On 2013/08/14
216 } 259 }
217 catch (Exception ex) 260 catch (Exception ex)
218 { 261 {
219 TraceSource.TraceEvent(TraceEventType.Error, "{0}\t Exceptio n [{1}] occurred", item, ex.Message); 262 TraceSource.TraceEvent(TraceEventType.Error, "{0}\t Exceptio n [{1}] occurred", item, ex.Message);
220 } 263 }
221 } 264 }
222 } 265 }
223 } 266 }
224 } 267 }
LEFTRIGHT

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