/// <summary>
        /// Extracts the workload manifest from the manifest package and generate a SWIX project for a Visual Studio component
        /// matching the manifests dependencies.
        /// </summary>
        /// <param name="workloadManifestPackage">The path of the workload package containing the manifest.</param>
        /// <returns>A set of items containing the generated SWIX projects.</returns>
        internal IEnumerable <ITaskItem> ProcessWorkloadManifest(string workloadManifestPackage)
        {
            NugetPackage workloadPackage = new(workloadManifestPackage, Log);

            string packageContentPath = Path.Combine(PackageDirectory, $"{workloadPackage.Identity}");

            workloadPackage.Extract(packageContentPath, Enumerable.Empty <string>());
            string workloadManifestJsonPath = Directory.GetFiles(packageContentPath, "WorkloadManifest.json").FirstOrDefault();

            if (string.IsNullOrWhiteSpace(workloadManifestJsonPath))
            {
                throw new FileNotFoundException($"Unable to locate WorkloadManifest.json under '{packageContentPath}'.");
            }

            WorkloadManifest manifest = WorkloadManifestReader.ReadWorkloadManifest(File.OpenRead(workloadManifestJsonPath));

            List <TaskItem> swixProjects = new();

            foreach (WorkloadDefinition workloadDefinition in manifest.Workloads.Values)
            {
                VisualStudioComponent component = VisualStudioComponent.Create(manifest, workloadDefinition);
                swixProjects.Add(component.Generate(Path.Combine(SourceDirectory, $"{workloadDefinition.Id}.{manifest.Version}.0")));
            }

            return(swixProjects);
        }
Example #2
0
        internal static ReleaseVersion GetValidatedSdkVersion(string versionOption, string providedVersion, string dotnetPath, string userProfileDir)
        {
            if (string.IsNullOrEmpty(versionOption))
            {
                return(new ReleaseVersion(providedVersion ?? Product.Version));
            }
            else
            {
                var manifests = new SdkDirectoryWorkloadManifestProvider(dotnetPath, versionOption, userProfileDir).GetManifests();
                if (!manifests.Any())
                {
                    throw new GracefulException(string.Format(LocalizableStrings.NoManifestsExistForFeatureBand, new SdkFeatureBand(versionOption).ToString()), isUserError: false);
                }
                try
                {
                    foreach (var readableManifest in manifests)
                    {
                        using (var manifestStream = readableManifest.OpenManifestStream())
                            using (var localizationStream = readableManifest.OpenLocalizationStream())
                            {
                                var manifest = WorkloadManifestReader.ReadWorkloadManifest(readableManifest.ManifestId, manifestStream, localizationStream, readableManifest.ManifestPath);
                            }
                    }
                }
                catch
                {
                    throw new GracefulException(string.Format(LocalizableStrings.IncompatibleManifests, versionOption), isUserError: false);
                }

                return(new ReleaseVersion(versionOption));
            }
        }
Example #3
0
        internal IEnumerable <ITaskItem> ProcessWorkloadManifestFile(string workloadManifestJsonPath)
        {
            WorkloadManifest manifest = WorkloadManifestReader.ReadWorkloadManifest(Path.GetFileNameWithoutExtension(workloadManifestJsonPath), File.OpenRead(workloadManifestJsonPath));

            List <TaskItem> swixProjects = new();

            foreach (WorkloadDefinition workloadDefinition in manifest.Workloads.Values)
            {
                if ((workloadDefinition.Platforms?.Count > 0) && (!workloadDefinition.Platforms.Any(p => p.StartsWith("win"))))
                {
                    Log?.LogMessage(MessageImportance.High, $"{workloadDefinition.Id} platforms does not support Windows and will be skipped ({string.Join(", ", workloadDefinition.Platforms)}).");
                    continue;
                }

                // Each workload maps to a Visual Studio component.
                VisualStudioComponent component = VisualStudioComponent.Create(Log, manifest, workloadDefinition,
                                                                               ComponentVersions, ShortNames, ComponentResources, MissingPacks);

                // If there are no dependencies, regardless of whether we are generating MSIs, we'll report an
                // error as we'd produce invalid SWIX.
                if (!component.HasDependencies)
                {
                    Log?.LogError($"Visual Studio components '{component.Name}' must have at least one dependency.");
                }

                string vsPayloadRelativePath = $"{component.Name},version={component.Version}\\_package.json";
                CheckRelativePayloadPath(vsPayloadRelativePath);

                swixProjects.Add(component.Generate(Path.Combine(SourceDirectory, $"{workloadDefinition.Id}.{manifest.Version}.0")));
            }

            return(swixProjects);
        }
