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); } }
/// <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); }
/// <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; }