private void Load(ConfigSourceGroup group, ConfigSource configSource)
        {
            NAssemblySource assemblySource = null;

            if (configSource.AssemblyPath == null)
            {
                Logger.Error("Assembly path not specified for <source>. Cannot be null");
                return;
            }

            // Check Parameters
            if (!File.Exists(configSource.AssemblyPath))
            {
                Logger.Error("Assembly file [{0}] not found", configSource.AssemblyPath);
                return;
            }

            var extension = Path.GetExtension(configSource.AssemblyPath);

            if (extension != null && (extension.ToLower() == ".dll" || extension.ToLower() == ".exe"))
            {
                assemblySource = LoadAssembly(group, configSource.AssemblyPath);
                AssemblySources.Add(assemblySource);
            }
            else
            {
                Logger.Fatal("Invalid Assembly source [{0}]. Must be either an Assembly", configSource.AssemblyPath);
            }

            // If documentation path is null, use by default the assembly path
            if (configSource.DocumentationPath == null)
            {
                configSource.DocumentationPath = Path.ChangeExtension(configSource.AssemblyPath, ".xml");
            }

            if (!File.Exists(configSource.DocumentationPath))
            {
                Logger.Error("Documentation file [{0}] not found", configSource.DocumentationPath);
                return;
            }

            extension = Path.GetExtension(configSource.DocumentationPath);
            if (extension != null && extension.ToLower() == ".xml")
            {
                if (assemblySource == null)
                {
                    assemblySource = new NAssemblySource();
                    AssemblySources.Add(assemblySource);
                }

                assemblySource.Document = LoadAssemblyDocumentation(configSource.DocumentationPath);
            }
            else
            {
                Logger.Fatal("Invalid Assembly source [{0}]. Must be either a Xml comment file", configSource.DocumentationPath);
            }
        }
