Do

Merge lp://staging/~alexlauni/do/no-repo into lp://staging/do

Proposed by Alex Launi
Status: Merged
Merged at revision: not available
Proposed branch: lp://staging/~alexlauni/do/no-repo
Merge into: lp://staging/do
Diff against target: None lines
To merge this branch: bzr merge lp://staging/~alexlauni/do/no-repo
Reviewer Review Type Date Requested Status
Jason Smith (community) Approve
Review via email: mp+5772@code.staging.launchpad.net
To post a comment you must log in.
Revision history for this message
Alex Launi (alexlauni) wrote :

the right branch

Revision history for this message
Jason Smith (jassmith) wrote :

The XmlTextReader needs to be disposed

This is not too friendly to translators:
string errorMessage = Catalog.GetString ("<b><span size=\"large\">There was an error installing the selected {0}</span></b>");

use:
string errorMessage = "<b><span size=\"large\">" + Catalog.GetString ("There was an error installing the selected ") + "{0}</span></b>";

Optionally:
LINQ-ify EnableDisabledPlugins ();

review: Approve
lp://staging/~alexlauni/do/no-repo updated
1118. By Alex Launi

wrap XmlReader in a using block

1119. By Alex Launi

some more linqification in InstallLocalPlugins

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Do.Universe/Do.Universe.mdp'
2--- Do.Universe/Do.Universe.mdp 2009-01-27 03:23:24 +0000
3+++ Do.Universe/Do.Universe.mdp 2009-04-21 01:01:54 +0000
4@@ -49,6 +49,5 @@
5 <ProjectReference type="Gac" localcopy="True" refto="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
6 <ProjectReference type="Gac" localcopy="True" refto="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
7 <ProjectReference type="Gac" localcopy="True" refto="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
8- <ProjectReference type="Gac" localcopy="True" refto="Do.Platform, Version=0.8.0.0, Culture=neutral, PublicKeyToken=null" />
9 </References>
10 </Project>
11\ No newline at end of file
12
13=== added file 'Do/Do.addins'
14--- Do/Do.addins 1970-01-01 00:00:00 +0000
15+++ Do/Do.addins 2009-03-31 23:04:25 +0000
16@@ -0,0 +1,3 @@
17+<Addins>
18+ <Directory include-subdirs="true">./plugins</Directory>
19+</Addins>
20
21=== modified file 'Do/Do.mdp'
22--- Do/Do.mdp 2009-04-18 03:12:46 +0000
23+++ Do/Do.mdp 2009-04-21 22:18:57 +0000
24@@ -101,6 +101,7 @@
25 <ProjectReference type="Project" localcopy="True" refto="Do.Interface.Linux" />
26 <ProjectReference type="Project" localcopy="True" refto="Do.Universe" />
27 <ProjectReference type="Gac" localcopy="True" refto="glib-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
28+ <ProjectReference type="Gac" localcopy="True" refto="System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
29 </References>
30 <LanguageParameters ApplicationIcon="../../../../../jason/do/trunk-merge/Do" ctype="CSharpProjectParameters" />
31 <Deployment.LinuxDeployData scriptName="gnome-do" />
32
33=== modified file 'Do/Makefile.am'
34--- Do/Makefile.am 2009-03-22 05:41:46 +0000
35+++ Do/Makefile.am 2009-04-21 22:18:57 +0000
36@@ -88,7 +88,8 @@
37 $(MONO_ADDINS_SETUP_LIBS) \
38 $(NUNIT_LIBS) \
39 System \
40- System.Core
41+ System.Core \
42+ System.Xml
43
44 PROJECT_REFERENCES = \
45 Do.Universe \
46@@ -103,7 +104,7 @@
47 CLEANFILES += Do.exe.config gnome-do
48 EXTRA_DIST += Do.exe.config.in gnome-do.in
49
50-module_DATA += Do.exe.config
51+module_DATA += Do.exe.config Do.addins
52 bin_SCRIPTS = gnome-do
53
54 MCS_FLAGS += -unsafe
55
56=== modified file 'Do/gtk-gui/gui.stetic'
57--- Do/gtk-gui/gui.stetic 2009-03-06 07:14:21 +0000
58+++ Do/gtk-gui/gui.stetic 2009-04-22 02:17:30 +0000
59@@ -5,7 +5,7 @@
60 <target-gtk-version>2.12</target-gtk-version>
61 </configuration>
62 <import>
63- <widget-library name="Mono.Addins.Gui, Version=0.3.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" />
64+ <widget-library name="Mono.Addins.Gui, Version=0.4.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" />
65 <widget-library name="../bin/Debug/Do.exe" internal="true" />
66 </import>
67 <widget class="Gtk.Window" id="Do.UI.PreferencesWindow" design-size="450 470">
68@@ -1011,7 +1011,7 @@
69 <child internal-child="VBox">
70 <widget class="Gtk.VBox" id="dialog1_VBox">
71 <property name="MemberName" />
72- <property name="BorderWidth">5</property>
73+ <property name="BorderWidth">2</property>
74 <child>
75 <widget class="Gtk.VBox" id="vbox2">
76 <property name="MemberName" />
77@@ -1119,7 +1119,7 @@
78 <child internal-child="ActionArea">
79 <widget class="Gtk.HButtonBox" id="dialog1_ActionArea">
80 <property name="MemberName" />
81- <property name="Spacing">10</property>
82+ <property name="Spacing">6</property>
83 <property name="BorderWidth">5</property>
84 <property name="Size">1</property>
85 <property name="LayoutStyle">End</property>
86
87=== modified file 'Do/gtk-gui/objects.xml'
88--- Do/gtk-gui/objects.xml 2009-04-18 03:12:46 +0000
89+++ Do/gtk-gui/objects.xml 2009-04-21 22:18:57 +0000
90@@ -1,2 +1,14 @@
91 <objects attr-sync="on">
92+ <object type="Do.UI.KeybindingsPreferencesWidget" palette-category="Do" allow-children="false" base-type="Gtk.Bin">
93+ <itemgroups />
94+ <signals />
95+ </object>
96+ <object type="Do.UI.GeneralPreferencesWidget" palette-category="Do" allow-children="false" base-type="Gtk.Bin">
97+ <itemgroups />
98+ <signals />
99+ </object>
100+ <object type="Do.UI.ManagePluginsPreferencesWidget" palette-category="Do" allow-children="false" base-type="Gtk.Bin">
101+ <itemgroups />
102+ <signals />
103+ </object>
104 </objects>
105\ No newline at end of file
106
107=== modified file 'Do/src/Do.Core/Paths.cs'
108--- Do/src/Do.Core/Paths.cs 2009-01-11 00:00:14 +0000
109+++ Do/src/Do.Core/Paths.cs 2009-04-22 02:51:50 +0000
110@@ -29,50 +29,22 @@
111
112 internal static class Paths
113 {
114+ const string PluginsDirectory = "plugins";
115 const string ApplicationDirectory = "gnome-do";
116- const string PluginsDirectory = "plugins";
117- const string RepositoryIndicatorFile = "main.mrep";
118+ const string DefaultAddinsDirectory = "addins";
119
120 //// <value>
121 /// Directory where Do saves its Mono.Addins repository cache.
122 /// </value>
123 public static string UserPluginsDirectory {
124 get {
125- string userData =
126- Environment.GetFolderPath (Environment.SpecialFolder.LocalApplicationData);
127- string pluginDirectory
128- = string.Format ("{0}-{1}", PluginsDirectory, AssemblyInfo.DisplayVersion);
129- return userData.Combine (ApplicationDirectory, pluginDirectory);
130- }
131- }
132-
133- //// <value>
134- /// Directories where Do looks for Mono.Addins repositories. These
135- /// directories exist and probably contain valid repositories.
136- /// </value>
137- public static IEnumerable<string> SystemPluginDirectories {
138- get {
139- foreach (string repository in MaybeSystemPluginDirectories) {
140- if (File.Exists (Path.Combine (repository, RepositoryIndicatorFile)))
141- yield return repository;
142- }
143- }
144- }
145-
146- //// <value>
147- /// Directories where Do might look for Mono.Addins repositories; these
148- /// directories may not exist or may not be valid repositories.
149- /// </value>
150- static IEnumerable<string> MaybeSystemPluginDirectories {
151- get {
152- yield return AppDomain.CurrentDomain.BaseDirectory.Combine (PluginsDirectory);
153-
154- string systemData =
155- Environment.GetFolderPath (Environment.SpecialFolder.CommonApplicationData);
156- yield return systemData.Combine (ApplicationDirectory, PluginsDirectory);
157- yield return "/usr/local/share".Combine (ApplicationDirectory, PluginsDirectory);
158+ string userData = Environment.GetFolderPath (Environment.SpecialFolder.LocalApplicationData);
159+ return userData.Combine (ApplicationDirectory, PluginsDirectory);
160 }
161 }
162
163+ public static string UserAddinInstallationDirectory {
164+ get { return UserPluginsDirectory.Combine (DefaultAddinsDirectory); }
165+ }
166 }
167 }
168
169=== modified file 'Do/src/Do.Core/PluginManager.cs'
170--- Do/src/Do.Core/PluginManager.cs 2009-01-18 19:59:39 +0000
171+++ Do/src/Do.Core/PluginManager.cs 2009-04-22 02:17:30 +0000
172@@ -20,6 +20,7 @@
173
174 using System;
175 using System.IO;
176+using System.Xml;
177 using System.Linq;
178 using System.Collections.Generic;
179
180@@ -54,25 +55,28 @@
181 new CommunityAddinClassifier (),
182 new GreedyAddinClassifier (),
183 };
184-
185+
186 /// <summary>
187 /// Performs plugin system initialization. Should be called before this
188 /// class or any Mono.Addins class is used. The ordering is very delicate.
189 /// </summary>
190 public static void Initialize ()
191 {
192+ IEnumerable<string> savedPlugins = PluginsEnabledBeforeLoad ();
193+
194 // Initialize Mono.Addins.
195 AddinManager.Initialize (Paths.UserPluginsDirectory);
196-
197- // Register repositories.
198- SetupService setup = new SetupService (AddinManager.Registry);
199- foreach (string path in Paths.SystemPluginDirectories) {
200- string url = "file://" + path;
201- if (!setup.Repositories.ContainsRepository (url)) {
202- setup.Repositories.RegisterRepository (null, url, false);
203- }
204- }
205-
206+ // This is a workaround for a Mono.Addins bug where updated addins will get
207+ // disabled on update. We save the currently enabled addins, update, then
208+ // reenable them with the Id of the new version. It's a bit hackish but lluis
209+ // said it's a reasonable approach until that bug is fixed
210+ // https://bugzilla.novell.com/show_bug.cgi?id=490302
211+ if (CorePreferences.PeekDebug)
212+ AddinManager.Registry.Rebuild (null);
213+ else
214+ AddinManager.Registry.Update (null);
215+ EnableDisabledPlugins (savedPlugins);
216+
217 // Initialize services before addins that may use them are loaded.
218 Services.Initialize ();
219 InterfaceManager.Initialize ();
220@@ -80,8 +84,24 @@
221 // Now allow loading of non-services.
222 foreach (string path in ExtensionPaths)
223 AddinManager.AddExtensionNodeHandler (path, OnPluginChanged);
224-
225- InstallLocalPlugins (setup);
226+ }
227+
228+ public static void InstallLocalPlugins ()
229+ {
230+ string [] manual;
231+ IEnumerable<string> saved;
232+
233+ manual = Directory.GetFiles (Paths.UserAddinInstallationDirectory, "*.dll");
234+ for (int i = 0; i < manual.Length; i++) {
235+ manual [i] = Path.GetFileName (manual [i]);
236+ }
237+
238+ AddinManager.Registry.Rebuild (null);
239+ saved = AddinManager.Registry.GetAddins ()
240+ .Where (addin => manual.Contains (Path.GetFileName (addin.AddinFile)))
241+ .Select (addin => addin.Id);
242+
243+ EnableDisabledPlugins (saved);
244 }
245
246 public static bool PluginClassifiesAs (AddinRepositoryEntry entry, string className)
247@@ -139,35 +159,67 @@
248 public static IEnumerable<Act> Actions {
249 get { return AddinManager.GetExtensionObjects ("/Do/Action").OfType<Act> (); }
250 }
251-
252+
253 /// <summary>
254- /// Installs plugins that are located in the <see
255- /// cref="Paths.UserPlugins"/> directory. This will build addins
256- /// (mpack files) and install them.
257+ /// Returns a list of the plugins that were enabled before Mono.Addins was initialised.
258+ /// this is read from config.xml.
259 /// </summary>
260- /// <param name="setup">
261- /// A <see cref="SetupService"/>
262- /// </param>
263- public static void InstallLocalPlugins (SetupService setup)
264- {
265- IProgressStatus status = new ConsoleProgressStatus (false);
266- // GetFilePaths is like Directory.GetFiles but returned files have directory prefixed.
267- Func<string, string, IEnumerable<string>> GetFilePaths = (dir, pattern) =>
268- Directory.GetFiles (dir, pattern).Select (f => Path.Combine (dir, f));
269-
270- // Create mpack (addin packages) out of dlls.
271- GetFilePaths (Paths.UserPluginsDirectory, "*.dll")
272- .ForEach (path => setup.BuildPackage (status, Paths.UserPluginsDirectory, new[] { path }))
273- // We delete the dlls after creating mpacks so we don't delete any dlls prematurely.
274- .ForEach (File.Delete);
275+ /// <returns>
276+ /// A <see cref="IEnumerable"/> of strings containing the versionless plugin id of all
277+ /// enabled plugins.
278+ /// </returns>
279+ static IEnumerable<string> PluginsEnabledBeforeLoad ()
280+ {
281+ XmlTextReader reader;
282+ List<string> plugins;
283+
284+ plugins = new List<string> ();
285+
286+ try {
287+ // set up the reader by loading file, telling it that whitespace doesn't matter, and the DTD is irrelevant
288+ reader = new XmlTextReader (Paths.UserPluginsDirectory.Combine ("addin-db-001", "config.xml"));
289+ reader.XmlResolver = null;
290+ reader.WhitespaceHandling = WhitespaceHandling.None;
291+ reader.MoveToContent ();
292+
293+ if (string.IsNullOrEmpty (reader.Name))
294+ return Enumerable.Empty<string> ();
295+
296+ while (reader.Read ()) {
297+ string id;
298+ if (reader.NodeType != XmlNodeType.Element || !reader.HasAttributes)
299+ continue;
300+
301+ reader.MoveToAttribute ("id");
302+ id = AddinIdWithoutVersion (reader.Value);
303+
304+ if (string.IsNullOrEmpty (id))
305+ continue;
306+
307+ reader.MoveToAttribute ("enabled");
308+
309+ if (Boolean.Parse (reader.Value))
310+ plugins.Add (id);
311+ }
312+ } catch (FileNotFoundException e) {
313+ Log.Debug ("Could not find locate Mono.Addins config.xml: {0}", e.Message);
314+ } catch (XmlException e) {
315+ Log.Error ("Error while parsing Mono.Addins config.xml: {0}", e.Message);
316+ Log.Debug (e.StackTrace);
317+ }
318+
319+ return plugins;
320+ }
321+
322+ static void EnableDisabledPlugins (IEnumerable<string> savedPlugins)
323+ {
324+ foreach (Addin addin in AddinManager.Registry.GetAddins ()) {
325+ string id = addin.Id;
326+ if (!AddinManager.Registry.IsAddinEnabled (id) && savedPlugins.Any (name => id.StartsWith (name)))
327+ AddinManager.Registry.EnableAddin (id);
328+ }
329+ }
330
331- // Install each mpack file, deleting each file when finished installing it.
332- foreach (string path in GetFilePaths (Paths.UserPluginsDirectory, "*.mpack")) {
333- setup.Install (status, new[] { path });
334- File.Delete (path);
335- }
336- }
337-
338 static void OnPluginChanged (object sender, ExtensionNodeEventArgs args)
339 {
340 TypeExtensionNode node = args.ExtensionNode as TypeExtensionNode;
341@@ -244,5 +296,10 @@
342 {
343 return ObjectsForAddin<IConfigurable> (id);
344 }
345+
346+ static string AddinIdWithoutVersion (string id)
347+ {
348+ return id.Substring (0, id.IndexOf (','));
349+ }
350 }
351 }
352
353=== modified file 'Do/src/Do.UI/ManagePluginsPreferencesWidget.cs'
354--- Do/src/Do.UI/ManagePluginsPreferencesWidget.cs 2009-02-19 03:09:17 +0000
355+++ Do/src/Do.UI/ManagePluginsPreferencesWidget.cs 2009-04-22 02:17:30 +0000
356@@ -25,10 +25,9 @@
357 using System.Collections.Generic;
358
359 using Gtk;
360-using Mono.Unix;
361 using Mono.Addins;
362-using Mono.Addins.Gui;
363 using Mono.Addins.Setup;
364+using Mono.Unix;
365
366 using Do;
367 using Do.Core;
368@@ -44,8 +43,7 @@
369 public partial class ManagePluginsPreferencesWidget : Bin, IConfigurable
370 {
371
372- const string PluginWikiPageFormat =
373- "http://do.davebsd.com/wiki/index.php?title={0}_Plugin";
374+ const string PluginWikiPageFormat = "http://do.davebsd.com/wiki/index.php?title={0}_Plugin";
375
376 PluginNodeView nview;
377 SearchEntry search_entry;
378@@ -92,44 +90,56 @@
379 search_entry.Show();
380 search_entry.Ready = true;
381
382- hbox1.PackStart (search_entry,true,true,0);
383- hbox1.ShowAll();
384+ hbox1.PackStart (search_entry, true, true, 0);
385+ hbox1.ShowAll ();
386
387- Services.Application.RunOnMainThread (() =>
388- search_entry.InnerEntry.GrabFocus ()
389- );
390+ Services.Application.RunOnMainThread (() => search_entry.InnerEntry.GrabFocus ());
391 }
392
393 protected void OnDragDataReceived (object sender, DragDataReceivedArgs args)
394 {
395- string data = Encoding.UTF8.GetString (args.SelectionData.Data);
396+ string data;
397+ string [] uriList;
398+ List<string> errors;
399+
400+ data = Encoding.UTF8.GetString (args.SelectionData.Data);
401 // Sometimes we get a null at the end, and it crashes us.
402 data = data.TrimEnd ('\0');
403
404- string [] uriList = Regex.Split (data, "\r\n");
405- List<string> errors = new List<string> ();
406+ errors = new List<string> ();
407+ uriList = Regex.Split (data, "\r\n");
408+
409 foreach (string uri in uriList) {
410- string file;
411- string path;
412+ string file, path, filename;
413
414+ if (string.IsNullOrEmpty (uri))
415+ continue;
416+
417 try {
418- file = uri.Remove (0, 7);
419- string fileName = System.IO.Path.GetFileName (file);
420+ file = uri.Remove (0, 7); // 7 is the length of file://
421+ // I have to use System.IO here due to a Gtk namespace conflict
422+ filename = System.IO.Path.GetFileName (file);
423+
424 if (!file.EndsWith (".dll")) {
425- errors.Add (fileName);
426+ errors.Add (filename);
427 continue;
428 }
429
430- path = Paths.UserPluginsDirectory.Combine (fileName);
431+ if (!Directory.Exists (Paths.UserAddinInstallationDirectory))
432+ Directory.CreateDirectory (Paths.UserAddinInstallationDirectory);
433+
434+ path = Paths.UserAddinInstallationDirectory.Combine (filename);
435 File.Copy (file, path, true);
436- } catch { }
437+
438+ if (errors.Count > 0)
439+ new PluginErrorDialog (errors.ToArray ());
440+
441+ PluginManager.InstallLocalPlugins ();
442+ } catch (Exception e) {
443+ Log<ManagePluginsPreferencesWidget>.Error ("An unexpected error occurred installing your plugin");
444+ Log<ManagePluginsPreferencesWidget>.Debug ("{0}\n{1}", e.Message, e.StackTrace);
445+ }
446 }
447-
448- if (errors.Count > 0)
449- new PluginErrorDialog (errors.ToArray ());
450-
451- SetupService setup = new SetupService (AddinManager.Registry);
452- PluginManager.InstallLocalPlugins (setup);
453 }
454
455 public Bin GetConfiguration ()
456
457=== modified file 'Do/src/Do.UI/PluginErrorDialog.cs'
458--- Do/src/Do.UI/PluginErrorDialog.cs 2008-10-25 03:53:44 +0000
459+++ Do/src/Do.UI/PluginErrorDialog.cs 2009-04-22 02:17:30 +0000
460@@ -29,12 +29,12 @@
461
462 public PluginErrorDialog(string[] files)
463 {
464+ string errorMessage = Catalog.GetString ("<b><span size=\"large\">There was an error installing the selected {0}</span></b>");
465+
466 this.Build();
467
468- if (files.Length > 1)
469- header_lbl.Markup = Catalog.GetString ("<b><span size=\"large\">There was an error installing the selected plugins</span></b>");
470- else
471- header_lbl.Markup = Catalog.GetString ("<b><span size=\"large\">There was an error installing the selected plugin</span></b>");
472+ header_lbl.Markup = Catalog.GetPluralString (string.Format (errorMessage, Catalog.GetString ("plugin")),
473+ string.Format (errorMessage, Catalog.GetString ("plugins")), files.Length);
474
475 string errors = "";
476 for (int i = 0; i < files.Length; i++) {
477
478=== modified file 'Do/src/Do.UI/PreferencesWindow.cs'
479--- Do/src/Do.UI/PreferencesWindow.cs 2009-01-05 22:19:09 +0000
480+++ Do/src/Do.UI/PreferencesWindow.cs 2009-04-22 02:17:30 +0000
481@@ -51,9 +51,7 @@
482
483 btn_close.IsFocus = true;
484
485- TargetEntry [] targets = {
486- new TargetEntry ("text/uri-list", 0, 0),
487- };
488+ TargetEntry [] targets = { new TargetEntry ("text/uri-list", 0, 0) };
489 Drag.DestSet (this, DestDefaults.All, targets, Gdk.DragAction.Copy);
490
491 // Add notebook pages.