public static void Generate(AssemblyGeneratorContext context, TextWriter errorOutput) { var referenceAssemblies = AssemblyReflecter.ProbeReferenceAssemblies(context.TemporaryPath); context.SourceAssembly = SpecFlowUtils.ProbeProjectAssemblyName(referenceAssemblies, context.TemporaryPath); var addedSpecRun = AddSpecRunIfNecessary(context, referenceAssemblies); var specFlowProject = SpecFlowUtils.ReadSpecFlowProject(context.TemporaryPath, context.SourceAssembly, context.DefaultNamespace); var generator = SpecFlowUtils.SetupGenerator(context.VerboseOutput, errorOutput); generator.ProcessProject(specFlowProject, false /* forceGeneration */); GenerateFeatureAssembly( context.TemporaryPath, referenceAssemblies.Select(assembly => assembly.FullPath).ToArray(), context.OutputPath, context.FeatureAssemblyName); CopyGeneratedAssemblies(context, addedSpecRun); GenerateConfiguration( Path.Combine(context.SourcePath, context.FeatureDllName + ".config"), AssemblyReflecter.GetStepAssemblyNames(referenceAssemblies, context.TemporaryPath)); DeleteRedundantFiles(context.TemporaryPath); }
private static void WriteSpecRunToSourcePath(AssemblyGeneratorContext context, bool addedSpecRun) { const string template = @"<?xml version=""1.0"" encoding=""utf-8""?> <TestProfile xmlns=""http://www.specflow.org/schemas/plus/TestProfile/1.5""> <Settings projectName=""{0}"" projectId=""{{{1}}}"" /> <Execution stopAfterFailures=""3"" testThreadCount=""1"" testSchedulingMode=""Sequential"" /> <TestAssemblyPaths> <TestAssemblyPath>{2}</TestAssemblyPath> </TestAssemblyPaths> <DeploymentTransformation> <Steps> </Steps> </DeploymentTransformation> </TestProfile>"; var specRunDll = Path.Combine(context.SourcePath, SpecRunAssemblyName); if (addedSpecRun && !File.Exists(specRunDll)) { File.Copy(Path.Combine(context.TemporaryPath, SpecRunAssemblyName), specRunDll, true); } var usingSpecRun = File.Exists(specRunDll); var srProfilePath = Path.Combine(context.SourcePath, (context.SpecifiedFeatureAssemblyName ?? context.SourceAssembly.AssemblyName) + ".srprofile"); if (usingSpecRun && !File.Exists(srProfilePath)) { var srProfile = string.Format(template, context.SourceAssembly.AssemblyName, Guid.NewGuid().ToString(), context.FeatureDllName); File.WriteAllText(srProfilePath, srProfile, System.Text.Encoding.UTF8); } }
static void CopyGeneratedAssemblies(AssemblyGeneratorContext context, bool addedSpecRun) { File.Copy(Path.Combine(context.OutputPath, context.FeatureDllName), Path.Combine(context.SourcePath, context.FeatureDllName), true); File.Copy(Path.Combine(context.OutputPath, context.FeatureAssemblyName + ".pdb"), Path.Combine(context.SourcePath, context.FeatureAssemblyName + ".pdb"), true); WriteSpecRunToSourcePath(context, addedSpecRun); }
public static void Register(CommandLineApplication cmdApp) { cmdApp.Command("generate", command => { command.Description = "Produce assembly for the project containing .feature cases."; var argProjectDir = command.Argument("[project]", "Optional. A folder path containing the project with .feature cases. The working directory will be used if not specified.", multipleValues: false); var optAssemblyName = command.Option("--assembly-name <ASSEMBLY_NAME>", "Optional. The name of the generated assembly. A random one will be used if not specified", CommandOptionType.SingleValue); var optDefaultNamespace = command.Option("--namespace <DEFAULT_NAMESPACE>", "The default namespace used to generate feature classes.", CommandOptionType.SingleValue); var optVerbose = command.Option("-v|--verbose", "Show verbose output", CommandOptionType.NoValue); command.HelpOption("-?|-h|--help"); command.OnExecute(() => { var basePath = argProjectDir.Value; basePath = Path.IsPathRooted(basePath) ? basePath : Environment.CurrentDirectory; var context = new AssemblyGeneratorContext { VerboseOutput = optVerbose.HasValue(), DefaultNamespace = optDefaultNamespace.Value(), SourcePath = basePath, SpecifiedFeatureAssemblyName = optAssemblyName.Value(), TemporaryPath = Path.Combine(Path.GetTempPath(), "SpecFlowFeatureAssemblyGenerator", "f" + Guid.NewGuid().ToString("N").Substring(0, 9)) }; return(Run(context)); }); }); }
static bool AddSpecRunIfNecessary(AssemblyGeneratorContext context, IList <LoadedAssembly> referenceAssemblies) { if (context.SourceAssembly.HasSpecFlowConfigured) { return(false); } var specRunPath = Path.Combine(context.TemporaryPath, SpecRunAssemblyName); var addSpecRun = !File.Exists(specRunPath); if (addSpecRun) { File.Copy(Path.Combine(DirectoryUtils.GetContainingDirectory(Assembly.GetExecutingAssembly().Location), SpecRunAssemblyName), specRunPath, true); referenceAssemblies.Add(new LoadedAssembly { FullPath = specRunPath, Definition = null }); } return(addSpecRun); }
static int Run(AssemblyGeneratorContext context) { var defaultColor = Console.ForegroundColor; var exitCode = 0; try { if (context.VerboseOutput) { Console.WriteLine("Generating source code using temporary path {0}", context.TemporaryPath); } Directory.CreateDirectory(context.TemporaryPath); Directory.CreateDirectory(context.OutputPath); DirectoryUtils.CopyDirectory(context.SourcePath, context.TemporaryPath); AssemblyGenerator.Generate(context, Console.Error); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Successfully generated assembly {0}", context.FeatureDllName); } catch (Exception ex) { Console.ForegroundColor = ConsoleColor.DarkRed; Console.Error.WriteLine("Could not generate assembly for the project."); Console.ForegroundColor = defaultColor; if (context.VerboseOutput) { Console.Error.WriteLine(ex.Message); Console.Error.WriteLine(ex.StackTrace); } exitCode = -1; } finally { Console.ForegroundColor = defaultColor; } return(exitCode); }