public PackageScript(string filename) { Event <Verbose> .Raise("PackageScript", "Constructor"); _sheet = new RootPropertySheet(this); // get the full path to the .autopkgFile FullPath = filename.GetFullPath(); // parse the script _sheet.ParseFile(filename); _sheet.ImportText(_requiredTemplate, "required"); // temp hack to work around static & ltcg getting marked as used when they are just in the template. var scriptText = File.ReadAllText(filename); if (scriptText.IndexOf("static", StringComparison.InvariantCultureIgnoreCase) > -1) { _sheet.ImportText(_requiredTemplateStatic, "required_static"); } // end hack if (scriptText.IndexOf("ltcg", StringComparison.InvariantCultureIgnoreCase) > -1) { _sheet.ImportText(_requiredTemplateLTCG, "required_ltcg"); } // ensure we have at least the package ID var packageName = _sheet.View.nuget.nuspec.id; if (string.IsNullOrEmpty(packageName)) { throw new ClrPlusException("the Field nuget.nuspec.id can not be null or empty. You must specify an id for a package."); } // set the package name macro _sheet.AddMacro("pkgname", packageName); _sheet.CurrentView.AddMacroHandler((name, context) => _macros.ContainsKey(name.ToLower()) ? _macros[name.ToLower()] : null); _sheet.CurrentView.AddMacroHandler((name, context) => System.Environment.GetEnvironmentVariable(name)); Pivots = new Pivots(_sheet.CurrentView.GetProperty("configurations")); }
internal string Save(bool cleanIntermediateFiles, bool generateOnly, out IEnumerable <string> overlayPackages) { List <string> overlays = null; string packageFileName = null; // overlays never really happen for overlay packages. IEnumerable <string> tmpOverlayPackages; // clear out the nuspec files node. _nuSpec.files = null; var temporaryFiles = new List <string>(); var files = _nuSpec.Add("files"); if (PkgRole == PackageRole.@default) { // default xamlUi var xamlText = _defaultUIProperties; if (xamlText.Is()) { var targetFilename = @"default-propertiesui.xml"; var xamlPath = Path.Combine(Directory, targetFilename); xamlPath.TryHardToDelete(); File.WriteAllText(xamlPath, xamlText); temporaryFiles.Add(xamlPath); AddFileToNuSpec(xamlPath, @"\build\native\{0}".format(targetFilename)); Targets.Value.Xml.AddItemGroup().AddItem("PropertyPageSchema", @"$(MSBuildThisFileDirectory)\{0}".format(targetFilename)); } // generated xaml var xaml = GenerateSettingsXaml(); if (xaml != null) { var targetFilename = @"{0}-propertiesui-{1}.xml".format(_pkgName, Guid.NewGuid()); var xamlPath = Path.Combine(Directory, targetFilename); xamlPath.TryHardToDelete(); Event <Verbose> .Raise("NugetPackage.Save", "Saving xaml file [{0}].", xamlPath); xaml.Save(xamlPath); temporaryFiles.Add(xamlPath); AddFileToNuSpec(xamlPath, @"\build\native\{0}".format(targetFilename)); Targets.Value.Xml.AddItemGroup().AddItem("PropertyPageSchema", @"$(MSBuildThisFileDirectory)\{0}".format(targetFilename)); } // save the /build/configurations.autopkg file var configurationsFilename = @"configurations.autopkg"; var cfgPath = Path.Combine(Directory, configurationsFilename); cfgPath.TryHardToDelete(); SaveConfigurationFile(cfgPath); temporaryFiles.Add(cfgPath); AddFileToNuSpec(cfgPath, @"\build\{0}".format(configurationsFilename)); var publisherInfoFilename = @"publisher-info.txt"; var pifPath = Path.Combine(Directory, publisherInfoFilename); pifPath.TryHardToDelete(); SavePifFile(pifPath); temporaryFiles.Add(pifPath); AddFileToNuSpec(pifPath, @"\build\{0}".format(publisherInfoFilename)); string tags = _nuSpec.metadata.tags; tags = tags.Replace(",", " "); if (tags.IndexOf("nativepackage") == -1) { tags = tags + " nativepackage"; } _nuSpec.metadata.tags = tags; // always add the msbuild extensions to the main package AddFileToNuSpec(Path.Combine(etcPath, "CoApp.NuGetNativeMSBuildTasks.dll.orig"), @"\build\native\private\CoApp.NuGetNativeMSBuildTasks.dll.orig"); // first, register all the tasks foreach (var t in MSBuildExtensionTasks) { var usingTask = Targets.Value.Xml.AddUsingTask(t, NuGetPackageOverlayTaskAssembly, null); usingTask.Condition = "'$(DesignTimeBuild)' != 'true' AND ('$(NugetMsBuildExtensionLoaded)' == '' OR '$(NugetMsBuildExtensionLoaded)' == 'false')"; } // 'declare' the property in props var pg = Props.Value.Xml.AddPropertyGroup(); var prop = pg.AddProperty("NugetMsBuildExtensionLoaded", "false"); prop.Condition = "'$(NugetMsBuildExtensionLoaded)' == '' OR '$(NuGet-OverlayLoaded)' == 'false'"; prop = pg.AddProperty(NuGetNativeExtensionPath, NuGetNativeExtensionPathValue); prop.Condition = NuGetNativeExtensionPathCondition; // 'declare' the properties in global scope/ var propName = "Needs-{0}".format(_pkgName); pg.AddProperty(propName, ""); pg.Condition = "'$({0})' == '' OR '$({0})' == '*Undefined*'".format(propName); propName = "Needs-{0}-Version".format(_pkgName); pg.AddProperty(propName, ""); pg.Condition = "'$({0})' == '' OR '$({0})' == '*Undefined*'".format(propName); var initTarget = Targets.Value.EarlyInitTarget.Value; var copyTask = initTarget.AddTask("Copy"); copyTask.SetParameter("SkipUnchangedFiles", "true"); copyTask.SetParameter("SourceFiles", @"$(NuGet-NativeExtensionPath)\coapp.NuGetNativeMSBuildTasks.dll.orig"); copyTask.SetParameter("DestinationFiles", @"$(NuGet-NativeExtensionPath)\coapp.NuGetNativeMSBuildTasks.dll"); pg = initTarget.AddPropertyGroup(); prop = pg.AddProperty("NugetMsBuildExtensionLoaded", "true"); prop.Condition = "'$(NugetMsBuildExtensionLoaded)' == '' OR '$(NuGet-OverlayLoaded)' == 'false'"; // then add the NuGetPackageOverlay tasks into the init target // var task = Targets.Value.LookupTarget("BeforeBuild").AddTask("CheckRuntimeLibrary"); // task.SetParameter("RuntimeLibrary", "%(ClCompile.RuntimeLibrary)"); // task.SetParameter("ExpectedRuntimeLibrary", @"$(ExpectedRuntimeLibrary)"); // task.SetParameter("LibraryName", SafeName); // task.SetParameter("Configuration", ""); } Event <Verbose> .Raise("NugetPackage.Save", "Saving nuget spec file to [{0}].", FullPath); // this is where we decide if we're going to split this into overlays or not. if (PkgRole == PackageRole.@default && _fileSets.Keys.Count > 1 && _fileSets.Keys.SelectMany(set => _fileSets[set].Values).Sum(srcPath => new FileInfo(srcPath).Length) > SplitThreshold) { // ok, this package is gonna get split // first, add the init target stuff in the .props var initTarget = Props.Value.EarlyInitTarget.Value; var pg = initTarget.AddPropertyGroup(); // version check. var wantVer = ((UInt64)((FourPartVersion)(string)_nuSpec.metadata.version)).ToString(); var nvPropName = "Needs-{0}-Version".format(_pkgName); var propName = "Needs-{0}".format(_pkgName); var prop = pg.AddProperty(nvPropName, (string)_nuSpec.metadata.version); prop.Condition = "'$({0})' == '' OR $({0}) < {1} ".format(propName, wantVer); prop = pg.AddProperty(propName, wantVer); prop.Condition = "'$({0})' == '' OR $({0}) < {1} ".format(propName, wantVer); // then add the init target stuff in the .targets // now, iterate thru each file set, and create an overlay package for just those files // (If the size of a whole file set is less than 100k, we'll just add it to the main package) foreach (var set in _fileSets.Keys.Where(each => each.Is())) { long setSize = _fileSets[set].Values.Sum(srcPath => new FileInfo(srcPath).Length); if (setSize < (MinimumPivotSize)) { foreach (var src in _fileSets[set].Keys) { AddFileToNuSpec(_fileSets[set][src], src); } } else { overlays = overlays ?? new List <string>(); var overlayPackageName = "{0}.overlay-{1}".format(_pkgName, Pivots.GetExpressionFilename("", set)); // create a seperate package file using (var pkg = new NugetPackage(_packageScript, PackageRole.overlay, overlayPackageName)) { pkg._fileSets.Add(string.Empty, _fileSets[set]); pkg.Process(); pkg.Save(cleanIntermediateFiles, generateOnly, out tmpOverlayPackages); // add each overlay package created to the master list of overlays overlays.Add(overlayPackageName); // iterate thru all the files in the base set, and add them to this package's list foreach (var src in _fileSets[string.Empty].Keys) { AddFileToNuSpec(_fileSets[string.Empty][src], src); } // then add the NuGetPackageOverlay tasks into the init target var task = Targets.Value.EarlyInitTarget.Value.AddTask("NuGetPackageOverlay"); task.SetParameter("Package", overlayPackageName); task.SetParameter("Version", "$({0})".format(nvPropName)); task.SetParameter("PackageDirectory", @"$(MSBuildThisFileDirectory)\..\.."); task.SetParameter("SolutionDirectory", @"$(SolutionDir)"); // set the condition for the overlay to the appropriate condition pivot. task.Condition = Pivots.GetMSBuildCondition(Targets.Value.Name, set); } } } if (overlays != null && overlays.Count > 0) { // add the two DLLs and the nuget.exe into the package. AddFileToNuSpec(Path.Combine(etcPath, "CoApp.NuGetNativeExtensions.dll"), @"\build\native\private\CoApp.NuGetNativeExtensions.dll"); AddFileToNuSpec(Path.Combine(etcPath, "nuget.exe"), @"\build\native\private\nuget.exe"); // add the cmd script to the root of the package var cmdScriptPath = Path.Combine(etcPath, "nuget-overlay.cmd"); var scriptText = File.ReadAllText(cmdScriptPath).Replace("$$VERSION$$", (string)_nuSpec.metadata.version); var scriptPath = Path.Combine(Directory, @"NuGet-Overlay.cmd"); scriptPath.TryHardToDelete(); File.WriteAllText(scriptPath, scriptText); temporaryFiles.Add(scriptPath); AddFileToNuSpec(scriptPath, @"\NuGet-Overlay.cmd"); var pivotListPath = Path.Combine(Directory, @"pivot-list.txt"); pivotListPath.TryHardToDelete(); File.WriteAllLines(pivotListPath, overlays.ToArray()); temporaryFiles.Add(pivotListPath); AddFileToNuSpec(pivotListPath, @"\build\native\pivot-list.txt"); } } else { // single package foreach (var set in _fileSets.Keys) { foreach (var src in _fileSets[set].Keys) { AddFileToNuSpec(_fileSets[set][src], src); } } } if (Props.IsValueCreated && Props.Value.Xml.Children.Count > 0) { Props.Value.FullPath.TryHardToDelete(); if (Props.Value.Save()) { temporaryFiles.Add(Props.Value.FullPath); AddFileToNuSpec(Props.Value.FullPath, @"\build\native\{0}".format(Props.Value.Filename)); } } if (Targets.IsValueCreated && Targets.Value.Xml.Children.Count > 0) { Targets.Value.FullPath.TryHardToDelete(); if (Targets.Value.Save()) { temporaryFiles.Add(Targets.Value.FullPath); AddFileToNuSpec(Targets.Value.FullPath, @"\build\native\{0}".format(Targets.Value.Filename)); } } _nuSpec.Save(FullPath); temporaryFiles.Add(FullPath); if (PkgRole == PackageRole.@default || !_fileSets.Values.IsNullOrEmpty()) { // don't save the package if it has no files in it. if (!generateOnly) { packageFileName = NuPack(FullPath); Event <OutputObject> .Raise(new FileInfo(packageFileName.GetFullPath())); } } if (generateOnly) { foreach (var t in temporaryFiles) { Event <OutputObject> .Raise(new FileInfo(t.GetFullPath())); } } if (cleanIntermediateFiles) { temporaryFiles.ForEach(FilesystemExtensions.TryHardToDelete); } overlayPackages = overlays ?? Enumerable.Empty <string>(); return(packageFileName); }