private static void PublishUpdatedRemoteSourceConfig(RemoteSourcePublishOptions options, TextWriter output)
        {
            output.WriteLine();
            output.WriteCommandText("Generating updated configuration file info (config.json)...");

            var targetFile = Path.Combine(Path.Combine(Path.GetTempPath(), "config.json"));

            Fs.SafeDeleteFile(targetFile);

            TemplatesSourceConfig config = RemoteSource.GetTemplatesSourceConfig(options.StorageAccount, options.Env);

            using (FileStream fs = new FileStream(targetFile, FileMode.CreateNew, FileAccess.Write))
            {
                StreamWriter sw = new StreamWriter(fs, Encoding.UTF8);

                JsonSerializerSettings settings = new JsonSerializerSettings();
                settings.NullValueHandling = NullValueHandling.Ignore;
                settings.Converters.Add(new StringEnumConverter());
                settings.Converters.Add(new VersionConverter());
                string content = JsonConvert.SerializeObject(config, settings);

                sw.WriteLine(content);
                sw.Flush();
            }

            output.WriteCommandText("Updating CND configuration file (config.json)...");
            output.WriteCommandText(RemoteSource.UploadElement(options.StorageAccount, options.AccountKey, options.Env.ToString().ToLowerInvariant(), targetFile));
        }
        public static TemplatesSourceConfig GetTemplatesSourceConfig(string storageAccount, EnvEnum environment)
        {
            string env = environment.ToString().ToLowerInvariant();

            CloudBlobContainer container = GetContainerAnonymous(storageAccount, env);
            var remoteElements           = RemoteSource.GetAllElements(container);
            var remotePackages           = remoteElements.Where(e => e != null && e.Name.StartsWith(env, StringComparison.OrdinalIgnoreCase) && e.Name.EndsWith(".mstx", StringComparison.OrdinalIgnoreCase))
                                           .Select((e) =>
                                                   new TemplatesPackageInfo()
            {
                Name  = e.Name,
                Bytes = e.Properties.Length,
                Date  = e.Properties.LastModified.Value.DateTime
            })
                                           .OrderByDescending(e => e.Date)
                                           .OrderByDescending(e => e.Version)
                                           .GroupBy(e => e.MainVersion)
                                           .Select(e => e.FirstOrDefault());

            TemplatesSourceConfig config = new TemplatesSourceConfig()
            {
                Latest   = remotePackages.FirstOrDefault(),
                Versions = remotePackages.ToList(),
                RootUri  = container.Uri
            };

            return(config);
        }
        public static TemplatesSourceConfig GetTemplatesSourceConfig(string storageAccount, EnvEnum environment)
        {
            string env = environment.ToString().ToLowerInvariant();

            CloudBlobContainer container = GetContainerAnonymous(storageAccount, env);
            var remoteElements           = RemoteSource.GetAllElements(container);
            var remotePackages           = remoteElements.Where(e => e != null && e.Name.StartsWith(env, StringComparison.OrdinalIgnoreCase) && e.Name.EndsWith(".mstx", StringComparison.OrdinalIgnoreCase))
                                           .Select((e) =>
                                                   new TemplatesPackageInfo()
            {
                Name           = e.Name,
                Bytes          = e.Properties.Length,
                Date           = e.Properties.LastModified.Value.DateTime,
                Platform       = e.Metadata.ContainsKey("platform") ? e.Metadata["platform"] : string.Empty,
                Language       = e.Metadata.ContainsKey("language") ? e.Metadata["language"] : string.Empty,
                WizardVersions = e.Metadata.ContainsKey("wizardversion") ? e.Metadata["wizardversion"].Split(';').Select(v => new Version(v)).ToList() : new List <Version>(),
            })
                                           .OrderByDescending(e => e.Date)
                                           .OrderByDescending(e => e.Version)
                                           .GroupBy(e => new { e.MainVersion, e.Language, e.Platform })
                                           .Select(e => e.FirstOrDefault());

            TemplatesSourceConfig config = new TemplatesSourceConfig()
            {
                Latest   = remotePackages.FirstOrDefault(),
                Versions = remotePackages.ToList(),
                RootUri  = container.Uri,
            };

            return(config);
        }
        private static void WriteSummary(TemplatesSourceConfig config, TextWriter output)
        {
            output.WriteCommandText($"Latest Version: {config.Latest?.MainVersion} ({config.Latest.Version?.ToString()})");
            output.WriteCommandText($"Latest Version Uri: {config.RootUri + config.Latest.Name}");

            output.WriteLine();
            output.WriteCommandText($"Available Versions: {string.Join(", ", config.Versions.Select(e => e.MainVersion).ToArray())}");
        }
        private static TemplatesSourceConfig GetConfigFromCdn(EnvEnum env)
        {
            Fs.SafeDeleteFile(Path.Combine(Path.GetTempPath(), "config.json"));
            string configFile = RemoteSource.DownloadCdnElement(Environments.CdnUrls[env], "config.json", Path.GetTempPath());

            TemplatesSourceConfig config = TemplatesSourceConfig.LoadFromFile(configFile);

            return(config);
        }
        public void TemplateSourceConfigTest_ResolveFile()
        {
            var configFile = Path.GetFullPath(@".\Packaging\SampleConfig.json");

            var config = TemplatesSourceConfig.LoadFromFile(configFile);

            var package = config.ResolvePackage(new Version(1, 3), Platforms.Uwp, ProgrammingLanguages.GetShortProgrammingLanguage(ProgrammingLanguages.CSharp));

            Assert.Equal("UWP.CS.Templates_1.2.3.4.mstx", package.Name);
        }
        public void TemplateSourceConfigTest_LoadFromFile()
        {
            var configFile = Path.GetFullPath(@".\Packaging\SampleConfig.json");
            var config     = TemplatesSourceConfig.LoadFromFile(configFile);

            Assert.Equal(new Version(1, 2, 3, 4), config.Latest.Version);
            Assert.Equal("CS", config.Latest.Language);
            Assert.Equal("Uwp", config.Latest.Platform);
            Assert.Equal(new Version(1, 2), config.Latest.WizardVersions[0]);
            Assert.Equal(2, config.Versions.Count());
        }
        private static TemplatesPackageInfo ResolvePackageForVersion(TemplatesSourceConfig config, string version, string platform, string language, TextWriter output)
        {
            Version v = new Version(version);

            if (v.Build != 0 || v.Revision != 0)
            {
                output.WriteCommandText($"WARN: Downloading main version for {v.Major}.{v.Minor}, ignoring the version parts build and revision ({v.Build}.{v.Revision}).");
            }

            TemplatesPackageInfo match = config.ResolvePackage(v, platform, language);

            return(match);
        }
        public static void ListSummaryInfo(RemoteSourceListOptions options, TextWriter output, TextWriter error)
        {
            try
            {
                output.WriteCommandHeader($"Summary Info for environment {options.Env.ToString()} ({options.StorageAccount})");
                TemplatesSourceConfig config = GetConfig(options, output);
                output.WriteLine();

                WriteSummary(config, output);
            }
            catch (Exception ex)
            {
                error.WriteException(ex, $"Unable to list remote source info from enviorment {options.Env.ToString()} (storage account: {options.StorageAccount}).");
            }
        }
        public static void DownloadContent(RemoteSourceDownloadOptions options, TextWriter output, TextWriter error)
        {
            try
            {
                var shortLanguage = ProgrammingLanguages.GetShortProgrammingLanguage(options.Language);

                output.WriteCommandHeader($"Downloading templates content from environment {options.Env.ToString()} ({options.StorageAccount})");

                TemplatesSourceConfig config = GetConfigFromCdn(options.Env);

                TemplatesPackageInfo package = null;
                if (options.Version != null)
                {
                    package = ResolvePackageForVersion(config, options.Version, options.Platform, shortLanguage, output);
                }
                else
                {
                    package = config.Latest;
                }

                if (package != null)
                {
                    Fs.EnsureFolderExists(options.Destination);

                    var result = RemoteSource.DownloadCdnElement(Environments.CdnUrls[options.Env], package.Name, options.Destination);
                    output.WriteLine();
                    output.WriteCommandText($"Successfully downloaded '{result}'");
                    output.WriteLine();
                }
                else
                {
                    output.WriteLine();
                    output.WriteCommandText($"Package not found for the version '{options.Version}', platform '{options.Platform}' and laguage '{options.Language}'");
                    output.WriteLine();
                }
            }
            catch (Exception ex)
            {
                error.WriteException(ex, $"Unable to download the file content from the specified environment.");
            }
        }