From feb0f5d712fee078fa9a03e6ed6fbececd857e01 Mon Sep 17 00:00:00 2001 From: laggingreflex Date: Fri, 16 Feb 2018 11:59:29 +0530 Subject: [PATCH 1/5] feat: create directory prompt --- src/ChocolateStore/Program.cs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/ChocolateStore/Program.cs b/src/ChocolateStore/Program.cs index 50a2c94..bf9dcbc 100644 --- a/src/ChocolateStore/Program.cs +++ b/src/ChocolateStore/Program.cs @@ -47,8 +47,13 @@ private static Arguments ParseArguments(string[] args) if (!Directory.Exists(arguments.Directory)) { - WriteError("Directory '{0}' does not exist.", arguments.Directory); - return null; + if (!PromptConfirm("Directory '{0}' does not exist. Create?", arguments.Directory)) + { + WriteError("Directory '{0}' does not exist.", arguments.Directory); + return null; + } + Directory.CreateDirectory(arguments.Directory); + Console.WriteLine("Created Directory '{0}'", arguments.Directory); } arguments.Url = args[1]; @@ -100,5 +105,15 @@ private static void WriteError(string format, params object[] arg) Console.ResetColor(); } + private static bool PromptConfirm(string format, params object[] arg) + { + Console.ForegroundColor = ConsoleColor.DarkCyan; + Console.Write(format + " [y/n] ", arg); + Console.ResetColor(); + ConsoleKey response = Console.ReadKey(false).Key; + Console.WriteLine(); + return response == ConsoleKey.Y; + } + } } From 13d30fdc8c9a6e9de7d2ec43de0cff413016026c Mon Sep 17 00:00:00 2001 From: laggingreflex Date: Fri, 16 Feb 2018 16:29:51 +0530 Subject: [PATCH 2/5] feat: accept package-name (auto-resolve URL) --- src/ChocolateStore/Arguments.cs | 1 + src/ChocolateStore/ChocolateStore.csproj | 4 ++++ src/ChocolateStore/PackageCacher.cs | 22 +++++++++++++++++++--- src/ChocolateStore/Program.cs | 12 ++++++------ src/ChocolateStore/packages.config | 1 + 5 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/ChocolateStore/Arguments.cs b/src/ChocolateStore/Arguments.cs index 8c515b4..0e1dedb 100644 --- a/src/ChocolateStore/Arguments.cs +++ b/src/ChocolateStore/Arguments.cs @@ -4,5 +4,6 @@ class Arguments { public string Directory { get; set; } public string Url { get; set; } + public string PackageName { get; set; } } } diff --git a/src/ChocolateStore/ChocolateStore.csproj b/src/ChocolateStore/ChocolateStore.csproj index 5e5c0db..2889edd 100644 --- a/src/ChocolateStore/ChocolateStore.csproj +++ b/src/ChocolateStore/ChocolateStore.csproj @@ -34,6 +34,10 @@ 4 + + ..\..\packages\HtmlAgilityPack.1.6.17\lib\Net40-client\HtmlAgilityPack.dll + True + ..\..\packages\DotNetZip.1.9.3\lib\net20\Ionic.Zip.dll diff --git a/src/ChocolateStore/PackageCacher.cs b/src/ChocolateStore/PackageCacher.cs index e5d9f47..ce6ce0c 100644 --- a/src/ChocolateStore/PackageCacher.cs +++ b/src/ChocolateStore/PackageCacher.cs @@ -5,6 +5,7 @@ using System.Text; using System.Text.RegularExpressions; using Ionic.Zip; +using HtmlAgilityPack; namespace ChocolateStore { @@ -20,9 +21,14 @@ class PackageCacher public event FileHandler DownloadingFile = delegate { }; public event DownloadFailedHandler DownloadFailed = delegate { }; - public void CachePackage(string dir, string url) + public void CachePackage(Arguments arguments) { - var packagePath = DownloadFile(url, dir); + if (arguments.Url == null) + { + arguments.Url = GetPackagePath(arguments.PackageName); + } + + var packagePath = DownloadFile(arguments.Url, arguments.Directory); using (var zip = ZipFile.Read(packagePath)) { @@ -41,7 +47,7 @@ public void CachePackage(string dir, string url) } } - content = CacheUrlFiles(Path.Combine(dir, packageName), content); + content = CacheUrlFiles(Path.Combine(arguments.Directory, packageName), content); zip.UpdateEntry(INSTALL_FILE, content); zip.Save(); @@ -64,6 +70,16 @@ private string CacheUrlFiles(string folder, string content) } + private string GetPackagePath(string packageName) + { + var url = "https://chocolatey.org/packages/" + packageName; + var web = new HtmlWeb(); + var doc = web.Load(url); + return doc.DocumentNode + .SelectSingleNode("//a[contains(@title, 'nupkg')]") + .Attributes["href"].Value; + } + private string DownloadFile(string url, string destination) { diff --git a/src/ChocolateStore/Program.cs b/src/ChocolateStore/Program.cs index 50a2c94..b29a36c 100644 --- a/src/ChocolateStore/Program.cs +++ b/src/ChocolateStore/Program.cs @@ -21,7 +21,7 @@ static void Main(string[] args) if (arguments != null) { - cacher.CachePackage(arguments.Directory, arguments.Url); + cacher.CachePackage(arguments); } } @@ -51,12 +51,12 @@ private static Arguments ParseArguments(string[] args) return null; } - arguments.Url = args[1]; - - if (!Uri.IsWellFormedUriString(arguments.Url, UriKind.Absolute)) + if (Uri.IsWellFormedUriString(args[1], UriKind.Absolute)) { - WriteError("URL '{0}' is invalid.", arguments.Url); - return null; + arguments.Url = args[1]; + } else + { + arguments.PackageName = args[1]; } return arguments; diff --git a/src/ChocolateStore/packages.config b/src/ChocolateStore/packages.config index ed41fa3..0387b2e 100644 --- a/src/ChocolateStore/packages.config +++ b/src/ChocolateStore/packages.config @@ -1,4 +1,5 @@  + \ No newline at end of file From 8f9308a9ce3326391d64a0752c6ff4a8c0a122b5 Mon Sep 17 00:00:00 2001 From: laggingreflex Date: Fri, 16 Feb 2018 16:50:15 +0530 Subject: [PATCH 3/5] fix: formatting: consistent line-endings --- src/ChocolateStore/PackageCacher.cs | 220 ++++++++++++++-------------- 1 file changed, 110 insertions(+), 110 deletions(-) diff --git a/src/ChocolateStore/PackageCacher.cs b/src/ChocolateStore/PackageCacher.cs index ce6ce0c..ebc35e1 100644 --- a/src/ChocolateStore/PackageCacher.cs +++ b/src/ChocolateStore/PackageCacher.cs @@ -1,117 +1,117 @@ -using System; -using System.IO; -using System.Linq; -using System.Net; -using System.Text; -using System.Text.RegularExpressions; -using Ionic.Zip; -using HtmlAgilityPack; - -namespace ChocolateStore -{ - class PackageCacher - { - - private const string INSTALL_FILE = "tools/chocolateyInstall.ps1"; - - public delegate void FileHandler(string fileName); - public delegate void DownloadFailedHandler(string url, Exception ex); - - public event FileHandler SkippingFile = delegate { }; - public event FileHandler DownloadingFile = delegate { }; - public event DownloadFailedHandler DownloadFailed = delegate { }; - - public void CachePackage(Arguments arguments) - { - if (arguments.Url == null) - { - arguments.Url = GetPackagePath(arguments.PackageName); - } - - var packagePath = DownloadFile(arguments.Url, arguments.Directory); - - using (var zip = ZipFile.Read(packagePath)) - { - var entry = zip.FirstOrDefault(x => string.Equals(x.FileName, INSTALL_FILE, StringComparison.OrdinalIgnoreCase)); - - if (entry != null) { - string content = null; - var packageName = Path.GetFileNameWithoutExtension(packagePath); - - using (MemoryStream ms = new MemoryStream()) { +using System; +using System.IO; +using System.Linq; +using System.Net; +using System.Text; +using System.Text.RegularExpressions; +using Ionic.Zip; +using HtmlAgilityPack; + +namespace ChocolateStore +{ + class PackageCacher + { + + private const string INSTALL_FILE = "tools/chocolateyInstall.ps1"; + + public delegate void FileHandler(string fileName); + public delegate void DownloadFailedHandler(string url, Exception ex); + + public event FileHandler SkippingFile = delegate { }; + public event FileHandler DownloadingFile = delegate { }; + public event DownloadFailedHandler DownloadFailed = delegate { }; + + public void CachePackage(Arguments arguments) + { + if (arguments.Url == null) + { + arguments.Url = GetPackagePath(arguments.PackageName); + } + + var packagePath = DownloadFile(arguments.Url, arguments.Directory); + + using (var zip = ZipFile.Read(packagePath)) + { + var entry = zip.FirstOrDefault(x => string.Equals(x.FileName, INSTALL_FILE, StringComparison.OrdinalIgnoreCase)); + + if (entry != null) { + string content = null; + var packageName = Path.GetFileNameWithoutExtension(packagePath); + + using (MemoryStream ms = new MemoryStream()) { entry.Extract(ms); ms.Position = 0; using (StreamReader reader = new StreamReader(ms, true)) { content = reader.ReadToEnd(); } - } - - content = CacheUrlFiles(Path.Combine(arguments.Directory, packageName), content); - zip.UpdateEntry(INSTALL_FILE, content); - zip.Save(); - - } - - } - - } - - private string CacheUrlFiles(string folder, string content) - { - - const string pattern = "(?<=['\"])http[\\S ]*(?=['\"])"; - - if (!Directory.Exists(folder)) { - Directory.CreateDirectory(folder); - } - - return Regex.Replace(content, pattern, new MatchEvaluator(m => DownloadFile(m.Value, folder))); - - } - - private string GetPackagePath(string packageName) - { - var url = "https://chocolatey.org/packages/" + packageName; - var web = new HtmlWeb(); - var doc = web.Load(url); - return doc.DocumentNode - .SelectSingleNode("//a[contains(@title, 'nupkg')]") - .Attributes["href"].Value; - } - - private string DownloadFile(string url, string destination) - { - - try - { - var request = WebRequest.Create(url); - var response = request.GetResponse(); - var fileName = Path.GetFileName(response.ResponseUri.LocalPath); - var filePath = Path.Combine(destination, fileName); - - if (File.Exists(filePath)) - { - SkippingFile(fileName); - } - else - { - DownloadingFile(fileName); - using (var fs = File.Create(filePath)) - { - response.GetResponseStream().CopyTo(fs); - } - } - - return filePath; - } - catch (Exception ex) - { - DownloadFailed(url, ex); - return url; - } - - } - - } + } + + content = CacheUrlFiles(Path.Combine(arguments.Directory, packageName), content); + zip.UpdateEntry(INSTALL_FILE, content); + zip.Save(); + + } + + } + + } + + private string CacheUrlFiles(string folder, string content) + { + + const string pattern = "(?<=['\"])http[\\S ]*(?=['\"])"; + + if (!Directory.Exists(folder)) { + Directory.CreateDirectory(folder); + } + + return Regex.Replace(content, pattern, new MatchEvaluator(m => DownloadFile(m.Value, folder))); + + } + + private string GetPackagePath(string packageName) + { + var url = "https://chocolatey.org/packages/" + packageName; + var web = new HtmlWeb(); + var doc = web.Load(url); + return doc.DocumentNode + .SelectSingleNode("//a[contains(@title, 'nupkg')]") + .Attributes["href"].Value; + } + + private string DownloadFile(string url, string destination) + { + + try + { + var request = WebRequest.Create(url); + var response = request.GetResponse(); + var fileName = Path.GetFileName(response.ResponseUri.LocalPath); + var filePath = Path.Combine(destination, fileName); + + if (File.Exists(filePath)) + { + SkippingFile(fileName); + } + else + { + DownloadingFile(fileName); + using (var fs = File.Create(filePath)) + { + response.GetResponseStream().CopyTo(fs); + } + } + + return filePath; + } + catch (Exception ex) + { + DownloadFailed(url, ex); + return url; + } + + } + + } } \ No newline at end of file From f1adc93583554c653c32165080ed05f7b6e3687b Mon Sep 17 00:00:00 2001 From: laggingreflex Date: Fri, 16 Feb 2018 16:52:53 +0530 Subject: [PATCH 4/5] fix: consistent indentation - spaces:4 --- src/ChocolateStore/PackageCacher.cs | 166 ++++++++++++++-------------- 1 file changed, 83 insertions(+), 83 deletions(-) diff --git a/src/ChocolateStore/PackageCacher.cs b/src/ChocolateStore/PackageCacher.cs index ebc35e1..08d0588 100644 --- a/src/ChocolateStore/PackageCacher.cs +++ b/src/ChocolateStore/PackageCacher.cs @@ -9,37 +9,37 @@ namespace ChocolateStore { - class PackageCacher - { + class PackageCacher + { - private const string INSTALL_FILE = "tools/chocolateyInstall.ps1"; + private const string INSTALL_FILE = "tools/chocolateyInstall.ps1"; - public delegate void FileHandler(string fileName); - public delegate void DownloadFailedHandler(string url, Exception ex); + public delegate void FileHandler(string fileName); + public delegate void DownloadFailedHandler(string url, Exception ex); - public event FileHandler SkippingFile = delegate { }; - public event FileHandler DownloadingFile = delegate { }; - public event DownloadFailedHandler DownloadFailed = delegate { }; + public event FileHandler SkippingFile = delegate { }; + public event FileHandler DownloadingFile = delegate { }; + public event DownloadFailedHandler DownloadFailed = delegate { }; - public void CachePackage(Arguments arguments) - { - if (arguments.Url == null) - { - arguments.Url = GetPackagePath(arguments.PackageName); - } + public void CachePackage(Arguments arguments) + { + if (arguments.Url == null) + { + arguments.Url = GetPackagePath(arguments.PackageName); + } - var packagePath = DownloadFile(arguments.Url, arguments.Directory); + var packagePath = DownloadFile(arguments.Url, arguments.Directory); - using (var zip = ZipFile.Read(packagePath)) - { - var entry = zip.FirstOrDefault(x => string.Equals(x.FileName, INSTALL_FILE, StringComparison.OrdinalIgnoreCase)); + using (var zip = ZipFile.Read(packagePath)) + { + var entry = zip.FirstOrDefault(x => string.Equals(x.FileName, INSTALL_FILE, StringComparison.OrdinalIgnoreCase)); - if (entry != null) { - string content = null; - var packageName = Path.GetFileNameWithoutExtension(packagePath); + if (entry != null) { + string content = null; + var packageName = Path.GetFileNameWithoutExtension(packagePath); - using (MemoryStream ms = new MemoryStream()) { - entry.Extract(ms); + using (MemoryStream ms = new MemoryStream()) { + entry.Extract(ms); ms.Position = 0; using (StreamReader reader = new StreamReader(ms, true)) { @@ -47,71 +47,71 @@ public void CachePackage(Arguments arguments) } } - content = CacheUrlFiles(Path.Combine(arguments.Directory, packageName), content); - zip.UpdateEntry(INSTALL_FILE, content); - zip.Save(); + content = CacheUrlFiles(Path.Combine(arguments.Directory, packageName), content); + zip.UpdateEntry(INSTALL_FILE, content); + zip.Save(); - } + } - } + } - } + } - private string CacheUrlFiles(string folder, string content) - { + private string CacheUrlFiles(string folder, string content) + { const string pattern = "(?<=['\"])http[\\S ]*(?=['\"])"; - if (!Directory.Exists(folder)) { - Directory.CreateDirectory(folder); - } - - return Regex.Replace(content, pattern, new MatchEvaluator(m => DownloadFile(m.Value, folder))); - - } - - private string GetPackagePath(string packageName) - { - var url = "https://chocolatey.org/packages/" + packageName; - var web = new HtmlWeb(); - var doc = web.Load(url); - return doc.DocumentNode - .SelectSingleNode("//a[contains(@title, 'nupkg')]") - .Attributes["href"].Value; - } - - private string DownloadFile(string url, string destination) - { - - try - { - var request = WebRequest.Create(url); - var response = request.GetResponse(); - var fileName = Path.GetFileName(response.ResponseUri.LocalPath); - var filePath = Path.Combine(destination, fileName); - - if (File.Exists(filePath)) - { - SkippingFile(fileName); - } - else - { - DownloadingFile(fileName); - using (var fs = File.Create(filePath)) - { - response.GetResponseStream().CopyTo(fs); - } - } - - return filePath; - } - catch (Exception ex) - { - DownloadFailed(url, ex); - return url; - } - - } - - } + if (!Directory.Exists(folder)) { + Directory.CreateDirectory(folder); + } + + return Regex.Replace(content, pattern, new MatchEvaluator(m => DownloadFile(m.Value, folder))); + + } + + private string GetPackagePath(string packageName) + { + var url = "https://chocolatey.org/packages/" + packageName; + var web = new HtmlWeb(); + var doc = web.Load(url); + return doc.DocumentNode + .SelectSingleNode("//a[contains(@title, 'nupkg')]") + .Attributes["href"].Value; + } + + private string DownloadFile(string url, string destination) + { + + try + { + var request = WebRequest.Create(url); + var response = request.GetResponse(); + var fileName = Path.GetFileName(response.ResponseUri.LocalPath); + var filePath = Path.Combine(destination, fileName); + + if (File.Exists(filePath)) + { + SkippingFile(fileName); + } + else + { + DownloadingFile(fileName); + using (var fs = File.Create(filePath)) + { + response.GetResponseStream().CopyTo(fs); + } + } + + return filePath; + } + catch (Exception ex) + { + DownloadFailed(url, ex); + return url; + } + + } + + } } \ No newline at end of file From 29c6352222e66e7a6a2480eb2f43282046d3456e Mon Sep 17 00:00:00 2001 From: laggingreflex Date: Fri, 16 Feb 2018 19:32:59 +0530 Subject: [PATCH 5/5] feat: resolves dependencies Resolves and downloads dependencies of packages. Breaking change: Does not accept URL anymore, only package name. Since we're accessing the chocolaty package page anyways, it's easier to just provide package name instead of URL. --- src/ChocolateStore/Arguments.cs | 1 - src/ChocolateStore/ChocolateStore.csproj | 1 + src/ChocolateStore/PackageCacher.cs | 30 ++++++++++-------------- src/ChocolateStore/PackageInfo.cs | 29 +++++++++++++++++++++++ src/ChocolateStore/Program.cs | 12 +++------- 5 files changed, 45 insertions(+), 28 deletions(-) create mode 100644 src/ChocolateStore/PackageInfo.cs diff --git a/src/ChocolateStore/Arguments.cs b/src/ChocolateStore/Arguments.cs index 0e1dedb..26f8c65 100644 --- a/src/ChocolateStore/Arguments.cs +++ b/src/ChocolateStore/Arguments.cs @@ -3,7 +3,6 @@ class Arguments { public string Directory { get; set; } - public string Url { get; set; } public string PackageName { get; set; } } } diff --git a/src/ChocolateStore/ChocolateStore.csproj b/src/ChocolateStore/ChocolateStore.csproj index 2889edd..da1592c 100644 --- a/src/ChocolateStore/ChocolateStore.csproj +++ b/src/ChocolateStore/ChocolateStore.csproj @@ -47,6 +47,7 @@ + diff --git a/src/ChocolateStore/PackageCacher.cs b/src/ChocolateStore/PackageCacher.cs index 08d0588..acc1e57 100644 --- a/src/ChocolateStore/PackageCacher.cs +++ b/src/ChocolateStore/PackageCacher.cs @@ -21,14 +21,11 @@ class PackageCacher public event FileHandler DownloadingFile = delegate { }; public event DownloadFailedHandler DownloadFailed = delegate { }; - public void CachePackage(Arguments arguments) + public void CachePackage(string packageName, string directory) { - if (arguments.Url == null) - { - arguments.Url = GetPackagePath(arguments.PackageName); - } + var packageInfo = new PackageInfo(packageName); - var packagePath = DownloadFile(arguments.Url, arguments.Directory); + var packagePath = DownloadFile(packageInfo.url, directory); using (var zip = ZipFile.Read(packagePath)) { @@ -36,7 +33,6 @@ public void CachePackage(Arguments arguments) if (entry != null) { string content = null; - var packageName = Path.GetFileNameWithoutExtension(packagePath); using (MemoryStream ms = new MemoryStream()) { entry.Extract(ms); @@ -47,7 +43,7 @@ public void CachePackage(Arguments arguments) } } - content = CacheUrlFiles(Path.Combine(arguments.Directory, packageName), content); + content = CacheUrlFiles(Path.Combine(directory, packageName), content); zip.UpdateEntry(INSTALL_FILE, content); zip.Save(); @@ -55,6 +51,14 @@ public void CachePackage(Arguments arguments) } + if (packageInfo.dependencies != null) + { + foreach (var dep in packageInfo.dependencies) + { + CachePackage(dep, directory); + } + } + } private string CacheUrlFiles(string folder, string content) @@ -70,16 +74,6 @@ private string CacheUrlFiles(string folder, string content) } - private string GetPackagePath(string packageName) - { - var url = "https://chocolatey.org/packages/" + packageName; - var web = new HtmlWeb(); - var doc = web.Load(url); - return doc.DocumentNode - .SelectSingleNode("//a[contains(@title, 'nupkg')]") - .Attributes["href"].Value; - } - private string DownloadFile(string url, string destination) { diff --git a/src/ChocolateStore/PackageInfo.cs b/src/ChocolateStore/PackageInfo.cs new file mode 100644 index 0000000..a3919d0 --- /dev/null +++ b/src/ChocolateStore/PackageInfo.cs @@ -0,0 +1,29 @@ +using System; +using System.Linq; +using HtmlAgilityPack; + +namespace ChocolateStore +{ + class PackageInfo + { + public string name { get; set; } + public string url { get; set; } + public string[] dependencies { get; set; } + public PackageInfo(string packageName) + { + Console.WriteLine("Reading package '{0}'", packageName); + this.name = packageName; + var web = new HtmlWeb(); + var doc = web.Load("https://chocolatey.org/packages/" + packageName); + this.url = doc.DocumentNode + .SelectSingleNode("//a[contains(@title, 'nupkg')]") + .Attributes["href"].Value; + Console.WriteLine("package URL: '{0}'", this.url); + try + { + this.dependencies = doc.DocumentNode.SelectNodes("//ul[@id='dependencySets']//a").Select(node => node.InnerText).ToArray(); + } catch (Exception) { } + + } + } +} diff --git a/src/ChocolateStore/Program.cs b/src/ChocolateStore/Program.cs index e64615f..3a9f5a7 100644 --- a/src/ChocolateStore/Program.cs +++ b/src/ChocolateStore/Program.cs @@ -21,7 +21,7 @@ static void Main(string[] args) if (arguments != null) { - cacher.CachePackage(arguments); + cacher.CachePackage(arguments.PackageName, arguments.Directory); } } @@ -39,7 +39,7 @@ private static Arguments ParseArguments(string[] args) if (args.Length != 2) { - WriteError("USAGE: ChocolateStore "); + WriteError("USAGE: ChocolateStore "); return null; } @@ -56,13 +56,7 @@ private static Arguments ParseArguments(string[] args) Console.WriteLine("Created Directory '{0}'", arguments.Directory); } - if (Uri.IsWellFormedUriString(args[1], UriKind.Absolute)) - { - arguments.Url = args[1]; - } else - { - arguments.PackageName = args[1]; - } + arguments.PackageName = args[1]; return arguments;