From a0e4f271209ab6058ce2df50f95dfd358187dbc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20Laval?= Date: Tue, 11 Dec 2012 11:41:21 +0100 Subject: [macdoc] Refactor doc merging process to support MonoMac too. --- AppDelegate.cs | 77 +++++++++++++++++++++++++++++++++--------------------- AppleDocHandler.cs | 4 ++- Product.cs | 62 +++++++++++++++++++++++++++++++++++++++++++ macdoc.csproj | 1 + 4 files changed, 113 insertions(+), 31 deletions(-) create mode 100644 Product.cs diff --git a/AppDelegate.cs b/AppDelegate.cs index f612061..8d2eb13 100644 --- a/AppDelegate.cs +++ b/AppDelegate.cs @@ -18,8 +18,6 @@ namespace macdoc { public partial class AppDelegate : NSApplicationDelegate { - const string MergeToolPath = "/Developer/MonoTouch/usr/share/doc/MonoTouch/apple-doc-wizard"; - static public RootTree Root; static public string MonodocDir; static public NSUrl MonodocBaseUrl; @@ -137,22 +135,26 @@ namespace macdoc else indexManager.AdvertiseFreshIndex (); }).ContinueWith (t => Logger.LogError ("Error while creating indexes", t.Exception), TaskContinuationOptions.OnlyOnFaulted); - - // Check if there is a MonoTouch documentation installed and launch accordingly - if (Root.HelpSources.Cast ().Any (hs => hs != null && hs.Name != null && hs.Name.StartsWith ("MonoTouch", StringComparison.InvariantCultureIgnoreCase)) - && File.Exists (MergeToolPath)) { + + // Check if there is a MonoTouch/MonoMac documentation installed and launch accordingly + var products = Root.HelpSources.Cast ().Where (hs => hs != null && hs.Name != null).ToProducts (); + if (products.Where (p => File.Exists (ProductUtils.GetMergeToolForProduct (p))).Any ()) { Task.Factory.StartNew (() => { - AppleDocHandler.AppleDocInformation infos; - bool mergeOutdated = false; - bool docOutdated = AppleDocHandler.CheckAppleDocFreshness (AppleDocHandler.IosAtomFeed, out infos); - if (!docOutdated) - mergeOutdated = AppleDocHandler.CheckMergedDocumentationFreshness (infos); - return Tuple.Create (docOutdated || mergeOutdated, docOutdated, mergeOutdated); + return products.ToDictionary (p => p, + p => { + AppleDocHandler.AppleDocInformation infos; + bool mergeOutdated = false; + bool docOutdated = AppleDocHandler.CheckAppleDocFreshness (ProductUtils.GetDocFeedForProduct (p), + out infos); + if (!docOutdated) + mergeOutdated = AppleDocHandler.CheckMergedDocumentationFreshness (infos); + return Tuple.Create (docOutdated, mergeOutdated); + }); }).ContinueWith (t => { - Logger.Log ("Merged status {0}", t.Result); - if (!t.Result.Item1) + Logger.Log ("Merged status {0}", string.Join (", ", t.Result.Select (kvp => kvp.ToString ()))); + if (!t.Result.Any (kvp => kvp.Value.Item1 || kvp.Value.Item2)) return; - BeginInvokeOnMainThread (() => LaunchDocumentationUpdate (t.Result.Item2, t.Result.Item3)); + BeginInvokeOnMainThread (() => LaunchDocumentationUpdate (t.Result)); }); } } @@ -249,15 +251,16 @@ namespace macdoc IntPtr.Zero); } - void LaunchDocumentationUpdate (bool docOutdated, bool mergeOutdated) + void LaunchDocumentationUpdate (Dictionary> toUpdate) { + var informative = "We have detected your " + string.Join (" and ", toUpdate.Keys.Select (ProductUtils.GetFriendlyName)) + + " documentation can be upgraded with Apple documentation." + + Environment.NewLine + Environment.NewLine + + "Would you like to update the documentation now? You can continue to browse the documentation while the update is performed."; var infoDialog = new NSAlert { AlertStyle = NSAlertStyle.Informational, MessageText = "Documentation update available", - InformativeText = "We have detected your MonoTouch documentation can be upgraded with Apple documentation." - + Environment.NewLine - + Environment.NewLine - + "Would you like to update the documentation now? You can continue to browse the documentation while the update is performed." + InformativeText = informative }; infoDialog.AddButton ("Update now"); @@ -268,18 +271,32 @@ namespace macdoc return; // Launching AppleDocWizard as root - var mergerTask = Task.Factory.StartNew (() => { - // If the script has its setuid bit on and user as root, then we launch it directly otherwise we first restore it - if (!RootLauncher.IsRootEnabled (MergeToolPath)) { - RootLauncher.LaunchExternalTool (MergeToolPath, docOutdated ? new string[] { "--self-repair" } : (string[])null); - // No good way to know when the process will finish, so wait a bit. Not ideal but since this is an unlikely codepath, shouldn't matter. - System.Threading.Thread.Sleep (1000); - } - return ProcessUtils.StartProcess (new System.Diagnostics.ProcessStartInfo (MergeToolPath, "--force-download"), null, null, CancellationToken.None); - }).Unwrap (); + var mergerTasks = toUpdate + .Where (kvp => kvp.Value.Item1 || kvp.Value.Item2) + .Select (kvp => Task.Factory.StartNew (() => { + var mergeToolPath = ProductUtils.GetMergeToolForProduct (kvp.Key); + var docOutdated = kvp.Value.Item1; + // If the script has its setuid bit on and user as root, then we launch it directly otherwise we first restore it + if (!RootLauncher.IsRootEnabled (mergeToolPath)) { + RootLauncher.LaunchExternalTool (mergeToolPath, new string[] { "--self-repair" }); + // No good way to know when the process will finish, so wait a bit. Not ideal but since this is an unlikely codepath, shouldn't matter. + System.Threading.Thread.Sleep (1000); + } + var psi = new System.Diagnostics.ProcessStartInfo (mergeToolPath, docOutdated ? "--force-download" : null); + return ProcessUtils.StartProcess (psi, null, null, CancellationToken.None); + }).Unwrap ()); + // No Task.WhenAll yet + var tcs = new TaskCompletionSource (); + Task.Factory.ContinueWhenAll (mergerTasks.ToArray (), ts => { + var faulteds = ts.Where (t => t.IsFaulted); + if (faulteds.Any ()) + tcs.SetException (faulteds.Select (t => t.Exception)); + else + tcs.SetResult (ts.Select (t => t.Result).FirstOrDefault (r => r != 0)); + }); var mergeController = new AppleDocMergeWindowController (); - mergeController.TrackProcessTask (mergerTask); + mergeController.TrackProcessTask (tcs.Task); mergeController.ShowWindow (this); mergeController.Window.Center (); } diff --git a/AppleDocHandler.cs b/AppleDocHandler.cs index 47f13d6..a499d04 100644 --- a/AppleDocHandler.cs +++ b/AppleDocHandler.cs @@ -24,8 +24,10 @@ namespace macdoc const string MonodocLibPath = "/Library/Frameworks/Mono.framework/External/monodoc/"; const string MonoTouchLibPath = "/Developer/MonoTouch/usr/lib/mono/2.1/monotouch.dll"; - public const string IosAtomFeed = "https://developer.apple.com/rss/com.apple.adc.documentation.AppleiPhone5_0.atom"; + public const string Ios5AtomFeed = "https://developer.apple.com/rss/com.apple.adc.documentation.AppleiPhone5_0.atom"; + public const string Ios6AtomFeed = "https://developer.apple.com/rss/com.apple.adc.documentation.AppleiPhone6.0.atom"; public const string MacLionAtomFeed = "http://developer.apple.com/rss/com.apple.adc.documentation.AppleLion.atom"; + public const string MacMountainLionFeed = "https://developer.apple.com/rss/com.apple.adc.documentation.AppleOSX10_8.atom"; readonly XNamespace docsetNamespace = "http://developer.apple.com/rss/docset_extensions"; readonly XNamespace atomNamespace = "http://www.w3.org/2005/Atom"; diff --git a/Product.cs b/Product.cs new file mode 100644 index 0000000..899f46c --- /dev/null +++ b/Product.cs @@ -0,0 +1,62 @@ +using System; +using System.Linq; +using System.Collections.Generic; +using Monodoc; + +namespace macdoc +{ + public enum Product + { + MonoTouch, + MonoMac + } + + public static class ProductUtils + { + public static string GetFriendlyName (Product product) + { + switch (product) { + case Product.MonoTouch: + return "Xamarin.iOS"; + case Product.MonoMac: + return "Xamarin.Mac"; + default: + return string.Empty; + } + } + + public static IEnumerable ToProducts (this IEnumerable sources) + { + foreach (var hs in sources) { + if (hs.Name.StartsWith ("MonoTouch", StringComparison.InvariantCultureIgnoreCase)) + yield return Product.MonoTouch; + else if (hs.Name.StartsWith ("MonoMac", StringComparison.InvariantCultureIgnoreCase)) + yield return Product.MonoMac; + } + } + + public static string GetDocFeedForProduct (Product product) + { + switch (product) { + case Product.MonoTouch: + return AppleDocHandler.Ios6AtomFeed; + case Product.MonoMac: + return AppleDocHandler.MacMountainLionFeed; + default: + return null; + } + } + + public static string GetMergeToolForProduct (Product product) + { + switch (product) { + case Product.MonoTouch: + return "/Developer/MonoTouch/usr/share/doc/MonoTouch/apple-doc-wizard"; + case Product.MonoMac: + return "/Library/Frameworks/Xamarin.Mac.framework/Versions/Current/share/doc/apple-doc-wizard"; + default: + return null; + } + } + } +} diff --git a/macdoc.csproj b/macdoc.csproj index 4db6cdc..2d3710b 100644 --- a/macdoc.csproj +++ b/macdoc.csproj @@ -106,6 +106,7 @@ AppleDocMergeWindow.cs + -- cgit v1.2.3