[mono/monomac] 4c4af435: Simplify the mac documentation updating

"Miguel de Icaza ([email protected])" <[email protected]>
Newsgroups gmane.comp.gnome.mono.patches
Message-ID <00000141a45660d5-f810dad2-e019-44db-be7d-3ba79a0b1cbc-000000@email.amazonses.com>
   Branch: refs/heads/master
     Home: https://github.com/mono/monomac
  Compare: https://github.com/mono/monomac/compare/61e1c0974d3c...4c4af435a802

   Commit: 4c4af435a802a4b4b569d4a29156d8da68f906d4
   Author: Miguel de Icaza <[email protected]> (migueldeicaza)
     Date: 2013-10-10 21:46:00 GMT
      URL: https://github.com/mono/monomac/commit/4c4af435a802a4b4b569d4a29156d8da68f906d4

Simplify the mac documentation updating

Changed paths:
  M samples/macdoc/AppDelegate.cs
  M samples/macdoc/Product.cs
  M samples/macdoc/macdoc.csproj
Removed paths:
  D samples/macdoc/AppleDocHandler.cs

Modified: samples/macdoc/AppDelegate.cs
===================================================================
@@ -13,6 +13,7 @@
 using MonoMac.ObjCRuntime;
 
 using Monodoc;
+using System.Text;
 
 namespace macdoc
 {
@@ -106,9 +107,21 @@ public AppDelegate ()
 			IndexUpdateManager = new IndexUpdateManager (helpSources,
 			                                             macDocPath);
 			BookmarkManager = new BookmarkManager (macDocPath);
-			AppleDocHandler = new AppleDocHandler ("/Library/Frameworks/Mono.framework/Versions/Current/etc/");
 		}
-		
+
+		int Run (string command)
+		{
+			var psi = new System.Diagnostics.ProcessStartInfo (command, " --need-update");
+			var t = ProcessUtils.StartProcess (psi, null, null, CancellationToken.None);
+			t.Wait ();
+
+			try {
+				return t.Result;
+			} catch {
+				return 1;
+			}
+		}
+
 		public override void FinishedLaunching (NSObject notification)
 		{
 			// Check if we are loaded with a search term and load a document for it
@@ -133,25 +146,23 @@ public override void FinishedLaunching (NSObject notification)
 
 			// Check if there is a MonoTouch/MonoMac documentation installed and launch accordingly
 			var products = Root.HelpSources.Where (hs => hs != null && hs.Name != null).ToProducts ().Distinct ().ToArray ();
-			if (products.Where (p => File.Exists (ProductUtils.GetMergeToolForProduct (p))).Any ()) {
-				Task.Factory.StartNew (() => {
-					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, p);
-						return Tuple.Create (docOutdated, mergeOutdated);
-					});
-				}).ContinueWith (t => {
-					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));
-				});
+			var message = new StringBuilder ("We have detected that your documentation for the following products can be improved by merging the Apple documentation:\n");
+			var toUpdate = new List<Product> ();
+			foreach (var p in products) {
+				bool needUpdate = false;
+				var tool = ProductUtils.GetMergeToolForProduct (p);
+
+				if (!File.Exists (tool))
+					continue;
+
+				if (Run (tool) == 0) {
+					toUpdate.Add (p);
+					message.AppendFormat ("{0}\n", ProductUtils.GetFriendlyName (p));
+				}
 			}
+
+			if (toUpdate.Count > 0)
+				LaunchDocumentationUpdate (toUpdate.ToArray (), message.ToString ());
 		}
 		
 		public static IndexUpdateManager IndexUpdateManager {
@@ -163,12 +174,7 @@ public override void FinishedLaunching (NSObject notification)
 			get;
 			private set;
 		}
-		
-		public static AppleDocHandler AppleDocHandler {
-			get;
-			private set;
-		}
-		
+
 		public static bool IsOnLionOrBetter {
 			get {
 				return isOnLion;
@@ -246,19 +252,12 @@ public override void WillTerminate (NSNotification notification)
 				                                       IntPtr.Zero);
 		}
 		