Example #4
0
        internal static ReleaseVersion GetValidatedSdkVersion(string versionOption, string providedVersion, string dotnetPath)
        {
            if (string.IsNullOrEmpty(versionOption))
            {
                return(new ReleaseVersion(providedVersion ?? Product.Version));
            }
            else
            {
                var manifests = new SdkDirectoryWorkloadManifestProvider(dotnetPath, versionOption).GetManifests();
                if (!manifests.Any())
                {
                    throw new GracefulException(string.Format(LocalizableStrings.NoManifestsExistForFeatureBand, versionOption));
                }
                try
                {
                    foreach ((string manifestId, string informationalPath, Func <Stream> openManifestStream) in manifests)
                    {
                        using (var manifestStream = openManifestStream())
                        {
                            var manifest = WorkloadManifestReader.ReadWorkloadManifest(manifestId, manifestStream);
                        }
                    }
                }
                catch
                {
                    throw new GracefulException(string.Format(LocalizableStrings.IncompatibleManifests, versionOption));
                }

                return(new ReleaseVersion(versionOption));
            }
        }
Example #5
0
        GetAdvertisingManifestVersionAndWorkloads(ManifestId manifestId)
        {
            var manifestPath = Path.Combine(GetAdvertisingManifestPath(_sdkFeatureBand, manifestId),
                                            "WorkloadManifest.json");

            if (!File.Exists(manifestPath))
            {
                return(null);
            }

            using (FileStream fsSource = new FileStream(manifestPath, FileMode.Open, FileAccess.Read))
            {
                var manifest = WorkloadManifestReader.ReadWorkloadManifest(manifestId.ToString(), fsSource, manifestPath);
                // we need to know the feature band of the advertised manifest (read it from the AdvertisedManifestFeatureBand.txt file)
                // if we don't find the file then use the current feature band
                var adManifestFeatureBandPath = Path.Combine(GetAdvertisingManifestPath(_sdkFeatureBand, manifestId), "AdvertisedManifestFeatureBand.txt");

                SdkFeatureBand adManifestFeatureBand = _sdkFeatureBand;
                if (File.Exists(adManifestFeatureBandPath))
                {
                    adManifestFeatureBand = new SdkFeatureBand(File.ReadAllText(adManifestFeatureBandPath));
                }


                return(new ManifestVersion(manifest.Version), adManifestFeatureBand, manifest.Workloads.Values.OfType <WorkloadDefinition>().ToDictionary(w => w.Id));
            }
        }
Example #6
0
        internal static IEnumerable <WorkloadPack> GetWorkloadPacks(ITaskItem[] workloadManifestItems)
        {
            // We need to track duplicate packs (same ID and version) so we only build MSIs once when processing
            // multiple manifests. We'll manually deduplicate the packs
            // since WorkloadPack doesn't provide an override for GetHashCode/Equals.
            Dictionary <string, WorkloadPack> packs = new();

            foreach (ITaskItem item in workloadManifestItems)
            {
                var workloadManifest = WorkloadManifestReader.ReadWorkloadManifest(
                    Path.GetFileNameWithoutExtension(item.ItemSpec), File.OpenRead(item.ItemSpec), item.ItemSpec);

                foreach (var workload in workloadManifest.Workloads.Values)
                {
                    if ((workload is WorkloadDefinition wd) && (wd.Platforms == null || wd.Platforms.Any(p => p.StartsWith("win"))) && (wd.Packs != null))
                    {
                        foreach (var packId in wd.Packs)
                        {
                            var    pack = workloadManifest.Packs[packId];
                            string key  = $"{pack.Id},{pack.Version}";

                            if (!packs.ContainsKey(key))
                            {
                                packs[key] = pack;
                            }
                        }
                    }
                }
            }

            return(packs.Values);
        }
 private static WorkloadManifest Create(string filename)
 {
     return(WorkloadManifestReader.ReadWorkloadManifest(
                Path.GetFileNameWithoutExtension(filename),
                File.OpenRead(Path.Combine(AppContext.BaseDirectory, "testassets", filename)),
                filename));
 }