Exemple #2
0
        /// <summary>
        /// Parses the command line arguments.
        /// </summary>
        /// <param name="args">The args.</param>
        public void ParseArguments(string[] args)
        {
            var showHelp = false;

            var files = new List<string>();

            var configParams = new List<ConfigParam>();
            var styleParams = new List<ConfigParam>();
            string webDocumentationUrl = null;
            NetworkCredential webDocumentationLogin = null;

            var additionalSearchDirectories = new List<string>();

            var options = new OptionSet()
                              {
                                  "Copyright (c) 2010-2013 SharpDoc - Alexandre Mutel",
                                  "Usage: SharpDoc [options]* [--config file.xml | Assembly1.dll Assembly1.xml...]*",
                                  "Documentation generator for .Net languages",
                                  "",
                                  "options:",
                                  {"c|config=", "Configuration file", opt => Config = Config.Load(opt, TopicLoader)},

                                  {
                                      "D=", "Define a template parameter with an (optional) value.",
                                      (param, value) =>
                                          {
                                              if (param == null)
                                                  throw new OptionException("Missing parameter name for option -D.", "-D");
                                              configParams.Add(new ConfigParam(param, value));
                                          }
                                      },
                                  {
                                      "S=", "Define a style parameter with a (optional) value.",
                                      (style, value) =>
                                          {
                                              if (style == null)
                                                  throw new OptionException("Missing parameter name/value for option -S.", "-S");
                                              styleParams.Add(new ConfigParam(style, value));
                                          }
                                      },
                                  {"d|style-dir=", "Add a style directory", opt => Config.StyleDirectories.Add(opt) },
                                  {"s|style=", "Specify the style to use [default: Standard]", opt => Config.StyleNames.Add(opt)},
                                  {"o|output=", "Specify the output directory [default: Output]", opt => Config.OutputDirectory = opt},
                                  {"r|searchdir=", "Add search directory in order to load source assemblies", additionalSearchDirectories.Add},
                                  {"w|webdoc=", "Url of the extern documentation site [with the protocol to use, ex: http(s)://...]", 
                                      (protocol, domain) =>
                                        {
                                            if (protocol == null || domain == null)
                                                throw new OptionException("Missing parameter web site home page url for option -w.", "-w");
                                            webDocumentationUrl = WebDocumentation.BuildWebDocumentationUrl(protocol, domain);
                                        }
                                      },
                                  {"wL|webdocLogin="******"(optional) Authentification file for the extern documentation site (first line: username, second line: password)", 
                                      opt =>
                                        {
                                            if (opt == null)
                                                throw new OptionException("Missing parameter web site auth file for option -wL.", "-wL");
                                            if (!File.Exists(opt))
                                                throw new OptionException("Auth config file doesn't exist.", "-wL");
                                            var lines = File.ReadAllLines(opt);
                                            if (lines.Length < 2)
                                                throw new OptionException("Invalid auth config file, should be one line for username, one line for password", "-wL");
                                            webDocumentationLogin = new NetworkCredential(lines[0], lines[1]);
                                        }
                                      },
                                  "",
                                  {"h|help", "Show this message and exit", opt => showHelp = opt != null},
                                  "",
                                  "[Assembly1.dll Assembly1.xml...] Source files, if a config file is not specified, load source assembly and xml from the specified list of files",
                                  // default
                                  {"<>", opt => files.AddRange(opt.Split(' ', '\t')) },
                              };           
            try
            {
                options.Parse(args);

                StyleManager.Init(Config);
            }
            catch (OptionException e)
            {
                UsageError(e.Message);
            }

            if (showHelp)
            {
                options.WriteOptionDescriptions(Console.Out);
                StyleManager.WriteAvailaibleStyles(Console.Out);
                throw new FatalException();
            }

            // Copy config params from command line to current config
            Config.Parameters.AddRange(configParams);
            Config.StyleParameters.AddRange(styleParams);

            // Override webdoc url from commmand line parameters
            if (webDocumentationUrl != null)
            {
                Config.WebDocumentationUrl = webDocumentationUrl;
            }
            if (webDocumentationLogin != null)
            {
                Config.WebDocumentationLogin = webDocumentationLogin;
            }

            // Add files from command line
            if (files.Count > 0)
            {
                ConfigSourceGroup group = null;

                foreach (var file in files)
                {
                    if (group == null)
                    {
                        group = new ConfigSourceGroup {MergeGroup = "default"};
                        Config.Groups.Add(group);
                    }

                    var configSource = new ConfigSource();
                    var ext = Path.GetExtension(file);
                    if (ext != null && ext.ToLower() == ".xml")
                    {
                        configSource.DocumentationPath = file;
                    }
                    else
                    {
                        configSource.AssemblyPath = file;
                    }

                    group.Sources.Add(configSource);
                }
            }

            if (Config.Groups.Count == 0 && Config.RootTopic == null)
                UsageError("At least one option is missing. Either a valid config file (-config) or a direct list of assembly/xml files must be specified");

            // Add global search directories
            foreach (var group in Config.Groups)
            {
                group.SearchDirectories.AddRange(additionalSearchDirectories);
            }

            // Add default style Standard if none is defined
            if (Config.StyleNames.Count == 0)
                Config.StyleNames.Add("Standard");

            // Verify the validity of the style
            foreach (var styleName in Config.StyleNames)
            {
                if (!StyleManager.StyleExist(styleName))
                    UsageError("Style [{0}] does not exist. Use --help to have a list of available styles.", styleName);
            }
        }
        private NAssemblySource LoadAssembly(ConfigSourceGroup group, string source)
        {
            var dirPath          = Path.GetDirectoryName(source);
            var assemblyResolver = new DefaultAssemblyResolver();

            // Remove any default search path
            assemblyResolver.RemoveSearchDirectory(".");
            assemblyResolver.RemoveSearchDirectory("bin");

            // Search from assembly directory
            assemblyResolver.AddSearchDirectory(dirPath);

            // Add additional search directory
            foreach (var searchDirectory in group.SearchDirectories)
            {
                assemblyResolver.AddSearchDirectory(searchDirectory);
            }

            var parameters = new ReaderParameters(ReadingMode.Immediate)
            {
                AssemblyResolver = assemblyResolver
            };

            assemblyResolver.ResolveFailure += (sender, reference) =>
            {
                var searchDirectories = assemblyResolver.GetSearchDirectories();
                foreach (var directory in searchDirectories)
                {
                    var tryPath = Path.Combine(directory, reference.Name + ".winmd");
                    if (!File.Exists(tryPath))
                    {
                        continue;
                    }

                    try
                    {
                        var winmdAssembly = AssemblyDefinition.ReadAssembly(tryPath, parameters);
                        if (winmdAssembly != null)
                        {
                            return(winmdAssembly);
                        }
                    }
                    catch
                    {
                        // Failed... fall thru and try the next one.
                    }
                }

                // Log an error if we can't find the assembly. Mono.Cecil will throw an exception just after returning from
                // this callback
                Logger.Error("Failed to resolve {0}", reference.FullName);
                return(null);
            };

            var assemblyDefinition = AssemblyDefinition.ReadAssembly(source, parameters);
            var assemblySource     = new NAssemblySource(assemblyDefinition)
            {
                Filename   = source,
                MergeGroup = group.MergeGroup
            };

            return(assemblySource);
        }
