~do-win/do/test-paths

« back to all changes in this revision

Viewing changes to Mono.Addins.Setup/Mono.Addins.Setup/.svn/text-base/SetupTool.cs.svn-base

  • Committer: Chris S.
  • Date: 2009-06-21 03:37:34 UTC
  • Revision ID: chris@szikszoy.com-20090621033734-ud2jdcd5pq9r3ue9
initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// mdsetup.cs
 
3
//
 
4
// Author:
 
5
//   Lluis Sanchez Gual
 
6
//
 
7
// Copyright (C) 2007 Novell, Inc (http://www.novell.com)
 
8
//
 
9
// Permission is hereby granted, free of charge, to any person obtaining
 
10
// a copy of this software and associated documentation files (the
 
11
// "Software"), to deal in the Software without restriction, including
 
12
// without limitation the rights to use, copy, modify, merge, publish,
 
13
// distribute, sublicense, and/or sell copies of the Software, and to
 
14
// permit persons to whom the Software is furnished to do so, subject to
 
15
// the following conditions:
 
16
// 
 
17
// The above copyright notice and this permission notice shall be
 
18
// included in all copies or substantial portions of the Software.
 
19
// 
 
20
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 
21
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
22
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 
23
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 
24
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 
25
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 
26
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
27
//
 
28
 
 
29
 
 
30
using System;
 
31
using System.Xml;
 
32
using System.Collections;
 
33
using Mono.Addins;
 
34
using Mono.Addins.Setup.ProgressMonitoring;
 
35
using Mono.Addins.Setup;
 
36
using System.IO;
 
37
using Mono.Addins.Description;
 
38
 
 
39
namespace Mono.Addins.Setup
 
