Merge pull request #2871 from BrzVlad/feature-conc-sweep-nrs
[mono.git] / mcs / tools / installvst / installvst.cs
1 //
2 // Authors:
3 //   Marek Habersack (mhabersack@novell.com)
4 //
5 // (C) 2007 Novell, Inc
6 //
7
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 using System;
29 using System.Collections;
30 using System.IO;
31 using System.Xml;
32
33 public class App
34 {
35   string templateFile;
36   string targetDir;
37   string targetPath;
38   string sourceDir;
39   
40   XmlNamespaceManager nsmgr;
41
42   Stack folders;
43   
44   public App (string templateFile, string targetDir)
45   {
46     this.templateFile = templateFile;
47     this.targetDir = targetDir;
48
49     this.sourceDir = Path.GetDirectoryName (templateFile);
50     if (this.sourceDir == null || this.sourceDir.Length == 0)
51       this.sourceDir = Directory.GetCurrentDirectory ();
52   }
53
54   public void Run ()
55   {
56     if (templateFile == null || templateFile.Length == 0 ||
57         targetDir == null || targetDir.Length == 0)
58       throw new ApplicationException ("Missing or invalid installation data");
59
60     XmlDocument doc = new XmlDocument ();
61     doc.Load (templateFile);
62     nsmgr = new XmlNamespaceManager (doc.NameTable);
63     nsmgr.AddNamespace ("def", "http://schemas.microsoft.com/developer/vstemplate/2005");
64     
65     ReadTemplateData (doc);
66     InstallProject (doc);
67   }
68
69   void ReadTemplateData (XmlDocument doc)
70   {
71     XmlNode defaultName = doc.SelectSingleNode ("//def:VSTemplate[@Type='Project']/def:TemplateData/def:DefaultName", nsmgr);
72     if (defaultName == null)
73       throw new ApplicationException ("Input file is not a VisualStudio Template");
74     string folderName = defaultName.InnerText;
75     targetPath = Path.Combine (targetDir, folderName);
76     
77     if (!Directory.Exists (targetPath))
78       Directory.CreateDirectory (targetPath);
79
80     folders = new Stack ();
81   }
82
83   string SafeGetAttribute (XmlNode node, string name)
84   {
85     XmlAttribute attr = node.Attributes [name];
86     if (attr != null)
87       return attr.Value;
88     return String.Empty;
89   }
90
91   string GetCurPath ()
92   {
93     string curPath = folders.Count > 0 ? (string) folders.Peek () : null;
94     if (curPath == null || curPath.Length == 0)
95       return targetPath;
96     return curPath;
97   }
98   
99   void ProcessFolder (XmlNode node)
100   {
101     string curPath = GetCurPath ();
102     string folderPath = Path.Combine (curPath, SafeGetAttribute (node, "Name"));
103     if (!Directory.Exists (folderPath))
104       Directory.CreateDirectory (folderPath);
105     folders.Push (folderPath);
106     foreach (XmlNode child in node.ChildNodes)
107       ProcessNode (child);
108     folders.Pop ();
109   }
110
111   void ProcessItem (XmlNode node)
112   {
113     string curPath = GetCurPath ();
114     string srcName = node.InnerText;
115     string targetName = SafeGetAttribute (node, "TargetFileName");
116     string src = Path.Combine (sourceDir, srcName);
117     string dst = Path.Combine (curPath, targetName.Length > 0 ? targetName : srcName);
118
119     if (!File.Exists (src)) {
120       Console.WriteLine ("Warning: source file {0} does not exist.", src);
121       return;
122     }
123     File.Copy (src, dst, true);
124   }
125   
126   void ProcessNode (XmlNode node)
127   {
128     if (node.NodeType != XmlNodeType.Element)
129       return;
130     
131     switch (node.Name) {
132       case "Folder":
133         ProcessFolder (node);
134         break;
135
136       case "ProjectItem":
137         ProcessItem (node);
138         break;
139       }
140   }
141   
142   void InstallProject (XmlDocument doc)
143   {
144     XmlNode project = doc.SelectSingleNode ("//def:VSTemplate[@Type='Project']/def:TemplateContent/def:Project", nsmgr);
145     if (project == null)
146       throw new ApplicationException ("Missing project contents in the template file");
147
148     foreach (XmlNode child in project.ChildNodes)
149       ProcessNode (child);
150   }
151 }
152
153 public class AppMain
154 {
155   public static void Main (string[] args)
156   {
157     if (args.Length < 2)
158       Usage ();
159
160     App app = new App (args [0], args [1]);
161
162     try {
163       app.Run ();
164     } catch (Exception ex) {
165       Console.WriteLine ("Failed to install template {0} in {1}\n{2}\n", args [0], args [1], ex.Message);
166       Console.WriteLine ("Exception: {0}", ex);
167       Environment.Exit (1);
168     }
169   }
170
171   static void Usage ()
172   {
173     Console.WriteLine ("Usage: installvst <VSTemplateFile> <DestinationPath>\n");
174     Environment.Exit (1);
175   }
176 }