7
// Copyright (C) 2007 Novell, Inc (http://www.novell.com)
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:
17
// The above copyright notice and this permission notice shall be
18
// included in all copies or substantial portions of the Software.
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.
32
using System.Collections;
34
using Mono.Addins.Setup.ProgressMonitoring;
35
using Mono.Addins.Setup;
37
using Mono.Addins.Description;
40
namespace Mono.Addins.Setup
43
/// A command line add-in manager.
46
/// This class can be used to provide an add-in management command line tool to applications.
48
public class SetupTool
50
Hashtable options = new Hashtable ();
52
string applicationName = "Mono";
54
AddinRegistry registry;
55
ArrayList commands = new ArrayList ();
56
string setupAppName = "";
62
/// Creates a new instance
64
/// <param name="registry">
65
/// Add-in registry to manage.
67
public SetupTool (AddinRegistry registry)
69
this.registry = registry;
70
service = new SetupService (registry);
75
/// Display name of the host application
77
public string ApplicationName {
78
get { return applicationName; }
79
set { applicationName = value; }
83
/// Default add-in namespace of the application (optional). If set, only add-ins that belong to that namespace
84
/// will be shown in add-in lists.
86
public string ApplicationNamespace {
87
get { return service.ApplicationNamespace; }
88
set { service.ApplicationNamespace = value; }
92
/// Enables or disables verbose output
94
public bool VerboseOutput {
95
get { return verbose > 1; }
96
set { verbose = value ? 2 : 1; }
100
/// Sets or gets the verbose output level (0: normal output, 1:verbose, 2+:extra verbose)
102
public int VerboseOutputLevel {
103
get { return verbose; }
104
set { verbose = value; }
108
/// Runs the command line tool.
110
/// <param name="args">
111
/// Array that contains the command line arguments
113
/// <param name="firstArgumentIndex">
114
/// Index of the arguments array that has the first argument for the management tool
117
/// 0 if it succeeds. != 0 otherwise
119
public int Run (string[] args, int firstArgumentIndex)
121
string[] aa = new string [args.Length - firstArgumentIndex];
122
Array.Copy (args, firstArgumentIndex, aa, 0, aa.Length);
127
/// Runs the command line tool.
129
/// <param name="args">
130
/// Command line arguments
133
/// 0 if it succeeds. != 0 otherwise
135
public int Run (string[] args)
137
if (args.Length == 0) {
142
string[] parms = new string [args.Length - 1];
143
Array.Copy (args, 1, parms, 0, args.Length - 1);
149
return RunCommand (args [0], parms);
150
} catch (InstallException ex) {
151
Console.WriteLine (ex.Message);
156
int RunCommand (string cmd, string[] parms)
158
SetupCommand cc = FindCommand (cmd);
164
Console.WriteLine ("Unknown command: " + cmd);
169
void Install (string[] args)
171
bool prompt = !args.Any (a => a == "-y");
172
var addins = args.Where (a => a != "-y");
174
if (!addins.Any ()) {
175
PrintHelp ("install");
179
PackageCollection packs = new PackageCollection ();
180
foreach (string arg in addins) {
181
if (File.Exists (arg)) {
182
packs.Add (AddinPackage.FromFile (arg));
184
string aname = Addin.GetIdName (GetFullId (arg));
185
string aversion = Addin.GetIdVersion (arg);
186
if (aversion.Length == 0) aversion = null;
188
AddinRepositoryEntry[] ads = service.Repositories.GetAvailableAddin (aname, aversion);
190
throw new InstallException ("The addin '" + arg + "' is not available for install.");
191
packs.Add (AddinPackage.FromRepository (ads[ads.Length-1]));
194
Install (packs, prompt);
197
void CheckInstall (string[] args)
199
if (args.Length < 1) {
200
PrintHelp ("check-install");
204
PackageCollection packs = new PackageCollection ();
205
for (int n=0; n<args.Length; n++) {
206
Addin addin = registry.GetAddin (GetFullId (args[n]));
209
string aname = Addin.GetIdName (GetFullId (args[n]));
210
string aversion = Addin.GetIdVersion (args[n]);
211
if (aversion.Length == 0) aversion = null;
213
AddinRepositoryEntry[] ads = service.Repositories.GetAvailableAddin (aname, aversion);
215
throw new InstallException ("The addin '" + args[n] + "' is not available for install.");
216
packs.Add (AddinPackage.FromRepository (ads[ads.Length-1]));
218
Install (packs, false);
221
void Install (PackageCollection packs, bool prompt)
223
PackageCollection toUninstall;
224
DependencyCollection unresolved;
226
IProgressStatus m = new ConsoleProgressStatus (verbose);
228
if (!service.Store.ResolveDependencies (m, packs, out toUninstall, out unresolved))
229
throw new InstallException ("Not all dependencies could be resolved.");
232
if (prompt && (packs.Count != n || toUninstall.Count != 0)) {
233
Console.WriteLine ("The following packages will be installed:");
234
foreach (Package p in packs)
235
Console.WriteLine (" - " + p.Name);
238
if (prompt && (toUninstall.Count != 0)) {
239
Console.WriteLine ("The following packages need to be uninstalled:");
240
foreach (Package p in toUninstall)
241
Console.WriteLine (" - " + p.Name);
245
Console.WriteLine ();
246
Console.Write ("Are you sure you want to continue? (y/N): ");
247
string res = Console.ReadLine ();
248
if (res != "y" && res != "Y")
252
if (!service.Store.Install (m, packs)) {
253
Console.WriteLine ("Install operation failed.");
257
void Uninstall (string[] args)
259
bool prompt = !args.Any (a => a == "-y");
260
var addins = args.Where (a => a != "-y");
263
throw new InstallException ("The add-in id is required.");
264
if (addins.Count () > 1)
265
throw new InstallException ("Only one add-in id can be provided.");
267
string id = addins.First ();
268
Addin ads = registry.GetAddin (GetFullId (id));
270
throw new InstallException ("The add-in '" + id + "' is not installed.");
271
if (!ads.Description.CanUninstall)
272
throw new InstallException ("The add-in '" + id + "' is protected and can't be uninstalled.");
275
Console.WriteLine ("The following add-ins will be uninstalled:");
276
Console.WriteLine (" - " + ads.Description.Name);
277
foreach (Addin si in service.GetDependentAddins (id, true))
278
Console.WriteLine (" - " + si.Description.Name);
280
Console.WriteLine ();
281
Console.Write ("Are you sure you want to continue? (y/N): ");
282
string res = Console.ReadLine ();
283
if (res != "y" && res != "Y")
286
service.Uninstall (new ConsoleProgressStatus (verbose), ads.Id);
289
bool IsHidden (Addin ainfo)
291
return service.ApplicationNamespace != null && !(ainfo.Namespace + ".").StartsWith (service.ApplicationNamespace + ".") || ainfo.Description.IsHidden;
294
bool IsHidden (AddinHeader ainfo)
296
return service.ApplicationNamespace != null && !(ainfo.Namespace + ".").StartsWith (service.ApplicationNamespace + ".");
299
string GetId (AddinHeader ainfo)
301
if (service.ApplicationNamespace != null && (ainfo.Namespace + ".").StartsWith (service.ApplicationNamespace + "."))
302
return ainfo.Id.Substring (service.ApplicationNamespace.Length + 1);
307
string GetFullId (string id)
309
if (service.ApplicationNamespace != null)
310
return service.ApplicationNamespace + "." + id;
315
void ListInstalled (string[] args)
318
bool showAll = alist.Contains ("-a");
319
Console.WriteLine ("Installed add-ins:");
320
ArrayList list = new ArrayList ();
321
list.AddRange (registry.GetAddins ());
322
if (alist.Contains ("-r"))
323
list.AddRange (registry.GetAddinRoots ());
324
foreach (Addin addin in list) {
325
if (!showAll && IsHidden (addin))
327
Console.Write (" - " + addin.Name + " " + addin.Version);
329
Console.Write (" (" + addin.AddinFile + ")");
330
Console.WriteLine ();
334
void ListAvailable (string[] args)
336
bool showAll = args.Length > 0 && args [0] == "-a";
337
Console.WriteLine ("Available add-ins:");
338
AddinRepositoryEntry[] addins = service.Repositories.GetAvailableAddins ();
339
foreach (PackageRepositoryEntry addin in addins) {
340
if (!showAll && IsHidden (addin.Addin))
342
Console.WriteLine (" - " + GetId (addin.Addin) + " (" + addin.Repository.Name + ")");
346
void ListUpdates (string[] args)
348
bool showAll = args.Length > 0 && args [0] == "-a";
350
Console.WriteLine ("Looking for updates...");
351
service.Repositories.UpdateAllRepositories (null);
352
Console.WriteLine ("Available add-in updates:");
353
AddinRepositoryEntry[] addins = service.Repositories.GetAvailableAddins ();
355
foreach (PackageRepositoryEntry addin in addins) {
356
Addin sinfo = registry.GetAddin (addin.Addin.Id);
357
if (!showAll && IsHidden (sinfo))
359
if (sinfo != null && Addin.CompareVersions (sinfo.Version, addin.Addin.Version) == 1) {
360
Console.WriteLine (" - " + addin.Addin.Id + " " + addin.Addin.Version + " (" + addin.Repository.Name + ")");
365
Console.WriteLine ("No updates found.");
368
void Update (string [] args)
370
bool showAll = args.Length > 0 && args [0] == "-a";
372
Console.WriteLine ("Looking for updates...");
373
service.Repositories.UpdateAllRepositories (null);
375
PackageCollection packs = new PackageCollection ();
376
AddinRepositoryEntry[] addins = service.Repositories.GetAvailableAddins ();
377
foreach (PackageRepositoryEntry addin in addins) {
378
Addin sinfo = registry.GetAddin (addin.Addin.Id);
379
if (!showAll && IsHidden (sinfo))
381
if (sinfo != null && Addin.CompareVersions (sinfo.Version, addin.Addin.Version) == 1)
382
packs.Add (AddinPackage.FromRepository (addin));
385
Install (packs, true);
387
Console.WriteLine ("No updates found.");
390
void UpdateAvailableAddins (string[] args)
392
service.Repositories.UpdateAllRepositories (new ConsoleProgressStatus (verbose));
395
void AddRepository (string[] args)
397
foreach (string rep in args)
398
service.Repositories.RegisterRepository (new ConsoleProgressStatus (verbose), rep);
401
string GetRepositoryUrl (string url)
403
AddinRepository[] reps = GetRepositoryList ();
405
if (int.TryParse (url, out nr)) {
406
if (nr < 0 || nr >= reps.Length)
407
throw new InstallException ("Invalid repository number.");
410
if (!service.Repositories.ContainsRepository (url))
411
throw new InstallException ("Repository not registered.");
416
void RemoveRepository (string[] args)
418
foreach (string rep in args) {
419
service.Repositories.RemoveRepository (GetRepositoryUrl (rep));
423
void EnableRepository (string[] args)
425
foreach (string rep in args)
426
service.Repositories.SetRepositoryEnabled (GetRepositoryUrl(rep), true);
429
void DisableRepository (string[] args)
431
foreach (string rep in args)
432
service.Repositories.SetRepositoryEnabled (GetRepositoryUrl(rep), false);
435
AddinRepository[] GetRepositoryList ()
437
AddinRepository[] reps = service.Repositories.GetRepositories ();
438
Array.Sort (reps, (r1,r2) => r1.Title.CompareTo(r2.Title));
442
void ListRepositories (string[] args)
444
AddinRepository[] reps = GetRepositoryList ();
445
if (reps.Length == 0) {
446
Console.WriteLine ("No repositories have been registered.");
450
Console.WriteLine ("Registered repositories:");
451
foreach (RepositoryRecord rep in reps) {
452
string num = n.ToString ();
453
Console.Write (num + ") ");
455
Console.Write ("(Disabled) ");
456
Console.WriteLine (rep.Title);
457
if (rep.Title != rep.Url)
458
Console.WriteLine (new string (' ', num.Length + 2) + rep.Url);
463
void BuildRepository (string[] args)
466
throw new InstallException ("A directory name is required.");
467
service.BuildRepository (new ConsoleProgressStatus (verbose), args[0]);
470
void BuildPackage (string[] args)
473
throw new InstallException ("A file name is required.");
475
service.BuildPackage (new ConsoleProgressStatus (verbose), GetOption ("d", "."), GetArguments ());
478
void PrintLibraries (string[] args)
480
if (GetArguments ().Length < 1)
481
throw new InstallException ("An add-in id is required.");
483
bool refFormat = HasOption ("r");
485
System.Text.StringBuilder sb = new System.Text.StringBuilder ();
486
foreach (string id in GetArguments ()) {
487
Addin addin = service.Registry.GetAddin (id);
489
foreach (string asm in addin.Description.MainModule.Assemblies) {
490
string file = Path.Combine (addin.Description.BasePath, asm);
499
Console.WriteLine (sb);
502
void PrintApplications (string[] args)
504
foreach (Application app in SetupService.GetExtensibleApplications ()) {
505
string line = app.Name;
506
if (!string.IsNullOrEmpty (app.Description))
507
line += " - " + app.Description;
508
Console.WriteLine (line);
512
void UpdateRegistry (string[] args)
514
registry.Update (new ConsoleProgressStatus (verbose));
517
void RepairRegistry (string[] args)
519
registry.Rebuild (new ConsoleProgressStatus (verbose));
522
void DumpRegistryFile (string[] args)
525
throw new InstallException ("A file name is required.");
526
registry.DumpFile (args[0]);
529
void PrintAddinInfo (string[] args)
531
bool generateXml = false;
532
bool generateAll = false;
533
bool pickNamespace = false;
534
bool extensionModel = true;
536
ArrayList addins = new ArrayList ();
537
ArrayList namespaces = new ArrayList ();
539
foreach (string a in args) {
542
pickNamespace = false;
549
if (a == "--namespace" || a == "-n") {
550
pickNamespace = true;
558
extensionModel = false;
561
AddinDescription desc = null;
562
if (File.Exists (args[0]))
563
desc = registry.GetAddinDescription (new Mono.Addins.ConsoleProgressStatus (verbose), args[0]);
565
Addin addin = registry.GetAddin (args [0]);
567
desc = addin.Description;
570
throw new InstallException (string.Format ("Add-in '{0}' not found.", a));
576
ArrayList list = new ArrayList ();
577
list.AddRange (registry.GetAddinRoots ());
578
list.AddRange (registry.GetAddins ());
579
foreach (Addin addin in list) {
580
if (namespaces.Count > 0) {
581
foreach (string ns in namespaces) {
582
if (addin.Id.StartsWith (ns + ".")) {
583
addins.Add (addin.Description);
588
addins.Add (addin.Description);
593
if (addins.Count == 0)
594
throw new InstallException ("A file name or add-in ID is required.");
598
XmlTextWriter tw = new XmlTextWriter (Console.Out);
599
tw.Formatting = Formatting.Indented;
600
tw.WriteStartElement ("Addins");
601
foreach (AddinDescription desc in addins) {
602
if (extensionModel && desc.ExtensionPoints.Count == 0)
604
PrintAddinXml (tw, desc);
609
foreach (AddinDescription des in addins)
614
void PrintAddinXml (XmlWriter tw, AddinDescription desc)
616
tw.WriteStartElement ("Addin");
617
tw.WriteAttributeString ("name", desc.Name);
618
tw.WriteAttributeString ("addinId", desc.LocalId);
619
tw.WriteAttributeString ("fullId", desc.AddinId);
620
tw.WriteAttributeString ("id", "addin_" + uniqueId);
622
if (desc.Namespace.Length > 0)
623
tw.WriteAttributeString ("namespace", desc.Namespace);
624
tw.WriteAttributeString ("isroot", desc.IsRoot.ToString ());
626
tw.WriteAttributeString ("version", desc.Version);
627
if (desc.CompatVersion.Length > 0)
628
tw.WriteAttributeString ("compatVersion", desc.CompatVersion);
630
if (desc.Author.Length > 0)
631
tw.WriteAttributeString ("author", desc.Author);
632
if (desc.Category.Length > 0)
633
tw.WriteAttributeString ("category", desc.Category);
634
if (desc.Copyright.Length > 0)
635
tw.WriteAttributeString ("copyright", desc.Copyright);
636
if (desc.Url.Length > 0)
637
tw.WriteAttributeString ("url", desc.Url);
639
if (desc.Description.Length > 0)
640
tw.WriteElementString ("Description", desc.Description);
642
if (desc.ExtensionPoints.Count > 0) {
643
ArrayList list = new ArrayList ();
644
Hashtable visited = new Hashtable ();
645
foreach (ExtensionPoint ep in desc.ExtensionPoints) {
646
tw.WriteStartElement ("ExtensionPoint");
647
tw.WriteAttributeString ("path", ep.Path);
648
if (ep.Name.Length > 0)
649
tw.WriteAttributeString ("name", ep.Name);
651
tw.WriteAttributeString ("name", ep.Path);
652
if (ep.Description.Length > 0)
653
tw.WriteElementString ("Description", ep.Description);
654
PrintExtensionNodeSetXml (tw, desc, ep.NodeSet, list, visited);
655
tw.WriteEndElement ();
658
for (int n=0; n<list.Count; n++) {
660
ExtensionNodeType nt = (ExtensionNodeType) list [n];
662
tw.WriteStartElement ("ExtensionNodeType");
663
tw.WriteAttributeString ("name", nt.Id);
664
tw.WriteAttributeString ("id", visited [nt.Id + " " + nt.TypeName].ToString ());
666
if (nt.Description.Length > 0)
667
tw.WriteElementString ("Description", nt.Description);
669
if (nt.Attributes.Count > 0) {
670
tw.WriteStartElement ("Attributes");
671
foreach (NodeTypeAttribute att in nt.Attributes) {
672
tw.WriteStartElement ("Attribute");
673
tw.WriteAttributeString ("name", att.Name);
674
tw.WriteAttributeString ("type", att.Type);
675
tw.WriteAttributeString ("required", att.Required.ToString ());
676
tw.WriteAttributeString ("localizable", att.Localizable.ToString ());
677
if (att.Description.Length > 0)
678
tw.WriteElementString ("Description", att.Description);
679
tw.WriteEndElement ();
681
tw.WriteEndElement ();
684
if (nt.NodeTypes.Count > 0 || nt.NodeSets.Count > 0) {
685
tw.WriteStartElement ("ChildNodes");
686
PrintExtensionNodeSetXml (tw, desc, nt, list, visited);
687
tw.WriteEndElement ();
689
tw.WriteEndElement ();
692
tw.WriteEndElement ();
695
void PrintExtensionNodeSetXml (XmlWriter tw, AddinDescription desc, ExtensionNodeSet nset, ArrayList list, Hashtable visited)
697
foreach (ExtensionNodeType nt in nset.GetAllowedNodeTypes ()) {
698
tw.WriteStartElement ("ExtensionNode");
699
tw.WriteAttributeString ("name", nt.Id);
700
string id = RegisterNodeXml (nt, list, visited);
701
tw.WriteAttributeString ("id", id.ToString ());
702
if (nt.Description.Length > 0)
703
tw.WriteElementString ("Description", nt.Description);
704
tw.WriteEndElement ();
708
string RegisterNodeXml (ExtensionNodeType nt, ArrayList list, Hashtable visited)
710
string key = nt.Id + " " + nt.TypeName;
711
if (visited.Contains (key))
712
return (string) visited [key];
713
string k = "ntype_" + uniqueId;
720
void PrintAddin (AddinDescription desc)
722
Console.WriteLine ();
723
Console.WriteLine ("Addin Header");
724
Console.WriteLine ("------------");
725
Console.WriteLine ();
726
Console.WriteLine ("Name: " + desc.Name);
727
Console.WriteLine ("Id: " + desc.LocalId);
728
if (desc.Namespace.Length > 0)
729
Console.WriteLine ("Namespace: " + desc.Namespace);
731
Console.Write ("Version: " + desc.Version);
732
if (desc.CompatVersion.Length > 0)
733
Console.WriteLine (" (compatible with: " + desc.CompatVersion + ")");
735
Console.WriteLine ();
737
if (desc.AddinFile.Length > 0)
738
Console.WriteLine ("File: " + desc.AddinFile);
739
if (desc.Author.Length > 0)
740
Console.WriteLine ("Author: " + desc.Author);
741
if (desc.Category.Length > 0)
742
Console.WriteLine ("Category: " + desc.Category);
743
if (desc.Copyright.Length > 0)
744
Console.WriteLine ("Copyright: " + desc.Copyright);
745
if (desc.Url.Length > 0)
746
Console.WriteLine ("Url: " + desc.Url);
748
if (desc.Description.Length > 0) {
749
Console.WriteLine ();
750
Console.WriteLine ("Description: \n" + desc.Description);
753
if (desc.ExtensionPoints.Count > 0) {
754
Console.WriteLine ();
755
Console.WriteLine ("Extenstion Points");
756
Console.WriteLine ("-----------------");
757
foreach (ExtensionPoint ep in desc.ExtensionPoints)
758
PrintExtensionPoint (desc, ep);
762
void PrintExtensionPoint (AddinDescription desc, ExtensionPoint ep)
764
Console.WriteLine ();
765
Console.WriteLine ("* Extension Point: " + ep.Path);
766
if (ep.Description.Length > 0)
767
Console.WriteLine (ep.Description);
769
ArrayList list = new ArrayList ();
770
Hashtable visited = new Hashtable ();
772
Console.WriteLine ();
773
Console.WriteLine (" Extension nodes:");
774
GetNodes (desc, ep.NodeSet, list, new Hashtable ());
776
foreach (ExtensionNodeType nt in list)
777
Console.WriteLine (" - " + nt.Id + ": " + nt.Description);
779
Console.WriteLine ();
780
Console.WriteLine (" Node description:");
784
for (int n=0; n<list.Count; n++) {
786
ExtensionNodeType nt = (ExtensionNodeType) list [n];
787
if (visited.Contains (nt.Id + " " + nt.TypeName))
790
visited.Add (nt.Id + " " + nt.TypeName, nt);
791
Console.WriteLine ();
793
Console.WriteLine (sind + "- " + nt.Id + ": " + nt.Description);
794
string nsind = sind + " ";
795
if (nt.Attributes.Count > 0) {
796
Console.WriteLine (nsind + "Attributes:");
797
foreach (NodeTypeAttribute att in nt.Attributes) {
798
string req = att.Required ? " (required)" : "";
799
Console.WriteLine (nsind + " " + att.Name + " (" + att.Type + "): " + att.Description + req);
803
if (nt.NodeTypes.Count > 0 || nt.NodeSets.Count > 0) {
804
Console.WriteLine (nsind + "Child nodes:");
805
ArrayList newList = new ArrayList ();
806
GetNodes (desc, nt, newList, new Hashtable ());
807
list.AddRange (newList);
808
foreach (ExtensionNodeType cnt in newList)
809
Console.WriteLine (" " + cnt.Id + ": " + cnt.Description);
812
Console.WriteLine ();
815
void GetNodes (AddinDescription desc, ExtensionNodeSet nset, ArrayList list, Hashtable visited)
817
if (visited.Contains (nset))
819
visited.Add (nset, nset);
821
foreach (ExtensionNodeType nt in nset.NodeTypes) {
822
if (!visited.Contains (nt.Id + " " + nt.TypeName)) {
824
visited.Add (nt.Id + " " + nt.TypeName, nt);
828
foreach (string nsid in nset.NodeSets) {
829
ExtensionNodeSet rset = desc.ExtensionNodeSets [nsid];
831
GetNodes (desc, rset, list, visited);
835
string[] GetArguments ()
840
bool HasOption (string key)
842
return options.Contains (key);
845
string GetOption (string key, string defValue)
847
object val = options [key];
848
if (val == null || val == (object) this)
854
void ReadOptions (string[] args)
856
options = new Hashtable ();
857
ArrayList list = new ArrayList ();
859
foreach (string arg in args) {
860
if (arg.StartsWith ("-")) {
861
int i = arg.IndexOf (':');
863
options [arg.Substring (1)] = this;
865
options [arg.Substring (1, i-1)] = arg.Substring (i+1);
870
arguments = (string[]) list.ToArray (typeof(string));
874
/// Adds a custom command to the add-in manager
876
/// <param name="category">
877
/// Category under which the command has to be shown in the help text
879
/// <param name="command">
880
/// Name of the command
882
/// <param name="shortName">
883
/// Short name of the command (it's an alias of the normal name)
885
/// <param name="arguments">
886
/// Formal description of the arguments that the command accepts. For example: "[addin-id|addin-file] [--xml] [--all] [--full] [--namespace <namespace>]"
888
/// <param name="description">
889
/// Short description of the command
891
/// <param name="longDescription">
892
/// Long description of the command
894
/// <param name="handler">
895
/// Delegate to be invoked to run the command
897
public void AddCommand (string category, string command, string shortName, string arguments, string description, string longDescription, SetupCommandHandler handler)
899
SetupCommand cmd = new SetupCommand (category, command, shortName, handler);
900
cmd.Usage = arguments;
901
cmd.Description = description;
902
cmd.LongDescription = longDescription;
905
for (int n=0; n<commands.Count; n++) {
906
SetupCommand ec = (SetupCommand) commands [n];
907
if (ec.Category == category)
910
if (lastCatPos == -1)
913
commands.Insert (lastCatPos+1, cmd);
916
SetupCommand FindCommand (string id)
918
foreach (SetupCommand cmd in commands)
919
if (cmd.Command == id || cmd.ShortCommand == id)
925
/// Prints help about the add-in management tool, or about a specific command
927
/// <param name="parms">
928
/// Optional command name and arguments
930
public void PrintHelp (params string[] parms)
932
if (parms.Length == 0) {
933
string lastCat = null;
934
foreach (SetupCommand cmd in commands) {
935
if (cmd.Command == "help")
937
if (lastCat != cmd.Category) {
938
Console.WriteLine ();
939
Console.WriteLine (cmd.Category + ":");
940
lastCat = cmd.Category;
942
string cc = cmd.CommandDesc;
944
cc += new string (' ', 16 - cc.Length);
945
Console.WriteLine (" " + cc + " " + cmd.Description);
947
Console.WriteLine ();
948
Console.WriteLine ("Run '" + setupAppName + "help <command>' to get help about a specific command.");
949
Console.WriteLine ();
953
Console.WriteLine ();
954
SetupCommand cmd = FindCommand (parms [0]);
956
Console.WriteLine ("{0}: {1}", cmd.CommandDesc, cmd.Description);
957
Console.WriteLine ();
958
Console.WriteLine ("Usage: {0}{1}", setupAppName, cmd.Usage);
959
Console.WriteLine ();
961
TextFormatter fm = new TextFormatter ();
962
fm.Wrap = WrappingType.Word;
963
fm.Append (cmd.LongDescription);
964
Console.WriteLine (fm.ToString ());
967
Console.WriteLine ("Unknown command: " + parms [0]);
968
Console.WriteLine ();
972
void CreateCommands ()
975
string cat = "Add-in commands";
977
cmd = new SetupCommand (cat, "install", "i", new SetupCommandHandler (Install));
978
cmd.Description = "Installs add-ins.";
979
cmd.Usage = "[-y] [package-name|package-file] ...";
980
cmd.AppendDesc ("Installs an add-in or set of addins. The command argument is a list");
981
cmd.AppendDesc ("of files and/or package names. If a package name is provided");
982
cmd.AppendDesc ("the package will be looked up in the registered repositories.");
983
cmd.AppendDesc ("A specific add-in version can be specified by appending it to.");
984
cmd.AppendDesc ("the package name using '/' as a separator, like in this example:");
985
cmd.AppendDesc ("MonoDevelop.SourceEditor/0.9.1\n");
986
cmd.AppendDesc ("-y: Don't ask for confirmation.");
989
cmd = new SetupCommand (cat, "uninstall", "u", new SetupCommandHandler (Uninstall));
990
cmd.Description = "Uninstalls add-ins.";
991
cmd.Usage = "[-y] <package-name>";
992
cmd.AppendDesc ("Uninstalls an add-in. The command argument is the name");
993
cmd.AppendDesc ("of the add-in to uninstall.\n");
994
cmd.AppendDesc ("-y: Don't ask for confirmation.");
997
cmd = new SetupCommand (cat, "check-install", "ci", new SetupCommandHandler (CheckInstall));
998
cmd.Description = "Checks installed add-ins.";
999
cmd.Usage = "[package-name|package-file] ...";
1000
cmd.AppendDesc ("Checks if a package is installed. If it is not, it looks for");
1001
cmd.AppendDesc ("the package in the registered repositories, and if found");
1002
cmd.AppendDesc ("the package is downloaded and installed, including all");
1003
cmd.AppendDesc ("needed dependencies.");
1007
cmd = new SetupCommand (cat, "update", "up", new SetupCommandHandler (Update));
1008
cmd.Description = "Updates installed add-ins.";
1009
cmd.AppendDesc ("Downloads and installs available updates for installed add-ins.");
1012
cmd = new SetupCommand (cat, "list", "l", new SetupCommandHandler (ListInstalled));
1013
cmd.Description = "Lists installed add-ins.";
1014
cmd.AppendDesc ("Prints a list of all installed add-ins.");
1017
cmd = new SetupCommand (cat, "list-av", "la", new SetupCommandHandler (ListAvailable));
1018
cmd.Description = "Lists add-ins available in registered repositories.";
1019
cmd.AppendDesc ("Prints a list of add-ins available to install in the");
1020
cmd.AppendDesc ("registered repositories.");
1023
cmd = new SetupCommand (cat, "list-update", "lu", new SetupCommandHandler (ListUpdates));
1024
cmd.Description = "Lists available add-in updates.";
1025
cmd.AppendDesc ("Prints a list of available add-in updates in the registered repositories.");
1028
cat = "Repository Commands";
1030
cmd = new SetupCommand (cat, "rep-add", "ra", new SetupCommandHandler (AddRepository));
1031
cmd.Description = "Registers repositories.";
1032
cmd.Usage = "<url> ...";
1033
cmd.AppendDesc ("Registers an add-in repository. Several URLs can be provided.");
1036
cmd = new SetupCommand (cat, "rep-remove", "rr", new SetupCommandHandler (RemoveRepository));
1037
cmd.Description = "Unregisters repositories.";
1038
cmd.Usage = "<url or number> ...";
1039
cmd.AppendDesc ("Unregisters an add-in repository. Several URLs can be provided.");
1040
cmd.AppendDesc ("Instead of an url, a repository number can be used (repository numbers are");
1041
cmd.AppendDesc ("shown by the rep-list command.");
1044
cmd = new SetupCommand (cat, "rep-enable", "re", new SetupCommandHandler (EnableRepository));
1045
cmd.Description = "Enables repositories.";
1046
cmd.Usage = "<url or number> ...";
1047
cmd.AppendDesc ("Enables an add-in repository which has been disabled. Several URLs can be");
1048
cmd.AppendDesc ("provided. Instead of an url, a repository number can be used (repository");
1049
cmd.AppendDesc ("numbers are shown by the rep-list command.");
1052
cmd = new SetupCommand (cat, "rep-disable", "rd", new SetupCommandHandler (DisableRepository));
1053
cmd.Description = "Disables repositories.";
1054
cmd.Usage = "<url> ...";
1055
cmd.AppendDesc ("Disables an add-in repository. Several URLs can be provided");
1056
cmd.AppendDesc ("When a repository is disabled, it will be ignored when using the update and");
1057
cmd.AppendDesc ("install commands.");
1058
cmd.AppendDesc ("Instead of an url, a repository number can be used (repository numbers are");
1059
cmd.AppendDesc ("shown by the rep-list command.");
1062
cmd = new SetupCommand (cat, "rep-update", "ru", new SetupCommandHandler (UpdateAvailableAddins));
1063
cmd.Description = "Updates the lists of available addins.";
1064
cmd.AppendDesc ("Updates the lists of addins available in all registered repositories.");
1067
cmd = new SetupCommand (cat, "rep-list", "rl", new SetupCommandHandler (ListRepositories));
1068
cmd.Description = "Lists registered repositories.";
1069
cmd.AppendDesc ("Shows a list of all registered repositories.");
1072
cat = "Add-in Registry Commands";
1074
cmd = new SetupCommand (cat, "reg-update", "rgu", new SetupCommandHandler (UpdateRegistry));
1075
cmd.Description = "Updates the add-in registry.";
1076
cmd.AppendDesc ("Looks for changes in add-in directories and updates the registry.");
1077
cmd.AppendDesc ("New add-ins will be added and deleted add-ins will be removed.");
1080
cmd = new SetupCommand (cat, "reg-build", "rgb", new SetupCommandHandler (RepairRegistry));
1081
cmd.Description = "Rebuilds the add-in registry.";
1082
cmd.AppendDesc ("Regenerates the add-in registry");
1085
cmd = new SetupCommand (cat, "info", null, new SetupCommandHandler (PrintAddinInfo));
1086
cmd.Usage = "[addin-id|addin-file] [--xml] [--all] [--full] [--namespace <namespace>]";
1087
cmd.Description = "Prints information about add-ins.";
1088
cmd.AppendDesc ("Prints information about add-ins. Options:\n");
1089
cmd.AppendDesc (" --xml: Dump the information using an XML format.\n");
1090
cmd.AppendDesc (" --all: Dump information from all add-ins.\n");
1091
cmd.AppendDesc (" --full: Include add-ins which don't define extension points.\n");
1092
cmd.AppendDesc (" --namespace ns: Include only add-ins from the specified 'ns' namespace.");
1095
cat = "Packaging Commands";
1097
cmd = new SetupCommand (cat, "rep-build", "rb", new SetupCommandHandler (BuildRepository));
1098
cmd.Description = "Creates a repository index file for a directory structure.";
1099
cmd.Usage = "<path>";
1100
cmd.AppendDesc ("Scans the provided directory and generates a set of index files with entries");
1101
cmd.AppendDesc ("for all add-in packages found in the directory tree. The resulting file");
1102
cmd.AppendDesc ("structure is an add-in repository that can be published in a web site or a");
1103
cmd.AppendDesc ("shared directory.");
1106
cmd = new SetupCommand (cat, "pack", "p", new SetupCommandHandler (BuildPackage));
1107
cmd.Description = "Creates a package from an add-in configuration file.";
1108
cmd.Usage = "<file-path> [-d:output-directory]";
1109
cmd.AppendDesc ("Creates an add-in package (.mpack file) which includes all files ");
1110
cmd.AppendDesc ("needed to deploy an add-in. The command parameter is the path to");
1111
cmd.AppendDesc ("the add-in's configuration file.");
1114
cmd = new SetupCommand (cat, "help", "h", new SetupCommandHandler (PrintHelp));
1115
cmd.Description = "Shows help about a command.";
1116
cmd.Usage = "<command>";
1119
cat = "Build Commands";
1121
cmd = new SetupCommand (cat, "libraries", "libs", new SetupCommandHandler (PrintLibraries));
1122
cmd.Description = "Lists add-in assemblies.";
1123
cmd.Usage = "[-r] <addin-id> ...";
1124
cmd.AppendDesc ("Prints a list of assemblies exported by the add-in or add-ins provided");
1125
cmd.AppendDesc ("as arguments. This list of assemblies can be used as references for");
1126
cmd.AppendDesc ("building add-ins that depend on them. If the -r option is specified,");
1127
cmd.AppendDesc ("each assembly is prefixed with '-r:'.");
1130
cmd = new SetupCommand (cat, "applications", "apps", new SetupCommandHandler (PrintApplications));
1131
cmd.Description = "Lists extensible applications.";
1132
cmd.AppendDesc ("Prints a list of registered extensible applications.");
1135
cat = "Debug Commands";
1137
cmd = new SetupCommand (cat, "dump-file", null, new SetupCommandHandler (DumpRegistryFile));
1138
cmd.Description = "Prints the contents of a registry file.";
1139
cmd.Usage = "<file-path>";
1140
cmd.AppendDesc ("Prints the contents of a registry file for debugging.");
1149
public SetupCommand (string cat, string cmd, string shortCmd, SetupCommandHandler handler)
1153
ShortCommand = shortCmd;
1157
public void AppendDesc (string s)
1159
LongDescription += s + " ";
1162
public string Category;
1163
public string Command;
1164
public string ShortCommand;
1165
public SetupCommandHandler Handler;
1167
public string Usage {
1168
get { return usage != null ? Command + " " + usage : Command; }
1169
set { usage = value; }
1172
public string CommandDesc {
1174
if (ShortCommand != null && ShortCommand.Length > 0)
1175
return Command + " (" + ShortCommand + ")";
1181
public string Description = "";
1182
public string LongDescription = "";
1186
/// A command handler
1188
public delegate void SetupCommandHandler (string[] args);