-		void LaunchDocumentationUpdate (Dictionary<Product, Tuple<bool, bool>> toUpdate)
+		void LaunchDocumentationUpdate (Product [] products, string informative)
 		{
-			var outdatedProducts = string.Join (" and ", toUpdate.Where (kvp => kvp.Value.Item1 || kvp.Value.Item2).Select (kvp => ProductUtils.GetFriendlyName (kvp.Key)));
-			var informative = "We have detected your " + outdatedProducts + " documentation can be upgraded with Apple documentation.";
-			// Check if we are going to be downloading stuff
-			if (toUpdate.Any (kvp => kvp.Value.Item1))
-				informative += Environment.NewLine + Environment.NewLine + "Warning: we are going to download documentation from Apple servers which can take a long time depending on your Internet connection.";
-			informative += Environment.NewLine + Environment.NewLine + "Would you like to update the documentation now?";
-
 			var infoDialog = new NSAlert {
 				AlertStyle = NSAlertStyle.Informational,
 				MessageText = "Documentation update available",
-				InformativeText = informative
+				InformativeText = informative + "\n\nWarning: If you have not downloaded the documentation with Xcode, this program will download the documentation from Apple servers which can take a long time.\n\nWould you like to update the documentation now?"
 			};
 			
 			infoDialog.AddButton ("Update now");
@@ -267,23 +266,14 @@ void LaunchDocumentationUpdate (Dictionary<Product, Tuple<bool, bool>> toUpdate)
 			// If Cancel was clicked, just return
 			if (dialogResult == (int)NSAlertButtonReturn.Second)
 				return;
-			
-			// Launching AppleDocWizard as root
-			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 ());
+			var mergerTasks = products.Select (p => Task.Factory.StartNew (() => {
+				var mergeToolPath = ProductUtils.GetMergeToolForProduct (p);
+
+				var psi = new System.Diagnostics.ProcessStartInfo (mergeToolPath, null);
+				return ProcessUtils.StartProcess (psi, null, null, CancellationToken.None);
+			}).Unwrap ());
+
 			// No Task.WhenAll yet
 			var tcs = new TaskCompletionSource<int> ();
 			Task.Factory.ContinueWhenAll (mergerTasks.ToArray (), ts => {

Removed: samples/macdoc/AppleDocHandler.cs
===================================================================
@@ -1,154 +0,0 @@
-using System;
-using System.IO;
-using System.Net;
-using System.Linq;
-using System.Threading;
-using System.Xml.Linq;
-using System.Collections.Generic;
-
-namespace macdoc
-{
-	public class AppleDocHandler
-	{
-		public class AppleDocInformation
-		{
-			public Version Version { get; set; }
-			public string ID { get; set; }
-			public DateTime UpdateDate { get; set; }
-			public string DownloadUrl { get; set; }
-		}
-		
-		readonly string[] searchPaths = new[] {
-			"/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Documentation/DocSets",
-			"/Applications/Xcode.app/Contents/Developer/Documentation/DocSets/",
-			"/Library/Developer/Shared/Documentation/DocSets/",
-			"/Developer/Platforms/iPhoneOS.platform/Developer/Documentation/DocSets/"
-		};
-		const string MonodocLibPath = "/Library/Frameworks/Mono.framework/External/monodoc/";
-		const string MonoTouchLibPath = "/Developer/MonoTouch/usr/lib/mono/2.1/monotouch.dll";
-
-		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";
-		readonly string baseApplicationPath;
-
-		Dictionary<string, XDocument> appleFeeds = new Dictionary<string, XDocument> ();
-		
-		public AppleDocHandler (string baseApplicationPath)
-		{
-			this.baseApplicationPath = baseApplicationPath;
-		}
-		
-		// We load the atom field that contains a timeline of the modifications down to documentation by Apple
-		XDocument LoadAppleFeed (string feedUrl)
-		{
-			XDocument appleFeed;
-			if (appleFeeds.TryGetValue (feedUrl, out appleFeed))
-				return appleFeed;
-
-			WebClient wc = new WebClient ();
-			var feed = wc.DownloadString (feedUrl);
-			return appleFeeds[feedUrl] = XDocument.Parse (feed);
-		}
-
-		// This method transforms the Atom XML data into a POCO for the the most recent item of the feed
-		AppleDocInformation GetLatestAppleDocInformation (XDocument feed)
-		{
-			var latestEntry = feed.Descendants (atomNamespace + "entry").FirstOrDefault ();
-			if (latestEntry == null)
-				return null;
-			
-			var infos = new AppleDocInformation () {
-				Version = CloneFillWithZeros (new Version (latestEntry.Element (docsetNamespace + "version").Value)),
-				ID = latestEntry.Element (docsetNamespace + "identifier").Value,
-				UpdateDate = DateTime.Parse (latestEntry.Element (atomNamespace + "updated").Value),
-				DownloadUrl = latestEntry.Element (atomNamespace + "link").Attribute ("href").Value
-			};
-
-			return infos;
-		}
-
-		// This method read the Info.plist available in all Apple .docset to get the version of the bundle
-		Version GetAppleDocVersion (string directory)
-		{
-			var plist = Path.Combine (directory, "Contents", "Info.plist");
-			if (!File.Exists (plist))
-				return null;
-
-			var doc = XDocument.Load (plist);
-			var version = doc.Descendants ("key")
-				.First (k => k.Value.Equals ("CFBundleVersion", StringComparison.Ordinal))
-				.ElementsAfterSelf ()
-				.First ()
-				.Value;
-
-			return CloneFillWithZeros (new Version (version));
-		}
-
-		// This method checks that an iOS documentation set is installed on the user machine
-		// and also checks if it's the latest available
-		bool CheckAppleDocAvailabilityAndFreshness (AppleDocInformation infos)
-		{
-			var path = searchPaths
-				.Select (p => Path.Combine (p, infos.ID + ".docset"))
-				.FirstOrDefault (p => Directory.Exists (p));
-
-			if (path == null)
-				return false;
-
-			var installedVersion = GetAppleDocVersion (path);
-			Logger.Log ("Installed doc version {0}, compared to remote {1}", installedVersion.ToString (), infos.Version.ToString ());
-			return installedVersion >= infos.Version;
-		}
-
-		// atom feed is one of the Apple documentation feed, iOS and Lion are given in const form above
-		// returns true if the documentation was updated, false otherwise. The progressDelegate parameter
-		// is given the completion percentage
-		public bool CheckAppleDocFreshness (string atomFeed, out AppleDocInformation infos)
-		{
-			Logger.Log ("Downloading Apple feed at {0}", atomFeed);
-			var feed = LoadAppleFeed (atomFeed);
-			infos = GetLatestAppleDocInformation (feed);
-			var needRefresh = !CheckAppleDocAvailabilityAndFreshness (infos);
-			
-			return needRefresh;
-		}
-		
-		public bool CheckMergedDocumentationFreshness (AppleDocInformation infos, Product product)
-		{
-			var statusFile = Path.Combine (baseApplicationPath, "macdoc");
-			if (!Directory.Exists (statusFile)) {
-				try {
-					Directory.CreateDirectory (statusFile);
-				} catch {}
-				return true;
-			}
-			statusFile = Path.Combine (statusFile, product == Product.MonoMac ? "merge.mac.status" : "merge.status");
-			if (!File.Exists (statusFile))
-				return true;
-			if (!string.IsNullOrEmpty (Environment.GetEnvironmentVariable ("APPLEDOCWIZARD_FORCE_MERGE")))
-				return true;
-			
-			var mergedVersion = CloneFillWithZeros (new Version (File.ReadAllText (statusFile)));
-			Logger.Log ("Comparing merged {0} with downloaded {1}", mergedVersion.ToString (), infos.Version.ToString ());
-			return mergedVersion != infos.Version;
-		}
-		
-		static Version CloneFillWithZeros (Version v)
-		{
-			if (v == null)
-				return null;
-			int major = v.Major == -1 ? 0 : v.Major;
-			int minor = v.Minor == -1 ? 0 : v.Minor;
-			int build = v.Build == -1 ? 0 : v.Build;
-			int revision = v.Revision == -1 ? 0 : v.Revision;
-
-			return new Version (major, minor, build, revision);
-		}
-
-	}
-}

Modified: samples/macdoc/Product.cs
===================================================================
@@ -35,18 +35,6 @@ public static IEnumerable<Product> ToProducts (this IEnumerable<HelpSource> sour
 			}
 		}
 
-		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) {

Modified: samples/macdoc/macdoc.csproj
===================================================================
@@ -100,7 +100,6 @@
     <Compile Include="FindBarExtraordinaire.designer.cs">
       <DependentUpon>FindBarExtraordinaire.cs</DependentUpon>
     </Compile>
-    <Compile Include="AppleDocHandler.cs" />
     <Compile Include="ProcessUtils.cs" />
     <Compile Include="AppleDocMergeWindow.cs" />
     <Compile Include="AppleDocMergeWindowController.cs" />


_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.