Exemple #4
0
        /// <summary>
        /// Parses the command line arguments.
        /// </summary>
        /// <param name="args">The args.</param>
        public void ParseArguments(string[] args)
        {
            var showHelp = false;

            var files = new List <string>();

            var               configParams          = new List <ConfigParam>();
            var               styleParams           = new List <ConfigParam>();
            string            webDocumentationUrl   = null;
            NetworkCredential webDocumentationLogin = null;

            var additionalSearchDirectories = new List <string>();

            var options = new OptionSet()
            {
                "Copyright (c) 2010-2013 SharpDoc - Alexandre Mutel",
                "Usage: SharpDoc [options]* [--config file.xml | Assembly1.dll Assembly1.xml...]*",
                "Documentation generator for .Net languages",
                "",
                "options:",
                { "c|config=", "Configuration file", opt => Config = Config.Load(opt, TopicLoader) },

                {
                    "D=", "Define a template parameter with an (optional) value.",
                    (param, value) =>
                    {
                        if (param == null)
                        {
                            throw new OptionException("Missing parameter name for option -D.", "-D");
                        }
                        configParams.Add(new ConfigParam(param, value));
                    }
                },
                {
                    "S=", "Define a style parameter with a (optional) value.",
                    (style, value) =>
                    {
                        if (style == null)
                        {
                            throw new OptionException("Missing parameter name/value for option -S.", "-S");
                        }
                        styleParams.Add(new ConfigParam(style, value));
                    }
                },
                { "d|style-dir=", "Add a style directory", opt => Config.StyleDirectories.Add(opt) },
                { "s|style=", "Specify the style to use [default: Standard]", opt => Config.StyleNames.Add(opt) },
                { "o|output=", "Specify the output directory [default: Output]", opt => Config.OutputDirectory = opt },
                { "r|searchdir=", "Add search directory in order to load source assemblies", additionalSearchDirectories.Add },
                { "w|webdoc=", "Url of the extern documentation site [with the protocol to use, ex: http(s)://...]",
                  (protocol, domain) =>
                  {
                      if (protocol == null || domain == null)
                      {
                          throw new OptionException("Missing parameter web site home page url for option -w.", "-w");
                      }
                      webDocumentationUrl = WebDocumentation.BuildWebDocumentationUrl(protocol, domain);
                  } },
                { "wL|webdocLogin="******"(optional) Authentification file for the extern documentation site (first line: username, second line: password)",
                  opt =>
                  {
                      if (opt == null)
                      {
                          throw new OptionException("Missing parameter web site auth file for option -wL.", "-wL");
                      }
                      if (!File.Exists(opt))
                      {
                          throw new OptionException("Auth config file doesn't exist.", "-wL");
                      }
                      var lines = File.ReadAllLines(opt);
                      if (lines.Length < 2)
                      {
                          throw new OptionException("Invalid auth config file, should be one line for username, one line for password", "-wL");
                      }
                      webDocumentationLogin = new NetworkCredential(lines[0], lines[1]);
                  } },
                "",
                { "h|help", "Show this message and exit", opt => showHelp = opt != null },
                "",
                "[Assembly1.dll Assembly1.xml...] Source files, if a config file is not specified, load source assembly and xml from the specified list of files",
                // default
                { "<>", opt => files.AddRange(opt.Split(' ', '\t')) },
            };

            try
            {
                options.Parse(args);

                StyleManager.Init(Config);
            }
            catch (OptionException e)
            {
                UsageError(e.Message);
            }

            if (showHelp)
            {
                options.WriteOptionDescriptions(Console.Out);
                StyleManager.WriteAvailaibleStyles(Console.Out);
                throw new FatalException();
            }

            // Copy config params from command line to current config
            Config.Parameters.AddRange(configParams);
            Config.StyleParameters.AddRange(styleParams);

            // Override webdoc url from commmand line parameters
            if (webDocumentationUrl != null)
            {
                Config.WebDocumentationUrl = webDocumentationUrl;
            }
            if (webDocumentationLogin != null)
            {
                Config.WebDocumentationLogin = webDocumentationLogin;
            }

            // Add files from command line
            if (files.Count > 0)
            {
                ConfigSourceGroup group = null;

                foreach (var file in files)
                {
                    if (group == null)
                    {
                        group = new ConfigSourceGroup {
                            MergeGroup = "default"
                        };
                        Config.Groups.Add(group);
                    }

                    var configSource = new ConfigSource();
                    var ext          = Path.GetExtension(file);
                    if (ext != null && ext.ToLower() == ".xml")
                    {
                        configSource.DocumentationPath = file;
                    }
                    else
                    {
                        configSource.AssemblyPath = file;
                    }

                    group.Sources.Add(configSource);
                }
            }

            if (Config.Groups.Count == 0 && Config.RootTopic == null)
            {
                UsageError("At least one option is missing. Either a valid config file (-config) or a direct list of assembly/xml files must be specified");
            }

            // Add global search directories
            foreach (var group in Config.Groups)
            {
                group.SearchDirectories.AddRange(additionalSearchDirectories);
            }

            // Add default style Standard if none is defined
            if (Config.StyleNames.Count == 0)
            {
                Config.StyleNames.Add("Standard");
            }

            // Verify the validity of the style
            foreach (var styleName in Config.StyleNames)
            {
                if (!StyleManager.StyleExist(styleName))
                {
                    UsageError("Style [{0}] does not exist. Use --help to have a list of available styles.", styleName);
                }
            }
        }
        private NAssemblySource LoadAssembly(ConfigSourceGroup group, string source)
        {
            var dirPath = Path.GetDirectoryName(source);
            var assemblyResolver = new DefaultAssemblyResolver();
            // Remove any default search path
            assemblyResolver.RemoveSearchDirectory(".");
            assemblyResolver.RemoveSearchDirectory("bin");

            // Search from assembly directory
            assemblyResolver.AddSearchDirectory(dirPath);

            // Add additional search directory
            foreach (var searchDirectory in group.SearchDirectories)
            {
                assemblyResolver.AddSearchDirectory(searchDirectory);
            }

            var parameters = new ReaderParameters(ReadingMode.Immediate) { AssemblyResolver = assemblyResolver };

            assemblyResolver.ResolveFailure += (sender, reference) =>
            {
                var searchDirectories = assemblyResolver.GetSearchDirectories();
                foreach (var directory in searchDirectories)
                {
                    var tryPath = Path.Combine(directory, reference.Name + ".winmd");
                    if (!File.Exists(tryPath))
                        continue;

                    try
                    {
                        var winmdAssembly = AssemblyDefinition.ReadAssembly(tryPath, parameters);
                        if (winmdAssembly != null)
                            return winmdAssembly;
                    }
                    catch
                    {
                        // Failed... fall thru and try the next one.
                    }
                }

                // Log an error if we can't find the assembly. Mono.Cecil will throw an exception just after returning from 
                // this callback
                Logger.Error("Failed to resolve {0}", reference.FullName);
                return null;
            };

            var assemblyDefinition = AssemblyDefinition.ReadAssembly(source, parameters);
            var assemblySource = new NAssemblySource(assemblyDefinition)
            {
                Filename = source,
                MergeGroup = group.MergeGroup
            };
            return assemblySource;
        }
        private void Load(ConfigSourceGroup group, ConfigSource configSource)
        {
            NAssemblySource assemblySource = null;

            if (configSource.AssemblyPath == null)
            {
                Logger.Error("Assembly path not specified for <source>. Cannot be null");
                return;
            }

            // Check Parameters
            if (!File.Exists(configSource.AssemblyPath))
            {
                Logger.Error("Assembly file [{0}] not found", configSource.AssemblyPath);
                return;
            }

            var extension = Path.GetExtension(configSource.AssemblyPath);
            if (extension != null && (extension.ToLower() == ".dll" || extension.ToLower() == ".exe"))
            {
                assemblySource = LoadAssembly(group, configSource.AssemblyPath);
                AssemblySources.Add(assemblySource);
            }
            else
            {
                Logger.Fatal("Invalid Assembly source [{0}]. Must be either an Assembly", configSource.AssemblyPath);
            }

            // If documentation path is null, use by default the assembly path
            if (configSource.DocumentationPath == null)
            {
                configSource.DocumentationPath = Path.ChangeExtension(configSource.AssemblyPath, ".xml");
            }

            if (!File.Exists(configSource.DocumentationPath))
            {
                Logger.Error("Documentation file [{0}] not found", configSource.DocumentationPath);
                return;
            }

            extension = Path.GetExtension(configSource.DocumentationPath);
            if (extension != null && extension.ToLower() == ".xml")
            {
                if (assemblySource == null)
                {
                    assemblySource = new NAssemblySource();
                    AssemblySources.Add(assemblySource);
                }

                assemblySource.Document = LoadAssemblyDocumentation(configSource.DocumentationPath);
            }
            else
            {
                Logger.Fatal("Invalid Assembly source [{0}]. Must be either a Xml comment file", configSource.DocumentationPath);
            }
        }