Example #8
0
        private IEnumerable <WorkloadPack> GetWorkloadPacks()
        {
            // We need to track duplicate packs so we only generate MSIs once. We'll key off the pack ID and version.
            IEnumerable <WorkloadManifest> manifests = WorkloadManifests.Select(
                w => WorkloadManifestReader.ReadWorkloadManifest(File.OpenRead(w.ItemSpec)));

            return(manifests.SelectMany(m => m.Packs.Values).GroupBy(x => new { x.Id, x.Version }).
                   Select(g => g.First()));
        }
Example #9
0
        public IEnumerable <(string id, string version)> GetInstalledWorkloads()
        {
            foreach (var manifestInfo in manifestProvider.GetManifests())
            {
                var m = WorkloadManifestReader.ReadWorkloadManifest(manifestInfo.manifestId, manifestInfo.manifestStream);

                // Each workload manifest can have one or more workloads defined
                foreach (var wl in m.Workloads)
                {
                    yield return(wl.Key.ToString(), m.Version);
                }
            }
        }
Example #10
0
        public void ItCanDeserialize()
        {
            using (FileStream fsSource = new FileStream(ManifestPath, FileMode.Open, FileAccess.Read))
            {
                var result = WorkloadManifestReader.ReadWorkloadManifest("Sample", fsSource);
                result.Version.Should().Be("5.0.0-preview1");
                var xamAndroidId = new WorkloadPackId("Xamarin.Android.Sdk");

                result.Packs[xamAndroidId].Id.Should().Be(xamAndroidId);
                result.Packs[xamAndroidId].IsAlias.Should().Be(false);
                result.Packs[xamAndroidId].Kind.Should().Be(WorkloadPackKind.Sdk);
                result.Packs[xamAndroidId].Version.Should().Be("8.4.7");
            }
        }
Example #11
0
        private ManifestVersion GetAdvertisingManifestVersion(ManifestId manifestId)
        {
            var manifestPath = Path.Combine(GetAdvertisingManifestPath(_sdkFeatureBand, manifestId), "WorkloadManifest.json");

            if (!File.Exists(manifestPath))
            {
                return(null);
            }

            using (FileStream fsSource = new FileStream(manifestPath, FileMode.Open, FileAccess.Read))
            {
                var manifest = WorkloadManifestReader.ReadWorkloadManifest(manifestId.ToString(), fsSource);
                return(new ManifestVersion(manifest.Version));
            }
        }
Example #12
0
        GetAdvertisingManifestVersionAndWorkloads(ManifestId manifestId)
        {
            var manifestPath = Path.Combine(GetAdvertisingManifestPath(_sdkFeatureBand, manifestId),
                                            "WorkloadManifest.json");

            if (!File.Exists(manifestPath))
            {
                return(null);
            }

            using (FileStream fsSource = new FileStream(manifestPath, FileMode.Open, FileAccess.Read))
            {
                var manifest = WorkloadManifestReader.ReadWorkloadManifest(manifestId.ToString(), fsSource);
                return(new ManifestVersion(manifest.Version), manifest.Workloads.Values.OfType <WorkloadDefinition>().ToDictionary(w => w.Id));
            }
        }
Example #13
0
        Dictionary <string, string> GetInstalledWorkloadManifestIdsAndVersions()
        {
            var items = new Dictionary <string, string>();

            var manifestProvider = new SdkDirectoryWorkloadManifestProvider(SdkRoot, SdkVersion, null);

            foreach (var manifestInfo in manifestProvider.GetManifests())
            {
                using (var manifestStream = manifestInfo.openManifestStream())
                {
                    var m = WorkloadManifestReader.ReadWorkloadManifest(manifestInfo.manifestId, manifestStream);
                    items[manifestInfo.manifestId] = m.Version;
                }
            }

            return(items);
        }
        public void ManifestReaderCanReadManifests()
        {
            var sdkManifestDir = Path.Combine(Path.GetDirectoryName(RepoDirectoriesProvider.DotnetUnderTest), "sdk-manifests");
            var sdkversionDir  = new DirectoryInfo(sdkManifestDir).EnumerateDirectories().First();

            foreach (var manifestDir in sdkversionDir.EnumerateDirectories())
            {
                var manifestId = manifestDir.Name;

                string manifestFile = manifestDir.GetFile("WorkloadManifest.json").FullName;

                File.Exists(manifestFile).Should().BeTrue();
                using var fileStream = new FileStream(manifestFile, FileMode.Open, FileAccess.Read);
                Action readManifest = () => WorkloadManifestReader.ReadWorkloadManifest(manifestId, fileStream);
                readManifest.ShouldNotThrow("manifestId:" + manifestId + " manifestFile:" + manifestFile + "is invalid");
            }
        }