40
{
 
41
        public class SetupTool
 
42
        {
 
43
                Hashtable options = new Hashtable ();
 
44
                string[] arguments;
 
45
                string applicationName = "Mono";
 
46
                SetupService service;
 
47
                AddinRegistry registry;
 
48
                ArrayList commands = new ArrayList ();
 
49
                string setupAppName = "";
 
50
                int uniqueId = 0;
 
51
                
 
52
                bool verbose;
 
53
                
 
54
                public SetupTool (AddinRegistry registry)
 
55
                {
 
56
                        this.registry = registry;
 
57
                        service = new SetupService (registry);
 
58
                        CreateCommands ();
 
59
                }
 
60
                
 
61
                public string ApplicationName {
 
62
                        get { return applicationName; }
 
63
                        set { applicationName = value; }
 
64
                }
 
65
                
 
66
                public string ApplicationNamespace {
 
67
                        get { return service.ApplicationNamespace; }
 
68
                        set { service.ApplicationNamespace = value; }
 
69
                }
 
70
                
 
71
                public bool VerboseOutput {
 
72
                        get { return verbose; }
 
73
                        set { verbose = value; }
 
74
                }
 
75
 
 
76
                public int Run (string[] args, int firstArgumentIndex)
 
77
                {
 
78
                        string[] aa = new string [args.Length - firstArgumentIndex];
 
79
                        Array.Copy (args, firstArgumentIndex, aa, 0, aa.Length);
 
80
                        return Run (aa);
 
81
                }
 
82
                
 
83
                public int Run (string[] args)
 
84
                {
 
85
                        if (args.Length == 0) {
 
86
                                PrintHelp ();
 
87
                                return 0;
 
88
                        }
 
89
                        
 
90
                        string[] parms = new string [args.Length - 1];
 
91
                        Array.Copy (args, 1, parms, 0, args.Length - 1);
 
92
                        
 
93
                        try {
 
94
                                ReadOptions (parms);
 
95
                                verbose = verbose || HasOption ("v");
 
96
                                return RunCommand (args [0], parms);
 
97
                        } catch (InstallException ex) {
 
98
                                Console.WriteLine (ex.Message);
 
99
                                return -1;
 
100
                        }
 
101
                }
 
102
                
 
103
                int RunCommand (string cmd, string[] parms)
 
104
                {
 
105
                        SetupCommand cc = FindCommand (cmd);
 
106
                        if (cc != null) {
 
107
                                cc.Handler (parms);
 
108
                                return 0;
 
109
                        }
 
110
                        else {
 
111
                                Console.WriteLine ("Unknown command: " + cmd);
 
112
                                return 1;
 
113
                        }
 
114
                }
 
115
                
 
116
                void Install (string[] args)
 
117
                {
 
118
                        if (args.Length < 1) {
 
119
                                PrintHelp ("install");
 
120
                                return;
 
121
                        }
 
122
                        
 
123
                        PackageCollection packs = new PackageCollection ();
 
124
                        for (int n=0; n<args.Length; n++) {
 
125
                                if (File.Exists (args [n])) { 
 
126
                                        packs.Add (AddinPackage.FromFile (args [n]));
 
127
                                } else {
 
128
                                        string aname = Addin.GetIdName (GetFullId (args[n]));
 
129
                                        string aversion = Addin.GetIdVersion (args[n]);
 
130
                                        if (aversion.Length == 0) aversion = null;
 
131
                                        
 
132
                                        AddinRepositoryEntry[] ads = service.Repositories.GetAvailableAddin (aname, aversion);
 
133
                                        if (ads.Length == 0)
 
134
                                                throw new InstallException ("The addin '" + args[n] + "' is not available for install.");
 
135
                                        packs.Add (AddinPackage.FromRepository (ads[ads.Length-1]));
 
136
                                }
 
137
                        }
 
138
                        Install (packs, true);
 
139
                }
 
140
                
 
141
                void CheckInstall (string[] args)
 
142
                {
 
143
                        if (args.Length < 1) {
 
144
                                PrintHelp ("check-install");
 
145
                                return;
 
146
                        }
 
147
                        
 
148
                        PackageCollection packs = new PackageCollection ();
 
149
                        for (int n=0; n<args.Length; n++) {
 
150
                                Addin addin = registry.GetAddin (GetFullId (args[n]));
 
151
                                if (addin != null)
 
152
                                        continue;
 
153
                                string aname = Addin.GetIdName (GetFullId (args[n]));
 
154
                                string aversion = Addin.GetIdVersion (args[n]);
 
155
                                if (aversion.Length == 0) aversion = null;
 
156
                                
 
157
                                AddinRepositoryEntry[] ads = service.Repositories.GetAvailableAddin (aname, aversion);
 
158
                                if (ads.Length == 0)
 
159
                                        throw new InstallException ("The addin '" + args[n] + "' is not available for install.");
 
160
                                packs.Add (AddinPackage.FromRepository (ads[ads.Length-1]));
 
161
                        }
 
162
                        Install (packs, false);
 
163
                }
 
164
                
 
165
                void Install (PackageCollection packs, bool prompt)
 
166
                {
 
167
                        PackageCollection toUninstall;
 
168
                        DependencyCollection unresolved;
 
169
                        
 
170
                        IProgressStatus m = new ConsoleProgressStatus (verbose);
 
171
                        int n = packs.Count;
 
172
                        if (!service.Store.ResolveDependencies (m, packs, out toUninstall, out unresolved))
 
173
                                throw new InstallException ("Not all dependencies could be resolved.");
 
174
 
 
175
                        bool ask = false;
 
176
                        if (prompt && (packs.Count != n || toUninstall.Count != 0)) {
 
177
                                Console.WriteLine ("The following packages will be installed:");
 
178
                                foreach (Package p in packs)
 
179
                                        Console.WriteLine (" - " + p.Name);
 
180
                                ask = true;
 
181
                        }
 
182
                        if (prompt && (toUninstall.Count != 0)) {
 
183
                                Console.WriteLine ("The following packages need to be uninstalled:");
 
184
                                foreach (Package p in toUninstall)
 
185
                                        Console.WriteLine (" - " + p.Name);
 
186
                                ask = true;
 
187
                        }
 
188
                        if (ask) {
 
189
                                Console.WriteLine ();
 
190
                                Console.Write ("Are you sure you want to continue? (y/N): ");
 
191
                                string res = Console.ReadLine ();
 
192
                                if (res != "y" && res != "Y")
 
193
                                        return;
 
194
                        }
 
195
                        
 
196
                        if (!service.Store.Install (m, packs)) {
 
197
                                Console.WriteLine ("Install operation failed.");
 
198
                        }
 
199
                }
 
200
                
 
201
                void Uninstall (string[] args)
 
202
                {
 
203
                        if (args.Length < 1)
 
204
                                throw new InstallException ("The add-in id is required.");
 
205
                        
 
206
                        Addin ads = registry.GetAddin (GetFullId (args[0]));
 
207
                        if (ads == null)
 
208
                                throw new InstallException ("The add-in '" + args[0] + "' is not installed.");
 
209
                        if (!ads.Description.CanUninstall)
 
210
                                throw new InstallException ("The add-in '" + args[0] + "' is protected and can't be uninstalled.");
 
211
                        
 
212
                        Console.WriteLine ("The following add-ins will be uninstalled:");
 
213
                        Console.WriteLine (" - " + ads.Description.Name);
 
214
                        foreach (Addin si in service.GetDependentAddins (args[0], true))
 
215
                                Console.WriteLine (" - " + si.Description.Name);
 
216
                        
 
217
                        Console.WriteLine ();
 
218
                        Console.Write ("Are you sure you want to continue? (y/N): ");
 
219
                        string res = Console.ReadLine ();
 
220
                        if (res == "y" || res == "Y")
 
221
                                service.Uninstall (new ConsoleProgressStatus (verbose), ads.Id);
 
222
                }
 
223
                
 
224
                bool IsHidden (Addin ainfo)
 
225
                {
 
226
                        return service.ApplicationNamespace != null && !(ainfo.Namespace + ".").StartsWith (service.ApplicationNamespace + ".") || ainfo.Description.IsHidden;
 
227
                }
 
228
                
 
229
                bool IsHidden (AddinHeader ainfo)
 
230
                {
 
231
                        return service.ApplicationNamespace != null && !(ainfo.Namespace + ".").StartsWith (service.ApplicationNamespace + ".");
 
232
                }
 
233
                
 
234
                string GetId (AddinHeader ainfo)
 
235
                {
 
236
                        if (service.ApplicationNamespace != null && (ainfo.Namespace + ".").StartsWith (service.ApplicationNamespace + "."))
 
237
                                return ainfo.Id.Substring (service.ApplicationNamespace.Length + 1);
 
238
                        else
 
239
                                return ainfo.Id;
 
240
                }
 
241
                
 
242
                string GetFullId (string id)
 
243
                {
 
244
                        if (service.ApplicationNamespace != null)
 
245
                                return service.ApplicationNamespace + "." + id;
 
246
                        else
 
247
                                return id;
 
248
                }
 
249
                
 
250
                void ListInstalled (string[] args)
 
251
                {
 
252
                        IList alist = args;
 
253
                        bool showAll = alist.Contains ("-a");
 
254
                        Console.WriteLine ("Installed add-ins:");
 
255
                        ArrayList list = new ArrayList ();
 
256
                        list.AddRange (registry.GetAddins ());
 
257
                        if (alist.Contains ("-r"))
 
258
                                list.AddRange (registry.GetAddinRoots ());
 
259
                        foreach (Addin addin in list) {
 
260
                                if (!showAll && IsHidden (addin))
 
261
                                        continue;
 
262
                                Console.Write (" - " + addin.Name + " " + addin.Version);
 
263
                                if (showAll)
 
264
                                        Console.Write (" (" + addin.AddinFile + ")");
 
265
                                Console.WriteLine ();
 
266
                        }
 
267
                }
 
268
                
 
269
                void ListAvailable (string[] args)
 
270
                {
 
271
                        bool showAll = args.Length > 0 && args [0] == "-a";
 
272
                        Console.WriteLine ("Available add-ins:");
 
273
                        AddinRepositoryEntry[] addins = service.Repositories.GetAvailableAddins ();
 
274
                        foreach (PackageRepositoryEntry addin in addins) {
 
275
                                if (!showAll && IsHidden (addin.Addin))
 
276
                                        continue;
 
277
                                Console.WriteLine (" - " + GetId (addin.Addin) + " (" + addin.Repository.Name + ")");
 
278
                        }
 
279
                }
 
280
                
 
281
                void ListUpdates (string[] args)
 
282
                {
 
283
                        bool showAll = args.Length > 0 && args [0] == "-a";
 
284
                        
 
285
                        Console.WriteLine ("Looking for updates...");
 
286
                        service.Repositories.UpdateAllRepositories (null);
 
287
                        Console.WriteLine ("Available add-in updates:");
 
288
                        AddinRepositoryEntry[] addins = service.Repositories.GetAvailableAddins ();
 
289
                        bool found = false;
 
290
                        foreach (PackageRepositoryEntry addin in addins) {
 
291
                                Addin sinfo = registry.GetAddin (addin.Addin.Id);
 
292
                                if (!showAll && IsHidden (sinfo))
 
293
                                        continue;
 
294
                                if (sinfo != null && Addin.CompareVersions (sinfo.Version, addin.Addin.Version) == 1) {
 
295
                                        Console.WriteLine (" - " + addin.Addin.Id + " " + addin.Addin.Version + " (" + addin.Repository.Name + ")");
 
296
                                        found = true;
 
297
                                }
 
298
                        }
 
299
                        if (!found)
 
300
                                Console.WriteLine ("No updates found.");
 
301
                }
 
302
                
 
303
                void Update (string [] args)
 
304
                {
 
305
                        bool showAll = args.Length > 0 && args [0] == "-a";
 
306
                        
 
307
                        Console.WriteLine ("Looking for updates...");
 
308
                        service.Repositories.UpdateAllRepositories (null);
 
309
                        
 
310
                        PackageCollection packs = new PackageCollection ();
 
311
                        AddinRepositoryEntry[] addins = service.Repositories.GetAvailableAddins ();
 
312
                        foreach (PackageRepositoryEntry addin in addins) {
 
313
                                Addin sinfo = registry.GetAddin (addin.Addin.Id);
 
314
                                if (!showAll && IsHidden (sinfo))
 
315
                                        continue;
 
316
                                if (sinfo != null && Addin.CompareVersions (sinfo.Version, addin.Addin.Version) == 1)
 
317
                                        packs.Add (AddinPackage.FromRepository (addin));
 
318
                        }
 
319
                        if (packs.Count > 0)
 
320
                                Install (packs, true);
 
321
                        else
 
322
                                Console.WriteLine ("No updates found.");
 
323
                }
 
324
                
 
325
                void UpdateAvailableAddins (string[] args)
 
326
                {
 
327
                        service.Repositories.UpdateAllRepositories (new ConsoleProgressStatus (verbose));
 
328
                }
 
329
                
 
330
                void AddRepository (string[] args)
 
331
                {
 
332
                        foreach (string rep in args)
 
333
                                service.Repositories.RegisterRepository (new ConsoleProgressStatus (verbose), rep);
 
334
                }
 
335
                
 
336
                void RemoveRepository (string[] args)
 
337
                {
 
338
                        foreach (string rep in args)
 
339
                                service.Repositories.RemoveRepository (rep);
 
340
                }
 
341
                
 
342
                void ListRepositories (string[] args)
 
343
                {
 
344
                        AddinRepository[] reps = service.Repositories.GetRepositories ();
 
345
                        if (reps.Length == 0) {
 
346
                                Console.WriteLine ("No repositories have been registered.");
 
347
                                return;
 
348
                        }
 
349
                        Console.WriteLine ("Registered repositories:");
 
350
                        foreach (RepositoryRecord rep in reps) {
 
351
                                Console.WriteLine (" - " + rep.Title);
 
352
                        }
 
353
                }
 
354
                
 
355
                void BuildRepository (string[] args)
 
356
                {
 
357
                        if (args.Length < 1)
 
358
                                throw new InstallException ("A directory name is required.");
 
359
                        service.BuildRepository (new ConsoleProgressStatus (verbose), args[0]);
 
360
                }
 
361
                
 
362
                void BuildPackage (string[] args)
 
363
                {
 
364
                        if (args.Length < 1)
 
365
                                throw new InstallException ("A file name is required.");
 
366
                                
 
367
                        service.BuildPackage (new ConsoleProgressStatus (verbose), GetOption ("d", "."), GetArguments ());
 
368
                }
 
369
                
 
370
                void UpdateRegistry (string[] args)
 
371
                {
 
372
                        registry.Update (new ConsoleProgressStatus (verbose));
 
373
                }
 
374
                
 
375
                void RepairRegistry (string[] args)
 
376
                {
 
377
                        registry.Rebuild (new ConsoleProgressStatus (verbose));
 
378
                }
 
379
                
 
380
                void DumpRegistryFile (string[] args)
 
381
                {
 
382
                        if (args.Length < 1)
 
383
                                throw new InstallException ("A file name is required.");
 
384
                        registry.DumpFile (args[0]);
 
385
                }
 
386
                
 
387
                void PrintAddinInfo (string[] args)
 
388
                {
 
389
                        bool generateXml = false;
 
390
                        bool generateAll = false;
 
391
                        bool pickNamespace = false;
 
392
                        bool extensionModel = true;
 
393
                        
 
394
                        ArrayList addins = new ArrayList ();
 
395
                        ArrayList namespaces = new ArrayList ();
 
396
                        
 
397
                        foreach (string a in args) {
 
398
                                if (pickNamespace) {
 
399
                                        namespaces.Add (a);
 
400
                                        pickNamespace = false;
 
401
                                        continue;
 
402
                                }
 
403
                                if (a == "--xml") {
 
404
                                        generateXml = true;
 
405
                                        continue;
 
406
                                }
 
407
                                if (a == "--namespace" || a == "-n") {
 
408
                                        pickNamespace = true;
 
409
                                        continue;
 
410
                                }
 
411
                                if (a == "--all") {
 
412
                                        generateAll = true;
 
413
                                        continue;
 
414
                                }
 
415
                                if (a == "--full") {
 
416
                                        extensionModel = false;
 
417
                                        continue;
 
418
                                }
 
419
                                AddinDescription desc = null;
 
420
                                if (File.Exists (args[0]))
 
421
                                        desc = registry.GetAddinDescription (new Mono.Addins.ConsoleProgressStatus (verbose), args[0]);
 
422
                                else {
 
423
                                        Addin addin = registry.GetAddin (args [0]);
 
424
                                        if (addin != null)
 
425
                                                desc = addin.Description;
 
426
                                }
 
427
                                if (desc == null)
 
428
                                        throw new InstallException (string.Format ("Add-in '{0}' not found.", a));
 
429
                                if (desc != null)
 
430
                                        addins.Add (desc);
 
431
                        }
 
432
                        
 
433
                        if (generateAll) {
 
434
                                ArrayList list = new ArrayList ();
 
435
                                list.AddRange (registry.GetAddinRoots ());
 
436
                                list.AddRange (registry.GetAddins ());
 
437
                                foreach (Addin addin in list) {
 
438
                                        if (namespaces.Count > 0) {
 
439
                                                foreach (string ns in namespaces) {
 
440
                                                        if (addin.Id.StartsWith (ns + ".")) {
 
441
                                                                addins.Add (addin.Description);
 
442
                                                                break;
 
443
                                                        }
 
444
                                                }
 
445
                                        } else {
 
446
                                                addins.Add (addin.Description);
 
447
                                        }
 
448
                                }
 
449
                        }
 
450
                        
 
451
                        if (addins.Count == 0)
 
452
                                throw new InstallException ("A file name or add-in ID is required.");
 
453
                        
 
454
                        
 
455
                        if (generateXml) {
 
456
                                XmlTextWriter tw = new XmlTextWriter (Console.Out);
 
457
                                tw.Formatting = Formatting.Indented;
 
458
                                tw.WriteStartElement ("Addins");
 
459
                                foreach (AddinDescription desc in addins) {
 
460
                                        if (extensionModel && desc.ExtensionPoints.Count == 0)
 
461
                                                continue;
 
462
                                        PrintAddinXml (tw, desc);
 
463
                                }
 
464
                                tw.Close ();
 
465
                        }
 
466
                        else {
 
467
                                foreach (AddinDescription des in addins)
 
468
                                        PrintAddin (des);
 
469
                        }
 
470
                }
 
471
                
 
472
                void PrintAddinXml (XmlWriter tw, AddinDescription desc)
 
473
                {
 
474
                        tw.WriteStartElement ("Addin");
 
475
                        tw.WriteAttributeString ("name", desc.Name);
 
476
                        tw.WriteAttributeString ("addinId", desc.LocalId);
 
477
                        tw.WriteAttributeString ("fullId", desc.AddinId);
 
478
                        tw.WriteAttributeString ("id", "addin_" + uniqueId);
 
479
                        uniqueId++;
 
480
                        if (desc.Namespace.Length > 0)
 
481
                                tw.WriteAttributeString ("namespace", desc.Namespace);
 
482
                        tw.WriteAttributeString ("isroot", desc.IsRoot.ToString ());
 
483
 
 
484
                        tw.WriteAttributeString ("version", desc.Version);
 
485
                        if (desc.CompatVersion.Length > 0)
 
486
                                tw.WriteAttributeString ("compatVersion", desc.CompatVersion);
 
487
                        
 
488
                        if (desc.Author.Length > 0)
 
489
                                tw.WriteAttributeString ("author", desc.Author);
 
490
                        if (desc.Category.Length > 0)
 
491
                                tw.WriteAttributeString ("category", desc.Category);
 
492
                        if (desc.Copyright.Length > 0)
 
493
                                tw.WriteAttributeString ("copyright", desc.Copyright);
 
494
                        if (desc.Url.Length > 0)
 
495
                                tw.WriteAttributeString ("url", desc.Url);
 
496
 
 
497
                        if (desc.Description.Length > 0)
 
498
                                tw.WriteElementString ("Description", desc.Description);
 
499
                        
 
500
                        if (desc.ExtensionPoints.Count > 0) {
 
501
                                ArrayList list = new ArrayList ();
 
502
                                Hashtable visited = new Hashtable ();
 
503
                                foreach (ExtensionPoint ep in desc.ExtensionPoints) {
 
504
                                        tw.WriteStartElement ("ExtensionPoint");
 
505
                                        tw.WriteAttributeString ("path", ep.Path);
 
506
                                        if (ep.Name.Length > 0)
 
507
                                                tw.WriteAttributeString ("name", ep.Name);
 
508
                                        else
 
509
                                                tw.WriteAttributeString ("name", ep.Path);
 
510
                                        if (ep.Description.Length > 0)
 
511
                                                tw.WriteElementString ("Description", ep.Description);
 
512
                                        PrintExtensionNodeSetXml (tw, desc, ep.NodeSet, list, visited);
 
513
                                        tw.WriteEndElement ();
 
514
                                }
 
515
                                
 
516
                                for (int n=0; n<list.Count; n++) {
 
517
                                        
 
518
                                        ExtensionNodeType nt = (ExtensionNodeType) list [n];
 
519
                                        
 
520
                                        tw.WriteStartElement ("ExtensionNodeType");
 
521
                                        tw.WriteAttributeString ("name", nt.Id);
 
522
                                        tw.WriteAttributeString ("id", visited [nt.Id + " " + nt.TypeName].ToString ());
 
523
                                        
 
524
                                        if (nt.Description.Length > 0)
 
525
                                                tw.WriteElementString ("Description", nt.Description);
 
526
                                        
 
527
                                        if (nt.Attributes.Count > 0) {
 
528
                                                tw.WriteStartElement ("Attributes");
 
529
                                                foreach (NodeTypeAttribute att in nt.Attributes) {
 
530
                                                        tw.WriteStartElement ("Attribute");
 
531
                                                        tw.WriteAttributeString ("name", att.Name);
 
532
                                                        tw.WriteAttributeString ("type", att.Type);
 
533
                                                        tw.WriteAttributeString ("required", att.Required.ToString ());
 
534
                                                        tw.WriteAttributeString ("localizable", att.Localizable.ToString ());
 
535
                                                        if (att.Description.Length > 0)
 
536
                                                                tw.WriteElementString ("Description", att.Description);
 
537
                                                        tw.WriteEndElement ();
 
538
                                                }
 
539
                                                tw.WriteEndElement ();
 
540
                                        }
 
541
                                        
 
542
                                        if (nt.NodeTypes.Count > 0 || nt.NodeSets.Count > 0) {
 
543
                                                tw.WriteStartElement ("ChildNodes");
 
544
                                                PrintExtensionNodeSetXml (tw, desc, nt, list, visited);
 
545
                                                tw.WriteEndElement ();
 
546
                                        }
 
547
                                        tw.WriteEndElement ();
 
548
                                }
 
549
                        }
 
550
                        tw.WriteEndElement ();
 
551
                }
 
552
                
 
553
                void PrintExtensionNodeSetXml (XmlWriter tw, AddinDescription desc, ExtensionNodeSet nset, ArrayList list, Hashtable visited)
 
554
                {
 
555
                        foreach (ExtensionNodeType nt in nset.GetAllowedNodeTypes ()) {
 
556
                                tw.WriteStartElement ("ExtensionNode");
 
557
                                tw.WriteAttributeString ("name", nt.Id);
 
558
                                string id = RegisterNodeXml (nt, list, visited);
 
559
                                tw.WriteAttributeString ("id", id.ToString ());
 
560
                                if (nt.Description.Length > 0)
 
561
                                        tw.WriteElementString ("Description", nt.Description);
 
562
                                tw.WriteEndElement ();
 
563
                        }
 
564
                }
 
565
                
 
566
                string RegisterNodeXml (ExtensionNodeType nt, ArrayList list, Hashtable visited)
 
567
                {
 
568
                        string key = nt.Id + " " + nt.TypeName;
 
569
                        if (visited.Contains (key))
 
570
                                return (string) visited [key];
 
571
                        string k = "ntype_" + uniqueId;
 
572
                        uniqueId++;
 
573
                        visited [key] = k;
 
574
                        list.Add (nt);
 
575
                        return k;
 
576
                }
 
577
                
 
578
                void PrintAddin (AddinDescription desc)
 
579
                {
 
580
                        Console.WriteLine ();
 
581
                        Console.WriteLine ("Addin Header");
 
582
                        Console.WriteLine ("------------");
 
583
                        Console.WriteLine ();
 
584
                        Console.WriteLine ("Name:      " + desc.Name);
 
585
                        Console.WriteLine ("Id:        " + desc.LocalId);
 
586
                        if (desc.Namespace.Length > 0)
 
587
                                Console.WriteLine ("Namespace: " + desc.Namespace);
 
588
 
 
589
                        Console.Write ("Version:   " + desc.Version);
 
590
                        if (desc.CompatVersion.Length > 0)
 
591
                                Console.WriteLine (" (compatible with: " + desc.CompatVersion + ")");
 
592
                        else
 
593
                                Console.WriteLine ();
 
594
                        
 
595
                        if (desc.AddinFile.Length > 0)
 
596
                                Console.WriteLine ("File:      " + desc.AddinFile);
 
597
                        if (desc.Author.Length > 0)
 
598
                                Console.WriteLine ("Author:    " + desc.Author);
 
599
                        if (desc.Category.Length > 0)
 
600
                                Console.WriteLine ("Category:  " + desc.Category);
 
601
                        if (desc.Copyright.Length > 0)
 
602
                                Console.WriteLine ("Copyright: " + desc.Copyright);
 
603
                        if (desc.Url.Length > 0)
 
604
                                Console.WriteLine ("Url:       " + desc.Url);
 
605
 
 
606
                        if (desc.Description.Length > 0) {
 
607
                                Console.WriteLine ();
 
608
                                Console.WriteLine ("Description: \n" + desc.Description);
 
609
                        }
 
610
                        
 
611
                        if (desc.ExtensionPoints.Count > 0) {
 
612
                                Console.WriteLine ();
 
613
                                Console.WriteLine ("Extenstion Points");
 
614
                                Console.WriteLine ("-----------------");
 
615
                                foreach (ExtensionPoint ep in desc.ExtensionPoints)
 
616
                                        PrintExtensionPoint (desc, ep);
 
617
                        }
 
618
                }
 
619
                
 
620
                void PrintExtensionPoint (AddinDescription desc, ExtensionPoint ep)
 
621
                {
 
622
                        Console.WriteLine ();
 
623
                        Console.WriteLine ("* Extension Point: " + ep.Path);
 
624
                        if (ep.Description.Length > 0)
 
625
                                Console.WriteLine (ep.Description);
 
626
                        
 
627
                        ArrayList list = new ArrayList ();
 
628
                        Hashtable visited = new Hashtable ();
 
629
                        
 
630
                        Console.WriteLine ();
 
631
                        Console.WriteLine ("  Extension nodes:");
 
632
                        GetNodes (desc, ep.NodeSet, list, new Hashtable ());
 
633
                        
 
634
                        foreach (ExtensionNodeType nt in list)
 
635
                                Console.WriteLine ("   - " + nt.Id + ": " + nt.Description);
 
636
                        
 
637
                        Console.WriteLine ();
 
638
                        Console.WriteLine ("  Node description:");
 
639
                        
 
640
                        string sind = "    ";
 
641
                        
 
642
                        for (int n=0; n<list.Count; n++) {
 
643
                                
 
644
                                ExtensionNodeType nt = (ExtensionNodeType) list [n];
 
645
                                if (visited.Contains (nt.Id + " " + nt.TypeName))
 
646
                                        continue;
 
647
                                
 
648
                                visited.Add (nt.Id + " " + nt.TypeName, nt);
 
649
                                Console.WriteLine ();
 
650
                                
 
651
                                Console.WriteLine (sind + "- " + nt.Id + ": " + nt.Description);
 
652
                                string nsind = sind + "    ";
 
653
                                if (nt.Attributes.Count > 0) {
 
654
                                        Console.WriteLine (nsind + "Attributes:");
 
655
                                        foreach (NodeTypeAttribute att in nt.Attributes) {
 
656
                                                string req = att.Required ? " (required)" : "";
 
657
                                                Console.WriteLine (nsind + "  " + att.Name + " (" + att.Type + "): " + att.Description + req);
 
658
                                        }
 
659
                                }
 
660
                                
 
661
                                if (nt.NodeTypes.Count > 0 || nt.NodeSets.Count > 0) {
 
662
                                        Console.WriteLine (nsind + "Child nodes:");
 
663
                                        ArrayList newList = new ArrayList ();
 
664
                                        GetNodes (desc, nt, newList, new Hashtable ());
 
665
                                        list.AddRange (newList);
 
666
                                        foreach (ExtensionNodeType cnt in newList)
 
667
                                                Console.WriteLine ("          " + cnt.Id + ": " + cnt.Description);
 
668
                                }
 
669
                        }
 
670
                        Console.WriteLine ();
 
671
                }
 
672
                
 
673
                void GetNodes (AddinDescription desc, ExtensionNodeSet nset, ArrayList list, Hashtable visited)
 
674
                {
 
675
                        if (visited.Contains (nset))
 
676
                                return;
 
677
                        visited.Add (nset, nset);
 
678
 
 
679
                        foreach (ExtensionNodeType nt in nset.NodeTypes) {
 
680
                                if (!visited.Contains (nt.Id + " " + nt.TypeName)) {
 
681
                                        list.Add (nt);
 
682
                                        visited.Add (nt.Id + " " + nt.TypeName, nt);
 
683
                                }
 
684
                        }
 
685
                        
 
686
                        foreach (string nsid in nset.NodeSets) {
 
687
                                ExtensionNodeSet rset = desc.ExtensionNodeSets [nsid];
 
688
                                if (rset != null)
 
689
                                        GetNodes (desc, rset, list, visited);
 
690
                        }
 
691
                }
 
692
                
 
693
                string[] GetArguments ()
 
694
                {
 
695
                        return arguments;
 
696
                }
 
697
                
 
698
                bool HasOption (string key)
 
699
                {
 
700
                        return options.Contains (key);
 
701
                }
 
702
                
 
703
                string GetOption (string key, string defValue)
 
704
                {
 
705
                        object val = options [key];
 
706
                        if (val == null || val == (object) this)
 
707
                                return defValue;
 
708
                        else
 
709
                                return (string) val;
 
710
                }
 
711
                
 
712
                void ReadOptions (string[] args)
 
713
                {
 
714
                        options = new Hashtable ();
 
715
                        ArrayList list = new ArrayList ();
 
716
                        
 
717
                        foreach (string arg in args) {
 
718
                                if (arg.StartsWith ("-")) {
 
719
                                        int i = arg.IndexOf (':');
 
720
                                        if (i == -1)
 
721
                                                options [arg.Substring (1)] = this;
 
722
                                        else
 
723
                                                options [arg.Substring (1, i-1)] = arg.Substring (i+1);
 
724
                                } else
 
725
                                        list.Add (arg);
 
726
                        }
 
727
                        
 
728
                        arguments = (string[]) list.ToArray (typeof(string));
 
729
                }
 
730
                
 
731
                public void AddCommand (string category, string command, string shortName, string arguments, string description, string longDescription, SetupCommandHandler handler)
 
732
                {
 
733
                        SetupCommand cmd = new SetupCommand (category, command, shortName, handler);
 
734
                        cmd.Usage = arguments;
 
735
                        cmd.Description = description;
 
736
                        cmd.LongDescription = longDescription;
 
737
                        
 
738
                        int lastCatPos = -1;
 
739
                        for (int n=0; n<commands.Count; n++) {
 
740
                                SetupCommand ec = (SetupCommand) commands [n];
 
741
                                if (ec.Category == category)
 
742
                                        lastCatPos = n;
 
743
                        }
 
744
                        if (lastCatPos == -1)
 
745
                                commands.Add (cmd);
 
746
                        else
 
747
                                commands.Insert (lastCatPos+1, cmd);
 
748
                }
 
749
                
 
750
                SetupCommand FindCommand (string id)
 
751
                {
 
752
                        foreach (SetupCommand cmd in commands)
 
753
                                if (cmd.Command == id || cmd.ShortCommand == id)
 
754
                                        return cmd;
 
755
                        return null;
 
756
                }
 
757
 
 
758
                public void PrintHelp (params string[] parms)
 
759
                {
 
760
                        if (parms.Length == 0) {
 
761
                                string lastCat = null;
 
762
                                foreach (SetupCommand cmd in commands) {
 
763
                                        if (lastCat != cmd.Category) {
 
764
                                                Console.WriteLine ();
 
765
                                                Console.WriteLine (cmd.Category + ":");
 
766
                                                lastCat = cmd.Category;
 
767
                                        }
 
768
                                        string cc = cmd.CommandDesc;
 
769
                                        if (cc.Length < 16)
 
770
                                                cc += new string (' ', 16 - cc.Length);
 
771
                                        Console.WriteLine ("  " + cc + " " + cmd.Description);
 
772
                                }
 
773
                                Console.WriteLine ();
 
774
                                Console.WriteLine ("Run '" + setupAppName + "help <command>' to get help about a specific command.");
 
775
                                Console.WriteLine ();
 
776
                                return;
 
777
                        }
 
778
                        else {
 
779
                                Console.WriteLine ();
 
780
                                SetupCommand cmd = FindCommand (parms [0]);
 
781
                                if (cmd != null) {
 
782
                                        Console.WriteLine ("{0}: {1}", cmd.CommandDesc, cmd.Description);
 
783
                                        Console.WriteLine ();
 
784
                                        Console.WriteLine ("Usage: {0}{1}", setupAppName, cmd.Usage);
 
785
                                        Console.WriteLine ();
 
786
                                        Console.WriteLine (cmd.LongDescription);
 
787
                                }
 
788
                                else
 
789
                                        Console.WriteLine ("Unknown command: " + parms [0]);
 
790
                                Console.WriteLine ();
 
791
                        }
 
792
                }
 
793
                        
 
794
                void CreateCommands ()
 
795
                {
 
796
                        SetupCommand cmd;
 
797
                        string cat = "Add-in commands";
 
798
                        
 
799
                        cmd = new SetupCommand (cat, "install", "i", new SetupCommandHandler (Install));
 
800
                        cmd.Description = "Installs add-ins.";
 
801
                        cmd.Usage = "[package-name|package-file] ...";
 
802
                        cmd.AppendDesc ("Installs an add-in or set of addins. The command argument is a list");
 
803
                        cmd.AppendDesc ("of files and/or package names. If a package name is provided");
 
804
                        cmd.AppendDesc ("the package will be looked out in the registered repositories.");
 
805
                        cmd.AppendDesc ("A specific add-in version can be specified by appending it to.");
 
806
                        cmd.AppendDesc ("the package name using '/' as a separator, like in this example:");
 
807
                        cmd.AppendDesc ("MonoDevelop.SourceEditor/0.9.1");
 
808
                        commands.Add (cmd);
 
809
                        
 
810
                        cmd = new SetupCommand (cat, "uninstall", "u", new SetupCommandHandler (Uninstall));
 
811
                        cmd.Description = "Uninstalls add-ins.";
 
812
                        cmd.Usage = "<package-name>";
 
813
                        cmd.AppendDesc ("Uninstalls an add-in. The command argument is the name");
 
814
                        cmd.AppendDesc ("of the add-in to uninstall.");
 
815
                        commands.Add (cmd);
 
816
                        
 
817
                        cmd = new SetupCommand (cat, "check-install", "ci", new SetupCommandHandler (CheckInstall));
 
818
                        cmd.Description = "Checks installed add-ins.";
 
819
                        cmd.Usage = "[package-name|package-file] ...";
 
820
                        cmd.AppendDesc ("Checks if a package is installed. If it is not, it looks for");
 
821
                        cmd.AppendDesc ("the package in the registered repositories, and if found");
 
822
                        cmd.AppendDesc ("the package is downloaded and installed, including all");
 
823
                        cmd.AppendDesc ("needed dependencies.");
 
824
                        commands.Add (cmd);
 
825
                        
 
826
                        
 
827
                        cmd = new SetupCommand (cat, "update", "up", new SetupCommandHandler (Update));
 
828
                        cmd.Description = "Updates installed add-ins.";
 
829
                        cmd.AppendDesc ("Downloads and installs available updates for installed add-ins.");
 
830
                        commands.Add (cmd);
 
831
                        
 
832
                        cmd = new SetupCommand (cat, "list", "l", new SetupCommandHandler (ListInstalled));
 
833
                        cmd.Description = "Lists installed add-ins.";
 
834
                        cmd.AppendDesc ("Prints a list of all installed add-ins.");
 
835
                        commands.Add (cmd);
 
836
                                        
 
837
                        cmd = new SetupCommand (cat, "list-av", "la", new SetupCommandHandler (ListAvailable));
 
838
                        cmd.Description = "Lists add-ins available in registered repositories.";
 
839
                        cmd.AppendDesc ("Prints a list of add-ins available to install in the");
 
840
                        cmd.AppendDesc ("registered repositories.");
 
841
                        commands.Add (cmd);
 
842
                                        
 
843
                        cmd = new SetupCommand (cat, "list-update", "lu", new SetupCommandHandler (ListUpdates));
 
844
                        cmd.Description = "Lists available add-in updates.";
 
845
                        cmd.AppendDesc ("Prints a list of available add-in updates in the registered repositories.");
 
846
                        commands.Add (cmd);
 
847
                        
 
848
                        cat = "Repository Commands";
 
849
 
 
850
                        cmd = new SetupCommand (cat, "rep-add", "ra", new SetupCommandHandler (AddRepository));
 
851
                        cmd.Description = "Registers repositories.";
 
852
                        cmd.Usage = "<url> ...";
 
853
                        cmd.AppendDesc ("Registers an add-in repository. Several URLs can be provided.");
 
854
                        commands.Add (cmd);
 
855
 
 
856
                        cmd = new SetupCommand (cat, "rep-remove", "rr", new SetupCommandHandler (RemoveRepository));
 
857
                        cmd.Description = "Unregisters repositories.";
 
858
                        cmd.Usage = "<url> ...";
 
859
                        cmd.AppendDesc ("Unregisters an add-in repository. Several URLs can be provided.");
 
860
                        commands.Add (cmd);
 
861
 
 
862
                        cmd = new SetupCommand (cat, "rep-update", "ru", new SetupCommandHandler (UpdateAvailableAddins));
 
863
                        cmd.Description = "Updates the lists of available addins.";
 
864
                        cmd.AppendDesc ("Updates the lists of addins available in all registered repositories.");
 
865
                        commands.Add (cmd);
 
866
 
 
867
                        cmd = new SetupCommand (cat, "rep-list", "rl", new SetupCommandHandler (ListRepositories));
 
868
                        cmd.Description = "Lists registered repositories.";
 
869
                        cmd.AppendDesc ("Shows a list of all registered repositories.");
 
870
                        commands.Add (cmd);
 
871
 
 
872
                        cat = "Add-in Registry Commands";
 
873
 
 
874
                        cmd = new SetupCommand (cat, "reg-update", "rgu", new SetupCommandHandler (UpdateRegistry));
 
875
                        cmd.Description = "Updates the add-in registry.";
 
876
                        cmd.AppendDesc ("Looks for changes in add-in directories and updates the registry.");
 
877
                        cmd.AppendDesc ("New add-ins will be added and deleted add-ins will be removed.");
 
878
                        commands.Add (cmd);
 
879
 
 
880
                        cmd = new SetupCommand (cat, "reg-build", "rgb", new SetupCommandHandler (RepairRegistry));
 
881
                        cmd.Description = "Rebuilds the add-in registry.";
 
882
                        cmd.AppendDesc ("Regenerates the add-in registry");
 
883
                        commands.Add (cmd);
 
884
 
 
885
                        cmd = new SetupCommand (cat, "info", null, new SetupCommandHandler (PrintAddinInfo));
 
886
                        cmd.Description = "Prints information about an add-in.";
 
887
                        cmd.AppendDesc ("Prints information about an add-in.");
 
888
                        commands.Add (cmd);
 
889
 
 
890
                        cat = "Packaging Commands";
 
891
 
 
892
                        cmd = new SetupCommand (cat, "rep-build", "rb", new SetupCommandHandler (BuildRepository));
 
893
                        cmd.Description = "Creates a repository index file for a directory structure.";
 
894
                        cmd.Usage = "<path>";
 
895
                        cmd.AppendDesc ("Scans the provided directory and generates a set of index files with entries");
 
896
                        cmd.AppendDesc ("for all add-in packages found in the directory tree. The resulting file");
 
897
                        cmd.AppendDesc ("structure is an add-in repository that can be published in a web site or a");
 
898
                        cmd.AppendDesc ("shared directory.");
 
899
                        commands.Add (cmd);
 
900
        
 
901
                        cmd = new SetupCommand (cat, "pack", "p", new SetupCommandHandler (BuildPackage));
 
902
                        cmd.Description = "Creates a package from an add-in configuration file.";
 
903
                        cmd.Usage = "<file-path> [-d:output-directory]";
 
904
                        cmd.AppendDesc ("Creates an add-in package (.mpack file) which includes all files ");
 
905
                        cmd.AppendDesc ("needed to deploy an add-in. The command parameter is the path to");
 
906
                        cmd.AppendDesc ("the add-in's configuration file.");
 
907
                        commands.Add (cmd);
 
908
        
 
909
                        cmd = new SetupCommand (cat, "help", "h", new SetupCommandHandler (PrintHelp));
 
910
                        cmd.Description = "Shows help about a command.";
 
911
                        cmd.Usage = "<command>";
 
912
                        commands.Add (cmd);
 
913
 
 
914
                        cat = "Debug Commands";
 
915
 
 
916
                        cmd = new SetupCommand (cat, "dump-file", null, new SetupCommandHandler (DumpRegistryFile));
 
917
                        cmd.Description = "Prints the contents of a registry file.";
 
918
                        cmd.Usage = "<file-path>";
 
919
                        cmd.AppendDesc ("Prints the contents of a registry file for debugging.");
 
920
                        commands.Add (cmd);
 
921
                }
 
922
        }
 
923
        
 
924
        class SetupCommand
 
925
        {
 
926
                string usage;
 
927
                
 
928
                public SetupCommand (string cat, string cmd, string shortCmd, SetupCommandHandler handler)
 
929
                {
 
930
                        Category = cat;
 
931
                        Command = cmd;
 
932
                        ShortCommand = shortCmd;
 
933
                        Handler = handler;
 
934
                }
 
935
                
 
936
                public void AppendDesc (string s)
 
937
                {
 
938
                        LongDescription += s + "\n";
 
939
                }
 
940
                
 
941
                public string Category;
 
942
                public string Command;
 
943
                public string ShortCommand;
 
944
                public SetupCommandHandler Handler; 
 
945
                
 
946
                public string Usage {
 
947
                        get { return usage != null ? Command + " " + usage : Command; }
 
948
                        set { usage = value; }
 
949
                }
 
950
                        
 
951
                public string CommandDesc {
 
952
                        get {
 
953
                                if (ShortCommand != null && ShortCommand.Length > 0)
 
954
                                        return Command + " (" + ShortCommand + ")";
 
955
                                else
 
956
                                        return Command;
 
957
                        }
 
958
                }
 
959
                
 
960
                public string Description = "";
 
961
                public string LongDescription = "";
 
962
        }
 
963
        
 
964
        public delegate void SetupCommandHandler (string[] args);
 
965
}
 
966