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

Unified Diff: 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/
Patch Set: David final comments Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Tools/Google.Apis.NuGet.Publisher/Google.Apis.NuGet.Publisher/Program.cs
===================================================================
new file mode 100644
--- /dev/null
+++ b/Tools/Google.Apis.NuGet.Publisher/Google.Apis.NuGet.Publisher/Program.cs
@@ -0,0 +1,267 @@
+/*
+Copyright 2013 Google Inc
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Threading.Tasks;
+
+using CommandLine;
+using CommandLine.Text;
+
+using Google.Apis.NuGet.Publisher.Discovery;
+using Google.Apis.Utils;
+
+namespace Google.Apis.NuGet.Publisher
+{
+ /// <summary>The options class which contains the different options to this utility.</summary>
+ class Options
+ {
+ public const string ModeTest = "test";
+ public const string ModePublish = "publisher";
+
+ [Option('a', "all_apis", HelpText = "Define if NuGet publisher works on all Google APIs")]
+ public bool AllApis { get; set; }
+
+ [Option('n', "api_name", HelpText = "Define the specific API to work on")]
+ public string ApiName { get; set; }
+
+ [Option('v', "api_version", HelpText = "Define the specific API version to work on")]
+ public string ApiVersion { get; set; }
+
+ [Option('m', "mode", DefaultValue = "test",
+ HelpText = "Indicate the mode of operation {" + ModeTest + "|" + ModePublish + "}")]
+ public string Mode { get; set; }
+
+ [Option('k', "nuget_key",
+ HelpText = @"Define the NuGet API key. If empty the publisher works local on 'C:\LocalNuGetFeed'")]
+ public string NuGetApiKey { get; set; }
+
+ [Option('l', "library_version",
+ HelpText = "Define the Google.Apis library which is used to download the bundles (e.g. 1.5.0-beta)")]
+ public string GoogleApisVersion { get; set; }
+
+ [Option('d', "apis_directory",
+ HelpText = "For testing purposes only. " +
+ "It Defines the APIs directory which contains all the APIs we want to test.")]
+ public string ApisDirectory { get; set; }
+
+ [HelpOption]
+ public string GetHelp()
+ {
+ return HelpText.AutoBuild(this, c => HelpText.DefaultParsingErrorsHandler(this, c));
+ }
+ }
+
+ /// <summary>
+ /// A Google APIs NuGet publisher which downloads the APIs latest bundles. For each API it checks if there a NuGet
+ /// package doesn't exist for the client version and the API revision, and if so it builds a new NuGet package and
+ /// publish it to NuGet main repository.
+ /// </summary>
+ /// <remarks>
+ /// The Google APIs NuGet publisher uses a local folder "C:\LocalNuGetFeed" to store all the NuGet packages
+ /// locally.
+ /// Notice also the different between bundle and package:
+ /// A bundle is the zip file that contains the sources, and it's is downloaded from
+ /// "https://google-api-client-libraries.appspot.com/"
+ /// A package is the NuGet package we use to build a solution. We can store NuGet packages locally (e.g. in
+ /// "C:\LocalNuGetFeed") or use the main NuGet repository at "https://nuget.org/api/v2/"
+ /// </remarks>
+ class Program
+ {
+ private static TraceSource TraceSource = new TraceSource("Google.Apis");
+
+ /// <summary>The discovery URI to get all the public APIs.</summary>
+ static readonly Uri DiscoveryApiUri = new Uri(@"https://www.googleapis.com/discovery/v1/apis");
+
+ /// <summary>The download URI format to download a specific API format. Two parameters are expected the API
+ /// name and its version.</summary>
+ const string DownloadUriFormat =
+ "https://google-api-client-libraries.appspot.com/download/library/{0}/{1}/csharp?deps=0";
+
+ /// <summary>The template directory which contains the '.nuget' directory and the necessary
+ /// 'Microsoft.Bcl.Build.targets' file.</summary>
+ readonly string TemplateDirectory;
+
+ /// <summary>The directory that the bundle will be downloaded to.</summary>
+ readonly string DownloadBundleTempDirectory = Path.Combine(Path.GetTempPath(), "GoogleAPIsPublisher");
+
+ /// <summary>The program's options.</summary>
+ readonly Options options;
+
+ #region Main
+
+ static void Main(string[] args)
+ {
+ var options = new Options();
+ if (!CommandLine.Parser.Default.ParseArguments(args, options))
+ {
+ // TODO(peleyal): add explanation which option is missing. Currently the command line utility just
+ // print the whole help without mention what is missing.
+ }
+ else if (!options.AllApis && (options.ApiName == null || options.ApiVersion == null))
+ {
+ Console.WriteLine("Please Set '--all_apis true' or the API name and version, e.g. " +
+ "'--api_name=drive --api_version=v2'");
+ }
+ else if (!new[] { Options.ModePublish, Options.ModeTest }.Contains(options.Mode))
+ {
+ Console.WriteLine("Mode should be '{0}' or '{1}'", Options.ModeTest, Options.ModePublish);
+ }
+ else
+ {
+
+ try
+ {
+ new Program(options).Run().Wait();
+ }
+ catch (AggregateException ex)
+ {
+ foreach (var inner in ex.InnerExceptions)
+ {
+ TraceSource.TraceEvent(TraceEventType.Error, "Exception was thrown. {0}", inner.Message);
+ }
+ }
+ }
+ Console.ReadKey();
+ }
+
+ #endregion
+
+ Program(Options options)
+ {
+ this.options = options;
+ // remove "Google.Apis.NuGet.Publisher\\bin\\{Debug|Release}\\Google.Apis.NuGet.Publisher.exe"
+ var fileInfo = new FileInfo(Assembly.GetEntryAssembly().Location);
+ TemplateDirectory = Path.Combine(fileInfo.Directory.Parent.Parent.Parent.FullName, "Template");
+ }
+
+ Task Run()
+ {
+ switch (options.Mode)
+ {
+ case Options.ModeTest:
+ return RunAsync("TEST", TestAsync);
+ case Options.ModePublish:
+ return RunAsync("PUBLISH", PublishAsync);
+ default:
+ throw new ArgumentException(string.Format("Mode should be {0} or {1}",
+ Options.ModePublish, Options.ModeTest));
+ }
+ }
+
+ /// <summary>The main wrapper to run, gets a function to run which contains the main logic.</summary>
+ async Task RunAsync(string header, Func<IEnumerable<DiscoveryItem>, Task> core)
+ {
+ TraceSource.TraceEvent(TraceEventType.Information, "=============== {0} ===============", header);
+ TraceSource.TraceEvent(TraceEventType.Information, "Entering Google.Apis.Nuget.Publihser");
+
+ IEnumerable<DiscoveryItem> apis;
+ if (options.AllApis)
+ {
+ apis = await new DiscoveryService().GetApis(DiscoveryApiUri);
+ }
+ else
+ {
+ apis = new List<DiscoveryItem> { new DiscoveryItem
+ {
+ Name = options.ApiName.ToLower(),
+ Version = options.ApiVersion.ToLower()
+ }};
+ }
+
+ if (Directory.Exists(DownloadBundleTempDirectory))
+ {
+ Directory.Delete(DownloadBundleTempDirectory, true);
+ }
+ Directory.CreateDirectory(DownloadBundleTempDirectory);
+
+ try
+ {
+ TraceSource.TraceEvent(TraceEventType.Information, "\"{0}\" folder was created",
+ DownloadBundleTempDirectory);
+
+ await core(apis);
+
+ TraceSource.TraceEvent(TraceEventType.Information, 0, "Exiting Google.Apis.Nuget.Publihser");
+ }
+ finally
+ {
+ Directory.Delete(DownloadBundleTempDirectory, true);
+ }
+ }
+
+ /// <summary>Publishes new APIs to NuGet main repository.</summary>
+ async Task PublishAsync(IEnumerable<DiscoveryItem> apis)
+ {
+ // TODO(peleyal): validate NuGetApiKey
+ foreach (var item in apis)
+ {
+ var workingDir = Path.Combine(DownloadBundleTempDirectory,
+ item.Name + "-" + item.Version);
+ Directory.CreateDirectory(workingDir);
+
+ var bundleUri = string.Format(DownloadUriFormat, item.Name, item.Version);
+ if (!string.IsNullOrEmpty(options.GoogleApisVersion))
+ {
+ bundleUri = bundleUri + "&lv=" + options.GoogleApisVersion;
+ }
+
+ var publisher = new NuGetApiPublisher(item)
+ {
+ BundleDirectory = workingDir,
+ BundleUri = new Uri(bundleUri),
+ TemplateDirectory = TemplateDirectory,
+ NuGetApiKey = options.NuGetApiKey,
+ };
+
+ try
+ {
+ await publisher.Run();
+ }
+ catch (Exception ex)
+ {
+ TraceSource.TraceEvent(TraceEventType.Error, "{0}\t Exception [{1}] occurred", item, ex.Message);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Tests the main logic behave as expected. <see cref="NuGetApiPublisher.Test"/> for more details.
+ /// </summary>
+ async Task TestAsync(IEnumerable<DiscoveryItem> apis)
+ {
+ foreach (var item in apis)
+ {
+ var publisher = new NuGetApiPublisher(item)
+ {
+ TemplateDirectory = TemplateDirectory,
+ };
+ try
+ {
+ await publisher.Test(options.ApisDirectory);
+ }
+ catch (Exception ex)
+ {
+ TraceSource.TraceEvent(TraceEventType.Error, "{0}\t Exception [{1}] occurred", item, ex.Message);
+ }
+ }
+ }
+ }
+}

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