Example #15
0
        private IEnumerable <WorkloadPack> GetWorkloadPacks()
        {
            // We need to track duplicate packs so we only generate MSIs once. We'll key off the pack ID and version.
            IEnumerable <WorkloadManifest> manifests = WorkloadManifests.Select(
                w => WorkloadManifestReader.ReadWorkloadManifest(Path.GetFileNameWithoutExtension(w.ItemSpec), File.OpenRead(w.ItemSpec)));

            // We want all workloads in all manifests iff the workload has no platform or at least one
            // platform includes Windows
            var workloads = manifests.SelectMany(m => m.Workloads).
                            Select(w => w.Value).
                            Where(wd => (wd.Platforms == null) || wd.Platforms.Any(p => p.StartsWith("win")));

            var packIds = workloads.Where(w => w.Packs != null).SelectMany(w => w.Packs).Distinct();

            return(manifests.SelectMany(m => m.Packs.Values).
                   Where(p => packIds.Contains(p.Id)).
                   Distinct());
        }
Example #16
0
        public IEnumerable <(string id, string version)> GetInstalledWorkloads()
        {
            var manifestProvider = new SdkDirectoryWorkloadManifestProvider(SdkRoot, SdkVersion, null);

            foreach (var manifestInfo in manifestProvider.GetManifests())
            {
                using (var manifestStream = manifestInfo.openManifestStream())
                {
                    var m = WorkloadManifestReader.ReadWorkloadManifest(manifestInfo.manifestId, manifestStream);

                    // Each workload manifest can have one or more workloads defined
                    foreach (var wl in m.Workloads)
                    {
                        yield return(wl.Key.ToString(), m.Version);
                    }
                }
            }
        }
Example #17
0
        public IEnumerable <WorkloadManifest> GetManifests(SdkDirectoryWorkloadManifestProvider?manifestProvider = null)
        {
            manifestProvider ??= CreateManifestProvider();
            List <WorkloadManifest> manifests = new List <WorkloadManifest>();

            foreach (var readableManifest in manifestProvider.GetManifests())
            {
                if (readableManifest.ManifestId.Equals("Microsoft.NET.Sdk.TestWorkload"))
                {
                    //  Ignore test workload for this
                    continue;
                }
                using (var stream = readableManifest.OpenManifestStream())
                {
                    var manifest = WorkloadManifestReader.ReadWorkloadManifest(readableManifest.ManifestId, stream, readableManifest.ManifestPath);
                    manifests.Add(manifest);
                }
            }

            return(manifests);
        }
Example #18
0
        private ManifestVersion GetInstalledManifestVersion(ManifestId manifestId)
        {
            var manifestDir = _workloadManifestProvider.GetManifestDirectories()
                              .FirstOrDefault(dir => Path.GetFileName(dir).ToLowerInvariant().Equals(manifestId.ToString()));

            if (manifestDir == null)
            {
                throw new Exception(string.Format(LocalizableStrings.ManifestDoesNotExist, manifestId.ToString()));
            }

            var manifestPath = Path.Combine(manifestDir, "WorkloadManifest.json");

            if (!File.Exists(manifestPath))
            {
                throw new Exception(string.Format(LocalizableStrings.ManifestDoesNotExist, manifestId.ToString()));
            }

            using (FileStream fsSource = new FileStream(manifestPath, FileMode.Open, FileAccess.Read))
            {
                var manifest = WorkloadManifestReader.ReadWorkloadManifest(manifestId.ToString(), fsSource);
                return(new ManifestVersion(manifest.Version));
            }
        }
        internal IEnumerable <ITaskItem> ProcessWorkloadManifestFile(string workloadManifestJsonPath)
        {
            WorkloadManifest manifest = WorkloadManifestReader.ReadWorkloadManifest(Path.GetFileNameWithoutExtension(workloadManifestJsonPath), File.OpenRead(workloadManifestJsonPath));

            List <TaskItem> swixProjects = new();

            foreach (WorkloadDefinition workloadDefinition in manifest.Workloads.Values)
            {
                // Each workload maps to a Visual Studio component.
                VisualStudioComponent component = VisualStudioComponent.Create(Log, manifest, workloadDefinition,
                                                                               ComponentVersion, ShortNames, ComponentResources, MissingPacks);

                // If there are no dependencies, regardless of whether we are generating MSIs, we'll report an
                // error as we'd produce invalid SWIX.
                if (!component.HasDependencies)
                {
                    Log?.LogError($"Visual Studio components '{component.Name}' must have at least one dependency.");
                }

                swixProjects.Add(component.Generate(Path.Combine(SourceDirectory, $"{workloadDefinition.Id}.{manifest.Version}.0")));
            }

            return(swixProjects);
        }
        public override bool Execute()
        {
            try
            {
                Directory.CreateDirectory(Path.GetDirectoryName(ProjectFile));

                List <string> packs = new();

                var excludedPackIds = ExcludedPackIds.Select(i => i.ItemSpec);

                XmlWriterSettings settings = new XmlWriterSettings
                {
                    Indent      = true,
                    IndentChars = "  "
                };

                XmlWriter writer = XmlWriter.Create(ProjectFile, settings);

                writer.WriteStartElement("Project");
                writer.WriteAttributeString("Sdk", "Microsoft.NET.Sdk");

                writer.WriteStartElement("PropertyGroup");
                writer.WriteElementString("TargetFramework", "net6.0");
                writer.WriteElementString("IncludeBuildOutput", "false");
                writer.WriteEndElement();

                writer.WriteStartElement("ItemGroup");

                foreach (var manifestFile in ManifestFiles)
                {
                    WorkloadManifest manifest = WorkloadManifestReader.ReadWorkloadManifest(
                        Path.GetFileNameWithoutExtension(manifestFile.ItemSpec), File.OpenRead(manifestFile.ItemSpec), manifestFile.ItemSpec);

                    foreach (var pack in manifest.Packs.Values)
                    {
                        if (pack.IsAlias)
                        {
                            foreach (var alias in pack.AliasTo.Keys.Where(k => k.StartsWith("win")))
                            {
                                if (!excludedPackIds.Contains($"{pack.AliasTo[alias]}"))
                                {
                                    WriteItem(writer, "PackageDownload", ("Include", $"{pack.AliasTo[alias]}"), ("Version", $"[{pack.Version}]"));
                                    packs.Add($"$(NuGetPackageRoot){pack.AliasTo[alias]}\\{pack.Version}\\*.nupkg");
                                }
                            }
                        }
                        else if (!excludedPackIds.Contains($"{pack.Id}"))
                        {
                            WriteItem(writer, "PackageDownload", ("Include", $"{pack.Id}"), ("Version", $"[{pack.Version}]"));
                            packs.Add($"$(NuGetPackageRoot){pack.Id}\\{pack.Version}\\*.nupkg");
                        }
                    }
                }

                writer.WriteEndElement();

                writer.WriteStartElement("Target");
                writer.WriteAttributeString("Name", "CopyPacks");
                writer.WriteAttributeString("AfterTargets", "Build");

                writer.WriteStartElement("ItemGroup");

                foreach (var pack in packs)
                {
                    WriteItem(writer, "Pack", ("Include", pack));
                }

                writer.WriteEndElement();

                writer.WriteStartElement("Copy");
                writer.WriteAttributeString("SourceFiles", "@(Pack)");
                writer.WriteAttributeString("DestinationFolder", $"{PackageSource}");
                writer.WriteEndElement();

                writer.WriteEndElement();

                writer.WriteEndElement();
                writer.Flush();
                writer.Close();
            }
            catch (Exception e)
            {
                Log.LogErrorFromException(e);
            }

            return(!Log.HasLoggedErrors);
        }