From 131f313fd4e59de0c92f0cd2171e82126329630a Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Thu, 25 Jan 2018 15:06:59 -0500 Subject: [PATCH 001/873] Adding several new data points to track in Unity --- .../Application/ApplicationManagerBase.cs | 3 +- src/GitHub.Api/Metrics/IUsageTracker.cs | 28 +++- src/GitHub.Api/Metrics/UsageModel.cs | 10 ++ src/GitHub.Api/Metrics/UsageTracker.cs | 138 ++++++++++++++++-- .../GitHub.Unity/UI/AuthenticationView.cs | 5 + .../Editor/GitHub.Unity/UI/BranchesView.cs | 5 +- .../Editor/GitHub.Unity/UI/ChangesView.cs | 5 + .../Editor/GitHub.Unity/UI/HistoryView.cs | 6 + 8 files changed, 181 insertions(+), 19 deletions(-) diff --git a/src/GitHub.Api/Application/ApplicationManagerBase.cs b/src/GitHub.Api/Application/ApplicationManagerBase.cs index 63c4d67bc..2c53665fc 100644 --- a/src/GitHub.Api/Application/ApplicationManagerBase.cs +++ b/src/GitHub.Api/Application/ApplicationManagerBase.cs @@ -120,6 +120,7 @@ public ITask InitializeRepository() Environment.InitializeRepository(); RestartRepository(); }) + .ThenInUI(UsageTracker.IncrementNumberOfProjectsInitialized) .ThenInUI(InitializeUI); return task; } @@ -179,7 +180,7 @@ protected void SetupMetrics(string unityVersion, bool firstRun) if (firstRun) { - UsageTracker.IncrementLaunchCount(); + UsageTracker.IncrementNumberOfStartups(); } } diff --git a/src/GitHub.Api/Metrics/IUsageTracker.cs b/src/GitHub.Api/Metrics/IUsageTracker.cs index 18b4584ee..0c5522b71 100644 --- a/src/GitHub.Api/Metrics/IUsageTracker.cs +++ b/src/GitHub.Api/Metrics/IUsageTracker.cs @@ -6,15 +6,33 @@ namespace GitHub.Unity public interface IUsageTracker { bool Enabled { get; set; } - void IncrementLaunchCount(); + void IncrementNumberOfStartups(); + void IncrementNumberOfCommits(); + void IncrementNumberOfFetches(); + void IncrementNumberOfPushes(); + void IncrementNumberOfPulls(); + void IncrementNumberOfAuthentications(); + void IncrementNumberOfProjectsInitialized(); + void IncrementNumberOfLocalBranchCreations(); + void IncrementNumberOfLocalBranchDeletions(); + void IncrementNumberOfLocalBranchCheckouts(); + void IncrementNumberOfRemoteBranchCheckouts(); } class NullUsageTracker : IUsageTracker { public bool Enabled { get; set; } - - public void IncrementLaunchCount(){ } - public void SetMetricsService(IMetricsService instance) - { } + public void IncrementNumberOfStartups() { } + public void IncrementNumberOfCommits() { } + public void IncrementNumberOfFetches() { } + public void IncrementNumberOfPushes() { } + public void IncrementNumberOfPulls() { } + public void IncrementNumberOfAuthentications() { } + public void IncrementNumberOfProjectsInitialized() { } + public void IncrementNumberOfLocalBranchCreations() { } + public void IncrementNumberOfLocalBranchDeletions() { } + public void IncrementNumberOfLocalBranchCheckouts() { } + public void IncrementNumberOfRemoteBranchCheckouts() { } + public void SetMetricsService(IMetricsService instance) { } } } diff --git a/src/GitHub.Api/Metrics/UsageModel.cs b/src/GitHub.Api/Metrics/UsageModel.cs index 66ae88362..2d9011115 100644 --- a/src/GitHub.Api/Metrics/UsageModel.cs +++ b/src/GitHub.Api/Metrics/UsageModel.cs @@ -12,6 +12,16 @@ public class Usage public string UnityVersion { get; set; } public string Lang { get; set; } public int NumberOfStartups { get; set; } + public int NumberOfCommits { get; set; } + public int NumberOfFetches { get; set; } + public int NumberOfPushes { get; set; } + public int NumberOfPulls { get; set; } + public int NumberOfProjectsInitialized { get; set; } + public int NumberOfAuthentications { get; set; } + public int NumberOfLocalBranchCreations { get; set; } + public int NumberOfLocalBranchDeletion { get; set; } + public int NumberOfLocalBranchCheckouts { get; set; } + public int NumberOfRemoteBranchCheckouts { get; set; } } class UsageModel diff --git a/src/GitHub.Api/Metrics/UsageTracker.cs b/src/GitHub.Api/Metrics/UsageTracker.cs index 30e90e44e..9d38d4eaa 100644 --- a/src/GitHub.Api/Metrics/UsageTracker.cs +++ b/src/GitHub.Api/Metrics/UsageTracker.cs @@ -104,12 +104,11 @@ private void RunTimer(int seconds) }, null, seconds * 1000, Timeout.Infinite); } - private async Task SendUsage() { Logger.Trace("SendUsage"); - var usage = LoadUsage(); + var usageStore = LoadUsage(); if (metricsService == null) { @@ -117,7 +116,7 @@ private async Task SendUsage() return; } - if (usage.LastUpdated.Date != DateTimeOffset.UtcNow.Date) + if (usageStore.LastUpdated.Date != DateTimeOffset.UtcNow.Date) { Logger.Trace("Sending Usage"); @@ -125,7 +124,7 @@ private async Task SendUsage() var beforeDate = currentTimeOffset.Date; var success = false; - var extractReports = usage.Model.SelectReports(beforeDate); + var extractReports = usageStore.Model.SelectReports(beforeDate); if (!extractReports.Any()) { Logger.Trace("No items to send"); @@ -151,24 +150,139 @@ private async Task SendUsage() if (success) { - usage.Model.RemoveReports(beforeDate); - usage.LastUpdated = currentTimeOffset; - SaveUsage(usage); + usageStore.Model.RemoveReports(beforeDate); + usageStore.LastUpdated = currentTimeOffset; + SaveUsage(usageStore); } } } - public void IncrementLaunchCount() + private Usage GetCurrentUsage(UsageStore usageStore) { - var usageStore = LoadUsage(); - var usage = usageStore.Model.GetCurrentUsage(); - usage.NumberOfStartups++; usage.UnityVersion = unityVersion; usage.Lang = CultureInfo.InstalledUICulture.IetfLanguageTag; usage.AppVersion = AppConfiguration.AssemblyName.Version.ToString(); + return usage; + } + + public void IncrementNumberOfStartups() + { + var usageStore = LoadUsage(); + var usage = GetCurrentUsage(usageStore); + + usage.NumberOfStartups++; + Logger.Trace("NumberOfStartups:{0} Date:{1}", usage.NumberOfStartups, usage.Date); + + SaveUsage(usageStore); + } + + public void IncrementNumberOfCommits() + { + var usageStore = LoadUsage(); + var usage = GetCurrentUsage(usageStore); + + usage.NumberOfCommits++; + Logger.Trace("NumberOfCommits:{0} Date:{1}", usage.NumberOfCommits, usage.Date); + + SaveUsage(usageStore); + } + + public void IncrementNumberOfFetches() + { + var usageStore = LoadUsage(); + var usage = GetCurrentUsage(usageStore); + + usage.NumberOfFetches++; + Logger.Trace("NumberOfFetches:{0} Date:{1}", usage.NumberOfFetches, usage.Date); + + SaveUsage(usageStore); + } + + public void IncrementNumberOfPushes() + { + var usageStore = LoadUsage(); + var usage = GetCurrentUsage(usageStore); + + usage.NumberOfPushes++; + Logger.Trace("NumberOfPushes:{0} Date:{1}", usage.NumberOfPushes, usage.Date); + + SaveUsage(usageStore); + } + + public void IncrementNumberOfProjectsInitialized() + { + var usageStore = LoadUsage(); + var usage = GetCurrentUsage(usageStore); + + usage.NumberOfProjectsInitialized++; + Logger.Trace("NumberOfProjectsInitialized:{0} Date:{1}", usage.NumberOfProjectsInitialized, usage.Date); + + SaveUsage(usageStore); + } + + public void IncrementNumberOfLocalBranchCreations() + { + var usageStore = LoadUsage(); + var usage = GetCurrentUsage(usageStore); + + usage.NumberOfLocalBranchCreations++; + Logger.Trace("NumberOfLocalBranchCreations:{0} Date:{1}", usage.NumberOfLocalBranchCreations, usage.Date); + + SaveUsage(usageStore); + } + + public void IncrementNumberOfLocalBranchDeletions() + { + var usageStore = LoadUsage(); + var usage = GetCurrentUsage(usageStore); + + usage.NumberOfLocalBranchDeletion++; + Logger.Trace("NumberOfLocalBranchDeletion:{0} Date:{1}", usage.NumberOfLocalBranchDeletion, usage.Date); + + SaveUsage(usageStore); + } + + public void IncrementNumberOfLocalBranchCheckouts() + { + var usageStore = LoadUsage(); + var usage = GetCurrentUsage(usageStore); + + usage.NumberOfLocalBranchCheckouts++; + Logger.Trace("NumberOfLocalBranchCheckouts:{0} Date:{1}", usage.NumberOfLocalBranchCheckouts, usage.Date); + + SaveUsage(usageStore); + } + + public void IncrementNumberOfRemoteBranchCheckouts() + { + var usageStore = LoadUsage(); + var usage = GetCurrentUsage(usageStore); + + usage.NumberOfRemoteBranchCheckouts++; + Logger.Trace("NumberOfRemoteBranchCheckouts:{0} Date:{1}", usage.NumberOfRemoteBranchCheckouts, usage.Date); + + SaveUsage(usageStore); + } + + public void IncrementNumberOfPulls() + { + var usageStore = LoadUsage(); + var usage = GetCurrentUsage(usageStore); + + usage.NumberOfPulls++; + Logger.Trace("NumberOfPulls:{0} Date:{1}", usage.NumberOfPulls, usage.Date); + + SaveUsage(usageStore); + } + + public void IncrementNumberOfAuthentications() + { + var usageStore = LoadUsage(); + var usage = GetCurrentUsage(usageStore); - Logger.Trace("IncrementLaunchCount Date:{0} NumberOfStartups:{1}", usage.Date, usage.NumberOfStartups); + usage.NumberOfAuthentications++; + Logger.Trace("NumberOfAuthentications:{0} Date:{1}", usage.NumberOfAuthentications, usage.Date); SaveUsage(usageStore); } diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/AuthenticationView.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/AuthenticationView.cs index c7795c05a..b99f6bf2e 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/AuthenticationView.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/AuthenticationView.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using UnityEngine; using UnityEditor; @@ -213,6 +214,10 @@ private void DoResult(bool success, string msg) if (success == true) { + new ActionTask(CancellationToken.None, () => { + EntryPoint.ApplicationManager.UsageTracker.IncrementNumberOfAuthentications(); + }) { Affinity = TaskAffinity.UI }.Start(); + Clear(); Finish(true); } diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/BranchesView.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/BranchesView.cs index a4bfff22e..0dbbd93e2 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/BranchesView.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/BranchesView.cs @@ -272,6 +272,7 @@ private void OnButtonBarGUI() { if (success) { + EntryPoint.ApplicationManager.UsageTracker.IncrementNumberOfLocalBranchCreations(); Redraw(); } else @@ -439,6 +440,7 @@ private void CheckoutRemoteBranch(string branch) GitClient.CreateBranch(branchName, branch).FinallyInUI((success, e) => { if (success) { + EntryPoint.ApplicationManager.UsageTracker.IncrementNumberOfRemoteBranchCheckouts(); Redraw(); } else @@ -459,6 +461,7 @@ private void SwitchBranch(string branch) GitClient.SwitchBranch(branch).FinallyInUI((success, e) => { if (success) { + EntryPoint.ApplicationManager.UsageTracker.IncrementNumberOfLocalBranchCheckouts(); Redraw(); } else @@ -475,7 +478,7 @@ private void DeleteLocalBranch(string branch) var dialogMessage = string.Format(DeleteBranchMessageFormatString, branch); if (EditorUtility.DisplayDialog(DeleteBranchTitle, dialogMessage, DeleteBranchButton, CancelButtonLabel)) { - GitClient.DeleteBranch(branch, true).Start(); + GitClient.DeleteBranch(branch, true).ThenInUI(EntryPoint.ApplicationManager.UsageTracker.IncrementNumberOfLocalBranchDeletions).Start(); } } diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesView.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesView.cs index 0acdfb56b..86cf8c858 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesView.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesView.cs @@ -318,6 +318,11 @@ private void Commit() addTask .FinallyInUI((b, exception) => { + if (b) + { + EntryPoint.ApplicationManager.UsageTracker.IncrementNumberOfCommits(); + } + commitMessage = ""; commitBody = ""; SetBusy(false); diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/HistoryView.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/HistoryView.cs index b2da0f974..658df2a25 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/HistoryView.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/HistoryView.cs @@ -681,6 +681,8 @@ private void Pull() .FinallyInUI((success, e) => { if (success) { + EntryPoint.ApplicationManager.UsageTracker.IncrementNumberOfPulls(); + EditorUtility.DisplayDialog(Localization.PullActionTitle, String.Format(Localization.PullSuccessDescription, currentRemoteName), Localization.Ok); @@ -703,6 +705,8 @@ private void Push() .FinallyInUI((success, e) => { if (success) { + EntryPoint.ApplicationManager.UsageTracker.IncrementNumberOfPushes(); + EditorUtility.DisplayDialog(Localization.PushActionTitle, String.Format(Localization.PushSuccessDescription, currentRemoteName), Localization.Ok); @@ -722,6 +726,8 @@ private void Fetch() Repository .Fetch() .FinallyInUI((success, e) => { + EntryPoint.ApplicationManager.UsageTracker.IncrementNumberOfFetches(); + if (!success) { EditorUtility.DisplayDialog(FetchActionTitle, FetchFailureDescription, From 861a27fde2dbcde776276ddbfaaf2ba0504c5426 Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Thu, 25 Jan 2018 15:07:53 -0500 Subject: [PATCH 002/873] If developing data won't send but it should still save --- src/GitHub.Api/Metrics/UsageTracker.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/GitHub.Api/Metrics/UsageTracker.cs b/src/GitHub.Api/Metrics/UsageTracker.cs index 9d38d4eaa..b66e7c204 100644 --- a/src/GitHub.Api/Metrics/UsageTracker.cs +++ b/src/GitHub.Api/Metrics/UsageTracker.cs @@ -71,11 +71,6 @@ private UsageStore LoadUsage() private void SaveUsage(UsageStore store) { - if (!Enabled) - { - return; - } - var pathString = storePath.ToString(); Logger.Trace("SaveUsage: \"{0}\"", pathString); From 481a56e52b2c55454a1a5aa4abf8c77ea883e88e Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Thu, 25 Jan 2018 16:52:50 -0500 Subject: [PATCH 003/873] Adding CurrentLang --- src/GitHub.Api/Metrics/UsageModel.cs | 1 + src/GitHub.Api/Metrics/UsageTracker.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/GitHub.Api/Metrics/UsageModel.cs b/src/GitHub.Api/Metrics/UsageModel.cs index 2d9011115..7ee9cb670 100644 --- a/src/GitHub.Api/Metrics/UsageModel.cs +++ b/src/GitHub.Api/Metrics/UsageModel.cs @@ -11,6 +11,7 @@ public class Usage public string AppVersion { get; set; } public string UnityVersion { get; set; } public string Lang { get; set; } + public string CurrentLang { get; set; } public int NumberOfStartups { get; set; } public int NumberOfCommits { get; set; } public int NumberOfFetches { get; set; } diff --git a/src/GitHub.Api/Metrics/UsageTracker.cs b/src/GitHub.Api/Metrics/UsageTracker.cs index b66e7c204..9f2cd9e61 100644 --- a/src/GitHub.Api/Metrics/UsageTracker.cs +++ b/src/GitHub.Api/Metrics/UsageTracker.cs @@ -158,6 +158,7 @@ private Usage GetCurrentUsage(UsageStore usageStore) usage.UnityVersion = unityVersion; usage.Lang = CultureInfo.InstalledUICulture.IetfLanguageTag; usage.AppVersion = AppConfiguration.AssemblyName.Version.ToString(); + usage.CurrentLang = CultureInfo.CurrentCulture.IetfLanguageTag; return usage; } From c8d6db5e2942464de19998ca0f26d2c2a748019c Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Thu, 25 Jan 2018 16:53:50 -0500 Subject: [PATCH 004/873] Grouping data records by GitHub for Unity version and Unity version --- src/GitHub.Api/Metrics/UsageModel.cs | 17 ++++++++++++++--- src/GitHub.Api/Metrics/UsageTracker.cs | 4 +--- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/GitHub.Api/Metrics/UsageModel.cs b/src/GitHub.Api/Metrics/UsageModel.cs index 7ee9cb670..e057fbac1 100644 --- a/src/GitHub.Api/Metrics/UsageModel.cs +++ b/src/GitHub.Api/Metrics/UsageModel.cs @@ -32,12 +32,18 @@ class UsageModel private Usage currentUsage; - public Usage GetCurrentUsage() + public Usage GetCurrentUsage(string appVersion, string unityVersion) { + Guard.ArgumentNotNullOrWhiteSpace(appVersion, "appVersion"); + Guard.ArgumentNotNullOrWhiteSpace(unityVersion, "unityVersion"); + var date = DateTime.UtcNow.Date; if (currentUsage == null) { - currentUsage = Reports.FirstOrDefault(usage => usage.Date == date); + currentUsage = Reports + .FirstOrDefault(usage => usage.Date == date + && usage.AppVersion == appVersion + && usage.UnityVersion == unityVersion); } if (currentUsage?.Date == date) @@ -48,7 +54,12 @@ public Usage GetCurrentUsage() } else { - currentUsage = new Usage { Date = date, Guid = Guid }; + currentUsage = new Usage { + Date = date, + Guid = Guid, + AppVersion = appVersion, + UnityVersion = unityVersion, + }; Reports.Add(currentUsage); } diff --git a/src/GitHub.Api/Metrics/UsageTracker.cs b/src/GitHub.Api/Metrics/UsageTracker.cs index 9f2cd9e61..dc624ed6f 100644 --- a/src/GitHub.Api/Metrics/UsageTracker.cs +++ b/src/GitHub.Api/Metrics/UsageTracker.cs @@ -154,10 +154,8 @@ private async Task SendUsage() private Usage GetCurrentUsage(UsageStore usageStore) { - var usage = usageStore.Model.GetCurrentUsage(); - usage.UnityVersion = unityVersion; + var usage = usageStore.Model.GetCurrentUsage(AppConfiguration.AssemblyName.Version.ToString(), unityVersion); usage.Lang = CultureInfo.InstalledUICulture.IetfLanguageTag; - usage.AppVersion = AppConfiguration.AssemblyName.Version.ToString(); usage.CurrentLang = CultureInfo.CurrentCulture.IetfLanguageTag; return usage; } From 0f4efef28caaf9c71a99e96a6e355221d66e2fee Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Thu, 25 Jan 2018 16:54:09 -0500 Subject: [PATCH 005/873] Adding Unity version to the log file --- src/UnityExtension/Assets/Editor/GitHub.Unity/EntryPoint.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/EntryPoint.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/EntryPoint.cs index 51aa84a09..924a9e7f6 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/EntryPoint.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/EntryPoint.cs @@ -62,7 +62,7 @@ private static void Initialize() } Logging.LogAdapter = new FileLogAdapter(logPath); - Logging.Info("Initializing GitHub for Unity version " + ApplicationInfo.Version); + Logging.Info("Initializing GitHubForUnity:v{0} Unity:v{1}", ApplicationInfo.Version, Environment.UnityVersion); ApplicationManager.Run(ApplicationCache.Instance.FirstRun); } From c69cf53465d9786d5e6802fb7cbdd0087ba4c603 Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Fri, 26 Jan 2018 09:26:58 -0500 Subject: [PATCH 006/873] Formatting fix --- .../Assets/Editor/GitHub.Unity/UI/BranchesView.cs | 5 ++++- .../Assets/Editor/GitHub.Unity/UI/HistoryView.cs | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/BranchesView.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/BranchesView.cs index 0dbbd93e2..a8328629b 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/BranchesView.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/BranchesView.cs @@ -478,7 +478,10 @@ private void DeleteLocalBranch(string branch) var dialogMessage = string.Format(DeleteBranchMessageFormatString, branch); if (EditorUtility.DisplayDialog(DeleteBranchTitle, dialogMessage, DeleteBranchButton, CancelButtonLabel)) { - GitClient.DeleteBranch(branch, true).ThenInUI(EntryPoint.ApplicationManager.UsageTracker.IncrementNumberOfLocalBranchDeletions).Start(); + GitClient + .DeleteBranch(branch, true) + .ThenInUI(EntryPoint.ApplicationManager.UsageTracker.IncrementNumberOfLocalBranchDeletions) + .Start(); } } diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/HistoryView.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/HistoryView.cs index 658df2a25..abd1a78da 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/HistoryView.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/HistoryView.cs @@ -681,7 +681,7 @@ private void Pull() .FinallyInUI((success, e) => { if (success) { - EntryPoint.ApplicationManager.UsageTracker.IncrementNumberOfPulls(); + EntryPoint.ApplicationManager.UsageTracker.IncrementNumberOfPulls(); EditorUtility.DisplayDialog(Localization.PullActionTitle, String.Format(Localization.PullSuccessDescription, currentRemoteName), From 096d1699debdce6f9f6cefbb0467c31428e597b0 Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Fri, 26 Jan 2018 12:22:21 -0500 Subject: [PATCH 007/873] Adding version for easier parsing --- src/GitHub.Api/Metrics/UsageModel.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/GitHub.Api/Metrics/UsageModel.cs b/src/GitHub.Api/Metrics/UsageModel.cs index e057fbac1..6bca9effa 100644 --- a/src/GitHub.Api/Metrics/UsageModel.cs +++ b/src/GitHub.Api/Metrics/UsageModel.cs @@ -8,6 +8,7 @@ public class Usage { public string Guid { get; set; } public DateTime Date { get; set; } + public int Version { get; set; } public string AppVersion { get; set; } public string UnityVersion { get; set; } public string Lang { get; set; } @@ -55,6 +56,7 @@ public Usage GetCurrentUsage(string appVersion, string unityVersion) else { currentUsage = new Usage { + Version = 2, Date = date, Guid = Guid, AppVersion = appVersion, From 4eff8ae4b2d49ecf61f8d4870fccaf72fe7a4655 Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Wed, 31 Jan 2018 09:17:03 -0500 Subject: [PATCH 008/873] Making the log entry a bit more parseable --- src/UnityExtension/Assets/Editor/GitHub.Unity/EntryPoint.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/EntryPoint.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/EntryPoint.cs index 924a9e7f6..0d94f8f6d 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/EntryPoint.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/EntryPoint.cs @@ -62,7 +62,7 @@ private static void Initialize() } Logging.LogAdapter = new FileLogAdapter(logPath); - Logging.Info("Initializing GitHubForUnity:v{0} Unity:v{1}", ApplicationInfo.Version, Environment.UnityVersion); + Logging.Info("Initializing GitHubForUnity:'v{0}' Unity:'v{1}'", ApplicationInfo.Version, Environment.UnityVersion); ApplicationManager.Run(ApplicationCache.Instance.FirstRun); } From 9157a894bc63d4c2e92d4f46a0e199d508f2e7de Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Wed, 31 Jan 2018 09:18:26 -0500 Subject: [PATCH 009/873] Removing switch to main thread This code is already running on the main thread --- .../Assets/Editor/GitHub.Unity/UI/AuthenticationView.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/AuthenticationView.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/AuthenticationView.cs index b99f6bf2e..8362ccfd0 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/AuthenticationView.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/AuthenticationView.cs @@ -212,11 +212,9 @@ private void DoResult(bool success, string msg) isBusy = false; - if (success == true) + if (success) { - new ActionTask(CancellationToken.None, () => { EntryPoint.ApplicationManager.UsageTracker.IncrementNumberOfAuthentications(); - }) { Affinity = TaskAffinity.UI }.Start(); Clear(); Finish(true); From d36f5ea8c64d2fdb7b9d1a97b44d3a3171c515b3 Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Wed, 31 Jan 2018 09:19:13 -0500 Subject: [PATCH 010/873] Using the Manager member variable --- .../Assets/Editor/GitHub.Unity/UI/AuthenticationView.cs | 2 +- .../Assets/Editor/GitHub.Unity/UI/BranchesView.cs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/AuthenticationView.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/AuthenticationView.cs index 8362ccfd0..9061ab05d 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/AuthenticationView.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/AuthenticationView.cs @@ -214,7 +214,7 @@ private void DoResult(bool success, string msg) if (success) { - EntryPoint.ApplicationManager.UsageTracker.IncrementNumberOfAuthentications(); + Manager.UsageTracker.IncrementNumberOfAuthentications(); Clear(); Finish(true); diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/BranchesView.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/BranchesView.cs index a8328629b..e278e6d22 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/BranchesView.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/BranchesView.cs @@ -272,7 +272,7 @@ private void OnButtonBarGUI() { if (success) { - EntryPoint.ApplicationManager.UsageTracker.IncrementNumberOfLocalBranchCreations(); + Manager.UsageTracker.IncrementNumberOfLocalBranchCreations(); Redraw(); } else @@ -440,7 +440,7 @@ private void CheckoutRemoteBranch(string branch) GitClient.CreateBranch(branchName, branch).FinallyInUI((success, e) => { if (success) { - EntryPoint.ApplicationManager.UsageTracker.IncrementNumberOfRemoteBranchCheckouts(); + Manager.UsageTracker.IncrementNumberOfRemoteBranchCheckouts(); Redraw(); } else @@ -461,7 +461,7 @@ private void SwitchBranch(string branch) GitClient.SwitchBranch(branch).FinallyInUI((success, e) => { if (success) { - EntryPoint.ApplicationManager.UsageTracker.IncrementNumberOfLocalBranchCheckouts(); + Manager.UsageTracker.IncrementNumberOfLocalBranchCheckouts(); Redraw(); } else @@ -480,7 +480,7 @@ private void DeleteLocalBranch(string branch) { GitClient .DeleteBranch(branch, true) - .ThenInUI(EntryPoint.ApplicationManager.UsageTracker.IncrementNumberOfLocalBranchDeletions) + .ThenInUI(Manager.UsageTracker.IncrementNumberOfLocalBranchDeletions) .Start(); } } From e6f0acfa50bc28b84f86f35fb7b3f44ed032c842 Mon Sep 17 00:00:00 2001 From: Mauro Palumbo Date: Mon, 16 Oct 2017 08:59:34 -0400 Subject: [PATCH 011/873] Initial implementation of discard (git checkout) functionality --- src/GitHub.Api/Git/GitClient.cs | 40 ++++++++++++- src/GitHub.Api/Git/IRepository.cs | 1 + src/GitHub.Api/Git/Repository.cs | 7 ++- src/GitHub.Api/Git/RepositoryManager.cs | 9 +++ src/GitHub.Api/Git/Tasks/GitCheckoutTask.cs | 36 +++++++++++ src/GitHub.Api/GitHub.Api.csproj | 1 + .../Events/RepositoryManagerTests.cs | 59 +++++++++++++++++++ 7 files changed, 150 insertions(+), 3 deletions(-) create mode 100644 src/GitHub.Api/Git/Tasks/GitCheckoutTask.cs diff --git a/src/GitHub.Api/Git/GitClient.cs b/src/GitHub.Api/Git/GitClient.cs index b54b058ef..0e0f16c65 100644 --- a/src/GitHub.Api/Git/GitClient.cs +++ b/src/GitHub.Api/Git/GitClient.cs @@ -69,7 +69,12 @@ ITask Add(IList files, ITask AddAll(IOutputProcessor processor = null); - ITask Remove(IList files, + ITask Discard( IList files, + IOutputProcessor processor = null ); + + ITask DiscardAll( IOutputProcessor processor = null ); + + ITask Remove(IList files, IOutputProcessor processor = null); ITask AddAndCommit(IList files, string message, string body, @@ -365,7 +370,38 @@ public ITask Add(IList files, return last; } - public ITask Remove(IList files, + public ITask Discard( IList files, + IOutputProcessor processor = null ) + { + Logger.Trace("Checkout Files"); + + GitCheckoutTask last = null; + foreach( var batch in files.Spool( 5000 ) ) + { + var current = new GitCheckoutTask( batch, cancellationToken, processor ).Configure( processManager ); + if( last == null ) + { + last = current; + } + else + { + last.Then( current ); + last = current; + } + } + + return last; + } + + public ITask DiscardAll( IOutputProcessor processor = null ) + { + Logger.Trace( "Checkout all files" ); + + return new GitCheckoutTask( cancellationToken, processor ) + .Configure( processManager ); + } + + public ITask Remove(IList files, IOutputProcessor processor = null) { Logger.Trace("Remove"); diff --git a/src/GitHub.Api/Git/IRepository.cs b/src/GitHub.Api/Git/IRepository.cs index 9b4754d4a..ec999b4bc 100644 --- a/src/GitHub.Api/Git/IRepository.cs +++ b/src/GitHub.Api/Git/IRepository.cs @@ -18,6 +18,7 @@ public interface IRepository : IEquatable ITask Revert(string changeset); ITask RequestLock(string file); ITask ReleaseLock(string file, bool force); + ITask CheckoutFiles( List files ); void CheckLogChangedEvent(CacheUpdateEvent gitLogCacheUpdateEvent); void CheckStatusChangedEvent(CacheUpdateEvent cacheUpdateEvent); diff --git a/src/GitHub.Api/Git/Repository.cs b/src/GitHub.Api/Git/Repository.cs index 3682a60d4..4e72d2192 100644 --- a/src/GitHub.Api/Git/Repository.cs +++ b/src/GitHub.Api/Git/Repository.cs @@ -112,6 +112,11 @@ public ITask ReleaseLock(string file, bool force) return repositoryManager.UnlockFile(file, force); } + public ITask CheckoutFiles( List files ) + { + return repositoryManager.CheckoutFiles( files ); + } + public void CheckLogChangedEvent(CacheUpdateEvent cacheUpdateEvent) { var managedCache = cacheContainer.GitLogCache; @@ -834,4 +839,4 @@ public string UpdatedTimeString private set { updatedTimeString = value; } } } -} +} \ No newline at end of file diff --git a/src/GitHub.Api/Git/RepositoryManager.cs b/src/GitHub.Api/Git/RepositoryManager.cs index e969f7f25..a60893d15 100644 --- a/src/GitHub.Api/Git/RepositoryManager.cs +++ b/src/GitHub.Api/Git/RepositoryManager.cs @@ -35,6 +35,7 @@ public interface IRepositoryManager : IDisposable ITask CreateBranch(string branch, string baseBranch); ITask LockFile(string file); ITask UnlockFile(string file, bool force); + ITask CheckoutFiles(List files); void UpdateGitLog(); void UpdateGitStatus(); void UpdateGitAheadBehindStatus(); @@ -284,6 +285,14 @@ public void UpdateGitStatus() }).Start(); } + public ITask CheckoutFiles( List files ) + { + var discard = GitClient.Discard(files); + discard.OnStart += t => IsBusy = true; + + return discard.Finally(() => IsBusy = false); + } + public void UpdateGitAheadBehindStatus() { ConfigBranch? configBranch; diff --git a/src/GitHub.Api/Git/Tasks/GitCheckoutTask.cs b/src/GitHub.Api/Git/Tasks/GitCheckoutTask.cs new file mode 100644 index 000000000..66e439da6 --- /dev/null +++ b/src/GitHub.Api/Git/Tasks/GitCheckoutTask.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Threading; + +namespace GitHub.Unity +{ + class GitCheckoutTask : ProcessTask + { + private const string TaskName = "git checkout"; + private readonly string arguments; + + public GitCheckoutTask( IEnumerable files, CancellationToken token, + IOutputProcessor processor = null ) : base(token, processor ?? new SimpleOutputProcessor()) + { + Guard.ArgumentNotNull( files, "files" ); + Name = TaskName; + + arguments = "checkout "; + arguments += " -- "; + + foreach( var file in files ) + { + arguments += " \"" + file.ToNPath().ToString( SlashMode.Forward ) + "\""; + } + } + + public GitCheckoutTask( CancellationToken token, + IOutputProcessor processor = null ) : base( token, processor ?? new SimpleOutputProcessor() ) + { + arguments = "checkout -- ."; + } + + public override string ProcessArguments { get { return arguments; } } + public override TaskAffinity Affinity { get { return TaskAffinity.Exclusive; } } + } +} \ No newline at end of file diff --git a/src/GitHub.Api/GitHub.Api.csproj b/src/GitHub.Api/GitHub.Api.csproj index 72cacaedd..6b45e1234 100644 --- a/src/GitHub.Api/GitHub.Api.csproj +++ b/src/GitHub.Api/GitHub.Api.csproj @@ -100,6 +100,7 @@ + diff --git a/src/tests/IntegrationTests/Events/RepositoryManagerTests.cs b/src/tests/IntegrationTests/Events/RepositoryManagerTests.cs index 2a8581320..700b1aae8 100644 --- a/src/tests/IntegrationTests/Events/RepositoryManagerTests.cs +++ b/src/tests/IntegrationTests/Events/RepositoryManagerTests.cs @@ -755,5 +755,64 @@ public async Task ShouldDetectGitFetch() EndTest(logger); } } + + + + [Test] + public async Task ShouldCheckoutFiles() + { + await Initialize( TestRepoMasterCleanSynchronized ); + + var repositoryManagerListener = Substitute.For(); + repositoryManagerListener.AttachListener( RepositoryManager, repositoryManagerEvents ); + + var expected = new GitStatus + { + Behind = 1, + LocalBranch = "master", + RemoteBranch = "origin/master", + Entries = + new List { + new GitStatusEntry("foobar.txt", TestRepoMasterCleanSynchronized.Combine("foobar.txt"), + "foobar.txt", GitFileStatus.None) + } + }; + + var result = new GitStatus(); + Environment.Repository.OnStatusUpdated += status => { result = status; }; + + var foobarTxt = TestRepoMasterCleanSynchronized.Combine( "foobar.txt" ); + foobarTxt.WriteAllText( "foobar" ); + + await TaskManager.Wait(); + RepositoryManager.WaitForEvents(); + WaitForNotBusy( repositoryManagerEvents, 1 ); + + repositoryManagerListener.Received().OnStatusUpdate( Args.GitStatus ); + repositoryManagerListener.DidNotReceive().OnActiveBranchChanged( Arg.Any() ); + repositoryManagerListener.DidNotReceive().OnActiveRemoteChanged( Arg.Any() ); + repositoryManagerListener.DidNotReceive().OnLocalBranchListChanged(); + repositoryManagerListener.DidNotReceive().OnRemoteBranchListChanged(); + repositoryManagerListener.Received().OnIsBusyChanged( Args.Bool ); + repositoryManagerListener.DidNotReceive().OnLocksUpdated( Args.EnumerableGitLock ); + + await RepositoryManager.CheckoutFiles( new List() { "foobar.txt" } ) + .StartAsAsync(); + + await TaskManager.Wait(); + RepositoryManager.WaitForEvents(); + WaitForNotBusy( repositoryManagerEvents, 1 ); + repositoryManagerEvents.OnStatusUpdate.WaitOne( TimeSpan.FromSeconds( 1 ) ); + + repositoryManagerListener.Received().OnStatusUpdate( Args.GitStatus ); + repositoryManagerListener.DidNotReceive().OnActiveBranchChanged( Arg.Any() ); + repositoryManagerListener.DidNotReceive().OnActiveRemoteChanged( Arg.Any() ); + repositoryManagerListener.DidNotReceive().OnLocalBranchListChanged(); + repositoryManagerListener.DidNotReceive().OnRemoteBranchListChanged(); + repositoryManagerListener.Received().OnIsBusyChanged( Args.Bool ); + repositoryManagerListener.DidNotReceive().OnLocksUpdated( Args.EnumerableGitLock ); + + result.AssertEqual( expected ); + } } } From 26aa280ba05daab252f52ba49ae5ab8ba466ea3a Mon Sep 17 00:00:00 2001 From: Mauro Palumbo Date: Tue, 17 Oct 2017 10:11:38 +0200 Subject: [PATCH 012/873] changed expected status in Checkout unit test --- src/tests/IntegrationTests/Events/RepositoryManagerTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/IntegrationTests/Events/RepositoryManagerTests.cs b/src/tests/IntegrationTests/Events/RepositoryManagerTests.cs index 700b1aae8..d9f962e69 100644 --- a/src/tests/IntegrationTests/Events/RepositoryManagerTests.cs +++ b/src/tests/IntegrationTests/Events/RepositoryManagerTests.cs @@ -774,7 +774,7 @@ public async Task ShouldCheckoutFiles() Entries = new List { new GitStatusEntry("foobar.txt", TestRepoMasterCleanSynchronized.Combine("foobar.txt"), - "foobar.txt", GitFileStatus.None) + "foobar.txt", GitFileStatus.Untracked) } }; From 67ed791cc3be9f1f8bb442aca7f86ac0807d0b81 Mon Sep 17 00:00:00 2001 From: Mauro Palumbo Date: Wed, 18 Oct 2017 14:43:42 +0200 Subject: [PATCH 013/873] Added repositoryManagerListener reset in Checkout test --- src/tests/IntegrationTests/Events/RepositoryManagerTests.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tests/IntegrationTests/Events/RepositoryManagerTests.cs b/src/tests/IntegrationTests/Events/RepositoryManagerTests.cs index d9f962e69..ac4dba20e 100644 --- a/src/tests/IntegrationTests/Events/RepositoryManagerTests.cs +++ b/src/tests/IntegrationTests/Events/RepositoryManagerTests.cs @@ -813,6 +813,9 @@ public async Task ShouldCheckoutFiles() repositoryManagerListener.DidNotReceive().OnLocksUpdated( Args.EnumerableGitLock ); result.AssertEqual( expected ); - } + + repositoryManagerListener.ClearReceivedCalls(); + repositoryManagerEvents.Reset(); + } } } From dcf27c90e2b272001914afc7dd8c6979dc237522 Mon Sep 17 00:00:00 2001 From: Mauro Palumbo Date: Thu, 19 Oct 2017 10:09:42 +0200 Subject: [PATCH 014/873] Styling fixes --- src/GitHub.Api/Git/GitClient.cs | 72 ++++++------ src/GitHub.Api/Git/IRepository.cs | 2 +- src/GitHub.Api/Git/Repository.cs | 8 +- src/GitHub.Api/Git/RepositoryManager.cs | 14 +-- src/GitHub.Api/Git/Tasks/GitCheckoutTask.cs | 48 ++++---- .../Events/RepositoryManagerTests.cs | 110 +++++++++--------- 6 files changed, 127 insertions(+), 127 deletions(-) diff --git a/src/GitHub.Api/Git/GitClient.cs b/src/GitHub.Api/Git/GitClient.cs index 0e0f16c65..f5ac5d9c5 100644 --- a/src/GitHub.Api/Git/GitClient.cs +++ b/src/GitHub.Api/Git/GitClient.cs @@ -69,12 +69,12 @@ ITask Add(IList files, ITask AddAll(IOutputProcessor processor = null); - ITask Discard( IList files, - IOutputProcessor processor = null ); + ITask Discard(IList files, + IOutputProcessor processor = null); - ITask DiscardAll( IOutputProcessor processor = null ); + ITask DiscardAll(IOutputProcessor processor = null); - ITask Remove(IList files, + ITask Remove(IList files, IOutputProcessor processor = null); ITask AddAndCommit(IList files, string message, string body, @@ -370,38 +370,38 @@ public ITask Add(IList files, return last; } - public ITask Discard( IList files, - IOutputProcessor processor = null ) - { - Logger.Trace("Checkout Files"); - - GitCheckoutTask last = null; - foreach( var batch in files.Spool( 5000 ) ) - { - var current = new GitCheckoutTask( batch, cancellationToken, processor ).Configure( processManager ); - if( last == null ) - { - last = current; - } - else - { - last.Then( current ); - last = current; - } - } - - return last; - } - - public ITask DiscardAll( IOutputProcessor processor = null ) - { - Logger.Trace( "Checkout all files" ); - - return new GitCheckoutTask( cancellationToken, processor ) - .Configure( processManager ); - } - - public ITask Remove(IList files, + public ITask Discard( IList files, + IOutputProcessor processor = null) + { + Logger.Trace("Checkout Files"); + + GitCheckoutTask last = null; + foreach (var batch in files.Spool(5000)) + { + var current = new GitCheckoutTask(batch, cancellationToken, processor).Configure(processManager); + if (last == null) + { + last = current; + } + else + { + last.Then(current); + last = current; + } + } + + return last; + } + + public ITask DiscardAll(IOutputProcessor processor = null) + { + Logger.Trace("Checkout all files"); + + return new GitCheckoutTask(cancellationToken, processor) + .Configure(processManager); + } + + public ITask Remove(IList files, IOutputProcessor processor = null) { Logger.Trace("Remove"); diff --git a/src/GitHub.Api/Git/IRepository.cs b/src/GitHub.Api/Git/IRepository.cs index ec999b4bc..7b9501e25 100644 --- a/src/GitHub.Api/Git/IRepository.cs +++ b/src/GitHub.Api/Git/IRepository.cs @@ -18,7 +18,7 @@ public interface IRepository : IEquatable ITask Revert(string changeset); ITask RequestLock(string file); ITask ReleaseLock(string file, bool force); - ITask CheckoutFiles( List files ); + ITask CheckoutFiles(List files); void CheckLogChangedEvent(CacheUpdateEvent gitLogCacheUpdateEvent); void CheckStatusChangedEvent(CacheUpdateEvent cacheUpdateEvent); diff --git a/src/GitHub.Api/Git/Repository.cs b/src/GitHub.Api/Git/Repository.cs index 4e72d2192..580a8b868 100644 --- a/src/GitHub.Api/Git/Repository.cs +++ b/src/GitHub.Api/Git/Repository.cs @@ -112,10 +112,10 @@ public ITask ReleaseLock(string file, bool force) return repositoryManager.UnlockFile(file, force); } - public ITask CheckoutFiles( List files ) - { - return repositoryManager.CheckoutFiles( files ); - } + public ITask CheckoutFiles(List files) + { + return repositoryManager.CheckoutFiles(files); + } public void CheckLogChangedEvent(CacheUpdateEvent cacheUpdateEvent) { diff --git a/src/GitHub.Api/Git/RepositoryManager.cs b/src/GitHub.Api/Git/RepositoryManager.cs index a60893d15..b9fed4e64 100644 --- a/src/GitHub.Api/Git/RepositoryManager.cs +++ b/src/GitHub.Api/Git/RepositoryManager.cs @@ -35,7 +35,7 @@ public interface IRepositoryManager : IDisposable ITask CreateBranch(string branch, string baseBranch); ITask LockFile(string file); ITask UnlockFile(string file, bool force); - ITask CheckoutFiles(List files); + ITask CheckoutFiles(List files); void UpdateGitLog(); void UpdateGitStatus(); void UpdateGitAheadBehindStatus(); @@ -285,13 +285,13 @@ public void UpdateGitStatus() }).Start(); } - public ITask CheckoutFiles( List files ) - { - var discard = GitClient.Discard(files); - discard.OnStart += t => IsBusy = true; + public ITask CheckoutFiles(List files) + { + var discard = GitClient.Discard(files); + discard.OnStart += t => IsBusy = true; - return discard.Finally(() => IsBusy = false); - } + return discard.Finally(() => IsBusy = false); + } public void UpdateGitAheadBehindStatus() { diff --git a/src/GitHub.Api/Git/Tasks/GitCheckoutTask.cs b/src/GitHub.Api/Git/Tasks/GitCheckoutTask.cs index 66e439da6..f64c89130 100644 --- a/src/GitHub.Api/Git/Tasks/GitCheckoutTask.cs +++ b/src/GitHub.Api/Git/Tasks/GitCheckoutTask.cs @@ -4,33 +4,33 @@ namespace GitHub.Unity { - class GitCheckoutTask : ProcessTask - { - private const string TaskName = "git checkout"; - private readonly string arguments; + class GitCheckoutTask : ProcessTask + { + private const string TaskName = "git checkout"; + private readonly string arguments; - public GitCheckoutTask( IEnumerable files, CancellationToken token, - IOutputProcessor processor = null ) : base(token, processor ?? new SimpleOutputProcessor()) - { - Guard.ArgumentNotNull( files, "files" ); - Name = TaskName; + public GitCheckoutTask(IEnumerable files, CancellationToken token, + IOutputProcessor processor = null) : base(token, processor ?? new SimpleOutputProcessor()) + { + Guard.ArgumentNotNull(files, "files"); + Name = TaskName; - arguments = "checkout "; - arguments += " -- "; + arguments = "checkout "; + arguments += " -- "; - foreach( var file in files ) - { - arguments += " \"" + file.ToNPath().ToString( SlashMode.Forward ) + "\""; - } - } + foreach (var file in files) + { + arguments += " \"" + file.ToNPath().ToString(SlashMode.Forward) + "\""; + } + } - public GitCheckoutTask( CancellationToken token, - IOutputProcessor processor = null ) : base( token, processor ?? new SimpleOutputProcessor() ) - { - arguments = "checkout -- ."; - } + public GitCheckoutTask(CancellationToken token, + IOutputProcessor processor = null) : base(token, processor ?? new SimpleOutputProcessor()) + { + arguments = "checkout -- ."; + } - public override string ProcessArguments { get { return arguments; } } - public override TaskAffinity Affinity { get { return TaskAffinity.Exclusive; } } - } + public override string ProcessArguments { get { return arguments; } } + public override TaskAffinity Affinity { get { return TaskAffinity.Exclusive; } } + } } \ No newline at end of file diff --git a/src/tests/IntegrationTests/Events/RepositoryManagerTests.cs b/src/tests/IntegrationTests/Events/RepositoryManagerTests.cs index ac4dba20e..e15d890fa 100644 --- a/src/tests/IntegrationTests/Events/RepositoryManagerTests.cs +++ b/src/tests/IntegrationTests/Events/RepositoryManagerTests.cs @@ -758,61 +758,61 @@ public async Task ShouldDetectGitFetch() - [Test] - public async Task ShouldCheckoutFiles() - { - await Initialize( TestRepoMasterCleanSynchronized ); - - var repositoryManagerListener = Substitute.For(); - repositoryManagerListener.AttachListener( RepositoryManager, repositoryManagerEvents ); - - var expected = new GitStatus - { - Behind = 1, - LocalBranch = "master", - RemoteBranch = "origin/master", - Entries = - new List { - new GitStatusEntry("foobar.txt", TestRepoMasterCleanSynchronized.Combine("foobar.txt"), - "foobar.txt", GitFileStatus.Untracked) - } - }; - - var result = new GitStatus(); - Environment.Repository.OnStatusUpdated += status => { result = status; }; - - var foobarTxt = TestRepoMasterCleanSynchronized.Combine( "foobar.txt" ); - foobarTxt.WriteAllText( "foobar" ); - - await TaskManager.Wait(); - RepositoryManager.WaitForEvents(); - WaitForNotBusy( repositoryManagerEvents, 1 ); - - repositoryManagerListener.Received().OnStatusUpdate( Args.GitStatus ); - repositoryManagerListener.DidNotReceive().OnActiveBranchChanged( Arg.Any() ); - repositoryManagerListener.DidNotReceive().OnActiveRemoteChanged( Arg.Any() ); - repositoryManagerListener.DidNotReceive().OnLocalBranchListChanged(); - repositoryManagerListener.DidNotReceive().OnRemoteBranchListChanged(); - repositoryManagerListener.Received().OnIsBusyChanged( Args.Bool ); - repositoryManagerListener.DidNotReceive().OnLocksUpdated( Args.EnumerableGitLock ); - - await RepositoryManager.CheckoutFiles( new List() { "foobar.txt" } ) - .StartAsAsync(); - - await TaskManager.Wait(); - RepositoryManager.WaitForEvents(); - WaitForNotBusy( repositoryManagerEvents, 1 ); - repositoryManagerEvents.OnStatusUpdate.WaitOne( TimeSpan.FromSeconds( 1 ) ); - - repositoryManagerListener.Received().OnStatusUpdate( Args.GitStatus ); - repositoryManagerListener.DidNotReceive().OnActiveBranchChanged( Arg.Any() ); - repositoryManagerListener.DidNotReceive().OnActiveRemoteChanged( Arg.Any() ); - repositoryManagerListener.DidNotReceive().OnLocalBranchListChanged(); - repositoryManagerListener.DidNotReceive().OnRemoteBranchListChanged(); - repositoryManagerListener.Received().OnIsBusyChanged( Args.Bool ); - repositoryManagerListener.DidNotReceive().OnLocksUpdated( Args.EnumerableGitLock ); - - result.AssertEqual( expected ); + [Test] + public async Task ShouldCheckoutFiles() + { + await Initialize(TestRepoMasterCleanSynchronized); + + var repositoryManagerListener = Substitute.For(); + repositoryManagerListener.AttachListener(RepositoryManager, repositoryManagerEvents); + + var expected = new GitStatus + { + Behind = 1, + LocalBranch = "master", + RemoteBranch = "origin/master", + Entries = + new List { + new GitStatusEntry("foobar.txt", TestRepoMasterCleanSynchronized.Combine("foobar.txt"), + "foobar.txt", GitFileStatus.Untracked) + } + }; + + var result = new GitStatus(); + Environment.Repository.OnStatusUpdated += status => { result = status; }; + + var foobarTxt = TestRepoMasterCleanSynchronized.Combine("foobar.txt"); + foobarTxt.WriteAllText("foobar"); + + await TaskManager.Wait(); + RepositoryManager.WaitForEvents(); + WaitForNotBusy(repositoryManagerEvents, 1); + + repositoryManagerListener.Received().OnStatusUpdate(Args.GitStatus); + repositoryManagerListener.DidNotReceive().OnActiveBranchChanged(Arg.Any()); + repositoryManagerListener.DidNotReceive().OnActiveRemoteChanged(Arg.Any()); + repositoryManagerListener.DidNotReceive().OnLocalBranchListChanged(); + repositoryManagerListener.DidNotReceive().OnRemoteBranchListChanged(); + repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); + repositoryManagerListener.DidNotReceive().OnLocksUpdated(Args.EnumerableGitLock); + + await RepositoryManager.CheckoutFiles(new List() { "foobar.txt" }) + .StartAsAsync(); + + await TaskManager.Wait(); + RepositoryManager.WaitForEvents(); + WaitForNotBusy(repositoryManagerEvents, 1); + repositoryManagerEvents.OnStatusUpdate.WaitOne(TimeSpan.FromSeconds(1)); + + repositoryManagerListener.Received().OnStatusUpdate(Args.GitStatus); + repositoryManagerListener.DidNotReceive().OnActiveBranchChanged(Arg.Any()); + repositoryManagerListener.DidNotReceive().OnActiveRemoteChanged(Arg.Any()); + repositoryManagerListener.DidNotReceive().OnLocalBranchListChanged(); + repositoryManagerListener.DidNotReceive().OnRemoteBranchListChanged(); + repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); + repositoryManagerListener.DidNotReceive().OnLocksUpdated(Args.EnumerableGitLock); + + result.AssertEqual(expected); repositoryManagerListener.ClearReceivedCalls(); repositoryManagerEvents.Reset(); From 23c642a9bdaa77043dbf45abd511e107bc4b0df3 Mon Sep 17 00:00:00 2001 From: Mauro Palumbo Date: Wed, 25 Oct 2017 13:57:26 +0200 Subject: [PATCH 015/873] Renamed IRepository::CheckoutFiles to DiscardChanges to better reflect its functionality --- src/GitHub.Api/Git/IRepository.cs | 4 ++-- src/GitHub.Api/Git/Repository.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/GitHub.Api/Git/IRepository.cs b/src/GitHub.Api/Git/IRepository.cs index 7b9501e25..95f35d3ba 100644 --- a/src/GitHub.Api/Git/IRepository.cs +++ b/src/GitHub.Api/Git/IRepository.cs @@ -4,7 +4,7 @@ namespace GitHub.Unity { /// - /// Represents a repository, either local or retreived via the GitHub API. + /// Represents a repository, either local or retrieved via the GitHub API. /// public interface IRepository : IEquatable { @@ -18,7 +18,7 @@ public interface IRepository : IEquatable ITask Revert(string changeset); ITask RequestLock(string file); ITask ReleaseLock(string file, bool force); - ITask CheckoutFiles(List files); + ITask DiscardChanges(List files); void CheckLogChangedEvent(CacheUpdateEvent gitLogCacheUpdateEvent); void CheckStatusChangedEvent(CacheUpdateEvent cacheUpdateEvent); diff --git a/src/GitHub.Api/Git/Repository.cs b/src/GitHub.Api/Git/Repository.cs index 580a8b868..903d222fa 100644 --- a/src/GitHub.Api/Git/Repository.cs +++ b/src/GitHub.Api/Git/Repository.cs @@ -112,7 +112,7 @@ public ITask ReleaseLock(string file, bool force) return repositoryManager.UnlockFile(file, force); } - public ITask CheckoutFiles(List files) + public ITask DiscardChanges(List files) { return repositoryManager.CheckoutFiles(files); } From 618e9dc7fd30588ab837a640f7bd09bfaa332fb0 Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Wed, 13 Dec 2017 15:15:02 -0500 Subject: [PATCH 016/873] Removing integration test --- src/GitHub.Api/Git/GitClient.cs | 2 +- .../Events/RepositoryManagerTests.cs | 62 ------------------- 2 files changed, 1 insertion(+), 63 deletions(-) diff --git a/src/GitHub.Api/Git/GitClient.cs b/src/GitHub.Api/Git/GitClient.cs index f5ac5d9c5..3c61bfd33 100644 --- a/src/GitHub.Api/Git/GitClient.cs +++ b/src/GitHub.Api/Git/GitClient.cs @@ -370,7 +370,7 @@ public ITask Add(IList files, return last; } - public ITask Discard( IList files, + public ITask Discard( IList files, IOutputProcessor processor = null) { Logger.Trace("Checkout Files"); diff --git a/src/tests/IntegrationTests/Events/RepositoryManagerTests.cs b/src/tests/IntegrationTests/Events/RepositoryManagerTests.cs index e15d890fa..2a8581320 100644 --- a/src/tests/IntegrationTests/Events/RepositoryManagerTests.cs +++ b/src/tests/IntegrationTests/Events/RepositoryManagerTests.cs @@ -755,67 +755,5 @@ public async Task ShouldDetectGitFetch() EndTest(logger); } } - - - - [Test] - public async Task ShouldCheckoutFiles() - { - await Initialize(TestRepoMasterCleanSynchronized); - - var repositoryManagerListener = Substitute.For(); - repositoryManagerListener.AttachListener(RepositoryManager, repositoryManagerEvents); - - var expected = new GitStatus - { - Behind = 1, - LocalBranch = "master", - RemoteBranch = "origin/master", - Entries = - new List { - new GitStatusEntry("foobar.txt", TestRepoMasterCleanSynchronized.Combine("foobar.txt"), - "foobar.txt", GitFileStatus.Untracked) - } - }; - - var result = new GitStatus(); - Environment.Repository.OnStatusUpdated += status => { result = status; }; - - var foobarTxt = TestRepoMasterCleanSynchronized.Combine("foobar.txt"); - foobarTxt.WriteAllText("foobar"); - - await TaskManager.Wait(); - RepositoryManager.WaitForEvents(); - WaitForNotBusy(repositoryManagerEvents, 1); - - repositoryManagerListener.Received().OnStatusUpdate(Args.GitStatus); - repositoryManagerListener.DidNotReceive().OnActiveBranchChanged(Arg.Any()); - repositoryManagerListener.DidNotReceive().OnActiveRemoteChanged(Arg.Any()); - repositoryManagerListener.DidNotReceive().OnLocalBranchListChanged(); - repositoryManagerListener.DidNotReceive().OnRemoteBranchListChanged(); - repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); - repositoryManagerListener.DidNotReceive().OnLocksUpdated(Args.EnumerableGitLock); - - await RepositoryManager.CheckoutFiles(new List() { "foobar.txt" }) - .StartAsAsync(); - - await TaskManager.Wait(); - RepositoryManager.WaitForEvents(); - WaitForNotBusy(repositoryManagerEvents, 1); - repositoryManagerEvents.OnStatusUpdate.WaitOne(TimeSpan.FromSeconds(1)); - - repositoryManagerListener.Received().OnStatusUpdate(Args.GitStatus); - repositoryManagerListener.DidNotReceive().OnActiveBranchChanged(Arg.Any()); - repositoryManagerListener.DidNotReceive().OnActiveRemoteChanged(Arg.Any()); - repositoryManagerListener.DidNotReceive().OnLocalBranchListChanged(); - repositoryManagerListener.DidNotReceive().OnRemoteBranchListChanged(); - repositoryManagerListener.Received().OnIsBusyChanged(Args.Bool); - repositoryManagerListener.DidNotReceive().OnLocksUpdated(Args.EnumerableGitLock); - - result.AssertEqual(expected); - - repositoryManagerListener.ClearReceivedCalls(); - repositoryManagerEvents.Reset(); - } } } From 5a478a152004e0c64cf52119b2cb304fdcddcc9c Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Mon, 18 Dec 2017 22:24:16 -0500 Subject: [PATCH 017/873] Functionality to revert and delete --- .../Application/ApplicationManagerBase.cs | 2 +- src/GitHub.Api/Git/IRepository.cs | 1 + src/GitHub.Api/Git/Repository.cs | 5 ++ src/GitHub.Api/Git/RepositoryManager.cs | 24 +++++++-- src/GitHub.Api/GitHub.Api.csproj | 1 + .../Platform/DeleteFilesExecTask.cs | 31 +++++++++++ .../Editor/GitHub.Unity/UI/ChangesView.cs | 53 ++++++++++++++++++- .../BaseGitEnvironmentTest.cs | 3 +- 8 files changed, 113 insertions(+), 7 deletions(-) create mode 100644 src/GitHub.Api/Platform/DeleteFilesExecTask.cs diff --git a/src/GitHub.Api/Application/ApplicationManagerBase.cs b/src/GitHub.Api/Application/ApplicationManagerBase.cs index 61894c369..d6ca6f2fb 100644 --- a/src/GitHub.Api/Application/ApplicationManagerBase.cs +++ b/src/GitHub.Api/Application/ApplicationManagerBase.cs @@ -128,7 +128,7 @@ public void RestartRepository() { if (Environment.RepositoryPath != null) { - repositoryManager = Unity.RepositoryManager.CreateInstance(Platform, TaskManager, GitClient, Environment.RepositoryPath); + repositoryManager = Unity.RepositoryManager.CreateInstance(Platform, TaskManager, GitClient, ProcessManager, Environment.RepositoryPath); repositoryManager.Initialize(); Environment.Repository.Initialize(repositoryManager); repositoryManager.Start(); diff --git a/src/GitHub.Api/Git/IRepository.cs b/src/GitHub.Api/Git/IRepository.cs index 95f35d3ba..8ca785412 100644 --- a/src/GitHub.Api/Git/IRepository.cs +++ b/src/GitHub.Api/Git/IRepository.cs @@ -19,6 +19,7 @@ public interface IRepository : IEquatable ITask RequestLock(string file); ITask ReleaseLock(string file, bool force); ITask DiscardChanges(List files); + ITask DeleteFiles(List list); void CheckLogChangedEvent(CacheUpdateEvent gitLogCacheUpdateEvent); void CheckStatusChangedEvent(CacheUpdateEvent cacheUpdateEvent); diff --git a/src/GitHub.Api/Git/Repository.cs b/src/GitHub.Api/Git/Repository.cs index 903d222fa..610aae9cc 100644 --- a/src/GitHub.Api/Git/Repository.cs +++ b/src/GitHub.Api/Git/Repository.cs @@ -117,6 +117,11 @@ public ITask DiscardChanges(List files) return repositoryManager.CheckoutFiles(files); } + public ITask DeleteFiles(List list) + { + return repositoryManager.DeleteFiles(list); + } + public void CheckLogChangedEvent(CacheUpdateEvent cacheUpdateEvent) { var managedCache = cacheContainer.GitLogCache; diff --git a/src/GitHub.Api/Git/RepositoryManager.cs b/src/GitHub.Api/Git/RepositoryManager.cs index b9fed4e64..926749808 100644 --- a/src/GitHub.Api/Git/RepositoryManager.cs +++ b/src/GitHub.Api/Git/RepositoryManager.cs @@ -36,6 +36,7 @@ public interface IRepositoryManager : IDisposable ITask LockFile(string file); ITask UnlockFile(string file, bool force); ITask CheckoutFiles(List files); + ITask DeleteFiles(List list); void UpdateGitLog(); void UpdateGitStatus(); void UpdateGitAheadBehindStatus(); @@ -97,6 +98,7 @@ class RepositoryManager : IRepositoryManager { private readonly IGitConfig config; private readonly IGitClient gitClient; + private readonly IProcessManager processManager; private readonly IRepositoryPathConfiguration repositoryPaths; private readonly IRepositoryWatcher watcher; @@ -113,18 +115,19 @@ class RepositoryManager : IRepositoryManager public RepositoryManager(IGitConfig gitConfig, IRepositoryWatcher repositoryWatcher, IGitClient gitClient, + IProcessManager processManager, IRepositoryPathConfiguration repositoryPaths) { this.repositoryPaths = repositoryPaths; this.gitClient = gitClient; + this.processManager = processManager; this.watcher = repositoryWatcher; this.config = gitConfig; SetupWatcher(); } - public static RepositoryManager CreateInstance(IPlatform platform, ITaskManager taskManager, - IGitClient gitClient, NPath repositoryRoot) + public static RepositoryManager CreateInstance(IPlatform platform, ITaskManager taskManager, IGitClient gitClient, IProcessManager processManager, NPath repositoryRoot) { var repositoryPathConfiguration = new RepositoryPathConfiguration(repositoryRoot); string filePath = repositoryPathConfiguration.DotGitConfig; @@ -133,7 +136,7 @@ public static RepositoryManager CreateInstance(IPlatform platform, ITaskManager var repositoryWatcher = new RepositoryWatcher(platform, repositoryPathConfiguration, taskManager.Token); return new RepositoryManager(gitConfig, repositoryWatcher, - gitClient, repositoryPathConfiguration); + gitClient, processManager, repositoryPathConfiguration); } public void Initialize() @@ -293,6 +296,21 @@ public ITask CheckoutFiles(List files) return discard.Finally(() => IsBusy = false); } + public ITask DeleteFiles(List list) + { + ITask> task = new DeleteFilesExecTask(list.ToArray(), CancellationToken.None) + .Configure(processManager); + + task = HookupHandlers(task, true, true); + + var @finally = task.Finally((b, exception, arg3) => { + Logger.Trace("Delete Files success:{0} output: {1}", b, arg3 != null ? string.Join(",", arg3.ToArray()) : "[NULL]"); + }); + + return @finally + .Start(); + } + public void UpdateGitAheadBehindStatus() { ConfigBranch? configBranch; diff --git a/src/GitHub.Api/GitHub.Api.csproj b/src/GitHub.Api/GitHub.Api.csproj index 6b45e1234..b5d01518c 100644 --- a/src/GitHub.Api/GitHub.Api.csproj +++ b/src/GitHub.Api/GitHub.Api.csproj @@ -147,6 +147,7 @@ + diff --git a/src/GitHub.Api/Platform/DeleteFilesExecTask.cs b/src/GitHub.Api/Platform/DeleteFilesExecTask.cs new file mode 100644 index 000000000..e63263a74 --- /dev/null +++ b/src/GitHub.Api/Platform/DeleteFilesExecTask.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; +using System.Threading; + +namespace GitHub.Unity +{ + class DeleteFilesExecTask : ProcessTask> + { + private readonly string arguments; + + public DeleteFilesExecTask(string[] files, CancellationToken token) + : base(token, new SimpleListOutputProcessor()) + { + Name = DefaultEnvironment.OnWindows ? "cmd" : "rm"; + + var fileString = string.Join(" ", files); + if (DefaultEnvironment.OnWindows) + { + arguments = $"/c \"del {fileString}\""; + } + else + { + arguments = fileString; + } + + } + + public override string ProcessName { get { return Name; } } + public override string ProcessArguments { get { return arguments; } } + public override TaskAffinity Affinity { get { return TaskAffinity.Concurrent; } } + } +} \ No newline at end of file diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesView.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesView.cs index 0acdfb56b..51c6138af 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesView.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesView.cs @@ -23,6 +23,9 @@ class ChangesView : Subview [NonSerialized] private bool currentLocksHasUpdate; [NonSerialized] private bool isBusy; + [NonSerialized] private GUIContent revertGuiContent; + [NonSerialized] private GUIContent deleteGuiContent; + [SerializeField] private string commitBody = ""; [SerializeField] private string commitMessage = ""; [SerializeField] private string currentBranch = "[unknown]"; @@ -143,7 +146,10 @@ private void OnTreeGUI(Rect rect) var treeRenderRect = treeChanges.Render(rect, treeScroll, node => { }, node => { }, - node => { }); + node => { + var menu = CreateContextMenu(node); + menu.ShowAsContext(); + }); if (treeChanges.RequiresRepaint) Redraw(); @@ -152,6 +158,51 @@ private void OnTreeGUI(Rect rect) } } + private GenericMenu CreateContextMenu(ChangesTreeNode node) + { + var genericMenu = new GenericMenu(); + var canRevert = false; + var canDelete = false; + + if (!node.isFolder) + { + canRevert = node.GitFileStatus == GitFileStatus.Added + || node.GitFileStatus == GitFileStatus.Modified + || node.GitFileStatus == GitFileStatus.Deleted + || node.GitFileStatus == GitFileStatus.Renamed; + + canDelete = node.GitFileStatus == GitFileStatus.Untracked; + } + + if (canRevert) + { + if (revertGuiContent == null) + { + revertGuiContent = new GUIContent("Revert"); + } + + genericMenu.AddItem(revertGuiContent, false, () => { + Repository.DiscardChanges(new List { node.Path }) + .Start(); + }); + } + + if (canDelete) + { + if (deleteGuiContent == null) + { + deleteGuiContent = new GUIContent("Delete"); + } + + genericMenu.AddItem(deleteGuiContent, false, () => { + Repository.DeleteFiles(new List { node.Path }) + .Start(); + }); + } + + return genericMenu; + } + private void RepositoryOnStatusEntriesChanged(CacheUpdateEvent cacheUpdateEvent) { if (!lastStatusEntriesChangedEvent.Equals(cacheUpdateEvent)) diff --git a/src/tests/IntegrationTests/BaseGitEnvironmentTest.cs b/src/tests/IntegrationTests/BaseGitEnvironmentTest.cs index 522bdef8e..e9ef4d1c5 100644 --- a/src/tests/IntegrationTests/BaseGitEnvironmentTest.cs +++ b/src/tests/IntegrationTests/BaseGitEnvironmentTest.cs @@ -14,8 +14,7 @@ protected IEnvironment Initialize(NPath repoPath, NPath environmentPath = null, { InitializePlatform(repoPath, environmentPath, enableEnvironmentTrace); - var repositoryManager = - GitHub.Unity.RepositoryManager.CreateInstance(Platform, TaskManager, GitClient, repoPath); + var repositoryManager = GitHub.Unity.RepositoryManager.CreateInstance(Platform, TaskManager, GitClient, ProcessManager, repoPath); onRepositoryManagerCreated?.Invoke(repositoryManager); RepositoryManager = repositoryManager; From 2942e249c4658efbc1e13ec57183efb7eb5d2c7d Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Wed, 31 Jan 2018 13:15:44 -0500 Subject: [PATCH 018/873] Doing delete with .Net is a whole lot faster --- .../Application/ApplicationManagerBase.cs | 2 +- src/GitHub.Api/Git/RepositoryManager.cs | 26 +++++++++------- src/GitHub.Api/GitHub.Api.csproj | 1 - .../Platform/DeleteFilesExecTask.cs | 31 ------------------- .../BaseGitEnvironmentTest.cs | 2 +- 5 files changed, 16 insertions(+), 46 deletions(-) delete mode 100644 src/GitHub.Api/Platform/DeleteFilesExecTask.cs diff --git a/src/GitHub.Api/Application/ApplicationManagerBase.cs b/src/GitHub.Api/Application/ApplicationManagerBase.cs index d6ca6f2fb..249f4e237 100644 --- a/src/GitHub.Api/Application/ApplicationManagerBase.cs +++ b/src/GitHub.Api/Application/ApplicationManagerBase.cs @@ -128,7 +128,7 @@ public void RestartRepository() { if (Environment.RepositoryPath != null) { - repositoryManager = Unity.RepositoryManager.CreateInstance(Platform, TaskManager, GitClient, ProcessManager, Environment.RepositoryPath); + repositoryManager = Unity.RepositoryManager.CreateInstance(Platform, TaskManager, GitClient, ProcessManager, Environment.RepositoryPath, Environment.FileSystem); repositoryManager.Initialize(); Environment.Repository.Initialize(repositoryManager); repositoryManager.Start(); diff --git a/src/GitHub.Api/Git/RepositoryManager.cs b/src/GitHub.Api/Git/RepositoryManager.cs index 926749808..d493d71b9 100644 --- a/src/GitHub.Api/Git/RepositoryManager.cs +++ b/src/GitHub.Api/Git/RepositoryManager.cs @@ -100,6 +100,7 @@ class RepositoryManager : IRepositoryManager private readonly IGitClient gitClient; private readonly IProcessManager processManager; private readonly IRepositoryPathConfiguration repositoryPaths; + private readonly IFileSystem fileSystem; private readonly IRepositoryWatcher watcher; private bool isBusy; @@ -116,9 +117,11 @@ class RepositoryManager : IRepositoryManager public RepositoryManager(IGitConfig gitConfig, IRepositoryWatcher repositoryWatcher, IGitClient gitClient, IProcessManager processManager, - IRepositoryPathConfiguration repositoryPaths) + IRepositoryPathConfiguration repositoryPaths, + IFileSystem fileSystem) { this.repositoryPaths = repositoryPaths; + this.fileSystem = fileSystem; this.gitClient = gitClient; this.processManager = processManager; this.watcher = repositoryWatcher; @@ -127,7 +130,7 @@ public RepositoryManager(IGitConfig gitConfig, SetupWatcher(); } - public static RepositoryManager CreateInstance(IPlatform platform, ITaskManager taskManager, IGitClient gitClient, IProcessManager processManager, NPath repositoryRoot) + public static RepositoryManager CreateInstance(IPlatform platform, ITaskManager taskManager, IGitClient gitClient, IProcessManager processManager, NPath repositoryRoot, IFileSystem fileSystem) { var repositoryPathConfiguration = new RepositoryPathConfiguration(repositoryRoot); string filePath = repositoryPathConfiguration.DotGitConfig; @@ -136,7 +139,7 @@ public static RepositoryManager CreateInstance(IPlatform platform, ITaskManager var repositoryWatcher = new RepositoryWatcher(platform, repositoryPathConfiguration, taskManager.Token); return new RepositoryManager(gitConfig, repositoryWatcher, - gitClient, processManager, repositoryPathConfiguration); + gitClient, processManager, repositoryPathConfiguration, fileSystem); } public void Initialize() @@ -298,17 +301,16 @@ public ITask CheckoutFiles(List files) public ITask DeleteFiles(List list) { - ITask> task = new DeleteFilesExecTask(list.ToArray(), CancellationToken.None) - .Configure(processManager); - - task = HookupHandlers(task, true, true); - - var @finally = task.Finally((b, exception, arg3) => { - Logger.Trace("Delete Files success:{0} output: {1}", b, arg3 != null ? string.Join(",", arg3.ToArray()) : "[NULL]"); + var delete = new ActionTask(CancellationToken.None, () => { + for (var index = 0; index < list.Count; index++) + { + fileSystem.FileDelete(list[index]); + } }); - return @finally - .Start(); + delete.OnStart += t => IsBusy = true; + + return delete.Finally(() => IsBusy = false); } public void UpdateGitAheadBehindStatus() diff --git a/src/GitHub.Api/GitHub.Api.csproj b/src/GitHub.Api/GitHub.Api.csproj index b5d01518c..6b45e1234 100644 --- a/src/GitHub.Api/GitHub.Api.csproj +++ b/src/GitHub.Api/GitHub.Api.csproj @@ -147,7 +147,6 @@ - diff --git a/src/GitHub.Api/Platform/DeleteFilesExecTask.cs b/src/GitHub.Api/Platform/DeleteFilesExecTask.cs deleted file mode 100644 index e63263a74..000000000 --- a/src/GitHub.Api/Platform/DeleteFilesExecTask.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Collections.Generic; -using System.Threading; - -namespace GitHub.Unity -{ - class DeleteFilesExecTask : ProcessTask> - { - private readonly string arguments; - - public DeleteFilesExecTask(string[] files, CancellationToken token) - : base(token, new SimpleListOutputProcessor()) - { - Name = DefaultEnvironment.OnWindows ? "cmd" : "rm"; - - var fileString = string.Join(" ", files); - if (DefaultEnvironment.OnWindows) - { - arguments = $"/c \"del {fileString}\""; - } - else - { - arguments = fileString; - } - - } - - public override string ProcessName { get { return Name; } } - public override string ProcessArguments { get { return arguments; } } - public override TaskAffinity Affinity { get { return TaskAffinity.Concurrent; } } - } -} \ No newline at end of file diff --git a/src/tests/IntegrationTests/BaseGitEnvironmentTest.cs b/src/tests/IntegrationTests/BaseGitEnvironmentTest.cs index e9ef4d1c5..c840f236c 100644 --- a/src/tests/IntegrationTests/BaseGitEnvironmentTest.cs +++ b/src/tests/IntegrationTests/BaseGitEnvironmentTest.cs @@ -14,7 +14,7 @@ protected IEnvironment Initialize(NPath repoPath, NPath environmentPath = null, { InitializePlatform(repoPath, environmentPath, enableEnvironmentTrace); - var repositoryManager = GitHub.Unity.RepositoryManager.CreateInstance(Platform, TaskManager, GitClient, ProcessManager, repoPath); + var repositoryManager = GitHub.Unity.RepositoryManager.CreateInstance(Platform, TaskManager, GitClient, ProcessManager, repoPath, Environment.FileSystem); onRepositoryManagerCreated?.Invoke(repositoryManager); RepositoryManager = repositoryManager; From 94f691f76ee77ff58cfab02123c9f070ff48db26 Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Wed, 31 Jan 2018 18:09:34 -0500 Subject: [PATCH 019/873] Allowing RepositoryManager to control the process of discarding changes --- src/GitHub.Api/Git/IRepository.cs | 3 +- src/GitHub.Api/Git/Repository.cs | 9 +- src/GitHub.Api/Git/RepositoryManager.cs | 137 +++++++++++------- .../GitHub.Unity/UI/ChangesTreeControl.cs | 17 +-- .../Editor/GitHub.Unity/UI/ChangesView.cs | 30 +--- 5 files changed, 102 insertions(+), 94 deletions(-) diff --git a/src/GitHub.Api/Git/IRepository.cs b/src/GitHub.Api/Git/IRepository.cs index 8ca785412..83791f9f8 100644 --- a/src/GitHub.Api/Git/IRepository.cs +++ b/src/GitHub.Api/Git/IRepository.cs @@ -18,8 +18,7 @@ public interface IRepository : IEquatable ITask Revert(string changeset); ITask RequestLock(string file); ITask ReleaseLock(string file, bool force); - ITask DiscardChanges(List files); - ITask DeleteFiles(List list); + ITask DiscardChanges(List files); void CheckLogChangedEvent(CacheUpdateEvent gitLogCacheUpdateEvent); void CheckStatusChangedEvent(CacheUpdateEvent cacheUpdateEvent); diff --git a/src/GitHub.Api/Git/Repository.cs b/src/GitHub.Api/Git/Repository.cs index 610aae9cc..68187ce70 100644 --- a/src/GitHub.Api/Git/Repository.cs +++ b/src/GitHub.Api/Git/Repository.cs @@ -112,14 +112,9 @@ public ITask ReleaseLock(string file, bool force) return repositoryManager.UnlockFile(file, force); } - public ITask DiscardChanges(List files) + public ITask DiscardChanges(List files) { - return repositoryManager.CheckoutFiles(files); - } - - public ITask DeleteFiles(List list) - { - return repositoryManager.DeleteFiles(list); + return repositoryManager.DiscardChanges(files); } public void CheckLogChangedEvent(CacheUpdateEvent cacheUpdateEvent) diff --git a/src/GitHub.Api/Git/RepositoryManager.cs b/src/GitHub.Api/Git/RepositoryManager.cs index d493d71b9..e1bb81c2b 100644 --- a/src/GitHub.Api/Git/RepositoryManager.cs +++ b/src/GitHub.Api/Git/RepositoryManager.cs @@ -35,8 +35,7 @@ public interface IRepositoryManager : IDisposable ITask CreateBranch(string branch, string baseBranch); ITask LockFile(string file); ITask UnlockFile(string file, bool force); - ITask CheckoutFiles(List files); - ITask DeleteFiles(List list); + ITask DiscardChanges(List files); void UpdateGitLog(); void UpdateGitStatus(); void UpdateGitAheadBehindStatus(); @@ -218,15 +217,13 @@ public ITask Revert(string changeset) public ITask RemoteAdd(string remote, string url) { var task = GitClient.RemoteAdd(remote, url); - task = HookupHandlers(task, true, false); - return task; + return HookupHandlers(task, true, false); } public ITask RemoteRemove(string remote) { var task = GitClient.RemoteRemove(remote); - task = HookupHandlers(task, true, false); - return task; + return HookupHandlers(task, true, false); } public ITask RemoteChange(string remote, string url) @@ -267,50 +264,86 @@ public ITask UnlockFile(string file, bool force) public void UpdateGitLog() { - var task = GitClient.Log(); - task = HookupHandlers(task, false, false); - task.Then((success, logEntries) => - { - if (success) + var task = GitClient + .Log() + .Then((success, logEntries) => { - GitLogUpdated?.Invoke(logEntries); - } - }).Start(); + if (success) + { + GitLogUpdated?.Invoke(logEntries); + } + }); + task = HookupHandlers(task, false, false); + task.Start(); } public void UpdateGitStatus() { - var task = GitClient.Status(); - task = HookupHandlers(task, true, false); - task.Then((success, status) => - { - if (success) + var task = GitClient + .Status() + .Then((success, status) => { - GitStatusUpdated?.Invoke(status); - } - }).Start(); + if (success) + { + GitStatusUpdated?.Invoke(status); + } + }); + task = HookupHandlers(task, true, false); + task.Start(); } - public ITask CheckoutFiles(List files) + public ITask DiscardChanges(List files) { - var discard = GitClient.Discard(files); - discard.OnStart += t => IsBusy = true; + var itemsToDelete = files + .Where(entry => entry.status == GitFileStatus.Added + || entry.status == GitFileStatus.Untracked) + .Select(entry => entry.path) + .ToArray(); - return discard.Finally(() => IsBusy = false); - } + ActionTask deleteItemsTask = null; + if (itemsToDelete.Any()) + { + deleteItemsTask = new ActionTask(CancellationToken.None, () => { + for (var index = 0; index < itemsToDelete.Length; index++) + { + var itemToDelete = itemsToDelete[index]; + fileSystem.FileDelete(itemToDelete); + } + }); + } - public ITask DeleteFiles(List list) - { - var delete = new ActionTask(CancellationToken.None, () => { - for (var index = 0; index < list.Count; index++) - { - fileSystem.FileDelete(list[index]); - } - }); + var itemsToRevert = files + .Where(entry => entry.status == GitFileStatus.Modified + || entry.status == GitFileStatus.Deleted + || entry.status == GitFileStatus.Renamed) + .Select(entry => entry.path) + .ToArray(); - delete.OnStart += t => IsBusy = true; + ITask gitDiscardTask = null; + if (itemsToRevert.Any()) + { + gitDiscardTask = GitClient.Discard(itemsToRevert); + } - return delete.Finally(() => IsBusy = false); + ITask task; + if(deleteItemsTask != null && gitDiscardTask != null) + { + task = deleteItemsTask.Then(gitDiscardTask); + } + else if (deleteItemsTask != null) + { + task = deleteItemsTask; + } + else if (gitDiscardTask != null) + { + task = gitDiscardTask; + } + else + { + throw new NotImplementedException(); + } + + return HookupHandlers(task, true, true); } public void UpdateGitAheadBehindStatus() @@ -324,15 +357,17 @@ public void UpdateGitAheadBehindStatus() var name = configBranch.Value.Name; var trackingName = configBranch.Value.IsTracking ? configBranch.Value.Remote.Value.Name + "/" + name : "[None]"; - var task = GitClient.AheadBehindStatus(name, trackingName); - task = HookupHandlers(task, true, false); - task.Then((success, status) => - { - if (success) + var task = GitClient + .AheadBehindStatus(name, trackingName) + .Then((success, status) => { - GitAheadBehindStatusUpdated?.Invoke(status); - } - }).Start(); + if (success) + { + GitAheadBehindStatusUpdated?.Invoke(status); + } + }); + task = HookupHandlers(task, true, false); + task.Start(); } else { @@ -353,9 +388,9 @@ public void UpdateLocks() }).Start(); } - private ITask HookupHandlers(ITask task, bool isExclusive, bool filesystemChangesExpected) + private ITask HookupHandlers(ITask task, bool isExclusive, bool filesystemChangesExpected) { - return new ActionTask(TaskManager.Instance.Token, () => { + return new ActionTask(CancellationToken.None, () => { if (isExclusive) { Logger.Trace("Starting Operation - Setting Busy Flag"); @@ -369,7 +404,7 @@ private ITask HookupHandlers(ITask task, bool isExclusive, bool filesys } }) .Then(task) - .Finally((success, exception, result) => { + .Finally((success, exception) => { if (filesystemChangesExpected) { Logger.Trace("Ended Operation - Enable Watcher"); @@ -382,12 +417,10 @@ private ITask HookupHandlers(ITask task, bool isExclusive, bool filesys IsBusy = false; } - if (success) + if (!success) { - return result; + throw exception; } - - throw exception; }); } diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesTreeControl.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesTreeControl.cs index a648f9509..798244dc4 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesTreeControl.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesTreeControl.cs @@ -17,16 +17,16 @@ public class ChangesTreeNode : TreeNode public GitFileStatus gitFileStatus; public bool isLocked; + public GitStatusEntry GitStatusEntry { get; set; } + public string ProjectPath { - get { return projectPath; } - set { projectPath = value; } + get { return GitStatusEntry.projectPath; } } public GitFileStatus GitFileStatus { - get { return gitFileStatus; } - set { gitFileStatus = value; } + get { return GitStatusEntry.status; } } public bool IsLocked @@ -191,15 +191,13 @@ protected Texture GetNodeIconBadge(ChangesTreeNode node) protected override ChangesTreeNode CreateTreeNode(string path, string label, int level, bool isFolder, bool isActive, bool isHidden, bool isCollapsed, bool isChecked, GitStatusEntryTreeData? treeData) { - var gitFileStatus = GitFileStatus.None; - var projectPath = (string) null; + var gitStatusEntry = GitStatusEntry.Default; var isLocked = false; if (treeData.HasValue) { isLocked = treeData.Value.IsLocked; - gitFileStatus = treeData.Value.FileStatus; - projectPath = treeData.Value.ProjectPath; + gitStatusEntry = treeData.Value.GitStatusEntry; } var node = new ChangesTreeNode @@ -213,8 +211,7 @@ protected override ChangesTreeNode CreateTreeNode(string path, string label, int IsCollapsed = isCollapsed, TreeIsCheckable = IsCheckable, CheckState = isChecked ? CheckState.Checked : CheckState.Empty, - GitFileStatus = gitFileStatus, - ProjectPath = projectPath, + GitStatusEntry = gitStatusEntry, IsLocked = isLocked, }; diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesView.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesView.cs index 51c6138af..c631fe3c4 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesView.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesView.cs @@ -24,7 +24,6 @@ class ChangesView : Subview [NonSerialized] private bool isBusy; [NonSerialized] private GUIContent revertGuiContent; - [NonSerialized] private GUIContent deleteGuiContent; [SerializeField] private string commitBody = ""; [SerializeField] private string commitMessage = ""; @@ -161,45 +160,30 @@ private void OnTreeGUI(Rect rect) private GenericMenu CreateContextMenu(ChangesTreeNode node) { var genericMenu = new GenericMenu(); - var canRevert = false; - var canDelete = false; + var canDiscard = false; if (!node.isFolder) { - canRevert = node.GitFileStatus == GitFileStatus.Added + canDiscard = node.GitFileStatus == GitFileStatus.Added || node.GitFileStatus == GitFileStatus.Modified || node.GitFileStatus == GitFileStatus.Deleted - || node.GitFileStatus == GitFileStatus.Renamed; - - canDelete = node.GitFileStatus == GitFileStatus.Untracked; + || node.GitFileStatus == GitFileStatus.Renamed + || node.GitFileStatus == GitFileStatus.Untracked; } - if (canRevert) + if (canDiscard) { if (revertGuiContent == null) { - revertGuiContent = new GUIContent("Revert"); + revertGuiContent = new GUIContent("Discard"); } genericMenu.AddItem(revertGuiContent, false, () => { - Repository.DiscardChanges(new List { node.Path }) + Repository.DiscardChanges(new List { node.GitStatusEntry }) .Start(); }); } - if (canDelete) - { - if (deleteGuiContent == null) - { - deleteGuiContent = new GUIContent("Delete"); - } - - genericMenu.AddItem(deleteGuiContent, false, () => { - Repository.DeleteFiles(new List { node.Path }) - .Start(); - }); - } - return genericMenu; } From bc63155dcebe8dadff05bd1861c1b712a664bf66 Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Wed, 31 Jan 2018 18:16:13 -0500 Subject: [PATCH 020/873] Renaming the GuiContent variable --- .../Assets/Editor/GitHub.Unity/UI/ChangesView.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesView.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesView.cs index c631fe3c4..ba3c26118 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesView.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesView.cs @@ -23,7 +23,7 @@ class ChangesView : Subview [NonSerialized] private bool currentLocksHasUpdate; [NonSerialized] private bool isBusy; - [NonSerialized] private GUIContent revertGuiContent; + [NonSerialized] private GUIContent discardGuiContent; [SerializeField] private string commitBody = ""; [SerializeField] private string commitMessage = ""; @@ -173,12 +173,12 @@ private GenericMenu CreateContextMenu(ChangesTreeNode node) if (canDiscard) { - if (revertGuiContent == null) + if (discardGuiContent == null) { - revertGuiContent = new GUIContent("Discard"); + discardGuiContent = new GUIContent("Discard"); } - genericMenu.AddItem(revertGuiContent, false, () => { + genericMenu.AddItem(discardGuiContent, false, () => { Repository.DiscardChanges(new List { node.GitStatusEntry }) .Start(); }); From c08b7768edd3ce0d03e40621259a9bc31eec663d Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Thu, 1 Feb 2018 09:50:12 -0500 Subject: [PATCH 021/873] Functionality to revert changes for a folder --- src/GitHub.Api/Git/IRepository.cs | 3 +- src/GitHub.Api/Git/Repository.cs | 4 +- src/GitHub.Api/Git/RepositoryManager.cs | 45 +++++++++---------- src/GitHub.Api/UI/TreeBase.cs | 27 +++++++++++ .../Editor/GitHub.Unity/UI/ChangesView.cs | 32 ++++++------- 5 files changed, 68 insertions(+), 43 deletions(-) diff --git a/src/GitHub.Api/Git/IRepository.cs b/src/GitHub.Api/Git/IRepository.cs index 83791f9f8..7acf918f0 100644 --- a/src/GitHub.Api/Git/IRepository.cs +++ b/src/GitHub.Api/Git/IRepository.cs @@ -18,8 +18,7 @@ public interface IRepository : IEquatable ITask Revert(string changeset); ITask RequestLock(string file); ITask ReleaseLock(string file, bool force); - ITask DiscardChanges(List files); - + ITask DiscardChanges(GitStatusEntry[] discardEntries); void CheckLogChangedEvent(CacheUpdateEvent gitLogCacheUpdateEvent); void CheckStatusChangedEvent(CacheUpdateEvent cacheUpdateEvent); void CheckStatusEntriesChangedEvent(CacheUpdateEvent cacheUpdateEvent); diff --git a/src/GitHub.Api/Git/Repository.cs b/src/GitHub.Api/Git/Repository.cs index 68187ce70..16e509c05 100644 --- a/src/GitHub.Api/Git/Repository.cs +++ b/src/GitHub.Api/Git/Repository.cs @@ -112,9 +112,9 @@ public ITask ReleaseLock(string file, bool force) return repositoryManager.UnlockFile(file, force); } - public ITask DiscardChanges(List files) + public ITask DiscardChanges(GitStatusEntry[] gitStatusEntry) { - return repositoryManager.DiscardChanges(files); + return repositoryManager.DiscardChanges(gitStatusEntry); } public void CheckLogChangedEvent(CacheUpdateEvent cacheUpdateEvent) diff --git a/src/GitHub.Api/Git/RepositoryManager.cs b/src/GitHub.Api/Git/RepositoryManager.cs index e1bb81c2b..6bbddc9f0 100644 --- a/src/GitHub.Api/Git/RepositoryManager.cs +++ b/src/GitHub.Api/Git/RepositoryManager.cs @@ -17,6 +17,7 @@ public interface IRepositoryManager : IDisposable event Action> GitLogUpdated; event Action> LocalBranchesUpdated; event Action, Dictionary>> RemoteBranchesUpdated; + event Action GitAheadBehindStatusUpdated; void Initialize(); void Start(); @@ -35,7 +36,7 @@ public interface IRepositoryManager : IDisposable ITask CreateBranch(string branch, string baseBranch); ITask LockFile(string file); ITask UnlockFile(string file, bool force); - ITask DiscardChanges(List files); + ITask DiscardChanges(GitStatusEntry[] gitStatusEntries); void UpdateGitLog(); void UpdateGitStatus(); void UpdateGitAheadBehindStatus(); @@ -45,7 +46,6 @@ public interface IRepositoryManager : IDisposable IGitConfig Config { get; } IGitClient GitClient { get; } bool IsBusy { get; } - event Action GitAheadBehindStatusUpdated; } interface IRepositoryPathConfiguration @@ -292,33 +292,36 @@ public void UpdateGitStatus() task.Start(); } - public ITask DiscardChanges(List files) + public ITask DiscardChanges(GitStatusEntry[] gitStatusEntries) { - var itemsToDelete = files - .Where(entry => entry.status == GitFileStatus.Added - || entry.status == GitFileStatus.Untracked) - .Select(entry => entry.path) - .ToArray(); + Guard.ArgumentNotNullOrEmpty(gitStatusEntries, "gitStatusEntries"); + + var itemsToDelete = new List(); + var itemsToRevert = new List(); + + foreach (var gitStatusEntry in gitStatusEntries) + { + if (gitStatusEntry.status == GitFileStatus.Added || gitStatusEntry.status == GitFileStatus.Untracked) + { + itemsToDelete.Add(gitStatusEntry.path); + } + else + { + itemsToRevert.Add(gitStatusEntry.path); + } + } ActionTask deleteItemsTask = null; if (itemsToDelete.Any()) { deleteItemsTask = new ActionTask(CancellationToken.None, () => { - for (var index = 0; index < itemsToDelete.Length; index++) + foreach (var itemToDelete in itemsToDelete) { - var itemToDelete = itemsToDelete[index]; fileSystem.FileDelete(itemToDelete); } }); } - var itemsToRevert = files - .Where(entry => entry.status == GitFileStatus.Modified - || entry.status == GitFileStatus.Deleted - || entry.status == GitFileStatus.Renamed) - .Select(entry => entry.path) - .ToArray(); - ITask gitDiscardTask = null; if (itemsToRevert.Any()) { @@ -326,7 +329,7 @@ public ITask DiscardChanges(List files) } ITask task; - if(deleteItemsTask != null && gitDiscardTask != null) + if (deleteItemsTask != null && gitDiscardTask != null) { task = deleteItemsTask.Then(gitDiscardTask); } @@ -334,14 +337,10 @@ public ITask DiscardChanges(List files) { task = deleteItemsTask; } - else if (gitDiscardTask != null) + else //if (gitDiscardTask != null) { task = gitDiscardTask; } - else - { - throw new NotImplementedException(); - } return HookupHandlers(task, true, true); } diff --git a/src/GitHub.Api/UI/TreeBase.cs b/src/GitHub.Api/UI/TreeBase.cs index fecf2063f..0c46b1888 100644 --- a/src/GitHub.Api/UI/TreeBase.cs +++ b/src/GitHub.Api/UI/TreeBase.cs @@ -290,6 +290,33 @@ private void ToggleChildrenChecked(int idx, TNode node, bool isChecked) } } + public List GetLeafNodes(TNode parentNode) + { + var index = Nodes.IndexOf(parentNode); + return GetLeafNodes(parentNode, index); + } + + private List GetLeafNodes(TNode node, int idx) + { + var results = new List(); + for (var i = idx + 1; i < Nodes.Count && node.Level < Nodes[i].Level; i++) + { + var childNode = Nodes[i]; + if (childNode.IsFolder) + { + var leafNodes = GetLeafNodes(childNode, i); + results.AddRange(leafNodes); + } + else + { + results.Add(childNode); + } + } + + return results; + } + + private void ToggleParentFoldersChecked(int idx, TNode node, bool isChecked) { while (true) diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesView.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesView.cs index ba3c26118..3b17ea5ad 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesView.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesView.cs @@ -160,29 +160,29 @@ private void OnTreeGUI(Rect rect) private GenericMenu CreateContextMenu(ChangesTreeNode node) { var genericMenu = new GenericMenu(); - var canDiscard = false; - if (!node.isFolder) + if (discardGuiContent == null) { - canDiscard = node.GitFileStatus == GitFileStatus.Added - || node.GitFileStatus == GitFileStatus.Modified - || node.GitFileStatus == GitFileStatus.Deleted - || node.GitFileStatus == GitFileStatus.Renamed - || node.GitFileStatus == GitFileStatus.Untracked; + discardGuiContent = new GUIContent("Discard"); } - if (canDiscard) - { - if (discardGuiContent == null) + genericMenu.AddItem(discardGuiContent, false, () => { + GitStatusEntry[] discardEntries; + if (node.isFolder) + { + discardEntries = treeChanges + .GetLeafNodes(node) + .Select(treeNode => treeNode.GitStatusEntry) + .ToArray(); + } + else { - discardGuiContent = new GUIContent("Discard"); + discardEntries = new [] { node.GitStatusEntry }; } - genericMenu.AddItem(discardGuiContent, false, () => { - Repository.DiscardChanges(new List { node.GitStatusEntry }) - .Start(); - }); - } + Repository.DiscardChanges(discardEntries) + .Start(); + }); return genericMenu; } From 3c1e8330bba1bb4010df54e8226407d8ea21b3b4 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Thu, 15 Feb 2018 16:29:11 +0100 Subject: [PATCH 022/873] Fix argument order, services should come before data. Also use cancellation tokens --- .../Application/ApplicationManagerBase.cs | 2 +- src/GitHub.Api/Git/RepositoryManager.cs | 15 ++++++++++----- .../IntegrationTests/BaseGitEnvironmentTest.cs | 2 +- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/GitHub.Api/Application/ApplicationManagerBase.cs b/src/GitHub.Api/Application/ApplicationManagerBase.cs index 249f4e237..d4924da39 100644 --- a/src/GitHub.Api/Application/ApplicationManagerBase.cs +++ b/src/GitHub.Api/Application/ApplicationManagerBase.cs @@ -128,7 +128,7 @@ public void RestartRepository() { if (Environment.RepositoryPath != null) { - repositoryManager = Unity.RepositoryManager.CreateInstance(Platform, TaskManager, GitClient, ProcessManager, Environment.RepositoryPath, Environment.FileSystem); + repositoryManager = Unity.RepositoryManager.CreateInstance(Platform, TaskManager, GitClient, ProcessManager, Environment.FileSystem, Environment.RepositoryPath); repositoryManager.Initialize(); Environment.Repository.Initialize(repositoryManager); repositoryManager.Start(); diff --git a/src/GitHub.Api/Git/RepositoryManager.cs b/src/GitHub.Api/Git/RepositoryManager.cs index 6bbddc9f0..24acde4a8 100644 --- a/src/GitHub.Api/Git/RepositoryManager.cs +++ b/src/GitHub.Api/Git/RepositoryManager.cs @@ -100,6 +100,7 @@ class RepositoryManager : IRepositoryManager private readonly IProcessManager processManager; private readonly IRepositoryPathConfiguration repositoryPaths; private readonly IFileSystem fileSystem; + private readonly CancellationToken token; private readonly IRepositoryWatcher watcher; private bool isBusy; @@ -116,11 +117,13 @@ class RepositoryManager : IRepositoryManager public RepositoryManager(IGitConfig gitConfig, IRepositoryWatcher repositoryWatcher, IGitClient gitClient, IProcessManager processManager, - IRepositoryPathConfiguration repositoryPaths, - IFileSystem fileSystem) + IFileSystem fileSystem, + CancellationToken token, + IRepositoryPathConfiguration repositoryPaths) { this.repositoryPaths = repositoryPaths; this.fileSystem = fileSystem; + this.token = token; this.gitClient = gitClient; this.processManager = processManager; this.watcher = repositoryWatcher; @@ -129,7 +132,8 @@ public RepositoryManager(IGitConfig gitConfig, SetupWatcher(); } - public static RepositoryManager CreateInstance(IPlatform platform, ITaskManager taskManager, IGitClient gitClient, IProcessManager processManager, NPath repositoryRoot, IFileSystem fileSystem) + public static RepositoryManager CreateInstance(IPlatform platform, ITaskManager taskManager, IGitClient gitClient, + IProcessManager processManager, IFileSystem fileSystem, NPath repositoryRoot) { var repositoryPathConfiguration = new RepositoryPathConfiguration(repositoryRoot); string filePath = repositoryPathConfiguration.DotGitConfig; @@ -138,7 +142,8 @@ public static RepositoryManager CreateInstance(IPlatform platform, ITaskManager var repositoryWatcher = new RepositoryWatcher(platform, repositoryPathConfiguration, taskManager.Token); return new RepositoryManager(gitConfig, repositoryWatcher, - gitClient, processManager, repositoryPathConfiguration, fileSystem); + gitClient, processManager, fileSystem, + taskManager.Token, repositoryPathConfiguration); } public void Initialize() @@ -389,7 +394,7 @@ public void UpdateLocks() private ITask HookupHandlers(ITask task, bool isExclusive, bool filesystemChangesExpected) { - return new ActionTask(CancellationToken.None, () => { + return new ActionTask(token, () => { if (isExclusive) { Logger.Trace("Starting Operation - Setting Busy Flag"); diff --git a/src/tests/IntegrationTests/BaseGitEnvironmentTest.cs b/src/tests/IntegrationTests/BaseGitEnvironmentTest.cs index c840f236c..d19d2777c 100644 --- a/src/tests/IntegrationTests/BaseGitEnvironmentTest.cs +++ b/src/tests/IntegrationTests/BaseGitEnvironmentTest.cs @@ -14,7 +14,7 @@ protected IEnvironment Initialize(NPath repoPath, NPath environmentPath = null, { InitializePlatform(repoPath, environmentPath, enableEnvironmentTrace); - var repositoryManager = GitHub.Unity.RepositoryManager.CreateInstance(Platform, TaskManager, GitClient, ProcessManager, repoPath, Environment.FileSystem); + var repositoryManager = GitHub.Unity.RepositoryManager.CreateInstance(Platform, TaskManager, GitClient, ProcessManager, Environment.FileSystem, repoPath); onRepositoryManagerCreated?.Invoke(repositoryManager); RepositoryManager = repositoryManager; From a529043e1b6f274efde25b65c1cf19484f07da34 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Thu, 15 Feb 2018 19:55:59 +0100 Subject: [PATCH 023/873] Run all of discard on a thread --- src/GitHub.Api/Git/RepositoryManager.cs | 68 +++++++++++-------------- 1 file changed, 29 insertions(+), 39 deletions(-) diff --git a/src/GitHub.Api/Git/RepositoryManager.cs b/src/GitHub.Api/Git/RepositoryManager.cs index 24acde4a8..119a62ea1 100644 --- a/src/GitHub.Api/Git/RepositoryManager.cs +++ b/src/GitHub.Api/Git/RepositoryManager.cs @@ -301,51 +301,41 @@ public ITask DiscardChanges(GitStatusEntry[] gitStatusEntries) { Guard.ArgumentNotNullOrEmpty(gitStatusEntries, "gitStatusEntries"); - var itemsToDelete = new List(); - var itemsToRevert = new List(); - - foreach (var gitStatusEntry in gitStatusEntries) - { - if (gitStatusEntry.status == GitFileStatus.Added || gitStatusEntry.status == GitFileStatus.Untracked) - { - itemsToDelete.Add(gitStatusEntry.path); - } - else + ActionTask task = null; + task = new ActionTask(token, (_, entries) => { - itemsToRevert.Add(gitStatusEntry.path); - } - } + var itemsToDelete = new List(); + var itemsToRevert = new List(); - ActionTask deleteItemsTask = null; - if (itemsToDelete.Any()) - { - deleteItemsTask = new ActionTask(CancellationToken.None, () => { - foreach (var itemToDelete in itemsToDelete) + foreach (var gitStatusEntry in gitStatusEntries) { - fileSystem.FileDelete(itemToDelete); + if (gitStatusEntry.status == GitFileStatus.Added || gitStatusEntry.status == GitFileStatus.Untracked) + { + itemsToDelete.Add(gitStatusEntry.path); + } + else + { + itemsToRevert.Add(gitStatusEntry.path); + } } - }); - } - ITask gitDiscardTask = null; - if (itemsToRevert.Any()) - { - gitDiscardTask = GitClient.Discard(itemsToRevert); - } + if (itemsToDelete.Any()) + { + foreach (var itemToDelete in itemsToDelete) + { + fileSystem.FileDelete(itemToDelete); + } + } + + ITask gitDiscardTask = null; + if (itemsToRevert.Any()) + { + gitDiscardTask = GitClient.Discard(itemsToRevert); + task.Then(gitDiscardTask); + } + } + , () => gitStatusEntries); - ITask task; - if (deleteItemsTask != null && gitDiscardTask != null) - { - task = deleteItemsTask.Then(gitDiscardTask); - } - else if (deleteItemsTask != null) - { - task = deleteItemsTask; - } - else //if (gitDiscardTask != null) - { - task = gitDiscardTask; - } return HookupHandlers(task, true, true); } From 6d3bae9b7b005e78679c15f07fc7a66d55351e3c Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Thu, 15 Feb 2018 19:56:55 +0100 Subject: [PATCH 024/873] Fix serialization of ChangesTreeNode --- .../GitHub.Unity/UI/ChangesTreeControl.cs | 35 +++++++++---------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesTreeControl.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesTreeControl.cs index 798244dc4..45e4c33c3 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesTreeControl.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ChangesTreeControl.cs @@ -13,48 +13,45 @@ public class ChangesTreeNodeDictionary : SerializableDictionary { + [NonSerialized] public Texture2D FolderIcon; + [SerializeField] public ChangesTreeNodeDictionary assets = new ChangesTreeNodeDictionary(); [SerializeField] public ChangesTreeNodeDictionary folders = new ChangesTreeNodeDictionary(); [SerializeField] public ChangesTreeNodeDictionary checkedFileNodes = new ChangesTreeNodeDictionary(); - - [NonSerialized] public Texture2D FolderIcon; [SerializeField] public string title = string.Empty; [SerializeField] public string pathSeparator = "/"; [SerializeField] public bool displayRootNode = true; [SerializeField] public bool isSelectable = true; [SerializeField] public bool isCheckable = false; [SerializeField] public bool isUsingGlobalSelection = false; - [SerializeField] private List nodes = new List(); - [SerializeField] private ChangesTreeNode selectedNode = null; + [NonSerialized] private bool viewHasFocus; [NonSerialized] private Object lastActivatedObject; + [SerializeField] private List nodes = new List(); + [SerializeField] private ChangesTreeNode selectedNode = null; + public override string Title { get { return title; } From 2270f0e4f65103c69842f3b98ad8cee5d25a4a3c Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Mon, 19 Feb 2018 17:29:46 +0100 Subject: [PATCH 025/873] Loading spinner and progress reporting --- .../Application/ApplicationManagerBase.cs | 10 +- .../Application/IApplicationManager.cs | 3 +- src/GitHub.Api/Installer/GitInstaller.cs | 60 ++++- src/GitHub.Api/Installer/IZipHelper.cs | 2 +- src/GitHub.Api/Installer/UnzipTask.cs | 17 +- src/GitHub.Api/Installer/ZipHelper.cs | 104 +-------- .../Editor/GitHub.Unity/ApplicationManager.cs | 1 + .../Assets/Editor/GitHub.Unity/EntryPoint.cs | 4 +- .../Editor/GitHub.Unity/GitHub.Unity.csproj | 15 ++ .../GitHub.Unity/IconsAndLogos/code.png | 3 + .../GitHub.Unity/IconsAndLogos/code@2x.png | 3 + .../GitHub.Unity/IconsAndLogos/merge.png | 3 + .../GitHub.Unity/IconsAndLogos/merge@2x.png | 3 + .../GitHub.Unity/IconsAndLogos/rocket.png | 3 + .../GitHub.Unity/IconsAndLogos/rocket@2x.png | 3 + .../IconsAndLogos/spinner-inside.png | 3 + .../IconsAndLogos/spinner-inside@2x.png | 3 + .../IconsAndLogos/spinner-outside.png | 3 + .../IconsAndLogos/spinner-outside@2x.png | 3 + .../Assets/Editor/GitHub.Unity/Misc/Styles.cs | 138 +++++++++++- .../Editor/GitHub.Unity/Misc/Utility.cs | 16 ++ .../Editor/GitHub.Unity/UI/BaseWindow.cs | 2 +- .../Editor/GitHub.Unity/UI/SettingsView.cs | 2 +- .../Assets/Editor/GitHub.Unity/UI/Spinner.cs | 207 ++++++++++++++++++ .../Assets/Editor/GitHub.Unity/UI/Window.cs | 135 +++++++----- .../BaseGitEnvironmentTest.cs | 2 +- src/tests/IntegrationTests/UnzipTaskTests.cs | 17 +- 27 files changed, 586 insertions(+), 179 deletions(-) create mode 100644 src/UnityExtension/Assets/Editor/GitHub.Unity/IconsAndLogos/code.png create mode 100644 src/UnityExtension/Assets/Editor/GitHub.Unity/IconsAndLogos/code@2x.png create mode 100644 src/UnityExtension/Assets/Editor/GitHub.Unity/IconsAndLogos/merge.png create mode 100644 src/UnityExtension/Assets/Editor/GitHub.Unity/IconsAndLogos/merge@2x.png create mode 100644 src/UnityExtension/Assets/Editor/GitHub.Unity/IconsAndLogos/rocket.png create mode 100644 src/UnityExtension/Assets/Editor/GitHub.Unity/IconsAndLogos/rocket@2x.png create mode 100644 src/UnityExtension/Assets/Editor/GitHub.Unity/IconsAndLogos/spinner-inside.png create mode 100644 src/UnityExtension/Assets/Editor/GitHub.Unity/IconsAndLogos/spinner-inside@2x.png create mode 100644 src/UnityExtension/Assets/Editor/GitHub.Unity/IconsAndLogos/spinner-outside.png create mode 100644 src/UnityExtension/Assets/Editor/GitHub.Unity/IconsAndLogos/spinner-outside@2x.png create mode 100644 src/UnityExtension/Assets/Editor/GitHub.Unity/UI/Spinner.cs diff --git a/src/GitHub.Api/Application/ApplicationManagerBase.cs b/src/GitHub.Api/Application/ApplicationManagerBase.cs index 61894c369..a00d9790a 100644 --- a/src/GitHub.Api/Application/ApplicationManagerBase.cs +++ b/src/GitHub.Api/Application/ApplicationManagerBase.cs @@ -12,6 +12,8 @@ abstract class ApplicationManagerBase : IApplicationManager protected static ILogging Logger { get; } = LogHelper.GetLogger(); private RepositoryManager repositoryManager; + protected bool isBusy; + public event Action OnProgress; public ApplicationManagerBase(SynchronizationContext synchronizationContext) { @@ -57,9 +59,11 @@ public void Run(bool firstRun) { Logger.Trace("No git path found in settings"); + isBusy = true; var initEnvironmentTask = new ActionTask(CancellationToken, (b, path) => InitializeEnvironment(path)) { Affinity = TaskAffinity.UI }; var findExecTask = new FindExecTask("git", CancellationToken) - .FinallyInUI((b, ex, path) => { + .FinallyInUI((b, ex, path) => + { if (b && path != null) { Logger.Trace("FindExecTask Success: {0}", path); @@ -70,6 +74,7 @@ public void Run(bool firstRun) Logger.Warning("FindExecTask Failure"); Logger.Error("Git not found"); } + isBusy = false; }); var applicationDataPath = Environment.GetSpecialFolder(System.Environment.SpecialFolder.LocalApplicationData).ToNPath(); @@ -190,7 +195,7 @@ private void InitializeEnvironment(NPath gitExecutablePath) } else { - Logger.Warning("No Windows CredentialHeloper found: Setting to wincred"); + Logger.Warning("No Windows CredentialHelper found: Setting to wincred"); GitClient.SetConfig("credential.helper", "wincred", GitConfigSource.Global) .Then(afterGitSetup) @@ -234,6 +239,7 @@ public void Dispose() public ISettings SystemSettings { get; protected set; } public ISettings UserSettings { get; protected set; } public IUsageTracker UsageTracker { get; protected set; } + public bool IsBusy { get { return isBusy || RepositoryManager.IsBusy; } } protected TaskScheduler UIScheduler { get; private set; } protected SynchronizationContext SynchronizationContext { get; private set; } protected IRepositoryManager RepositoryManager { get { return repositoryManager; } } diff --git a/src/GitHub.Api/Application/IApplicationManager.cs b/src/GitHub.Api/Application/IApplicationManager.cs index fd59878a8..4642101ed 100644 --- a/src/GitHub.Api/Application/IApplicationManager.cs +++ b/src/GitHub.Api/Application/IApplicationManager.cs @@ -17,9 +17,10 @@ public interface IApplicationManager : IDisposable ITaskManager TaskManager { get; } IGitClient GitClient { get; } IUsageTracker UsageTracker { get; } - + bool IsBusy { get; } void Run(bool firstRun); void RestartRepository(); ITask InitializeRepository(); + event Action OnProgress; } } \ No newline at end of file diff --git a/src/GitHub.Api/Installer/GitInstaller.cs b/src/GitHub.Api/Installer/GitInstaller.cs index 8fb339f56..a1cf21a92 100644 --- a/src/GitHub.Api/Installer/GitInstaller.cs +++ b/src/GitHub.Api/Installer/GitInstaller.cs @@ -77,6 +77,8 @@ class GitInstaller private readonly IZipHelper sharpZipLibHelper; private NPath gitArchiveFilePath; private NPath gitLfsArchivePath; + private Progress progress = new Progress(); + public event Action OnProgress; public GitInstaller(IEnvironment environment, CancellationToken cancellationToken, GitInstallDetails installDetails) @@ -115,6 +117,9 @@ public void SetupGitIfNeeded(ActionTask onSuccess, ITask onFailure) if (IsGitExtracted()) { Logger.Trace("SetupGitIfNeeded: Skipped"); + progress.Total = 100; + progress.Value = 100; + OnProgress?.Invoke(progress); onSuccess.PreviousResult = installDetails.GitExecutablePath; onSuccess.Start(); } @@ -127,6 +132,7 @@ public void SetupGitIfNeeded(ActionTask onSuccess, ITask onFailure) private void ExtractPortableGit(ActionTask onSuccess, ITask onFailure) { + Logger.Trace("ExtractPortableGit"); ITask downloadFilesTask = null; if ((gitArchiveFilePath == null) || (gitLfsArchivePath == null)) { @@ -138,7 +144,19 @@ private void ExtractPortableGit(ActionTask onSuccess, ITask onFailure) var gitLfsExtractPath = tempZipExtractPath.Combine("git-lfs").CreateDirectory(); var resultTask = new UnzipTask(cancellationToken, gitArchiveFilePath, gitExtractPath, sharpZipLibHelper, environment.FileSystem, GitInstallDetails.GitExtractedMD5) + .Progress(p => + { + progress.Task = p.Task; + var pt = p.Value / p.Total; + progress.Value = 40 + 20 * pt; + }) .Then(new UnzipTask(cancellationToken, gitLfsArchivePath, gitLfsExtractPath, sharpZipLibHelper, environment.FileSystem, GitInstallDetails .GitLfsExtractedMD5)) + .Progress(p => + { + progress.Task = p.Task; + var pt = p.Value / p.Total; + progress.Value = 60 + 20 * pt; + }) .Then(s => MoveGitAndLfs(gitExtractPath, gitLfsExtractPath, tempZipExtractPath)); resultTask.Then(onFailure, TaskRunOptions.OnFailure); @@ -154,6 +172,9 @@ private void ExtractPortableGit(ActionTask onSuccess, ITask onFailure) private NPath MoveGitAndLfs(NPath gitExtractPath, NPath gitLfsExtractPath, NPath tempZipExtractPath) { + progress.Value = 80; + OnProgress?.Invoke(progress); + var targetGitLfsExecPath = installDetails.GetGitLfsExecutablePath(gitExtractPath); var extractGitLfsExePath = gitLfsExtractPath.Combine(installDetails.GitLfsExecutable); @@ -163,6 +184,9 @@ private NPath MoveGitAndLfs(NPath gitExtractPath, NPath gitLfsExtractPath, NPath Logger.Trace($"Moving tempDirectory:'{gitExtractPath}' to extractTarget:'{installDetails.GitInstallationPath}'"); + progress.Value = 90; + OnProgress?.Invoke(progress); + installDetails.GitInstallationPath.EnsureParentDirectoryExists(); gitExtractPath.Move(installDetails.GitInstallationPath); @@ -182,22 +206,46 @@ private ITask CreateDownloadTask() gitLfsArchivePath = tempZipPath.Combine("git-lfs.zip"); var downloadGitMd5Task = new DownloadTextTask(TaskManager.Instance.Token, environment.FileSystem, - installDetails.GitZipMd5Url, tempZipPath); + installDetails.GitZipMd5Url, tempZipPath) + .Progress(p => + { + progress.Task = p.Task; + var pt = p.Value / p.Total; + progress.Value = 10 * pt; + }); var downloadGitTask = new DownloadTask(TaskManager.Instance.Token, environment.FileSystem, - installDetails.GitZipUrl, tempZipPath); + installDetails.GitZipUrl, tempZipPath) + .Progress(p => + { + progress.Task = p.Task; + var pt = p.Value / p.Total; + progress.Value = 10 + 10 * pt; + }); var downloadGitLfsMd5Task = new DownloadTextTask(TaskManager.Instance.Token, environment.FileSystem, - installDetails.GitLfsZipMd5Url, tempZipPath); + installDetails.GitLfsZipMd5Url, tempZipPath) + .Progress(p => + { + progress.Task = p.Task; + var pt = p.Value / p.Total; + progress.Value = 20 + 10 * pt; + }); var downloadGitLfsTask = new DownloadTask(TaskManager.Instance.Token, environment.FileSystem, - installDetails.GitLfsZipUrl, tempZipPath); + installDetails.GitLfsZipUrl, tempZipPath) + .Progress(p => + { + progress.Task = p.Task; + var pt = p.Value / p.Total; + progress.Value = 30 + 10 * pt; + }); return - downloadGitMd5Task.Then((b, s) => { downloadGitTask.ValidationHash = s; }) + downloadGitMd5Task.Then((b, s) => { ((DownloadTask)downloadGitTask).ValidationHash = s; }) .Then(downloadGitTask) .Then(downloadGitLfsMd5Task) - .Then((b, s) => { downloadGitLfsTask.ValidationHash = s; }) + .Then((b, s) => { ((DownloadTask)downloadGitLfsTask).ValidationHash = s; }) .Then(downloadGitLfsTask); } diff --git a/src/GitHub.Api/Installer/IZipHelper.cs b/src/GitHub.Api/Installer/IZipHelper.cs index 7f6c1d84e..a536dcadf 100644 --- a/src/GitHub.Api/Installer/IZipHelper.cs +++ b/src/GitHub.Api/Installer/IZipHelper.cs @@ -6,6 +6,6 @@ namespace GitHub.Unity interface IZipHelper { void Extract(string archive, string outFolder, CancellationToken cancellationToken, - IProgress zipFileProgress = null, IProgress estimatedDurationProgress = null); + Func onProgress = null); } } diff --git a/src/GitHub.Api/Installer/UnzipTask.cs b/src/GitHub.Api/Installer/UnzipTask.cs index f12902eef..b8b6ae3db 100644 --- a/src/GitHub.Api/Installer/UnzipTask.cs +++ b/src/GitHub.Api/Installer/UnzipTask.cs @@ -11,16 +11,14 @@ class UnzipTask: TaskBase private readonly IZipHelper zipHelper; private readonly IFileSystem fileSystem; private readonly string expectedMD5; - private readonly IProgress zipFileProgress; - private readonly IProgress estimatedDurationProgress; - public UnzipTask(CancellationToken token, string archiveFilePath, NPath extractedPath, IFileSystem fileSystem, string expectedMD5 = null, IProgress zipFileProgress = null, IProgress estimatedDurationProgress = null) : - this(token, archiveFilePath, extractedPath, ZipHelper.Instance, fileSystem, expectedMD5, zipFileProgress, estimatedDurationProgress) + public UnzipTask(CancellationToken token, string archiveFilePath, NPath extractedPath, IFileSystem fileSystem, string expectedMD5 = null) : + this(token, archiveFilePath, extractedPath, ZipHelper.Instance, fileSystem, expectedMD5) { } - public UnzipTask(CancellationToken token, string archiveFilePath, NPath extractedPath, IZipHelper zipHelper, IFileSystem fileSystem, string expectedMD5 = null, IProgress zipFileProgress = null, IProgress estimatedDurationProgress = null) + public UnzipTask(CancellationToken token, string archiveFilePath, NPath extractedPath, IZipHelper zipHelper, IFileSystem fileSystem, string expectedMD5 = null) : base(token) { this.archiveFilePath = archiveFilePath; @@ -28,8 +26,6 @@ public UnzipTask(CancellationToken token, string archiveFilePath, NPath extracte this.zipHelper = zipHelper; this.fileSystem = fileSystem; this.expectedMD5 = expectedMD5; - this.zipFileProgress = zipFileProgress; - this.estimatedDurationProgress = estimatedDurationProgress; } protected override void Run(bool success) @@ -40,7 +36,12 @@ protected override void Run(bool success) try { - zipHelper.Extract(archiveFilePath, extractedPath, Token, zipFileProgress, estimatedDurationProgress); + zipHelper.Extract(archiveFilePath, extractedPath, Token, + (value, total) => + { + UpdateProgress(value, total); + return !Token.IsCancellationRequested; + }); } catch (Exception ex) { diff --git a/src/GitHub.Api/Installer/ZipHelper.cs b/src/GitHub.Api/Installer/ZipHelper.cs index 34701b803..554ec7d17 100644 --- a/src/GitHub.Api/Installer/ZipHelper.cs +++ b/src/GitHub.Api/Installer/ZipHelper.cs @@ -23,87 +23,17 @@ public static IZipHelper Instance } } - public static bool Copy(Stream source, Stream destination, int chunkSize, long totalSize, - Func progress, int progressUpdateRate) - { - var buffer = new byte[chunkSize]; - var bytesRead = 0; - long totalRead = 0; - var averageSpeed = -1f; - var lastSpeed = 0f; - var smoothing = 0.005f; - long readLastSecond = 0; - long timeToFinish = 0; - Stopwatch watch = null; - var success = true; - - var trackProgress = totalSize > 0 && progress != null; - if (trackProgress) - { - watch = new Stopwatch(); - } - - do - { - if (trackProgress) - { - watch.Start(); - } - - bytesRead = source.Read(buffer, 0, chunkSize); - - if (trackProgress) - { - watch.Stop(); - } - - totalRead += bytesRead; - - if (bytesRead > 0) - { - destination.Write(buffer, 0, bytesRead); - if (trackProgress) - { - readLastSecond += bytesRead; - if (watch.ElapsedMilliseconds >= progressUpdateRate || totalRead == totalSize) - { - watch.Reset(); - lastSpeed = readLastSecond; - readLastSecond = 0; - averageSpeed = averageSpeed < 0f - ? lastSpeed - : smoothing * lastSpeed + (1f - smoothing) * averageSpeed; - timeToFinish = Math.Max(1L, - (long)((totalSize - totalRead) / (averageSpeed / progressUpdateRate))); - - if (!progress(totalRead, timeToFinish)) - { - break; - } - } - } - } - } while (bytesRead > 0); - - if (totalRead > 0) - { - destination.Flush(); - } - - return success; - } - public void Extract(string archive, string outFolder, CancellationToken cancellationToken, - IProgress zipFileProgress = null, IProgress estimatedDurationProgress = null) + Func onProgress = null) { - ExtractZipFile(archive, outFolder, cancellationToken, zipFileProgress, estimatedDurationProgress); + ExtractZipFile(archive, outFolder, cancellationToken, onProgress); } public static void ExtractZipFile(string archive, string outFolder, CancellationToken cancellationToken, - IProgress zipFileProgress = null, IProgress estimatedDurationProgress = null) + Func onProgress) { + const int chunkSize = 4096; // 4K is optimum ZipFile zf = null; - var estimatedDuration = 1L; var startTime = DateTime.Now; var processed = 0; var totalBytes = 0L; @@ -112,9 +42,11 @@ public static void ExtractZipFile(string archive, string outFolder, Cancellation { var fs = File.OpenRead(archive); zf = new ZipFile(fs); + var totalSize = fs.Length; foreach (ZipEntry zipEntry in zf) { + cancellationToken.ThrowIfCancellationRequested(); if (zipEntry.IsDirectory) { continue; // Ignore directories @@ -152,28 +84,16 @@ public static void ExtractZipFile(string archive, string outFolder, Cancellation var targetFile = new FileInfo(fullZipToPath); using (var streamWriter = targetFile.OpenWrite()) { - const int chunkSize = 4096; // 4K is optimum - Copy(zipStream, streamWriter, chunkSize, targetFile.Length, (totalRead, timeToFinish) => - { - estimatedDuration = timeToFinish; - - estimatedDurationProgress.Report(estimatedDuration); - zipFileProgress?.Report((float)(totalBytes + totalRead) / targetFile.Length); - return true; - }, 100); - cancellationToken.ThrowIfCancellationRequested(); + if (!Utils.Copy(zipStream, streamWriter, targetFile.Length, chunkSize, + progress: (totalRead, timeToFinish) => { + totalBytes += totalRead; + return onProgress(totalBytes, totalSize); + })) + return; } targetFile.LastWriteTime = zipEntry.DateTime; processed++; - totalBytes += zipEntry.Size; - - var elapsedMillisecondsPerFile = (DateTime.Now - startTime).TotalMilliseconds / processed; - estimatedDuration = Math.Max(1L, (long)((fs.Length - totalBytes) * elapsedMillisecondsPerFile)); - - estimatedDurationProgress?.Report(estimatedDuration); - zipFileProgress?.Report((float)processed / zf.Count); - cancellationToken.ThrowIfCancellationRequested(); } } finally diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationManager.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationManager.cs index c5fcfd00c..fd09a6781 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationManager.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationManager.cs @@ -31,6 +31,7 @@ protected override void InitializeUI() Logger.Trace("Restarted {0}", Environment.Repository); EnvironmentCache.Instance.Flush(); + isBusy = false; ProjectWindowInterface.Initialize(Environment.Repository); var window = Window.GetWindow(); if (window != null) diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/EntryPoint.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/EntryPoint.cs index 3b25a5277..7cfa0d5d3 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/EntryPoint.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/EntryPoint.cs @@ -62,7 +62,9 @@ private static void Initialize() Debug.LogFormat("Initialized GitHub for Unity version {0}{1}Log file: {2}", ApplicationInfo.Version, Environment.NewLine, logPath); } - LogHelper.LogAdapter = new FileLogAdapter(logPath); + LogHelper.LogAdapter = new MultipleLogAdapter(new FileLogAdapter(logPath) + , new UnityLogAdapter() + ); LogHelper.Info("Initializing GitHub for Unity version " + ApplicationInfo.Version); ApplicationManager.Run(ApplicationCache.Instance.FirstRun); diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/GitHub.Unity.csproj b/src/UnityExtension/Assets/Editor/GitHub.Unity/GitHub.Unity.csproj index 1bc293176..e4bb48940 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/GitHub.Unity.csproj +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/GitHub.Unity.csproj @@ -108,6 +108,7 @@ + @@ -217,6 +218,20 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/OctoRun/Program.cs b/src/OctoRun/Program.cs new file mode 100644 index 000000000..dd6cd4a32 --- /dev/null +++ b/src/OctoRun/Program.cs @@ -0,0 +1,113 @@ +using GitHub.Unity; +using Mono.Options; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading.Tasks; +using static OctoRun.LoginManager; + +namespace OctoRun +{ + class LoginCommand + { + public Command[] Commands { get; private set; } + private string host; + private bool in2fa; + + public static LoginCommand Initialize() + { + var instance = new LoginCommand(); + instance.Commands = new Command[] + { + new Command("login", "login") + { + Options = new OptionSet { + { "h|host=", host => instance.host = host }, + { "2fa", v => instance.in2fa = v != null } + }, + Run = args => instance.Run(args) + } + }; + return instance; + } + + public void Run(IEnumerable args) + { + DoLogin(); + } + + private void DoLogin() + { + var login = Console.ReadLine(); + var token = Console.ReadLine(); + string twofa = null; + if (in2fa) + twofa = Console.ReadLine(); + var credStore = new CredentialStore { Login = login, Token = token, Code = twofa }; + var hostAddress = HostAddress.Create(host); + var client = new ApiClient(credStore, hostAddress); + + LoginResult result = null; + if (!in2fa) + { + result = client.Login(); + if (result.NeedTwoFA) + { + Console.WriteLine("2fa"); + Console.WriteLine(credStore.Token); + } + else if (result.Success) + { + Console.WriteLine(credStore.Token); + } + else + { + Console.WriteLine("failed"); + Console.WriteLine(result.Message); + } + } + else + { + result = client.ContinueLogin(); + if (result.NeedTwoFA) + { + Console.WriteLine("2fa"); + Console.WriteLine(credStore.Token); + } + else if (result.Success) + { + Console.WriteLine(credStore.Token); + } + else + { + Console.WriteLine("failed"); + Console.WriteLine(result.Message); + } + } + + } + } + + class Program + { + static void Main(string[] args) + { + Logging.LogAdapter = new ConsoleLogAdapter(); + + AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; + + var opts = new OptionSet(); + var commands = new CommandSet(""); + foreach (var cmd in LoginCommand.Initialize().Commands) + commands.Add(cmd); + + opts.Parse(args); + commands.Run(args); + } + + private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) + { + Debugger.Break(); + } + } +} diff --git a/src/OctoRun/Properties/AssemblyInfo.cs b/src/OctoRun/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..7b4846420 --- /dev/null +++ b/src/OctoRun/Properties/AssemblyInfo.cs @@ -0,0 +1,12 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OctoRun")] +[assembly: AssemblyDescription("")] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("127f84fe-db89-4543-9a83-74db4e751061")] diff --git a/src/OctoRun/StringEquivalent.cs b/src/OctoRun/StringEquivalent.cs new file mode 100644 index 000000000..88756fe82 --- /dev/null +++ b/src/OctoRun/StringEquivalent.cs @@ -0,0 +1,109 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.Serialization; +using System.Xml; +using System.Xml.Schema; +using System.Xml.Serialization; + +namespace OctoRun +{ + [Serializable] + public abstract class StringEquivalent : ISerializable, IXmlSerializable where T : StringEquivalent + { + protected string Value; + + protected StringEquivalent(string value) + { + Value = value; + } + + protected StringEquivalent() + { + } + + public abstract T Combine(string addition); + + [SuppressMessage("Microsoft.Usage", "CA2225:OperatorOverloadsHaveNamedAlternates", Justification = "Add doesn't make sense in the case of a string equivalent")] + public static T operator +(StringEquivalent a, string b) + { + return a.Combine(b); + } + + public static bool operator ==(StringEquivalent a, StringEquivalent b) + { + // If both are null, or both are same instance, return true. + if (ReferenceEquals(a, b)) + { + return true; + } + + // If one is null, but not both, return false. + if (((object)a == null) || ((object)b == null)) + { + return false; + } + + // Return true if the fields match: + return a.Value.Equals(b.Value, StringComparison.OrdinalIgnoreCase); + } + + public static bool operator !=(StringEquivalent a, StringEquivalent b) + { + return !(a == b); + } + + public override bool Equals(Object obj) + { + return obj != null && Equals(obj as T) || Equals(obj as string); + } + + public virtual bool Equals(T stringEquivalent) + { + return this == stringEquivalent; + } + + public override int GetHashCode() + { + return (Value ?? "").GetHashCode(); + } + + public virtual bool Equals(string other) + { + return other != null && Value == other; + } + + public override string ToString() + { + return Value; + } + + protected StringEquivalent(SerializationInfo info) : this(info.GetValue("Value", typeof(string)) as string) + { + } + + public virtual void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("Value", Value); + } + + public XmlSchema GetSchema() + { + return null; + } + + public void ReadXml(XmlReader reader) + { + Value = reader.ReadString(); + } + + public void WriteXml(XmlWriter writer) + { + writer.WriteString(Value); + } + + public int Length + { + get { return Value != null ? Value.Length : 0; } + } + } +} diff --git a/src/OctoRun/StringExtensions.cs b/src/OctoRun/StringExtensions.cs new file mode 100644 index 000000000..ce966542e --- /dev/null +++ b/src/OctoRun/StringExtensions.cs @@ -0,0 +1,160 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; + +namespace OctoRun +{ + static class StringExtensions + { + public static bool Contains(this string s, string expectedSubstring, StringComparison comparison) + { + return s.IndexOf(expectedSubstring, comparison) > -1; + } + + public static bool ContainsAny(this string s, IEnumerable characters) + { + return s.IndexOfAny(characters.ToArray()) > -1; + } + + public static string ToNullIfEmpty(this string s) + { + return String.IsNullOrEmpty(s) ? null : s; + } + + public static bool StartsWith(this string s, char c) + { + if (String.IsNullOrEmpty(s)) return false; + return s.First() == c; + } + + public static string RightAfter(this string s, string search) + { + if (s == null) return null; + int lastIndex = s.IndexOf(search, StringComparison.OrdinalIgnoreCase); + if (lastIndex < 0) + return null; + + return s.Substring(lastIndex + search.Length); + } + + public static string RightAfterLast(this string s, string search) + { + if (s == null) return null; + int lastIndex = s.LastIndexOf(search, StringComparison.OrdinalIgnoreCase); + if (lastIndex < 0) + return null; + + return s.Substring(lastIndex + search.Length); + } + + public static string LeftBeforeLast(this string s, string search) + { + if (s == null) return null; + int lastIndex = s.LastIndexOf(search, StringComparison.OrdinalIgnoreCase); + if (lastIndex < 0) + return null; + + return s.Substring(0, lastIndex); + } + + public static string TrimEnd(this string s, string suffix) + { + if (s == null) return null; + if (!s.EndsWith(suffix, StringComparison.OrdinalIgnoreCase)) + return s; + + return s.Substring(0, s.Length - suffix.Length); + } + + /// + /// Pretty much the same things as `String.Join` but used when appending to an already delimited string. If the values passed + /// in are empty, it does not prepend the delimeter. Otherwise, it prepends with the delimiter. + /// + /// The separator character + /// The set values to join + public static string JoinForAppending(string separator, IEnumerable values) + { + return values.Any() + ? separator + String.Join(separator, values.ToArray()) + : string.Empty; + } + + public static string RemoveSurroundingQuotes(this string s) + { + Guard.ArgumentNotNull(s, "string"); + + if (s.Length < 2) + return s; + + var quoteCharacters = new[] { '"', '\'' }; + char firstCharacter = s[0]; + if (!quoteCharacters.Contains(firstCharacter)) + return s; + + if (firstCharacter != s[s.Length - 1]) + return s; + + return s.Substring(1, s.Length - 2); + } + + public static string RightAfter(this string s, char search) + { + if (s == null) return null; + int lastIndex = s.IndexOf(search); + if (lastIndex < 0) + return null; + + return s.Substring(lastIndex + 1); + } + + public static string RightAfterLast(this string s, char search) + { + if (s == null) return null; + int lastIndex = s.LastIndexOf(search); + if (lastIndex < 0) + return null; + + return s.Substring(lastIndex + 1); + } + + public static string LeftBeforeLast(this string s, char search) + { + if (s == null) return null; + int lastIndex = s.LastIndexOf(search); + if (lastIndex < 0) + return null; + + return s.Substring(0, lastIndex); + } + + public static StringResult? NextChunk(this string s, int start, char search) + { + if (s == null) return null; + int index = s.IndexOf(search, start); + if (index < 0) + return null; + + return new StringResult { Chunk = s.Substring(start, index - start), Start = start, End = index }; + } + + public static StringResult? NextChunk(this string s, int start, string search) + { + if (s == null) return null; + int index = s.IndexOf(search, start); + if (index < 0) + return null; + + return new StringResult { Chunk = s.Substring(start, index - start), Start = start, End = index }; + } + } + + public struct StringResult + { + public string Chunk; + public int Start; + public int End; + } +} diff --git a/src/OctoRun/UriExtensions.cs b/src/OctoRun/UriExtensions.cs new file mode 100644 index 000000000..c0e6893bf --- /dev/null +++ b/src/OctoRun/UriExtensions.cs @@ -0,0 +1,38 @@ +using System; + +namespace OctoRun +{ + static class UriExtensions + { + /// + /// Appends a relative path to the URL. + /// + /// + /// The Uri constructor for combining relative URLs have a different behavior with URLs that end with / + /// than those that don't. + /// + public static Uri Append(this Uri uri, string relativePath) + { + if (!uri.AbsolutePath.EndsWith("/", StringComparison.Ordinal)) + { + uri = new Uri(uri + "/"); + } + return new Uri(uri, new Uri(relativePath, UriKind.Relative)); + } + + public static bool IsHypertextTransferProtocol(this Uri uri) + { + return uri.Scheme == "http" || uri.Scheme == "https"; + } + + public static bool IsSameHost(this Uri uri, Uri compareUri) + { + return uri.Host.Equals(compareUri.Host, StringComparison.OrdinalIgnoreCase); + } + + public static UriString ToUriString(this Uri uri) + { + return uri == null ? null : new UriString(uri.ToString()); + } + } +} diff --git a/src/OctoRun/UriString.cs b/src/OctoRun/UriString.cs new file mode 100644 index 000000000..da91f50fa --- /dev/null +++ b/src/OctoRun/UriString.cs @@ -0,0 +1,285 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Linq; +using System.Runtime.Serialization; +using System.Text.RegularExpressions; + +namespace OctoRun +{ + /// + /// This class represents a URI given to us as a string and is implicitly + /// convertible to and from string. + /// + /// + /// This typically represents a URI from an external source such as user input, a + /// Git Repo Remote, or an API URL. We try to preserve the original form and let + /// downstream clients validate the URL. This class doesn't validate the URL. It just + /// performs a best-effort to parse the URI into bits important to us. For example, + /// we need to know the HOST so we can compare against GitHub.com, GH:E instances, etc. + /// + [SuppressMessage("Microsoft.Usage", "CA2240:ImplementISerializableCorrectly", Justification = "GetObjectData is implemented in the base class")] + [Serializable] + public class UriString : StringEquivalent, IEquatable + { + static readonly Regex sshRegex = new Regex(@"^.+@(?(\[.*?\]|[a-z0-9-.]+?))(:(?.*?))?(/(?.*)(\.git)?)?$", RegexOptions.Compiled | RegexOptions.IgnoreCase); + readonly Uri url; + + public UriString(string uriString) : base(NormalizePath(uriString)) + { + if (uriString == null || uriString.Length == 0) return; + if (Uri.TryCreate(uriString, UriKind.Absolute, out url)) + { + if (!url.IsFile) + SetUri(url); + else + SetFilePath(url); + } + else if (!ParseScpSyntax(uriString)) + { + SetFilePath(uriString); + } + + if (RepositoryName != null) + { + NameWithOwner = Owner != null + ? string.Format(CultureInfo.InvariantCulture, "{0}/{1}", Owner, RepositoryName) + : RepositoryName; + } + } + + public static UriString ToUriString(Uri uri) + { + return uri == null ? null : new UriString(uri.ToString()); + } + + public static UriString TryParse(string uri) + { + if (uri == null || uri.Length == 0) return null; + return new UriString(uri); + } + + public Uri ToUri() + { + if (url == null) + throw new InvalidOperationException("This Uri String is not a valid Uri"); + return url; + } + + void SetUri(Uri uri) + { + Host = uri.Host; + if (uri.Segments.Any()) + { + RepositoryName = GetRepositoryName(uri.Segments.Last()); + } + + if (uri.Segments.Length > 2) + { + Owner = (uri.Segments[uri.Segments.Length - 2] ?? "").TrimEnd('/').ToNullIfEmpty(); + } + + IsHypertextTransferProtocol = uri.IsHypertextTransferProtocol(); + } + + void SetFilePath(Uri uri) + { + Host = ""; + Owner = ""; + RepositoryName = GetRepositoryName(uri.Segments.Last()); + IsFileUri = true; + } + + void SetFilePath(string path) + { + Host = ""; + Owner = ""; + RepositoryName = GetRepositoryName(path.Replace("/", @"\").RightAfterLast(@"\")); + IsFileUri = true; + } + + // For xml serialization + protected UriString() + { + } + + bool ParseScpSyntax(string scpString) + { + var match = sshRegex.Match(scpString); + if (match.Success) + { + Host = match.Groups["host"].Value.ToNullIfEmpty(); + Owner = match.Groups["owner"].Value.ToNullIfEmpty(); + RepositoryName = GetRepositoryName(match.Groups["repo"].Value); + IsScpUri = true; + return true; + } + return false; + } + + public string Host { get; private set; } + + public string Owner { get; private set; } + + public string RepositoryName { get; private set; } + + public string NameWithOwner { get; private set; } + + public bool IsFileUri { get; private set; } + + public bool IsScpUri { get; private set; } + + public bool IsValidUri => url != null; + public string Protocol => url?.Scheme; + + /// + /// Attempts a best-effort to convert the remote origin to a GitHub Repository URL. + /// + /// A converted uri, or the existing one if we can't convert it (which might be null) + public Uri ToRepositoryUri() + { + // we only want to process urls that represent network resources + if (!IsScpUri && (!IsValidUri || IsFileUri)) return url; + + var scheme = url != null && IsHypertextTransferProtocol + ? url.Scheme + : Uri.UriSchemeHttps; + + var port = url?.Port == 80 + ? -1 + : (url?.Port ?? -1); + return new UriBuilder + { + Scheme = scheme, + Host = Host, + Path = NameWithOwner, + Port = port + }.Uri; + } + + /// + /// Attempts a best-effort to convert the remote origin to a GitHub Repository URL. + /// + /// A converted uri, or the existing one if we can't convert it (which might be null) + public UriString ToRepositoryUrl() + { + // we only want to process urls that represent network resources + if (!IsScpUri && (!IsValidUri || IsFileUri)) return this; + + var scheme = url != null && IsHypertextTransferProtocol + ? url.Scheme + : Uri.UriSchemeHttps; + + var port = url?.Port == 80 + ? -1 + : (url?.Port ?? -1); + return new UriString(new UriBuilder + { + Scheme = scheme, + Host = Host, + Path = NameWithOwner, + Port = port + }.Uri.ToString()); + } + + /// + /// True if the URL is HTTP or HTTPS + /// + public bool IsHypertextTransferProtocol { get; private set; } + + [SuppressMessage("Microsoft.Usage", "CA2225:OperatorOverloadsHaveNamedAlternates")] + public static implicit operator UriString(string value) + { + if (value == null) return null; + + return new UriString(value); + } + + [SuppressMessage("Microsoft.Usage", "CA2225:OperatorOverloadsHaveNamedAlternates")] + public static implicit operator string(UriString uriString) + { + return uriString?.Value; + } + + [SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings", Justification = "No.")] + public override UriString Combine(string addition) + { + if (url != null) + { + var urlBuilder = new UriBuilder(url); + if (!String.IsNullOrEmpty(urlBuilder.Query)) + { + var query = urlBuilder.Query; + if (query.StartsWith("?", StringComparison.Ordinal)) + { + query = query.Substring(1); + } + + if (!addition.StartsWith("&", StringComparison.Ordinal) && query.Length > 0) + { + addition = "&" + addition; + } + urlBuilder.Query = query + addition; + } + else + { + var path = url.AbsolutePath; + if (path == "/") path = ""; + if (!addition.StartsWith("/", StringComparison.Ordinal)) addition = "/" + addition; + + urlBuilder.Path = path + addition; + } + return ToUriString(urlBuilder.Uri); + } + return String.Concat(Value, addition); + } + + public override string ToString() + { + // Makes this look better in the debugger. + return Value; + } + + protected UriString(SerializationInfo info, StreamingContext context) + : this(GetSerializedValue(info)) + { + } + + static string GetSerializedValue(SerializationInfo info) + { + // First try to get the current way it's serialized, then fall back to the older way it's serialized. + string value; + try + { + value = info.GetValue("Value", typeof(string)) as string; + } + catch (SerializationException) + { + value = info.GetValue("uriString", typeof(string)) as string; + } + + return value; + } + + static string NormalizePath(string path) + { + return path?.Replace('\\', '/'); + } + + static string GetRepositoryName(string repositoryNameSegment) + { + if (String.IsNullOrEmpty(repositoryNameSegment) + || repositoryNameSegment.Equals("/", StringComparison.Ordinal)) + { + return null; + } + + return repositoryNameSegment.TrimEnd('/').TrimEnd(".git"); + } + + bool IEquatable.Equals(UriString other) + { + return other != null && ToString().Equals(other.ToString()); + } + } +} diff --git a/src/OctoRun/packages.config b/src/OctoRun/packages.config new file mode 100644 index 000000000..b37f38e52 --- /dev/null +++ b/src/OctoRun/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationManager.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationManager.cs index cb3a46c6a..a284af80b 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationManager.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationManager.cs @@ -21,6 +21,11 @@ public ApplicationManager(IMainThreadSynchronizationContext synchronizationConte Initialize(); } + public override NPath GetTool(string tool) + { + return Utility.GetTool(tool); + } + protected override void SetupMetrics() { SetupMetrics(Environment.UnityVersion, ApplicationCache.Instance.FirstRun); diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/EntryPoint.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/EntryPoint.cs index dea9fc30b..f80ab9f6f 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/EntryPoint.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/EntryPoint.cs @@ -24,6 +24,7 @@ static EntryPoint() Logging.LogAdapter = new FileLogAdapter(tempEnv.LogPath); ServicePointManager.ServerCertificateValidationCallback = ServerCertificateValidationCallback; + ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072; EditorApplication.update += Initialize; } diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/GitHub.Unity.csproj b/src/UnityExtension/Assets/Editor/GitHub.Unity/GitHub.Unity.csproj index 97cf5479c..288cb3ef3 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/GitHub.Unity.csproj +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/GitHub.Unity.csproj @@ -195,6 +195,9 @@ + + Tools\octorun.exe + diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/Misc/Utility.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/Misc/Utility.cs index 8b0e86bc2..cfaf0b767 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/Misc/Utility.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/Misc/Utility.cs @@ -49,6 +49,24 @@ public static Texture2D GetTextureFromColor(Color color) return result; } + + public static NPath GetTool(string filename, string filename2x = "") + { + var outfile = Application.temporaryCachePath.ToNPath().Combine(filename); + if (outfile.Exists()) + return outfile; + + var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("GitHub.Unity.Tools." + filename); + if (stream != null) + { + var targetFile = new FileInfo(outfile); + using (var outstream = targetFile.OpenWrite()) + { + ZipHelper.Copy(stream, outstream, 8192, stream.Length, null, 0); + } + } + return outfile; + } } static class StreamExtensions diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/Services/AuthenticationService.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/Services/AuthenticationService.cs index 3d81553cf..c627615ee 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/Services/AuthenticationService.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/Services/AuthenticationService.cs @@ -10,7 +10,7 @@ class AuthenticationService public AuthenticationService(UriString host, IKeychain keychain) { - client = ApiClient.Create(host, keychain); + client = ApiClient.Create(host, keychain, EntryPoint.ApplicationManager.ProcessManager, EntryPoint.ApplicationManager.TaskManager, EntryPoint.ApplicationManager.LoginTool); } public void Login(string username, string password, Action twofaRequired, Action authResult) diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/PopupWindow.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/PopupWindow.cs index 6eb91b501..1fdd82047 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/PopupWindow.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/PopupWindow.cs @@ -198,7 +198,7 @@ public IApiClient Client host = UriString.ToUriString(HostAddress.GitHubDotComHostAddress.WebUri); } - client = ApiClient.Create(host, Platform.Keychain); + client = ApiClient.Create(host, Platform.Keychain, Manager.ProcessManager, TaskManager, Manager.LoginTool); } return client; diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/PublishView.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/PublishView.cs index 99ab79516..895842cde 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/PublishView.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/PublishView.cs @@ -53,7 +53,7 @@ public IApiClient Client host = UriString.ToUriString(HostAddress.GitHubDotComHostAddress.WebUri); } - client = ApiClient.Create(host, Platform.Keychain); + client = ApiClient.Create(host, Platform.Keychain, Manager.ProcessManager, TaskManager, Manager.LoginTool); } return client; diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/Window.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/Window.cs index 54afa6a1e..b522531ff 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/Window.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/Window.cs @@ -416,7 +416,7 @@ private void SignOut(object obj) host = UriString.ToUriString(HostAddress.GitHubDotComHostAddress.WebUri); } - var apiClient = ApiClient.Create(host, Platform.Keychain); + var apiClient = ApiClient.Create(host, Platform.Keychain, null, null, null); apiClient.Logout(host); } From 66eb21e64199139b5efd18f33a68f0426ae1026d Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Fri, 23 Feb 2018 15:26:57 +0100 Subject: [PATCH 035/873] Fix build and add dependencies of the tool --- src/GitHub.Api/Authentication/LoginManager.cs | 2 +- src/OctoRun/OctoRun.csproj | 4 ++-- src/OctoRun/Program.cs | 2 +- src/OctoRun/packages.config | 1 + .../Editor/GitHub.Unity/GitHub.Unity.csproj | 9 +++++++++ .../Assets/Editor/GitHub.Unity/Misc/Utility.cs | 15 ++++++++++++--- 6 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/GitHub.Api/Authentication/LoginManager.cs b/src/GitHub.Api/Authentication/LoginManager.cs index efad70dd9..db961428a 100644 --- a/src/GitHub.Api/Authentication/LoginManager.cs +++ b/src/GitHub.Api/Authentication/LoginManager.cs @@ -257,7 +257,7 @@ private async Task TryLogin( string password ) { - logger.Info("Login Username:{0}", username); + logger.Info("Login Username:{0} {1}", username, loginTool); ApplicationAuthorization auth = null; var loginTask = new SimpleListProcessTask(taskManager.Token, loginTool, $"login --host={host}"); diff --git a/src/OctoRun/OctoRun.csproj b/src/OctoRun/OctoRun.csproj index 8ea4869c8..7e4dd4491 100644 --- a/src/OctoRun/OctoRun.csproj +++ b/src/OctoRun/OctoRun.csproj @@ -39,8 +39,8 @@ True - False - ..\..\..\octokit.net\Octokit\bin\Debug\net45\Octokit.dll + ..\..\packages\Octokit.0.29.0\lib\net45\Octokit.dll + True diff --git a/src/OctoRun/Program.cs b/src/OctoRun/Program.cs index dd6cd4a32..680ac54fd 100644 --- a/src/OctoRun/Program.cs +++ b/src/OctoRun/Program.cs @@ -92,7 +92,7 @@ class Program { static void Main(string[] args) { - Logging.LogAdapter = new ConsoleLogAdapter(); + //Logging.LogAdapter = new ConsoleLogAdapter(); AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; diff --git a/src/OctoRun/packages.config b/src/OctoRun/packages.config index b37f38e52..c98040a1a 100644 --- a/src/OctoRun/packages.config +++ b/src/OctoRun/packages.config @@ -1,4 +1,5 @@  + \ No newline at end of file diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/GitHub.Unity.csproj b/src/UnityExtension/Assets/Editor/GitHub.Unity/GitHub.Unity.csproj index 288cb3ef3..17ade194b 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/GitHub.Unity.csproj +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/GitHub.Unity.csproj @@ -198,6 +198,15 @@ Tools\octorun.exe + + Tools\GitHub.Logging.dll + + + Tools\Mono.Options.dll + + + Tools\Octokit.dll + diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/Misc/Utility.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/Misc/Utility.cs index cfaf0b767..80ac058dd 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/Misc/Utility.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/Misc/Utility.cs @@ -50,13 +50,21 @@ public static Texture2D GetTextureFromColor(Color color) return result; } - public static NPath GetTool(string filename, string filename2x = "") + public static NPath GetTool(string tool) { - var outfile = Application.temporaryCachePath.ToNPath().Combine(filename); + var outfile = Application.temporaryCachePath.ToNPath().Combine(tool); + + if (tool == "octorun.exe") + { + GetTool("Mono.Options.dll"); + GetTool("GitHub.Logging.dll"); + GetTool("Octokit.dll"); + } + if (outfile.Exists()) return outfile; - var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("GitHub.Unity.Tools." + filename); + var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("GitHub.Unity.Tools." + tool); if (stream != null) { var targetFile = new FileInfo(outfile); @@ -65,6 +73,7 @@ public static NPath GetTool(string filename, string filename2x = "") ZipHelper.Copy(stream, outstream, 8192, stream.Length, null, 0); } } + Logging.GetLogger().Debug(outfile); return outfile; } } From e3b86a76b7ad839557b838a0dd8c3ea332203289 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Fri, 23 Feb 2018 15:34:37 +0100 Subject: [PATCH 036/873] Fix path to executable --- src/GitHub.Api/NewTaskSystem/ProcessTask.cs | 10 +++++----- src/GitHub.Api/OutputProcessors/ProcessManager.cs | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/GitHub.Api/NewTaskSystem/ProcessTask.cs b/src/GitHub.Api/NewTaskSystem/ProcessTask.cs index b2967f2c9..3099a47ad 100644 --- a/src/GitHub.Api/NewTaskSystem/ProcessTask.cs +++ b/src/GitHub.Api/NewTaskSystem/ProcessTask.cs @@ -84,10 +84,10 @@ public void Run() { Process.ErrorDataReceived += (s, e) => { - //if (e.Data != null) - //{ - // Logger.Trace("ErrorData \"" + (e.Data == null ? "'null'" : e.Data) + "\""); - //} + //if (e.Data != null) + //{ + // Logger.Trace("ErrorData \"" + (e.Data == null ? "'null'" : e.Data) + "\""); + //} string encodedData = null; if (e.Data != null) @@ -503,6 +503,6 @@ public SimpleListProcessTask(CancellationToken token, string arguments, IOutputP this.arguments = arguments; } - public override string ProcessName => fullPathToExecutable?.FileName; + public override string ProcessName => fullPathToExecutable; public override string ProcessArguments => arguments; }} \ No newline at end of file diff --git a/src/GitHub.Api/OutputProcessors/ProcessManager.cs b/src/GitHub.Api/OutputProcessors/ProcessManager.cs index 79bd83135..bf8711cc2 100644 --- a/src/GitHub.Api/OutputProcessors/ProcessManager.cs +++ b/src/GitHub.Api/OutputProcessors/ProcessManager.cs @@ -41,6 +41,8 @@ public T Configure(T processTask, NPath executable = null, string arguments = StandardErrorEncoding = Encoding.UTF8 }; + if (!executable.IsRelative) + workingDirectory = executable.Parent; gitEnvironment.Configure(startInfo, workingDirectory ?? environment.RepositoryPath); if (executable.IsRelative) From 2ede40f38ab0c1c0ec599e1f0a10609841966125 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Fri, 23 Feb 2018 15:37:16 +0100 Subject: [PATCH 037/873] Need to close after writing --- src/GitHub.Api/Authentication/LoginManager.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/GitHub.Api/Authentication/LoginManager.cs b/src/GitHub.Api/Authentication/LoginManager.cs index db961428a..d0fcc84dd 100644 --- a/src/GitHub.Api/Authentication/LoginManager.cs +++ b/src/GitHub.Api/Authentication/LoginManager.cs @@ -266,6 +266,7 @@ string password { proc.StandardInput.WriteLine(username); proc.StandardInput.WriteLine(password); + proc.StandardInput.Close(); }; var ret = await loginTask.StartAwait(); if (ret.Count == 0) @@ -313,6 +314,7 @@ string code proc.StandardInput.WriteLine(username); proc.StandardInput.WriteLine(password); proc.StandardInput.WriteLine(code); + proc.StandardInput.Close(); }; var ret = await loginTask.StartAwait(); if (ret.Count == 0) From 92547badf890b869eede1731cd93cec1fdbc90db Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Fri, 23 Feb 2018 16:02:48 +0100 Subject: [PATCH 038/873] Make sure we're on tls 12 --- src/OctoRun/Program.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/OctoRun/Program.cs b/src/OctoRun/Program.cs index 680ac54fd..c149ba868 100644 --- a/src/OctoRun/Program.cs +++ b/src/OctoRun/Program.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Net; using System.Threading.Tasks; using static OctoRun.LoginManager; @@ -94,6 +95,8 @@ static void Main(string[] args) { //Logging.LogAdapter = new ConsoleLogAdapter(); + ServicePointManager.ServerCertificateValidationCallback = (sender, chain, cert, errors) => true; + ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; var opts = new OptionSet(); From f76d78cbe2503f34911249312b97666ef1bc41b1 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Fri, 23 Feb 2018 16:03:16 +0100 Subject: [PATCH 039/873] Cosmetic tweak --- src/GitHub.Api/NewTaskSystem/ProcessTask.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/GitHub.Api/NewTaskSystem/ProcessTask.cs b/src/GitHub.Api/NewTaskSystem/ProcessTask.cs index 3099a47ad..03646906a 100644 --- a/src/GitHub.Api/NewTaskSystem/ProcessTask.cs +++ b/src/GitHub.Api/NewTaskSystem/ProcessTask.cs @@ -505,4 +505,5 @@ public SimpleListProcessTask(CancellationToken token, string arguments, IOutputP public override string ProcessName => fullPathToExecutable; public override string ProcessArguments => arguments; - }} \ No newline at end of file + } +} \ No newline at end of file From c14d3f59733e206e067ca1b58c0de786b25dff05 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Fri, 23 Feb 2018 16:22:59 +0100 Subject: [PATCH 040/873] Bump version to 0.27.0 --- common/SolutionInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/SolutionInfo.cs b/common/SolutionInfo.cs index 902f73e57..bbde9c488 100644 --- a/common/SolutionInfo.cs +++ b/common/SolutionInfo.cs @@ -31,6 +31,6 @@ namespace System { internal static class AssemblyVersionInformation { - internal const string Version = "0.26.1"; + internal const string Version = "0.27.0"; } } From 86f2e2318e5cf88fd3c66b39380b8fcd9aaec8ed Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Fri, 23 Feb 2018 16:31:28 +0100 Subject: [PATCH 041/873] Need to target 4.6 for mono to compile it --- src/OctoRun/OctoRun.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OctoRun/OctoRun.csproj b/src/OctoRun/OctoRun.csproj index 7e4dd4491..b72ec6fe6 100644 --- a/src/OctoRun/OctoRun.csproj +++ b/src/OctoRun/OctoRun.csproj @@ -9,7 +9,7 @@ Properties OctoRun octorun - v4.5.2 + v4.6.1 512 true Internal From 9de6b3d587256494b69feb581ad8ae4e3feaca5f Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Fri, 23 Feb 2018 16:39:27 +0100 Subject: [PATCH 042/873] Make sure the build of OctoRun happens before the rest with the correct configuration --- common/properties.props | 3 ++- package.cmd | 3 +++ package.sh | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/common/properties.props b/common/properties.props index 9d7fd40c6..c6eaf184b 100644 --- a/common/properties.props +++ b/common/properties.props @@ -10,6 +10,7 @@ C:\Program Files\Unity\Editor\Data\Managed\ C:\Program Files (x86)\Unity\Editor\Data\Managed\ \Applications\Unity\Unity.app\Contents\Managed\ - Debug + Debug + $(Configuration) \ No newline at end of file diff --git a/package.cmd b/package.cmd index e25ddbd41..e71dbbb66 100644 --- a/package.cmd +++ b/package.cmd @@ -39,6 +39,9 @@ if not exist "%Unity%" ( cd .. call common\nuget.exe restore GitHub.Unity.sln + echo xbuild GitHub.Unity.sln /target:OctoRun /property:Configuration=%Configuration% + call xbuild GitHub.Unity.sln /target:OctoRun /property:Configuration=%Configuration% + echo xbuild GitHub.Unity.sln /property:Configuration=%Configuration% call xbuild GitHub.Unity.sln /property:Configuration=%Configuration% diff --git a/package.sh b/package.sh index ca09bd5e5..b2ce61ee9 100755 --- a/package.sh +++ b/package.sh @@ -51,6 +51,7 @@ else nuget restore GitHub.Unity.sln fi +xbuild GitHub.Unity.sln /target:OctoRun /property:Configuration=$Configuration xbuild GitHub.Unity.sln /property:Configuration=$Configuration rm -f unity/PackageProject/Assets/Plugins/GitHub/Editor/deleteme* From f3516a898a4e3406a44ba7451e6acec0337cfacd Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Fri, 23 Feb 2018 16:40:15 +0100 Subject: [PATCH 043/873] Bump version to 0.26.2 --- common/SolutionInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/SolutionInfo.cs b/common/SolutionInfo.cs index bbde9c488..a32f7ba47 100644 --- a/common/SolutionInfo.cs +++ b/common/SolutionInfo.cs @@ -31,6 +31,6 @@ namespace System { internal static class AssemblyVersionInformation { - internal const string Version = "0.27.0"; + internal const string Version = "0.26.2"; } } From 2f6b28ba3f1b105a5274812371c5280b8fa35275 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Fri, 23 Feb 2018 16:46:02 +0100 Subject: [PATCH 044/873] Place the tools in a known location independent of project --- src/UnityExtension/Assets/Editor/GitHub.Unity/Misc/Utility.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/Misc/Utility.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/Misc/Utility.cs index 80ac058dd..e3da709c9 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/Misc/Utility.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/Misc/Utility.cs @@ -52,7 +52,8 @@ public static Texture2D GetTextureFromColor(Color color) public static NPath GetTool(string tool) { - var outfile = Application.temporaryCachePath.ToNPath().Combine(tool); + var outfile = EntryPoint.Environment.UserCachePath.Combine("tools", tool); + outfile.EnsureParentDirectoryExists(); if (tool == "octorun.exe") { From 85b11e7d7fa3f2df411eb4f131fa57ff095a3458 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Fri, 23 Feb 2018 17:20:21 +0100 Subject: [PATCH 045/873] Build octorun before anything else in appveyor --- appveyor.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index a5d0c4580..9a1098d41 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -43,6 +43,9 @@ install: nuget restore GitHub.Unity.sln +before_build: + - cmd: msbuild GitHub.Unity.sln /target:OctoRun /Configuration:Release + assembly_info: patch: false file: common\SolutionInfo.cs From bfc3436d3d343baa4c7e5d9516e8387b9c31bf3e Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Fri, 23 Feb 2018 17:24:20 +0100 Subject: [PATCH 046/873] Call msbuild correctly, doh --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 9a1098d41..2bcf0501c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -44,7 +44,7 @@ install: nuget restore GitHub.Unity.sln before_build: - - cmd: msbuild GitHub.Unity.sln /target:OctoRun /Configuration:Release + - cmd: msbuild GitHub.Unity.sln /target:OctoRun /property:Configuration=Release assembly_info: patch: false From 5b5ca253268e48ff806cb1f0f72e59bc8fec3262 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Fri, 23 Feb 2018 18:00:16 +0100 Subject: [PATCH 047/873] Fix breakage in process running --- src/GitHub.Api/Authentication/LoginManager.cs | 2 +- src/GitHub.Api/OutputProcessors/ProcessManager.cs | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/GitHub.Api/Authentication/LoginManager.cs b/src/GitHub.Api/Authentication/LoginManager.cs index d0fcc84dd..44ad79f60 100644 --- a/src/GitHub.Api/Authentication/LoginManager.cs +++ b/src/GitHub.Api/Authentication/LoginManager.cs @@ -261,7 +261,7 @@ string password ApplicationAuthorization auth = null; var loginTask = new SimpleListProcessTask(taskManager.Token, loginTool, $"login --host={host}"); - loginTask.Configure(processManager, true); + loginTask.Configure(processManager, workingDirectory: loginTool.Parent, withInput: true); loginTask.OnStartProcess += proc => { proc.StandardInput.WriteLine(username); diff --git a/src/GitHub.Api/OutputProcessors/ProcessManager.cs b/src/GitHub.Api/OutputProcessors/ProcessManager.cs index bf8711cc2..79bd83135 100644 --- a/src/GitHub.Api/OutputProcessors/ProcessManager.cs +++ b/src/GitHub.Api/OutputProcessors/ProcessManager.cs @@ -41,8 +41,6 @@ public T Configure(T processTask, NPath executable = null, string arguments = StandardErrorEncoding = Encoding.UTF8 }; - if (!executable.IsRelative) - workingDirectory = executable.Parent; gitEnvironment.Configure(startInfo, workingDirectory ?? environment.RepositoryPath); if (executable.IsRelative) From d2f70fdfbb153dfaad4540df1900aa15c897be34 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Fri, 23 Feb 2018 18:02:42 +0100 Subject: [PATCH 048/873] Missed one --- src/GitHub.Api/Authentication/LoginManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GitHub.Api/Authentication/LoginManager.cs b/src/GitHub.Api/Authentication/LoginManager.cs index 44ad79f60..7995b897e 100644 --- a/src/GitHub.Api/Authentication/LoginManager.cs +++ b/src/GitHub.Api/Authentication/LoginManager.cs @@ -308,7 +308,7 @@ string code ApplicationAuthorization auth = null; var loginTask = new SimpleListProcessTask(taskManager.Token, loginTool, $"login --host={host} --2fa"); - loginTask.Configure(processManager, true); + loginTask.Configure(processManager, workingDirectory: loginTool.Parent, withInput: true); loginTask.OnStartProcess += proc => { proc.StandardInput.WriteLine(username); From 0080d3dfd745eca707ccda04213ebeaca4116a9c Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Mon, 26 Feb 2018 13:34:32 -0500 Subject: [PATCH 049/873] Ignoring a test from AppVeyor --- src/tests/IntegrationTests/Installer/GitInstallerTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tests/IntegrationTests/Installer/GitInstallerTests.cs b/src/tests/IntegrationTests/Installer/GitInstallerTests.cs index 900b428e3..da8824978 100644 --- a/src/tests/IntegrationTests/Installer/GitInstallerTests.cs +++ b/src/tests/IntegrationTests/Installer/GitInstallerTests.cs @@ -35,6 +35,7 @@ public override void TestFixtureTearDown() } [Test] + [Category("DoNotRunOnAppVeyor")] public void GitInstallTest() { var gitInstallationPath = TestBasePath.Combine("GitInstall").CreateDirectory(); From eb3c65c7bf091644b39276f4758dfda3a9d8375e Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Tue, 27 Feb 2018 10:10:50 -0500 Subject: [PATCH 050/873] Discovering UserCachePath --- src/GitHub.Api/Application/ApplicationManagerBase.cs | 3 +-- src/GitHub.Api/Installer/GitInstaller.cs | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/GitHub.Api/Application/ApplicationManagerBase.cs b/src/GitHub.Api/Application/ApplicationManagerBase.cs index 61894c369..6920afd60 100644 --- a/src/GitHub.Api/Application/ApplicationManagerBase.cs +++ b/src/GitHub.Api/Application/ApplicationManagerBase.cs @@ -72,8 +72,7 @@ public void Run(bool firstRun) } }); - var applicationDataPath = Environment.GetSpecialFolder(System.Environment.SpecialFolder.LocalApplicationData).ToNPath(); - var installDetails = new GitInstallDetails(applicationDataPath, true); + var installDetails = new GitInstallDetails(Environment.UserCachePath, true); var gitInstaller = new GitInstaller(Environment, CancellationToken, installDetails); // if successful, continue with environment initialization, otherwise try to find an existing git installation diff --git a/src/GitHub.Api/Installer/GitInstaller.cs b/src/GitHub.Api/Installer/GitInstaller.cs index 8b303f55b..073742bd1 100644 --- a/src/GitHub.Api/Installer/GitInstaller.cs +++ b/src/GitHub.Api/Installer/GitInstaller.cs @@ -25,11 +25,11 @@ class GitInstallDetails private readonly bool onWindows; - public GitInstallDetails(NPath applicationDataPath, bool onWindows) + public GitInstallDetails(NPath pluginDataPath, bool onWindows) { this.onWindows = onWindows; - PluginDataPath = applicationDataPath.Combine(ApplicationInfo.ApplicationName); + PluginDataPath = pluginDataPath; var gitInstallPath = PluginDataPath.Combine(PackageNameWithVersion); GitInstallationPath = gitInstallPath; From b69605d2659f08a296614189ab17e42393393ab3 Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Tue, 27 Feb 2018 12:08:04 -0500 Subject: [PATCH 051/873] Fix GitLock's Default member The default value will be 0 not -1 --- src/GitHub.Api/Git/GitLock.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GitHub.Api/Git/GitLock.cs b/src/GitHub.Api/Git/GitLock.cs index 1267e7af4..f604a0fdf 100644 --- a/src/GitHub.Api/Git/GitLock.cs +++ b/src/GitHub.Api/Git/GitLock.cs @@ -5,7 +5,7 @@ namespace GitHub.Unity [Serializable] public struct GitLock { - public static GitLock Default = new GitLock { ID = -1 }; + public static GitLock Default = new GitLock(); public int ID; public string Path; From 314d61ea7ebafebf5df00e162d5ac0d563e4508c Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Tue, 27 Feb 2018 12:09:41 -0500 Subject: [PATCH 052/873] Adding LfsLocksModificationProcessor --- .../Editor/GitHub.Unity/ApplicationManager.cs | 1 + .../Editor/GitHub.Unity/GitHub.Unity.csproj | 1 + .../UI/LfsLocksModificationProcessor.cs | 107 ++++++++++++++++++ 3 files changed, 109 insertions(+) create mode 100644 src/UnityExtension/Assets/Editor/GitHub.Unity/UI/LfsLocksModificationProcessor.cs diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationManager.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationManager.cs index c5fcfd00c..bcf9702ca 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationManager.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationManager.cs @@ -31,6 +31,7 @@ protected override void InitializeUI() Logger.Trace("Restarted {0}", Environment.Repository); EnvironmentCache.Instance.Flush(); + LfsLocksModificationProcessor.Initialize(Environment.Repository); ProjectWindowInterface.Initialize(Environment.Repository); var window = Window.GetWindow(); if (window != null) diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/GitHub.Unity.csproj b/src/UnityExtension/Assets/Editor/GitHub.Unity/GitHub.Unity.csproj index 1bc293176..43466162c 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/GitHub.Unity.csproj +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/GitHub.Unity.csproj @@ -94,6 +94,7 @@ + diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/LfsLocksModificationProcessor.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/LfsLocksModificationProcessor.cs new file mode 100644 index 000000000..328a620fe --- /dev/null +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/LfsLocksModificationProcessor.cs @@ -0,0 +1,107 @@ +using System.Collections.Generic; +using System.Linq; +using GitHub.Logging; +using UnityEditor; + +namespace GitHub.Unity +{ + class LfsLocksModificationProcessor : UnityEditor.AssetModificationProcessor + { + private static ILogging logger; + private static ILogging Logger { get { return logger = logger ?? LogHelper.GetLogger(); } } + + private static IRepository repository; + + private static List locks = new List(); + + private static CacheUpdateEvent lastLocksChangedEvent; + + public static void Initialize(IRepository repo) + { + Logger.Trace("Initialize HasRepository:{0}", repo != null); + + repository = repo; + + if (repository != null) + { + repository.LocksChanged += RepositoryOnLocksChanged; + repository.CheckLocksChangedEvent(lastLocksChangedEvent); + } + } + + private static void RepositoryOnLocksChanged(CacheUpdateEvent cacheUpdateEvent) + { + if (!lastLocksChangedEvent.Equals(cacheUpdateEvent)) + { + lastLocksChangedEvent = cacheUpdateEvent; + locks = repository.CurrentLocks; + } + } + + public static string[] OnWillSaveAssets(string[] paths) + { + Logger.Trace("OnWillSaveAssets: [{0}]", string.Join(", ", paths)); + return paths; + } + + public static AssetMoveResult OnWillMoveAsset(string oldPath, string newPath) + { + Logger.Trace("OnWillMoveAsset:{0}->{1}", oldPath, newPath); + + var result = AssetMoveResult.DidNotMove; + if (IsLocked(oldPath)) + { + result = AssetMoveResult.FailedMove; + } + else if (IsLocked(newPath)) + { + result = AssetMoveResult.FailedMove; + } + return result; + } + + public static AssetDeleteResult OnWillDeleteAsset(string assetPath, RemoveAssetOptions option) + { + Logger.Trace("OnWillDeleteAsset:{0}", assetPath); + + if (IsLocked(assetPath)) + { + return AssetDeleteResult.FailedDelete; + } + return AssetDeleteResult.DidNotDelete; + } + + public static bool IsOpenForEdit(string assetPath, out string message) + { + Logger.Trace("IsOpenForEdit:{0}", assetPath); + + if (IsLocked(assetPath)) + { + message = "File is locked for editing!"; + return false; + } + else + { + message = null; + return true; + } + } + + private static bool IsLocked(string assetPath) + { + if(repository != null) + { + var repositoryPath = EntryPoint.Environment.GetRepositoryPath(assetPath.ToNPath()); + var gitLock = locks.FirstOrDefault(@lock => @lock.Path == repositoryPath); + if (!gitLock.Equals(GitLock.Default)) + { + Logger.Trace("Lock found on: {0}", assetPath); + + //TODO: Check user and return true + } + } + + return false; + } + } +} \ No newline at end of file From 53de0aa74934c73dd12a2e03a26654e26b0533d4 Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Tue, 27 Feb 2018 13:38:27 -0500 Subject: [PATCH 053/873] Initial project from 'yo nodejs-cli-typescript' --- octorun/.gitignore | 2 + octorun/LICENSE | 21 ++ octorun/bin/octorun | 3 + octorun/bin/octorun-write | 3 + octorun/dist/bin/app-write.d.ts | 7 + octorun/dist/bin/app-write.js | 30 ++ octorun/dist/bin/app.d.ts | 6 + octorun/dist/bin/app.js | 18 + octorun/dist/writer.d.ts | 3 + octorun/dist/writer.js | 8 + octorun/package-lock.json | 609 ++++++++++++++++++++++++++++++++ octorun/package.json | 43 +++ octorun/src/bin/app-write.ts | 39 ++ octorun/src/bin/app.ts | 23 ++ octorun/src/writer.ts | 7 + octorun/test/writer-spec.ts | 34 ++ octorun/tsconfig.json | 21 ++ 17 files changed, 877 insertions(+) create mode 100644 octorun/.gitignore create mode 100644 octorun/LICENSE create mode 100644 octorun/bin/octorun create mode 100644 octorun/bin/octorun-write create mode 100644 octorun/dist/bin/app-write.d.ts create mode 100644 octorun/dist/bin/app-write.js create mode 100644 octorun/dist/bin/app.d.ts create mode 100644 octorun/dist/bin/app.js create mode 100644 octorun/dist/writer.d.ts create mode 100644 octorun/dist/writer.js create mode 100644 octorun/package-lock.json create mode 100644 octorun/package.json create mode 100644 octorun/src/bin/app-write.ts create mode 100644 octorun/src/bin/app.ts create mode 100644 octorun/src/writer.ts create mode 100644 octorun/test/writer-spec.ts create mode 100644 octorun/tsconfig.json diff --git a/octorun/.gitignore b/octorun/.gitignore new file mode 100644 index 000000000..93f136199 --- /dev/null +++ b/octorun/.gitignore @@ -0,0 +1,2 @@ +node_modules +npm-debug.log diff --git a/octorun/LICENSE b/octorun/LICENSE new file mode 100644 index 000000000..0776bd363 --- /dev/null +++ b/octorun/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2018 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/octorun/bin/octorun b/octorun/bin/octorun new file mode 100644 index 000000000..81c553ba0 --- /dev/null +++ b/octorun/bin/octorun @@ -0,0 +1,3 @@ +#!/usr/bin/env node + +require('../dist/bin/app.js'); diff --git a/octorun/bin/octorun-write b/octorun/bin/octorun-write new file mode 100644 index 000000000..62ead2886 --- /dev/null +++ b/octorun/bin/octorun-write @@ -0,0 +1,3 @@ +#!/usr/bin/env node + +require('../dist/bin/app-write.js'); diff --git a/octorun/dist/bin/app-write.d.ts b/octorun/dist/bin/app-write.d.ts new file mode 100644 index 000000000..b6e272292 --- /dev/null +++ b/octorun/dist/bin/app-write.d.ts @@ -0,0 +1,7 @@ +export declare class Write { + private program; + private package; + private writer; + constructor(); + initialize(): void; +} diff --git a/octorun/dist/bin/app-write.js b/octorun/dist/bin/app-write.js new file mode 100644 index 000000000..d3b06281b --- /dev/null +++ b/octorun/dist/bin/app-write.js @@ -0,0 +1,30 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const commander = require("commander"); +const writer_1 = require("../writer"); +class Write { + constructor() { + this.program = commander; + this.package = require('../../package.json'); + this.writer = new writer_1.Writer(); + } + initialize() { + this.program + .version(this.package.version) + .option('-m, --message [value]', 'Say hello!') + .parse(process.argv); + if (this.program.message != null) { + if (typeof this.program.message !== 'string') { + this.writer.write(); + } + else { + this.writer.write(this.program.message); + } + process.exit(); + } + this.program.help(); + } +} +exports.Write = Write; +let app = new Write(); +app.initialize(); diff --git a/octorun/dist/bin/app.d.ts b/octorun/dist/bin/app.d.ts new file mode 100644 index 000000000..65223902d --- /dev/null +++ b/octorun/dist/bin/app.d.ts @@ -0,0 +1,6 @@ +export declare class App { + private program; + private package; + constructor(); + initialize(): void; +} diff --git a/octorun/dist/bin/app.js b/octorun/dist/bin/app.js new file mode 100644 index 000000000..28bcd5ebe --- /dev/null +++ b/octorun/dist/bin/app.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const commander = require("commander"); +class App { + constructor() { + this.program = commander; + this.package = require('../../package.json'); + } + initialize() { + this.program + .version(this.package.version) + .command('write [message]', 'say hello!') + .parse(process.argv); + } +} +exports.App = App; +let app = new App(); +app.initialize(); diff --git a/octorun/dist/writer.d.ts b/octorun/dist/writer.d.ts new file mode 100644 index 000000000..8373b156f --- /dev/null +++ b/octorun/dist/writer.d.ts @@ -0,0 +1,3 @@ +export declare class Writer { + write(message?: String): void; +} diff --git a/octorun/dist/writer.js b/octorun/dist/writer.js new file mode 100644 index 000000000..cc6f2a672 --- /dev/null +++ b/octorun/dist/writer.js @@ -0,0 +1,8 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class Writer { + write(message = "Hello World!") { + console.log(message); + } +} +exports.Writer = Writer; diff --git a/octorun/package-lock.json b/octorun/package-lock.json new file mode 100644 index 000000000..0a2cf1867 --- /dev/null +++ b/octorun/package-lock.json @@ -0,0 +1,609 @@ +{ + "name": "octorun", + "version": "0.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/chai": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.2.tgz", + "integrity": "sha512-D8uQwKYUw2KESkorZ27ykzXgvkDJYXVEihGklgfp5I4HUP8D6IxtcdLTMB1emjQiWzV7WZ5ihm1cxIzVwjoleQ==", + "dev": true + }, + "@types/commander": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/@types/commander/-/commander-2.12.2.tgz", + "integrity": "sha512-0QEFiR8ljcHp9bAbWxecjVRuAMr16ivPiGOw6KFQBVrVd0RQIcM3xKdRisH2EDWgVWujiYtHwhSkSUoAAGzH7Q==", + "dev": true, + "requires": { + "commander": "2.14.1" + } + }, + "@types/mocha": { + "version": "2.2.48", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.48.tgz", + "integrity": "sha512-nlK/iyETgafGli8Zh9zJVCTicvU3iajSkRwOh3Hhiva598CMqNJ4NcVCGMTGKpGpTYj/9R8RLzS9NAykSSCqGw==", + "dev": true + }, + "@types/node": { + "version": "7.0.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.55.tgz", + "integrity": "sha512-diCxfWNT4g2UM9Y+BPgy4s3egcZ2qOXc0mXLauvbsBUq9SBKQfh0SmuEUEhJVFZt/p6UDsjg1s2EgfM6OSlp4g==", + "dev": true + }, + "@types/sinon": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-2.3.7.tgz", + "integrity": "sha512-w+LjztaZbgZWgt/y/VMP5BUAWLtSyoIJhXyW279hehLPyubDoBNwvhcj3WaSptcekuKYeTCVxrq60rdLc6ImJA==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "browser-stdout": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "dev": true + }, + "chai": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", + "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", + "dev": true, + "requires": { + "assertion-error": "1.1.0", + "check-error": "1.0.2", + "deep-eql": "3.0.1", + "get-func-name": "2.0.0", + "pathval": "1.1.0", + "type-detect": "4.0.8" + } + }, + "chalk": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", + "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", + "dev": true, + "requires": { + "ansi-styles": "3.2.0", + "escape-string-regexp": "1.0.5", + "supports-color": "5.2.0" + }, + "dependencies": { + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", + "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", + "dev": true, + "requires": { + "has-flag": "3.0.0" + } + } + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "color-convert": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", + "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "commander": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz", + "integrity": "sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "debug": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "diff": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", + "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "formatio": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.2.0.tgz", + "integrity": "sha1-87IWfZBoxGmKjVH092CjmlTYGOs=", + "dev": true, + "requires": { + "samsam": "1.3.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", + "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", + "dev": true + }, + "growl": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", + "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", + "dev": true + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "homedir-polyfill": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", + "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", + "dev": true, + "requires": { + "parse-passwd": "1.0.0" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "json3": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", + "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", + "dev": true + }, + "lodash._baseassign": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", + "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", + "dev": true, + "requires": { + "lodash._basecopy": "3.0.1", + "lodash.keys": "3.1.2" + } + }, + "lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", + "dev": true + }, + "lodash._basecreate": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", + "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=", + "dev": true + }, + "lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", + "dev": true + }, + "lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", + "dev": true + }, + "lodash.create": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", + "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=", + "dev": true, + "requires": { + "lodash._baseassign": "3.2.0", + "lodash._basecreate": "3.0.3", + "lodash._isiterateecall": "3.0.9" + } + }, + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", + "dev": true + }, + "lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", + "dev": true + }, + "lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "dev": true, + "requires": { + "lodash._getnative": "3.9.1", + "lodash.isarguments": "3.1.0", + "lodash.isarray": "3.0.4" + } + }, + "lolex": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-1.6.0.tgz", + "integrity": "sha1-OpoCg0UqR9dDnnJzG54H1zhuSfY=", + "dev": true + }, + "make-error": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.4.tgz", + "integrity": "sha512-0Dab5btKVPhibSalc9QGXb559ED7G7iLjFXBaj9Wq8O3vorueR5K5jaE3hkG6ZQINyhA/JgG6Qk4qdFQjsYV6g==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "1.1.11" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.3.tgz", + "integrity": "sha512-/6na001MJWEtYxHOV1WLfsmR4YIynkUEhBwzsb+fk2qmQ3iqsi258l/Q2MWHJMImAcNpZ8DEdYAK72NHoIQ9Eg==", + "dev": true, + "requires": { + "browser-stdout": "1.3.0", + "commander": "2.9.0", + "debug": "2.6.8", + "diff": "3.2.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.1", + "growl": "1.9.2", + "he": "1.1.1", + "json3": "3.3.2", + "lodash.create": "3.1.1", + "mkdirp": "0.5.1", + "supports-color": "3.1.2" + }, + "dependencies": { + "commander": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "dev": true, + "requires": { + "graceful-readlink": "1.0.1" + } + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "native-promise-only": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", + "integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, + "requires": { + "glob": "7.1.1" + } + }, + "samsam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", + "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", + "dev": true + }, + "sinon": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-2.4.1.tgz", + "integrity": "sha512-vFTrO9Wt0ECffDYIPSP/E5bBugt0UjcBQOfQUMh66xzkyPEnhl/vM2LRZi2ajuTdkH07sA6DzrM6KvdvGIH8xw==", + "dev": true, + "requires": { + "diff": "3.2.0", + "formatio": "1.2.0", + "lolex": "1.6.0", + "native-promise-only": "0.8.1", + "path-to-regexp": "1.7.0", + "samsam": "1.3.0", + "text-encoding": "0.6.4", + "type-detect": "4.0.8" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "requires": { + "source-map": "0.5.7" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", + "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=", + "dev": true, + "requires": { + "has-flag": "1.0.0" + } + }, + "text-encoding": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", + "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", + "dev": true + }, + "ts-node": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-3.3.0.tgz", + "integrity": "sha1-wTxqMCTjC+EYDdUwOPwgkonUv2k=", + "dev": true, + "requires": { + "arrify": "1.0.1", + "chalk": "2.3.1", + "diff": "3.2.0", + "make-error": "1.3.4", + "minimist": "1.2.0", + "mkdirp": "0.5.1", + "source-map-support": "0.4.18", + "tsconfig": "6.0.0", + "v8flags": "3.0.2", + "yn": "2.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "tsconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-6.0.0.tgz", + "integrity": "sha1-aw6DdgA9evGGT434+J3QBZ/80DI=", + "dev": true, + "requires": { + "strip-bom": "3.0.0", + "strip-json-comments": "2.0.1" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "typescript": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.7.2.tgz", + "integrity": "sha512-p5TCYZDAO0m4G344hD+wx/LATebLWZNkkh2asWUFqSsD2OrDNhbAHuSjobrmsUmdzjJjEeZVU9g1h3O6vpstnw==", + "dev": true + }, + "v8flags": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.0.2.tgz", + "integrity": "sha512-6sgSKoFw1UpUPd3cFdF7QGnrH6tDeBgW1F3v9gy8gLY0mlbiBXq8soy8aQpY6xeeCjH5K+JvC62Acp7gtl7wWA==", + "dev": true, + "requires": { + "homedir-polyfill": "1.0.1" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "yn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", + "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", + "dev": true + } + } +} diff --git a/octorun/package.json b/octorun/package.json new file mode 100644 index 000000000..7f4888d0d --- /dev/null +++ b/octorun/package.json @@ -0,0 +1,43 @@ +{ + "name": "octorun", + "version": "0.1.0", + "description": "", + "repository": "", + "license": "MIT", + "scripts": { + "clean": "rimraf dist", + "build": "npm run clean && tsc --pretty", + "test": "npm run build && mocha --compilers ts:ts-node/register --recursive test/**/*-spec.ts", + "watch": "npm run build -- --watch", + "watch:test": "npm run test -- --watch" + }, + "author": { + "name": "Stanley Goldman", + "email": "Stanley.Goldman@gmail.com" + }, + "main": "dist/bin/app.js", + "typings": "dist/bin/app.d.ts", + "bin": { + "octorun": "bin/octorun" + }, + "files": [ + "bin", + "dist" + ], + "devDependencies": { + "@types/chai": "^4.0.0", + "@types/commander": "^2.3.31", + "@types/mocha": "^2.2.39", + "@types/node": "^7.0.5", + "@types/sinon": "^2.3.0", + "chai": "^4.0.1", + "mocha": "^3.2.0", + "rimraf": "^2.6.1", + "sinon": "^2.3.2", + "ts-node": "^3.0.4", + "typescript": "^2.2.1" + }, + "dependencies": { + "commander": "^2.9.0" + } +} diff --git a/octorun/src/bin/app-write.ts b/octorun/src/bin/app-write.ts new file mode 100644 index 000000000..743f97f54 --- /dev/null +++ b/octorun/src/bin/app-write.ts @@ -0,0 +1,39 @@ +import * as commander from 'commander'; +import { Writer } from '../writer'; + +export class Write { + + private program: commander.CommanderStatic; + private package: any; + private writer: Writer; + + constructor() { + this.program = commander; + this.package = require('../../package.json'); + this.writer = new Writer(); + } + + public initialize() { + this.program + .version(this.package.version) + .option('-m, --message [value]', 'Say hello!') + .parse(process.argv); + + if (this.program.message != null) { + + if (typeof this.program.message !== 'string') { + this.writer.write(); + } else { + this.writer.write(this.program.message); + } + + process.exit(); + } + + this.program.help(); + } + +} + +let app = new Write(); +app.initialize(); diff --git a/octorun/src/bin/app.ts b/octorun/src/bin/app.ts new file mode 100644 index 000000000..53feb85a4 --- /dev/null +++ b/octorun/src/bin/app.ts @@ -0,0 +1,23 @@ +import * as commander from 'commander'; + +export class App { + + private program: commander.CommanderStatic; + private package: any; + + constructor() { + this.program = commander; + this.package = require('../../package.json'); + } + + public initialize() { + this.program + .version(this.package.version) + .command('write [message]', 'say hello!') + .parse(process.argv); + } + +} + +let app = new App(); +app.initialize(); diff --git a/octorun/src/writer.ts b/octorun/src/writer.ts new file mode 100644 index 000000000..2a15fdff9 --- /dev/null +++ b/octorun/src/writer.ts @@ -0,0 +1,7 @@ +export class Writer { + + public write(message: String = "Hello World!") { + console.log(message); + } + +} diff --git a/octorun/test/writer-spec.ts b/octorun/test/writer-spec.ts new file mode 100644 index 000000000..b85289ec6 --- /dev/null +++ b/octorun/test/writer-spec.ts @@ -0,0 +1,34 @@ +import { Writer } from '../src/writer'; +import * as chai from 'chai'; +import * as sinon from 'sinon'; + +const assert = chai.assert; + +describe('Writer', () => { + describe('#write()', () => { + it('should write a message', () => { + + let spy = sinon.spy(console, 'log'); + + var writer = new Writer(); + writer.write('I am being tested!'); + + assert(spy.calledWith('I am being tested!')); + + spy.restore(); + + }); + it('should write a default message', () => { + + let spy = sinon.spy(console, 'log'); + + var writer = new Writer(); + writer.write(); + + assert(spy.calledWith('Hello World!')); + + spy.restore(); + + }); + }); +}); diff --git a/octorun/tsconfig.json b/octorun/tsconfig.json new file mode 100644 index 000000000..7706353b9 --- /dev/null +++ b/octorun/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "target": "es6", + "declaration": true, + "module": "commonjs", + "moduleResolution": "node", + "noImplicitAny": true, + "outDir": "./dist", + "preserveConstEnums": true, + "removeComments": true + }, + "include": [ + "src/**/*" + ], + "exclude": [ + "node_modules", + "!node_modules/@types", + "test/**/*-spec.ts" + ] +} From 61d370b777b1597f833cbecd3ac9f054a392af71 Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Tue, 27 Feb 2018 13:41:29 -0500 Subject: [PATCH 054/873] Adding octokit --- octorun/package.json | 83 ++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/octorun/package.json b/octorun/package.json index 7f4888d0d..d00f413d9 100644 --- a/octorun/package.json +++ b/octorun/package.json @@ -1,43 +1,44 @@ { - "name": "octorun", - "version": "0.1.0", - "description": "", - "repository": "", - "license": "MIT", - "scripts": { - "clean": "rimraf dist", - "build": "npm run clean && tsc --pretty", - "test": "npm run build && mocha --compilers ts:ts-node/register --recursive test/**/*-spec.ts", - "watch": "npm run build -- --watch", - "watch:test": "npm run test -- --watch" - }, - "author": { - "name": "Stanley Goldman", - "email": "Stanley.Goldman@gmail.com" - }, - "main": "dist/bin/app.js", - "typings": "dist/bin/app.d.ts", - "bin": { - "octorun": "bin/octorun" - }, - "files": [ - "bin", - "dist" - ], - "devDependencies": { - "@types/chai": "^4.0.0", - "@types/commander": "^2.3.31", - "@types/mocha": "^2.2.39", - "@types/node": "^7.0.5", - "@types/sinon": "^2.3.0", - "chai": "^4.0.1", - "mocha": "^3.2.0", - "rimraf": "^2.6.1", - "sinon": "^2.3.2", - "ts-node": "^3.0.4", - "typescript": "^2.2.1" - }, - "dependencies": { - "commander": "^2.9.0" - } + "name": "octorun", + "version": "0.1.0", + "description": "", + "repository": "", + "license": "MIT", + "scripts": { + "clean": "rimraf dist", + "build": "npm run clean && tsc --pretty", + "test": "npm run build && mocha --compilers ts:ts-node/register --recursive test/**/*-spec.ts", + "watch": "npm run build -- --watch", + "watch:test": "npm run test -- --watch" + }, + "author": { + "name": "Stanley Goldman", + "email": "Stanley.Goldman@gmail.com" + }, + "main": "dist/bin/app.js", + "typings": "dist/bin/app.d.ts", + "bin": { + "octorun": "bin/octorun" + }, + "files": [ + "bin", + "dist" + ], + "devDependencies": { + "@types/chai": "^4.0.0", + "@types/commander": "^2.3.31", + "@types/mocha": "^2.2.39", + "@types/node": "^7.0.5", + "@types/sinon": "^2.3.0", + "chai": "^4.0.1", + "mocha": "^3.2.0", + "rimraf": "^2.6.1", + "sinon": "^2.3.2", + "ts-node": "^3.0.4", + "typescript": "^2.2.1" + }, + "dependencies": { + "@octokit/rest": "^14.0.9", + "commander": "^2.9.0" + } } From 9f99333f6827f7ec242dce942445f06a6a0237fb Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Tue, 27 Feb 2018 14:22:35 -0500 Subject: [PATCH 055/873] Login command and Authenticator --- octorun/bin/octorun-login | 3 +++ octorun/dist/authenticator.d.ts | 5 +++++ octorun/dist/authenticator.js | 21 ++++++++++++++++++ octorun/dist/bin/app-login.d.ts | 7 ++++++ octorun/dist/bin/app-login.js | 23 ++++++++++++++++++++ octorun/src/authenticator.ts | 34 +++++++++++++++++++++++++++++ octorun/src/bin/app-login.ts | 38 +++++++++++++++++++++++++++++++++ 7 files changed, 131 insertions(+) create mode 100644 octorun/bin/octorun-login create mode 100644 octorun/dist/authenticator.d.ts create mode 100644 octorun/dist/authenticator.js create mode 100644 octorun/dist/bin/app-login.d.ts create mode 100644 octorun/dist/bin/app-login.js create mode 100644 octorun/src/authenticator.ts create mode 100644 octorun/src/bin/app-login.ts diff --git a/octorun/bin/octorun-login b/octorun/bin/octorun-login new file mode 100644 index 000000000..fe09da41a --- /dev/null +++ b/octorun/bin/octorun-login @@ -0,0 +1,3 @@ +#!/usr/bin/env node + +require('../dist/bin/app-login.js'); diff --git a/octorun/dist/authenticator.d.ts b/octorun/dist/authenticator.d.ts new file mode 100644 index 000000000..3e80a0cb2 --- /dev/null +++ b/octorun/dist/authenticator.d.ts @@ -0,0 +1,5 @@ +export declare class Authenticator { + private github; + constructor(); + authenticate(): void; +} diff --git a/octorun/dist/authenticator.js b/octorun/dist/authenticator.js new file mode 100644 index 000000000..27e329d56 --- /dev/null +++ b/octorun/dist/authenticator.js @@ -0,0 +1,21 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const GitHub = require("@octokit/rest"); +class Authenticator { + constructor() { + this.github = new GitHub({ + timeout: 0, + requestMedia: 'application/vnd.github.v3+json', + headers: { + 'user-agent': 'octokit/rest.js v1.2.3' + }, + host: 'api.github.com', + pathPrefix: '', + protocol: 'https', + port: 443, + }); + } + authenticate() { + } +} +exports.Authenticator = Authenticator; diff --git a/octorun/dist/bin/app-login.d.ts b/octorun/dist/bin/app-login.d.ts new file mode 100644 index 000000000..1a4eeeebc --- /dev/null +++ b/octorun/dist/bin/app-login.d.ts @@ -0,0 +1,7 @@ +export declare class Write { + private program; + private package; + private authenticator; + constructor(); + initialize(): void; +} diff --git a/octorun/dist/bin/app-login.js b/octorun/dist/bin/app-login.js new file mode 100644 index 000000000..84edd3eec --- /dev/null +++ b/octorun/dist/bin/app-login.js @@ -0,0 +1,23 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const commander = require("commander"); +const authenticator_1 = require("../authenticator"); +class Write { + constructor() { + this.program = commander; + this.package = require('../../package.json'); + this.authenticator = new authenticator_1.Authenticator(); + } + initialize() { + this.program + .version(this.package.version) + .parse(process.argv); + if (this.program.message != null) { + process.exit(); + } + this.program.help(); + } +} +exports.Write = Write; +let app = new Write(); +app.initialize(); diff --git a/octorun/src/authenticator.ts b/octorun/src/authenticator.ts new file mode 100644 index 000000000..c30816126 --- /dev/null +++ b/octorun/src/authenticator.ts @@ -0,0 +1,34 @@ +//const octokit = require('@octokit/rest') + +import * as GitHub from '@octokit/rest'; + +export class Authenticator { + + private github: GitHub; + + constructor(){ + + //Listed defaults from https://github.com/octokit/rest.js#options + + this.github = new GitHub({ + timeout: 0, // 0 means no request timeout + requestMedia: 'application/vnd.github.v3+json', + headers: { + 'user-agent': 'octokit/rest.js v1.2.3' // v1.2.3 will be current version + }, + + // change for custom GitHub Enterprise URL + host: 'api.github.com', + pathPrefix: '', + protocol: 'https', + port: 443, + + // Node only: advanced request options can be passed as http(s) agent + //agent: undefined + }) + } + + public authenticate() { + + } +} diff --git a/octorun/src/bin/app-login.ts b/octorun/src/bin/app-login.ts new file mode 100644 index 000000000..5022eebd3 --- /dev/null +++ b/octorun/src/bin/app-login.ts @@ -0,0 +1,38 @@ +import * as commander from 'commander'; +import { Authenticator } from '../authenticator'; + +export class Write { + + private program: commander.CommanderStatic; + private package: any; + private authenticator: Authenticator; + + constructor() { + this.program = commander; + this.package = require('../../package.json'); + this.authenticator = new Authenticator(); + } + + public initialize() { + this.program + .version(this.package.version) + .parse(process.argv); + + if (this.program.message != null) { + + // if (typeof this.program.message !== 'string') { + // this.writer.write(); + // } else { + // this.writer.write(this.program.message); + // } + + process.exit(); + } + + this.program.help(); + } + +} + +let app = new Write(); +app.initialize(); From 5f0486004d3d4aeefcebb90c0373489897b4c568 Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Tue, 27 Feb 2018 16:30:11 -0500 Subject: [PATCH 056/873] A chunk of octorun that should work --- octorun/.env.template | 2 + octorun/.gitignore | 1 + octorun/bin/octorun | 2 + octorun/dist/authenticator.d.ts | 2 +- octorun/dist/authenticator.js | 70 +++++++++++++++++++++++++++++---- octorun/dist/bin/app-login.js | 67 ++++++++++++++++++++++++++----- octorun/dist/bin/app-write.js | 19 ++++----- octorun/dist/bin/app.js | 18 +++++---- octorun/dist/configuration.d.ts | 5 +++ octorun/dist/configuration.js | 7 ++++ octorun/dist/writer.js | 14 ++++--- octorun/package.json | 4 +- octorun/src/authenticator.ts | 19 ++++++--- octorun/src/bin/app-login.ts | 12 +++--- octorun/src/bin/app.ts | 3 ++ octorun/src/configuration.ts | 6 +++ octorun/tsconfig.json | 39 +++++++++--------- 17 files changed, 217 insertions(+), 73 deletions(-) create mode 100644 octorun/.env.template create mode 100644 octorun/dist/configuration.d.ts create mode 100644 octorun/dist/configuration.js create mode 100644 octorun/src/configuration.ts diff --git a/octorun/.env.template b/octorun/.env.template new file mode 100644 index 000000000..7eaafeb53 --- /dev/null +++ b/octorun/.env.template @@ -0,0 +1,2 @@ +OCTOKIT_CLIENT_ID= +OCTOKIT_CLIENT_SECRET= \ No newline at end of file diff --git a/octorun/.gitignore b/octorun/.gitignore index 93f136199..ef4fcce9d 100644 --- a/octorun/.gitignore +++ b/octorun/.gitignore @@ -1,2 +1,3 @@ +.env node_modules npm-debug.log diff --git a/octorun/bin/octorun b/octorun/bin/octorun index 81c553ba0..6c0fe6d04 100644 --- a/octorun/bin/octorun +++ b/octorun/bin/octorun @@ -1,3 +1,5 @@ #!/usr/bin/env node +console.log("NodeJs", process.argv[0]); + require('../dist/bin/app.js'); diff --git a/octorun/dist/authenticator.d.ts b/octorun/dist/authenticator.d.ts index 3e80a0cb2..ba36c1983 100644 --- a/octorun/dist/authenticator.d.ts +++ b/octorun/dist/authenticator.d.ts @@ -1,5 +1,5 @@ export declare class Authenticator { private github; constructor(); - authenticate(): void; + createAndDeleteExistingApplicationAuthorization(input?: string): Promise; } diff --git a/octorun/dist/authenticator.js b/octorun/dist/authenticator.js index 27e329d56..38d60518c 100644 --- a/octorun/dist/authenticator.js +++ b/octorun/dist/authenticator.js @@ -1,8 +1,44 @@ "use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -const GitHub = require("@octokit/rest"); -class Authenticator { - constructor() { +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +exports.__esModule = true; +var GitHub = require("@octokit/rest"); +var configuration_1 = require("./configuration"); +var Authenticator = (function () { + function Authenticator() { this.github = new GitHub({ timeout: 0, requestMedia: 'application/vnd.github.v3+json', @@ -12,10 +48,28 @@ class Authenticator { host: 'api.github.com', pathPrefix: '', protocol: 'https', - port: 443, + port: 443 }); } - authenticate() { - } -} + Authenticator.prototype.createAndDeleteExistingApplicationAuthorization = function (input) { + return __awaiter(this, void 0, void 0, function () { + var authParams; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + authParams = { + client_id: configuration_1.configuration.ClientId, + client_secret: configuration_1.configuration.ClientSecret, + scopes: ["user", "repo", "gist", "write:public_key"] + }; + return [4, this.github.authorization.getOrCreateAuthorizationForApp(authParams)]; + case 1: + _a.sent(); + return [2]; + } + }); + }); + }; + return Authenticator; +}()); exports.Authenticator = Authenticator; diff --git a/octorun/dist/bin/app-login.js b/octorun/dist/bin/app-login.js index 84edd3eec..afdf9fe8c 100644 --- a/octorun/dist/bin/app-login.js +++ b/octorun/dist/bin/app-login.js @@ -1,23 +1,70 @@ "use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -const commander = require("commander"); -const authenticator_1 = require("../authenticator"); -class Write { - constructor() { +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +exports.__esModule = true; +var commander = require("commander"); +var authenticator_1 = require("../authenticator"); +var Write = (function () { + function Write() { this.program = commander; this.package = require('../../package.json'); this.authenticator = new authenticator_1.Authenticator(); } - initialize() { + Write.prototype.initialize = function () { + var _this = this; this.program .version(this.package.version) + .option('-l, --login') + .option('-t, --twoFactor') .parse(process.argv); - if (this.program.message != null) { + if (this.program.login) { + var blah = function () { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2]; + }); + }); }; + process.exit(); + } + else if (this.program.twoFactor) { process.exit(); } this.program.help(); - } -} + }; + return Write; +}()); exports.Write = Write; -let app = new Write(); +var app = new Write(); app.initialize(); diff --git a/octorun/dist/bin/app-write.js b/octorun/dist/bin/app-write.js index d3b06281b..fd02ec270 100644 --- a/octorun/dist/bin/app-write.js +++ b/octorun/dist/bin/app-write.js @@ -1,14 +1,14 @@ "use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -const commander = require("commander"); -const writer_1 = require("../writer"); -class Write { - constructor() { +exports.__esModule = true; +var commander = require("commander"); +var writer_1 = require("../writer"); +var Write = (function () { + function Write() { this.program = commander; this.package = require('../../package.json'); this.writer = new writer_1.Writer(); } - initialize() { + Write.prototype.initialize = function () { this.program .version(this.package.version) .option('-m, --message [value]', 'Say hello!') @@ -23,8 +23,9 @@ class Write { process.exit(); } this.program.help(); - } -} + }; + return Write; +}()); exports.Write = Write; -let app = new Write(); +var app = new Write(); app.initialize(); diff --git a/octorun/dist/bin/app.js b/octorun/dist/bin/app.js index 28bcd5ebe..10a9c9caf 100644 --- a/octorun/dist/bin/app.js +++ b/octorun/dist/bin/app.js @@ -1,18 +1,20 @@ "use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -const commander = require("commander"); -class App { - constructor() { +exports.__esModule = true; +var commander = require("commander"); +var App = (function () { + function App() { this.program = commander; this.package = require('../../package.json'); } - initialize() { + App.prototype.initialize = function () { this.program .version(this.package.version) + .command('login [-h|-2fa]', 'Authenticate') .command('write [message]', 'say hello!') .parse(process.argv); - } -} + }; + return App; +}()); exports.App = App; -let app = new App(); +var app = new App(); app.initialize(); diff --git a/octorun/dist/configuration.d.ts b/octorun/dist/configuration.d.ts new file mode 100644 index 000000000..93e15f619 --- /dev/null +++ b/octorun/dist/configuration.d.ts @@ -0,0 +1,5 @@ +declare const configuration: { + ClientId: any; + ClientSecret: any; +}; +export { configuration }; diff --git a/octorun/dist/configuration.js b/octorun/dist/configuration.js new file mode 100644 index 000000000..1a3d3ed1c --- /dev/null +++ b/octorun/dist/configuration.js @@ -0,0 +1,7 @@ +"use strict"; +exports.__esModule = true; +var configuration = { + ClientId: process.env.OCTOKIT_CLIENT_ID, + ClientSecret: process.env.OCTOKIT_CLIENT_SECRET +}; +exports.configuration = configuration; diff --git a/octorun/dist/writer.js b/octorun/dist/writer.js index cc6f2a672..e5d55d015 100644 --- a/octorun/dist/writer.js +++ b/octorun/dist/writer.js @@ -1,8 +1,12 @@ "use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -class Writer { - write(message = "Hello World!") { - console.log(message); +exports.__esModule = true; +var Writer = (function () { + function Writer() { } -} + Writer.prototype.write = function (message) { + if (message === void 0) { message = "Hello World!"; } + console.log(message); + }; + return Writer; +}()); exports.Writer = Writer; diff --git a/octorun/package.json b/octorun/package.json index d00f413d9..c8dac5670 100644 --- a/octorun/package.json +++ b/octorun/package.json @@ -27,6 +27,7 @@ "devDependencies": { "@types/chai": "^4.0.0", "@types/commander": "^2.3.31", + "@types/dotenv": "^4.0.2", "@types/mocha": "^2.2.39", "@types/node": "^7.0.5", "@types/sinon": "^2.3.0", @@ -39,6 +40,7 @@ }, "dependencies": { "@octokit/rest": "^14.0.9", - "commander": "^2.9.0" + "commander": "^2.9.0", + "dotenv": "^5.0.1" } } diff --git a/octorun/src/authenticator.ts b/octorun/src/authenticator.ts index c30816126..aa43e6acc 100644 --- a/octorun/src/authenticator.ts +++ b/octorun/src/authenticator.ts @@ -1,12 +1,13 @@ //const octokit = require('@octokit/rest') import * as GitHub from '@octokit/rest'; +import { configuration } from './configuration'; export class Authenticator { private github: GitHub; - constructor(){ + constructor() { //Listed defaults from https://github.com/octokit/rest.js#options @@ -14,21 +15,27 @@ export class Authenticator { timeout: 0, // 0 means no request timeout requestMedia: 'application/vnd.github.v3+json', headers: { - 'user-agent': 'octokit/rest.js v1.2.3' // v1.2.3 will be current version + 'user-agent': 'octokit/rest.js v1.2.3' // v1.2.3 will be current version }, - + // change for custom GitHub Enterprise URL host: 'api.github.com', pathPrefix: '', protocol: 'https', port: 443, - + // Node only: advanced request options can be passed as http(s) agent //agent: undefined - }) + }) } - public authenticate() { + public async createAndDeleteExistingApplicationAuthorization() { + const authParams: GitHub.AuthorizationGetOrCreateAuthorizationForAppParams = { + client_id: configuration.ClientId, + client_secret: configuration.ClientSecret, + scopes: ["user", "repo", "gist", "write:public_key"] + }; + await this.github.authorization.getOrCreateAuthorizationForApp(authParams); } } diff --git a/octorun/src/bin/app-login.ts b/octorun/src/bin/app-login.ts index 5022eebd3..a5ea8f3bf 100644 --- a/octorun/src/bin/app-login.ts +++ b/octorun/src/bin/app-login.ts @@ -16,15 +16,15 @@ export class Write { public initialize() { this.program .version(this.package.version) + .option('-l, --login') + .option('-t, --twoFactor') .parse(process.argv); - if (this.program.message != null) { + if (this.program.login) { - // if (typeof this.program.message !== 'string') { - // this.writer.write(); - // } else { - // this.writer.write(this.program.message); - // } + process.exit(); + } + else if (this.program.twoFactor) { process.exit(); } diff --git a/octorun/src/bin/app.ts b/octorun/src/bin/app.ts index 53feb85a4..5bc468e57 100644 --- a/octorun/src/bin/app.ts +++ b/octorun/src/bin/app.ts @@ -1,3 +1,5 @@ +//require('dotenv').config(); + import * as commander from 'commander'; export class App { @@ -13,6 +15,7 @@ export class App { public initialize() { this.program .version(this.package.version) + .command('login [-h|-2fa]', 'Authenticate') .command('write [message]', 'say hello!') .parse(process.argv); } diff --git a/octorun/src/configuration.ts b/octorun/src/configuration.ts new file mode 100644 index 000000000..b72e19aed --- /dev/null +++ b/octorun/src/configuration.ts @@ -0,0 +1,6 @@ +const configuration = { + ClientId: process.env.OCTOKIT_CLIENT_ID, + ClientSecret: process.env.OCTOKIT_CLIENT_SECRET, +}; + +export { configuration }; \ No newline at end of file diff --git a/octorun/tsconfig.json b/octorun/tsconfig.json index 7706353b9..021d9fb8a 100644 --- a/octorun/tsconfig.json +++ b/octorun/tsconfig.json @@ -1,21 +1,22 @@ { - "compileOnSave": false, - "compilerOptions": { - "target": "es6", - "declaration": true, - "module": "commonjs", - "moduleResolution": "node", - "noImplicitAny": true, - "outDir": "./dist", - "preserveConstEnums": true, - "removeComments": true - }, - "include": [ - "src/**/*" - ], - "exclude": [ - "node_modules", - "!node_modules/@types", - "test/**/*-spec.ts" - ] + "compileOnSave": false, + "compilerOptions": { + "target": "es3", + "declaration": true, + "module": "commonjs", + "moduleResolution": "node", + "noImplicitAny": true, + "outDir": "./dist", + "preserveConstEnums": true, + "removeComments": true, + "lib":["es2015"] + }, + "include": [ + "src/**/*" + ], + "exclude": [ + "node_modules", + "!node_modules/@types", + "test/**/*-spec.ts" + ] } From 67220c4fc63a09e19bc7ad3bb7f9319b37322a47 Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Wed, 28 Feb 2018 10:20:06 -0500 Subject: [PATCH 057/873] Changing package octokit/rest to a modified github@9.3.1 --- octorun/dist/authenticator.d.ts | 2 +- octorun/dist/authenticator.js | 8 +++---- octorun/dist/bin/app-login.js | 42 +-------------------------------- octorun/package.json | 4 ++-- octorun/src/authenticator.ts | 6 ++--- octorun/src/bin/app-login.ts | 2 ++ 6 files changed, 12 insertions(+), 52 deletions(-) diff --git a/octorun/dist/authenticator.d.ts b/octorun/dist/authenticator.d.ts index ba36c1983..cc6697a38 100644 --- a/octorun/dist/authenticator.d.ts +++ b/octorun/dist/authenticator.d.ts @@ -1,5 +1,5 @@ export declare class Authenticator { private github; constructor(); - createAndDeleteExistingApplicationAuthorization(input?: string): Promise; + createAndDeleteExistingApplicationAuthorization(): Promise; } diff --git a/octorun/dist/authenticator.js b/octorun/dist/authenticator.js index 38d60518c..fd2d27f27 100644 --- a/octorun/dist/authenticator.js +++ b/octorun/dist/authenticator.js @@ -35,23 +35,21 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; exports.__esModule = true; -var GitHub = require("@octokit/rest"); +var GitHub = require("github"); var configuration_1 = require("./configuration"); var Authenticator = (function () { function Authenticator() { this.github = new GitHub({ timeout: 0, - requestMedia: 'application/vnd.github.v3+json', headers: { 'user-agent': 'octokit/rest.js v1.2.3' }, host: 'api.github.com', pathPrefix: '', - protocol: 'https', - port: 443 + protocol: 'https' }); } - Authenticator.prototype.createAndDeleteExistingApplicationAuthorization = function (input) { + Authenticator.prototype.createAndDeleteExistingApplicationAuthorization = function () { return __awaiter(this, void 0, void 0, function () { var authParams; return __generator(this, function (_a) { diff --git a/octorun/dist/bin/app-login.js b/octorun/dist/bin/app-login.js index afdf9fe8c..4bfbefe90 100644 --- a/octorun/dist/bin/app-login.js +++ b/octorun/dist/bin/app-login.js @@ -1,39 +1,4 @@ "use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __generator = (this && this.__generator) || function (thisArg, body) { - var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; - return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; - function verb(n) { return function (v) { return step([n, v]); }; } - function step(op) { - if (f) throw new TypeError("Generator is already executing."); - while (_) try { - if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [0, t.value]; - switch (op[0]) { - case 0: case 1: t = op; break; - case 4: _.label++; return { value: op[1], done: false }; - case 5: _.label++; y = op[1]; op = [0]; continue; - case 7: op = _.ops.pop(); _.trys.pop(); continue; - default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } - if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } - if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } - if (t[2]) _.ops.pop(); - _.trys.pop(); continue; - } - op = body.call(thisArg, _); - } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } - if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; - } -}; exports.__esModule = true; var commander = require("commander"); var authenticator_1 = require("../authenticator"); @@ -44,18 +9,13 @@ var Write = (function () { this.authenticator = new authenticator_1.Authenticator(); } Write.prototype.initialize = function () { - var _this = this; this.program .version(this.package.version) .option('-l, --login') .option('-t, --twoFactor') .parse(process.argv); if (this.program.login) { - var blah = function () { return __awaiter(_this, void 0, void 0, function () { - return __generator(this, function (_a) { - return [2]; - }); - }); }; + this.authenticator.createAndDeleteExistingApplicationAuthorization(); process.exit(); } else if (this.program.twoFactor) { diff --git a/octorun/package.json b/octorun/package.json index c8dac5670..4c658c7c7 100644 --- a/octorun/package.json +++ b/octorun/package.json @@ -39,8 +39,8 @@ "typescript": "^2.2.1" }, "dependencies": { - "@octokit/rest": "^14.0.9", "commander": "^2.9.0", - "dotenv": "^5.0.1" + "dotenv": "^5.0.1", + "github": "git+https://github.com/StanleyGoldman/rest.js.git#gfu" } } diff --git a/octorun/src/authenticator.ts b/octorun/src/authenticator.ts index aa43e6acc..290241364 100644 --- a/octorun/src/authenticator.ts +++ b/octorun/src/authenticator.ts @@ -1,6 +1,6 @@ //const octokit = require('@octokit/rest') -import * as GitHub from '@octokit/rest'; +import * as GitHub from 'github'; import { configuration } from './configuration'; export class Authenticator { @@ -13,7 +13,7 @@ export class Authenticator { this.github = new GitHub({ timeout: 0, // 0 means no request timeout - requestMedia: 'application/vnd.github.v3+json', + //requestMedia: 'application/vnd.github.v3+json', headers: { 'user-agent': 'octokit/rest.js v1.2.3' // v1.2.3 will be current version }, @@ -22,7 +22,7 @@ export class Authenticator { host: 'api.github.com', pathPrefix: '', protocol: 'https', - port: 443, + //port: 443, // Node only: advanced request options can be passed as http(s) agent //agent: undefined diff --git a/octorun/src/bin/app-login.ts b/octorun/src/bin/app-login.ts index a5ea8f3bf..d216709fd 100644 --- a/octorun/src/bin/app-login.ts +++ b/octorun/src/bin/app-login.ts @@ -22,6 +22,8 @@ export class Write { if (this.program.login) { + this.authenticator.createAndDeleteExistingApplicationAuthorization() + process.exit(); } else if (this.program.twoFactor) { From 5a6e3aeee594ad857e10d017875a286887ac5dbd Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Wed, 28 Feb 2018 15:42:00 -0500 Subject: [PATCH 058/873] Changing to a modified @octokit/rest compiled for es3 --- octorun/dist/authenticator.js | 6 +- octorun/package.json | 2 +- octorun/src/authenticator.ts | 8 +- octorun/typings/octokit-rest-es3/index.d.ts | 3476 +++++++++++++++++++ 4 files changed, 3485 insertions(+), 7 deletions(-) create mode 100644 octorun/typings/octokit-rest-es3/index.d.ts diff --git a/octorun/dist/authenticator.js b/octorun/dist/authenticator.js index fd2d27f27..c6698dc32 100644 --- a/octorun/dist/authenticator.js +++ b/octorun/dist/authenticator.js @@ -35,18 +35,20 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; exports.__esModule = true; -var GitHub = require("github"); +var GitHub = require("octokit-rest-es3"); var configuration_1 = require("./configuration"); var Authenticator = (function () { function Authenticator() { this.github = new GitHub({ timeout: 0, + requestMedia: 'application/vnd.github.v3+json', headers: { 'user-agent': 'octokit/rest.js v1.2.3' }, host: 'api.github.com', pathPrefix: '', - protocol: 'https' + protocol: 'https', + port: 443 }); } Authenticator.prototype.createAndDeleteExistingApplicationAuthorization = function () { diff --git a/octorun/package.json b/octorun/package.json index 4c658c7c7..19abf98d1 100644 --- a/octorun/package.json +++ b/octorun/package.json @@ -41,6 +41,6 @@ "dependencies": { "commander": "^2.9.0", "dotenv": "^5.0.1", - "github": "git+https://github.com/StanleyGoldman/rest.js.git#gfu" + "octokit-rest-es3": "github:gr2m/octokit-rest-es3" } } diff --git a/octorun/src/authenticator.ts b/octorun/src/authenticator.ts index 290241364..2e47f5109 100644 --- a/octorun/src/authenticator.ts +++ b/octorun/src/authenticator.ts @@ -1,6 +1,6 @@ -//const octokit = require('@octokit/rest') +/// -import * as GitHub from 'github'; +import * as GitHub from 'octokit-rest-es3'; import { configuration } from './configuration'; export class Authenticator { @@ -13,7 +13,7 @@ export class Authenticator { this.github = new GitHub({ timeout: 0, // 0 means no request timeout - //requestMedia: 'application/vnd.github.v3+json', + requestMedia: 'application/vnd.github.v3+json', headers: { 'user-agent': 'octokit/rest.js v1.2.3' // v1.2.3 will be current version }, @@ -22,7 +22,7 @@ export class Authenticator { host: 'api.github.com', pathPrefix: '', protocol: 'https', - //port: 443, + port: 443, // Node only: advanced request options can be passed as http(s) agent //agent: undefined diff --git a/octorun/typings/octokit-rest-es3/index.d.ts b/octorun/typings/octokit-rest-es3/index.d.ts new file mode 100644 index 000000000..693473ddb --- /dev/null +++ b/octorun/typings/octokit-rest-es3/index.d.ts @@ -0,0 +1,3476 @@ +/** + * This declaration file requires TypeScript 2.1 or above. + */ +declare namespace Github { + type json = any + type date = string + + export interface AnyResponse { + /** This is the data you would see in https://developer.github.com/v3/ */ + data: any + + /** Request metadata */ + meta:{ + 'x-ratelimit-limit': string, + 'x-ratelimit-remaining': string, + 'x-ratelimit-reset': string, + 'x-github-request-id': string, + 'x-github-media-type': string, + link: string, + 'last-modified': string, + etag: string, + status: string + } + + [Symbol.iterator](): Iterator + } + + export interface EmptyParams { + } + + export interface Options { + timeout?: number; + host?: string; + pathPrefix?: string; + protocol?: string; + port?: number; + proxy?: string; + ca?: string; + headers?: {[header: string]: any}; + requestMedia?: string; + rejectUnauthorized?: boolean; + family?: number; + } + + export interface AuthBasic { + type: "basic"; + username: string; + password: string; + } + + export interface AuthOAuthToken { + type: "oauth"; + token: string; + } + + export interface AuthOAuthSecret { + type: "oauth"; + key: string; + secret: string; + } + + export interface AuthUserToken { + type: "token"; + token: string; + } + + export interface AuthJWT { + type: "integration"; + token: string; + } + + export type Auth = + | AuthBasic + | AuthOAuthToken + | AuthOAuthSecret + | AuthUserToken + | AuthJWT; + + export type Link = + | { link: string; } + | { meta: { link: string; }; } + | string; + + export interface Callback { + (error: Error | null, result: any): any; + } + + + export type AuthorizationGetParams = + & { + id: string; + }; + export type AuthorizationCreateParams = + & { + scopes?: string[]; + note?: string; + note_url?: string; + client_id?: string; + client_secret?: string; + fingerprint?: string; + }; + export type AuthorizationUpdateParams = + & { + id: string; + scopes?: string[]; + add_scopes?: string[]; + remove_scopes?: string[]; + note?: string; + note_url?: string; + fingerprint?: string; + }; + export type AuthorizationDeleteParams = + & { + id: string; + }; + export type AuthorizationCheckParams = + & { + client_id?: string; + access_token: string; + }; + export type AuthorizationResetParams = + & { + client_id?: string; + access_token: string; + }; + export type AuthorizationRevokeParams = + & { + client_id?: string; + access_token: string; + }; + export type AuthorizationGetGrantsParams = + & { + page?: number; + per_page?: number; + }; + export type AuthorizationGetGrantParams = + & { + id: string; + page?: number; + per_page?: number; + }; + export type AuthorizationDeleteGrantParams = + & { + id: string; + }; + export type AuthorizationGetAllParams = + & { + page?: number; + per_page?: number; + }; + export type AuthorizationGetOrCreateAuthorizationForAppParams = + & { + client_id?: string; + client_secret: string; + scopes?: string[]; + note?: string; + note_url?: string; + fingerprint?: string; + }; + export type AuthorizationGetOrCreateAuthorizationForAppAndFingerprintParams = + & { + client_id?: string; + fingerprint?: string; + client_secret: string; + scopes?: string[]; + note?: string; + note_url?: string; + }; + export type AuthorizationRevokeGrantParams = + & { + client_id?: string; + access_token: string; + }; + export type ActivityGetEventsParams = + & { + page?: number; + per_page?: number; + }; + export type ActivityGetEventsForRepoParams = + & { + owner: string; + repo: string; + page?: number; + per_page?: number; + }; + export type ActivityGetEventsForRepoIssuesParams = + & { + owner: string; + repo: string; + page?: number; + per_page?: number; + }; + export type ActivityGetEventsForRepoNetworkParams = + & { + owner: string; + repo: string; + page?: number; + per_page?: number; + }; + export type ActivityGetEventsForOrgParams = + & { + org: string; + page?: number; + per_page?: number; + }; + export type ActivityGetEventsReceivedParams = + & { + username: string; + page?: number; + per_page?: number; + }; + export type ActivityGetEventsReceivedPublicParams = + & { + username: string; + page?: number; + per_page?: number; + }; + export type ActivityGetEventsForUserParams = + & { + username: string; + page?: number; + per_page?: number; + }; + export type ActivityGetEventsForUserPublicParams = + & { + username: string; + page?: number; + per_page?: number; + }; + export type ActivityGetEventsForUserOrgParams = + & { + username: string; + org: string; + page?: number; + per_page?: number; + }; + export type ActivityGetNotificationsParams = + & { + all?: boolean; + participating?: boolean; + since?: date; + before?: string; + }; + export type ActivityGetNotificationsForUserParams = + & { + owner: string; + repo: string; + all?: boolean; + participating?: boolean; + since?: date; + before?: string; + }; + export type ActivityMarkNotificationsAsReadParams = + & { + last_read_at?: string; + }; + export type ActivityMarkNotificationsAsReadForRepoParams = + & { + owner: string; + repo: string; + last_read_at?: string; + }; + export type ActivityGetNotificationThreadParams = + & { + id: string; + }; + export type ActivityMarkNotificationThreadAsReadParams = + & { + id: string; + }; + export type ActivityCheckNotificationThreadSubscriptionParams = + & { + id: string; + }; + export type ActivitySetNotificationThreadSubscriptionParams = + & { + id: string; + subscribed?: boolean; + ignored?: boolean; + }; + export type ActivityDeleteNotificationThreadSubscriptionParams = + & { + id: string; + }; + export type ActivityGetStargazersForRepoParams = + & { + owner: string; + repo: string; + page?: number; + per_page?: number; + }; + export type ActivityGetStarredReposForUserParams = + & { + username: string; + sort?: "created"|"updated"; + direction?: "asc"|"desc"; + page?: number; + per_page?: number; + }; + export type ActivityGetStarredReposParams = + & { + sort?: "created"|"updated"; + direction?: "asc"|"desc"; + page?: number; + per_page?: number; + }; + export type ActivityCheckStarringRepoParams = + & { + owner: string; + repo: string; + page?: number; + per_page?: number; + }; + export type ActivityStarRepoParams = + & { + owner: string; + repo: string; + }; + export type ActivityUnstarRepoParams = + & { + owner: string; + repo: string; + }; + export type ActivityGetWatchersForRepoParams = + & { + owner: string; + repo: string; + page?: number; + per_page?: number; + }; + export type ActivityGetWatchedReposForUserParams = + & { + username: string; + page?: number; + per_page?: number; + }; + export type ActivityGetWatchedReposParams = + & { + page?: number; + per_page?: number; + }; + export type ActivityGetRepoSubscriptionParams = + & { + owner: string; + repo: string; + page?: number; + per_page?: number; + }; + export type ActivitySetRepoSubscriptionParams = + & { + owner: string; + repo: string; + subscribed?: boolean; + ignored?: boolean; + }; + export type ActivityUnwatchRepoParams = + & { + owner: string; + repo: string; + }; + export type GistsGetParams = + & { + id: string; + }; + export type GistsCreateParams = + & { + files: json; + description?: string; + public: boolean; + }; + export type GistsEditParams = + & { + id: string; + description?: string; + files: json; + content?: string; + filename?: string; + }; + export type GistsStarParams = + & { + id: string; + }; + export type GistsUnstarParams = + & { + id: string; + }; + export type GistsForkParams = + & { + id: string; + }; + export type GistsDeleteParams = + & { + id: string; + }; + export type GistsGetForUserParams = + & { + username: string; + since?: date; + page?: number; + per_page?: number; + }; + export type GistsGetAllParams = + & { + since?: date; + page?: number; + per_page?: number; + }; + export type GistsGetPublicParams = + & { + since?: date; + }; + export type GistsGetStarredParams = + & { + since?: date; + }; + export type GistsGetRevisionParams = + & { + id: string; + sha: string; + }; + export type GistsGetCommitsParams = + & { + id: string; + }; + export type GistsCheckStarParams = + & { + id: string; + }; + export type GistsGetForksParams = + & { + id: string; + page?: number; + per_page?: number; + }; + export type GistsGetCommentsParams = + & { + gist_id: string; + }; + export type GistsGetCommentParams = + & { + gist_id: string; + id: string; + }; + export type GistsCreateCommentParams = + & { + gist_id: string; + body: string; + }; + export type GistsEditCommentParams = + & { + gist_id: string; + id: string; + body: string; + }; + export type GistsDeleteCommentParams = + & { + gist_id: string; + id: string; + }; + export type GitdataGetBlobParams = + & { + owner: string; + repo: string; + sha: string; + page?: number; + per_page?: number; + }; + export type GitdataCreateBlobParams = + & { + owner: string; + repo: string; + content: string; + encoding: string; + }; + export type GitdataGetCommitParams = + & { + owner: string; + repo: string; + sha: string; + }; + export type GitdataCreateCommitParams = + & { + owner: string; + repo: string; + message: string; + tree: string; + parents: string[]; + author?: json; + committer?: json; + }; + export type GitdataGetCommitSignatureVerificationParams = + & { + owner: string; + repo: string; + sha: string; + }; + export type GitdataGetReferenceParams = + & { + owner: string; + repo: string; + ref: string; + }; + export type GitdataGetReferencesParams = + & { + owner: string; + repo: string; + page?: number; + per_page?: number; + }; + export type GitdataGetTagsParams = + & { + owner: string; + repo: string; + page?: number; + per_page?: number; + }; + export type GitdataCreateReferenceParams = + & { + owner: string; + repo: string; + ref: string; + sha: string; + }; + export type GitdataUpdateReferenceParams = + & { + owner: string; + repo: string; + ref: string; + sha: string; + force?: boolean; + }; + export type GitdataDeleteReferenceParams = + & { + owner: string; + repo: string; + ref: string; + }; + export type GitdataGetTagParams = + & { + owner: string; + repo: string; + sha: string; + }; + export type GitdataCreateTagParams = + & { + owner: string; + repo: string; + tag: string; + message: string; + object: string; + type: string; + tagger: json; + }; + export type GitdataGetTagSignatureVerificationParams = + & { + owner: string; + repo: string; + sha: string; + }; + export type GitdataGetTreeParams = + & { + owner: string; + repo: string; + sha: string; + recursive?: boolean; + }; + export type GitdataCreateTreeParams = + & { + owner: string; + repo: string; + tree: json; + base_tree?: string; + }; + export type IntegrationsGetInstallationsParams = + & { + page?: number; + per_page?: number; + }; + export type IntegrationsCreateInstallationTokenParams = + & { + installation_id: string; + user_id?: string; + }; + export type IntegrationsGetInstallationRepositoriesParams = + & { + user_id?: string; + }; + export type IntegrationsAddRepoToInstallationParams = + & { + installation_id: string; + repository_id: string; + }; + export type IntegrationsRemoveRepoFromInstallationParams = + & { + installation_id: string; + repository_id: string; + }; + export type AppsGetForSlugParams = + & { + app_slug: string; + }; + export type AppsGetInstallationsParams = + & { + page?: number; + per_page?: number; + }; + export type AppsGetInstallationParams = + & { + installation_id: string; + }; + export type AppsCreateInstallationTokenParams = + & { + installation_id: string; + user_id?: string; + }; + export type AppsGetInstallationRepositoriesParams = + & { + user_id?: string; + }; + export type AppsAddRepoToInstallationParams = + & { + installation_id: string; + repository_id: string; + }; + export type AppsRemoveRepoFromInstallationParams = + & { + installation_id: string; + repository_id: string; + }; + export type AppsGetMarketplaceListingPlansParams = + & { + page?: number; + per_page?: number; + }; + export type AppsGetMarketplaceListingStubbedPlansParams = + & { + page?: number; + per_page?: number; + }; + export type AppsGetMarketplaceListingPlanAccountsParams = + & { + id: string; + page?: number; + per_page?: number; + }; + export type AppsGetMarketplaceListingStubbedPlanAccountsParams = + & { + id: string; + page?: number; + per_page?: number; + }; + export type AppsCheckMarketplaceListingAccountParams = + & { + id: string; + }; + export type AppsCheckMarketplaceListingStubbedAccountParams = + & { + id: string; + }; + export type IssuesGetParams = + & { + owner: string; + repo: string; + number: number; + }; + export type IssuesCreateParams = + & { + owner: string; + repo: string; + title: string; + body?: string; + assignee?: string; + milestone?: number; + labels?: string[]; + assignees?: string[]; + }; + export type IssuesEditParams = + & { + owner: string; + repo: string; + number: number; + title?: string; + body?: string; + assignee?: string; + state?: "open"|"closed"; + milestone?: number; + labels?: string[]; + assignees?: string[]; + }; + export type IssuesLockParams = + & { + owner: string; + repo: string; + number: number; + }; + export type IssuesUnlockParams = + & { + owner: string; + repo: string; + number: number; + }; + export type IssuesGetAllParams = + & { + filter?: "all"|"assigned"|"created"|"mentioned"|"subscribed"; + state?: "open"|"closed"|"all"; + labels?: string; + sort?: "created"|"updated"|"comments"; + direction?: "asc"|"desc"; + since?: date; + page?: number; + per_page?: number; + }; + export type IssuesGetForUserParams = + & { + filter?: "all"|"assigned"|"created"|"mentioned"|"subscribed"; + state?: "open"|"closed"|"all"; + labels?: string; + sort?: "created"|"updated"|"comments"; + direction?: "asc"|"desc"; + since?: date; + page?: number; + per_page?: number; + }; + export type IssuesGetForOrgParams = + & { + org: string; + filter?: "all"|"assigned"|"created"|"mentioned"|"subscribed"; + state?: "open"|"closed"|"all"; + labels?: string; + sort?: "created"|"updated"|"comments"; + direction?: "asc"|"desc"; + since?: date; + page?: number; + per_page?: number; + }; + export type IssuesGetForRepoParams = + & { + owner: string; + repo: string; + milestone?: string; + state?: "open"|"closed"|"all"; + assignee?: string; + creator?: string; + mentioned?: string; + labels?: string; + sort?: "created"|"updated"|"comments"; + direction?: "asc"|"desc"; + since?: date; + page?: number; + per_page?: number; + }; + export type IssuesGetAssigneesParams = + & { + owner: string; + repo: string; + }; + export type IssuesCheckAssigneeParams = + & { + owner: string; + repo: string; + assignee: string; + }; + export type IssuesAddAssigneesToIssueParams = + & { + owner: string; + repo: string; + number: number; + assignees: string[]; + }; + export type IssuesRemoveAssigneesFromIssueParams = + & { + owner: string; + repo: string; + number: number; + body: json; + }; + export type IssuesGetCommentsParams = + & { + owner: string; + repo: string; + number: number; + since?: date; + page?: number; + per_page?: number; + }; + export type IssuesGetCommentsForRepoParams = + & { + owner: string; + repo: string; + sort?: "created"|"updated"; + direction?: "asc"|"desc"; + since?: date; + page?: number; + per_page?: number; + }; + export type IssuesGetCommentParams = + & { + owner: string; + repo: string; + id: string; + }; + export type IssuesCreateCommentParams = + & { + owner: string; + repo: string; + number: number; + body: string; + }; + export type IssuesEditCommentParams = + & { + owner: string; + repo: string; + id: string; + body: string; + }; + export type IssuesDeleteCommentParams = + & { + owner: string; + repo: string; + id: string; + }; + export type IssuesGetEventsParams = + & { + owner: string; + repo: string; + issue_number: number; + page?: number; + per_page?: number; + }; + export type IssuesGetEventsForRepoParams = + & { + owner: string; + repo: string; + page?: number; + per_page?: number; + }; + export type IssuesGetEventParams = + & { + owner: string; + repo: string; + id: string; + }; + export type IssuesGetLabelsParams = + & { + owner: string; + repo: string; + page?: number; + per_page?: number; + }; + export type IssuesGetLabelParams = + & { + owner: string; + repo: string; + name: string; + }; + export type IssuesCreateLabelParams = + & { + owner: string; + repo: string; + name: string; + color: string; + }; + export type IssuesUpdateLabelParams = + & { + owner: string; + repo: string; + oldname: string; + name: string; + color: string; + }; + export type IssuesDeleteLabelParams = + & { + owner: string; + repo: string; + name: string; + }; + export type IssuesGetIssueLabelsParams = + & { + owner: string; + repo: string; + number: number; + }; + export type IssuesAddLabelsParams = + & { + owner: string; + repo: string; + number: number; + labels: string[]; + }; + export type IssuesRemoveLabelParams = + & { + owner: string; + repo: string; + number: number; + name: string; + }; + export type IssuesReplaceAllLabelsParams = + & { + owner: string; + repo: string; + number: number; + labels: string[]; + }; + export type IssuesRemoveAllLabelsParams = + & { + owner: string; + repo: string; + number: number; + }; + export type IssuesGetMilestoneLabelsParams = + & { + owner: string; + repo: string; + number: number; + }; + export type IssuesGetMilestonesParams = + & { + owner: string; + repo: string; + state?: "open"|"closed"|"all"; + sort?: "due_on"|"completeness"; + direction?: "asc"|"desc"; + page?: number; + per_page?: number; + }; + export type IssuesGetMilestoneParams = + & { + owner: string; + repo: string; + number: number; + }; + export type IssuesCreateMilestoneParams = + & { + owner: string; + repo: string; + title: string; + state?: "open"|"closed"|"all"; + description?: string; + due_on?: date; + }; + export type IssuesUpdateMilestoneParams = + & { + owner: string; + repo: string; + number: number; + title: string; + state?: "open"|"closed"|"all"; + description?: string; + due_on?: date; + }; + export type IssuesDeleteMilestoneParams = + & { + owner: string; + repo: string; + number: number; + }; + export type IssuesGetEventsTimelineParams = + & { + owner: string; + repo: string; + issue_number: number; + page?: number; + per_page?: number; + }; + export type MigrationsStartMigrationParams = + & { + org: string; + repositories: string[]; + lock_repositories?: boolean; + exclude_attachments?: boolean; + }; + export type MigrationsGetMigrationsParams = + & { + org: string; + page?: number; + per_page?: number; + }; + export type MigrationsGetMigrationStatusParams = + & { + org: string; + id: string; + }; + export type MigrationsGetMigrationArchiveLinkParams = + & { + org: string; + id: string; + }; + export type MigrationsDeleteMigrationArchiveParams = + & { + org: string; + id: string; + }; + export type MigrationsUnlockRepoLockedForMigrationParams = + & { + org: string; + id: string; + repo_name: string; + }; + export type MigrationsStartImportParams = + & { + owner: string; + repo: string; + vcs_url: string; + vcs?: "subversion"|"git"|"mercurial"|"tfvc"; + vcs_username?: string; + vcs_password?: string; + tfvc_project?: string; + }; + export type MigrationsGetImportProgressParams = + & { + owner: string; + repo: string; + }; + export type MigrationsUpdateImportParams = + & { + owner: string; + repo: string; + vcs_username?: string; + vcs_password?: string; + }; + export type MigrationsGetImportCommitAuthorsParams = + & { + owner: string; + repo: string; + since?: string; + }; + export type MigrationsMapImportCommitAuthorParams = + & { + owner: string; + repo: string; + author_id: string; + email?: string; + name?: string; + }; + export type MigrationsSetImportLfsPreferenceParams = + & { + owner: string; + name: string; + use_lfs: string; + }; + export type MigrationsGetLargeImportFilesParams = + & { + owner: string; + name: string; + }; + export type MigrationsCancelImportParams = + & { + owner: string; + repo: string; + }; + export type MiscGetCodeOfConductParams = + & { + key: string; + }; + export type MiscGetRepoCodeOfConductParams = + & { + owner: string; + repo: string; + }; + export type MiscGetGitignoreTemplateParams = + & { + name: string; + }; + export type MiscGetLicenseParams = + & { + license: string; + }; + export type MiscGetRepoLicenseParams = + & { + owner: string; + repo: string; + }; + export type MiscRenderMarkdownParams = + & { + text: string; + mode?: "markdown"|"gfm"; + context?: string; + }; + export type MiscRenderMarkdownRawParams = + & { + data: string; + }; + export type OrgsGetParams = + & { + org: string; + page?: number; + per_page?: number; + }; + export type OrgsUpdateParams = + & { + org: string; + billing_email?: string; + company?: string; + email?: string; + location?: string; + name?: string; + description?: string; + default_repository_permission?: "read"|"write"|"admin"|"none"; + members_can_create_repositories?: boolean; + }; + export type OrgsGetAllParams = + & { + since?: string; + page?: number; + per_page?: number; + }; + export type OrgsGetForUserParams = + & { + username: string; + page?: number; + per_page?: number; + }; + export type OrgsGetMembersParams = + & { + org: string; + filter?: "all"|"2fa_disabled"; + role?: "all"|"admin"|"member"; + page?: number; + per_page?: number; + }; + export type OrgsCheckMembershipParams = + & { + org: string; + username: string; + }; + export type OrgsRemoveMemberParams = + & { + org: string; + username: string; + }; + export type OrgsGetPublicMembersParams = + & { + org: string; + }; + export type OrgsCheckPublicMembershipParams = + & { + org: string; + username: string; + }; + export type OrgsPublicizeMembershipParams = + & { + org: string; + username: string; + }; + export type OrgsConcealMembershipParams = + & { + org: string; + username: string; + }; + export type OrgsGetOrgMembershipParams = + & { + org: string; + username: string; + }; + export type OrgsAddOrgMembershipParams = + & { + org: string; + username: string; + role: "admin"|"member"; + }; + export type OrgsRemoveOrgMembershipParams = + & { + org: string; + username: string; + }; + export type OrgsGetPendingOrgInvitesParams = + & { + org: string; + }; + export type OrgsGetOutsideCollaboratorsParams = + & { + org: string; + filter?: "all"|"2fa_disabled"; + page?: number; + per_page?: number; + }; + export type OrgsRemoveOutsideCollaboratorParams = + & { + org: string; + username: string; + }; + export type OrgsConvertMemberToOutsideCollaboratorParams = + & { + org: string; + username: string; + }; + export type OrgsGetTeamsParams = + & { + org: string; + page?: number; + per_page?: number; + }; + export type OrgsGetTeamParams = + & { + id: string; + }; + export type OrgsCreateTeamParams = + & { + org: string; + name: string; + description?: string; + maintainers?: string[]; + repo_names?: string[]; + privacy?: "secret"|"closed"; + parent_team_id?: string; + }; + export type OrgsEditTeamParams = + & { + id: string; + name: string; + description?: string; + privacy?: "secret"|"closed"; + parent_team_id?: string; + }; + export type OrgsDeleteTeamParams = + & { + id: string; + }; + export type OrgsGetTeamMembersParams = + & { + id: string; + role?: "member"|"maintainer"|"all"; + page?: number; + per_page?: number; + }; + export type OrgsGetChildTeamsParams = + & { + id: string; + page?: number; + per_page?: number; + }; + export type OrgsGetTeamMembershipParams = + & { + id: string; + username: string; + }; + export type OrgsAddTeamMembershipParams = + & { + id: string; + username: string; + role?: "member"|"maintainer"; + }; + export type OrgsRemoveTeamMembershipParams = + & { + id: string; + username: string; + }; + export type OrgsGetTeamReposParams = + & { + id: string; + page?: number; + per_page?: number; + }; + export type OrgsGetPendingTeamInvitesParams = + & { + id: string; + page?: number; + per_page?: number; + }; + export type OrgsCheckTeamRepoParams = + & { + id: string; + owner: string; + repo: string; + }; + export type OrgsAddTeamRepoParams = + & { + id: string; + org: string; + repo: string; + permission?: "pull"|"push"|"admin"; + }; + export type OrgsDeleteTeamRepoParams = + & { + id: string; + owner: string; + repo: string; + }; + export type OrgsGetHooksParams = + & { + org: string; + page?: number; + per_page?: number; + }; + export type OrgsGetHookParams = + & { + org: string; + id: string; + }; + export type OrgsCreateHookParams = + & { + org: string; + name: string; + config: json; + events?: string[]; + active?: boolean; + }; + export type OrgsEditHookParams = + & { + org: string; + id: string; + config: json; + events?: string[]; + active?: boolean; + }; + export type OrgsPingHookParams = + & { + org: string; + id: string; + }; + export type OrgsDeleteHookParams = + & { + org: string; + id: string; + }; + export type OrgsGetBlockedUsersParams = + & { + org: string; + page?: number; + per_page?: number; + }; + export type OrgsCheckBlockedUserParams = + & { + org: string; + username: string; + }; + export type OrgsBlockUserParams = + & { + org: string; + username: string; + }; + export type OrgsUnblockUserParams = + & { + org: string; + username: string; + }; + export type ProjectsGetRepoProjectsParams = + & { + owner: string; + repo: string; + state?: "open"|"closed"|"all"; + }; + export type ProjectsGetOrgProjectsParams = + & { + org: string; + state?: "open"|"closed"|"all"; + }; + export type ProjectsGetProjectParams = + & { + id: string; + }; + export type ProjectsCreateRepoProjectParams = + & { + owner: string; + repo: string; + name: string; + body?: string; + }; + export type ProjectsCreateOrgProjectParams = + & { + org: string; + name: string; + body?: string; + }; + export type ProjectsUpdateProjectParams = + & { + id: string; + name: string; + body?: string; + state?: "open"|"closed"|"all"; + }; + export type ProjectsDeleteProjectParams = + & { + id: string; + }; + export type ProjectsGetProjectCardsParams = + & { + column_id: string; + }; + export type ProjectsGetProjectCardParams = + & { + id: string; + }; + export type ProjectsCreateProjectCardParams = + & { + column_id: string; + note?: string; + content_id?: string; + content_type?: string; + }; + export type ProjectsUpdateProjectCardParams = + & { + id: string; + note?: string; + }; + export type ProjectsDeleteProjectCardParams = + & { + id: string; + }; + export type ProjectsMoveProjectCardParams = + & { + id: string; + position: string; + column_id?: string; + }; + export type ProjectsGetProjectColumnsParams = + & { + project_id: string; + }; + export type ProjectsGetProjectColumnParams = + & { + id: string; + }; + export type ProjectsCreateProjectColumnParams = + & { + project_id: string; + name: string; + }; + export type ProjectsUpdateProjectColumnParams = + & { + id: string; + name: string; + }; + export type ProjectsDeleteProjectColumnParams = + & { + id: string; + }; + export type ProjectsMoveProjectColumnParams = + & { + id: string; + position: string; + }; + export type PullRequestsGetParams = + & { + owner: string; + repo: string; + number: number; + }; + export type PullRequestsCreateParams = + & { + owner: string; + repo: string; + head: string; + base: string; + }; + export type PullRequestsUpdateParams = + & { + owner: string; + repo: string; + number: number; + title?: string; + body?: string; + state?: "open"|"closed"; + base?: string; + maintainer_can_modify?: boolean; + }; + export type PullRequestsMergeParams = + & { + owner: string; + repo: string; + number: number; + commit_title?: string; + commit_message?: string; + sha?: string; + merge_method?: "merge"|"squash"|"rebase"; + }; + export type PullRequestsGetAllParams = + & { + owner: string; + repo: string; + state?: "open"|"closed"|"all"; + head?: string; + base?: string; + sort?: "created"|"updated"|"popularity"|"long-running"; + direction?: "asc"|"desc"; + page?: number; + per_page?: number; + }; + export type PullRequestsCreateFromIssueParams = + & { + owner: string; + repo: string; + issue: number; + head: string; + base: string; + }; + export type PullRequestsGetCommitsParams = + & { + owner: string; + repo: string; + number: number; + page?: number; + per_page?: number; + }; + export type PullRequestsGetFilesParams = + & { + owner: string; + repo: string; + number: number; + page?: number; + per_page?: number; + }; + export type PullRequestsCheckMergedParams = + & { + owner: string; + repo: string; + number: number; + page?: number; + per_page?: number; + }; + export type PullRequestsGetReviewsParams = + & { + owner: string; + repo: string; + number: number; + page?: number; + per_page?: number; + }; + export type PullRequestsGetReviewParams = + & { + owner: string; + repo: string; + number: number; + id: string; + }; + export type PullRequestsDeletePendingReviewParams = + & { + owner: string; + repo: string; + number: number; + id: string; + }; + export type PullRequestsGetReviewCommentsParams = + & { + owner: string; + repo: string; + number: number; + id: string; + page?: number; + per_page?: number; + }; + export type PullRequestsCreateReviewParams = + & { + owner: string; + repo: string; + number: number; + commit_id?: string; + body?: string; + event?: "APPROVE"|"REQUEST_CHANGES"|"COMMENT"|"PENDING"; + comments?: string[]; + }; + export type PullRequestsSubmitReviewParams = + & { + owner: string; + repo: string; + number: number; + id: string; + body?: string; + event?: "APPROVE"|"REQUEST_CHANGES"|"COMMENT"|"PENDING"; + }; + export type PullRequestsDismissReviewParams = + & { + owner: string; + repo: string; + number: number; + id: string; + message?: string; + page?: number; + per_page?: number; + }; + export type PullRequestsGetCommentsParams = + & { + owner: string; + repo: string; + number: number; + page?: number; + per_page?: number; + }; + export type PullRequestsGetCommentsForRepoParams = + & { + owner: string; + repo: string; + sort?: "created"|"updated"; + direction?: "asc"|"desc"; + since?: date; + page?: number; + per_page?: number; + }; + export type PullRequestsGetCommentParams = + & { + owner: string; + repo: string; + id: string; + }; + export type PullRequestsCreateCommentParams = + & { + owner: string; + repo: string; + number: number; + body: string; + }; + export type PullRequestsCreateCommentReplyParams = + & { + owner: string; + repo: string; + number: number; + body: string; + in_reply_to: number; + }; + export type PullRequestsEditCommentParams = + & { + owner: string; + repo: string; + id: string; + body: string; + }; + export type PullRequestsDeleteCommentParams = + & { + owner: string; + repo: string; + id: string; + }; + export type PullRequestsGetReviewRequestsParams = + & { + owner: string; + repo: string; + number: number; + page?: number; + per_page?: number; + }; + export type PullRequestsCreateReviewRequestParams = + & { + owner: string; + repo: string; + number: number; + reviewers?: string[]; + team_reviewers?: string[]; + }; + export type PullRequestsDeleteReviewRequestParams = + & { + owner: string; + repo: string; + number: number; + reviewers?: string[]; + team_reviewers?: string[]; + }; + export type ReactionsDeleteParams = + & { + id: string; + }; + export type ReactionsGetForCommitCommentParams = + & { + owner: string; + repo: string; + id: string; + content?: "+1"|"-1"|"laugh"|"confused"|"heart"|"hooray"; + }; + export type ReactionsCreateForCommitCommentParams = + & { + owner: string; + repo: string; + id: string; + content: "+1"|"-1"|"laugh"|"confused"|"heart"|"hooray"; + }; + export type ReactionsGetForIssueParams = + & { + owner: string; + repo: string; + number: number; + content?: "+1"|"-1"|"laugh"|"confused"|"heart"|"hooray"; + }; + export type ReactionsCreateForIssueParams = + & { + owner: string; + repo: string; + number: number; + content: "+1"|"-1"|"laugh"|"confused"|"heart"|"hooray"; + }; + export type ReactionsGetForIssueCommentParams = + & { + owner: string; + repo: string; + id: string; + content?: "+1"|"-1"|"laugh"|"confused"|"heart"|"hooray"; + }; + export type ReactionsCreateForIssueCommentParams = + & { + owner: string; + repo: string; + id: string; + content: "+1"|"-1"|"laugh"|"confused"|"heart"|"hooray"; + }; + export type ReactionsGetForPullRequestReviewCommentParams = + & { + owner: string; + repo: string; + id: string; + content?: "+1"|"-1"|"laugh"|"confused"|"heart"|"hooray"; + }; + export type ReactionsCreateForPullRequestReviewCommentParams = + & { + owner: string; + repo: string; + id: string; + content: "+1"|"-1"|"laugh"|"confused"|"heart"|"hooray"; + }; + export type ReposCreateParams = + & { + name: string; + description?: string; + homepage?: string; + private?: boolean; + has_issues?: boolean; + has_projects?: boolean; + has_wiki?: boolean; + team_id?: number; + auto_init?: boolean; + gitignore_template?: string; + license_template?: string; + allow_squash_merge?: boolean; + allow_merge_commit?: boolean; + allow_rebase_merge?: boolean; + }; + export type ReposGetParams = + & { + owner: string; + repo: string; + }; + export type ReposEditParams = + & { + owner: string; + repo: string; + name: string; + description?: string; + homepage?: string; + private?: boolean; + has_issues?: boolean; + has_projects?: boolean; + has_wiki?: boolean; + default_branch?: string; + allow_squash_merge?: boolean; + allow_merge_commit?: boolean; + allow_rebase_merge?: boolean; + }; + export type ReposDeleteParams = + & { + owner: string; + repo: string; + }; + export type ReposForkParams = + & { + owner: string; + repo: string; + organization?: string; + }; + export type ReposMergeParams = + & { + owner: string; + repo: string; + base: string; + head: string; + commit_message?: string; + }; + export type ReposGetAllParams = + & { + visibility?: "all"|"public"|"private"; + affiliation?: string; + type?: "all"|"owner"|"public"|"private"|"member"; + sort?: "created"|"updated"|"pushed"|"full_name"; + direction?: "asc"|"desc"; + page?: number; + per_page?: number; + }; + export type ReposGetForUserParams = + & { + username: string; + type?: "all"|"owner"|"member"; + sort?: "created"|"updated"|"pushed"|"full_name"; + direction?: "asc"|"desc"; + page?: number; + per_page?: number; + }; + export type ReposGetForOrgParams = + & { + org: string; + type?: "all"|"public"|"private"|"forks"|"sources"|"member"; + page?: number; + per_page?: number; + }; + export type ReposGetPublicParams = + & { + since?: string; + page?: number; + per_page?: number; + }; + export type ReposCreateForOrgParams = + & { + org: string; + name: string; + description?: string; + homepage?: string; + private?: boolean; + has_issues?: boolean; + has_projects?: boolean; + has_wiki?: boolean; + team_id?: number; + auto_init?: boolean; + gitignore_template?: string; + license_template?: string; + allow_squash_merge?: boolean; + allow_merge_commit?: boolean; + allow_rebase_merge?: boolean; + }; + export type ReposGetByIdParams = + & { + id: string; + }; + export type ReposGetTopicsParams = + & { + owner: string; + repo: string; + page?: number; + per_page?: number; + }; + export type ReposReplaceTopicsParams = + & { + owner: string; + repo: string; + names: string[]; + }; + export type ReposGetContributorsParams = + & { + owner: string; + repo: string; + anon?: boolean; + page?: number; + per_page?: number; + }; + export type ReposGetLanguagesParams = + & { + owner: string; + repo: string; + page?: number; + per_page?: number; + }; + export type ReposGetTeamsParams = + & { + owner: string; + repo: string; + page?: number; + per_page?: number; + }; + export type ReposGetTagsParams = + & { + owner: string; + repo: string; + page?: number; + per_page?: number; + }; + export type ReposGetBranchesParams = + & { + owner: string; + repo: string; + protected?: boolean; + page?: number; + per_page?: number; + }; + export type ReposGetBranchParams = + & { + owner: string; + repo: string; + branch: string; + page?: number; + per_page?: number; + }; + export type ReposGetBranchProtectionParams = + & { + owner: string; + repo: string; + branch: string; + page?: number; + per_page?: number; + }; + export type ReposUpdateBranchProtectionParams = + & { + owner: string; + repo: string; + branch: string; + required_status_checks: json; + required_pull_request_reviews: json; + dismissal_restrictions?: json; + restrictions: json; + enforce_admins: boolean; + page?: number; + per_page?: number; + }; + export type ReposRemoveBranchProtectionParams = + & { + owner: string; + repo: string; + branch: string; + }; + export type ReposGetProtectedBranchRequiredStatusChecksParams = + & { + owner: string; + repo: string; + branch: string; + page?: number; + per_page?: number; + }; + export type ReposUpdateProtectedBranchRequiredStatusChecksParams = + & { + owner: string; + repo: string; + branch: string; + strict?: boolean; + contexts?: string[]; + }; + export type ReposRemoveProtectedBranchRequiredStatusChecksParams = + & { + owner: string; + repo: string; + branch: string; + }; + export type ReposGetProtectedBranchRequiredStatusChecksContextsParams = + & { + owner: string; + repo: string; + branch: string; + page?: number; + per_page?: number; + }; + export type ReposReplaceProtectedBranchRequiredStatusChecksContextsParams = + & { + owner: string; + repo: string; + branch: string; + contexts: string[]; + }; + export type ReposAddProtectedBranchRequiredStatusChecksContextsParams = + & { + owner: string; + repo: string; + branch: string; + contexts: string[]; + }; + export type ReposRemoveProtectedBranchRequiredStatusChecksContextsParams = + & { + owner: string; + repo: string; + branch: string; + contexts: string[]; + }; + export type ReposGetProtectedBranchPullRequestReviewEnforcementParams = + & { + owner: string; + repo: string; + branch: string; + page?: number; + per_page?: number; + }; + export type ReposUpdateProtectedBranchPullRequestReviewEnforcementParams = + & { + owner: string; + repo: string; + branch: string; + dismissal_restrictions?: json; + dismiss_stale_reviews?: boolean; + require_code_owner_reviews?: boolean; + }; + export type ReposRemoveProtectedBranchPullRequestReviewEnforcementParams = + & { + owner: string; + repo: string; + branch: string; + }; + export type ReposGetProtectedBranchAdminEnforcementParams = + & { + owner: string; + repo: string; + branch: string; + page?: number; + per_page?: number; + }; + export type ReposAddProtectedBranchAdminEnforcementParams = + & { + owner: string; + repo: string; + branch: string; + page?: number; + per_page?: number; + }; + export type ReposRemoveProtectedBranchAdminEnforcementParams = + & { + owner: string; + repo: string; + branch: string; + }; + export type ReposGetProtectedBranchRestrictionsParams = + & { + owner: string; + repo: string; + branch: string; + page?: number; + per_page?: number; + }; + export type ReposRemoveProtectedBranchRestrictionsParams = + & { + owner: string; + repo: string; + branch: string; + }; + export type ReposGetProtectedBranchTeamRestrictionsParams = + & { + owner: string; + repo: string; + branch: string; + page?: number; + per_page?: number; + }; + export type ReposReplaceProtectedBranchTeamRestrictionsParams = + & { + owner: string; + repo: string; + branch: string; + teams: string[]; + }; + export type ReposAddProtectedBranchTeamRestrictionsParams = + & { + owner: string; + repo: string; + branch: string; + teams: string[]; + }; + export type ReposRemoveProtectedBranchTeamRestrictionsParams = + & { + owner: string; + repo: string; + branch: string; + teams: string[]; + }; + export type ReposGetProtectedBranchUserRestrictionsParams = + & { + owner: string; + repo: string; + branch: string; + page?: number; + per_page?: number; + }; + export type ReposReplaceProtectedBranchUserRestrictionsParams = + & { + owner: string; + repo: string; + branch: string; + users: string[]; + }; + export type ReposAddProtectedBranchUserRestrictionsParams = + & { + owner: string; + repo: string; + branch: string; + users: string[]; + }; + export type ReposRemoveProtectedBranchUserRestrictionsParams = + & { + owner: string; + repo: string; + branch: string; + users: string[]; + }; + export type ReposGetCollaboratorsParams = + & { + owner: string; + repo: string; + affiliation?: "outside"|"all"|"direct"; + page?: number; + per_page?: number; + }; + export type ReposCheckCollaboratorParams = + & { + owner: string; + repo: string; + username: string; + }; + export type ReposReviewUserPermissionLevelParams = + & { + owner: string; + repo: string; + username: string; + }; + export type ReposAddCollaboratorParams = + & { + owner: string; + repo: string; + username: string; + permission?: "pull"|"push"|"admin"; + }; + export type ReposRemoveCollaboratorParams = + & { + owner: string; + repo: string; + username: string; + }; + export type ReposGetAllCommitCommentsParams = + & { + owner: string; + repo: string; + page?: number; + per_page?: number; + }; + export type ReposGetCommitCommentsParams = + & { + owner: string; + repo: string; + ref: string; + page?: number; + per_page?: number; + }; + export type ReposCreateCommitCommentParams = + & { + owner: string; + repo: string; + sha: string; + body: string; + path?: string; + position?: number; + }; + export type ReposGetCommitCommentParams = + & { + owner: string; + repo: string; + id: string; + }; + export type ReposUpdateCommitCommentParams = + & { + owner: string; + repo: string; + id: string; + body: string; + }; + export type ReposDeleteCommitCommentParams = + & { + owner: string; + repo: string; + id: string; + }; + export type ReposGetCommunityProfileMetricsParams = + & { + owner: string; + name: string; + }; + export type ReposGetCommitsParams = + & { + owner: string; + repo: string; + sha?: string; + path?: string; + author?: string; + since?: date; + until?: date; + page?: number; + per_page?: number; + }; + export type ReposGetCommitParams = + & { + owner: string; + repo: string; + sha: string; + }; + export type ReposGetShaOfCommitRefParams = + & { + owner: string; + repo: string; + ref: string; + }; + export type ReposCompareCommitsParams = + & { + owner: string; + repo: string; + base: string; + head: string; + }; + export type ReposGetReadmeParams = + & { + owner: string; + repo: string; + ref?: string; + }; + export type ReposGetContentParams = + & { + owner: string; + repo: string; + path: string; + ref?: string; + }; + export type ReposCreateFileParams = + & { + owner: string; + repo: string; + path: string; + message: string; + content: string; + branch?: string; + committer?: json; + author?: json; + }; + export type ReposUpdateFileParams = + & { + owner: string; + repo: string; + path: string; + message: string; + content: string; + sha: string; + branch?: string; + committer?: json; + author?: json; + }; + export type ReposDeleteFileParams = + & { + owner: string; + repo: string; + path: string; + message: string; + sha: string; + branch?: string; + committer?: json; + author?: json; + }; + export type ReposGetArchiveLinkParams = + & { + owner: string; + repo: string; + archive_format: "tarball"|"zipball"; + ref?: string; + }; + export type ReposGetDeployKeysParams = + & { + owner: string; + repo: string; + page?: number; + per_page?: number; + }; + export type ReposGetDeployKeyParams = + & { + owner: string; + repo: string; + id: string; + }; + export type ReposAddDeployKeyParams = + & { + owner: string; + repo: string; + title: string; + key: string; + read_only?: boolean; + }; + export type ReposDeleteDeployKeyParams = + & { + owner: string; + repo: string; + id: string; + }; + export type ReposGetDeploymentsParams = + & { + owner: string; + repo: string; + sha?: string; + ref?: string; + task?: string; + environment?: string; + page?: number; + per_page?: number; + }; + export type ReposGetDeploymentParams = + & { + owner: string; + repo: string; + deployment_id: string; + }; + export type ReposCreateDeploymentParams = + & { + owner: string; + repo: string; + ref: string; + task?: string; + auto_merge?: boolean; + required_contexts?: string[]; + payload?: string; + environment?: string; + description?: string; + transient_environment?: boolean; + production_environment?: boolean; + }; + export type ReposGetDeploymentStatusesParams = + & { + owner: string; + repo: string; + id: string; + }; + export type ReposGetDeploymentStatusParams = + & { + owner: string; + repo: string; + id: string; + status_id: string; + }; + export type ReposCreateDeploymentStatusParams = + & { + owner: string; + repo: string; + id: string; + state?: string; + target_url?: string; + log_url?: string; + description?: string; + environment_url?: string; + auto_inactive?: boolean; + }; + export type ReposGetDownloadsParams = + & { + owner: string; + repo: string; + page?: number; + per_page?: number; + }; + export type ReposGetDownloadParams = + & { + owner: string; + repo: string; + id: string; + }; + export type ReposDeleteDownloadParams = + & { + owner: string; + repo: string; + id: string; + }; + export type ReposGetForksParams = + & { + owner: string; + repo: string; + sort?: "newest"|"oldest"|"stargazers"; + page?: number; + per_page?: number; + }; + export type ReposGetInvitesParams = + & { + owner: string; + repo: string; + }; + export type ReposDeleteInviteParams = + & { + owner: string; + repo: string; + invitation_id: string; + }; + export type ReposUpdateInviteParams = + & { + owner: string; + repo: string; + invitation_id: string; + permissions?: "read"|"write"|"admin"; + }; + export type ReposGetPagesParams = + & { + owner: string; + repo: string; + page?: number; + per_page?: number; + }; + export type ReposRequestPageBuildParams = + & { + owner: string; + repo: string; + }; + export type ReposGetPagesBuildsParams = + & { + owner: string; + repo: string; + page?: number; + per_page?: number; + }; + export type ReposGetLatestPagesBuildParams = + & { + owner: string; + repo: string; + }; + export type ReposGetPagesBuildParams = + & { + owner: string; + repo: string; + id: string; + }; + export type ReposGetReleasesParams = + & { + owner: string; + repo: string; + page?: number; + per_page?: number; + }; + export type ReposGetReleaseParams = + & { + owner: string; + repo: string; + id: string; + }; + export type ReposGetLatestReleaseParams = + & { + owner: string; + repo: string; + }; + export type ReposGetReleaseByTagParams = + & { + owner: string; + repo: string; + tag: string; + }; + export type ReposCreateReleaseParams = + & { + owner: string; + repo: string; + tag_name: string; + target_commitish?: string; + name?: string; + body?: string; + draft?: boolean; + prerelease?: boolean; + }; + export type ReposEditReleaseParams = + & { + owner: string; + repo: string; + id: string; + tag_name: string; + target_commitish?: string; + name?: string; + body?: string; + draft?: boolean; + prerelease?: boolean; + }; + export type ReposDeleteReleaseParams = + & { + owner: string; + repo: string; + id: string; + }; + export type ReposGetAssetsParams = + & { + owner: string; + repo: string; + id: string; + }; + export type ReposUploadAssetParams = + & { + url: string; + file: string | object; + contentType: string; + contentLength: number; + name: string; + label?: string; + }; + export type ReposGetAssetParams = + & { + owner: string; + repo: string; + id: string; + }; + export type ReposEditAssetParams = + & { + owner: string; + repo: string; + id: string; + name: string; + label?: string; + }; + export type ReposDeleteAssetParams = + & { + owner: string; + repo: string; + id: string; + }; + export type ReposGetStatsContributorsParams = + & { + owner: string; + repo: string; + }; + export type ReposGetStatsCommitActivityParams = + & { + owner: string; + repo: string; + }; + export type ReposGetStatsCodeFrequencyParams = + & { + owner: string; + repo: string; + }; + export type ReposGetStatsParticipationParams = + & { + owner: string; + repo: string; + }; + export type ReposGetStatsPunchCardParams = + & { + owner: string; + repo: string; + }; + export type ReposCreateStatusParams = + & { + owner: string; + repo: string; + sha: string; + state: "pending"|"success"|"error"|"failure"; + target_url?: string; + description?: string; + context?: string; + }; + export type ReposGetStatusesParams = + & { + owner: string; + repo: string; + ref: string; + page?: number; + per_page?: number; + }; + export type ReposGetCombinedStatusForRefParams = + & { + owner: string; + repo: string; + ref: string; + page?: number; + per_page?: number; + }; + export type ReposGetReferrersParams = + & { + owner: string; + repo: string; + page?: number; + per_page?: number; + }; + export type ReposGetPathsParams = + & { + owner: string; + repo: string; + page?: number; + per_page?: number; + }; + export type ReposGetViewsParams = + & { + owner: string; + repo: string; + page?: number; + per_page?: number; + }; + export type ReposGetClonesParams = + & { + owner: string; + repo: string; + page?: number; + per_page?: number; + }; + export type ReposGetHooksParams = + & { + owner: string; + repo: string; + page?: number; + per_page?: number; + }; + export type ReposGetHookParams = + & { + owner: string; + repo: string; + id: string; + }; + export type ReposCreateHookParams = + & { + owner: string; + repo: string; + name: string; + config: json; + events?: string[]; + active?: boolean; + }; + export type ReposEditHookParams = + & { + owner: string; + repo: string; + id: string; + name: string; + config: json; + events?: string[]; + add_events?: string[]; + remove_events?: string[]; + active?: boolean; + }; + export type ReposTestHookParams = + & { + owner: string; + repo: string; + id: string; + }; + export type ReposPingHookParams = + & { + owner: string; + repo: string; + id: string; + }; + export type ReposDeleteHookParams = + & { + owner: string; + repo: string; + id: string; + }; + export type SearchReposParams = + & { + q: string; + sort?: "stars"|"forks"|"updated"; + order?: "asc"|"desc"; + page?: number; + per_page?: number; + }; + export type SearchCodeParams = + & { + q: string; + sort?: "indexed"; + order?: "asc"|"desc"; + page?: number; + per_page?: number; + }; + export type SearchCommitsParams = + & { + q: string; + sort?: "author-date"|"committer-date"; + order?: "asc"|"desc"; + page?: number; + per_page?: number; + }; + export type SearchIssuesParams = + & { + q: string; + sort?: "comments"|"created"|"updated"; + order?: "asc"|"desc"; + page?: number; + per_page?: number; + }; + export type SearchUsersParams = + & { + q: string; + sort?: "followers"|"repositories"|"joined"; + order?: "asc"|"desc"; + page?: number; + per_page?: number; + }; + export type SearchEmailParams = + & { + email: string; + }; + export type UsersUpdateParams = + & { + name?: string; + email?: string; + blog?: string; + company?: string; + location?: string; + hireable?: boolean; + bio?: string; + }; + export type UsersPromoteParams = + & { + username: string; + }; + export type UsersDemoteParams = + & { + username: string; + }; + export type UsersSuspendParams = + & { + username: string; + }; + export type UsersUnsuspendParams = + & { + username: string; + }; + export type UsersGetForUserParams = + & { + username: string; + }; + export type UsersGetByIdParams = + & { + id: string; + }; + export type UsersGetAllParams = + & { + since?: number; + }; + export type UsersGetOrgsParams = + & { + page?: number; + per_page?: number; + }; + export type UsersGetOrgMembershipsParams = + & { + state?: "active"|"pending"; + }; + export type UsersGetOrgMembershipParams = + & { + org: string; + }; + export type UsersEditOrgMembershipParams = + & { + org: string; + state: "active"; + }; + export type UsersGetTeamsParams = + & { + page?: number; + per_page?: number; + }; + export type UsersGetEmailsParams = + & { + page?: number; + per_page?: number; + }; + export type UsersGetPublicEmailsParams = + & { + page?: number; + per_page?: number; + }; + export type UsersAddEmailsParams = + & { + emails: string[]; + }; + export type UsersDeleteEmailsParams = + & { + emails: string[]; + }; + export type UsersGetFollowersForUserParams = + & { + username: string; + page?: number; + per_page?: number; + }; + export type UsersGetFollowersParams = + & { + page?: number; + per_page?: number; + }; + export type UsersGetFollowingForUserParams = + & { + username: string; + page?: number; + per_page?: number; + }; + export type UsersGetFollowingParams = + & { + page?: number; + per_page?: number; + }; + export type UsersCheckFollowingParams = + & { + username: string; + }; + export type UsersCheckIfOneFollowersOtherParams = + & { + username: string; + target_user: string; + }; + export type UsersFollowUserParams = + & { + username: string; + }; + export type UsersUnfollowUserParams = + & { + username: string; + }; + export type UsersGetKeysForUserParams = + & { + username: string; + page?: number; + per_page?: number; + }; + export type UsersGetKeysParams = + & { + page?: number; + per_page?: number; + }; + export type UsersGetKeyParams = + & { + id: string; + }; + export type UsersCreateKeyParams = + & { + title: string; + key: string; + }; + export type UsersDeleteKeyParams = + & { + id: string; + }; + export type UsersGetGpgKeysForUserParams = + & { + username: string; + page?: number; + per_page?: number; + }; + export type UsersGetGpgKeysParams = + & { + page?: number; + per_page?: number; + }; + export type UsersGetGpgKeyParams = + & { + id: string; + }; + export type UsersCreateGpgKeyParams = + & { + armored_public_key: string; + }; + export type UsersDeleteGpgKeyParams = + & { + id: string; + }; + export type UsersCheckBlockedUserParams = + & { + username: string; + }; + export type UsersBlockUserParams = + & { + username: string; + }; + export type UsersUnblockUserParams = + & { + username: string; + }; + export type UsersAcceptRepoInviteParams = + & { + invitation_id: string; + }; + export type UsersDeclineRepoInviteParams = + & { + invitation_id: string; + }; + export type UsersGetInstallationsParams = + & { + page?: number; + per_page?: number; + }; + export type UsersGetInstallationReposParams = + & { + installation_id: string; + page?: number; + per_page?: number; + }; + export type UsersAddRepoToInstallationParams = + & { + installation_id: string; + repository_id: string; + }; + export type UsersRemoveRepoFromInstallationParams = + & { + installation_id: string; + repository_id: string; + }; + export type UsersGetMarketplacePurchasesParams = + & { + page?: number; + per_page?: number; + }; + export type UsersGetMarketplaceStubbedPurchasesParams = + & { + page?: number; + per_page?: number; + }; + export type EnterpriseStatsParams = + & { + type: "issues"|"hooks"|"milestones"|"orgs"|"comments"|"pages"|"users"|"gists"|"pulls"|"repos"|"all"; + }; + export type EnterpriseUpdateLdapForUserParams = + & { + username: string; + ldap_dn: string; + }; + export type EnterpriseSyncLdapForUserParams = + & { + username: string; + }; + export type EnterpriseUpdateLdapForTeamParams = + & { + team_id: number; + ldap_dn: string; + }; + export type EnterpriseSyncLdapForTeamParams = + & { + team_id: number; + }; + export type EnterpriseGetPreReceiveEnvironmentParams = + & { + id: string; + }; + export type EnterpriseCreatePreReceiveEnvironmentParams = + & { + name: string; + image_url: string; + }; + export type EnterpriseEditPreReceiveEnvironmentParams = + & { + id: string; + name: string; + image_url: string; + }; + export type EnterpriseDeletePreReceiveEnvironmentParams = + & { + id: string; + }; + export type EnterpriseGetPreReceiveEnvironmentDownloadStatusParams = + & { + id: string; + }; + export type EnterpriseTriggerPreReceiveEnvironmentDownloadParams = + & { + id: string; + }; + export type EnterpriseGetPreReceiveHookParams = + & { + id: string; + }; + export type EnterpriseCreatePreReceiveHookParams = + & { + name: string; + script: string; + script_repository: json; + environment: json; + enforcement?: string; + allow_downstream_configuration?: boolean; + }; + export type EnterpriseEditPreReceiveHookParams = + & { + id: string; + hook: json; + }; + export type EnterpriseDeletePreReceiveHookParams = + & { + id: string; + }; + export type EnterpriseQueueIndexingJobParams = + & { + target: string; + }; + export type EnterpriseCreateOrgParams = + & { + login: string; + admin: string; + profile_name?: string; + }; +} + +declare class Github { + constructor(options?: Github.Options); + authenticate(auth: Github.Auth): void; + hasNextPage(link: Github.Link): string | undefined; + hasPreviousPage(link: Github.Link): string | undefined; + hasLastPage(link: Github.Link): string | undefined; + hasFirstPage(link: Github.Link): string | undefined; + + getNextPage(link: Github.Link, callback?: Github.Callback): Promise; + getNextPage(link: Github.Link, headers?: {[header: string]: any}, callback?: Github.Callback): Promise; + + getPreviousPage(link: Github.Link, callback?: Github.Callback): Promise; + getPreviousPage(link: Github.Link, headers?: {[header: string]: any}, callback?: Github.Callback): Promise; + + getLastPage(link: Github.Link, callback?: Github.Callback): Promise; + getLastPage(link: Github.Link, headers?: {[header: string]: any}, callback?: Github.Callback): Promise; + + getFirstPage(link: Github.Link, callback?: Github.Callback): Promise; + getFirstPage(link: Github.Link, headers?: {[header: string]: any}, callback?: Github.Callback): Promise; + + authorization: { + get(params: Github.AuthorizationGetParams, callback?: Github.Callback): Promise; + create(params: Github.AuthorizationCreateParams, callback?: Github.Callback): Promise; + update(params: Github.AuthorizationUpdateParams, callback?: Github.Callback): Promise; + delete(params: Github.AuthorizationDeleteParams, callback?: Github.Callback): Promise; + check(params: Github.AuthorizationCheckParams, callback?: Github.Callback): Promise; + reset(params: Github.AuthorizationResetParams, callback?: Github.Callback): Promise; + revoke(params: Github.AuthorizationRevokeParams, callback?: Github.Callback): Promise; + getGrants(params: Github.AuthorizationGetGrantsParams, callback?: Github.Callback): Promise; + getGrant(params: Github.AuthorizationGetGrantParams, callback?: Github.Callback): Promise; + deleteGrant(params: Github.AuthorizationDeleteGrantParams, callback?: Github.Callback): Promise; + getAll(params: Github.AuthorizationGetAllParams, callback?: Github.Callback): Promise; + getOrCreateAuthorizationForApp(params: Github.AuthorizationGetOrCreateAuthorizationForAppParams, callback?: Github.Callback): Promise; + getOrCreateAuthorizationForAppAndFingerprint(params: Github.AuthorizationGetOrCreateAuthorizationForAppAndFingerprintParams, callback?: Github.Callback): Promise; + revokeGrant(params: Github.AuthorizationRevokeGrantParams, callback?: Github.Callback): Promise; + }; + activity: { + getEvents(params: Github.ActivityGetEventsParams, callback?: Github.Callback): Promise; + getEventsForRepo(params: Github.ActivityGetEventsForRepoParams, callback?: Github.Callback): Promise; + getEventsForRepoIssues(params: Github.ActivityGetEventsForRepoIssuesParams, callback?: Github.Callback): Promise; + getEventsForRepoNetwork(params: Github.ActivityGetEventsForRepoNetworkParams, callback?: Github.Callback): Promise; + getEventsForOrg(params: Github.ActivityGetEventsForOrgParams, callback?: Github.Callback): Promise; + getEventsReceived(params: Github.ActivityGetEventsReceivedParams, callback?: Github.Callback): Promise; + getEventsReceivedPublic(params: Github.ActivityGetEventsReceivedPublicParams, callback?: Github.Callback): Promise; + getEventsForUser(params: Github.ActivityGetEventsForUserParams, callback?: Github.Callback): Promise; + getEventsForUserPublic(params: Github.ActivityGetEventsForUserPublicParams, callback?: Github.Callback): Promise; + getEventsForUserOrg(params: Github.ActivityGetEventsForUserOrgParams, callback?: Github.Callback): Promise; + getFeeds(params: Github.EmptyParams, callback?: Github.Callback): Promise; + getNotifications(params: Github.ActivityGetNotificationsParams, callback?: Github.Callback): Promise; + getNotificationsForUser(params: Github.ActivityGetNotificationsForUserParams, callback?: Github.Callback): Promise; + markNotificationsAsRead(params: Github.ActivityMarkNotificationsAsReadParams, callback?: Github.Callback): Promise; + markNotificationsAsReadForRepo(params: Github.ActivityMarkNotificationsAsReadForRepoParams, callback?: Github.Callback): Promise; + getNotificationThread(params: Github.ActivityGetNotificationThreadParams, callback?: Github.Callback): Promise; + markNotificationThreadAsRead(params: Github.ActivityMarkNotificationThreadAsReadParams, callback?: Github.Callback): Promise; + checkNotificationThreadSubscription(params: Github.ActivityCheckNotificationThreadSubscriptionParams, callback?: Github.Callback): Promise; + setNotificationThreadSubscription(params: Github.ActivitySetNotificationThreadSubscriptionParams, callback?: Github.Callback): Promise; + deleteNotificationThreadSubscription(params: Github.ActivityDeleteNotificationThreadSubscriptionParams, callback?: Github.Callback): Promise; + getStargazersForRepo(params: Github.ActivityGetStargazersForRepoParams, callback?: Github.Callback): Promise; + getStarredReposForUser(params: Github.ActivityGetStarredReposForUserParams, callback?: Github.Callback): Promise; + getStarredRepos(params: Github.ActivityGetStarredReposParams, callback?: Github.Callback): Promise; + checkStarringRepo(params: Github.ActivityCheckStarringRepoParams, callback?: Github.Callback): Promise; + starRepo(params: Github.ActivityStarRepoParams, callback?: Github.Callback): Promise; + unstarRepo(params: Github.ActivityUnstarRepoParams, callback?: Github.Callback): Promise; + getWatchersForRepo(params: Github.ActivityGetWatchersForRepoParams, callback?: Github.Callback): Promise; + getWatchedReposForUser(params: Github.ActivityGetWatchedReposForUserParams, callback?: Github.Callback): Promise; + getWatchedRepos(params: Github.ActivityGetWatchedReposParams, callback?: Github.Callback): Promise; + getRepoSubscription(params: Github.ActivityGetRepoSubscriptionParams, callback?: Github.Callback): Promise; + setRepoSubscription(params: Github.ActivitySetRepoSubscriptionParams, callback?: Github.Callback): Promise; + unwatchRepo(params: Github.ActivityUnwatchRepoParams, callback?: Github.Callback): Promise; + }; + gists: { + get(params: Github.GistsGetParams, callback?: Github.Callback): Promise; + create(params: Github.GistsCreateParams, callback?: Github.Callback): Promise; + edit(params: Github.GistsEditParams, callback?: Github.Callback): Promise; + star(params: Github.GistsStarParams, callback?: Github.Callback): Promise; + unstar(params: Github.GistsUnstarParams, callback?: Github.Callback): Promise; + fork(params: Github.GistsForkParams, callback?: Github.Callback): Promise; + delete(params: Github.GistsDeleteParams, callback?: Github.Callback): Promise; + getForUser(params: Github.GistsGetForUserParams, callback?: Github.Callback): Promise; + getAll(params: Github.GistsGetAllParams, callback?: Github.Callback): Promise; + getPublic(params: Github.GistsGetPublicParams, callback?: Github.Callback): Promise; + getStarred(params: Github.GistsGetStarredParams, callback?: Github.Callback): Promise; + getRevision(params: Github.GistsGetRevisionParams, callback?: Github.Callback): Promise; + getCommits(params: Github.GistsGetCommitsParams, callback?: Github.Callback): Promise; + checkStar(params: Github.GistsCheckStarParams, callback?: Github.Callback): Promise; + getForks(params: Github.GistsGetForksParams, callback?: Github.Callback): Promise; + getComments(params: Github.GistsGetCommentsParams, callback?: Github.Callback): Promise; + getComment(params: Github.GistsGetCommentParams, callback?: Github.Callback): Promise; + createComment(params: Github.GistsCreateCommentParams, callback?: Github.Callback): Promise; + editComment(params: Github.GistsEditCommentParams, callback?: Github.Callback): Promise; + deleteComment(params: Github.GistsDeleteCommentParams, callback?: Github.Callback): Promise; + }; + gitdata: { + getBlob(params: Github.GitdataGetBlobParams, callback?: Github.Callback): Promise; + createBlob(params: Github.GitdataCreateBlobParams, callback?: Github.Callback): Promise; + getCommit(params: Github.GitdataGetCommitParams, callback?: Github.Callback): Promise; + createCommit(params: Github.GitdataCreateCommitParams, callback?: Github.Callback): Promise; + getCommitSignatureVerification(params: Github.GitdataGetCommitSignatureVerificationParams, callback?: Github.Callback): Promise; + getReference(params: Github.GitdataGetReferenceParams, callback?: Github.Callback): Promise; + getReferences(params: Github.GitdataGetReferencesParams, callback?: Github.Callback): Promise; + getTags(params: Github.GitdataGetTagsParams, callback?: Github.Callback): Promise; + createReference(params: Github.GitdataCreateReferenceParams, callback?: Github.Callback): Promise; + updateReference(params: Github.GitdataUpdateReferenceParams, callback?: Github.Callback): Promise; + deleteReference(params: Github.GitdataDeleteReferenceParams, callback?: Github.Callback): Promise; + getTag(params: Github.GitdataGetTagParams, callback?: Github.Callback): Promise; + createTag(params: Github.GitdataCreateTagParams, callback?: Github.Callback): Promise; + getTagSignatureVerification(params: Github.GitdataGetTagSignatureVerificationParams, callback?: Github.Callback): Promise; + getTree(params: Github.GitdataGetTreeParams, callback?: Github.Callback): Promise; + createTree(params: Github.GitdataCreateTreeParams, callback?: Github.Callback): Promise; + }; + integrations: { + getInstallations(params: Github.IntegrationsGetInstallationsParams, callback?: Github.Callback): Promise; + createInstallationToken(params: Github.IntegrationsCreateInstallationTokenParams, callback?: Github.Callback): Promise; + getInstallationRepositories(params: Github.IntegrationsGetInstallationRepositoriesParams, callback?: Github.Callback): Promise; + addRepoToInstallation(params: Github.IntegrationsAddRepoToInstallationParams, callback?: Github.Callback): Promise; + removeRepoFromInstallation(params: Github.IntegrationsRemoveRepoFromInstallationParams, callback?: Github.Callback): Promise; + }; + apps: { + get(params: Github.EmptyParams, callback?: Github.Callback): Promise; + getForSlug(params: Github.AppsGetForSlugParams, callback?: Github.Callback): Promise; + getInstallations(params: Github.AppsGetInstallationsParams, callback?: Github.Callback): Promise; + getInstallation(params: Github.AppsGetInstallationParams, callback?: Github.Callback): Promise; + createInstallationToken(params: Github.AppsCreateInstallationTokenParams, callback?: Github.Callback): Promise; + getInstallationRepositories(params: Github.AppsGetInstallationRepositoriesParams, callback?: Github.Callback): Promise; + addRepoToInstallation(params: Github.AppsAddRepoToInstallationParams, callback?: Github.Callback): Promise; + removeRepoFromInstallation(params: Github.AppsRemoveRepoFromInstallationParams, callback?: Github.Callback): Promise; + getMarketplaceListingPlans(params: Github.AppsGetMarketplaceListingPlansParams, callback?: Github.Callback): Promise; + getMarketplaceListingStubbedPlans(params: Github.AppsGetMarketplaceListingStubbedPlansParams, callback?: Github.Callback): Promise; + getMarketplaceListingPlanAccounts(params: Github.AppsGetMarketplaceListingPlanAccountsParams, callback?: Github.Callback): Promise; + getMarketplaceListingStubbedPlanAccounts(params: Github.AppsGetMarketplaceListingStubbedPlanAccountsParams, callback?: Github.Callback): Promise; + checkMarketplaceListingAccount(params: Github.AppsCheckMarketplaceListingAccountParams, callback?: Github.Callback): Promise; + checkMarketplaceListingStubbedAccount(params: Github.AppsCheckMarketplaceListingStubbedAccountParams, callback?: Github.Callback): Promise; + }; + issues: { + get(params: Github.IssuesGetParams, callback?: Github.Callback): Promise; + create(params: Github.IssuesCreateParams, callback?: Github.Callback): Promise; + edit(params: Github.IssuesEditParams, callback?: Github.Callback): Promise; + lock(params: Github.IssuesLockParams, callback?: Github.Callback): Promise; + unlock(params: Github.IssuesUnlockParams, callback?: Github.Callback): Promise; + getAll(params: Github.IssuesGetAllParams, callback?: Github.Callback): Promise; + getForUser(params: Github.IssuesGetForUserParams, callback?: Github.Callback): Promise; + getForOrg(params: Github.IssuesGetForOrgParams, callback?: Github.Callback): Promise; + getForRepo(params: Github.IssuesGetForRepoParams, callback?: Github.Callback): Promise; + getAssignees(params: Github.IssuesGetAssigneesParams, callback?: Github.Callback): Promise; + checkAssignee(params: Github.IssuesCheckAssigneeParams, callback?: Github.Callback): Promise; + addAssigneesToIssue(params: Github.IssuesAddAssigneesToIssueParams, callback?: Github.Callback): Promise; + removeAssigneesFromIssue(params: Github.IssuesRemoveAssigneesFromIssueParams, callback?: Github.Callback): Promise; + getComments(params: Github.IssuesGetCommentsParams, callback?: Github.Callback): Promise; + getCommentsForRepo(params: Github.IssuesGetCommentsForRepoParams, callback?: Github.Callback): Promise; + getComment(params: Github.IssuesGetCommentParams, callback?: Github.Callback): Promise; + createComment(params: Github.IssuesCreateCommentParams, callback?: Github.Callback): Promise; + editComment(params: Github.IssuesEditCommentParams, callback?: Github.Callback): Promise; + deleteComment(params: Github.IssuesDeleteCommentParams, callback?: Github.Callback): Promise; + getEvents(params: Github.IssuesGetEventsParams, callback?: Github.Callback): Promise; + getEventsForRepo(params: Github.IssuesGetEventsForRepoParams, callback?: Github.Callback): Promise; + getEvent(params: Github.IssuesGetEventParams, callback?: Github.Callback): Promise; + getLabels(params: Github.IssuesGetLabelsParams, callback?: Github.Callback): Promise; + getLabel(params: Github.IssuesGetLabelParams, callback?: Github.Callback): Promise; + createLabel(params: Github.IssuesCreateLabelParams, callback?: Github.Callback): Promise; + updateLabel(params: Github.IssuesUpdateLabelParams, callback?: Github.Callback): Promise; + deleteLabel(params: Github.IssuesDeleteLabelParams, callback?: Github.Callback): Promise; + getIssueLabels(params: Github.IssuesGetIssueLabelsParams, callback?: Github.Callback): Promise; + addLabels(params: Github.IssuesAddLabelsParams, callback?: Github.Callback): Promise; + removeLabel(params: Github.IssuesRemoveLabelParams, callback?: Github.Callback): Promise; + replaceAllLabels(params: Github.IssuesReplaceAllLabelsParams, callback?: Github.Callback): Promise; + removeAllLabels(params: Github.IssuesRemoveAllLabelsParams, callback?: Github.Callback): Promise; + getMilestoneLabels(params: Github.IssuesGetMilestoneLabelsParams, callback?: Github.Callback): Promise; + getMilestones(params: Github.IssuesGetMilestonesParams, callback?: Github.Callback): Promise; + getMilestone(params: Github.IssuesGetMilestoneParams, callback?: Github.Callback): Promise; + createMilestone(params: Github.IssuesCreateMilestoneParams, callback?: Github.Callback): Promise; + updateMilestone(params: Github.IssuesUpdateMilestoneParams, callback?: Github.Callback): Promise; + deleteMilestone(params: Github.IssuesDeleteMilestoneParams, callback?: Github.Callback): Promise; + getEventsTimeline(params: Github.IssuesGetEventsTimelineParams, callback?: Github.Callback): Promise; + }; + migrations: { + startMigration(params: Github.MigrationsStartMigrationParams, callback?: Github.Callback): Promise; + getMigrations(params: Github.MigrationsGetMigrationsParams, callback?: Github.Callback): Promise; + getMigrationStatus(params: Github.MigrationsGetMigrationStatusParams, callback?: Github.Callback): Promise; + getMigrationArchiveLink(params: Github.MigrationsGetMigrationArchiveLinkParams, callback?: Github.Callback): Promise; + deleteMigrationArchive(params: Github.MigrationsDeleteMigrationArchiveParams, callback?: Github.Callback): Promise; + unlockRepoLockedForMigration(params: Github.MigrationsUnlockRepoLockedForMigrationParams, callback?: Github.Callback): Promise; + startImport(params: Github.MigrationsStartImportParams, callback?: Github.Callback): Promise; + getImportProgress(params: Github.MigrationsGetImportProgressParams, callback?: Github.Callback): Promise; + updateImport(params: Github.MigrationsUpdateImportParams, callback?: Github.Callback): Promise; + getImportCommitAuthors(params: Github.MigrationsGetImportCommitAuthorsParams, callback?: Github.Callback): Promise; + mapImportCommitAuthor(params: Github.MigrationsMapImportCommitAuthorParams, callback?: Github.Callback): Promise; + setImportLfsPreference(params: Github.MigrationsSetImportLfsPreferenceParams, callback?: Github.Callback): Promise; + getLargeImportFiles(params: Github.MigrationsGetLargeImportFilesParams, callback?: Github.Callback): Promise; + cancelImport(params: Github.MigrationsCancelImportParams, callback?: Github.Callback): Promise; + }; + misc: { + getCodesOfConduct(params: Github.EmptyParams, callback?: Github.Callback): Promise; + getCodeOfConduct(params: Github.MiscGetCodeOfConductParams, callback?: Github.Callback): Promise; + getRepoCodeOfConduct(params: Github.MiscGetRepoCodeOfConductParams, callback?: Github.Callback): Promise; + getEmojis(params: Github.EmptyParams, callback?: Github.Callback): Promise; + getGitignoreTemplates(params: Github.EmptyParams, callback?: Github.Callback): Promise; + getGitignoreTemplate(params: Github.MiscGetGitignoreTemplateParams, callback?: Github.Callback): Promise; + getLicenses(params: Github.EmptyParams, callback?: Github.Callback): Promise; + getLicense(params: Github.MiscGetLicenseParams, callback?: Github.Callback): Promise; + getRepoLicense(params: Github.MiscGetRepoLicenseParams, callback?: Github.Callback): Promise; + renderMarkdown(params: Github.MiscRenderMarkdownParams, callback?: Github.Callback): Promise; + renderMarkdownRaw(params: Github.MiscRenderMarkdownRawParams, callback?: Github.Callback): Promise; + getMeta(params: Github.EmptyParams, callback?: Github.Callback): Promise; + getRateLimit(params: Github.EmptyParams, callback?: Github.Callback): Promise; + }; + orgs: { + get(params: Github.OrgsGetParams, callback?: Github.Callback): Promise; + update(params: Github.OrgsUpdateParams, callback?: Github.Callback): Promise; + getAll(params: Github.OrgsGetAllParams, callback?: Github.Callback): Promise; + getForUser(params: Github.OrgsGetForUserParams, callback?: Github.Callback): Promise; + getMembers(params: Github.OrgsGetMembersParams, callback?: Github.Callback): Promise; + checkMembership(params: Github.OrgsCheckMembershipParams, callback?: Github.Callback): Promise; + removeMember(params: Github.OrgsRemoveMemberParams, callback?: Github.Callback): Promise; + getPublicMembers(params: Github.OrgsGetPublicMembersParams, callback?: Github.Callback): Promise; + checkPublicMembership(params: Github.OrgsCheckPublicMembershipParams, callback?: Github.Callback): Promise; + publicizeMembership(params: Github.OrgsPublicizeMembershipParams, callback?: Github.Callback): Promise; + concealMembership(params: Github.OrgsConcealMembershipParams, callback?: Github.Callback): Promise; + getOrgMembership(params: Github.OrgsGetOrgMembershipParams, callback?: Github.Callback): Promise; + addOrgMembership(params: Github.OrgsAddOrgMembershipParams, callback?: Github.Callback): Promise; + removeOrgMembership(params: Github.OrgsRemoveOrgMembershipParams, callback?: Github.Callback): Promise; + getPendingOrgInvites(params: Github.OrgsGetPendingOrgInvitesParams, callback?: Github.Callback): Promise; + getOutsideCollaborators(params: Github.OrgsGetOutsideCollaboratorsParams, callback?: Github.Callback): Promise; + removeOutsideCollaborator(params: Github.OrgsRemoveOutsideCollaboratorParams, callback?: Github.Callback): Promise; + convertMemberToOutsideCollaborator(params: Github.OrgsConvertMemberToOutsideCollaboratorParams, callback?: Github.Callback): Promise; + getTeams(params: Github.OrgsGetTeamsParams, callback?: Github.Callback): Promise; + getTeam(params: Github.OrgsGetTeamParams, callback?: Github.Callback): Promise; + createTeam(params: Github.OrgsCreateTeamParams, callback?: Github.Callback): Promise; + editTeam(params: Github.OrgsEditTeamParams, callback?: Github.Callback): Promise; + deleteTeam(params: Github.OrgsDeleteTeamParams, callback?: Github.Callback): Promise; + getTeamMembers(params: Github.OrgsGetTeamMembersParams, callback?: Github.Callback): Promise; + getChildTeams(params: Github.OrgsGetChildTeamsParams, callback?: Github.Callback): Promise; + getTeamMembership(params: Github.OrgsGetTeamMembershipParams, callback?: Github.Callback): Promise; + addTeamMembership(params: Github.OrgsAddTeamMembershipParams, callback?: Github.Callback): Promise; + removeTeamMembership(params: Github.OrgsRemoveTeamMembershipParams, callback?: Github.Callback): Promise; + getTeamRepos(params: Github.OrgsGetTeamReposParams, callback?: Github.Callback): Promise; + getPendingTeamInvites(params: Github.OrgsGetPendingTeamInvitesParams, callback?: Github.Callback): Promise; + checkTeamRepo(params: Github.OrgsCheckTeamRepoParams, callback?: Github.Callback): Promise; + addTeamRepo(params: Github.OrgsAddTeamRepoParams, callback?: Github.Callback): Promise; + deleteTeamRepo(params: Github.OrgsDeleteTeamRepoParams, callback?: Github.Callback): Promise; + getHooks(params: Github.OrgsGetHooksParams, callback?: Github.Callback): Promise; + getHook(params: Github.OrgsGetHookParams, callback?: Github.Callback): Promise; + createHook(params: Github.OrgsCreateHookParams, callback?: Github.Callback): Promise; + editHook(params: Github.OrgsEditHookParams, callback?: Github.Callback): Promise; + pingHook(params: Github.OrgsPingHookParams, callback?: Github.Callback): Promise; + deleteHook(params: Github.OrgsDeleteHookParams, callback?: Github.Callback): Promise; + getBlockedUsers(params: Github.OrgsGetBlockedUsersParams, callback?: Github.Callback): Promise; + checkBlockedUser(params: Github.OrgsCheckBlockedUserParams, callback?: Github.Callback): Promise; + blockUser(params: Github.OrgsBlockUserParams, callback?: Github.Callback): Promise; + unblockUser(params: Github.OrgsUnblockUserParams, callback?: Github.Callback): Promise; + }; + projects: { + getRepoProjects(params: Github.ProjectsGetRepoProjectsParams, callback?: Github.Callback): Promise; + getOrgProjects(params: Github.ProjectsGetOrgProjectsParams, callback?: Github.Callback): Promise; + getProject(params: Github.ProjectsGetProjectParams, callback?: Github.Callback): Promise; + createRepoProject(params: Github.ProjectsCreateRepoProjectParams, callback?: Github.Callback): Promise; + createOrgProject(params: Github.ProjectsCreateOrgProjectParams, callback?: Github.Callback): Promise; + updateProject(params: Github.ProjectsUpdateProjectParams, callback?: Github.Callback): Promise; + deleteProject(params: Github.ProjectsDeleteProjectParams, callback?: Github.Callback): Promise; + getProjectCards(params: Github.ProjectsGetProjectCardsParams, callback?: Github.Callback): Promise; + getProjectCard(params: Github.ProjectsGetProjectCardParams, callback?: Github.Callback): Promise; + createProjectCard(params: Github.ProjectsCreateProjectCardParams, callback?: Github.Callback): Promise; + updateProjectCard(params: Github.ProjectsUpdateProjectCardParams, callback?: Github.Callback): Promise; + deleteProjectCard(params: Github.ProjectsDeleteProjectCardParams, callback?: Github.Callback): Promise; + moveProjectCard(params: Github.ProjectsMoveProjectCardParams, callback?: Github.Callback): Promise; + getProjectColumns(params: Github.ProjectsGetProjectColumnsParams, callback?: Github.Callback): Promise; + getProjectColumn(params: Github.ProjectsGetProjectColumnParams, callback?: Github.Callback): Promise; + createProjectColumn(params: Github.ProjectsCreateProjectColumnParams, callback?: Github.Callback): Promise; + updateProjectColumn(params: Github.ProjectsUpdateProjectColumnParams, callback?: Github.Callback): Promise; + deleteProjectColumn(params: Github.ProjectsDeleteProjectColumnParams, callback?: Github.Callback): Promise; + moveProjectColumn(params: Github.ProjectsMoveProjectColumnParams, callback?: Github.Callback): Promise; + }; + pullRequests: { + get(params: Github.PullRequestsGetParams, callback?: Github.Callback): Promise; + create(params: Github.PullRequestsCreateParams, callback?: Github.Callback): Promise; + update(params: Github.PullRequestsUpdateParams, callback?: Github.Callback): Promise; + merge(params: Github.PullRequestsMergeParams, callback?: Github.Callback): Promise; + getAll(params: Github.PullRequestsGetAllParams, callback?: Github.Callback): Promise; + createFromIssue(params: Github.PullRequestsCreateFromIssueParams, callback?: Github.Callback): Promise; + getCommits(params: Github.PullRequestsGetCommitsParams, callback?: Github.Callback): Promise; + getFiles(params: Github.PullRequestsGetFilesParams, callback?: Github.Callback): Promise; + checkMerged(params: Github.PullRequestsCheckMergedParams, callback?: Github.Callback): Promise; + getReviews(params: Github.PullRequestsGetReviewsParams, callback?: Github.Callback): Promise; + getReview(params: Github.PullRequestsGetReviewParams, callback?: Github.Callback): Promise; + deletePendingReview(params: Github.PullRequestsDeletePendingReviewParams, callback?: Github.Callback): Promise; + getReviewComments(params: Github.PullRequestsGetReviewCommentsParams, callback?: Github.Callback): Promise; + createReview(params: Github.PullRequestsCreateReviewParams, callback?: Github.Callback): Promise; + submitReview(params: Github.PullRequestsSubmitReviewParams, callback?: Github.Callback): Promise; + dismissReview(params: Github.PullRequestsDismissReviewParams, callback?: Github.Callback): Promise; + getComments(params: Github.PullRequestsGetCommentsParams, callback?: Github.Callback): Promise; + getCommentsForRepo(params: Github.PullRequestsGetCommentsForRepoParams, callback?: Github.Callback): Promise; + getComment(params: Github.PullRequestsGetCommentParams, callback?: Github.Callback): Promise; + createComment(params: Github.PullRequestsCreateCommentParams, callback?: Github.Callback): Promise; + createCommentReply(params: Github.PullRequestsCreateCommentReplyParams, callback?: Github.Callback): Promise; + editComment(params: Github.PullRequestsEditCommentParams, callback?: Github.Callback): Promise; + deleteComment(params: Github.PullRequestsDeleteCommentParams, callback?: Github.Callback): Promise; + getReviewRequests(params: Github.PullRequestsGetReviewRequestsParams, callback?: Github.Callback): Promise; + createReviewRequest(params: Github.PullRequestsCreateReviewRequestParams, callback?: Github.Callback): Promise; + deleteReviewRequest(params: Github.PullRequestsDeleteReviewRequestParams, callback?: Github.Callback): Promise; + }; + reactions: { + delete(params: Github.ReactionsDeleteParams, callback?: Github.Callback): Promise; + getForCommitComment(params: Github.ReactionsGetForCommitCommentParams, callback?: Github.Callback): Promise; + createForCommitComment(params: Github.ReactionsCreateForCommitCommentParams, callback?: Github.Callback): Promise; + getForIssue(params: Github.ReactionsGetForIssueParams, callback?: Github.Callback): Promise; + createForIssue(params: Github.ReactionsCreateForIssueParams, callback?: Github.Callback): Promise; + getForIssueComment(params: Github.ReactionsGetForIssueCommentParams, callback?: Github.Callback): Promise; + createForIssueComment(params: Github.ReactionsCreateForIssueCommentParams, callback?: Github.Callback): Promise; + getForPullRequestReviewComment(params: Github.ReactionsGetForPullRequestReviewCommentParams, callback?: Github.Callback): Promise; + createForPullRequestReviewComment(params: Github.ReactionsCreateForPullRequestReviewCommentParams, callback?: Github.Callback): Promise; + }; + repos: { + create(params: Github.ReposCreateParams, callback?: Github.Callback): Promise; + get(params: Github.ReposGetParams, callback?: Github.Callback): Promise; + edit(params: Github.ReposEditParams, callback?: Github.Callback): Promise; + delete(params: Github.ReposDeleteParams, callback?: Github.Callback): Promise; + fork(params: Github.ReposForkParams, callback?: Github.Callback): Promise; + merge(params: Github.ReposMergeParams, callback?: Github.Callback): Promise; + getAll(params: Github.ReposGetAllParams, callback?: Github.Callback): Promise; + getForUser(params: Github.ReposGetForUserParams, callback?: Github.Callback): Promise; + getForOrg(params: Github.ReposGetForOrgParams, callback?: Github.Callback): Promise; + getPublic(params: Github.ReposGetPublicParams, callback?: Github.Callback): Promise; + createForOrg(params: Github.ReposCreateForOrgParams, callback?: Github.Callback): Promise; + getById(params: Github.ReposGetByIdParams, callback?: Github.Callback): Promise; + getTopics(params: Github.ReposGetTopicsParams, callback?: Github.Callback): Promise; + replaceTopics(params: Github.ReposReplaceTopicsParams, callback?: Github.Callback): Promise; + getContributors(params: Github.ReposGetContributorsParams, callback?: Github.Callback): Promise; + getLanguages(params: Github.ReposGetLanguagesParams, callback?: Github.Callback): Promise; + getTeams(params: Github.ReposGetTeamsParams, callback?: Github.Callback): Promise; + getTags(params: Github.ReposGetTagsParams, callback?: Github.Callback): Promise; + getBranches(params: Github.ReposGetBranchesParams, callback?: Github.Callback): Promise; + getBranch(params: Github.ReposGetBranchParams, callback?: Github.Callback): Promise; + getBranchProtection(params: Github.ReposGetBranchProtectionParams, callback?: Github.Callback): Promise; + updateBranchProtection(params: Github.ReposUpdateBranchProtectionParams, callback?: Github.Callback): Promise; + removeBranchProtection(params: Github.ReposRemoveBranchProtectionParams, callback?: Github.Callback): Promise; + getProtectedBranchRequiredStatusChecks(params: Github.ReposGetProtectedBranchRequiredStatusChecksParams, callback?: Github.Callback): Promise; + updateProtectedBranchRequiredStatusChecks(params: Github.ReposUpdateProtectedBranchRequiredStatusChecksParams, callback?: Github.Callback): Promise; + removeProtectedBranchRequiredStatusChecks(params: Github.ReposRemoveProtectedBranchRequiredStatusChecksParams, callback?: Github.Callback): Promise; + getProtectedBranchRequiredStatusChecksContexts(params: Github.ReposGetProtectedBranchRequiredStatusChecksContextsParams, callback?: Github.Callback): Promise; + replaceProtectedBranchRequiredStatusChecksContexts(params: Github.ReposReplaceProtectedBranchRequiredStatusChecksContextsParams, callback?: Github.Callback): Promise; + addProtectedBranchRequiredStatusChecksContexts(params: Github.ReposAddProtectedBranchRequiredStatusChecksContextsParams, callback?: Github.Callback): Promise; + removeProtectedBranchRequiredStatusChecksContexts(params: Github.ReposRemoveProtectedBranchRequiredStatusChecksContextsParams, callback?: Github.Callback): Promise; + getProtectedBranchPullRequestReviewEnforcement(params: Github.ReposGetProtectedBranchPullRequestReviewEnforcementParams, callback?: Github.Callback): Promise; + updateProtectedBranchPullRequestReviewEnforcement(params: Github.ReposUpdateProtectedBranchPullRequestReviewEnforcementParams, callback?: Github.Callback): Promise; + removeProtectedBranchPullRequestReviewEnforcement(params: Github.ReposRemoveProtectedBranchPullRequestReviewEnforcementParams, callback?: Github.Callback): Promise; + getProtectedBranchAdminEnforcement(params: Github.ReposGetProtectedBranchAdminEnforcementParams, callback?: Github.Callback): Promise; + addProtectedBranchAdminEnforcement(params: Github.ReposAddProtectedBranchAdminEnforcementParams, callback?: Github.Callback): Promise; + removeProtectedBranchAdminEnforcement(params: Github.ReposRemoveProtectedBranchAdminEnforcementParams, callback?: Github.Callback): Promise; + getProtectedBranchRestrictions(params: Github.ReposGetProtectedBranchRestrictionsParams, callback?: Github.Callback): Promise; + removeProtectedBranchRestrictions(params: Github.ReposRemoveProtectedBranchRestrictionsParams, callback?: Github.Callback): Promise; + getProtectedBranchTeamRestrictions(params: Github.ReposGetProtectedBranchTeamRestrictionsParams, callback?: Github.Callback): Promise; + replaceProtectedBranchTeamRestrictions(params: Github.ReposReplaceProtectedBranchTeamRestrictionsParams, callback?: Github.Callback): Promise; + addProtectedBranchTeamRestrictions(params: Github.ReposAddProtectedBranchTeamRestrictionsParams, callback?: Github.Callback): Promise; + removeProtectedBranchTeamRestrictions(params: Github.ReposRemoveProtectedBranchTeamRestrictionsParams, callback?: Github.Callback): Promise; + getProtectedBranchUserRestrictions(params: Github.ReposGetProtectedBranchUserRestrictionsParams, callback?: Github.Callback): Promise; + replaceProtectedBranchUserRestrictions(params: Github.ReposReplaceProtectedBranchUserRestrictionsParams, callback?: Github.Callback): Promise; + addProtectedBranchUserRestrictions(params: Github.ReposAddProtectedBranchUserRestrictionsParams, callback?: Github.Callback): Promise; + removeProtectedBranchUserRestrictions(params: Github.ReposRemoveProtectedBranchUserRestrictionsParams, callback?: Github.Callback): Promise; + getCollaborators(params: Github.ReposGetCollaboratorsParams, callback?: Github.Callback): Promise; + checkCollaborator(params: Github.ReposCheckCollaboratorParams, callback?: Github.Callback): Promise; + reviewUserPermissionLevel(params: Github.ReposReviewUserPermissionLevelParams, callback?: Github.Callback): Promise; + addCollaborator(params: Github.ReposAddCollaboratorParams, callback?: Github.Callback): Promise; + removeCollaborator(params: Github.ReposRemoveCollaboratorParams, callback?: Github.Callback): Promise; + getAllCommitComments(params: Github.ReposGetAllCommitCommentsParams, callback?: Github.Callback): Promise; + getCommitComments(params: Github.ReposGetCommitCommentsParams, callback?: Github.Callback): Promise; + createCommitComment(params: Github.ReposCreateCommitCommentParams, callback?: Github.Callback): Promise; + getCommitComment(params: Github.ReposGetCommitCommentParams, callback?: Github.Callback): Promise; + updateCommitComment(params: Github.ReposUpdateCommitCommentParams, callback?: Github.Callback): Promise; + deleteCommitComment(params: Github.ReposDeleteCommitCommentParams, callback?: Github.Callback): Promise; + getCommunityProfileMetrics(params: Github.ReposGetCommunityProfileMetricsParams, callback?: Github.Callback): Promise; + getCommits(params: Github.ReposGetCommitsParams, callback?: Github.Callback): Promise; + getCommit(params: Github.ReposGetCommitParams, callback?: Github.Callback): Promise; + getShaOfCommitRef(params: Github.ReposGetShaOfCommitRefParams, callback?: Github.Callback): Promise; + compareCommits(params: Github.ReposCompareCommitsParams, callback?: Github.Callback): Promise; + getReadme(params: Github.ReposGetReadmeParams, callback?: Github.Callback): Promise; + getContent(params: Github.ReposGetContentParams, callback?: Github.Callback): Promise; + createFile(params: Github.ReposCreateFileParams, callback?: Github.Callback): Promise; + updateFile(params: Github.ReposUpdateFileParams, callback?: Github.Callback): Promise; + deleteFile(params: Github.ReposDeleteFileParams, callback?: Github.Callback): Promise; + getArchiveLink(params: Github.ReposGetArchiveLinkParams, callback?: Github.Callback): Promise; + getDeployKeys(params: Github.ReposGetDeployKeysParams, callback?: Github.Callback): Promise; + getDeployKey(params: Github.ReposGetDeployKeyParams, callback?: Github.Callback): Promise; + addDeployKey(params: Github.ReposAddDeployKeyParams, callback?: Github.Callback): Promise; + deleteDeployKey(params: Github.ReposDeleteDeployKeyParams, callback?: Github.Callback): Promise; + getDeployments(params: Github.ReposGetDeploymentsParams, callback?: Github.Callback): Promise; + getDeployment(params: Github.ReposGetDeploymentParams, callback?: Github.Callback): Promise; + createDeployment(params: Github.ReposCreateDeploymentParams, callback?: Github.Callback): Promise; + getDeploymentStatuses(params: Github.ReposGetDeploymentStatusesParams, callback?: Github.Callback): Promise; + getDeploymentStatus(params: Github.ReposGetDeploymentStatusParams, callback?: Github.Callback): Promise; + createDeploymentStatus(params: Github.ReposCreateDeploymentStatusParams, callback?: Github.Callback): Promise; + getDownloads(params: Github.ReposGetDownloadsParams, callback?: Github.Callback): Promise; + getDownload(params: Github.ReposGetDownloadParams, callback?: Github.Callback): Promise; + deleteDownload(params: Github.ReposDeleteDownloadParams, callback?: Github.Callback): Promise; + getForks(params: Github.ReposGetForksParams, callback?: Github.Callback): Promise; + getInvites(params: Github.ReposGetInvitesParams, callback?: Github.Callback): Promise; + deleteInvite(params: Github.ReposDeleteInviteParams, callback?: Github.Callback): Promise; + updateInvite(params: Github.ReposUpdateInviteParams, callback?: Github.Callback): Promise; + getPages(params: Github.ReposGetPagesParams, callback?: Github.Callback): Promise; + requestPageBuild(params: Github.ReposRequestPageBuildParams, callback?: Github.Callback): Promise; + getPagesBuilds(params: Github.ReposGetPagesBuildsParams, callback?: Github.Callback): Promise; + getLatestPagesBuild(params: Github.ReposGetLatestPagesBuildParams, callback?: Github.Callback): Promise; + getPagesBuild(params: Github.ReposGetPagesBuildParams, callback?: Github.Callback): Promise; + getReleases(params: Github.ReposGetReleasesParams, callback?: Github.Callback): Promise; + getRelease(params: Github.ReposGetReleaseParams, callback?: Github.Callback): Promise; + getLatestRelease(params: Github.ReposGetLatestReleaseParams, callback?: Github.Callback): Promise; + getReleaseByTag(params: Github.ReposGetReleaseByTagParams, callback?: Github.Callback): Promise; + createRelease(params: Github.ReposCreateReleaseParams, callback?: Github.Callback): Promise; + editRelease(params: Github.ReposEditReleaseParams, callback?: Github.Callback): Promise; + deleteRelease(params: Github.ReposDeleteReleaseParams, callback?: Github.Callback): Promise; + getAssets(params: Github.ReposGetAssetsParams, callback?: Github.Callback): Promise; + uploadAsset(params: Github.ReposUploadAssetParams, callback?: Github.Callback): Promise; + getAsset(params: Github.ReposGetAssetParams, callback?: Github.Callback): Promise; + editAsset(params: Github.ReposEditAssetParams, callback?: Github.Callback): Promise; + deleteAsset(params: Github.ReposDeleteAssetParams, callback?: Github.Callback): Promise; + getStatsContributors(params: Github.ReposGetStatsContributorsParams, callback?: Github.Callback): Promise; + getStatsCommitActivity(params: Github.ReposGetStatsCommitActivityParams, callback?: Github.Callback): Promise; + getStatsCodeFrequency(params: Github.ReposGetStatsCodeFrequencyParams, callback?: Github.Callback): Promise; + getStatsParticipation(params: Github.ReposGetStatsParticipationParams, callback?: Github.Callback): Promise; + getStatsPunchCard(params: Github.ReposGetStatsPunchCardParams, callback?: Github.Callback): Promise; + createStatus(params: Github.ReposCreateStatusParams, callback?: Github.Callback): Promise; + getStatuses(params: Github.ReposGetStatusesParams, callback?: Github.Callback): Promise; + getCombinedStatusForRef(params: Github.ReposGetCombinedStatusForRefParams, callback?: Github.Callback): Promise; + getReferrers(params: Github.ReposGetReferrersParams, callback?: Github.Callback): Promise; + getPaths(params: Github.ReposGetPathsParams, callback?: Github.Callback): Promise; + getViews(params: Github.ReposGetViewsParams, callback?: Github.Callback): Promise; + getClones(params: Github.ReposGetClonesParams, callback?: Github.Callback): Promise; + getHooks(params: Github.ReposGetHooksParams, callback?: Github.Callback): Promise; + getHook(params: Github.ReposGetHookParams, callback?: Github.Callback): Promise; + createHook(params: Github.ReposCreateHookParams, callback?: Github.Callback): Promise; + editHook(params: Github.ReposEditHookParams, callback?: Github.Callback): Promise; + testHook(params: Github.ReposTestHookParams, callback?: Github.Callback): Promise; + pingHook(params: Github.ReposPingHookParams, callback?: Github.Callback): Promise; + deleteHook(params: Github.ReposDeleteHookParams, callback?: Github.Callback): Promise; + }; + search: { + repos(params: Github.SearchReposParams, callback?: Github.Callback): Promise; + code(params: Github.SearchCodeParams, callback?: Github.Callback): Promise; + commits(params: Github.SearchCommitsParams, callback?: Github.Callback): Promise; + issues(params: Github.SearchIssuesParams, callback?: Github.Callback): Promise; + users(params: Github.SearchUsersParams, callback?: Github.Callback): Promise; + email(params: Github.SearchEmailParams, callback?: Github.Callback): Promise; + }; + users: { + get(params: Github.EmptyParams, callback?: Github.Callback): Promise; + update(params: Github.UsersUpdateParams, callback?: Github.Callback): Promise; + promote(params: Github.UsersPromoteParams, callback?: Github.Callback): Promise; + demote(params: Github.UsersDemoteParams, callback?: Github.Callback): Promise; + suspend(params: Github.UsersSuspendParams, callback?: Github.Callback): Promise; + unsuspend(params: Github.UsersUnsuspendParams, callback?: Github.Callback): Promise; + getForUser(params: Github.UsersGetForUserParams, callback?: Github.Callback): Promise; + getById(params: Github.UsersGetByIdParams, callback?: Github.Callback): Promise; + getAll(params: Github.UsersGetAllParams, callback?: Github.Callback): Promise; + getOrgs(params: Github.UsersGetOrgsParams, callback?: Github.Callback): Promise; + getOrgMemberships(params: Github.UsersGetOrgMembershipsParams, callback?: Github.Callback): Promise; + getOrgMembership(params: Github.UsersGetOrgMembershipParams, callback?: Github.Callback): Promise; + editOrgMembership(params: Github.UsersEditOrgMembershipParams, callback?: Github.Callback): Promise; + getTeams(params: Github.UsersGetTeamsParams, callback?: Github.Callback): Promise; + getEmails(params: Github.UsersGetEmailsParams, callback?: Github.Callback): Promise; + getPublicEmails(params: Github.UsersGetPublicEmailsParams, callback?: Github.Callback): Promise; + addEmails(params: Github.UsersAddEmailsParams, callback?: Github.Callback): Promise; + deleteEmails(params: Github.UsersDeleteEmailsParams, callback?: Github.Callback): Promise; + togglePrimaryEmailVisibility(params: Github.EmptyParams, callback?: Github.Callback): Promise; + getFollowersForUser(params: Github.UsersGetFollowersForUserParams, callback?: Github.Callback): Promise; + getFollowers(params: Github.UsersGetFollowersParams, callback?: Github.Callback): Promise; + getFollowingForUser(params: Github.UsersGetFollowingForUserParams, callback?: Github.Callback): Promise; + getFollowing(params: Github.UsersGetFollowingParams, callback?: Github.Callback): Promise; + checkFollowing(params: Github.UsersCheckFollowingParams, callback?: Github.Callback): Promise; + checkIfOneFollowersOther(params: Github.UsersCheckIfOneFollowersOtherParams, callback?: Github.Callback): Promise; + followUser(params: Github.UsersFollowUserParams, callback?: Github.Callback): Promise; + unfollowUser(params: Github.UsersUnfollowUserParams, callback?: Github.Callback): Promise; + getKeysForUser(params: Github.UsersGetKeysForUserParams, callback?: Github.Callback): Promise; + getKeys(params: Github.UsersGetKeysParams, callback?: Github.Callback): Promise; + getKey(params: Github.UsersGetKeyParams, callback?: Github.Callback): Promise; + createKey(params: Github.UsersCreateKeyParams, callback?: Github.Callback): Promise; + deleteKey(params: Github.UsersDeleteKeyParams, callback?: Github.Callback): Promise; + getGpgKeysForUser(params: Github.UsersGetGpgKeysForUserParams, callback?: Github.Callback): Promise; + getGpgKeys(params: Github.UsersGetGpgKeysParams, callback?: Github.Callback): Promise; + getGpgKey(params: Github.UsersGetGpgKeyParams, callback?: Github.Callback): Promise; + createGpgKey(params: Github.UsersCreateGpgKeyParams, callback?: Github.Callback): Promise; + deleteGpgKey(params: Github.UsersDeleteGpgKeyParams, callback?: Github.Callback): Promise; + getBlockedUsers(params: Github.EmptyParams, callback?: Github.Callback): Promise; + checkBlockedUser(params: Github.UsersCheckBlockedUserParams, callback?: Github.Callback): Promise; + blockUser(params: Github.UsersBlockUserParams, callback?: Github.Callback): Promise; + unblockUser(params: Github.UsersUnblockUserParams, callback?: Github.Callback): Promise; + getRepoInvites(params: Github.EmptyParams, callback?: Github.Callback): Promise; + acceptRepoInvite(params: Github.UsersAcceptRepoInviteParams, callback?: Github.Callback): Promise; + declineRepoInvite(params: Github.UsersDeclineRepoInviteParams, callback?: Github.Callback): Promise; + getInstallations(params: Github.UsersGetInstallationsParams, callback?: Github.Callback): Promise; + getInstallationRepos(params: Github.UsersGetInstallationReposParams, callback?: Github.Callback): Promise; + addRepoToInstallation(params: Github.UsersAddRepoToInstallationParams, callback?: Github.Callback): Promise; + removeRepoFromInstallation(params: Github.UsersRemoveRepoFromInstallationParams, callback?: Github.Callback): Promise; + getMarketplacePurchases(params: Github.UsersGetMarketplacePurchasesParams, callback?: Github.Callback): Promise; + getMarketplaceStubbedPurchases(params: Github.UsersGetMarketplaceStubbedPurchasesParams, callback?: Github.Callback): Promise; + }; + enterprise: { + stats(params: Github.EnterpriseStatsParams, callback?: Github.Callback): Promise; + updateLdapForUser(params: Github.EnterpriseUpdateLdapForUserParams, callback?: Github.Callback): Promise; + syncLdapForUser(params: Github.EnterpriseSyncLdapForUserParams, callback?: Github.Callback): Promise; + updateLdapForTeam(params: Github.EnterpriseUpdateLdapForTeamParams, callback?: Github.Callback): Promise; + syncLdapForTeam(params: Github.EnterpriseSyncLdapForTeamParams, callback?: Github.Callback): Promise; + getLicense(params: Github.EmptyParams, callback?: Github.Callback): Promise; + getPreReceiveEnvironment(params: Github.EnterpriseGetPreReceiveEnvironmentParams, callback?: Github.Callback): Promise; + getPreReceiveEnvironments(params: Github.EmptyParams, callback?: Github.Callback): Promise; + createPreReceiveEnvironment(params: Github.EnterpriseCreatePreReceiveEnvironmentParams, callback?: Github.Callback): Promise; + editPreReceiveEnvironment(params: Github.EnterpriseEditPreReceiveEnvironmentParams, callback?: Github.Callback): Promise; + deletePreReceiveEnvironment(params: Github.EnterpriseDeletePreReceiveEnvironmentParams, callback?: Github.Callback): Promise; + getPreReceiveEnvironmentDownloadStatus(params: Github.EnterpriseGetPreReceiveEnvironmentDownloadStatusParams, callback?: Github.Callback): Promise; + triggerPreReceiveEnvironmentDownload(params: Github.EnterpriseTriggerPreReceiveEnvironmentDownloadParams, callback?: Github.Callback): Promise; + getPreReceiveHook(params: Github.EnterpriseGetPreReceiveHookParams, callback?: Github.Callback): Promise; + getPreReceiveHooks(params: Github.EmptyParams, callback?: Github.Callback): Promise; + createPreReceiveHook(params: Github.EnterpriseCreatePreReceiveHookParams, callback?: Github.Callback): Promise; + editPreReceiveHook(params: Github.EnterpriseEditPreReceiveHookParams, callback?: Github.Callback): Promise; + deletePreReceiveHook(params: Github.EnterpriseDeletePreReceiveHookParams, callback?: Github.Callback): Promise; + queueIndexingJob(params: Github.EnterpriseQueueIndexingJobParams, callback?: Github.Callback): Promise; + createOrg(params: Github.EnterpriseCreateOrgParams, callback?: Github.Callback): Promise; + }; +} + +declare module "octokit-rest-es3" { + export = Github; +} \ No newline at end of file From 29cb502be5d0795ee82756510323a0a8e9a9287f Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Thu, 1 Mar 2018 12:43:20 +0000 Subject: [PATCH 059/873] Make it so we don't run tasks inside tasks, and instead just run one chain (so it can fail and we can catch it) --- src/GitHub.Api/Installer/GitInstaller.cs | 56 +++++++++++++----------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/src/GitHub.Api/Installer/GitInstaller.cs b/src/GitHub.Api/Installer/GitInstaller.cs index 8fb339f56..165e3e0af 100644 --- a/src/GitHub.Api/Installer/GitInstaller.cs +++ b/src/GitHub.Api/Installer/GitInstaller.cs @@ -111,45 +111,51 @@ public void SetupGitIfNeeded(ActionTask onSuccess, ITask onFailure) return; } - new ActionTask(cancellationToken, () => { - if (IsGitExtracted()) + var task = new FuncTask(cancellationToken, () => + { + if (!IsGitExtracted()) { Logger.Trace("SetupGitIfNeeded: Skipped"); - onSuccess.PreviousResult = installDetails.GitExecutablePath; - onSuccess.Start(); - } - else - { - ExtractPortableGit(onSuccess, onFailure); + throw new Exception(); } - }).Start(); + return installDetails.GitExecutablePath; + }); + var extractTask = ExtractPortableGit(); + extractTask.Then(onSuccess, TaskRunOptions.OnSuccess, taskIsTopOfChain: true); + extractTask.Then(onFailure, TaskRunOptions.OnFailure, taskIsTopOfChain: true); + + task.Then(onSuccess, TaskRunOptions.OnSuccess, taskIsTopOfChain: true); + task.Then(extractTask, TaskRunOptions.OnFailure, taskIsTopOfChain: true); + task.Start(); } - private void ExtractPortableGit(ActionTask onSuccess, ITask onFailure) + private FuncTask ExtractPortableGit() { - ITask downloadFilesTask = null; - if ((gitArchiveFilePath == null) || (gitLfsArchivePath == null)) - { - downloadFilesTask = CreateDownloadTask(); - } - var tempZipExtractPath = NPath.CreateTempDirectory("git_zip_extract_zip_paths"); var gitExtractPath = tempZipExtractPath.Combine("git").CreateDirectory(); var gitLfsExtractPath = tempZipExtractPath.Combine("git-lfs").CreateDirectory(); - var resultTask = new UnzipTask(cancellationToken, gitArchiveFilePath, gitExtractPath, sharpZipLibHelper, environment.FileSystem, GitInstallDetails.GitExtractedMD5) - .Then(new UnzipTask(cancellationToken, gitLfsArchivePath, gitLfsExtractPath, sharpZipLibHelper, environment.FileSystem, GitInstallDetails .GitLfsExtractedMD5)) - .Then(s => MoveGitAndLfs(gitExtractPath, gitLfsExtractPath, tempZipExtractPath)); - - resultTask.Then(onFailure, TaskRunOptions.OnFailure); - resultTask.Then(onSuccess, TaskRunOptions.OnSuccess); + var unzipTasks = CreateUnzipTasks(gitExtractPath, gitLfsExtractPath, tempZipExtractPath); - if (downloadFilesTask != null) + if (gitArchiveFilePath == null || gitLfsArchivePath == null) { - resultTask = downloadFilesTask.Then(resultTask); + var downloadFilesTask = CreateDownloadTask(); + unzipTasks = downloadFilesTask.Then(unzipTasks); } - resultTask.Start(); + return unzipTasks; + } + + private FuncTask CreateUnzipTasks(NPath gitExtractPath, NPath gitLfsExtractPath, NPath tempZipExtractPath) + { + var unzipGitTask = new UnzipTask(cancellationToken, gitArchiveFilePath, gitExtractPath, sharpZipLibHelper, + environment.FileSystem, GitInstallDetails.GitExtractedMD5); + var unzipGitLfsTask = new UnzipTask(cancellationToken, gitLfsArchivePath, gitLfsExtractPath, sharpZipLibHelper, + environment.FileSystem, GitInstallDetails.GitLfsExtractedMD5); + var moveGitTask = new FuncTask(cancellationToken, () => MoveGitAndLfs(gitExtractPath, gitLfsExtractPath, tempZipExtractPath)); + return unzipGitTask + .Then(unzipGitLfsTask) + .Then(moveGitTask); } private NPath MoveGitAndLfs(NPath gitExtractPath, NPath gitLfsExtractPath, NPath tempZipExtractPath) From 0d3ca28365e3f5719004e86ad54199ad319f54e2 Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Wed, 28 Feb 2018 16:13:46 -0500 Subject: [PATCH 060/873] Let me stop here for a moment --- octorun/LICENSE | 21 - octorun/bin/octorun | 5 - octorun/bin/octorun-login | 3 - octorun/bin/octorun-write | 3 - octorun/dist/authenticator.d.ts | 5 - octorun/dist/authenticator.js | 75 - octorun/dist/bin/app-login.d.ts | 7 - octorun/dist/bin/app-login.js | 30 - octorun/dist/bin/app-write.d.ts | 7 - octorun/dist/bin/app-write.js | 31 - octorun/dist/bin/app.d.ts | 6 - octorun/dist/bin/app.js | 20 - octorun/dist/configuration.d.ts | 5 - octorun/dist/configuration.js | 7 - octorun/dist/writer.d.ts | 3 - octorun/dist/writer.js | 12 - octorun/src/authenticator.ts | 41 - octorun/src/bin/app-login.ts | 40 - octorun/src/bin/app-write.ts | 39 - octorun/src/bin/app.ts | 26 - octorun/src/configuration.ts | 6 - octorun/src/writer.ts | 7 - octorun/test/writer-spec.ts | 34 - octorun/tsconfig.json | 22 - octorun/typings/octokit-rest-es3/index.d.ts | 3476 ------------------- 25 files changed, 3931 deletions(-) delete mode 100644 octorun/LICENSE delete mode 100644 octorun/bin/octorun delete mode 100644 octorun/bin/octorun-login delete mode 100644 octorun/bin/octorun-write delete mode 100644 octorun/dist/authenticator.d.ts delete mode 100644 octorun/dist/authenticator.js delete mode 100644 octorun/dist/bin/app-login.d.ts delete mode 100644 octorun/dist/bin/app-login.js delete mode 100644 octorun/dist/bin/app-write.d.ts delete mode 100644 octorun/dist/bin/app-write.js delete mode 100644 octorun/dist/bin/app.d.ts delete mode 100644 octorun/dist/bin/app.js delete mode 100644 octorun/dist/configuration.d.ts delete mode 100644 octorun/dist/configuration.js delete mode 100644 octorun/dist/writer.d.ts delete mode 100644 octorun/dist/writer.js delete mode 100644 octorun/src/authenticator.ts delete mode 100644 octorun/src/bin/app-login.ts delete mode 100644 octorun/src/bin/app-write.ts delete mode 100644 octorun/src/bin/app.ts delete mode 100644 octorun/src/configuration.ts delete mode 100644 octorun/src/writer.ts delete mode 100644 octorun/test/writer-spec.ts delete mode 100644 octorun/tsconfig.json delete mode 100644 octorun/typings/octokit-rest-es3/index.d.ts diff --git a/octorun/LICENSE b/octorun/LICENSE deleted file mode 100644 index 0776bd363..000000000 --- a/octorun/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2018 - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/octorun/bin/octorun b/octorun/bin/octorun deleted file mode 100644 index 6c0fe6d04..000000000 --- a/octorun/bin/octorun +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env node - -console.log("NodeJs", process.argv[0]); - -require('../dist/bin/app.js'); diff --git a/octorun/bin/octorun-login b/octorun/bin/octorun-login deleted file mode 100644 index fe09da41a..000000000 --- a/octorun/bin/octorun-login +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env node - -require('../dist/bin/app-login.js'); diff --git a/octorun/bin/octorun-write b/octorun/bin/octorun-write deleted file mode 100644 index 62ead2886..000000000 --- a/octorun/bin/octorun-write +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env node - -require('../dist/bin/app-write.js'); diff --git a/octorun/dist/authenticator.d.ts b/octorun/dist/authenticator.d.ts deleted file mode 100644 index cc6697a38..000000000 --- a/octorun/dist/authenticator.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export declare class Authenticator { - private github; - constructor(); - createAndDeleteExistingApplicationAuthorization(): Promise; -} diff --git a/octorun/dist/authenticator.js b/octorun/dist/authenticator.js deleted file mode 100644 index c6698dc32..000000000 --- a/octorun/dist/authenticator.js +++ /dev/null @@ -1,75 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __generator = (this && this.__generator) || function (thisArg, body) { - var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; - return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; - function verb(n) { return function (v) { return step([n, v]); }; } - function step(op) { - if (f) throw new TypeError("Generator is already executing."); - while (_) try { - if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [0, t.value]; - switch (op[0]) { - case 0: case 1: t = op; break; - case 4: _.label++; return { value: op[1], done: false }; - case 5: _.label++; y = op[1]; op = [0]; continue; - case 7: op = _.ops.pop(); _.trys.pop(); continue; - default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } - if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } - if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } - if (t[2]) _.ops.pop(); - _.trys.pop(); continue; - } - op = body.call(thisArg, _); - } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } - if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; - } -}; -exports.__esModule = true; -var GitHub = require("octokit-rest-es3"); -var configuration_1 = require("./configuration"); -var Authenticator = (function () { - function Authenticator() { - this.github = new GitHub({ - timeout: 0, - requestMedia: 'application/vnd.github.v3+json', - headers: { - 'user-agent': 'octokit/rest.js v1.2.3' - }, - host: 'api.github.com', - pathPrefix: '', - protocol: 'https', - port: 443 - }); - } - Authenticator.prototype.createAndDeleteExistingApplicationAuthorization = function () { - return __awaiter(this, void 0, void 0, function () { - var authParams; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - authParams = { - client_id: configuration_1.configuration.ClientId, - client_secret: configuration_1.configuration.ClientSecret, - scopes: ["user", "repo", "gist", "write:public_key"] - }; - return [4, this.github.authorization.getOrCreateAuthorizationForApp(authParams)]; - case 1: - _a.sent(); - return [2]; - } - }); - }); - }; - return Authenticator; -}()); -exports.Authenticator = Authenticator; diff --git a/octorun/dist/bin/app-login.d.ts b/octorun/dist/bin/app-login.d.ts deleted file mode 100644 index 1a4eeeebc..000000000 --- a/octorun/dist/bin/app-login.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export declare class Write { - private program; - private package; - private authenticator; - constructor(); - initialize(): void; -} diff --git a/octorun/dist/bin/app-login.js b/octorun/dist/bin/app-login.js deleted file mode 100644 index 4bfbefe90..000000000 --- a/octorun/dist/bin/app-login.js +++ /dev/null @@ -1,30 +0,0 @@ -"use strict"; -exports.__esModule = true; -var commander = require("commander"); -var authenticator_1 = require("../authenticator"); -var Write = (function () { - function Write() { - this.program = commander; - this.package = require('../../package.json'); - this.authenticator = new authenticator_1.Authenticator(); - } - Write.prototype.initialize = function () { - this.program - .version(this.package.version) - .option('-l, --login') - .option('-t, --twoFactor') - .parse(process.argv); - if (this.program.login) { - this.authenticator.createAndDeleteExistingApplicationAuthorization(); - process.exit(); - } - else if (this.program.twoFactor) { - process.exit(); - } - this.program.help(); - }; - return Write; -}()); -exports.Write = Write; -var app = new Write(); -app.initialize(); diff --git a/octorun/dist/bin/app-write.d.ts b/octorun/dist/bin/app-write.d.ts deleted file mode 100644 index b6e272292..000000000 --- a/octorun/dist/bin/app-write.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export declare class Write { - private program; - private package; - private writer; - constructor(); - initialize(): void; -} diff --git a/octorun/dist/bin/app-write.js b/octorun/dist/bin/app-write.js deleted file mode 100644 index fd02ec270..000000000 --- a/octorun/dist/bin/app-write.js +++ /dev/null @@ -1,31 +0,0 @@ -"use strict"; -exports.__esModule = true; -var commander = require("commander"); -var writer_1 = require("../writer"); -var Write = (function () { - function Write() { - this.program = commander; - this.package = require('../../package.json'); - this.writer = new writer_1.Writer(); - } - Write.prototype.initialize = function () { - this.program - .version(this.package.version) - .option('-m, --message [value]', 'Say hello!') - .parse(process.argv); - if (this.program.message != null) { - if (typeof this.program.message !== 'string') { - this.writer.write(); - } - else { - this.writer.write(this.program.message); - } - process.exit(); - } - this.program.help(); - }; - return Write; -}()); -exports.Write = Write; -var app = new Write(); -app.initialize(); diff --git a/octorun/dist/bin/app.d.ts b/octorun/dist/bin/app.d.ts deleted file mode 100644 index 65223902d..000000000 --- a/octorun/dist/bin/app.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -export declare class App { - private program; - private package; - constructor(); - initialize(): void; -} diff --git a/octorun/dist/bin/app.js b/octorun/dist/bin/app.js deleted file mode 100644 index 10a9c9caf..000000000 --- a/octorun/dist/bin/app.js +++ /dev/null @@ -1,20 +0,0 @@ -"use strict"; -exports.__esModule = true; -var commander = require("commander"); -var App = (function () { - function App() { - this.program = commander; - this.package = require('../../package.json'); - } - App.prototype.initialize = function () { - this.program - .version(this.package.version) - .command('login [-h|-2fa]', 'Authenticate') - .command('write [message]', 'say hello!') - .parse(process.argv); - }; - return App; -}()); -exports.App = App; -var app = new App(); -app.initialize(); diff --git a/octorun/dist/configuration.d.ts b/octorun/dist/configuration.d.ts deleted file mode 100644 index 93e15f619..000000000 --- a/octorun/dist/configuration.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare const configuration: { - ClientId: any; - ClientSecret: any; -}; -export { configuration }; diff --git a/octorun/dist/configuration.js b/octorun/dist/configuration.js deleted file mode 100644 index 1a3d3ed1c..000000000 --- a/octorun/dist/configuration.js +++ /dev/null @@ -1,7 +0,0 @@ -"use strict"; -exports.__esModule = true; -var configuration = { - ClientId: process.env.OCTOKIT_CLIENT_ID, - ClientSecret: process.env.OCTOKIT_CLIENT_SECRET -}; -exports.configuration = configuration; diff --git a/octorun/dist/writer.d.ts b/octorun/dist/writer.d.ts deleted file mode 100644 index 8373b156f..000000000 --- a/octorun/dist/writer.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export declare class Writer { - write(message?: String): void; -} diff --git a/octorun/dist/writer.js b/octorun/dist/writer.js deleted file mode 100644 index e5d55d015..000000000 --- a/octorun/dist/writer.js +++ /dev/null @@ -1,12 +0,0 @@ -"use strict"; -exports.__esModule = true; -var Writer = (function () { - function Writer() { - } - Writer.prototype.write = function (message) { - if (message === void 0) { message = "Hello World!"; } - console.log(message); - }; - return Writer; -}()); -exports.Writer = Writer; diff --git a/octorun/src/authenticator.ts b/octorun/src/authenticator.ts deleted file mode 100644 index 2e47f5109..000000000 --- a/octorun/src/authenticator.ts +++ /dev/null @@ -1,41 +0,0 @@ -/// - -import * as GitHub from 'octokit-rest-es3'; -import { configuration } from './configuration'; - -export class Authenticator { - - private github: GitHub; - - constructor() { - - //Listed defaults from https://github.com/octokit/rest.js#options - - this.github = new GitHub({ - timeout: 0, // 0 means no request timeout - requestMedia: 'application/vnd.github.v3+json', - headers: { - 'user-agent': 'octokit/rest.js v1.2.3' // v1.2.3 will be current version - }, - - // change for custom GitHub Enterprise URL - host: 'api.github.com', - pathPrefix: '', - protocol: 'https', - port: 443, - - // Node only: advanced request options can be passed as http(s) agent - //agent: undefined - }) - } - - public async createAndDeleteExistingApplicationAuthorization() { - const authParams: GitHub.AuthorizationGetOrCreateAuthorizationForAppParams = { - client_id: configuration.ClientId, - client_secret: configuration.ClientSecret, - scopes: ["user", "repo", "gist", "write:public_key"] - }; - - await this.github.authorization.getOrCreateAuthorizationForApp(authParams); - } -} diff --git a/octorun/src/bin/app-login.ts b/octorun/src/bin/app-login.ts deleted file mode 100644 index d216709fd..000000000 --- a/octorun/src/bin/app-login.ts +++ /dev/null @@ -1,40 +0,0 @@ -import * as commander from 'commander'; -import { Authenticator } from '../authenticator'; - -export class Write { - - private program: commander.CommanderStatic; - private package: any; - private authenticator: Authenticator; - - constructor() { - this.program = commander; - this.package = require('../../package.json'); - this.authenticator = new Authenticator(); - } - - public initialize() { - this.program - .version(this.package.version) - .option('-l, --login') - .option('-t, --twoFactor') - .parse(process.argv); - - if (this.program.login) { - - this.authenticator.createAndDeleteExistingApplicationAuthorization() - - process.exit(); - } - else if (this.program.twoFactor) { - - process.exit(); - } - - this.program.help(); - } - -} - -let app = new Write(); -app.initialize(); diff --git a/octorun/src/bin/app-write.ts b/octorun/src/bin/app-write.ts deleted file mode 100644 index 743f97f54..000000000 --- a/octorun/src/bin/app-write.ts +++ /dev/null @@ -1,39 +0,0 @@ -import * as commander from 'commander'; -import { Writer } from '../writer'; - -export class Write { - - private program: commander.CommanderStatic; - private package: any; - private writer: Writer; - - constructor() { - this.program = commander; - this.package = require('../../package.json'); - this.writer = new Writer(); - } - - public initialize() { - this.program - .version(this.package.version) - .option('-m, --message [value]', 'Say hello!') - .parse(process.argv); - - if (this.program.message != null) { - - if (typeof this.program.message !== 'string') { - this.writer.write(); - } else { - this.writer.write(this.program.message); - } - - process.exit(); - } - - this.program.help(); - } - -} - -let app = new Write(); -app.initialize(); diff --git a/octorun/src/bin/app.ts b/octorun/src/bin/app.ts deleted file mode 100644 index 5bc468e57..000000000 --- a/octorun/src/bin/app.ts +++ /dev/null @@ -1,26 +0,0 @@ -//require('dotenv').config(); - -import * as commander from 'commander'; - -export class App { - - private program: commander.CommanderStatic; - private package: any; - - constructor() { - this.program = commander; - this.package = require('../../package.json'); - } - - public initialize() { - this.program - .version(this.package.version) - .command('login [-h|-2fa]', 'Authenticate') - .command('write [message]', 'say hello!') - .parse(process.argv); - } - -} - -let app = new App(); -app.initialize(); diff --git a/octorun/src/configuration.ts b/octorun/src/configuration.ts deleted file mode 100644 index b72e19aed..000000000 --- a/octorun/src/configuration.ts +++ /dev/null @@ -1,6 +0,0 @@ -const configuration = { - ClientId: process.env.OCTOKIT_CLIENT_ID, - ClientSecret: process.env.OCTOKIT_CLIENT_SECRET, -}; - -export { configuration }; \ No newline at end of file diff --git a/octorun/src/writer.ts b/octorun/src/writer.ts deleted file mode 100644 index 2a15fdff9..000000000 --- a/octorun/src/writer.ts +++ /dev/null @@ -1,7 +0,0 @@ -export class Writer { - - public write(message: String = "Hello World!") { - console.log(message); - } - -} diff --git a/octorun/test/writer-spec.ts b/octorun/test/writer-spec.ts deleted file mode 100644 index b85289ec6..000000000 --- a/octorun/test/writer-spec.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Writer } from '../src/writer'; -import * as chai from 'chai'; -import * as sinon from 'sinon'; - -const assert = chai.assert; - -describe('Writer', () => { - describe('#write()', () => { - it('should write a message', () => { - - let spy = sinon.spy(console, 'log'); - - var writer = new Writer(); - writer.write('I am being tested!'); - - assert(spy.calledWith('I am being tested!')); - - spy.restore(); - - }); - it('should write a default message', () => { - - let spy = sinon.spy(console, 'log'); - - var writer = new Writer(); - writer.write(); - - assert(spy.calledWith('Hello World!')); - - spy.restore(); - - }); - }); -}); diff --git a/octorun/tsconfig.json b/octorun/tsconfig.json deleted file mode 100644 index 021d9fb8a..000000000 --- a/octorun/tsconfig.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "compileOnSave": false, - "compilerOptions": { - "target": "es3", - "declaration": true, - "module": "commonjs", - "moduleResolution": "node", - "noImplicitAny": true, - "outDir": "./dist", - "preserveConstEnums": true, - "removeComments": true, - "lib":["es2015"] - }, - "include": [ - "src/**/*" - ], - "exclude": [ - "node_modules", - "!node_modules/@types", - "test/**/*-spec.ts" - ] -} diff --git a/octorun/typings/octokit-rest-es3/index.d.ts b/octorun/typings/octokit-rest-es3/index.d.ts deleted file mode 100644 index 693473ddb..000000000 --- a/octorun/typings/octokit-rest-es3/index.d.ts +++ /dev/null @@ -1,3476 +0,0 @@ -/** - * This declaration file requires TypeScript 2.1 or above. - */ -declare namespace Github { - type json = any - type date = string - - export interface AnyResponse { - /** This is the data you would see in https://developer.github.com/v3/ */ - data: any - - /** Request metadata */ - meta:{ - 'x-ratelimit-limit': string, - 'x-ratelimit-remaining': string, - 'x-ratelimit-reset': string, - 'x-github-request-id': string, - 'x-github-media-type': string, - link: string, - 'last-modified': string, - etag: string, - status: string - } - - [Symbol.iterator](): Iterator - } - - export interface EmptyParams { - } - - export interface Options { - timeout?: number; - host?: string; - pathPrefix?: string; - protocol?: string; - port?: number; - proxy?: string; - ca?: string; - headers?: {[header: string]: any}; - requestMedia?: string; - rejectUnauthorized?: boolean; - family?: number; - } - - export interface AuthBasic { - type: "basic"; - username: string; - password: string; - } - - export interface AuthOAuthToken { - type: "oauth"; - token: string; - } - - export interface AuthOAuthSecret { - type: "oauth"; - key: string; - secret: string; - } - - export interface AuthUserToken { - type: "token"; - token: string; - } - - export interface AuthJWT { - type: "integration"; - token: string; - } - - export type Auth = - | AuthBasic - | AuthOAuthToken - | AuthOAuthSecret - | AuthUserToken - | AuthJWT; - - export type Link = - | { link: string; } - | { meta: { link: string; }; } - | string; - - export interface Callback { - (error: Error | null, result: any): any; - } - - - export type AuthorizationGetParams = - & { - id: string; - }; - export type AuthorizationCreateParams = - & { - scopes?: string[]; - note?: string; - note_url?: string; - client_id?: string; - client_secret?: string; - fingerprint?: string; - }; - export type AuthorizationUpdateParams = - & { - id: string; - scopes?: string[]; - add_scopes?: string[]; - remove_scopes?: string[]; - note?: string; - note_url?: string; - fingerprint?: string; - }; - export type AuthorizationDeleteParams = - & { - id: string; - }; - export type AuthorizationCheckParams = - & { - client_id?: string; - access_token: string; - }; - export type AuthorizationResetParams = - & { - client_id?: string; - access_token: string; - }; - export type AuthorizationRevokeParams = - & { - client_id?: string; - access_token: string; - }; - export type AuthorizationGetGrantsParams = - & { - page?: number; - per_page?: number; - }; - export type AuthorizationGetGrantParams = - & { - id: string; - page?: number; - per_page?: number; - }; - export type AuthorizationDeleteGrantParams = - & { - id: string; - }; - export type AuthorizationGetAllParams = - & { - page?: number; - per_page?: number; - }; - export type AuthorizationGetOrCreateAuthorizationForAppParams = - & { - client_id?: string; - client_secret: string; - scopes?: string[]; - note?: string; - note_url?: string; - fingerprint?: string; - }; - export type AuthorizationGetOrCreateAuthorizationForAppAndFingerprintParams = - & { - client_id?: string; - fingerprint?: string; - client_secret: string; - scopes?: string[]; - note?: string; - note_url?: string; - }; - export type AuthorizationRevokeGrantParams = - & { - client_id?: string; - access_token: string; - }; - export type ActivityGetEventsParams = - & { - page?: number; - per_page?: number; - }; - export type ActivityGetEventsForRepoParams = - & { - owner: string; - repo: string; - page?: number; - per_page?: number; - }; - export type ActivityGetEventsForRepoIssuesParams = - & { - owner: string; - repo: string; - page?: number; - per_page?: number; - }; - export type ActivityGetEventsForRepoNetworkParams = - & { - owner: string; - repo: string; - page?: number; - per_page?: number; - }; - export type ActivityGetEventsForOrgParams = - & { - org: string; - page?: number; - per_page?: number; - }; - export type ActivityGetEventsReceivedParams = - & { - username: string; - page?: number; - per_page?: number; - }; - export type ActivityGetEventsReceivedPublicParams = - & { - username: string; - page?: number; - per_page?: number; - }; - export type ActivityGetEventsForUserParams = - & { - username: string; - page?: number; - per_page?: number; - }; - export type ActivityGetEventsForUserPublicParams = - & { - username: string; - page?: number; - per_page?: number; - }; - export type ActivityGetEventsForUserOrgParams = - & { - username: string; - org: string; - page?: number; - per_page?: number; - }; - export type ActivityGetNotificationsParams = - & { - all?: boolean; - participating?: boolean; - since?: date; - before?: string; - }; - export type ActivityGetNotificationsForUserParams = - & { - owner: string; - repo: string; - all?: boolean; - participating?: boolean; - since?: date; - before?: string; - }; - export type ActivityMarkNotificationsAsReadParams = - & { - last_read_at?: string; - }; - export type ActivityMarkNotificationsAsReadForRepoParams = - & { - owner: string; - repo: string; - last_read_at?: string; - }; - export type ActivityGetNotificationThreadParams = - & { - id: string; - }; - export type ActivityMarkNotificationThreadAsReadParams = - & { - id: string; - }; - export type ActivityCheckNotificationThreadSubscriptionParams = - & { - id: string; - }; - export type ActivitySetNotificationThreadSubscriptionParams = - & { - id: string; - subscribed?: boolean; - ignored?: boolean; - }; - export type ActivityDeleteNotificationThreadSubscriptionParams = - & { - id: string; - }; - export type ActivityGetStargazersForRepoParams = - & { - owner: string; - repo: string; - page?: number; - per_page?: number; - }; - export type ActivityGetStarredReposForUserParams = - & { - username: string; - sort?: "created"|"updated"; - direction?: "asc"|"desc"; - page?: number; - per_page?: number; - }; - export type ActivityGetStarredReposParams = - & { - sort?: "created"|"updated"; - direction?: "asc"|"desc"; - page?: number; - per_page?: number; - }; - export type ActivityCheckStarringRepoParams = - & { - owner: string; - repo: string; - page?: number; - per_page?: number; - }; - export type ActivityStarRepoParams = - & { - owner: string; - repo: string; - }; - export type ActivityUnstarRepoParams = - & { - owner: string; - repo: string; - }; - export type ActivityGetWatchersForRepoParams = - & { - owner: string; - repo: string; - page?: number; - per_page?: number; - }; - export type ActivityGetWatchedReposForUserParams = - & { - username: string; - page?: number; - per_page?: number; - }; - export type ActivityGetWatchedReposParams = - & { - page?: number; - per_page?: number; - }; - export type ActivityGetRepoSubscriptionParams = - & { - owner: string; - repo: string; - page?: number; - per_page?: number; - }; - export type ActivitySetRepoSubscriptionParams = - & { - owner: string; - repo: string; - subscribed?: boolean; - ignored?: boolean; - }; - export type ActivityUnwatchRepoParams = - & { - owner: string; - repo: string; - }; - export type GistsGetParams = - & { - id: string; - }; - export type GistsCreateParams = - & { - files: json; - description?: string; - public: boolean; - }; - export type GistsEditParams = - & { - id: string; - description?: string; - files: json; - content?: string; - filename?: string; - }; - export type GistsStarParams = - & { - id: string; - }; - export type GistsUnstarParams = - & { - id: string; - }; - export type GistsForkParams = - & { - id: string; - }; - export type GistsDeleteParams = - & { - id: string; - }; - export type GistsGetForUserParams = - & { - username: string; - since?: date; - page?: number; - per_page?: number; - }; - export type GistsGetAllParams = - & { - since?: date; - page?: number; - per_page?: number; - }; - export type GistsGetPublicParams = - & { - since?: date; - }; - export type GistsGetStarredParams = - & { - since?: date; - }; - export type GistsGetRevisionParams = - & { - id: string; - sha: string; - }; - export type GistsGetCommitsParams = - & { - id: string; - }; - export type GistsCheckStarParams = - & { - id: string; - }; - export type GistsGetForksParams = - & { - id: string; - page?: number; - per_page?: number; - }; - export type GistsGetCommentsParams = - & { - gist_id: string; - }; - export type GistsGetCommentParams = - & { - gist_id: string; - id: string; - }; - export type GistsCreateCommentParams = - & { - gist_id: string; - body: string; - }; - export type GistsEditCommentParams = - & { - gist_id: string; - id: string; - body: string; - }; - export type GistsDeleteCommentParams = - & { - gist_id: string; - id: string; - }; - export type GitdataGetBlobParams = - & { - owner: string; - repo: string; - sha: string; - page?: number; - per_page?: number; - }; - export type GitdataCreateBlobParams = - & { - owner: string; - repo: string; - content: string; - encoding: string; - }; - export type GitdataGetCommitParams = - & { - owner: string; - repo: string; - sha: string; - }; - export type GitdataCreateCommitParams = - & { - owner: string; - repo: string; - message: string; - tree: string; - parents: string[]; - author?: json; - committer?: json; - }; - export type GitdataGetCommitSignatureVerificationParams = - & { - owner: string; - repo: string; - sha: string; - }; - export type GitdataGetReferenceParams = - & { - owner: string; - repo: string; - ref: string; - }; - export type GitdataGetReferencesParams = - & { - owner: string; - repo: string; - page?: number; - per_page?: number; - }; - export type GitdataGetTagsParams = - & { - owner: string; - repo: string; - page?: number; - per_page?: number; - }; - export type GitdataCreateReferenceParams = - & { - owner: string; - repo: string; - ref: string; - sha: string; - }; - export type GitdataUpdateReferenceParams = - & { - owner: string; - repo: string; - ref: string; - sha: string; - force?: boolean; - }; - export type GitdataDeleteReferenceParams = - & { - owner: string; - repo: string; - ref: string; - }; - export type GitdataGetTagParams = - & { - owner: string; - repo: string; - sha: string; - }; - export type GitdataCreateTagParams = - & { - owner: string; - repo: string; - tag: string; - message: string; - object: string; - type: string; - tagger: json; - }; - export type GitdataGetTagSignatureVerificationParams = - & { - owner: string; - repo: string; - sha: string; - }; - export type GitdataGetTreeParams = - & { - owner: string; - repo: string; - sha: string; - recursive?: boolean; - }; - export type GitdataCreateTreeParams = - & { - owner: string; - repo: string; - tree: json; - base_tree?: string; - }; - export type IntegrationsGetInstallationsParams = - & { - page?: number; - per_page?: number; - }; - export type IntegrationsCreateInstallationTokenParams = - & { - installation_id: string; - user_id?: string; - }; - export type IntegrationsGetInstallationRepositoriesParams = - & { - user_id?: string; - }; - export type IntegrationsAddRepoToInstallationParams = - & { - installation_id: string; - repository_id: string; - }; - export type IntegrationsRemoveRepoFromInstallationParams = - & { - installation_id: string; - repository_id: string; - }; - export type AppsGetForSlugParams = - & { - app_slug: string; - }; - export type AppsGetInstallationsParams = - & { - page?: number; - per_page?: number; - }; - export type AppsGetInstallationParams = - & { - installation_id: string; - }; - export type AppsCreateInstallationTokenParams = - & { - installation_id: string; - user_id?: string; - }; - export type AppsGetInstallationRepositoriesParams = - & { - user_id?: string; - }; - export type AppsAddRepoToInstallationParams = - & { - installation_id: string; - repository_id: string; - }; - export type AppsRemoveRepoFromInstallationParams = - & { - installation_id: string; - repository_id: string; - }; - export type AppsGetMarketplaceListingPlansParams = - & { - page?: number; - per_page?: number; - }; - export type AppsGetMarketplaceListingStubbedPlansParams = - & { - page?: number; - per_page?: number; - }; - export type AppsGetMarketplaceListingPlanAccountsParams = - & { - id: string; - page?: number; - per_page?: number; - }; - export type AppsGetMarketplaceListingStubbedPlanAccountsParams = - & { - id: string; - page?: number; - per_page?: number; - }; - export type AppsCheckMarketplaceListingAccountParams = - & { - id: string; - }; - export type AppsCheckMarketplaceListingStubbedAccountParams = - & { - id: string; - }; - export type IssuesGetParams = - & { - owner: string; - repo: string; - number: number; - }; - export type IssuesCreateParams = - & { - owner: string; - repo: string; - title: string; - body?: string; - assignee?: string; - milestone?: number; - labels?: string[]; - assignees?: string[]; - }; - export type IssuesEditParams = - & { - owner: string; - repo: string; - number: number; - title?: string; - body?: string; - assignee?: string; - state?: "open"|"closed"; - milestone?: number; - labels?: string[]; - assignees?: string[]; - }; - export type IssuesLockParams = - & { - owner: string; - repo: string; - number: number; - }; - export type IssuesUnlockParams = - & { - owner: string; - repo: string; - number: number; - }; - export type IssuesGetAllParams = - & { - filter?: "all"|"assigned"|"created"|"mentioned"|"subscribed"; - state?: "open"|"closed"|"all"; - labels?: string; - sort?: "created"|"updated"|"comments"; - direction?: "asc"|"desc"; - since?: date; - page?: number; - per_page?: number; - }; - export type IssuesGetForUserParams = - & { - filter?: "all"|"assigned"|"created"|"mentioned"|"subscribed"; - state?: "open"|"closed"|"all"; - labels?: string; - sort?: "created"|"updated"|"comments"; - direction?: "asc"|"desc"; - since?: date; - page?: number; - per_page?: number; - }; - export type IssuesGetForOrgParams = - & { - org: string; - filter?: "all"|"assigned"|"created"|"mentioned"|"subscribed"; - state?: "open"|"closed"|"all"; - labels?: string; - sort?: "created"|"updated"|"comments"; - direction?: "asc"|"desc"; - since?: date; - page?: number; - per_page?: number; - }; - export type IssuesGetForRepoParams = - & { - owner: string; - repo: string; - milestone?: string; - state?: "open"|"closed"|"all"; - assignee?: string; - creator?: string; - mentioned?: string; - labels?: string; - sort?: "created"|"updated"|"comments"; - direction?: "asc"|"desc"; - since?: date; - page?: number; - per_page?: number; - }; - export type IssuesGetAssigneesParams = - & { - owner: string; - repo: string; - }; - export type IssuesCheckAssigneeParams = - & { - owner: string; - repo: string; - assignee: string; - }; - export type IssuesAddAssigneesToIssueParams = - & { - owner: string; - repo: string; - number: number; - assignees: string[]; - }; - export type IssuesRemoveAssigneesFromIssueParams = - & { - owner: string; - repo: string; - number: number; - body: json; - }; - export type IssuesGetCommentsParams = - & { - owner: string; - repo: string; - number: number; - since?: date; - page?: number; - per_page?: number; - }; - export type IssuesGetCommentsForRepoParams = - & { - owner: string; - repo: string; - sort?: "created"|"updated"; - direction?: "asc"|"desc"; - since?: date; - page?: number; - per_page?: number; - }; - export type IssuesGetCommentParams = - & { - owner: string; - repo: string; - id: string; - }; - export type IssuesCreateCommentParams = - & { - owner: string; - repo: string; - number: number; - body: string; - }; - export type IssuesEditCommentParams = - & { - owner: string; - repo: string; - id: string; - body: string; - }; - export type IssuesDeleteCommentParams = - & { - owner: string; - repo: string; - id: string; - }; - export type IssuesGetEventsParams = - & { - owner: string; - repo: string; - issue_number: number; - page?: number; - per_page?: number; - }; - export type IssuesGetEventsForRepoParams = - & { - owner: string; - repo: string; - page?: number; - per_page?: number; - }; - export type IssuesGetEventParams = - & { - owner: string; - repo: string; - id: string; - }; - export type IssuesGetLabelsParams = - & { - owner: string; - repo: string; - page?: number; - per_page?: number; - }; - export type IssuesGetLabelParams = - & { - owner: string; - repo: string; - name: string; - }; - export type IssuesCreateLabelParams = - & { - owner: string; - repo: string; - name: string; - color: string; - }; - export type IssuesUpdateLabelParams = - & { - owner: string; - repo: string; - oldname: string; - name: string; - color: string; - }; - export type IssuesDeleteLabelParams = - & { - owner: string; - repo: string; - name: string; - }; - export type IssuesGetIssueLabelsParams = - & { - owner: string; - repo: string; - number: number; - }; - export type IssuesAddLabelsParams = - & { - owner: string; - repo: string; - number: number; - labels: string[]; - }; - export type IssuesRemoveLabelParams = - & { - owner: string; - repo: string; - number: number; - name: string; - }; - export type IssuesReplaceAllLabelsParams = - & { - owner: string; - repo: string; - number: number; - labels: string[]; - }; - export type IssuesRemoveAllLabelsParams = - & { - owner: string; - repo: string; - number: number; - }; - export type IssuesGetMilestoneLabelsParams = - & { - owner: string; - repo: string; - number: number; - }; - export type IssuesGetMilestonesParams = - & { - owner: string; - repo: string; - state?: "open"|"closed"|"all"; - sort?: "due_on"|"completeness"; - direction?: "asc"|"desc"; - page?: number; - per_page?: number; - }; - export type IssuesGetMilestoneParams = - & { - owner: string; - repo: string; - number: number; - }; - export type IssuesCreateMilestoneParams = - & { - owner: string; - repo: string; - title: string; - state?: "open"|"closed"|"all"; - description?: string; - due_on?: date; - }; - export type IssuesUpdateMilestoneParams = - & { - owner: string; - repo: string; - number: number; - title: string; - state?: "open"|"closed"|"all"; - description?: string; - due_on?: date; - }; - export type IssuesDeleteMilestoneParams = - & { - owner: string; - repo: string; - number: number; - }; - export type IssuesGetEventsTimelineParams = - & { - owner: string; - repo: string; - issue_number: number; - page?: number; - per_page?: number; - }; - export type MigrationsStartMigrationParams = - & { - org: string; - repositories: string[]; - lock_repositories?: boolean; - exclude_attachments?: boolean; - }; - export type MigrationsGetMigrationsParams = - & { - org: string; - page?: number; - per_page?: number; - }; - export type MigrationsGetMigrationStatusParams = - & { - org: string; - id: string; - }; - export type MigrationsGetMigrationArchiveLinkParams = - & { - org: string; - id: string; - }; - export type MigrationsDeleteMigrationArchiveParams = - & { - org: string; - id: string; - }; - export type MigrationsUnlockRepoLockedForMigrationParams = - & { - org: string; - id: string; - repo_name: string; - }; - export type MigrationsStartImportParams = - & { - owner: string; - repo: string; - vcs_url: string; - vcs?: "subversion"|"git"|"mercurial"|"tfvc"; - vcs_username?: string; - vcs_password?: string; - tfvc_project?: string; - }; - export type MigrationsGetImportProgressParams = - & { - owner: string; - repo: string; - }; - export type MigrationsUpdateImportParams = - & { - owner: string; - repo: string; - vcs_username?: string; - vcs_password?: string; - }; - export type MigrationsGetImportCommitAuthorsParams = - & { - owner: string; - repo: string; - since?: string; - }; - export type MigrationsMapImportCommitAuthorParams = - & { - owner: string; - repo: string; - author_id: string; - email?: string; - name?: string; - }; - export type MigrationsSetImportLfsPreferenceParams = - & { - owner: string; - name: string; - use_lfs: string; - }; - export type MigrationsGetLargeImportFilesParams = - & { - owner: string; - name: string; - }; - export type MigrationsCancelImportParams = - & { - owner: string; - repo: string; - }; - export type MiscGetCodeOfConductParams = - & { - key: string; - }; - export type MiscGetRepoCodeOfConductParams = - & { - owner: string; - repo: string; - }; - export type MiscGetGitignoreTemplateParams = - & { - name: string; - }; - export type MiscGetLicenseParams = - & { - license: string; - }; - export type MiscGetRepoLicenseParams = - & { - owner: string; - repo: string; - }; - export type MiscRenderMarkdownParams = - & { - text: string; - mode?: "markdown"|"gfm"; - context?: string; - }; - export type MiscRenderMarkdownRawParams = - & { - data: string; - }; - export type OrgsGetParams = - & { - org: string; - page?: number; - per_page?: number; - }; - export type OrgsUpdateParams = - & { - org: string; - billing_email?: string; - company?: string; - email?: string; - location?: string; - name?: string; - description?: string; - default_repository_permission?: "read"|"write"|"admin"|"none"; - members_can_create_repositories?: boolean; - }; - export type OrgsGetAllParams = - & { - since?: string; - page?: number; - per_page?: number; - }; - export type OrgsGetForUserParams = - & { - username: string; - page?: number; - per_page?: number; - }; - export type OrgsGetMembersParams = - & { - org: string; - filter?: "all"|"2fa_disabled"; - role?: "all"|"admin"|"member"; - page?: number; - per_page?: number; - }; - export type OrgsCheckMembershipParams = - & { - org: string; - username: string; - }; - export type OrgsRemoveMemberParams = - & { - org: string; - username: string; - }; - export type OrgsGetPublicMembersParams = - & { - org: string; - }; - export type OrgsCheckPublicMembershipParams = - & { - org: string; - username: string; - }; - export type OrgsPublicizeMembershipParams = - & { - org: string; - username: string; - }; - export type OrgsConcealMembershipParams = - & { - org: string; - username: string; - }; - export type OrgsGetOrgMembershipParams = - & { - org: string; - username: string; - }; - export type OrgsAddOrgMembershipParams = - & { - org: string; - username: string; - role: "admin"|"member"; - }; - export type OrgsRemoveOrgMembershipParams = - & { - org: string; - username: string; - }; - export type OrgsGetPendingOrgInvitesParams = - & { - org: string; - }; - export type OrgsGetOutsideCollaboratorsParams = - & { - org: string; - filter?: "all"|"2fa_disabled"; - page?: number; - per_page?: number; - }; - export type OrgsRemoveOutsideCollaboratorParams = - & { - org: string; - username: string; - }; - export type OrgsConvertMemberToOutsideCollaboratorParams = - & { - org: string; - username: string; - }; - export type OrgsGetTeamsParams = - & { - org: string; - page?: number; - per_page?: number; - }; - export type OrgsGetTeamParams = - & { - id: string; - }; - export type OrgsCreateTeamParams = - & { - org: string; - name: string; - description?: string; - maintainers?: string[]; - repo_names?: string[]; - privacy?: "secret"|"closed"; - parent_team_id?: string; - }; - export type OrgsEditTeamParams = - & { - id: string; - name: string; - description?: string; - privacy?: "secret"|"closed"; - parent_team_id?: string; - }; - export type OrgsDeleteTeamParams = - & { - id: string; - }; - export type OrgsGetTeamMembersParams = - & { - id: string; - role?: "member"|"maintainer"|"all"; - page?: number; - per_page?: number; - }; - export type OrgsGetChildTeamsParams = - & { - id: string; - page?: number; - per_page?: number; - }; - export type OrgsGetTeamMembershipParams = - & { - id: string; - username: string; - }; - export type OrgsAddTeamMembershipParams = - & { - id: string; - username: string; - role?: "member"|"maintainer"; - }; - export type OrgsRemoveTeamMembershipParams = - & { - id: string; - username: string; - }; - export type OrgsGetTeamReposParams = - & { - id: string; - page?: number; - per_page?: number; - }; - export type OrgsGetPendingTeamInvitesParams = - & { - id: string; - page?: number; - per_page?: number; - }; - export type OrgsCheckTeamRepoParams = - & { - id: string; - owner: string; - repo: string; - }; - export type OrgsAddTeamRepoParams = - & { - id: string; - org: string; - repo: string; - permission?: "pull"|"push"|"admin"; - }; - export type OrgsDeleteTeamRepoParams = - & { - id: string; - owner: string; - repo: string; - }; - export type OrgsGetHooksParams = - & { - org: string; - page?: number; - per_page?: number; - }; - export type OrgsGetHookParams = - & { - org: string; - id: string; - }; - export type OrgsCreateHookParams = - & { - org: string; - name: string; - config: json; - events?: string[]; - active?: boolean; - }; - export type OrgsEditHookParams = - & { - org: string; - id: string; - config: json; - events?: string[]; - active?: boolean; - }; - export type OrgsPingHookParams = - & { - org: string; - id: string; - }; - export type OrgsDeleteHookParams = - & { - org: string; - id: string; - }; - export type OrgsGetBlockedUsersParams = - & { - org: string; - page?: number; - per_page?: number; - }; - export type OrgsCheckBlockedUserParams = - & { - org: string; - username: string; - }; - export type OrgsBlockUserParams = - & { - org: string; - username: string; - }; - export type OrgsUnblockUserParams = - & { - org: string; - username: string; - }; - export type ProjectsGetRepoProjectsParams = - & { - owner: string; - repo: string; - state?: "open"|"closed"|"all"; - }; - export type ProjectsGetOrgProjectsParams = - & { - org: string; - state?: "open"|"closed"|"all"; - }; - export type ProjectsGetProjectParams = - & { - id: string; - }; - export type ProjectsCreateRepoProjectParams = - & { - owner: string; - repo: string; - name: string; - body?: string; - }; - export type ProjectsCreateOrgProjectParams = - & { - org: string; - name: string; - body?: string; - }; - export type ProjectsUpdateProjectParams = - & { - id: string; - name: string; - body?: string; - state?: "open"|"closed"|"all"; - }; - export type ProjectsDeleteProjectParams = - & { - id: string; - }; - export type ProjectsGetProjectCardsParams = - & { - column_id: string; - }; - export type ProjectsGetProjectCardParams = - & { - id: string; - }; - export type ProjectsCreateProjectCardParams = - & { - column_id: string; - note?: string; - content_id?: string; - content_type?: string; - }; - export type ProjectsUpdateProjectCardParams = - & { - id: string; - note?: string; - }; - export type ProjectsDeleteProjectCardParams = - & { - id: string; - }; - export type ProjectsMoveProjectCardParams = - & { - id: string; - position: string; - column_id?: string; - }; - export type ProjectsGetProjectColumnsParams = - & { - project_id: string; - }; - export type ProjectsGetProjectColumnParams = - & { - id: string; - }; - export type ProjectsCreateProjectColumnParams = - & { - project_id: string; - name: string; - }; - export type ProjectsUpdateProjectColumnParams = - & { - id: string; - name: string; - }; - export type ProjectsDeleteProjectColumnParams = - & { - id: string; - }; - export type ProjectsMoveProjectColumnParams = - & { - id: string; - position: string; - }; - export type PullRequestsGetParams = - & { - owner: string; - repo: string; - number: number; - }; - export type PullRequestsCreateParams = - & { - owner: string; - repo: string; - head: string; - base: string; - }; - export type PullRequestsUpdateParams = - & { - owner: string; - repo: string; - number: number; - title?: string; - body?: string; - state?: "open"|"closed"; - base?: string; - maintainer_can_modify?: boolean; - }; - export type PullRequestsMergeParams = - & { - owner: string; - repo: string; - number: number; - commit_title?: string; - commit_message?: string; - sha?: string; - merge_method?: "merge"|"squash"|"rebase"; - }; - export type PullRequestsGetAllParams = - & { - owner: string; - repo: string; - state?: "open"|"closed"|"all"; - head?: string; - base?: string; - sort?: "created"|"updated"|"popularity"|"long-running"; - direction?: "asc"|"desc"; - page?: number; - per_page?: number; - }; - export type PullRequestsCreateFromIssueParams = - & { - owner: string; - repo: string; - issue: number; - head: string; - base: string; - }; - export type PullRequestsGetCommitsParams = - & { - owner: string; - repo: string; - number: number; - page?: number; - per_page?: number; - }; - export type PullRequestsGetFilesParams = - & { - owner: string; - repo: string; - number: number; - page?: number; - per_page?: number; - }; - export type PullRequestsCheckMergedParams = - & { - owner: string; - repo: string; - number: number; - page?: number; - per_page?: number; - }; - export type PullRequestsGetReviewsParams = - & { - owner: string; - repo: string; - number: number; - page?: number; - per_page?: number; - }; - export type PullRequestsGetReviewParams = - & { - owner: string; - repo: string; - number: number; - id: string; - }; - export type PullRequestsDeletePendingReviewParams = - & { - owner: string; - repo: string; - number: number; - id: string; - }; - export type PullRequestsGetReviewCommentsParams = - & { - owner: string; - repo: string; - number: number; - id: string; - page?: number; - per_page?: number; - }; - export type PullRequestsCreateReviewParams = - & { - owner: string; - repo: string; - number: number; - commit_id?: string; - body?: string; - event?: "APPROVE"|"REQUEST_CHANGES"|"COMMENT"|"PENDING"; - comments?: string[]; - }; - export type PullRequestsSubmitReviewParams = - & { - owner: string; - repo: string; - number: number; - id: string; - body?: string; - event?: "APPROVE"|"REQUEST_CHANGES"|"COMMENT"|"PENDING"; - }; - export type PullRequestsDismissReviewParams = - & { - owner: string; - repo: string; - number: number; - id: string; - message?: string; - page?: number; - per_page?: number; - }; - export type PullRequestsGetCommentsParams = - & { - owner: string; - repo: string; - number: number; - page?: number; - per_page?: number; - }; - export type PullRequestsGetCommentsForRepoParams = - & { - owner: string; - repo: string; - sort?: "created"|"updated"; - direction?: "asc"|"desc"; - since?: date; - page?: number; - per_page?: number; - }; - export type PullRequestsGetCommentParams = - & { - owner: string; - repo: string; - id: string; - }; - export type PullRequestsCreateCommentParams = - & { - owner: string; - repo: string; - number: number; - body: string; - }; - export type PullRequestsCreateCommentReplyParams = - & { - owner: string; - repo: string; - number: number; - body: string; - in_reply_to: number; - }; - export type PullRequestsEditCommentParams = - & { - owner: string; - repo: string; - id: string; - body: string; - }; - export type PullRequestsDeleteCommentParams = - & { - owner: string; - repo: string; - id: string; - }; - export type PullRequestsGetReviewRequestsParams = - & { - owner: string; - repo: string; - number: number; - page?: number; - per_page?: number; - }; - export type PullRequestsCreateReviewRequestParams = - & { - owner: string; - repo: string; - number: number; - reviewers?: string[]; - team_reviewers?: string[]; - }; - export type PullRequestsDeleteReviewRequestParams = - & { - owner: string; - repo: string; - number: number; - reviewers?: string[]; - team_reviewers?: string[]; - }; - export type ReactionsDeleteParams = - & { - id: string; - }; - export type ReactionsGetForCommitCommentParams = - & { - owner: string; - repo: string; - id: string; - content?: "+1"|"-1"|"laugh"|"confused"|"heart"|"hooray"; - }; - export type ReactionsCreateForCommitCommentParams = - & { - owner: string; - repo: string; - id: string; - content: "+1"|"-1"|"laugh"|"confused"|"heart"|"hooray"; - }; - export type ReactionsGetForIssueParams = - & { - owner: string; - repo: string; - number: number; - content?: "+1"|"-1"|"laugh"|"confused"|"heart"|"hooray"; - }; - export type ReactionsCreateForIssueParams = - & { - owner: string; - repo: string; - number: number; - content: "+1"|"-1"|"laugh"|"confused"|"heart"|"hooray"; - }; - export type ReactionsGetForIssueCommentParams = - & { - owner: string; - repo: string; - id: string; - content?: "+1"|"-1"|"laugh"|"confused"|"heart"|"hooray"; - }; - export type ReactionsCreateForIssueCommentParams = - & { - owner: string; - repo: string; - id: string; - content: "+1"|"-1"|"laugh"|"confused"|"heart"|"hooray"; - }; - export type ReactionsGetForPullRequestReviewCommentParams = - & { - owner: string; - repo: string; - id: string; - content?: "+1"|"-1"|"laugh"|"confused"|"heart"|"hooray"; - }; - export type ReactionsCreateForPullRequestReviewCommentParams = - & { - owner: string; - repo: string; - id: string; - content: "+1"|"-1"|"laugh"|"confused"|"heart"|"hooray"; - }; - export type ReposCreateParams = - & { - name: string; - description?: string; - homepage?: string; - private?: boolean; - has_issues?: boolean; - has_projects?: boolean; - has_wiki?: boolean; - team_id?: number; - auto_init?: boolean; - gitignore_template?: string; - license_template?: string; - allow_squash_merge?: boolean; - allow_merge_commit?: boolean; - allow_rebase_merge?: boolean; - }; - export type ReposGetParams = - & { - owner: string; - repo: string; - }; - export type ReposEditParams = - & { - owner: string; - repo: string; - name: string; - description?: string; - homepage?: string; - private?: boolean; - has_issues?: boolean; - has_projects?: boolean; - has_wiki?: boolean; - default_branch?: string; - allow_squash_merge?: boolean; - allow_merge_commit?: boolean; - allow_rebase_merge?: boolean; - }; - export type ReposDeleteParams = - & { - owner: string; - repo: string; - }; - export type ReposForkParams = - & { - owner: string; - repo: string; - organization?: string; - }; - export type ReposMergeParams = - & { - owner: string; - repo: string; - base: string; - head: string; - commit_message?: string; - }; - export type ReposGetAllParams = - & { - visibility?: "all"|"public"|"private"; - affiliation?: string; - type?: "all"|"owner"|"public"|"private"|"member"; - sort?: "created"|"updated"|"pushed"|"full_name"; - direction?: "asc"|"desc"; - page?: number; - per_page?: number; - }; - export type ReposGetForUserParams = - & { - username: string; - type?: "all"|"owner"|"member"; - sort?: "created"|"updated"|"pushed"|"full_name"; - direction?: "asc"|"desc"; - page?: number; - per_page?: number; - }; - export type ReposGetForOrgParams = - & { - org: string; - type?: "all"|"public"|"private"|"forks"|"sources"|"member"; - page?: number; - per_page?: number; - }; - export type ReposGetPublicParams = - & { - since?: string; - page?: number; - per_page?: number; - }; - export type ReposCreateForOrgParams = - & { - org: string; - name: string; - description?: string; - homepage?: string; - private?: boolean; - has_issues?: boolean; - has_projects?: boolean; - has_wiki?: boolean; - team_id?: number; - auto_init?: boolean; - gitignore_template?: string; - license_template?: string; - allow_squash_merge?: boolean; - allow_merge_commit?: boolean; - allow_rebase_merge?: boolean; - }; - export type ReposGetByIdParams = - & { - id: string; - }; - export type ReposGetTopicsParams = - & { - owner: string; - repo: string; - page?: number; - per_page?: number; - }; - export type ReposReplaceTopicsParams = - & { - owner: string; - repo: string; - names: string[]; - }; - export type ReposGetContributorsParams = - & { - owner: string; - repo: string; - anon?: boolean; - page?: number; - per_page?: number; - }; - export type ReposGetLanguagesParams = - & { - owner: string; - repo: string; - page?: number; - per_page?: number; - }; - export type ReposGetTeamsParams = - & { - owner: string; - repo: string; - page?: number; - per_page?: number; - }; - export type ReposGetTagsParams = - & { - owner: string; - repo: string; - page?: number; - per_page?: number; - }; - export type ReposGetBranchesParams = - & { - owner: string; - repo: string; - protected?: boolean; - page?: number; - per_page?: number; - }; - export type ReposGetBranchParams = - & { - owner: string; - repo: string; - branch: string; - page?: number; - per_page?: number; - }; - export type ReposGetBranchProtectionParams = - & { - owner: string; - repo: string; - branch: string; - page?: number; - per_page?: number; - }; - export type ReposUpdateBranchProtectionParams = - & { - owner: string; - repo: string; - branch: string; - required_status_checks: json; - required_pull_request_reviews: json; - dismissal_restrictions?: json; - restrictions: json; - enforce_admins: boolean; - page?: number; - per_page?: number; - }; - export type ReposRemoveBranchProtectionParams = - & { - owner: string; - repo: string; - branch: string; - }; - export type ReposGetProtectedBranchRequiredStatusChecksParams = - & { - owner: string; - repo: string; - branch: string; - page?: number; - per_page?: number; - }; - export type ReposUpdateProtectedBranchRequiredStatusChecksParams = - & { - owner: string; - repo: string; - branch: string; - strict?: boolean; - contexts?: string[]; - }; - export type ReposRemoveProtectedBranchRequiredStatusChecksParams = - & { - owner: string; - repo: string; - branch: string; - }; - export type ReposGetProtectedBranchRequiredStatusChecksContextsParams = - & { - owner: string; - repo: string; - branch: string; - page?: number; - per_page?: number; - }; - export type ReposReplaceProtectedBranchRequiredStatusChecksContextsParams = - & { - owner: string; - repo: string; - branch: string; - contexts: string[]; - }; - export type ReposAddProtectedBranchRequiredStatusChecksContextsParams = - & { - owner: string; - repo: string; - branch: string; - contexts: string[]; - }; - export type ReposRemoveProtectedBranchRequiredStatusChecksContextsParams = - & { - owner: string; - repo: string; - branch: string; - contexts: string[]; - }; - export type ReposGetProtectedBranchPullRequestReviewEnforcementParams = - & { - owner: string; - repo: string; - branch: string; - page?: number; - per_page?: number; - }; - export type ReposUpdateProtectedBranchPullRequestReviewEnforcementParams = - & { - owner: string; - repo: string; - branch: string; - dismissal_restrictions?: json; - dismiss_stale_reviews?: boolean; - require_code_owner_reviews?: boolean; - }; - export type ReposRemoveProtectedBranchPullRequestReviewEnforcementParams = - & { - owner: string; - repo: string; - branch: string; - }; - export type ReposGetProtectedBranchAdminEnforcementParams = - & { - owner: string; - repo: string; - branch: string; - page?: number; - per_page?: number; - }; - export type ReposAddProtectedBranchAdminEnforcementParams = - & { - owner: string; - repo: string; - branch: string; - page?: number; - per_page?: number; - }; - export type ReposRemoveProtectedBranchAdminEnforcementParams = - & { - owner: string; - repo: string; - branch: string; - }; - export type ReposGetProtectedBranchRestrictionsParams = - & { - owner: string; - repo: string; - branch: string; - page?: number; - per_page?: number; - }; - export type ReposRemoveProtectedBranchRestrictionsParams = - & { - owner: string; - repo: string; - branch: string; - }; - export type ReposGetProtectedBranchTeamRestrictionsParams = - & { - owner: string; - repo: string; - branch: string; - page?: number; - per_page?: number; - }; - export type ReposReplaceProtectedBranchTeamRestrictionsParams = - & { - owner: string; - repo: string; - branch: string; - teams: string[]; - }; - export type ReposAddProtectedBranchTeamRestrictionsParams = - & { - owner: string; - repo: string; - branch: string; - teams: string[]; - }; - export type ReposRemoveProtectedBranchTeamRestrictionsParams = - & { - owner: string; - repo: string; - branch: string; - teams: string[]; - }; - export type ReposGetProtectedBranchUserRestrictionsParams = - & { - owner: string; - repo: string; - branch: string; - page?: number; - per_page?: number; - }; - export type ReposReplaceProtectedBranchUserRestrictionsParams = - & { - owner: string; - repo: string; - branch: string; - users: string[]; - }; - export type ReposAddProtectedBranchUserRestrictionsParams = - & { - owner: string; - repo: string; - branch: string; - users: string[]; - }; - export type ReposRemoveProtectedBranchUserRestrictionsParams = - & { - owner: string; - repo: string; - branch: string; - users: string[]; - }; - export type ReposGetCollaboratorsParams = - & { - owner: string; - repo: string; - affiliation?: "outside"|"all"|"direct"; - page?: number; - per_page?: number; - }; - export type ReposCheckCollaboratorParams = - & { - owner: string; - repo: string; - username: string; - }; - export type ReposReviewUserPermissionLevelParams = - & { - owner: string; - repo: string; - username: string; - }; - export type ReposAddCollaboratorParams = - & { - owner: string; - repo: string; - username: string; - permission?: "pull"|"push"|"admin"; - }; - export type ReposRemoveCollaboratorParams = - & { - owner: string; - repo: string; - username: string; - }; - export type ReposGetAllCommitCommentsParams = - & { - owner: string; - repo: string; - page?: number; - per_page?: number; - }; - export type ReposGetCommitCommentsParams = - & { - owner: string; - repo: string; - ref: string; - page?: number; - per_page?: number; - }; - export type ReposCreateCommitCommentParams = - & { - owner: string; - repo: string; - sha: string; - body: string; - path?: string; - position?: number; - }; - export type ReposGetCommitCommentParams = - & { - owner: string; - repo: string; - id: string; - }; - export type ReposUpdateCommitCommentParams = - & { - owner: string; - repo: string; - id: string; - body: string; - }; - export type ReposDeleteCommitCommentParams = - & { - owner: string; - repo: string; - id: string; - }; - export type ReposGetCommunityProfileMetricsParams = - & { - owner: string; - name: string; - }; - export type ReposGetCommitsParams = - & { - owner: string; - repo: string; - sha?: string; - path?: string; - author?: string; - since?: date; - until?: date; - page?: number; - per_page?: number; - }; - export type ReposGetCommitParams = - & { - owner: string; - repo: string; - sha: string; - }; - export type ReposGetShaOfCommitRefParams = - & { - owner: string; - repo: string; - ref: string; - }; - export type ReposCompareCommitsParams = - & { - owner: string; - repo: string; - base: string; - head: string; - }; - export type ReposGetReadmeParams = - & { - owner: string; - repo: string; - ref?: string; - }; - export type ReposGetContentParams = - & { - owner: string; - repo: string; - path: string; - ref?: string; - }; - export type ReposCreateFileParams = - & { - owner: string; - repo: string; - path: string; - message: string; - content: string; - branch?: string; - committer?: json; - author?: json; - }; - export type ReposUpdateFileParams = - & { - owner: string; - repo: string; - path: string; - message: string; - content: string; - sha: string; - branch?: string; - committer?: json; - author?: json; - }; - export type ReposDeleteFileParams = - & { - owner: string; - repo: string; - path: string; - message: string; - sha: string; - branch?: string; - committer?: json; - author?: json; - }; - export type ReposGetArchiveLinkParams = - & { - owner: string; - repo: string; - archive_format: "tarball"|"zipball"; - ref?: string; - }; - export type ReposGetDeployKeysParams = - & { - owner: string; - repo: string; - page?: number; - per_page?: number; - }; - export type ReposGetDeployKeyParams = - & { - owner: string; - repo: string; - id: string; - }; - export type ReposAddDeployKeyParams = - & { - owner: string; - repo: string; - title: string; - key: string; - read_only?: boolean; - }; - export type ReposDeleteDeployKeyParams = - & { - owner: string; - repo: string; - id: string; - }; - export type ReposGetDeploymentsParams = - & { - owner: string; - repo: string; - sha?: string; - ref?: string; - task?: string; - environment?: string; - page?: number; - per_page?: number; - }; - export type ReposGetDeploymentParams = - & { - owner: string; - repo: string; - deployment_id: string; - }; - export type ReposCreateDeploymentParams = - & { - owner: string; - repo: string; - ref: string; - task?: string; - auto_merge?: boolean; - required_contexts?: string[]; - payload?: string; - environment?: string; - description?: string; - transient_environment?: boolean; - production_environment?: boolean; - }; - export type ReposGetDeploymentStatusesParams = - & { - owner: string; - repo: string; - id: string; - }; - export type ReposGetDeploymentStatusParams = - & { - owner: string; - repo: string; - id: string; - status_id: string; - }; - export type ReposCreateDeploymentStatusParams = - & { - owner: string; - repo: string; - id: string; - state?: string; - target_url?: string; - log_url?: string; - description?: string; - environment_url?: string; - auto_inactive?: boolean; - }; - export type ReposGetDownloadsParams = - & { - owner: string; - repo: string; - page?: number; - per_page?: number; - }; - export type ReposGetDownloadParams = - & { - owner: string; - repo: string; - id: string; - }; - export type ReposDeleteDownloadParams = - & { - owner: string; - repo: string; - id: string; - }; - export type ReposGetForksParams = - & { - owner: string; - repo: string; - sort?: "newest"|"oldest"|"stargazers"; - page?: number; - per_page?: number; - }; - export type ReposGetInvitesParams = - & { - owner: string; - repo: string; - }; - export type ReposDeleteInviteParams = - & { - owner: string; - repo: string; - invitation_id: string; - }; - export type ReposUpdateInviteParams = - & { - owner: string; - repo: string; - invitation_id: string; - permissions?: "read"|"write"|"admin"; - }; - export type ReposGetPagesParams = - & { - owner: string; - repo: string; - page?: number; - per_page?: number; - }; - export type ReposRequestPageBuildParams = - & { - owner: string; - repo: string; - }; - export type ReposGetPagesBuildsParams = - & { - owner: string; - repo: string; - page?: number; - per_page?: number; - }; - export type ReposGetLatestPagesBuildParams = - & { - owner: string; - repo: string; - }; - export type ReposGetPagesBuildParams = - & { - owner: string; - repo: string; - id: string; - }; - export type ReposGetReleasesParams = - & { - owner: string; - repo: string; - page?: number; - per_page?: number; - }; - export type ReposGetReleaseParams = - & { - owner: string; - repo: string; - id: string; - }; - export type ReposGetLatestReleaseParams = - & { - owner: string; - repo: string; - }; - export type ReposGetReleaseByTagParams = - & { - owner: string; - repo: string; - tag: string; - }; - export type ReposCreateReleaseParams = - & { - owner: string; - repo: string; - tag_name: string; - target_commitish?: string; - name?: string; - body?: string; - draft?: boolean; - prerelease?: boolean; - }; - export type ReposEditReleaseParams = - & { - owner: string; - repo: string; - id: string; - tag_name: string; - target_commitish?: string; - name?: string; - body?: string; - draft?: boolean; - prerelease?: boolean; - }; - export type ReposDeleteReleaseParams = - & { - owner: string; - repo: string; - id: string; - }; - export type ReposGetAssetsParams = - & { - owner: string; - repo: string; - id: string; - }; - export type ReposUploadAssetParams = - & { - url: string; - file: string | object; - contentType: string; - contentLength: number; - name: string; - label?: string; - }; - export type ReposGetAssetParams = - & { - owner: string; - repo: string; - id: string; - }; - export type ReposEditAssetParams = - & { - owner: string; - repo: string; - id: string; - name: string; - label?: string; - }; - export type ReposDeleteAssetParams = - & { - owner: string; - repo: string; - id: string; - }; - export type ReposGetStatsContributorsParams = - & { - owner: string; - repo: string; - }; - export type ReposGetStatsCommitActivityParams = - & { - owner: string; - repo: string; - }; - export type ReposGetStatsCodeFrequencyParams = - & { - owner: string; - repo: string; - }; - export type ReposGetStatsParticipationParams = - & { - owner: string; - repo: string; - }; - export type ReposGetStatsPunchCardParams = - & { - owner: string; - repo: string; - }; - export type ReposCreateStatusParams = - & { - owner: string; - repo: string; - sha: string; - state: "pending"|"success"|"error"|"failure"; - target_url?: string; - description?: string; - context?: string; - }; - export type ReposGetStatusesParams = - & { - owner: string; - repo: string; - ref: string; - page?: number; - per_page?: number; - }; - export type ReposGetCombinedStatusForRefParams = - & { - owner: string; - repo: string; - ref: string; - page?: number; - per_page?: number; - }; - export type ReposGetReferrersParams = - & { - owner: string; - repo: string; - page?: number; - per_page?: number; - }; - export type ReposGetPathsParams = - & { - owner: string; - repo: string; - page?: number; - per_page?: number; - }; - export type ReposGetViewsParams = - & { - owner: string; - repo: string; - page?: number; - per_page?: number; - }; - export type ReposGetClonesParams = - & { - owner: string; - repo: string; - page?: number; - per_page?: number; - }; - export type ReposGetHooksParams = - & { - owner: string; - repo: string; - page?: number; - per_page?: number; - }; - export type ReposGetHookParams = - & { - owner: string; - repo: string; - id: string; - }; - export type ReposCreateHookParams = - & { - owner: string; - repo: string; - name: string; - config: json; - events?: string[]; - active?: boolean; - }; - export type ReposEditHookParams = - & { - owner: string; - repo: string; - id: string; - name: string; - config: json; - events?: string[]; - add_events?: string[]; - remove_events?: string[]; - active?: boolean; - }; - export type ReposTestHookParams = - & { - owner: string; - repo: string; - id: string; - }; - export type ReposPingHookParams = - & { - owner: string; - repo: string; - id: string; - }; - export type ReposDeleteHookParams = - & { - owner: string; - repo: string; - id: string; - }; - export type SearchReposParams = - & { - q: string; - sort?: "stars"|"forks"|"updated"; - order?: "asc"|"desc"; - page?: number; - per_page?: number; - }; - export type SearchCodeParams = - & { - q: string; - sort?: "indexed"; - order?: "asc"|"desc"; - page?: number; - per_page?: number; - }; - export type SearchCommitsParams = - & { - q: string; - sort?: "author-date"|"committer-date"; - order?: "asc"|"desc"; - page?: number; - per_page?: number; - }; - export type SearchIssuesParams = - & { - q: string; - sort?: "comments"|"created"|"updated"; - order?: "asc"|"desc"; - page?: number; - per_page?: number; - }; - export type SearchUsersParams = - & { - q: string; - sort?: "followers"|"repositories"|"joined"; - order?: "asc"|"desc"; - page?: number; - per_page?: number; - }; - export type SearchEmailParams = - & { - email: string; - }; - export type UsersUpdateParams = - & { - name?: string; - email?: string; - blog?: string; - company?: string; - location?: string; - hireable?: boolean; - bio?: string; - }; - export type UsersPromoteParams = - & { - username: string; - }; - export type UsersDemoteParams = - & { - username: string; - }; - export type UsersSuspendParams = - & { - username: string; - }; - export type UsersUnsuspendParams = - & { - username: string; - }; - export type UsersGetForUserParams = - & { - username: string; - }; - export type UsersGetByIdParams = - & { - id: string; - }; - export type UsersGetAllParams = - & { - since?: number; - }; - export type UsersGetOrgsParams = - & { - page?: number; - per_page?: number; - }; - export type UsersGetOrgMembershipsParams = - & { - state?: "active"|"pending"; - }; - export type UsersGetOrgMembershipParams = - & { - org: string; - }; - export type UsersEditOrgMembershipParams = - & { - org: string; - state: "active"; - }; - export type UsersGetTeamsParams = - & { - page?: number; - per_page?: number; - }; - export type UsersGetEmailsParams = - & { - page?: number; - per_page?: number; - }; - export type UsersGetPublicEmailsParams = - & { - page?: number; - per_page?: number; - }; - export type UsersAddEmailsParams = - & { - emails: string[]; - }; - export type UsersDeleteEmailsParams = - & { - emails: string[]; - }; - export type UsersGetFollowersForUserParams = - & { - username: string; - page?: number; - per_page?: number; - }; - export type UsersGetFollowersParams = - & { - page?: number; - per_page?: number; - }; - export type UsersGetFollowingForUserParams = - & { - username: string; - page?: number; - per_page?: number; - }; - export type UsersGetFollowingParams = - & { - page?: number; - per_page?: number; - }; - export type UsersCheckFollowingParams = - & { - username: string; - }; - export type UsersCheckIfOneFollowersOtherParams = - & { - username: string; - target_user: string; - }; - export type UsersFollowUserParams = - & { - username: string; - }; - export type UsersUnfollowUserParams = - & { - username: string; - }; - export type UsersGetKeysForUserParams = - & { - username: string; - page?: number; - per_page?: number; - }; - export type UsersGetKeysParams = - & { - page?: number; - per_page?: number; - }; - export type UsersGetKeyParams = - & { - id: string; - }; - export type UsersCreateKeyParams = - & { - title: string; - key: string; - }; - export type UsersDeleteKeyParams = - & { - id: string; - }; - export type UsersGetGpgKeysForUserParams = - & { - username: string; - page?: number; - per_page?: number; - }; - export type UsersGetGpgKeysParams = - & { - page?: number; - per_page?: number; - }; - export type UsersGetGpgKeyParams = - & { - id: string; - }; - export type UsersCreateGpgKeyParams = - & { - armored_public_key: string; - }; - export type UsersDeleteGpgKeyParams = - & { - id: string; - }; - export type UsersCheckBlockedUserParams = - & { - username: string; - }; - export type UsersBlockUserParams = - & { - username: string; - }; - export type UsersUnblockUserParams = - & { - username: string; - }; - export type UsersAcceptRepoInviteParams = - & { - invitation_id: string; - }; - export type UsersDeclineRepoInviteParams = - & { - invitation_id: string; - }; - export type UsersGetInstallationsParams = - & { - page?: number; - per_page?: number; - }; - export type UsersGetInstallationReposParams = - & { - installation_id: string; - page?: number; - per_page?: number; - }; - export type UsersAddRepoToInstallationParams = - & { - installation_id: string; - repository_id: string; - }; - export type UsersRemoveRepoFromInstallationParams = - & { - installation_id: string; - repository_id: string; - }; - export type UsersGetMarketplacePurchasesParams = - & { - page?: number; - per_page?: number; - }; - export type UsersGetMarketplaceStubbedPurchasesParams = - & { - page?: number; - per_page?: number; - }; - export type EnterpriseStatsParams = - & { - type: "issues"|"hooks"|"milestones"|"orgs"|"comments"|"pages"|"users"|"gists"|"pulls"|"repos"|"all"; - }; - export type EnterpriseUpdateLdapForUserParams = - & { - username: string; - ldap_dn: string; - }; - export type EnterpriseSyncLdapForUserParams = - & { - username: string; - }; - export type EnterpriseUpdateLdapForTeamParams = - & { - team_id: number; - ldap_dn: string; - }; - export type EnterpriseSyncLdapForTeamParams = - & { - team_id: number; - }; - export type EnterpriseGetPreReceiveEnvironmentParams = - & { - id: string; - }; - export type EnterpriseCreatePreReceiveEnvironmentParams = - & { - name: string; - image_url: string; - }; - export type EnterpriseEditPreReceiveEnvironmentParams = - & { - id: string; - name: string; - image_url: string; - }; - export type EnterpriseDeletePreReceiveEnvironmentParams = - & { - id: string; - }; - export type EnterpriseGetPreReceiveEnvironmentDownloadStatusParams = - & { - id: string; - }; - export type EnterpriseTriggerPreReceiveEnvironmentDownloadParams = - & { - id: string; - }; - export type EnterpriseGetPreReceiveHookParams = - & { - id: string; - }; - export type EnterpriseCreatePreReceiveHookParams = - & { - name: string; - script: string; - script_repository: json; - environment: json; - enforcement?: string; - allow_downstream_configuration?: boolean; - }; - export type EnterpriseEditPreReceiveHookParams = - & { - id: string; - hook: json; - }; - export type EnterpriseDeletePreReceiveHookParams = - & { - id: string; - }; - export type EnterpriseQueueIndexingJobParams = - & { - target: string; - }; - export type EnterpriseCreateOrgParams = - & { - login: string; - admin: string; - profile_name?: string; - }; -} - -declare class Github { - constructor(options?: Github.Options); - authenticate(auth: Github.Auth): void; - hasNextPage(link: Github.Link): string | undefined; - hasPreviousPage(link: Github.Link): string | undefined; - hasLastPage(link: Github.Link): string | undefined; - hasFirstPage(link: Github.Link): string | undefined; - - getNextPage(link: Github.Link, callback?: Github.Callback): Promise; - getNextPage(link: Github.Link, headers?: {[header: string]: any}, callback?: Github.Callback): Promise; - - getPreviousPage(link: Github.Link, callback?: Github.Callback): Promise; - getPreviousPage(link: Github.Link, headers?: {[header: string]: any}, callback?: Github.Callback): Promise; - - getLastPage(link: Github.Link, callback?: Github.Callback): Promise; - getLastPage(link: Github.Link, headers?: {[header: string]: any}, callback?: Github.Callback): Promise; - - getFirstPage(link: Github.Link, callback?: Github.Callback): Promise; - getFirstPage(link: Github.Link, headers?: {[header: string]: any}, callback?: Github.Callback): Promise; - - authorization: { - get(params: Github.AuthorizationGetParams, callback?: Github.Callback): Promise; - create(params: Github.AuthorizationCreateParams, callback?: Github.Callback): Promise; - update(params: Github.AuthorizationUpdateParams, callback?: Github.Callback): Promise; - delete(params: Github.AuthorizationDeleteParams, callback?: Github.Callback): Promise; - check(params: Github.AuthorizationCheckParams, callback?: Github.Callback): Promise; - reset(params: Github.AuthorizationResetParams, callback?: Github.Callback): Promise; - revoke(params: Github.AuthorizationRevokeParams, callback?: Github.Callback): Promise; - getGrants(params: Github.AuthorizationGetGrantsParams, callback?: Github.Callback): Promise; - getGrant(params: Github.AuthorizationGetGrantParams, callback?: Github.Callback): Promise; - deleteGrant(params: Github.AuthorizationDeleteGrantParams, callback?: Github.Callback): Promise; - getAll(params: Github.AuthorizationGetAllParams, callback?: Github.Callback): Promise; - getOrCreateAuthorizationForApp(params: Github.AuthorizationGetOrCreateAuthorizationForAppParams, callback?: Github.Callback): Promise; - getOrCreateAuthorizationForAppAndFingerprint(params: Github.AuthorizationGetOrCreateAuthorizationForAppAndFingerprintParams, callback?: Github.Callback): Promise; - revokeGrant(params: Github.AuthorizationRevokeGrantParams, callback?: Github.Callback): Promise; - }; - activity: { - getEvents(params: Github.ActivityGetEventsParams, callback?: Github.Callback): Promise; - getEventsForRepo(params: Github.ActivityGetEventsForRepoParams, callback?: Github.Callback): Promise; - getEventsForRepoIssues(params: Github.ActivityGetEventsForRepoIssuesParams, callback?: Github.Callback): Promise; - getEventsForRepoNetwork(params: Github.ActivityGetEventsForRepoNetworkParams, callback?: Github.Callback): Promise; - getEventsForOrg(params: Github.ActivityGetEventsForOrgParams, callback?: Github.Callback): Promise; - getEventsReceived(params: Github.ActivityGetEventsReceivedParams, callback?: Github.Callback): Promise; - getEventsReceivedPublic(params: Github.ActivityGetEventsReceivedPublicParams, callback?: Github.Callback): Promise; - getEventsForUser(params: Github.ActivityGetEventsForUserParams, callback?: Github.Callback): Promise; - getEventsForUserPublic(params: Github.ActivityGetEventsForUserPublicParams, callback?: Github.Callback): Promise; - getEventsForUserOrg(params: Github.ActivityGetEventsForUserOrgParams, callback?: Github.Callback): Promise; - getFeeds(params: Github.EmptyParams, callback?: Github.Callback): Promise; - getNotifications(params: Github.ActivityGetNotificationsParams, callback?: Github.Callback): Promise; - getNotificationsForUser(params: Github.ActivityGetNotificationsForUserParams, callback?: Github.Callback): Promise; - markNotificationsAsRead(params: Github.ActivityMarkNotificationsAsReadParams, callback?: Github.Callback): Promise; - markNotificationsAsReadForRepo(params: Github.ActivityMarkNotificationsAsReadForRepoParams, callback?: Github.Callback): Promise; - getNotificationThread(params: Github.ActivityGetNotificationThreadParams, callback?: Github.Callback): Promise; - markNotificationThreadAsRead(params: Github.ActivityMarkNotificationThreadAsReadParams, callback?: Github.Callback): Promise; - checkNotificationThreadSubscription(params: Github.ActivityCheckNotificationThreadSubscriptionParams, callback?: Github.Callback): Promise; - setNotificationThreadSubscription(params: Github.ActivitySetNotificationThreadSubscriptionParams, callback?: Github.Callback): Promise; - deleteNotificationThreadSubscription(params: Github.ActivityDeleteNotificationThreadSubscriptionParams, callback?: Github.Callback): Promise; - getStargazersForRepo(params: Github.ActivityGetStargazersForRepoParams, callback?: Github.Callback): Promise; - getStarredReposForUser(params: Github.ActivityGetStarredReposForUserParams, callback?: Github.Callback): Promise; - getStarredRepos(params: Github.ActivityGetStarredReposParams, callback?: Github.Callback): Promise; - checkStarringRepo(params: Github.ActivityCheckStarringRepoParams, callback?: Github.Callback): Promise; - starRepo(params: Github.ActivityStarRepoParams, callback?: Github.Callback): Promise; - unstarRepo(params: Github.ActivityUnstarRepoParams, callback?: Github.Callback): Promise; - getWatchersForRepo(params: Github.ActivityGetWatchersForRepoParams, callback?: Github.Callback): Promise; - getWatchedReposForUser(params: Github.ActivityGetWatchedReposForUserParams, callback?: Github.Callback): Promise; - getWatchedRepos(params: Github.ActivityGetWatchedReposParams, callback?: Github.Callback): Promise; - getRepoSubscription(params: Github.ActivityGetRepoSubscriptionParams, callback?: Github.Callback): Promise; - setRepoSubscription(params: Github.ActivitySetRepoSubscriptionParams, callback?: Github.Callback): Promise; - unwatchRepo(params: Github.ActivityUnwatchRepoParams, callback?: Github.Callback): Promise; - }; - gists: { - get(params: Github.GistsGetParams, callback?: Github.Callback): Promise; - create(params: Github.GistsCreateParams, callback?: Github.Callback): Promise; - edit(params: Github.GistsEditParams, callback?: Github.Callback): Promise; - star(params: Github.GistsStarParams, callback?: Github.Callback): Promise; - unstar(params: Github.GistsUnstarParams, callback?: Github.Callback): Promise; - fork(params: Github.GistsForkParams, callback?: Github.Callback): Promise; - delete(params: Github.GistsDeleteParams, callback?: Github.Callback): Promise; - getForUser(params: Github.GistsGetForUserParams, callback?: Github.Callback): Promise; - getAll(params: Github.GistsGetAllParams, callback?: Github.Callback): Promise; - getPublic(params: Github.GistsGetPublicParams, callback?: Github.Callback): Promise; - getStarred(params: Github.GistsGetStarredParams, callback?: Github.Callback): Promise; - getRevision(params: Github.GistsGetRevisionParams, callback?: Github.Callback): Promise; - getCommits(params: Github.GistsGetCommitsParams, callback?: Github.Callback): Promise; - checkStar(params: Github.GistsCheckStarParams, callback?: Github.Callback): Promise; - getForks(params: Github.GistsGetForksParams, callback?: Github.Callback): Promise; - getComments(params: Github.GistsGetCommentsParams, callback?: Github.Callback): Promise; - getComment(params: Github.GistsGetCommentParams, callback?: Github.Callback): Promise; - createComment(params: Github.GistsCreateCommentParams, callback?: Github.Callback): Promise; - editComment(params: Github.GistsEditCommentParams, callback?: Github.Callback): Promise; - deleteComment(params: Github.GistsDeleteCommentParams, callback?: Github.Callback): Promise; - }; - gitdata: { - getBlob(params: Github.GitdataGetBlobParams, callback?: Github.Callback): Promise; - createBlob(params: Github.GitdataCreateBlobParams, callback?: Github.Callback): Promise; - getCommit(params: Github.GitdataGetCommitParams, callback?: Github.Callback): Promise; - createCommit(params: Github.GitdataCreateCommitParams, callback?: Github.Callback): Promise; - getCommitSignatureVerification(params: Github.GitdataGetCommitSignatureVerificationParams, callback?: Github.Callback): Promise; - getReference(params: Github.GitdataGetReferenceParams, callback?: Github.Callback): Promise; - getReferences(params: Github.GitdataGetReferencesParams, callback?: Github.Callback): Promise; - getTags(params: Github.GitdataGetTagsParams, callback?: Github.Callback): Promise; - createReference(params: Github.GitdataCreateReferenceParams, callback?: Github.Callback): Promise; - updateReference(params: Github.GitdataUpdateReferenceParams, callback?: Github.Callback): Promise; - deleteReference(params: Github.GitdataDeleteReferenceParams, callback?: Github.Callback): Promise; - getTag(params: Github.GitdataGetTagParams, callback?: Github.Callback): Promise; - createTag(params: Github.GitdataCreateTagParams, callback?: Github.Callback): Promise; - getTagSignatureVerification(params: Github.GitdataGetTagSignatureVerificationParams, callback?: Github.Callback): Promise; - getTree(params: Github.GitdataGetTreeParams, callback?: Github.Callback): Promise; - createTree(params: Github.GitdataCreateTreeParams, callback?: Github.Callback): Promise; - }; - integrations: { - getInstallations(params: Github.IntegrationsGetInstallationsParams, callback?: Github.Callback): Promise; - createInstallationToken(params: Github.IntegrationsCreateInstallationTokenParams, callback?: Github.Callback): Promise; - getInstallationRepositories(params: Github.IntegrationsGetInstallationRepositoriesParams, callback?: Github.Callback): Promise; - addRepoToInstallation(params: Github.IntegrationsAddRepoToInstallationParams, callback?: Github.Callback): Promise; - removeRepoFromInstallation(params: Github.IntegrationsRemoveRepoFromInstallationParams, callback?: Github.Callback): Promise; - }; - apps: { - get(params: Github.EmptyParams, callback?: Github.Callback): Promise; - getForSlug(params: Github.AppsGetForSlugParams, callback?: Github.Callback): Promise; - getInstallations(params: Github.AppsGetInstallationsParams, callback?: Github.Callback): Promise; - getInstallation(params: Github.AppsGetInstallationParams, callback?: Github.Callback): Promise; - createInstallationToken(params: Github.AppsCreateInstallationTokenParams, callback?: Github.Callback): Promise; - getInstallationRepositories(params: Github.AppsGetInstallationRepositoriesParams, callback?: Github.Callback): Promise; - addRepoToInstallation(params: Github.AppsAddRepoToInstallationParams, callback?: Github.Callback): Promise; - removeRepoFromInstallation(params: Github.AppsRemoveRepoFromInstallationParams, callback?: Github.Callback): Promise; - getMarketplaceListingPlans(params: Github.AppsGetMarketplaceListingPlansParams, callback?: Github.Callback): Promise; - getMarketplaceListingStubbedPlans(params: Github.AppsGetMarketplaceListingStubbedPlansParams, callback?: Github.Callback): Promise; - getMarketplaceListingPlanAccounts(params: Github.AppsGetMarketplaceListingPlanAccountsParams, callback?: Github.Callback): Promise; - getMarketplaceListingStubbedPlanAccounts(params: Github.AppsGetMarketplaceListingStubbedPlanAccountsParams, callback?: Github.Callback): Promise; - checkMarketplaceListingAccount(params: Github.AppsCheckMarketplaceListingAccountParams, callback?: Github.Callback): Promise; - checkMarketplaceListingStubbedAccount(params: Github.AppsCheckMarketplaceListingStubbedAccountParams, callback?: Github.Callback): Promise; - }; - issues: { - get(params: Github.IssuesGetParams, callback?: Github.Callback): Promise; - create(params: Github.IssuesCreateParams, callback?: Github.Callback): Promise; - edit(params: Github.IssuesEditParams, callback?: Github.Callback): Promise; - lock(params: Github.IssuesLockParams, callback?: Github.Callback): Promise; - unlock(params: Github.IssuesUnlockParams, callback?: Github.Callback): Promise; - getAll(params: Github.IssuesGetAllParams, callback?: Github.Callback): Promise; - getForUser(params: Github.IssuesGetForUserParams, callback?: Github.Callback): Promise; - getForOrg(params: Github.IssuesGetForOrgParams, callback?: Github.Callback): Promise; - getForRepo(params: Github.IssuesGetForRepoParams, callback?: Github.Callback): Promise; - getAssignees(params: Github.IssuesGetAssigneesParams, callback?: Github.Callback): Promise; - checkAssignee(params: Github.IssuesCheckAssigneeParams, callback?: Github.Callback): Promise; - addAssigneesToIssue(params: Github.IssuesAddAssigneesToIssueParams, callback?: Github.Callback): Promise; - removeAssigneesFromIssue(params: Github.IssuesRemoveAssigneesFromIssueParams, callback?: Github.Callback): Promise; - getComments(params: Github.IssuesGetCommentsParams, callback?: Github.Callback): Promise; - getCommentsForRepo(params: Github.IssuesGetCommentsForRepoParams, callback?: Github.Callback): Promise; - getComment(params: Github.IssuesGetCommentParams, callback?: Github.Callback): Promise; - createComment(params: Github.IssuesCreateCommentParams, callback?: Github.Callback): Promise; - editComment(params: Github.IssuesEditCommentParams, callback?: Github.Callback): Promise; - deleteComment(params: Github.IssuesDeleteCommentParams, callback?: Github.Callback): Promise; - getEvents(params: Github.IssuesGetEventsParams, callback?: Github.Callback): Promise; - getEventsForRepo(params: Github.IssuesGetEventsForRepoParams, callback?: Github.Callback): Promise; - getEvent(params: Github.IssuesGetEventParams, callback?: Github.Callback): Promise; - getLabels(params: Github.IssuesGetLabelsParams, callback?: Github.Callback): Promise; - getLabel(params: Github.IssuesGetLabelParams, callback?: Github.Callback): Promise; - createLabel(params: Github.IssuesCreateLabelParams, callback?: Github.Callback): Promise; - updateLabel(params: Github.IssuesUpdateLabelParams, callback?: Github.Callback): Promise; - deleteLabel(params: Github.IssuesDeleteLabelParams, callback?: Github.Callback): Promise; - getIssueLabels(params: Github.IssuesGetIssueLabelsParams, callback?: Github.Callback): Promise; - addLabels(params: Github.IssuesAddLabelsParams, callback?: Github.Callback): Promise; - removeLabel(params: Github.IssuesRemoveLabelParams, callback?: Github.Callback): Promise; - replaceAllLabels(params: Github.IssuesReplaceAllLabelsParams, callback?: Github.Callback): Promise; - removeAllLabels(params: Github.IssuesRemoveAllLabelsParams, callback?: Github.Callback): Promise; - getMilestoneLabels(params: Github.IssuesGetMilestoneLabelsParams, callback?: Github.Callback): Promise; - getMilestones(params: Github.IssuesGetMilestonesParams, callback?: Github.Callback): Promise; - getMilestone(params: Github.IssuesGetMilestoneParams, callback?: Github.Callback): Promise; - createMilestone(params: Github.IssuesCreateMilestoneParams, callback?: Github.Callback): Promise; - updateMilestone(params: Github.IssuesUpdateMilestoneParams, callback?: Github.Callback): Promise; - deleteMilestone(params: Github.IssuesDeleteMilestoneParams, callback?: Github.Callback): Promise; - getEventsTimeline(params: Github.IssuesGetEventsTimelineParams, callback?: Github.Callback): Promise; - }; - migrations: { - startMigration(params: Github.MigrationsStartMigrationParams, callback?: Github.Callback): Promise; - getMigrations(params: Github.MigrationsGetMigrationsParams, callback?: Github.Callback): Promise; - getMigrationStatus(params: Github.MigrationsGetMigrationStatusParams, callback?: Github.Callback): Promise; - getMigrationArchiveLink(params: Github.MigrationsGetMigrationArchiveLinkParams, callback?: Github.Callback): Promise; - deleteMigrationArchive(params: Github.MigrationsDeleteMigrationArchiveParams, callback?: Github.Callback): Promise; - unlockRepoLockedForMigration(params: Github.MigrationsUnlockRepoLockedForMigrationParams, callback?: Github.Callback): Promise; - startImport(params: Github.MigrationsStartImportParams, callback?: Github.Callback): Promise; - getImportProgress(params: Github.MigrationsGetImportProgressParams, callback?: Github.Callback): Promise; - updateImport(params: Github.MigrationsUpdateImportParams, callback?: Github.Callback): Promise; - getImportCommitAuthors(params: Github.MigrationsGetImportCommitAuthorsParams, callback?: Github.Callback): Promise; - mapImportCommitAuthor(params: Github.MigrationsMapImportCommitAuthorParams, callback?: Github.Callback): Promise; - setImportLfsPreference(params: Github.MigrationsSetImportLfsPreferenceParams, callback?: Github.Callback): Promise; - getLargeImportFiles(params: Github.MigrationsGetLargeImportFilesParams, callback?: Github.Callback): Promise; - cancelImport(params: Github.MigrationsCancelImportParams, callback?: Github.Callback): Promise; - }; - misc: { - getCodesOfConduct(params: Github.EmptyParams, callback?: Github.Callback): Promise; - getCodeOfConduct(params: Github.MiscGetCodeOfConductParams, callback?: Github.Callback): Promise; - getRepoCodeOfConduct(params: Github.MiscGetRepoCodeOfConductParams, callback?: Github.Callback): Promise; - getEmojis(params: Github.EmptyParams, callback?: Github.Callback): Promise; - getGitignoreTemplates(params: Github.EmptyParams, callback?: Github.Callback): Promise; - getGitignoreTemplate(params: Github.MiscGetGitignoreTemplateParams, callback?: Github.Callback): Promise; - getLicenses(params: Github.EmptyParams, callback?: Github.Callback): Promise; - getLicense(params: Github.MiscGetLicenseParams, callback?: Github.Callback): Promise; - getRepoLicense(params: Github.MiscGetRepoLicenseParams, callback?: Github.Callback): Promise; - renderMarkdown(params: Github.MiscRenderMarkdownParams, callback?: Github.Callback): Promise; - renderMarkdownRaw(params: Github.MiscRenderMarkdownRawParams, callback?: Github.Callback): Promise; - getMeta(params: Github.EmptyParams, callback?: Github.Callback): Promise; - getRateLimit(params: Github.EmptyParams, callback?: Github.Callback): Promise; - }; - orgs: { - get(params: Github.OrgsGetParams, callback?: Github.Callback): Promise; - update(params: Github.OrgsUpdateParams, callback?: Github.Callback): Promise; - getAll(params: Github.OrgsGetAllParams, callback?: Github.Callback): Promise; - getForUser(params: Github.OrgsGetForUserParams, callback?: Github.Callback): Promise; - getMembers(params: Github.OrgsGetMembersParams, callback?: Github.Callback): Promise; - checkMembership(params: Github.OrgsCheckMembershipParams, callback?: Github.Callback): Promise; - removeMember(params: Github.OrgsRemoveMemberParams, callback?: Github.Callback): Promise; - getPublicMembers(params: Github.OrgsGetPublicMembersParams, callback?: Github.Callback): Promise; - checkPublicMembership(params: Github.OrgsCheckPublicMembershipParams, callback?: Github.Callback): Promise; - publicizeMembership(params: Github.OrgsPublicizeMembershipParams, callback?: Github.Callback): Promise; - concealMembership(params: Github.OrgsConcealMembershipParams, callback?: Github.Callback): Promise; - getOrgMembership(params: Github.OrgsGetOrgMembershipParams, callback?: Github.Callback): Promise; - addOrgMembership(params: Github.OrgsAddOrgMembershipParams, callback?: Github.Callback): Promise; - removeOrgMembership(params: Github.OrgsRemoveOrgMembershipParams, callback?: Github.Callback): Promise; - getPendingOrgInvites(params: Github.OrgsGetPendingOrgInvitesParams, callback?: Github.Callback): Promise; - getOutsideCollaborators(params: Github.OrgsGetOutsideCollaboratorsParams, callback?: Github.Callback): Promise; - removeOutsideCollaborator(params: Github.OrgsRemoveOutsideCollaboratorParams, callback?: Github.Callback): Promise; - convertMemberToOutsideCollaborator(params: Github.OrgsConvertMemberToOutsideCollaboratorParams, callback?: Github.Callback): Promise; - getTeams(params: Github.OrgsGetTeamsParams, callback?: Github.Callback): Promise; - getTeam(params: Github.OrgsGetTeamParams, callback?: Github.Callback): Promise; - createTeam(params: Github.OrgsCreateTeamParams, callback?: Github.Callback): Promise; - editTeam(params: Github.OrgsEditTeamParams, callback?: Github.Callback): Promise; - deleteTeam(params: Github.OrgsDeleteTeamParams, callback?: Github.Callback): Promise; - getTeamMembers(params: Github.OrgsGetTeamMembersParams, callback?: Github.Callback): Promise; - getChildTeams(params: Github.OrgsGetChildTeamsParams, callback?: Github.Callback): Promise; - getTeamMembership(params: Github.OrgsGetTeamMembershipParams, callback?: Github.Callback): Promise; - addTeamMembership(params: Github.OrgsAddTeamMembershipParams, callback?: Github.Callback): Promise; - removeTeamMembership(params: Github.OrgsRemoveTeamMembershipParams, callback?: Github.Callback): Promise; - getTeamRepos(params: Github.OrgsGetTeamReposParams, callback?: Github.Callback): Promise; - getPendingTeamInvites(params: Github.OrgsGetPendingTeamInvitesParams, callback?: Github.Callback): Promise; - checkTeamRepo(params: Github.OrgsCheckTeamRepoParams, callback?: Github.Callback): Promise; - addTeamRepo(params: Github.OrgsAddTeamRepoParams, callback?: Github.Callback): Promise; - deleteTeamRepo(params: Github.OrgsDeleteTeamRepoParams, callback?: Github.Callback): Promise; - getHooks(params: Github.OrgsGetHooksParams, callback?: Github.Callback): Promise; - getHook(params: Github.OrgsGetHookParams, callback?: Github.Callback): Promise; - createHook(params: Github.OrgsCreateHookParams, callback?: Github.Callback): Promise; - editHook(params: Github.OrgsEditHookParams, callback?: Github.Callback): Promise; - pingHook(params: Github.OrgsPingHookParams, callback?: Github.Callback): Promise; - deleteHook(params: Github.OrgsDeleteHookParams, callback?: Github.Callback): Promise; - getBlockedUsers(params: Github.OrgsGetBlockedUsersParams, callback?: Github.Callback): Promise; - checkBlockedUser(params: Github.OrgsCheckBlockedUserParams, callback?: Github.Callback): Promise; - blockUser(params: Github.OrgsBlockUserParams, callback?: Github.Callback): Promise; - unblockUser(params: Github.OrgsUnblockUserParams, callback?: Github.Callback): Promise; - }; - projects: { - getRepoProjects(params: Github.ProjectsGetRepoProjectsParams, callback?: Github.Callback): Promise; - getOrgProjects(params: Github.ProjectsGetOrgProjectsParams, callback?: Github.Callback): Promise; - getProject(params: Github.ProjectsGetProjectParams, callback?: Github.Callback): Promise; - createRepoProject(params: Github.ProjectsCreateRepoProjectParams, callback?: Github.Callback): Promise; - createOrgProject(params: Github.ProjectsCreateOrgProjectParams, callback?: Github.Callback): Promise; - updateProject(params: Github.ProjectsUpdateProjectParams, callback?: Github.Callback): Promise; - deleteProject(params: Github.ProjectsDeleteProjectParams, callback?: Github.Callback): Promise; - getProjectCards(params: Github.ProjectsGetProjectCardsParams, callback?: Github.Callback): Promise; - getProjectCard(params: Github.ProjectsGetProjectCardParams, callback?: Github.Callback): Promise; - createProjectCard(params: Github.ProjectsCreateProjectCardParams, callback?: Github.Callback): Promise; - updateProjectCard(params: Github.ProjectsUpdateProjectCardParams, callback?: Github.Callback): Promise; - deleteProjectCard(params: Github.ProjectsDeleteProjectCardParams, callback?: Github.Callback): Promise; - moveProjectCard(params: Github.ProjectsMoveProjectCardParams, callback?: Github.Callback): Promise; - getProjectColumns(params: Github.ProjectsGetProjectColumnsParams, callback?: Github.Callback): Promise; - getProjectColumn(params: Github.ProjectsGetProjectColumnParams, callback?: Github.Callback): Promise; - createProjectColumn(params: Github.ProjectsCreateProjectColumnParams, callback?: Github.Callback): Promise; - updateProjectColumn(params: Github.ProjectsUpdateProjectColumnParams, callback?: Github.Callback): Promise; - deleteProjectColumn(params: Github.ProjectsDeleteProjectColumnParams, callback?: Github.Callback): Promise; - moveProjectColumn(params: Github.ProjectsMoveProjectColumnParams, callback?: Github.Callback): Promise; - }; - pullRequests: { - get(params: Github.PullRequestsGetParams, callback?: Github.Callback): Promise; - create(params: Github.PullRequestsCreateParams, callback?: Github.Callback): Promise; - update(params: Github.PullRequestsUpdateParams, callback?: Github.Callback): Promise; - merge(params: Github.PullRequestsMergeParams, callback?: Github.Callback): Promise; - getAll(params: Github.PullRequestsGetAllParams, callback?: Github.Callback): Promise; - createFromIssue(params: Github.PullRequestsCreateFromIssueParams, callback?: Github.Callback): Promise; - getCommits(params: Github.PullRequestsGetCommitsParams, callback?: Github.Callback): Promise; - getFiles(params: Github.PullRequestsGetFilesParams, callback?: Github.Callback): Promise; - checkMerged(params: Github.PullRequestsCheckMergedParams, callback?: Github.Callback): Promise; - getReviews(params: Github.PullRequestsGetReviewsParams, callback?: Github.Callback): Promise; - getReview(params: Github.PullRequestsGetReviewParams, callback?: Github.Callback): Promise; - deletePendingReview(params: Github.PullRequestsDeletePendingReviewParams, callback?: Github.Callback): Promise; - getReviewComments(params: Github.PullRequestsGetReviewCommentsParams, callback?: Github.Callback): Promise; - createReview(params: Github.PullRequestsCreateReviewParams, callback?: Github.Callback): Promise; - submitReview(params: Github.PullRequestsSubmitReviewParams, callback?: Github.Callback): Promise; - dismissReview(params: Github.PullRequestsDismissReviewParams, callback?: Github.Callback): Promise; - getComments(params: Github.PullRequestsGetCommentsParams, callback?: Github.Callback): Promise; - getCommentsForRepo(params: Github.PullRequestsGetCommentsForRepoParams, callback?: Github.Callback): Promise; - getComment(params: Github.PullRequestsGetCommentParams, callback?: Github.Callback): Promise; - createComment(params: Github.PullRequestsCreateCommentParams, callback?: Github.Callback): Promise; - createCommentReply(params: Github.PullRequestsCreateCommentReplyParams, callback?: Github.Callback): Promise; - editComment(params: Github.PullRequestsEditCommentParams, callback?: Github.Callback): Promise; - deleteComment(params: Github.PullRequestsDeleteCommentParams, callback?: Github.Callback): Promise; - getReviewRequests(params: Github.PullRequestsGetReviewRequestsParams, callback?: Github.Callback): Promise; - createReviewRequest(params: Github.PullRequestsCreateReviewRequestParams, callback?: Github.Callback): Promise; - deleteReviewRequest(params: Github.PullRequestsDeleteReviewRequestParams, callback?: Github.Callback): Promise; - }; - reactions: { - delete(params: Github.ReactionsDeleteParams, callback?: Github.Callback): Promise; - getForCommitComment(params: Github.ReactionsGetForCommitCommentParams, callback?: Github.Callback): Promise; - createForCommitComment(params: Github.ReactionsCreateForCommitCommentParams, callback?: Github.Callback): Promise; - getForIssue(params: Github.ReactionsGetForIssueParams, callback?: Github.Callback): Promise; - createForIssue(params: Github.ReactionsCreateForIssueParams, callback?: Github.Callback): Promise; - getForIssueComment(params: Github.ReactionsGetForIssueCommentParams, callback?: Github.Callback): Promise; - createForIssueComment(params: Github.ReactionsCreateForIssueCommentParams, callback?: Github.Callback): Promise; - getForPullRequestReviewComment(params: Github.ReactionsGetForPullRequestReviewCommentParams, callback?: Github.Callback): Promise; - createForPullRequestReviewComment(params: Github.ReactionsCreateForPullRequestReviewCommentParams, callback?: Github.Callback): Promise; - }; - repos: { - create(params: Github.ReposCreateParams, callback?: Github.Callback): Promise; - get(params: Github.ReposGetParams, callback?: Github.Callback): Promise; - edit(params: Github.ReposEditParams, callback?: Github.Callback): Promise; - delete(params: Github.ReposDeleteParams, callback?: Github.Callback): Promise; - fork(params: Github.ReposForkParams, callback?: Github.Callback): Promise; - merge(params: Github.ReposMergeParams, callback?: Github.Callback): Promise; - getAll(params: Github.ReposGetAllParams, callback?: Github.Callback): Promise; - getForUser(params: Github.ReposGetForUserParams, callback?: Github.Callback): Promise; - getForOrg(params: Github.ReposGetForOrgParams, callback?: Github.Callback): Promise; - getPublic(params: Github.ReposGetPublicParams, callback?: Github.Callback): Promise; - createForOrg(params: Github.ReposCreateForOrgParams, callback?: Github.Callback): Promise; - getById(params: Github.ReposGetByIdParams, callback?: Github.Callback): Promise; - getTopics(params: Github.ReposGetTopicsParams, callback?: Github.Callback): Promise; - replaceTopics(params: Github.ReposReplaceTopicsParams, callback?: Github.Callback): Promise; - getContributors(params: Github.ReposGetContributorsParams, callback?: Github.Callback): Promise; - getLanguages(params: Github.ReposGetLanguagesParams, callback?: Github.Callback): Promise; - getTeams(params: Github.ReposGetTeamsParams, callback?: Github.Callback): Promise; - getTags(params: Github.ReposGetTagsParams, callback?: Github.Callback): Promise; - getBranches(params: Github.ReposGetBranchesParams, callback?: Github.Callback): Promise; - getBranch(params: Github.ReposGetBranchParams, callback?: Github.Callback): Promise; - getBranchProtection(params: Github.ReposGetBranchProtectionParams, callback?: Github.Callback): Promise; - updateBranchProtection(params: Github.ReposUpdateBranchProtectionParams, callback?: Github.Callback): Promise; - removeBranchProtection(params: Github.ReposRemoveBranchProtectionParams, callback?: Github.Callback): Promise; - getProtectedBranchRequiredStatusChecks(params: Github.ReposGetProtectedBranchRequiredStatusChecksParams, callback?: Github.Callback): Promise; - updateProtectedBranchRequiredStatusChecks(params: Github.ReposUpdateProtectedBranchRequiredStatusChecksParams, callback?: Github.Callback): Promise; - removeProtectedBranchRequiredStatusChecks(params: Github.ReposRemoveProtectedBranchRequiredStatusChecksParams, callback?: Github.Callback): Promise; - getProtectedBranchRequiredStatusChecksContexts(params: Github.ReposGetProtectedBranchRequiredStatusChecksContextsParams, callback?: Github.Callback): Promise; - replaceProtectedBranchRequiredStatusChecksContexts(params: Github.ReposReplaceProtectedBranchRequiredStatusChecksContextsParams, callback?: Github.Callback): Promise; - addProtectedBranchRequiredStatusChecksContexts(params: Github.ReposAddProtectedBranchRequiredStatusChecksContextsParams, callback?: Github.Callback): Promise; - removeProtectedBranchRequiredStatusChecksContexts(params: Github.ReposRemoveProtectedBranchRequiredStatusChecksContextsParams, callback?: Github.Callback): Promise; - getProtectedBranchPullRequestReviewEnforcement(params: Github.ReposGetProtectedBranchPullRequestReviewEnforcementParams, callback?: Github.Callback): Promise; - updateProtectedBranchPullRequestReviewEnforcement(params: Github.ReposUpdateProtectedBranchPullRequestReviewEnforcementParams, callback?: Github.Callback): Promise; - removeProtectedBranchPullRequestReviewEnforcement(params: Github.ReposRemoveProtectedBranchPullRequestReviewEnforcementParams, callback?: Github.Callback): Promise; - getProtectedBranchAdminEnforcement(params: Github.ReposGetProtectedBranchAdminEnforcementParams, callback?: Github.Callback): Promise; - addProtectedBranchAdminEnforcement(params: Github.ReposAddProtectedBranchAdminEnforcementParams, callback?: Github.Callback): Promise; - removeProtectedBranchAdminEnforcement(params: Github.ReposRemoveProtectedBranchAdminEnforcementParams, callback?: Github.Callback): Promise; - getProtectedBranchRestrictions(params: Github.ReposGetProtectedBranchRestrictionsParams, callback?: Github.Callback): Promise; - removeProtectedBranchRestrictions(params: Github.ReposRemoveProtectedBranchRestrictionsParams, callback?: Github.Callback): Promise; - getProtectedBranchTeamRestrictions(params: Github.ReposGetProtectedBranchTeamRestrictionsParams, callback?: Github.Callback): Promise; - replaceProtectedBranchTeamRestrictions(params: Github.ReposReplaceProtectedBranchTeamRestrictionsParams, callback?: Github.Callback): Promise; - addProtectedBranchTeamRestrictions(params: Github.ReposAddProtectedBranchTeamRestrictionsParams, callback?: Github.Callback): Promise; - removeProtectedBranchTeamRestrictions(params: Github.ReposRemoveProtectedBranchTeamRestrictionsParams, callback?: Github.Callback): Promise; - getProtectedBranchUserRestrictions(params: Github.ReposGetProtectedBranchUserRestrictionsParams, callback?: Github.Callback): Promise; - replaceProtectedBranchUserRestrictions(params: Github.ReposReplaceProtectedBranchUserRestrictionsParams, callback?: Github.Callback): Promise; - addProtectedBranchUserRestrictions(params: Github.ReposAddProtectedBranchUserRestrictionsParams, callback?: Github.Callback): Promise; - removeProtectedBranchUserRestrictions(params: Github.ReposRemoveProtectedBranchUserRestrictionsParams, callback?: Github.Callback): Promise; - getCollaborators(params: Github.ReposGetCollaboratorsParams, callback?: Github.Callback): Promise; - checkCollaborator(params: Github.ReposCheckCollaboratorParams, callback?: Github.Callback): Promise; - reviewUserPermissionLevel(params: Github.ReposReviewUserPermissionLevelParams, callback?: Github.Callback): Promise; - addCollaborator(params: Github.ReposAddCollaboratorParams, callback?: Github.Callback): Promise; - removeCollaborator(params: Github.ReposRemoveCollaboratorParams, callback?: Github.Callback): Promise; - getAllCommitComments(params: Github.ReposGetAllCommitCommentsParams, callback?: Github.Callback): Promise; - getCommitComments(params: Github.ReposGetCommitCommentsParams, callback?: Github.Callback): Promise; - createCommitComment(params: Github.ReposCreateCommitCommentParams, callback?: Github.Callback): Promise; - getCommitComment(params: Github.ReposGetCommitCommentParams, callback?: Github.Callback): Promise; - updateCommitComment(params: Github.ReposUpdateCommitCommentParams, callback?: Github.Callback): Promise; - deleteCommitComment(params: Github.ReposDeleteCommitCommentParams, callback?: Github.Callback): Promise; - getCommunityProfileMetrics(params: Github.ReposGetCommunityProfileMetricsParams, callback?: Github.Callback): Promise; - getCommits(params: Github.ReposGetCommitsParams, callback?: Github.Callback): Promise; - getCommit(params: Github.ReposGetCommitParams, callback?: Github.Callback): Promise; - getShaOfCommitRef(params: Github.ReposGetShaOfCommitRefParams, callback?: Github.Callback): Promise; - compareCommits(params: Github.ReposCompareCommitsParams, callback?: Github.Callback): Promise; - getReadme(params: Github.ReposGetReadmeParams, callback?: Github.Callback): Promise; - getContent(params: Github.ReposGetContentParams, callback?: Github.Callback): Promise; - createFile(params: Github.ReposCreateFileParams, callback?: Github.Callback): Promise; - updateFile(params: Github.ReposUpdateFileParams, callback?: Github.Callback): Promise; - deleteFile(params: Github.ReposDeleteFileParams, callback?: Github.Callback): Promise; - getArchiveLink(params: Github.ReposGetArchiveLinkParams, callback?: Github.Callback): Promise; - getDeployKeys(params: Github.ReposGetDeployKeysParams, callback?: Github.Callback): Promise; - getDeployKey(params: Github.ReposGetDeployKeyParams, callback?: Github.Callback): Promise; - addDeployKey(params: Github.ReposAddDeployKeyParams, callback?: Github.Callback): Promise; - deleteDeployKey(params: Github.ReposDeleteDeployKeyParams, callback?: Github.Callback): Promise; - getDeployments(params: Github.ReposGetDeploymentsParams, callback?: Github.Callback): Promise; - getDeployment(params: Github.ReposGetDeploymentParams, callback?: Github.Callback): Promise; - createDeployment(params: Github.ReposCreateDeploymentParams, callback?: Github.Callback): Promise; - getDeploymentStatuses(params: Github.ReposGetDeploymentStatusesParams, callback?: Github.Callback): Promise; - getDeploymentStatus(params: Github.ReposGetDeploymentStatusParams, callback?: Github.Callback): Promise; - createDeploymentStatus(params: Github.ReposCreateDeploymentStatusParams, callback?: Github.Callback): Promise; - getDownloads(params: Github.ReposGetDownloadsParams, callback?: Github.Callback): Promise; - getDownload(params: Github.ReposGetDownloadParams, callback?: Github.Callback): Promise; - deleteDownload(params: Github.ReposDeleteDownloadParams, callback?: Github.Callback): Promise; - getForks(params: Github.ReposGetForksParams, callback?: Github.Callback): Promise; - getInvites(params: Github.ReposGetInvitesParams, callback?: Github.Callback): Promise; - deleteInvite(params: Github.ReposDeleteInviteParams, callback?: Github.Callback): Promise; - updateInvite(params: Github.ReposUpdateInviteParams, callback?: Github.Callback): Promise; - getPages(params: Github.ReposGetPagesParams, callback?: Github.Callback): Promise; - requestPageBuild(params: Github.ReposRequestPageBuildParams, callback?: Github.Callback): Promise; - getPagesBuilds(params: Github.ReposGetPagesBuildsParams, callback?: Github.Callback): Promise; - getLatestPagesBuild(params: Github.ReposGetLatestPagesBuildParams, callback?: Github.Callback): Promise; - getPagesBuild(params: Github.ReposGetPagesBuildParams, callback?: Github.Callback): Promise; - getReleases(params: Github.ReposGetReleasesParams, callback?: Github.Callback): Promise; - getRelease(params: Github.ReposGetReleaseParams, callback?: Github.Callback): Promise; - getLatestRelease(params: Github.ReposGetLatestReleaseParams, callback?: Github.Callback): Promise; - getReleaseByTag(params: Github.ReposGetReleaseByTagParams, callback?: Github.Callback): Promise; - createRelease(params: Github.ReposCreateReleaseParams, callback?: Github.Callback): Promise; - editRelease(params: Github.ReposEditReleaseParams, callback?: Github.Callback): Promise; - deleteRelease(params: Github.ReposDeleteReleaseParams, callback?: Github.Callback): Promise; - getAssets(params: Github.ReposGetAssetsParams, callback?: Github.Callback): Promise; - uploadAsset(params: Github.ReposUploadAssetParams, callback?: Github.Callback): Promise; - getAsset(params: Github.ReposGetAssetParams, callback?: Github.Callback): Promise; - editAsset(params: Github.ReposEditAssetParams, callback?: Github.Callback): Promise; - deleteAsset(params: Github.ReposDeleteAssetParams, callback?: Github.Callback): Promise; - getStatsContributors(params: Github.ReposGetStatsContributorsParams, callback?: Github.Callback): Promise; - getStatsCommitActivity(params: Github.ReposGetStatsCommitActivityParams, callback?: Github.Callback): Promise; - getStatsCodeFrequency(params: Github.ReposGetStatsCodeFrequencyParams, callback?: Github.Callback): Promise; - getStatsParticipation(params: Github.ReposGetStatsParticipationParams, callback?: Github.Callback): Promise; - getStatsPunchCard(params: Github.ReposGetStatsPunchCardParams, callback?: Github.Callback): Promise; - createStatus(params: Github.ReposCreateStatusParams, callback?: Github.Callback): Promise; - getStatuses(params: Github.ReposGetStatusesParams, callback?: Github.Callback): Promise; - getCombinedStatusForRef(params: Github.ReposGetCombinedStatusForRefParams, callback?: Github.Callback): Promise; - getReferrers(params: Github.ReposGetReferrersParams, callback?: Github.Callback): Promise; - getPaths(params: Github.ReposGetPathsParams, callback?: Github.Callback): Promise; - getViews(params: Github.ReposGetViewsParams, callback?: Github.Callback): Promise; - getClones(params: Github.ReposGetClonesParams, callback?: Github.Callback): Promise; - getHooks(params: Github.ReposGetHooksParams, callback?: Github.Callback): Promise; - getHook(params: Github.ReposGetHookParams, callback?: Github.Callback): Promise; - createHook(params: Github.ReposCreateHookParams, callback?: Github.Callback): Promise; - editHook(params: Github.ReposEditHookParams, callback?: Github.Callback): Promise; - testHook(params: Github.ReposTestHookParams, callback?: Github.Callback): Promise; - pingHook(params: Github.ReposPingHookParams, callback?: Github.Callback): Promise; - deleteHook(params: Github.ReposDeleteHookParams, callback?: Github.Callback): Promise; - }; - search: { - repos(params: Github.SearchReposParams, callback?: Github.Callback): Promise; - code(params: Github.SearchCodeParams, callback?: Github.Callback): Promise; - commits(params: Github.SearchCommitsParams, callback?: Github.Callback): Promise; - issues(params: Github.SearchIssuesParams, callback?: Github.Callback): Promise; - users(params: Github.SearchUsersParams, callback?: Github.Callback): Promise; - email(params: Github.SearchEmailParams, callback?: Github.Callback): Promise; - }; - users: { - get(params: Github.EmptyParams, callback?: Github.Callback): Promise; - update(params: Github.UsersUpdateParams, callback?: Github.Callback): Promise; - promote(params: Github.UsersPromoteParams, callback?: Github.Callback): Promise; - demote(params: Github.UsersDemoteParams, callback?: Github.Callback): Promise; - suspend(params: Github.UsersSuspendParams, callback?: Github.Callback): Promise; - unsuspend(params: Github.UsersUnsuspendParams, callback?: Github.Callback): Promise; - getForUser(params: Github.UsersGetForUserParams, callback?: Github.Callback): Promise; - getById(params: Github.UsersGetByIdParams, callback?: Github.Callback): Promise; - getAll(params: Github.UsersGetAllParams, callback?: Github.Callback): Promise; - getOrgs(params: Github.UsersGetOrgsParams, callback?: Github.Callback): Promise; - getOrgMemberships(params: Github.UsersGetOrgMembershipsParams, callback?: Github.Callback): Promise; - getOrgMembership(params: Github.UsersGetOrgMembershipParams, callback?: Github.Callback): Promise; - editOrgMembership(params: Github.UsersEditOrgMembershipParams, callback?: Github.Callback): Promise; - getTeams(params: Github.UsersGetTeamsParams, callback?: Github.Callback): Promise; - getEmails(params: Github.UsersGetEmailsParams, callback?: Github.Callback): Promise; - getPublicEmails(params: Github.UsersGetPublicEmailsParams, callback?: Github.Callback): Promise; - addEmails(params: Github.UsersAddEmailsParams, callback?: Github.Callback): Promise; - deleteEmails(params: Github.UsersDeleteEmailsParams, callback?: Github.Callback): Promise; - togglePrimaryEmailVisibility(params: Github.EmptyParams, callback?: Github.Callback): Promise; - getFollowersForUser(params: Github.UsersGetFollowersForUserParams, callback?: Github.Callback): Promise; - getFollowers(params: Github.UsersGetFollowersParams, callback?: Github.Callback): Promise; - getFollowingForUser(params: Github.UsersGetFollowingForUserParams, callback?: Github.Callback): Promise; - getFollowing(params: Github.UsersGetFollowingParams, callback?: Github.Callback): Promise; - checkFollowing(params: Github.UsersCheckFollowingParams, callback?: Github.Callback): Promise; - checkIfOneFollowersOther(params: Github.UsersCheckIfOneFollowersOtherParams, callback?: Github.Callback): Promise; - followUser(params: Github.UsersFollowUserParams, callback?: Github.Callback): Promise; - unfollowUser(params: Github.UsersUnfollowUserParams, callback?: Github.Callback): Promise; - getKeysForUser(params: Github.UsersGetKeysForUserParams, callback?: Github.Callback): Promise; - getKeys(params: Github.UsersGetKeysParams, callback?: Github.Callback): Promise; - getKey(params: Github.UsersGetKeyParams, callback?: Github.Callback): Promise; - createKey(params: Github.UsersCreateKeyParams, callback?: Github.Callback): Promise; - deleteKey(params: Github.UsersDeleteKeyParams, callback?: Github.Callback): Promise; - getGpgKeysForUser(params: Github.UsersGetGpgKeysForUserParams, callback?: Github.Callback): Promise; - getGpgKeys(params: Github.UsersGetGpgKeysParams, callback?: Github.Callback): Promise; - getGpgKey(params: Github.UsersGetGpgKeyParams, callback?: Github.Callback): Promise; - createGpgKey(params: Github.UsersCreateGpgKeyParams, callback?: Github.Callback): Promise; - deleteGpgKey(params: Github.UsersDeleteGpgKeyParams, callback?: Github.Callback): Promise; - getBlockedUsers(params: Github.EmptyParams, callback?: Github.Callback): Promise; - checkBlockedUser(params: Github.UsersCheckBlockedUserParams, callback?: Github.Callback): Promise; - blockUser(params: Github.UsersBlockUserParams, callback?: Github.Callback): Promise; - unblockUser(params: Github.UsersUnblockUserParams, callback?: Github.Callback): Promise; - getRepoInvites(params: Github.EmptyParams, callback?: Github.Callback): Promise; - acceptRepoInvite(params: Github.UsersAcceptRepoInviteParams, callback?: Github.Callback): Promise; - declineRepoInvite(params: Github.UsersDeclineRepoInviteParams, callback?: Github.Callback): Promise; - getInstallations(params: Github.UsersGetInstallationsParams, callback?: Github.Callback): Promise; - getInstallationRepos(params: Github.UsersGetInstallationReposParams, callback?: Github.Callback): Promise; - addRepoToInstallation(params: Github.UsersAddRepoToInstallationParams, callback?: Github.Callback): Promise; - removeRepoFromInstallation(params: Github.UsersRemoveRepoFromInstallationParams, callback?: Github.Callback): Promise; - getMarketplacePurchases(params: Github.UsersGetMarketplacePurchasesParams, callback?: Github.Callback): Promise; - getMarketplaceStubbedPurchases(params: Github.UsersGetMarketplaceStubbedPurchasesParams, callback?: Github.Callback): Promise; - }; - enterprise: { - stats(params: Github.EnterpriseStatsParams, callback?: Github.Callback): Promise; - updateLdapForUser(params: Github.EnterpriseUpdateLdapForUserParams, callback?: Github.Callback): Promise; - syncLdapForUser(params: Github.EnterpriseSyncLdapForUserParams, callback?: Github.Callback): Promise; - updateLdapForTeam(params: Github.EnterpriseUpdateLdapForTeamParams, callback?: Github.Callback): Promise; - syncLdapForTeam(params: Github.EnterpriseSyncLdapForTeamParams, callback?: Github.Callback): Promise; - getLicense(params: Github.EmptyParams, callback?: Github.Callback): Promise; - getPreReceiveEnvironment(params: Github.EnterpriseGetPreReceiveEnvironmentParams, callback?: Github.Callback): Promise; - getPreReceiveEnvironments(params: Github.EmptyParams, callback?: Github.Callback): Promise; - createPreReceiveEnvironment(params: Github.EnterpriseCreatePreReceiveEnvironmentParams, callback?: Github.Callback): Promise; - editPreReceiveEnvironment(params: Github.EnterpriseEditPreReceiveEnvironmentParams, callback?: Github.Callback): Promise; - deletePreReceiveEnvironment(params: Github.EnterpriseDeletePreReceiveEnvironmentParams, callback?: Github.Callback): Promise; - getPreReceiveEnvironmentDownloadStatus(params: Github.EnterpriseGetPreReceiveEnvironmentDownloadStatusParams, callback?: Github.Callback): Promise; - triggerPreReceiveEnvironmentDownload(params: Github.EnterpriseTriggerPreReceiveEnvironmentDownloadParams, callback?: Github.Callback): Promise; - getPreReceiveHook(params: Github.EnterpriseGetPreReceiveHookParams, callback?: Github.Callback): Promise; - getPreReceiveHooks(params: Github.EmptyParams, callback?: Github.Callback): Promise; - createPreReceiveHook(params: Github.EnterpriseCreatePreReceiveHookParams, callback?: Github.Callback): Promise; - editPreReceiveHook(params: Github.EnterpriseEditPreReceiveHookParams, callback?: Github.Callback): Promise; - deletePreReceiveHook(params: Github.EnterpriseDeletePreReceiveHookParams, callback?: Github.Callback): Promise; - queueIndexingJob(params: Github.EnterpriseQueueIndexingJobParams, callback?: Github.Callback): Promise; - createOrg(params: Github.EnterpriseCreateOrgParams, callback?: Github.Callback): Promise; - }; -} - -declare module "octokit-rest-es3" { - export = Github; -} \ No newline at end of file From 204bb8954a61c7355c0ffc6551313661ff77defa Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Thu, 1 Mar 2018 09:21:36 -0500 Subject: [PATCH 061/873] Changing package and providing polyfill --- octorun/package-lock.json | 628 ++------------------------------------ octorun/package.json | 46 +-- 2 files changed, 29 insertions(+), 645 deletions(-) diff --git a/octorun/package-lock.json b/octorun/package-lock.json index 0a2cf1867..5a8839da0 100644 --- a/octorun/package-lock.json +++ b/octorun/package-lock.json @@ -1,609 +1,23 @@ { - "name": "octorun", - "version": "0.1.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@types/chai": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.2.tgz", - "integrity": "sha512-D8uQwKYUw2KESkorZ27ykzXgvkDJYXVEihGklgfp5I4HUP8D6IxtcdLTMB1emjQiWzV7WZ5ihm1cxIzVwjoleQ==", - "dev": true - }, - "@types/commander": { - "version": "2.12.2", - "resolved": "https://registry.npmjs.org/@types/commander/-/commander-2.12.2.tgz", - "integrity": "sha512-0QEFiR8ljcHp9bAbWxecjVRuAMr16ivPiGOw6KFQBVrVd0RQIcM3xKdRisH2EDWgVWujiYtHwhSkSUoAAGzH7Q==", - "dev": true, - "requires": { - "commander": "2.14.1" - } - }, - "@types/mocha": { - "version": "2.2.48", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.48.tgz", - "integrity": "sha512-nlK/iyETgafGli8Zh9zJVCTicvU3iajSkRwOh3Hhiva598CMqNJ4NcVCGMTGKpGpTYj/9R8RLzS9NAykSSCqGw==", - "dev": true - }, - "@types/node": { - "version": "7.0.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.55.tgz", - "integrity": "sha512-diCxfWNT4g2UM9Y+BPgy4s3egcZ2qOXc0mXLauvbsBUq9SBKQfh0SmuEUEhJVFZt/p6UDsjg1s2EgfM6OSlp4g==", - "dev": true - }, - "@types/sinon": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-2.3.7.tgz", - "integrity": "sha512-w+LjztaZbgZWgt/y/VMP5BUAWLtSyoIJhXyW279hehLPyubDoBNwvhcj3WaSptcekuKYeTCVxrq60rdLc6ImJA==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "1.9.1" - } - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "1.0.0", - "concat-map": "0.0.1" - } - }, - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "chai": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", - "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", - "dev": true, - "requires": { - "assertion-error": "1.1.0", - "check-error": "1.0.2", - "deep-eql": "3.0.1", - "get-func-name": "2.0.0", - "pathval": "1.1.0", - "type-detect": "4.0.8" - } - }, - "chalk": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", - "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "5.2.0" - }, - "dependencies": { - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "supports-color": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", - "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } - } - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "color-convert": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", - "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "commander": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz", - "integrity": "sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "diff": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", - "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "formatio": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.2.0.tgz", - "integrity": "sha1-87IWfZBoxGmKjVH092CjmlTYGOs=", - "dev": true, - "requires": { - "samsam": "1.3.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", - "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", - "dev": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", - "dev": true - }, - "growl": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", - "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", - "dev": true - }, - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "homedir-polyfill": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", - "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", - "dev": true, - "requires": { - "parse-passwd": "1.0.0" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "json3": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", - "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", - "dev": true - }, - "lodash._baseassign": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", - "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", - "dev": true, - "requires": { - "lodash._basecopy": "3.0.1", - "lodash.keys": "3.1.2" - } - }, - "lodash._basecopy": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", - "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", - "dev": true - }, - "lodash._basecreate": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", - "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=", - "dev": true - }, - "lodash._getnative": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", - "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", - "dev": true - }, - "lodash._isiterateecall": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", - "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", - "dev": true - }, - "lodash.create": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", - "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=", - "dev": true, - "requires": { - "lodash._baseassign": "3.2.0", - "lodash._basecreate": "3.0.3", - "lodash._isiterateecall": "3.0.9" - } - }, - "lodash.isarguments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", - "dev": true - }, - "lodash.isarray": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", - "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", - "dev": true - }, - "lodash.keys": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", - "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", - "dev": true, - "requires": { - "lodash._getnative": "3.9.1", - "lodash.isarguments": "3.1.0", - "lodash.isarray": "3.0.4" - } - }, - "lolex": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-1.6.0.tgz", - "integrity": "sha1-OpoCg0UqR9dDnnJzG54H1zhuSfY=", - "dev": true - }, - "make-error": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.4.tgz", - "integrity": "sha512-0Dab5btKVPhibSalc9QGXb559ED7G7iLjFXBaj9Wq8O3vorueR5K5jaE3hkG6ZQINyhA/JgG6Qk4qdFQjsYV6g==", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "1.1.11" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "mocha": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.3.tgz", - "integrity": "sha512-/6na001MJWEtYxHOV1WLfsmR4YIynkUEhBwzsb+fk2qmQ3iqsi258l/Q2MWHJMImAcNpZ8DEdYAK72NHoIQ9Eg==", - "dev": true, - "requires": { - "browser-stdout": "1.3.0", - "commander": "2.9.0", - "debug": "2.6.8", - "diff": "3.2.0", - "escape-string-regexp": "1.0.5", - "glob": "7.1.1", - "growl": "1.9.2", - "he": "1.1.1", - "json3": "3.3.2", - "lodash.create": "3.1.1", - "mkdirp": "0.5.1", - "supports-color": "3.1.2" - }, - "dependencies": { - "commander": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", - "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", - "dev": true, - "requires": { - "graceful-readlink": "1.0.1" - } - } - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "native-promise-only": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", - "integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1.0.2" - } - }, - "parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-to-regexp": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", - "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", - "dev": true, - "requires": { - "isarray": "0.0.1" - } - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "requires": { - "glob": "7.1.1" - } - }, - "samsam": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", - "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", - "dev": true - }, - "sinon": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-2.4.1.tgz", - "integrity": "sha512-vFTrO9Wt0ECffDYIPSP/E5bBugt0UjcBQOfQUMh66xzkyPEnhl/vM2LRZi2ajuTdkH07sA6DzrM6KvdvGIH8xw==", - "dev": true, - "requires": { - "diff": "3.2.0", - "formatio": "1.2.0", - "lolex": "1.6.0", - "native-promise-only": "0.8.1", - "path-to-regexp": "1.7.0", - "samsam": "1.3.0", - "text-encoding": "0.6.4", - "type-detect": "4.0.8" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", - "dev": true, - "requires": { - "source-map": "0.5.7" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", - "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=", - "dev": true, - "requires": { - "has-flag": "1.0.0" - } - }, - "text-encoding": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", - "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", - "dev": true - }, - "ts-node": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-3.3.0.tgz", - "integrity": "sha1-wTxqMCTjC+EYDdUwOPwgkonUv2k=", - "dev": true, - "requires": { - "arrify": "1.0.1", - "chalk": "2.3.1", - "diff": "3.2.0", - "make-error": "1.3.4", - "minimist": "1.2.0", - "mkdirp": "0.5.1", - "source-map-support": "0.4.18", - "tsconfig": "6.0.0", - "v8flags": "3.0.2", - "yn": "2.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "tsconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-6.0.0.tgz", - "integrity": "sha1-aw6DdgA9evGGT434+J3QBZ/80DI=", - "dev": true, - "requires": { - "strip-bom": "3.0.0", - "strip-json-comments": "2.0.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typescript": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.7.2.tgz", - "integrity": "sha512-p5TCYZDAO0m4G344hD+wx/LATebLWZNkkh2asWUFqSsD2OrDNhbAHuSjobrmsUmdzjJjEeZVU9g1h3O6vpstnw==", - "dev": true - }, - "v8flags": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.0.2.tgz", - "integrity": "sha512-6sgSKoFw1UpUPd3cFdF7QGnrH6tDeBgW1F3v9gy8gLY0mlbiBXq8soy8aQpY6xeeCjH5K+JvC62Acp7gtl7wWA==", - "dev": true, - "requires": { - "homedir-polyfill": "1.0.1" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - } - } + "name": "octorun", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "dotenv": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-1.2.0.tgz", + "integrity": "sha1-fNc+FuB/BXyAchR6W8OoZ38KtcY=" + }, + "es6-promise": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", + "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==" + }, + "octokit-rest-nothing-to-see-here-kthxbye": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/octokit-rest-nothing-to-see-here-kthxbye/-/octokit-rest-nothing-to-see-here-kthxbye-1.0.0.tgz", + "integrity": "sha1-tdcZKisFpFWv6uu66os/eQpmDK8=" + } + } } diff --git a/octorun/package.json b/octorun/package.json index 19abf98d1..7e83036dd 100644 --- a/octorun/package.json +++ b/octorun/package.json @@ -1,46 +1,16 @@ { "name": "octorun", - "version": "0.1.0", + "version": "1.0.0", "description": "", - "repository": "", - "license": "MIT", + "main": "index.js", "scripts": { - "clean": "rimraf dist", - "build": "npm run clean && tsc --pretty", - "test": "npm run build && mocha --compilers ts:ts-node/register --recursive test/**/*-spec.ts", - "watch": "npm run build -- --watch", - "watch:test": "npm run test -- --watch" - }, - "author": { - "name": "Stanley Goldman", - "email": "Stanley.Goldman@gmail.com" - }, - "main": "dist/bin/app.js", - "typings": "dist/bin/app.d.ts", - "bin": { - "octorun": "bin/octorun" - }, - "files": [ - "bin", - "dist" - ], - "devDependencies": { - "@types/chai": "^4.0.0", - "@types/commander": "^2.3.31", - "@types/dotenv": "^4.0.2", - "@types/mocha": "^2.2.39", - "@types/node": "^7.0.5", - "@types/sinon": "^2.3.0", - "chai": "^4.0.1", - "mocha": "^3.2.0", - "rimraf": "^2.6.1", - "sinon": "^2.3.2", - "ts-node": "^3.0.4", - "typescript": "^2.2.1" + "test": "echo \"Error: no test specified\" && exit 1" }, + "author": "", + "license": "ISC", "dependencies": { - "commander": "^2.9.0", - "dotenv": "^5.0.1", - "octokit-rest-es3": "github:gr2m/octokit-rest-es3" + "dotenv": "^1.0.0", + "es6-promise": "^4.2.4", + "octokit-rest-nothing-to-see-here-kthxbye": "^1.0.0" } } From 5b80d1638cab9bd31ac1cb4c776b1cae19e45023 Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Thu, 1 Mar 2018 09:21:59 -0500 Subject: [PATCH 062/873] Adding a modern version of octorun --- octorun-modern/.env.template | 2 + octorun-modern/.gitignore | 3 ++ octorun-modern/index.js | 26 +++++++++++++ octorun-modern/package-lock.json | 64 ++++++++++++++++++++++++++++++++ octorun-modern/package.json | 15 ++++++++ octorun/index.js | 34 +++++++++++++++++ 6 files changed, 144 insertions(+) create mode 100644 octorun-modern/.env.template create mode 100644 octorun-modern/.gitignore create mode 100644 octorun-modern/index.js create mode 100644 octorun-modern/package-lock.json create mode 100644 octorun-modern/package.json create mode 100644 octorun/index.js diff --git a/octorun-modern/.env.template b/octorun-modern/.env.template new file mode 100644 index 000000000..7eaafeb53 --- /dev/null +++ b/octorun-modern/.env.template @@ -0,0 +1,2 @@ +OCTOKIT_CLIENT_ID= +OCTOKIT_CLIENT_SECRET= \ No newline at end of file diff --git a/octorun-modern/.gitignore b/octorun-modern/.gitignore new file mode 100644 index 000000000..ef4fcce9d --- /dev/null +++ b/octorun-modern/.gitignore @@ -0,0 +1,3 @@ +.env +node_modules +npm-debug.log diff --git a/octorun-modern/index.js b/octorun-modern/index.js new file mode 100644 index 000000000..b36e9b156 --- /dev/null +++ b/octorun-modern/index.js @@ -0,0 +1,26 @@ +require("dotenv").config(); + +console.log("NodeJS Path: ", process.argv[0]); + +console.log(process.env.OCTOKIT_CLIENT_ID); +console.log(process.env.OCTOKIT_CLIENT_SECRET); + +var GitHub = require('@octokit/rest'); +var gitHub = new GitHub(); + +var authParams = { + client_id: process.env.OCTOKIT_CLIENT_ID, + client_secret: process.env.OCTOKIT_CLIENT_SECRET, + scopes: ["user", "repo", "gist", "write:public_key"] +}; + +gitHub.authorization.getOrCreateAuthorizationForApp(authParams, function (error, result) { + if (error) { + console.log("error", error, error.stack); + } + else { + console.log("result", result); + } + + process.exit(); +}); \ No newline at end of file diff --git a/octorun-modern/package-lock.json b/octorun-modern/package-lock.json new file mode 100644 index 000000000..35d7fa8f8 --- /dev/null +++ b/octorun-modern/package-lock.json @@ -0,0 +1,64 @@ +{ + "name": "octorun-modern", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@octokit/rest": { + "version": "14.0.9", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-14.0.9.tgz", + "integrity": "sha512-irP9phKfTXEZIcW2R+VNCtGHZJrXMWmSYp6RRfFn4BtAqtDRXF5z9JxCEQlAhNBf6X1koNi5k49tIAAAEJNlVQ==", + "requires": { + "before-after-hook": "1.1.0", + "debug": "3.1.0", + "is-array-buffer": "1.0.0", + "is-stream": "1.1.0", + "lodash": "4.17.5", + "url-template": "2.0.8" + } + }, + "before-after-hook": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.1.0.tgz", + "integrity": "sha512-VOMDtYPwLbIncTxNoSzRyvaMxtXmLWLUqr8k5AfC1BzLk34HvBXaQX8snOwQZ4c0aX8aSERqtJSiI9/m2u5kuA==" + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "dotenv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-1.0.0.tgz", + "integrity": "sha1-/cUn/GZBHGHXSjq50Znr+HRTLNQ=" + }, + "is-array-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-1.0.0.tgz", + "integrity": "sha512-KtzJzWuC1kZQ377GJbEsoBh0LuQh1uaZnQg8oL2LcDkY/Ny8rpAzu21Ls3oph3SEKXbnrLHt3rAUVm28iuEPfw==" + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "lodash": { + "version": "4.17.5", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", + "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "url-template": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", + "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" + } + } +} diff --git a/octorun-modern/package.json b/octorun-modern/package.json new file mode 100644 index 000000000..9059e6e92 --- /dev/null +++ b/octorun-modern/package.json @@ -0,0 +1,15 @@ +{ + "name": "octorun-modern", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "@octokit/rest": "^14.0.9", + "dotenv": "^1.0.0" + } +} diff --git a/octorun/index.js b/octorun/index.js new file mode 100644 index 000000000..e66262ede --- /dev/null +++ b/octorun/index.js @@ -0,0 +1,34 @@ +// polyfill Buffer.from +if (!Buffer.from) { + Buffer.from = function (data, encoding, length) { + return new Buffer(data, encoding, length) + } +} + +require("dotenv").config(); +require('es6-promise').polyfill(); + +console.log("NodeJS Path: ", process.argv[0]); + +console.log(process.env.OCTOKIT_CLIENT_ID); +console.log(process.env.OCTOKIT_CLIENT_SECRET); + +var GitHub = require('octokit-rest-nothing-to-see-here-kthxbye'); +var gitHub = new GitHub(); + +var authParams = { + client_id: process.env.OCTOKIT_CLIENT_ID, + client_secret: process.env.OCTOKIT_CLIENT_SECRET, + scopes: ["user", "repo", "gist", "write:public_key"] +}; + +gitHub.authorization.getOrCreateAuthorizationForApp(authParams, function (error, result) { + if (error) { + console.log("error", error, error.stack); + } + else { + console.log("result", result); + } + + process.exit(); +}); \ No newline at end of file From caf09610db5071631f06602c486a37d79909849c Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Thu, 1 Mar 2018 10:49:17 -0500 Subject: [PATCH 063/873] I understand how i'm supposed to do this now --- octorun-modern/.env.template | 3 +- octorun-modern/index.js | 80 ++++++++++++++++++++++++-------- octorun-modern/package-lock.json | 5 ++ octorun-modern/package.json | 3 +- 4 files changed, 70 insertions(+), 21 deletions(-) diff --git a/octorun-modern/.env.template b/octorun-modern/.env.template index 7eaafeb53..53bc61631 100644 --- a/octorun-modern/.env.template +++ b/octorun-modern/.env.template @@ -1,2 +1,3 @@ OCTOKIT_CLIENT_ID= -OCTOKIT_CLIENT_SECRET= \ No newline at end of file +OCTOKIT_CLIENT_SECRET= +OCTOKIT_APP_NAME = \ No newline at end of file diff --git a/octorun-modern/index.js b/octorun-modern/index.js index b36e9b156..246fc0c82 100644 --- a/octorun-modern/index.js +++ b/octorun-modern/index.js @@ -1,26 +1,68 @@ -require("dotenv").config(); +const readlineSync = require("readline-sync"); +const octokit = require('@octokit/rest')({ + timeout: 0, // 0 means no request timeout + requestMedia: 'application/vnd.github.v3+json', + headers: { + 'user-agent': 'octokit/rest.js v1.2.3' // v1.2.3 will be current version + }, + + // change for custom GitHub Enterprise URL + //host: 'api.github.com', + //pathPrefix: '', + //protocol: 'https', + //port: 443, + + // Node only: advanced request options can be passed as http(s) agent + //agent: undefined + }); console.log("NodeJS Path: ", process.argv[0]); -console.log(process.env.OCTOKIT_CLIENT_ID); -console.log(process.env.OCTOKIT_CLIENT_SECRET); +require("dotenv").config(); + +const clientId = process.env.OCTOKIT_CLIENT_ID; +const clientSecret = process.env.OCTOKIT_CLIENT_SECRET; + +const appName = process.env.OCTORUN_APP_NAME | "octorun"; +let user = process.env.OCTORUN_USER; +const token = process.env.OCTORUN_TOKEN; + +const scopes = ["user", "repo", "gist", "write:public_key"]; + +if(user != null && token != null) +{ + +} +else +{ + user = readlineSync.question('User: '); + + var pwd = readlineSync.question('Password: ', { + hideEchoBack: true + }); + + octokit.authenticate({ + type:"basic", + username:user, + password:pwd + }); -var GitHub = require('@octokit/rest'); -var gitHub = new GitHub(); + octokit.authorization.create({ + scopes: scopes, + note: appName, + client_id: clientId, + client_secret: clientSecret + }, function(err, res) { -var authParams = { - client_id: process.env.OCTOKIT_CLIENT_ID, - client_secret: process.env.OCTOKIT_CLIENT_SECRET, - scopes: ["user", "repo", "gist", "write:public_key"] -}; + console.log("err", err, "res", res); -gitHub.authorization.getOrCreateAuthorizationForApp(authParams, function (error, result) { - if (error) { - console.log("error", error, error.stack); - } - else { - console.log("result", result); - } + if(err) + { + + } + else + { - process.exit(); -}); \ No newline at end of file + } + }); +} diff --git a/octorun-modern/package-lock.json b/octorun-modern/package-lock.json index 35d7fa8f8..a769d5561 100644 --- a/octorun-modern/package-lock.json +++ b/octorun-modern/package-lock.json @@ -55,6 +55,11 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "readline-sync": { + "version": "1.4.9", + "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.9.tgz", + "integrity": "sha1-PtqOZfI80qF+YTAbHwADOWr17No=" + }, "url-template": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", diff --git a/octorun-modern/package.json b/octorun-modern/package.json index 9059e6e92..7a3648841 100644 --- a/octorun-modern/package.json +++ b/octorun-modern/package.json @@ -10,6 +10,7 @@ "license": "ISC", "dependencies": { "@octokit/rest": "^14.0.9", - "dotenv": "^1.0.0" + "dotenv": "^1.0.0", + "readline-sync": "^1.4.9" } } From e52090a6a615bda3cf4f88b1f38274f180c2b063 Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Thu, 1 Mar 2018 13:33:42 -0500 Subject: [PATCH 064/873] I can two factor auth --- octorun/index.js | 122 ++++++++++++++++++++++++++++++++------ octorun/package-lock.json | 23 ------- octorun/package.json | 3 +- 3 files changed, 106 insertions(+), 42 deletions(-) delete mode 100644 octorun/package-lock.json diff --git a/octorun/index.js b/octorun/index.js index e66262ede..4b4ff183c 100644 --- a/octorun/index.js +++ b/octorun/index.js @@ -1,34 +1,120 @@ // polyfill Buffer.from if (!Buffer.from) { Buffer.from = function (data, encoding, length) { - return new Buffer(data, encoding, length) + return new Buffer(data, encoding, length) } } require("dotenv").config(); require('es6-promise').polyfill(); +var readlineSync = require("readline-sync"); +var http = require("http"); console.log("NodeJS Path: ", process.argv[0]); -console.log(process.env.OCTOKIT_CLIENT_ID); -console.log(process.env.OCTOKIT_CLIENT_SECRET); +var clientId = process.env.OCTOKIT_CLIENT_ID; +var clientSecret = process.env.OCTOKIT_CLIENT_SECRET; +var appName = process.env.OCTORUN_APP_NAME | "octorun"; +var user = process.env.OCTORUN_USER; +var token = process.env.OCTORUN_TOKEN; -var GitHub = require('octokit-rest-nothing-to-see-here-kthxbye'); -var gitHub = new GitHub(); +var scopes = ["user", "repo", "gist", "write:public_key"]; -var authParams = { - client_id: process.env.OCTOKIT_CLIENT_ID, - client_secret: process.env.OCTOKIT_CLIENT_SECRET, - scopes: ["user", "repo", "gist", "write:public_key"] +var Octokit = require('octokit-rest-nothing-to-see-here-kthxbye'); +var createOctokit = function () { + return Octokit({ + timeout: 0, + requestMedia: 'application/vnd.github.v3+json', + headers: { + 'user-agent': 'octokit/rest.js v1.2.3' + } + + // change for custom GitHub Enterprise URL + //host: 'api.github.com', + //pathPrefix: '', + //protocol: 'https', + //port: 443 + }); }; -gitHub.authorization.getOrCreateAuthorizationForApp(authParams, function (error, result) { - if (error) { - console.log("error", error, error.stack); - } - else { - console.log("result", result); - } +var handleBasicAuthentication = function (onSuccess, onRequiresTwoFa, onFailure) { + var user = readlineSync.question('User: '); + + var pwd = readlineSync.question('Password: ', { + hideEchoBack: true + }); + + var octokit = createOctokit(); + + octokit.authenticate({ + type: "basic", + username: user, + password: pwd + }); + + octokit.authorization.create({ + scopes: scopes, + note: appName, + client_id: clientId, + client_secret: clientSecret + }, function (err, res) { + if (err) { + if (err.message === '{"message":"Must specify two-factor authentication OTP code.","documentation_url":"https://developer.github.com/v3/auth#working-with-two-factor-authentication"}') { + onRequiresTwoFa(); + return; + } + else { + onFailure(err) + } + } + else { + onSuccess(res.data.token); + } + }); +} + +var handleTwoFactorAuthentication = function (onSuccess, onFailure) { + var user = readlineSync.question('User: '); - process.exit(); -}); \ No newline at end of file + var pwd = readlineSync.question('Password: ', { + hideEchoBack: true + }); + + var twofa = readlineSync.question('TwoFactor: '); + + var octokit = createOctokit(); + + octokit.authenticate({ + type: "basic", + username: user, + password: pwd + }); + + octokit.authorization.create({ + scopes: scopes, + note: appName, + client_id: clientId, + client_secret: clientSecret, + headers: { + "X-GitHub-OTP": twofa + } + }, function (err, res) { + if (err) { + onFailure(err) + } + else { + onSuccess(res.data.token); + } + }); +} + +if (user != null && token != null) { + +} +else { + handleTwoFactorAuthentication(function (token) { + console.log("token", token); + }, function (err) { + console.log("error", error); + }) +} diff --git a/octorun/package-lock.json b/octorun/package-lock.json deleted file mode 100644 index 5a8839da0..000000000 --- a/octorun/package-lock.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "octorun", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "dotenv": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-1.2.0.tgz", - "integrity": "sha1-fNc+FuB/BXyAchR6W8OoZ38KtcY=" - }, - "es6-promise": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", - "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==" - }, - "octokit-rest-nothing-to-see-here-kthxbye": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/octokit-rest-nothing-to-see-here-kthxbye/-/octokit-rest-nothing-to-see-here-kthxbye-1.0.0.tgz", - "integrity": "sha1-tdcZKisFpFWv6uu66os/eQpmDK8=" - } - } -} diff --git a/octorun/package.json b/octorun/package.json index 7e83036dd..42b714409 100644 --- a/octorun/package.json +++ b/octorun/package.json @@ -11,6 +11,7 @@ "dependencies": { "dotenv": "^1.0.0", "es6-promise": "^4.2.4", - "octokit-rest-nothing-to-see-here-kthxbye": "^1.0.0" + "octokit-rest-nothing-to-see-here-kthxbye": "^1.0.1", + "readline-sync": "^1.4.9" } } From 4d28a19b59a74ad9e8d74385e5be6cd9e9a4fce0 Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Thu, 1 Mar 2018 14:06:17 -0500 Subject: [PATCH 065/873] Completed functionality to authenticate --- octorun/bin/octorun | 5 ++ octorun/bin/octorun-login | 3 + octorun/package.json | 2 + octorun/{index.js => src/authentication.js} | 67 +++++---------------- octorun/src/bin/app-login.js | 30 +++++++++ octorun/src/bin/app.js | 8 +++ octorun/src/configuration.js | 15 +++++ octorun/src/octokit.js | 20 ++++++ 8 files changed, 97 insertions(+), 53 deletions(-) create mode 100644 octorun/bin/octorun create mode 100644 octorun/bin/octorun-login rename octorun/{index.js => src/authentication.js} (52%) create mode 100644 octorun/src/bin/app-login.js create mode 100644 octorun/src/bin/app.js create mode 100644 octorun/src/configuration.js create mode 100644 octorun/src/octokit.js diff --git a/octorun/bin/octorun b/octorun/bin/octorun new file mode 100644 index 000000000..c3e1f57c8 --- /dev/null +++ b/octorun/bin/octorun @@ -0,0 +1,5 @@ +#!/usr/bin/env node + +console.log("NodeJs", process.argv[0]); + +require('../src/bin/app.js'); diff --git a/octorun/bin/octorun-login b/octorun/bin/octorun-login new file mode 100644 index 000000000..f74f2b860 --- /dev/null +++ b/octorun/bin/octorun-login @@ -0,0 +1,3 @@ +#!/usr/bin/env node + +require('../src/bin/app-login.js'); diff --git a/octorun/package.json b/octorun/package.json index 42b714409..2ab332898 100644 --- a/octorun/package.json +++ b/octorun/package.json @@ -6,9 +6,11 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, + "main": "src/app.js", "author": "", "license": "ISC", "dependencies": { + "commander": "^2.14.1", "dotenv": "^1.0.0", "es6-promise": "^4.2.4", "octokit-rest-nothing-to-see-here-kthxbye": "^1.0.1", diff --git a/octorun/index.js b/octorun/src/authentication.js similarity index 52% rename from octorun/index.js rename to octorun/src/authentication.js index 4b4ff183c..ebaebd26e 100644 --- a/octorun/index.js +++ b/octorun/src/authentication.js @@ -1,42 +1,9 @@ -// polyfill Buffer.from -if (!Buffer.from) { - Buffer.from = function (data, encoding, length) { - return new Buffer(data, encoding, length) - } -} - -require("dotenv").config(); -require('es6-promise').polyfill(); var readlineSync = require("readline-sync"); -var http = require("http"); - -console.log("NodeJS Path: ", process.argv[0]); - -var clientId = process.env.OCTOKIT_CLIENT_ID; -var clientSecret = process.env.OCTOKIT_CLIENT_SECRET; -var appName = process.env.OCTORUN_APP_NAME | "octorun"; -var user = process.env.OCTORUN_USER; -var token = process.env.OCTORUN_TOKEN; +var config = require("./configuration"); +var octokitWrapper = require("./octokit"); var scopes = ["user", "repo", "gist", "write:public_key"]; -var Octokit = require('octokit-rest-nothing-to-see-here-kthxbye'); -var createOctokit = function () { - return Octokit({ - timeout: 0, - requestMedia: 'application/vnd.github.v3+json', - headers: { - 'user-agent': 'octokit/rest.js v1.2.3' - } - - // change for custom GitHub Enterprise URL - //host: 'api.github.com', - //pathPrefix: '', - //protocol: 'https', - //port: 443 - }); -}; - var handleBasicAuthentication = function (onSuccess, onRequiresTwoFa, onFailure) { var user = readlineSync.question('User: '); @@ -44,7 +11,7 @@ var handleBasicAuthentication = function (onSuccess, onRequiresTwoFa, onFailure) hideEchoBack: true }); - var octokit = createOctokit(); + var octokit = octokitWrapper.createOctokit(); octokit.authenticate({ type: "basic", @@ -54,9 +21,9 @@ var handleBasicAuthentication = function (onSuccess, onRequiresTwoFa, onFailure) octokit.authorization.create({ scopes: scopes, - note: appName, - client_id: clientId, - client_secret: clientSecret + note: config.appName, + client_id: config.clientId, + client_secret: config.clientSecret }, function (err, res) { if (err) { if (err.message === '{"message":"Must specify two-factor authentication OTP code.","documentation_url":"https://developer.github.com/v3/auth#working-with-two-factor-authentication"}') { @@ -82,7 +49,7 @@ var handleTwoFactorAuthentication = function (onSuccess, onFailure) { var twofa = readlineSync.question('TwoFactor: '); - var octokit = createOctokit(); + var octokit = octokitWrapper.createOctokit(); octokit.authenticate({ type: "basic", @@ -92,9 +59,9 @@ var handleTwoFactorAuthentication = function (onSuccess, onFailure) { octokit.authorization.create({ scopes: scopes, - note: appName, - client_id: clientId, - client_secret: clientSecret, + note: config.appName, + client_id: config.clientId, + client_secret: config.clientSecret, headers: { "X-GitHub-OTP": twofa } @@ -108,13 +75,7 @@ var handleTwoFactorAuthentication = function (onSuccess, onFailure) { }); } -if (user != null && token != null) { - -} -else { - handleTwoFactorAuthentication(function (token) { - console.log("token", token); - }, function (err) { - console.log("error", error); - }) -} +module.exports = { + handleBasicAuthentication: handleBasicAuthentication, + handleTwoFactorAuthentication: handleTwoFactorAuthentication, +}; \ No newline at end of file diff --git a/octorun/src/bin/app-login.js b/octorun/src/bin/app-login.js new file mode 100644 index 000000000..69be74001 --- /dev/null +++ b/octorun/src/bin/app-login.js @@ -0,0 +1,30 @@ +var commander = require("commander"); +var package = require('../../package.json') +var authentication = require('../authentication') + +commander + .version(package.version) + .option('-t, --twoFactor') + .parse(process.argv); + +if (commander.twoFactor) { + authentication.handleTwoFactorAuthentication(function (token) { + console.log(token); + process.exit(); + }, function () { + console.log("Must specify two-factor authentication OTP code."); + process.exit(); + }, function (err) { + console.log(err); + process.exit(-1); + }); +} +else { + authentication.handleBasicAuthentication(function (token) { + console.log(token); + process.exit(); + }, function (err) { + console.log(err); + process.exit(-1); + }); +} \ No newline at end of file diff --git a/octorun/src/bin/app.js b/octorun/src/bin/app.js new file mode 100644 index 000000000..27e3dcd44 --- /dev/null +++ b/octorun/src/bin/app.js @@ -0,0 +1,8 @@ + +var commander = require("commander"); +var package = require('../../package.json') + +commander + .version(package.version) + .command('login [-t]', 'Authenticate') + .parse(process.argv); \ No newline at end of file diff --git a/octorun/src/configuration.js b/octorun/src/configuration.js new file mode 100644 index 000000000..5ae9d40e8 --- /dev/null +++ b/octorun/src/configuration.js @@ -0,0 +1,15 @@ +require("dotenv").config(); + +var clientId = process.env.OCTOKIT_CLIENT_ID; +var clientSecret = process.env.OCTOKIT_CLIENT_SECRET; +var appName = process.env.OCTORUN_APP_NAME | "octorun"; +var user = process.env.OCTORUN_USER; +var token = process.env.OCTORUN_TOKEN; + +module.exports = { + clientId: clientId, + clientSecret: clientSecret, + appName: appName, + user: user, + token: token, +}; \ No newline at end of file diff --git a/octorun/src/octokit.js b/octorun/src/octokit.js new file mode 100644 index 000000000..a13bea657 --- /dev/null +++ b/octorun/src/octokit.js @@ -0,0 +1,20 @@ +require('es6-promise').polyfill(); +var Octokit = require('octokit-rest-nothing-to-see-here-kthxbye'); + +var createOctokit = function () { + return Octokit({ + timeout: 0, + requestMedia: 'application/vnd.github.v3+json', + headers: { + 'user-agent': 'octokit/rest.js v1.2.3' + } + + // change for custom GitHub Enterprise URL + //host: 'api.github.com', + //pathPrefix: '', + //protocol: 'https', + //port: 443 + }); +}; + +module.exports = { createOctokit: createOctokit }; \ No newline at end of file From 0bfff0940cfaad850971c73a32cb7c241bc7bfd1 Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Thu, 1 Mar 2018 14:47:06 -0500 Subject: [PATCH 066/873] Functionality to validate the user and get an organization list --- octorun/.env.template | 4 +++- octorun/bin/octorun | 2 +- octorun/bin/octorun-organizations | 3 +++ octorun/bin/octorun-validate | 3 +++ octorun/src/api.js | 31 ++++++++++++++++++++++++++++ octorun/src/bin/app-login.js | 6 +++--- octorun/src/bin/app-organizations.js | 19 +++++++++++++++++ octorun/src/bin/app-validate.js | 20 ++++++++++++++++++ octorun/src/bin/app.js | 2 ++ octorun/src/configuration.js | 2 +- 10 files changed, 86 insertions(+), 6 deletions(-) create mode 100644 octorun/bin/octorun-organizations create mode 100644 octorun/bin/octorun-validate create mode 100644 octorun/src/api.js create mode 100644 octorun/src/bin/app-organizations.js create mode 100644 octorun/src/bin/app-validate.js diff --git a/octorun/.env.template b/octorun/.env.template index 7eaafeb53..2c1f93479 100644 --- a/octorun/.env.template +++ b/octorun/.env.template @@ -1,2 +1,4 @@ OCTOKIT_CLIENT_ID= -OCTOKIT_CLIENT_SECRET= \ No newline at end of file +OCTOKIT_CLIENT_SECRET= +OCTORUN_USER= +OCTORUN_TOKEN= \ No newline at end of file diff --git a/octorun/bin/octorun b/octorun/bin/octorun index c3e1f57c8..f7c15dc90 100644 --- a/octorun/bin/octorun +++ b/octorun/bin/octorun @@ -1,5 +1,5 @@ #!/usr/bin/env node -console.log("NodeJs", process.argv[0]); +console.log("node:", process.argv[0]); require('../src/bin/app.js'); diff --git a/octorun/bin/octorun-organizations b/octorun/bin/octorun-organizations new file mode 100644 index 000000000..bf6c9f558 --- /dev/null +++ b/octorun/bin/octorun-organizations @@ -0,0 +1,3 @@ +#!/usr/bin/env node + +require('../src/bin/app-organizations.js'); diff --git a/octorun/bin/octorun-validate b/octorun/bin/octorun-validate new file mode 100644 index 000000000..e81615852 --- /dev/null +++ b/octorun/bin/octorun-validate @@ -0,0 +1,3 @@ +#!/usr/bin/env node + +require('../src/bin/app-validate.js'); diff --git a/octorun/src/api.js b/octorun/src/api.js new file mode 100644 index 000000000..3f87d1dd0 --- /dev/null +++ b/octorun/src/api.js @@ -0,0 +1,31 @@ +var readlineSync = require("readline-sync"); +var config = require("./configuration"); +var octokitWrapper = require("./octokit"); + +function ApiWrapper() { + this.octokit = octokitWrapper.createOctokit(); + + if (!config.user || !config.token) { + throw "User and/or Token missing"; + } + + this.octokit.authenticate({ + type: "oauth", + token: config.token + }); +} + +ApiWrapper.prototype.verifyUser = function (callback) { + this.octokit.users.get({}, function(error, result){ + callback(error, (!result) ? null : result.data.login); + }); +}; + +ApiWrapper.prototype.getOrgs = function (callback) { + var position = { page: 0, per_page: 100 }; + this.octokit.users.getOrgs(position, function (error, result) { + callback(error, (!result) ? null : result.data.map(function (item) { return item.login; })); + }); +}; + +module.exports = ApiWrapper; \ No newline at end of file diff --git a/octorun/src/bin/app-login.js b/octorun/src/bin/app-login.js index 69be74001..c0b7bddb2 100644 --- a/octorun/src/bin/app-login.js +++ b/octorun/src/bin/app-login.js @@ -11,9 +11,6 @@ if (commander.twoFactor) { authentication.handleTwoFactorAuthentication(function (token) { console.log(token); process.exit(); - }, function () { - console.log("Must specify two-factor authentication OTP code."); - process.exit(); }, function (err) { console.log(err); process.exit(-1); @@ -23,6 +20,9 @@ else { authentication.handleBasicAuthentication(function (token) { console.log(token); process.exit(); + }, function () { + console.log("Must specify two-factor authentication OTP code."); + process.exit(1); }, function (err) { console.log(err); process.exit(-1); diff --git a/octorun/src/bin/app-organizations.js b/octorun/src/bin/app-organizations.js new file mode 100644 index 000000000..e57acc8d3 --- /dev/null +++ b/octorun/src/bin/app-organizations.js @@ -0,0 +1,19 @@ +var commander = require("commander"); +var package = require('../../package.json') +var ApiWrapper = require('../api') + +commander + .version(package.version) + .parse(process.argv); + +var apiWrapper = new ApiWrapper(); +apiWrapper.getOrgs(function (error, result) { + if (error) { + console.log(error); + process.exit(-1); + } + else { + console.log(result); + process.exit(); + } +}); \ No newline at end of file diff --git a/octorun/src/bin/app-validate.js b/octorun/src/bin/app-validate.js new file mode 100644 index 000000000..5e63750bd --- /dev/null +++ b/octorun/src/bin/app-validate.js @@ -0,0 +1,20 @@ +var commander = require("commander"); +var package = require('../../package.json') +var ApiWrapper = require('../api') + +commander + .version(package.version) + .parse(process.argv); + +var apiWrapper = new ApiWrapper(); + +apiWrapper.verifyUser(function (error, result) { + if (error) { + console.log(error); + process.exit(-1); + } + else { + console.log(result); + process.exit(); + } +}); \ No newline at end of file diff --git a/octorun/src/bin/app.js b/octorun/src/bin/app.js index 27e3dcd44..d144ea1ac 100644 --- a/octorun/src/bin/app.js +++ b/octorun/src/bin/app.js @@ -5,4 +5,6 @@ var package = require('../../package.json') commander .version(package.version) .command('login [-t]', 'Authenticate') + .command('validate', 'Validate Current User') + .command('organizations', 'Get Organizations') .parse(process.argv); \ No newline at end of file diff --git a/octorun/src/configuration.js b/octorun/src/configuration.js index 5ae9d40e8..4d9474b40 100644 --- a/octorun/src/configuration.js +++ b/octorun/src/configuration.js @@ -11,5 +11,5 @@ module.exports = { clientSecret: clientSecret, appName: appName, user: user, - token: token, + token: token }; \ No newline at end of file From 30dd778a09808d6831dd7333999dd7f6082561d9 Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Thu, 1 Mar 2018 15:01:25 -0500 Subject: [PATCH 067/873] An orgs function that will paginate all pages --- octorun/src/api.js | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/octorun/src/api.js b/octorun/src/api.js index 3f87d1dd0..3c413367a 100644 --- a/octorun/src/api.js +++ b/octorun/src/api.js @@ -16,16 +16,37 @@ function ApiWrapper() { } ApiWrapper.prototype.verifyUser = function (callback) { - this.octokit.users.get({}, function(error, result){ + this.octokit.users.get({}, function (error, result) { callback(error, (!result) ? null : result.data.login); }); }; ApiWrapper.prototype.getOrgs = function (callback) { - var position = { page: 0, per_page: 100 }; - this.octokit.users.getOrgs(position, function (error, result) { - callback(error, (!result) ? null : result.data.map(function (item) { return item.login; })); - }); + var perPageCount = 100; + var organizations = []; + var position = { page: 1, per_page: perPageCount }; + + var that = this; + var getOrgsAtPosition = function () { + that.octokit.users.getOrgs(position, function (error, result) { + for (var index = 0; index < result.data.length; index++) { + var element = result.data[index]; + organizations.push(element); + } + + if (result.data.length == perPageCount) { + position.page = position.page + 1; + getOrgsAtPosition(); + } + else { + callback(error, organizations.map(function (item) { + return item.login; + })); + } + }); + } + + getOrgsAtPosition(); }; module.exports = ApiWrapper; \ No newline at end of file From b80a0212b17e85bd386f9e0bf790ace808c2f958 Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Thu, 1 Mar 2018 15:28:57 -0500 Subject: [PATCH 068/873] Added functionality to publish a repo --- octorun/bin/octorun-publish | 3 +++ octorun/src/api.js | 22 ++++++++++++++++++++ octorun/src/bin/app-publish.js | 38 ++++++++++++++++++++++++++++++++++ octorun/src/bin/app.js | 3 ++- 4 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 octorun/bin/octorun-publish create mode 100644 octorun/src/bin/app-publish.js diff --git a/octorun/bin/octorun-publish b/octorun/bin/octorun-publish new file mode 100644 index 000000000..c95bdbb44 --- /dev/null +++ b/octorun/bin/octorun-publish @@ -0,0 +1,3 @@ +#!/usr/bin/env node + +require('../src/bin/app-publish.js'); diff --git a/octorun/src/api.js b/octorun/src/api.js index 3c413367a..3cc79b581 100644 --- a/octorun/src/api.js +++ b/octorun/src/api.js @@ -49,4 +49,26 @@ ApiWrapper.prototype.getOrgs = function (callback) { getOrgsAtPosition(); }; +ApiWrapper.prototype.publish = function (name, desc, private, organization, callback) { + if (organization) { + this.octokit.repos.createForOrg({ + org: organization, + name: name, + description: desc, + private: private + }, function (error, result) { + callback(error, (!result) ? null : result.data.git_url); + }); + } + else { + this.octokit.repos.create({ + name: name, + description: desc, + private: private + }, function (error, result) { + callback(error, (!result) ? null : result.data.git_url); + }); + } +}; + module.exports = ApiWrapper; \ No newline at end of file diff --git a/octorun/src/bin/app-publish.js b/octorun/src/bin/app-publish.js new file mode 100644 index 000000000..a02033276 --- /dev/null +++ b/octorun/src/bin/app-publish.js @@ -0,0 +1,38 @@ +var commander = require("commander"); +var package = require('../../package.json') +var ApiWrapper = require('../api') + +commander + .version(package.version) + .option('-r, --repository ') + .option('-d, --description ') + .option('-o, --organization ') + .option('-p, --private') + .parse(process.argv); + +if(!commander.repository) +{ + console.log("repository required"); + commander.help(); + process.exit(-1); + return; +} + +var private = false; +if (commander.private) { + private = true; +} + +var apiWrapper = new ApiWrapper(); + +apiWrapper.publish(commander.repository, commander.description, private, commander.organization, + function (error, result) { + if (error) { + console.log(error); + process.exit(-1); + } + else { + console.log(result); + process.exit(); + } + }); \ No newline at end of file diff --git a/octorun/src/bin/app.js b/octorun/src/bin/app.js index d144ea1ac..c80c4a07c 100644 --- a/octorun/src/bin/app.js +++ b/octorun/src/bin/app.js @@ -4,7 +4,8 @@ var package = require('../../package.json') commander .version(package.version) - .command('login [-t]', 'Authenticate') + .command('login', 'Authenticate') .command('validate', 'Validate Current User') .command('organizations', 'Get Organizations') + .command('publish', 'Publish') .parse(process.argv); \ No newline at end of file From 831728b9225c0fcb91286b95a45c40b5752972fd Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Thu, 1 Mar 2018 15:30:42 -0500 Subject: [PATCH 069/873] Removing unused package --- octorun/package.json | 1 - octorun/src/octokit.js | 1 - 2 files changed, 2 deletions(-) diff --git a/octorun/package.json b/octorun/package.json index 2ab332898..2fd6a68ce 100644 --- a/octorun/package.json +++ b/octorun/package.json @@ -12,7 +12,6 @@ "dependencies": { "commander": "^2.14.1", "dotenv": "^1.0.0", - "es6-promise": "^4.2.4", "octokit-rest-nothing-to-see-here-kthxbye": "^1.0.1", "readline-sync": "^1.4.9" } diff --git a/octorun/src/octokit.js b/octorun/src/octokit.js index a13bea657..f75250491 100644 --- a/octorun/src/octokit.js +++ b/octorun/src/octokit.js @@ -1,4 +1,3 @@ -require('es6-promise').polyfill(); var Octokit = require('octokit-rest-nothing-to-see-here-kthxbye'); var createOctokit = function () { From 044e3ff19f356f76a8acea6dd4c773e894a9ebe8 Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Thu, 1 Mar 2018 16:07:25 -0500 Subject: [PATCH 070/873] Functionality to submit Unity usage --- octorun/bin/octorun-usage | 3 +++ octorun/src/bin/app-usage.js | 42 ++++++++++++++++++++++++++++++++++++ octorun/src/bin/app.js | 1 + 3 files changed, 46 insertions(+) create mode 100644 octorun/bin/octorun-usage create mode 100644 octorun/src/bin/app-usage.js diff --git a/octorun/bin/octorun-usage b/octorun/bin/octorun-usage new file mode 100644 index 000000000..8366ae34e --- /dev/null +++ b/octorun/bin/octorun-usage @@ -0,0 +1,3 @@ +#!/usr/bin/env node + +require('../src/bin/app-usage.js'); diff --git a/octorun/src/bin/app-usage.js b/octorun/src/bin/app-usage.js new file mode 100644 index 000000000..c3f6ea5f6 --- /dev/null +++ b/octorun/src/bin/app-usage.js @@ -0,0 +1,42 @@ +var commander = require("commander"); +var package = require('../../package.json') +var readlineSync = require("readline-sync"); +var endOfLine = require('os').EOL; + +commander + .version(package.version) + .parse(process.argv); + +var postData = readlineSync.question(); + +var https = require('https'); + +var options = { + hostname: 'central.github.com', + path: '/api/usage/unity', + method: 'POST', + headers: { + 'Content-Type': 'application/json' + } +}; + +var req = https.request(options, function (res) { + console.log('statusCode:', res.statusCode); + + res.on('data', function (d) { + process.stdout.write(d); + process.stdout.write(endOfLine); + }); + + res.on('end', function (d) { + process.exit(); + }); +}); + +req.on('error', function (e) { + console.error(e); + process.exit(-1); +}); + +req.write(postData); +req.end(); \ No newline at end of file diff --git a/octorun/src/bin/app.js b/octorun/src/bin/app.js index c80c4a07c..e40d738b2 100644 --- a/octorun/src/bin/app.js +++ b/octorun/src/bin/app.js @@ -8,4 +8,5 @@ commander .command('validate', 'Validate Current User') .command('organizations', 'Get Organizations') .command('publish', 'Publish') + .command('usage', 'Usage') .parse(process.argv); \ No newline at end of file From 71f2f644e92590176e7d2432897b07b34f506ac3 Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Thu, 1 Mar 2018 16:08:04 -0500 Subject: [PATCH 071/873] Removing octorun-modern --- octorun-modern/.env.template | 3 -- octorun-modern/.gitignore | 3 -- octorun-modern/index.js | 68 ------------------------------- octorun-modern/package-lock.json | 69 -------------------------------- octorun-modern/package.json | 16 -------- 5 files changed, 159 deletions(-) delete mode 100644 octorun-modern/.env.template delete mode 100644 octorun-modern/.gitignore delete mode 100644 octorun-modern/index.js delete mode 100644 octorun-modern/package-lock.json delete mode 100644 octorun-modern/package.json diff --git a/octorun-modern/.env.template b/octorun-modern/.env.template deleted file mode 100644 index 53bc61631..000000000 --- a/octorun-modern/.env.template +++ /dev/null @@ -1,3 +0,0 @@ -OCTOKIT_CLIENT_ID= -OCTOKIT_CLIENT_SECRET= -OCTOKIT_APP_NAME = \ No newline at end of file diff --git a/octorun-modern/.gitignore b/octorun-modern/.gitignore deleted file mode 100644 index ef4fcce9d..000000000 --- a/octorun-modern/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.env -node_modules -npm-debug.log diff --git a/octorun-modern/index.js b/octorun-modern/index.js deleted file mode 100644 index 246fc0c82..000000000 --- a/octorun-modern/index.js +++ /dev/null @@ -1,68 +0,0 @@ -const readlineSync = require("readline-sync"); -const octokit = require('@octokit/rest')({ - timeout: 0, // 0 means no request timeout - requestMedia: 'application/vnd.github.v3+json', - headers: { - 'user-agent': 'octokit/rest.js v1.2.3' // v1.2.3 will be current version - }, - - // change for custom GitHub Enterprise URL - //host: 'api.github.com', - //pathPrefix: '', - //protocol: 'https', - //port: 443, - - // Node only: advanced request options can be passed as http(s) agent - //agent: undefined - }); - -console.log("NodeJS Path: ", process.argv[0]); - -require("dotenv").config(); - -const clientId = process.env.OCTOKIT_CLIENT_ID; -const clientSecret = process.env.OCTOKIT_CLIENT_SECRET; - -const appName = process.env.OCTORUN_APP_NAME | "octorun"; -let user = process.env.OCTORUN_USER; -const token = process.env.OCTORUN_TOKEN; - -const scopes = ["user", "repo", "gist", "write:public_key"]; - -if(user != null && token != null) -{ - -} -else -{ - user = readlineSync.question('User: '); - - var pwd = readlineSync.question('Password: ', { - hideEchoBack: true - }); - - octokit.authenticate({ - type:"basic", - username:user, - password:pwd - }); - - octokit.authorization.create({ - scopes: scopes, - note: appName, - client_id: clientId, - client_secret: clientSecret - }, function(err, res) { - - console.log("err", err, "res", res); - - if(err) - { - - } - else - { - - } - }); -} diff --git a/octorun-modern/package-lock.json b/octorun-modern/package-lock.json deleted file mode 100644 index a769d5561..000000000 --- a/octorun-modern/package-lock.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "octorun-modern", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@octokit/rest": { - "version": "14.0.9", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-14.0.9.tgz", - "integrity": "sha512-irP9phKfTXEZIcW2R+VNCtGHZJrXMWmSYp6RRfFn4BtAqtDRXF5z9JxCEQlAhNBf6X1koNi5k49tIAAAEJNlVQ==", - "requires": { - "before-after-hook": "1.1.0", - "debug": "3.1.0", - "is-array-buffer": "1.0.0", - "is-stream": "1.1.0", - "lodash": "4.17.5", - "url-template": "2.0.8" - } - }, - "before-after-hook": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.1.0.tgz", - "integrity": "sha512-VOMDtYPwLbIncTxNoSzRyvaMxtXmLWLUqr8k5AfC1BzLk34HvBXaQX8snOwQZ4c0aX8aSERqtJSiI9/m2u5kuA==" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "dotenv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-1.0.0.tgz", - "integrity": "sha1-/cUn/GZBHGHXSjq50Znr+HRTLNQ=" - }, - "is-array-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-1.0.0.tgz", - "integrity": "sha512-KtzJzWuC1kZQ377GJbEsoBh0LuQh1uaZnQg8oL2LcDkY/Ny8rpAzu21Ls3oph3SEKXbnrLHt3rAUVm28iuEPfw==" - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "lodash": { - "version": "4.17.5", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", - "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==" - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "readline-sync": { - "version": "1.4.9", - "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.9.tgz", - "integrity": "sha1-PtqOZfI80qF+YTAbHwADOWr17No=" - }, - "url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" - } - } -} diff --git a/octorun-modern/package.json b/octorun-modern/package.json deleted file mode 100644 index 7a3648841..000000000 --- a/octorun-modern/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "octorun-modern", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "ISC", - "dependencies": { - "@octokit/rest": "^14.0.9", - "dotenv": "^1.0.0", - "readline-sync": "^1.4.9" - } -} From 70273deb8185a8069bcf3596a6a4938e1cfd7189 Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Thu, 1 Mar 2018 16:18:24 -0500 Subject: [PATCH 072/873] Updating package name --- octorun/package.json | 2 +- octorun/src/octokit.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/octorun/package.json b/octorun/package.json index 2fd6a68ce..2485e16e1 100644 --- a/octorun/package.json +++ b/octorun/package.json @@ -12,7 +12,7 @@ "dependencies": { "commander": "^2.14.1", "dotenv": "^1.0.0", - "octokit-rest-nothing-to-see-here-kthxbye": "^1.0.1", + "octokit-rest-for-node-v0.12": "^1.0.1", "readline-sync": "^1.4.9" } } diff --git a/octorun/src/octokit.js b/octorun/src/octokit.js index f75250491..1cf90b1ac 100644 --- a/octorun/src/octokit.js +++ b/octorun/src/octokit.js @@ -1,4 +1,4 @@ -var Octokit = require('octokit-rest-nothing-to-see-here-kthxbye'); +var Octokit = require('octokit-rest-for-node-v0.12'); var createOctokit = function () { return Octokit({ From 119def35891002c5f03f2cfb27727d26bfeb5d6a Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Thu, 1 Mar 2018 16:19:38 -0500 Subject: [PATCH 073/873] Making package version exact --- octorun/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/octorun/package.json b/octorun/package.json index 2485e16e1..dc1ceee3e 100644 --- a/octorun/package.json +++ b/octorun/package.json @@ -12,7 +12,7 @@ "dependencies": { "commander": "^2.14.1", "dotenv": "^1.0.0", - "octokit-rest-for-node-v0.12": "^1.0.1", + "octokit-rest-for-node-v0.12": "1.0.1", "readline-sync": "^1.4.9" } } From effa004d550f5bae8cc0dab5b2a41362737fe163 Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Fri, 2 Mar 2018 08:39:45 -0500 Subject: [PATCH 074/873] Initial hardcoding where to find octorun.js --- .../Application/ApplicationManagerBase.cs | 14 +++++++++----- src/GitHub.Api/Platform/DefaultEnvironment.cs | 1 + src/GitHub.Api/Platform/IEnvironment.cs | 1 + 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/GitHub.Api/Application/ApplicationManagerBase.cs b/src/GitHub.Api/Application/ApplicationManagerBase.cs index 83283b6af..cdba86a67 100644 --- a/src/GitHub.Api/Application/ApplicationManagerBase.cs +++ b/src/GitHub.Api/Application/ApplicationManagerBase.cs @@ -47,23 +47,26 @@ public void Run(bool firstRun) { Logger.Trace("Run - CurrentDirectory {0}", NPath.CurrentDirectory); + var applicationDataPath = Environment.GetSpecialFolder(System.Environment.SpecialFolder.LocalApplicationData).ToNPath(); + var octorunExecPath = applicationDataPath.Combine("octorun", "bin", "octorun"); + var gitExecutablePath = SystemSettings.Get(Constants.GitInstallPathKey)?.ToNPath(); if (gitExecutablePath != null && gitExecutablePath.FileExists()) // we have a git path { Logger.Trace("Using git install path from settings: {0}", gitExecutablePath); - InitializeEnvironment(gitExecutablePath); + InitializeEnvironment(gitExecutablePath, octorunExecPath); } else // we need to go find git { Logger.Trace("No git path found in settings"); - var initEnvironmentTask = new ActionTask(CancellationToken, (b, path) => InitializeEnvironment(path)) { Affinity = TaskAffinity.UI }; + var initEnvironmentTask = new ActionTask(CancellationToken, (b, path) => InitializeEnvironment(path, octorunExecPath)) { Affinity = TaskAffinity.UI }; var findExecTask = new FindExecTask("git", CancellationToken) .FinallyInUI((b, ex, path) => { if (b && path != null) { Logger.Trace("FindExecTask Success: {0}", path); - InitializeEnvironment(gitExecutablePath); + InitializeEnvironment(gitExecutablePath, octorunExecPath); } else { @@ -72,7 +75,6 @@ public void Run(bool firstRun) } }); - var applicationDataPath = Environment.GetSpecialFolder(System.Environment.SpecialFolder.LocalApplicationData).ToNPath(); var installDetails = new GitInstallDetails(applicationDataPath, true); var gitInstaller = new GitInstaller(Environment, CancellationToken, installDetails); @@ -170,12 +172,14 @@ protected void SetupMetrics(string unityVersion, bool firstRun) /// Initialize environment after finding where git is. This needs to run on the main thread /// /// - private void InitializeEnvironment(NPath gitExecutablePath) + /// + private void InitializeEnvironment(NPath gitExecutablePath, NPath octorunExecPath) { var afterGitSetup = new ActionTask(CancellationToken, RestartRepository) .ThenInUI(InitializeUI); Environment.GitExecutablePath = gitExecutablePath; + Environment.OctorunExectablePath = octorunExecPath; Environment.User.Initialize(GitClient); if (Environment.IsWindows) diff --git a/src/GitHub.Api/Platform/DefaultEnvironment.cs b/src/GitHub.Api/Platform/DefaultEnvironment.cs index 5536e93a0..f9955a645 100644 --- a/src/GitHub.Api/Platform/DefaultEnvironment.cs +++ b/src/GitHub.Api/Platform/DefaultEnvironment.cs @@ -116,6 +116,7 @@ public string GetEnvironmentVariable(string variable) public NPath SystemCachePath { get; set; } public NPath Path { get { return Environment.GetEnvironmentVariable("PATH").ToNPath(); } } public string NewLine { get { return Environment.NewLine; } } + public NPath OctorunExectablePath { get; set; } private NPath gitExecutablePath; public NPath GitExecutablePath diff --git a/src/GitHub.Api/Platform/IEnvironment.cs b/src/GitHub.Api/Platform/IEnvironment.cs index d37c89ec9..e24572c1b 100644 --- a/src/GitHub.Api/Platform/IEnvironment.cs +++ b/src/GitHub.Api/Platform/IEnvironment.cs @@ -13,6 +13,7 @@ public interface IEnvironment NPath Path { get; } string NewLine { get; } NPath GitExecutablePath { get; set; } + NPath OctorunExectablePath { get; set; } bool IsWindows { get; } bool IsLinux { get; } bool IsMac { get; } From 1b094a146defd80bbd7a26eca042dfd7ff07e54b Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Fri, 2 Mar 2018 12:41:33 -0500 Subject: [PATCH 075/873] Starting to call octorun in nodejs --- octorun/src/bin/app-login.js | 6 +- src/GitHub.Api/Application/ApiClient.cs | 15 ++-- .../Application/ApplicationManagerBase.cs | 24 +++--- .../Application/IApplicationManager.cs | 2 - src/GitHub.Api/Authentication/LoginManager.cs | 77 +++++++++++-------- src/GitHub.Api/Platform/DefaultEnvironment.cs | 19 ++++- src/GitHub.Api/Platform/IEnvironment.cs | 3 +- .../Editor/GitHub.Unity/ApplicationManager.cs | 5 -- .../Editor/GitHub.Unity/Misc/Utility.cs | 28 ------- .../Services/AuthenticationService.cs | 4 +- .../GitHub.Unity/UI/AuthenticationView.cs | 2 +- .../Editor/GitHub.Unity/UI/PopupWindow.cs | 2 +- .../Editor/GitHub.Unity/UI/PublishView.cs | 2 +- .../Assets/Editor/GitHub.Unity/UI/Window.cs | 2 +- .../IntegrationTestEnvironment.cs | 2 + 15 files changed, 91 insertions(+), 102 deletions(-) diff --git a/octorun/src/bin/app-login.js b/octorun/src/bin/app-login.js index c0b7bddb2..19f2582fd 100644 --- a/octorun/src/bin/app-login.js +++ b/octorun/src/bin/app-login.js @@ -13,7 +13,7 @@ if (commander.twoFactor) { process.exit(); }, function (err) { console.log(err); - process.exit(-1); + process.exit(); }); } else { @@ -22,9 +22,9 @@ else { process.exit(); }, function () { console.log("Must specify two-factor authentication OTP code."); - process.exit(1); + process.exit(); }, function (err) { console.log(err); - process.exit(-1); + process.exit(); }); } \ No newline at end of file diff --git a/src/GitHub.Api/Application/ApiClient.cs b/src/GitHub.Api/Application/ApiClient.cs index a691c6321..59ea6a55b 100644 --- a/src/GitHub.Api/Application/ApiClient.cs +++ b/src/GitHub.Api/Application/ApiClient.cs @@ -10,7 +10,7 @@ namespace GitHub.Unity { class ApiClient : IApiClient { - public static IApiClient Create(UriString repositoryUrl, IKeychain keychain, IProcessManager processManager, ITaskManager taskManager, NPath loginTool) + public static IApiClient Create(UriString repositoryUrl, IKeychain keychain, IProcessManager processManager, ITaskManager taskManager, NPath nodeJsExecutablePath, NPath octorunScriptPath) { logger.Trace("Creating ApiClient: {0}", repositoryUrl); @@ -19,7 +19,7 @@ public static IApiClient Create(UriString repositoryUrl, IKeychain keychain, IPr return new ApiClient(repositoryUrl, keychain, new GitHubClient(ApplicationConfiguration.ProductHeader, credentialStore, hostAddress.ApiUri), - processManager, taskManager, loginTool); + processManager, taskManager, nodeJsExecutablePath, octorunScriptPath); } private static readonly ILogging logger = LogHelper.GetLogger(); @@ -30,10 +30,10 @@ public static IApiClient Create(UriString repositoryUrl, IKeychain keychain, IPr private readonly IGitHubClient githubClient; private readonly IProcessManager processManager; private readonly ITaskManager taskManager; - private readonly NPath loginTool; + private readonly NPath octorunScriptPath; private readonly ILoginManager loginManager; - public ApiClient(UriString hostUrl, IKeychain keychain, IGitHubClient githubClient, IProcessManager processManager, ITaskManager taskManager, NPath loginTool) + public ApiClient(UriString hostUrl, IKeychain keychain, IGitHubClient githubClient, IProcessManager processManager, ITaskManager taskManager, NPath nodeJsExecutablePath, NPath octorunScriptPath) { Guard.ArgumentNotNull(hostUrl, nameof(hostUrl)); Guard.ArgumentNotNull(keychain, nameof(keychain)); @@ -45,11 +45,12 @@ public ApiClient(UriString hostUrl, IKeychain keychain, IGitHubClient githubClie this.githubClient = githubClient; this.processManager = processManager; this.taskManager = taskManager; - this.loginTool = loginTool; + this.octorunScriptPath = octorunScriptPath; loginManager = new LoginManager(keychain, ApplicationInfo.ClientId, ApplicationInfo.ClientSecret, processManager: processManager, - taskManager: taskManager, - loginTool: loginTool); + taskManager: taskManager, + nodeJsExecutablePath: nodeJsExecutablePath, + octorunScript: octorunScriptPath); } public async Task Logout(UriString host) diff --git a/src/GitHub.Api/Application/ApplicationManagerBase.cs b/src/GitHub.Api/Application/ApplicationManagerBase.cs index cdba86a67..2d0093808 100644 --- a/src/GitHub.Api/Application/ApplicationManagerBase.cs +++ b/src/GitHub.Api/Application/ApplicationManagerBase.cs @@ -47,26 +47,26 @@ public void Run(bool firstRun) { Logger.Trace("Run - CurrentDirectory {0}", NPath.CurrentDirectory); - var applicationDataPath = Environment.GetSpecialFolder(System.Environment.SpecialFolder.LocalApplicationData).ToNPath(); - var octorunExecPath = applicationDataPath.Combine("octorun", "bin", "octorun"); + var octorunScriptPath = Environment.UserCachePath.Combine("octorun", "src", "bin", "app.js"); + Logger.Trace("Using octorunScriptPath: {0}", octorunScriptPath); var gitExecutablePath = SystemSettings.Get(Constants.GitInstallPathKey)?.ToNPath(); if (gitExecutablePath != null && gitExecutablePath.FileExists()) // we have a git path { Logger.Trace("Using git install path from settings: {0}", gitExecutablePath); - InitializeEnvironment(gitExecutablePath, octorunExecPath); + InitializeEnvironment(gitExecutablePath, octorunScriptPath); } else // we need to go find git { Logger.Trace("No git path found in settings"); - var initEnvironmentTask = new ActionTask(CancellationToken, (b, path) => InitializeEnvironment(path, octorunExecPath)) { Affinity = TaskAffinity.UI }; + var initEnvironmentTask = new ActionTask(CancellationToken, (b, path) => InitializeEnvironment(path, octorunScriptPath)) { Affinity = TaskAffinity.UI }; var findExecTask = new FindExecTask("git", CancellationToken) .FinallyInUI((b, ex, path) => { if (b && path != null) { Logger.Trace("FindExecTask Success: {0}", path); - InitializeEnvironment(gitExecutablePath, octorunExecPath); + InitializeEnvironment(gitExecutablePath, octorunScriptPath); } else { @@ -75,7 +75,7 @@ public void Run(bool firstRun) } }); - var installDetails = new GitInstallDetails(applicationDataPath, true); + var installDetails = new GitInstallDetails(Environment.GetSpecialFolder(System.Environment.SpecialFolder.LocalApplicationData).ToNPath(), true); var gitInstaller = new GitInstaller(Environment, CancellationToken, installDetails); // if successful, continue with environment initialization, otherwise try to find an existing git installation @@ -172,14 +172,14 @@ protected void SetupMetrics(string unityVersion, bool firstRun) /// Initialize environment after finding where git is. This needs to run on the main thread /// /// - /// - private void InitializeEnvironment(NPath gitExecutablePath, NPath octorunExecPath) + /// + private void InitializeEnvironment(NPath gitExecutablePath, NPath octorunScriptPath) { var afterGitSetup = new ActionTask(CancellationToken, RestartRepository) .ThenInUI(InitializeUI); Environment.GitExecutablePath = gitExecutablePath; - Environment.OctorunExectablePath = octorunExecPath; + Environment.OctorunScriptPath = octorunScriptPath; Environment.User.Initialize(GitClient); if (Environment.IsWindows) @@ -221,11 +221,6 @@ protected virtual void Dispose(bool disposing) } } - public virtual NPath GetTool(string tool) - { - return null; - } - public void Dispose() { Dispose(true); @@ -243,7 +238,6 @@ public void Dispose() public ISettings SystemSettings { get; protected set; } public ISettings UserSettings { get; protected set; } public IUsageTracker UsageTracker { get; protected set; } - public NPath LoginTool => GetTool("octorun.exe"); protected TaskScheduler UIScheduler { get; private set; } protected SynchronizationContext SynchronizationContext { get; private set; } protected IRepositoryManager RepositoryManager { get { return repositoryManager; } } diff --git a/src/GitHub.Api/Application/IApplicationManager.cs b/src/GitHub.Api/Application/IApplicationManager.cs index 004c4e7d9..fd59878a8 100644 --- a/src/GitHub.Api/Application/IApplicationManager.cs +++ b/src/GitHub.Api/Application/IApplicationManager.cs @@ -17,11 +17,9 @@ public interface IApplicationManager : IDisposable ITaskManager TaskManager { get; } IGitClient GitClient { get; } IUsageTracker UsageTracker { get; } - NPath LoginTool { get; } void Run(bool firstRun); void RestartRepository(); ITask InitializeRepository(); - NPath GetTool(string tool); } } \ No newline at end of file diff --git a/src/GitHub.Api/Authentication/LoginManager.cs b/src/GitHub.Api/Authentication/LoginManager.cs index eae7156ab..fd83383d5 100644 --- a/src/GitHub.Api/Authentication/LoginManager.cs +++ b/src/GitHub.Api/Authentication/LoginManager.cs @@ -30,7 +30,8 @@ class LoginManager : ILoginManager private readonly string fingerprint; private readonly IProcessManager processManager; private readonly ITaskManager taskManager; - private readonly NPath loginTool; + private readonly NPath nodeJsExecutablePath; + private readonly NPath octorunScript; /// /// Initializes a new instance of the class. @@ -42,16 +43,15 @@ class LoginManager : ILoginManager /// The machine fingerprint. /// /// - /// - /// The cache in which to store login details. - /// The handler for 2FA challenges. + /// + /// public LoginManager( IKeychain keychain, string clientId, string clientSecret, string authorizationNote = null, string fingerprint = null, - IProcessManager processManager = null, ITaskManager taskManager = null, NPath loginTool = null) + IProcessManager processManager = null, ITaskManager taskManager = null, NPath nodeJsExecutablePath = null, NPath octorunScript = null) { Guard.ArgumentNotNull(keychain, nameof(keychain)); Guard.ArgumentNotNullOrWhiteSpace(clientId, nameof(clientId)); @@ -64,7 +64,8 @@ public LoginManager( this.fingerprint = fingerprint; this.processManager = processManager; this.taskManager = taskManager; - this.loginTool = loginTool; + this.nodeJsExecutablePath = nodeJsExecutablePath; + this.octorunScript = octorunScript; } /// @@ -258,11 +259,11 @@ private async Task TryLogin( string password ) { - logger.Info("Login Username:{0} {1}", username, loginTool); + logger.Info("Login Username:{0} {1}", username, octorunScript); ApplicationAuthorization auth = null; - var loginTask = new SimpleListProcessTask(taskManager.Token, loginTool, $"login --host={host}"); - loginTask.Configure(processManager, workingDirectory: loginTool.Parent, withInput: true); + var loginTask = new SimpleListProcessTask(taskManager.Token, nodeJsExecutablePath, $"{octorunScript} login"); + loginTask.Configure(processManager, workingDirectory: octorunScript.Parent.Parent.Parent, withInput: true); loginTask.OnStartProcess += proc => { proc.StandardInput.WriteLine(username); @@ -270,31 +271,39 @@ string password proc.StandardInput.Close(); }; var ret = await loginTask.StartAwait(); - if (ret.Count == 0) + + foreach (var result in ret) { - throw new Exception("Authentication failed"); + logger.Trace(result); } - // success - else if (ret.Count == 1) - { - auth = new ApplicationAuthorization(ret[0]); - } - else - { - if (ret[0] == "2fa") - { - keychain.SetToken(host, ret[1]); - await keychain.Save(host); - throw new TwoFactorRequiredException(TwoFactorType.Unknown); - } - else if (ret[0] == "locked") - { - throw new LoginAttemptsExceededException(null, null); - } - else - throw new Exception("Authentication failed"); - } - return auth; + + throw new Exception("Authentication failed"); + + // if (ret.Count == 0) + // { + // throw new Exception("Authentication failed"); + // } + // // success + // else if (ret.Count == 1) + // { + // auth = new ApplicationAuthorization(ret[0]); + // } + // else + // { + // if (ret[0] == "Must specify two-factor authentication OTP code.") + // { + // keychain.SetToken(host, ret[1]); + // await keychain.Save(host); + // throw new TwoFactorRequiredException(TwoFactorType.Unknown); + // } + // else if (ret[0] == "locked") + // { + // throw new LoginAttemptsExceededException(null, null); + // } + // else + // throw new Exception("Authentication failed"); + // } + // return auth; } private async Task TryContinueLogin( @@ -308,8 +317,8 @@ string code logger.Info("Continue Username:{0}", username); ApplicationAuthorization auth = null; - var loginTask = new SimpleListProcessTask(taskManager.Token, loginTool, $"login --host={host} --2fa"); - loginTask.Configure(processManager, workingDirectory: loginTool.Parent, withInput: true); + var loginTask = new SimpleListProcessTask(taskManager.Token, nodeJsExecutablePath, $"{octorunScript} login --twoFactor"); + loginTask.Configure(processManager, workingDirectory: nodeJsExecutablePath.Parent, withInput: true); loginTask.OnStartProcess += proc => { proc.StandardInput.WriteLine(username); diff --git a/src/GitHub.Api/Platform/DefaultEnvironment.cs b/src/GitHub.Api/Platform/DefaultEnvironment.cs index f9955a645..24056d69d 100644 --- a/src/GitHub.Api/Platform/DefaultEnvironment.cs +++ b/src/GitHub.Api/Platform/DefaultEnvironment.cs @@ -116,7 +116,7 @@ public string GetEnvironmentVariable(string variable) public NPath SystemCachePath { get; set; } public NPath Path { get { return Environment.GetEnvironmentVariable("PATH").ToNPath(); } } public string NewLine { get { return Environment.NewLine; } } - public NPath OctorunExectablePath { get; set; } + public NPath OctorunScriptPath { get; set; } private NPath gitExecutablePath; public NPath GitExecutablePath @@ -132,6 +132,23 @@ public NPath GitExecutablePath } } + private NPath nodeJsExecutablePath; + + public NPath NodeJsExecutablePath + { + get + { + if (nodeJsExecutablePath == null) + { + nodeJsExecutablePath = IsWindows + ? UnityApplication.Parent.Combine("Data", "Tools", "nodejs", "node.exe") + : UnityApplication.Combine("Contents", "Tools", "nodejs", "node"); + } + + return nodeJsExecutablePath; + } + } + public NPath GitInstallPath { get; private set; } public NPath RepositoryPath { get; private set; } diff --git a/src/GitHub.Api/Platform/IEnvironment.cs b/src/GitHub.Api/Platform/IEnvironment.cs index e24572c1b..59f7e0289 100644 --- a/src/GitHub.Api/Platform/IEnvironment.cs +++ b/src/GitHub.Api/Platform/IEnvironment.cs @@ -13,7 +13,8 @@ public interface IEnvironment NPath Path { get; } string NewLine { get; } NPath GitExecutablePath { get; set; } - NPath OctorunExectablePath { get; set; } + NPath NodeJsExecutablePath { get; } + NPath OctorunScriptPath { get; set; } bool IsWindows { get; } bool IsLinux { get; } bool IsMac { get; } diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationManager.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationManager.cs index 47780c415..c5fcfd00c 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationManager.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationManager.cs @@ -21,11 +21,6 @@ public ApplicationManager(IMainThreadSynchronizationContext synchronizationConte Initialize(); } - public override NPath GetTool(string tool) - { - return Utility.GetTool(tool); - } - protected override void SetupMetrics() { SetupMetrics(Environment.UnityVersion, ApplicationCache.Instance.FirstRun); diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/Misc/Utility.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/Misc/Utility.cs index 7bd4e70ad..91f2a9400 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/Misc/Utility.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/Misc/Utility.cs @@ -50,34 +50,6 @@ public static Texture2D GetTextureFromColor(Color color) return result; } - - public static NPath GetTool(string tool) - { - var outfile = EntryPoint.Environment.UserCachePath.Combine("tools", tool); - outfile.EnsureParentDirectoryExists(); - - if (tool == "octorun.exe") - { - GetTool("Mono.Options.dll"); - GetTool("GitHub.Logging.dll"); - GetTool("Octokit.dll"); - } - - if (outfile.Exists()) - return outfile; - - var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("GitHub.Unity.Tools." + tool); - if (stream != null) - { - var targetFile = new FileInfo(outfile); - using (var outstream = targetFile.OpenWrite()) - { - ZipHelper.Copy(stream, outstream, 8192, stream.Length, null, 0); - } - } - LogHelper.GetLogger().Debug(outfile); - return outfile; - } } static class StreamExtensions diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/Services/AuthenticationService.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/Services/AuthenticationService.cs index c627615ee..73b38da86 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/Services/AuthenticationService.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/Services/AuthenticationService.cs @@ -8,9 +8,9 @@ class AuthenticationService private LoginResult loginResultData; - public AuthenticationService(UriString host, IKeychain keychain) + public AuthenticationService(UriString host, IKeychain keychain, NPath nodeJsExecutablePath, NPath octorunExecutablePath) { - client = ApiClient.Create(host, keychain, EntryPoint.ApplicationManager.ProcessManager, EntryPoint.ApplicationManager.TaskManager, EntryPoint.ApplicationManager.LoginTool); + client = ApiClient.Create(host, keychain, EntryPoint.ApplicationManager.ProcessManager, EntryPoint.ApplicationManager.TaskManager, nodeJsExecutablePath, octorunExecutablePath); } public void Login(string username, string password, Action twofaRequired, Action authResult) diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/AuthenticationView.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/AuthenticationView.cs index c7795c05a..fd3dc96e7 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/AuthenticationView.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/AuthenticationView.cs @@ -256,7 +256,7 @@ private AuthenticationService AuthenticationService host = UriString.ToUriString(HostAddress.GitHubDotComHostAddress.WebUri); } - AuthenticationService = new AuthenticationService(host, Platform.Keychain); + AuthenticationService = new AuthenticationService(host, Platform.Keychain, Environment.NodeJsExecutablePath, Environment.OctorunScriptPath); } return authenticationService; } diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/PopupWindow.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/PopupWindow.cs index 1fdd82047..f2a15fa89 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/PopupWindow.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/PopupWindow.cs @@ -198,7 +198,7 @@ public IApiClient Client host = UriString.ToUriString(HostAddress.GitHubDotComHostAddress.WebUri); } - client = ApiClient.Create(host, Platform.Keychain, Manager.ProcessManager, TaskManager, Manager.LoginTool); + client = ApiClient.Create(host, Platform.Keychain, Manager.ProcessManager, TaskManager, Environment.NodeJsExecutablePath, Environment.OctorunScriptPath); } return client; diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/PublishView.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/PublishView.cs index 4ff5cac35..29d1505cc 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/PublishView.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/PublishView.cs @@ -53,7 +53,7 @@ public IApiClient Client host = UriString.ToUriString(HostAddress.GitHubDotComHostAddress.WebUri); } - client = ApiClient.Create(host, Platform.Keychain, Manager.ProcessManager, TaskManager, Manager.LoginTool); + client = ApiClient.Create(host, Platform.Keychain, Manager.ProcessManager, TaskManager, Environment.NodeJsExecutablePath, Environment.OctorunScriptPath); } return client; diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/Window.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/Window.cs index 3f73c7107..b4cf889c1 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/Window.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/Window.cs @@ -451,7 +451,7 @@ private void SignOut(object obj) host = UriString.ToUriString(HostAddress.GitHubDotComHostAddress.WebUri); } - var apiClient = ApiClient.Create(host, Platform.Keychain, null, null, null); + var apiClient = ApiClient.Create(host, Platform.Keychain, null, null, null, null); apiClient.Logout(host); } diff --git a/src/tests/IntegrationTests/IntegrationTestEnvironment.cs b/src/tests/IntegrationTests/IntegrationTestEnvironment.cs index a99d636d1..7071f260a 100644 --- a/src/tests/IntegrationTests/IntegrationTestEnvironment.cs +++ b/src/tests/IntegrationTests/IntegrationTestEnvironment.cs @@ -104,6 +104,8 @@ public NPath GitExecutablePath } } + public NPath OctorunScriptPath { get; set; } + public bool IsWindows => defaultEnvironment.IsWindows; public bool IsLinux => defaultEnvironment.IsLinux; public bool IsMac => defaultEnvironment.IsMac; From 7873cd26a664e49758c621739698eb94b51168af Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Fri, 2 Mar 2018 18:52:05 +0000 Subject: [PATCH 076/873] Make downloading parallel and fix concurrent threading Make the downloads in pairs (file and md5) in a downloader class that can run them all parallel. I kept getting deadlocks and it's something to do with how the concurrent scheduler is set up, so replaced it with a scheduler that just fires a thread per task and does nothing smart about it. --- src/GitHub.Api/GitHub.Api.csproj | 1 + src/GitHub.Api/IO/NiceIO.cs | 5 + src/GitHub.Api/IO/Utils.cs | 65 +-- src/GitHub.Api/Installer/GitInstaller.cs | 49 +-- src/GitHub.Api/Installer/UnzipTask.cs | 4 +- src/GitHub.Api/Managers/Downloader.cs | 216 ++++++++++ src/GitHub.Api/Tasks/ActionTask.cs | 19 + .../Tasks/ConcurrentExclusiveInterleave.cs | 52 ++- src/GitHub.Api/Tasks/DownloadTask.cs | 106 +---- src/GitHub.Api/Tasks/TaskBase.cs | 20 +- src/GitHub.Api/Tasks/TaskManager.cs | 4 +- .../Download/DownloadTaskTests.cs | 384 +++++++++++++----- src/tests/IntegrationTests/UnzipTaskTests.cs | 46 +-- src/tests/TaskSystemIntegrationTests/Tests.cs | 4 +- src/tests/TestWebServer/HttpServer.cs | 6 +- 15 files changed, 636 insertions(+), 345 deletions(-) create mode 100644 src/GitHub.Api/Managers/Downloader.cs diff --git a/src/GitHub.Api/GitHub.Api.csproj b/src/GitHub.Api/GitHub.Api.csproj index 6b45e1234..073f5da6d 100644 --- a/src/GitHub.Api/GitHub.Api.csproj +++ b/src/GitHub.Api/GitHub.Api.csproj @@ -118,6 +118,7 @@ + diff --git a/src/GitHub.Api/IO/NiceIO.cs b/src/GitHub.Api/IO/NiceIO.cs index eab97ee5c..27e59377a 100644 --- a/src/GitHub.Api/IO/NiceIO.cs +++ b/src/GitHub.Api/IO/NiceIO.cs @@ -1074,6 +1074,11 @@ public static NPath Resolve(this NPath path) return new NPath(Mono.Unix.UnixPath.GetCompleteRealPath(path.ToString())); } + + public static string CalculateMD5(this NPath path) + { + return NPath.FileSystem.CalculateFileMD5(path); + } } public enum SlashMode diff --git a/src/GitHub.Api/IO/Utils.cs b/src/GitHub.Api/IO/Utils.cs index 2c0621906..34fcccdf0 100644 --- a/src/GitHub.Api/IO/Utils.cs +++ b/src/GitHub.Api/IO/Utils.cs @@ -82,68 +82,11 @@ public static bool Copy(Stream source, Stream destination, return success; } - - public static bool Download(ILogging logger, UriString url, - Stream destinationStream, - Func onProgress) + public static bool VerifyFileIntegrity(NPath file, NPath md5file) { - long bytes = destinationStream.Length; - - var expectingResume = bytes > 0; - - var webRequest = (HttpWebRequest)WebRequest.Create(url); - - if (expectingResume) - { - // classlib for 3.5 doesn't take long overloads... - webRequest.AddRange((int)bytes); - } - - webRequest.Method = "GET"; - webRequest.Timeout = ApplicationConfiguration.WebTimeout; - - if (expectingResume) - logger.Trace($"Resuming download of {url}"); - else - logger.Trace($"Downloading {url}"); - - using (var webResponse = (HttpWebResponse) webRequest.GetResponseWithoutException()) - { - var httpStatusCode = webResponse.StatusCode; - logger.Trace($"Downloading {url} StatusCode:{(int)webResponse.StatusCode}"); - - if (expectingResume && httpStatusCode == HttpStatusCode.RequestedRangeNotSatisfiable) - { - onProgress(bytes, bytes); - return true; - } - - if (!(httpStatusCode == HttpStatusCode.OK || httpStatusCode == HttpStatusCode.PartialContent)) - { - return false; - } - - if (expectingResume && httpStatusCode == HttpStatusCode.OK) - { - expectingResume = false; - destinationStream.Seek(0, SeekOrigin.Begin); - } - - var responseLength = webResponse.ContentLength; - if (expectingResume) - { - if (!onProgress(bytes, bytes + responseLength)) - return false; - } - - using (var responseStream = webResponse.GetResponseStream()) - { - return Copy(responseStream, destinationStream, responseLength, - progress: (totalRead, timeToFinish) => { - return onProgress(totalRead, responseLength); - }); - } - } + var expected = md5file.ReadAllText(); + var actual = file.CalculateMD5(); + return expected.Equals(actual, StringComparison.InvariantCultureIgnoreCase); } } } \ No newline at end of file diff --git a/src/GitHub.Api/Installer/GitInstaller.cs b/src/GitHub.Api/Installer/GitInstaller.cs index a1fdc3a56..c8e9e28c6 100644 --- a/src/GitHub.Api/Installer/GitInstaller.cs +++ b/src/GitHub.Api/Installer/GitInstaller.cs @@ -1,5 +1,6 @@ using System; using System.Threading; +using System.Threading.Tasks; using GitHub.Logging; namespace GitHub.Unity @@ -116,22 +117,27 @@ public void SetupGitIfNeeded(ActionTask onSuccess, ITask onFailure) return; } - var task = new FuncTask(cancellationToken, () => + var isGitExtractedTask = new FuncTask(cancellationToken, () => { if (!IsGitExtracted()) - { - Logger.Trace("SetupGitIfNeeded: Skipped"); - throw new Exception(); - } + return null; + Logger.Trace("SetupGitIfNeeded: Skipped"); return installDetails.GitExecutablePath; }); - var extractTask = ExtractPortableGit(); - extractTask.Then(onSuccess, TaskRunOptions.OnSuccess, taskIsTopOfChain: true); - extractTask.Then(onFailure, TaskRunOptions.OnFailure, taskIsTopOfChain: true); + isGitExtractedTask.OnEnd += (t, res, _, __) => + { + if (res == null) + { + var extractTask = ExtractPortableGit(); + extractTask.Then(onSuccess, TaskRunOptions.OnSuccess, taskIsTopOfChain: true); + extractTask.Then(onFailure, TaskRunOptions.OnFailure, taskIsTopOfChain: true); + t.Then(extractTask); + } + else + t.Then(onSuccess); + }; - task.Then(onSuccess, TaskRunOptions.OnSuccess, taskIsTopOfChain: true); - task.Then(extractTask, TaskRunOptions.OnFailure, taskIsTopOfChain: true); - task.Start(); + isGitExtractedTask.Start(); } private FuncTask ExtractPortableGit() @@ -157,6 +163,7 @@ private FuncTask CreateUnzipTasks(NPath gitExtractPath, NPath gitLfsExtra environment.FileSystem, GitInstallDetails.GitExtractedMD5); var unzipGitLfsTask = new UnzipTask(cancellationToken, gitLfsArchivePath, gitLfsExtractPath, sharpZipLibHelper, environment.FileSystem, GitInstallDetails.GitLfsExtractedMD5); + var moveGitTask = new FuncTask(cancellationToken, () => MoveGitAndLfs(gitExtractPath, gitLfsExtractPath, tempZipExtractPath)); return unzipGitTask .Then(unzipGitLfsTask) @@ -191,24 +198,12 @@ private ITask CreateDownloadTask() gitArchiveFilePath = installDetails.PluginDataPath.Combine("git.zip"); gitLfsArchivePath = installDetails.PluginDataPath.Combine("git-lfs.zip"); - var downloadGitMd5Task = new DownloadTextTask(TaskManager.Instance.Token, environment.FileSystem, - installDetails.GitZipMd5Url, installDetails.PluginDataPath); - - var downloadGitTask = new DownloadTask(TaskManager.Instance.Token, environment.FileSystem, - installDetails.GitZipUrl, installDetails.PluginDataPath); - - var downloadGitLfsMd5Task = new DownloadTextTask(TaskManager.Instance.Token, environment.FileSystem, - installDetails.GitLfsZipMd5Url, installDetails.PluginDataPath); + var downloader = new Downloader(); - var downloadGitLfsTask = new DownloadTask(TaskManager.Instance.Token, environment.FileSystem, - installDetails.GitLfsZipUrl, installDetails.PluginDataPath); + downloader.QueueDownload(installDetails.GitZipUrl, installDetails.GitZipMd5Url, installDetails.PluginDataPath); + downloader.QueueDownload(installDetails.GitLfsZipUrl, installDetails.GitLfsZipMd5Url, installDetails.PluginDataPath); - return - downloadGitMd5Task.Then((b, s) => { downloadGitTask.ValidationHash = s; }) - .Then(downloadGitTask) - .Then(downloadGitLfsMd5Task) - .Then((b, s) => { downloadGitLfsTask.ValidationHash = s; }) - .Then(downloadGitLfsTask); + return downloader; } private bool IsGitExtracted() diff --git a/src/GitHub.Api/Installer/UnzipTask.cs b/src/GitHub.Api/Installer/UnzipTask.cs index 822d64e02..4e0eadb43 100644 --- a/src/GitHub.Api/Installer/UnzipTask.cs +++ b/src/GitHub.Api/Installer/UnzipTask.cs @@ -78,7 +78,7 @@ protected virtual void RunUnzip(bool success) if (expectedMD5 != null) { var calculatedMD5 = fileSystem.CalculateFolderMD5(extractedPath); - success = !calculatedMD5.Equals(expectedMD5, StringComparison.InvariantCultureIgnoreCase); + success = calculatedMD5.Equals(expectedMD5, StringComparison.InvariantCultureIgnoreCase); if (!success) { extractedPath.DeleteIfExists(); @@ -100,7 +100,7 @@ protected virtual void RunUnzip(bool success) if (!success) { Token.ThrowIfCancellationRequested(); - throw new UnzipException("Error downloading file", exception); + throw new UnzipException("Error unzipping file", exception); } } protected int RetryCount { get; } diff --git a/src/GitHub.Api/Managers/Downloader.cs b/src/GitHub.Api/Managers/Downloader.cs new file mode 100644 index 000000000..735862194 --- /dev/null +++ b/src/GitHub.Api/Managers/Downloader.cs @@ -0,0 +1,216 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Threading; +using System.Threading.Tasks; +using GitHub.Logging; +using System.Linq; + +namespace GitHub.Unity +{ + class DownloadData + { + public UriString Url { get; } + public NPath File { get; } + public DownloadData(UriString url, NPath file) + { + this.Url = url; + this.File = file; + } + } + + class Downloader : FuncListTask + { + public event Action DownloadStart; + public event Action DownloadComplete; + public event Action DownloadFailed; + + private readonly List downloaders = new List(); + + public Downloader() : base(TaskManager.Instance.Token, RunDownloaders) + {} + + public void QueueDownload(UriString url, UriString md5Url, NPath targetDirectory) + { + var pairDownloader = new PairDownloader(); + pairDownloader.QueueDownload(url, md5Url, targetDirectory); + downloaders.Add(pairDownloader); + } + + private static List RunDownloaders(bool success, FuncListTask source) + { + Downloader self = (Downloader)source; + List result = null; + var listOfTasks = new List>(); + foreach (var downloader in self.downloaders) + { + downloader.DownloadStart += self.DownloadStart; + downloader.DownloadComplete += self.DownloadComplete; + downloader.DownloadFailed += self.DownloadFailed; + listOfTasks.Add(downloader.Run()); + } + var res = TaskEx.WhenAll(listOfTasks).Result; + if (res != null) + result = new List(res); + return result; + } + + class PairDownloader + { + public event Action DownloadStart; + public event Action DownloadComplete; + public event Action DownloadFailed; + + private readonly List> queuedTasks = new List>(); + private readonly TaskCompletionSource aggregateDownloads = new TaskCompletionSource(); + private readonly IFileSystem fs; + private readonly CancellationToken cancellationToken; + + private volatile int finishedTaskCount; + private volatile bool isSuccessful = true; + private volatile Exception exception; + + public PairDownloader() + { + fs = NPath.FileSystem; + cancellationToken = TaskManager.Instance.Token; + DownloadComplete += d => aggregateDownloads.TrySetResult(d); + DownloadFailed += (_, e) => aggregateDownloads.TrySetException(e); + } + + public Task Run() + { + foreach (var task in queuedTasks) + task.Start(); + return aggregateDownloads.Task; + } + + public Task QueueDownload(UriString url, UriString md5Url, NPath targetDirectory) + { + var destinationFile = targetDirectory.Combine(url.Filename); + var destinationMd5 = targetDirectory.Combine(md5Url.Filename); + var result = new DownloadData(url, destinationFile); + + Action, NPath, bool, Exception> verifyDownload = (t, res, success, ex) => + { + var count = Interlocked.Increment(ref finishedTaskCount); + isSuccessful &= success; + if (!success) + exception = ex; + if (count == queuedTasks.Count) + { + if (!isSuccessful) + { + DownloadFailed(result, exception); + } + else + { + if (!Utils.VerifyFileIntegrity(destinationFile, destinationMd5)) + { + destinationMd5.Delete(); + destinationFile.Delete(); + DownloadFailed(result, new DownloadException($"Verification of {url} failed")); + } + else + DownloadComplete(result); + } + } + }; + + var md5Exists = destinationMd5.FileExists(); + var fileExists = destinationFile.FileExists(); + + if (!md5Exists) + { + destinationMd5.DeleteIfExists(); + var md5Download = new DownloadTask(cancellationToken, fs, md5Url, targetDirectory) + .Catch(e => DownloadFailed(result, e)); + md5Download.OnEnd += verifyDownload; + queuedTasks.Add(md5Download); + } + + if (!fileExists) + { + var fileDownload = new DownloadTask(cancellationToken, fs, url, targetDirectory) + .Catch(e => DownloadFailed(result, e)); + fileDownload.OnStart += _ => DownloadStart?.Invoke(result); + fileDownload.OnEnd += verifyDownload; + queuedTasks.Add(fileDownload); + } + + if (fileExists && md5Exists) + { + var verification = new FuncTask(cancellationToken, () => destinationFile); + verification.OnEnd += verifyDownload; + queuedTasks.Add(verification); + } + return aggregateDownloads.Task; + } + } + + public static bool Download(ILogging logger, UriString url, + Stream destinationStream, + Func onProgress) + { + long bytes = destinationStream.Length; + + var expectingResume = bytes > 0; + + var webRequest = (HttpWebRequest)WebRequest.Create(url); + + if (expectingResume) + { + // classlib for 3.5 doesn't take long overloads... + webRequest.AddRange((int)bytes); + } + + webRequest.Method = "GET"; + webRequest.Timeout = ApplicationConfiguration.WebTimeout; + + if (expectingResume) + logger.Trace($"Resuming download of {url}"); + else + logger.Trace($"Downloading {url}"); + + using (var webResponse = (HttpWebResponse)webRequest.GetResponseWithoutException()) + { + var httpStatusCode = webResponse.StatusCode; + logger.Trace($"Downloading {url} StatusCode:{(int)webResponse.StatusCode}"); + + if (expectingResume && httpStatusCode == HttpStatusCode.RequestedRangeNotSatisfiable) + { + onProgress(bytes, bytes); + return true; + } + + if (!(httpStatusCode == HttpStatusCode.OK || httpStatusCode == HttpStatusCode.PartialContent)) + { + return false; + } + + if (expectingResume && httpStatusCode == HttpStatusCode.OK) + { + expectingResume = false; + destinationStream.Seek(0, SeekOrigin.Begin); + } + + var responseLength = webResponse.ContentLength; + if (expectingResume) + { + if (!onProgress(bytes, bytes + responseLength)) + return false; + } + + using (var responseStream = webResponse.GetResponseStream()) + { + return Utils.Copy(responseStream, destinationStream, responseLength, + progress: (totalRead, timeToFinish) => + { + return onProgress(totalRead, responseLength); + }); + } + } + } + } +} diff --git a/src/GitHub.Api/Tasks/ActionTask.cs b/src/GitHub.Api/Tasks/ActionTask.cs index be0dd6790..abe89bbd9 100644 --- a/src/GitHub.Api/Tasks/ActionTask.cs +++ b/src/GitHub.Api/Tasks/ActionTask.cs @@ -280,6 +280,7 @@ protected override TResult RunWithData(bool success, T previousResult) class FuncListTask : DataTaskBase> { protected Func> Callback { get; } + protected Func, List> CallbackWithSelf { get; } protected Func> CallbackWithException { get; } public FuncListTask(CancellationToken token, Func> action) @@ -296,6 +297,13 @@ public FuncListTask(CancellationToken token, Func> acti this.CallbackWithException = action; } + public FuncListTask(CancellationToken token, Func, List> action) + : base(token) + { + Guard.ArgumentNotNull(action, "action"); + this.CallbackWithSelf = action; + } + public FuncListTask(Task> task) : base(task) { } @@ -312,12 +320,23 @@ protected override List RunWithReturn(bool success) { result = Callback(success); } + else if (CallbackWithSelf != null) + { + result = CallbackWithSelf(success, this); + } else if (CallbackWithException != null) { var thrown = GetThrownException(); result = CallbackWithException(success, thrown); } } + catch (AggregateException ex) + { + var e = ex.GetBaseException(); + Errors = e.Message; + if (!RaiseFaultHandlers(e)) + throw e; + } catch (Exception ex) { Errors = ex.Message; diff --git a/src/GitHub.Api/Tasks/ConcurrentExclusiveInterleave.cs b/src/GitHub.Api/Tasks/ConcurrentExclusiveInterleave.cs index 8d14887f4..47e2cd871 100644 --- a/src/GitHub.Api/Tasks/ConcurrentExclusiveInterleave.cs +++ b/src/GitHub.Api/Tasks/ConcurrentExclusiveInterleave.cs @@ -1,12 +1,19 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using System.Reflection; using System.Threading; using System.Threading.Tasks; namespace GitHub.Unity { + public interface ITaskScheduler + { + Queue Tasks { get; } + void ExecuteTask(Task task); + } + class TaskSchedulerExcludingThread : TaskScheduler { private static ParameterizedThreadStart longRunningThreadWork = new ParameterizedThreadStart(LongRunningThreadWork); @@ -91,7 +98,7 @@ public sealed class ConcurrentExclusiveInterleave /// Synchronizes all activity in this type and its generated schedulers. private readonly object internalLock; /// The scheduler used to queue and execute "reader" tasks that may run concurrently with other readers. - private readonly ConcurrentExclusiveTaskScheduler concurrentTaskScheduler; + private readonly ITaskScheduler concurrentTaskScheduler; /// Whether the exclusive processing of a task should include all of its children as well. private readonly bool exclusiveProcessingIncludesChildren; /// The scheduler used to queue and execute "writer" tasks that must run exclusively while no other tasks for this interleave are running. @@ -121,7 +128,8 @@ public ConcurrentExclusiveInterleave(bool exclusiveProcessingIncludesChildren) // Create the state for this interleave internalLock = new object(); this.exclusiveProcessingIncludesChildren = exclusiveProcessingIncludesChildren; - concurrentTaskScheduler = new ConcurrentExclusiveTaskScheduler(this, new Queue(), interleaveTaskScheduler.MaximumConcurrencyLevel); + //concurrentTaskScheduler = new ConcurrentExclusiveTaskScheduler(this, new Queue(), interleaveTaskScheduler.MaximumConcurrencyLevel); + concurrentTaskScheduler = new ThreadPerTaskScheduler(); exclusiveTaskScheduler = new ConcurrentExclusiveTaskScheduler(this, new Queue(), 1); } @@ -150,6 +158,8 @@ internal void NotifyOfNewWork() /// This has been separated out into its own method to improve the Parallel Tasks window experience. private void ConcurrentExclusiveInterleaveProcessor() { + Logging.LogHelper.GetLogger().Trace("ConcurrentExclusiveInterleaveProcessor"); + if (token.IsCancellationRequested) return; interleaveTaskScheduler.ThreadToExclude = Thread.CurrentThread.ManagedThreadId; @@ -262,7 +272,7 @@ private IEnumerable GetExclusiveTasks() /// Gets a TaskScheduler that can be used to schedule tasks to this interleave /// that may run concurrently with other tasks on this interleave. /// - public TaskScheduler ConcurrentTaskScheduler + public ITaskScheduler ConcurrentTaskScheduler { get { return concurrentTaskScheduler; } } @@ -330,7 +340,7 @@ public Task InterleaveTask /// /// A scheduler shim used to queue tasks to the interleave and execute those tasks on request of the interleave. /// - private class ConcurrentExclusiveTaskScheduler : TaskScheduler + private class ConcurrentExclusiveTaskScheduler : TaskScheduler, ITaskScheduler { /// The parent interleave. private readonly ConcurrentExclusiveInterleave interleave; @@ -389,7 +399,7 @@ protected override IEnumerable GetScheduledTasks() /// Executes a task on this scheduler. /// The task to be executed. - internal void ExecuteTask(Task task) + public void ExecuteTask(Task task) { var isProcessingTaskOnCurrentThread = this.processingTaskOnCurrentThread.Value; if (!isProcessingTaskOnCurrentThread) this.processingTaskOnCurrentThread.Value = true; @@ -413,7 +423,37 @@ public override int MaximumConcurrencyLevel } /// Gets the queue of tasks for this scheduler. - internal Queue Tasks { get; } + public Queue Tasks { get; } + } + } + + /// Provides a task scheduler that dedicates a thread per task. + public class ThreadPerTaskScheduler : TaskScheduler, ITaskScheduler + { + /// Gets the tasks currently scheduled to this scheduler. + /// This will always return an empty enumerable, as tasks are launched as soon as they're queued. + protected override IEnumerable GetScheduledTasks() { return Enumerable.Empty(); } + public Queue Tasks { get; } = new Queue(); + + /// Starts a new thread to process the provided task. + /// The task to be executed. + protected override void QueueTask(Task task) + { + new Thread(() => TryExecuteTask(task)) { IsBackground = true }.Start(); + } + + /// Runs the provided task on the current thread. + /// The task to be executed. + /// Ignored. + /// Whether the task could be executed on the current thread. + protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) + { + return TryExecuteTask(task); + } + + public void ExecuteTask(Task task) + { + TryExecuteTask(task); } } } diff --git a/src/GitHub.Api/Tasks/DownloadTask.cs b/src/GitHub.Api/Tasks/DownloadTask.cs index 934c1d757..b253c0ec8 100644 --- a/src/GitHub.Api/Tasks/DownloadTask.cs +++ b/src/GitHub.Api/Tasks/DownloadTask.cs @@ -1,7 +1,6 @@ using System; using System.IO; using System.Net; -using System.Text; using System.Threading; namespace GitHub.Unity @@ -26,7 +25,7 @@ public static WebResponse GetResponseWithoutException(this WebRequest request) } } - class DownloadTask : TaskBase + class DownloadTask : TaskBase { protected readonly IFileSystem fileSystem; @@ -34,11 +33,10 @@ public DownloadTask(CancellationToken token, IFileSystem fileSystem, UriString url, NPath targetDirectory = null, string filename = null, - string validationHash = null, int retryCount = 0) + int retryCount = 0) : base(token) { this.fileSystem = fileSystem; - ValidationHash = validationHash; RetryCount = retryCount; Url = url; Filename = filename ?? url.Filename; @@ -51,7 +49,7 @@ protected string BaseRunWithReturn(bool success) return base.RunWithReturn(success); } - protected override string RunWithReturn(bool success) + protected override NPath RunWithReturn(bool success) { var result = base.RunWithReturn(success); @@ -83,70 +81,36 @@ protected override string RunWithReturn(bool success) /// /// /// - protected virtual string RunDownload(bool success) + protected virtual NPath RunDownload(bool success) { Exception exception = null; var attempts = 0; bool result = false; + var partialFile = TargetDirectory.Combine(Filename + ".partial"); do { + exception = null; + if (Token.IsCancellationRequested) break; - exception = null; - try { Logger.Trace($"Download of {Url} to {Destination} Attempt {attempts + 1} of {RetryCount + 1}"); - var fileExistsAndValid = false; - if (Destination.FileExists()) + using (var destinationStream = fileSystem.OpenWrite(partialFile, FileMode.Append)) { - if (ValidationHash == null) - { - Destination.Delete(); - } - else - { - var md5 = fileSystem.CalculateFileMD5(Destination); - result = md5.Equals(ValidationHash, StringComparison.CurrentCultureIgnoreCase); - - if (result) + result = Downloader.Download(Logger, Url, destinationStream, + (value, total) => { - Logger.Trace($"Download previously exists & confirmed {md5}"); - fileExistsAndValid = true; - } - } + UpdateProgress(value, total); + return !Token.IsCancellationRequested; + }); } - if (!fileExistsAndValid) + if (result) { - using (var destinationStream = fileSystem.OpenWrite(Destination, FileMode.Append)) - { - result = Utils.Download(Logger, Url, destinationStream, - (value, total) => - { - UpdateProgress(value, total); - return !Token.IsCancellationRequested; - }); - } - - if (result && ValidationHash != null) - { - var md5 = fileSystem.CalculateFileMD5(Destination); - result = md5.Equals(ValidationHash, StringComparison.CurrentCultureIgnoreCase); - - if (!result) - { - Logger.Warning($"Downloaded MD5 {md5} does not match {ValidationHash}. Deleting {Destination}."); - fileSystem.FileDelete(TargetDirectory); - } - else - { - Logger.Trace($"Download confirmed {md5}"); - break; - } - } + partialFile.Move(Destination); } } catch (Exception ex) @@ -177,8 +141,6 @@ public override string ToString() public NPath Destination { get { return TargetDirectory?.Combine(Filename); } } - public string ValidationHash { get; set; } - protected int RetryCount { get; } } @@ -190,42 +152,4 @@ public DownloadException(string message) : base(message) public DownloadException(string message, Exception innerException) : base(message, innerException) { } } - - class DownloadTextTask : DownloadTask - { - public DownloadTextTask(CancellationToken token, - IFileSystem fileSystem, UriString url, - NPath targetDirectory = null, - string filename = null, - int retryCount = 0) - : base(token, fileSystem, url, targetDirectory, filename, retryCount: retryCount) - { - Name = nameof(DownloadTextTask); - } - - protected override string RunWithReturn(bool success) - { - var result = BaseRunWithReturn(success); - - RaiseOnStart(); - - try - { - result = RunDownload(success); - result = fileSystem.ReadAllText(result, Encoding.UTF8); - } - catch (Exception ex) - { - Errors = ex.Message; - if (!RaiseFaultHandlers(ex)) - throw; - } - finally - { - RaiseOnEnd(result); - } - - return result; - } - } } diff --git a/src/GitHub.Api/Tasks/TaskBase.cs b/src/GitHub.Api/Tasks/TaskBase.cs index 21b3e4abd..a4a96c45d 100644 --- a/src/GitHub.Api/Tasks/TaskBase.cs +++ b/src/GitHub.Api/Tasks/TaskBase.cs @@ -43,7 +43,7 @@ public interface ITask : IAsyncResult CancellationToken Token { get; } TaskBase DependsOn { get; } event Action OnStart; - event Action OnEnd; + event Action OnEnd; ITask GetTopOfChain(); /// @@ -74,7 +74,7 @@ public interface ITask : ITask TResult Result { get; } new Task Task { get; } new event Action> OnStart; - new event Action, TResult> OnEnd; + new event Action, TResult, bool, Exception> OnEnd; } interface ITask : ITask @@ -89,12 +89,13 @@ public abstract class TaskBase : ITask protected const TaskContinuationOptions runOnFaultOptions = TaskContinuationOptions.OnlyOnFaulted; public event Action OnStart; - public event Action OnEnd; + public event Action OnEnd; protected bool previousSuccess = true; protected Exception previousException; protected bool taskFailed = false; protected bool exceptionWasHandled = false; + protected Exception exception; protected TaskBase continuationOnSuccess; protected TaskBase continuationOnFailure; @@ -394,7 +395,7 @@ protected virtual void RaiseOnStart() protected virtual void RaiseOnEnd() { - OnEnd?.Invoke(this); + OnEnd?.Invoke(this, !taskFailed, exception); if (!taskFailed || exceptionWasHandled) { if (continuationOnSuccess == null && continuationOnAlways == null) @@ -420,6 +421,7 @@ protected void CallFinallyHandler() protected virtual bool RaiseFaultHandlers(Exception ex) { taskFailed = true; + exception = ex; if (catchHandler == null) return continuationOnFailure != null; foreach (var handler in catchHandler.GetInvocationList()) @@ -479,7 +481,8 @@ abstract class TaskBase : TaskBase, ITask private event Action finallyHandler; public new event Action> OnStart; - public new event Action, TResult> OnEnd; + public new event Action, TResult, bool, Exception> OnEnd; + private TResult result; protected TaskBase(CancellationToken token) : base(token) @@ -613,7 +616,7 @@ public ITask Finally(Action continuation, TaskAffinity protected virtual TResult RunWithReturn(bool success) { base.Run(success); - return default(TResult); + return result; } protected override void RaiseOnStart() @@ -623,9 +626,10 @@ protected override void RaiseOnStart() base.RaiseOnStart(); } - protected virtual void RaiseOnEnd(TResult result) + protected virtual void RaiseOnEnd(TResult data) { - OnEnd?.Invoke(this, result); + this.result = data; + OnEnd?.Invoke(this, result, !taskFailed, exception); if (continuationOnSuccess == null && continuationOnFailure == null && continuationOnAlways == null) { finallyHandler?.Invoke(Task.Status == TaskStatus.RanToCompletion, result); diff --git a/src/GitHub.Api/Tasks/TaskManager.cs b/src/GitHub.Api/Tasks/TaskManager.cs index bd884c8a5..dcd1322f6 100644 --- a/src/GitHub.Api/Tasks/TaskManager.cs +++ b/src/GitHub.Api/Tasks/TaskManager.cs @@ -12,7 +12,7 @@ class TaskManager : ITaskManager private CancellationTokenSource cts; private readonly ConcurrentExclusiveInterleave manager; public TaskScheduler UIScheduler { get; set; } - public TaskScheduler ConcurrentScheduler { get { return manager.ConcurrentTaskScheduler; } } + public TaskScheduler ConcurrentScheduler { get { return (TaskScheduler)manager.ConcurrentTaskScheduler; } } public TaskScheduler ExclusiveScheduler { get { return manager.ExclusiveTaskScheduler; } } public CancellationToken Token { get { return cts.Token; } } @@ -149,7 +149,7 @@ private T ScheduleConcurrent(T task, bool setupFaultHandler) TaskContinuationOptions.OnlyOnFaulted, ConcurrentScheduler ); } - return (T)task.Start(manager.ConcurrentTaskScheduler); + return (T)task.Start((TaskScheduler)manager.ConcurrentTaskScheduler); } private void Stop() diff --git a/src/tests/IntegrationTests/Download/DownloadTaskTests.cs b/src/tests/IntegrationTests/Download/DownloadTaskTests.cs index c4745495a..c25325eb6 100644 --- a/src/tests/IntegrationTests/Download/DownloadTaskTests.cs +++ b/src/tests/IntegrationTests/Download/DownloadTaskTests.cs @@ -8,13 +8,14 @@ using System.Diagnostics; using GitHub.Logging; using System.Runtime.CompilerServices; +using System.Collections.Generic; namespace IntegrationTests.Download { - [TestFixture] - class DownloadTaskTests : BaseTaskManagerTest + class BaseDownloaderTest : BaseTaskManagerTest { - const int Timeout = 30000; + protected const int Timeout = 30000; + protected TestWebServer.HttpServer server; public override void OnSetup() { @@ -22,13 +23,12 @@ public override void OnSetup() InitializeEnvironment(TestBasePath, initializeRepository: false); } - private TestWebServer.HttpServer server; public override void TestFixtureSetUp() { base.TestFixtureSetUp(); server = new TestWebServer.HttpServer(SolutionDirectory.Combine("files")); Task.Factory.StartNew(server.Start); - ApplicationConfiguration.WebTimeout = 5000; + ApplicationConfiguration.WebTimeout = 50000; } public override void TestFixtureTearDown() @@ -38,14 +38,14 @@ public override void TestFixtureTearDown() ApplicationConfiguration.WebTimeout = ApplicationConfiguration.DefaultWebTimeout; } - private void StartTest(out Stopwatch watch, out ILogging logger, [CallerMemberName] string testName = "test") + protected void StartTest(out Stopwatch watch, out ILogging logger, [CallerMemberName] string testName = "test") { watch = new Stopwatch(); logger = LogHelper.GetLogger(testName); logger.Trace("Starting test"); } - private void StartTrackTime(Stopwatch watch, ILogging logger = null, string message = "") + protected void StartTrackTime(Stopwatch watch, ILogging logger = null, string message = "") { if (!String.IsNullOrEmpty(message)) logger.Trace(message); @@ -53,14 +53,198 @@ private void StartTrackTime(Stopwatch watch, ILogging logger = null, string mess watch.Start(); } - private void StopTrackTimeAndLog(Stopwatch watch, ILogging logger) + protected void StopTrackTimeAndLog(Stopwatch watch, ILogging logger) { watch.Stop(); logger.Trace($"Time: {watch.ElapsedMilliseconds}"); } + } + + [TestFixture] + class DownloaderTests : BaseDownloaderTest + { + [Test] + public async Task DownloadAndVerificationWorks() + { + Stopwatch watch; + ILogging logger; + StartTest(out watch, out logger); + + var fileSystem = Environment.FileSystem; + var fileUrl = new UriString($"http://localhost:{server.Port}/git-lfs.zip"); + var md5Url = new UriString($"http://localhost:{server.Port}/git-lfs.zip.MD5.txt"); + + var downloader = new Downloader(); + StartTrackTime(watch, logger, md5Url); + downloader.QueueDownload(fileUrl, md5Url, TestBasePath); + + var task = await TaskEx.WhenAny(downloader.Start().Task, TaskEx.Delay(Timeout)); + StopTrackTimeAndLog(watch, logger); + Assert.AreEqual(downloader.Task, task); + Assert.IsTrue(downloader.Successful); + var result = await downloader.Task; + Assert.AreEqual(1, result.Count); + Assert.AreEqual(TestBasePath.Combine(fileUrl.Filename), result[0].File); + } + + [Test] + public async Task DownloadingNonExistingFileThrows() + { + Stopwatch watch; + ILogging logger; + StartTest(out watch, out logger); + + var fileSystem = Environment.FileSystem; + var fileUrl = new UriString($"http://localhost:{server.Port}/nope"); + var md5Url = new UriString($"http://localhost:{server.Port}/git-lfs.zip.MD5.txt"); + + var downloader = new Downloader(); + StartTrackTime(watch, logger, md5Url); + downloader.QueueDownload(fileUrl, md5Url, TestBasePath); + var task = await TaskEx.WhenAny(downloader.Start().Task, TaskEx.Delay(Timeout)); + StopTrackTimeAndLog(watch, logger); + Assert.AreEqual(downloader.Task, task); + Assert.Throws(typeof(DownloadException), async () => await downloader.Task); + } + + [Test] + public async Task FailsIfVerificationFails() + { + Stopwatch watch; + ILogging logger; + StartTest(out watch, out logger); + + var fileSystem = Environment.FileSystem; + var fileUrl = new UriString($"http://localhost:{server.Port}/git.zip"); + var md5Url = new UriString($"http://localhost:{server.Port}/git-lfs.zip.MD5.txt"); + + var downloader = new Downloader(); + StartTrackTime(watch, logger, md5Url); + downloader.QueueDownload(fileUrl, md5Url, TestBasePath); + var task = await TaskEx.WhenAny(downloader.Start().Task, TaskEx.Delay(Timeout)); + StopTrackTimeAndLog(watch, logger); + Assert.AreEqual(downloader.Task, task); + Assert.Throws(typeof(DownloadException), async () => await downloader.Task); + } + + [Test] + public async Task ResumingWorks() + { + Stopwatch watch; + ILogging logger; + StartTest(out watch, out logger); + + var fileSystem = Environment.FileSystem; + var fileUrl = new UriString($"http://localhost:{server.Port}/git-lfs.zip"); + var md5Url = new UriString($"http://localhost:{server.Port}/git-lfs.zip.MD5.txt"); + + var downloader = new Downloader(); + StartTrackTime(watch, logger, md5Url); + downloader.QueueDownload(fileUrl, md5Url, TestBasePath); + var task = await TaskEx.WhenAny(downloader.Start().Task, TaskEx.Delay(Timeout)); + StopTrackTimeAndLog(watch, logger); + Assert.AreEqual(downloader.Task, task); + var result = await downloader.Task; + var downloadData = result.FirstOrDefault(); + + var downloadPathBytes = fileSystem.ReadAllBytes(downloadData.File); + Logger.Trace("File size {0} bytes", downloadPathBytes.Length); + + var cutDownloadPathBytes = downloadPathBytes.Take(downloadPathBytes.Length - 1000).ToArray(); + fileSystem.FileDelete(downloadData.File); + fileSystem.WriteAllBytes(downloadData + ".partial", cutDownloadPathBytes); + + downloader = new Downloader(); + StartTrackTime(watch, logger, "resuming download"); + downloader.QueueDownload(fileUrl, md5Url, TestBasePath); + task = await TaskEx.WhenAny(downloader.Start().Task, TaskEx.Delay(Timeout)); + StopTrackTimeAndLog(watch, logger); + Assert.AreEqual(downloader.Task, task); + result = await downloader.Task; + downloadData = result.FirstOrDefault(); + + var md5Sum = downloadData.File.CalculateMD5(); + var md5 = TestBasePath.Combine(md5Url.Filename).ReadAllText(); + md5Sum.Should().BeEquivalentTo(md5); + } + + [Test] + public async Task SucceedIfEverythingIsAlreadyDownloaded() + { + Stopwatch watch; + ILogging logger; + StartTest(out watch, out logger); + + var fileSystem = Environment.FileSystem; + var fileUrl = new UriString($"http://localhost:{server.Port}/git-lfs.zip"); + var md5Url = new UriString($"http://localhost:{server.Port}/git-lfs.zip.MD5.txt"); + + var downloader = new Downloader(); + StartTrackTime(watch, logger, md5Url); + downloader.QueueDownload(fileUrl, md5Url, TestBasePath); + var task = await TaskEx.WhenAny(downloader.Start().Task, TaskEx.Delay(Timeout)); + StopTrackTimeAndLog(watch, logger); + Assert.AreEqual(downloader.Task, task); + var downloadData = await downloader.Task; + var downloadPath = downloadData.FirstOrDefault().File; + + downloader = new Downloader(); + StartTrackTime(watch, logger, "downloading again"); + downloader.QueueDownload(fileUrl, md5Url, TestBasePath); + task = await TaskEx.WhenAny(downloader.Start().Task, TaskEx.Delay(Timeout)); + StopTrackTimeAndLog(watch, logger); + Assert.AreEqual(downloader.Task, task); + downloadData = await downloader.Task; + downloadPath = downloadData.FirstOrDefault().File; + + var md5Sum = downloadPath.CalculateMD5(); + var md5 = TestBasePath.Combine(md5Url.Filename).ReadAllText(); + md5Sum.Should().BeEquivalentTo(md5); + } + + [Test] + public async Task DownloadsRunSideBySide() + { + Stopwatch watch; + ILogging logger; + StartTest(out watch, out logger); + + var fileUrl1 = new UriString($"http://localhost:{server.Port}/git-lfs.zip"); + var md5Url1 = new UriString($"http://localhost:{server.Port}/git-lfs.zip.MD5.txt"); + var fileUrl2 = new UriString($"http://localhost:{server.Port}/git.zip"); + var md5Url2 = new UriString($"http://localhost:{server.Port}/git.zip.MD5.txt"); + + var events = new List(); + + var downloader = new Downloader(); + downloader.QueueDownload(fileUrl2, md5Url2, TestBasePath); + downloader.QueueDownload(fileUrl1, md5Url1, TestBasePath); + downloader.DownloadStart += d => events.Add("start " + d.Url.Filename); + downloader.DownloadComplete += d => events.Add("end " + d.Url.Filename); + downloader.DownloadFailed += (d, _) => events.Add("failed " + d.Url.Filename); + + server.Delay = 1; + StartTrackTime(watch, logger); + var task = await TaskEx.WhenAny(downloader.Start().Task, TaskEx.Delay(Timeout)); + StopTrackTimeAndLog(watch, logger); + server.Delay = 0; + + Assert.AreEqual(downloader.Task, task); + + CollectionAssert.AreEqual(new string[] { + "start git.zip", + "start git-lfs.zip", + "end git-lfs.zip", + "end git.zip", + }, events); + } + } + [TestFixture] + class DownloadTaskTests : BaseDownloaderTest + { [Test] - public void ResumingDownloadsWorks() + public async Task ResumingDownloadsWorks() { Stopwatch watch; ILogging logger; @@ -71,67 +255,47 @@ public void ResumingDownloadsWorks() var gitLfs = new UriString($"http://localhost:{server.Port}/git-lfs.zip"); var gitLfsMd5 = new UriString($"http://localhost:{server.Port}/git-lfs.zip.MD5.txt"); - var evtDone = new ManualResetEventSlim(false); - - string md5 = null; + var downloadTask = new DownloadTask(TaskManager.Token, fileSystem, gitLfsMd5, TestBasePath); StartTrackTime(watch, logger, gitLfsMd5); - new DownloadTextTask(TaskManager.Token, fileSystem, gitLfsMd5, TestBasePath) - .Finally((success, r) => { - md5 = r; - evtDone.Set(); - }) - .Start(); - - evtDone.Wait(Timeout).Should().BeTrue("Finally raised the signal"); + var task = await TaskEx.WhenAny(downloadTask.Start().Task, TaskEx.Delay(Timeout)); StopTrackTimeAndLog(watch, logger); - evtDone.Reset(); + task.ShouldBeEquivalentTo(downloadTask.Task); + var downloadPath = await downloadTask.Task; + var md5 = downloadPath.ReadAllText(); Assert.NotNull(md5); - string downloadPath = null; StartTrackTime(watch, logger, gitLfs); - new DownloadTask(TaskManager.Token, fileSystem, gitLfs, TestBasePath) - .Finally((success, r) => { - downloadPath = r; - evtDone.Set(); - }) - .Start(); + downloadTask = new DownloadTask(TaskManager.Token, fileSystem, gitLfs, TestBasePath); - evtDone.Wait(Timeout).Should().BeTrue("Finally raised the signal");; + StartTrackTime(watch, logger, gitLfsMd5); + task = await TaskEx.WhenAny(downloadTask.Start().Task, TaskEx.Delay(Timeout)); StopTrackTimeAndLog(watch, logger); + task.ShouldBeEquivalentTo(downloadTask.Task); - evtDone.Reset(); - + downloadPath = await downloadTask.Task; Assert.NotNull(downloadPath); - var md5Sum = fileSystem.CalculateFileMD5(downloadPath); + var md5Sum = downloadPath.CalculateMD5(); md5Sum.Should().BeEquivalentTo(md5); - var downloadPathBytes = fileSystem.ReadAllBytes(downloadPath); + var downloadPathBytes = downloadPath.ReadAllBytes(); Logger.Trace("File size {0} bytes", downloadPathBytes.Length); var cutDownloadPathBytes = downloadPathBytes.Take(downloadPathBytes.Length - 1000).ToArray(); - fileSystem.FileDelete(downloadPath); - fileSystem.WriteAllBytes(downloadPath, cutDownloadPathBytes); + downloadPath.Delete(); + new NPath(downloadPath + ".partial").WriteAllBytes(cutDownloadPathBytes); - StartTrackTime(watch, logger, "resuming download"); - new DownloadTask(TaskManager.Token, fileSystem, gitLfs, TestBasePath) - .Finally((success, r) => { - downloadPath = r; - evtDone.Set(); - }) - .Start(); + downloadTask = new DownloadTask(TaskManager.Token, fileSystem, gitLfs, TestBasePath); - evtDone.Wait(Timeout).Should().BeTrue("Finally raised the signal");; + StartTrackTime(watch, logger, gitLfs); + task = await TaskEx.WhenAny(downloadTask.Start().Task, TaskEx.Delay(Timeout)); StopTrackTimeAndLog(watch, logger); + task.ShouldBeEquivalentTo(downloadTask.Task); + downloadPath = await downloadTask.Task; - evtDone.Reset(); - - var downloadHalfPathBytes = fileSystem.ReadAllBytes(downloadPath); - Logger.Trace("File size {0} Bytes", downloadHalfPathBytes.Length); - - md5Sum = fileSystem.CalculateFileMD5(downloadPath); + md5Sum = downloadPath.CalculateMD5(); md5Sum.Should().BeEquivalentTo(md5); } @@ -169,35 +333,35 @@ public void DownloadingNonExistingFileThrows() exceptionThrown.Should().NotBeNull(); } - [Test] - public void DownloadingATextFileWorks() - { - Stopwatch watch; - ILogging logger; - StartTest(out watch, out logger); + //[Test] + //public void DownloadingATextFileWorks() + //{ + // Stopwatch watch; + // ILogging logger; + // StartTest(out watch, out logger); - var fileSystem = Environment.FileSystem; + // var fileSystem = Environment.FileSystem; - var gitLfsMd5 = new UriString($"http://localhost:{server.Port}/git-lfs.zip.MD5.txt"); + // var gitLfsMd5 = new UriString($"http://localhost:{server.Port}/git-lfs.zip.MD5.txt"); - var downloadTask = new DownloadTextTask(TaskManager.Token, fileSystem, gitLfsMd5, TestBasePath); + // var downloadTask = new DownloadTextTask(TaskManager.Token, fileSystem, gitLfsMd5, TestBasePath); - var autoResetEvent = new AutoResetEvent(false); - string result = null; + // var autoResetEvent = new AutoResetEvent(false); + // string result = null; - StartTrackTime(watch); - downloadTask - .Finally((success, r) => { - result = r; - autoResetEvent.Set(); - }) - .Start(); + // StartTrackTime(watch); + // downloadTask + // .Finally((success, r) => { + // result = r; + // autoResetEvent.Set(); + // }) + // .Start(); - autoResetEvent.WaitOne(Timeout).Should().BeTrue("Finally raised the signal");; - StopTrackTimeAndLog(watch, logger); + // autoResetEvent.WaitOne(Timeout).Should().BeTrue("Finally raised the signal");; + // StopTrackTimeAndLog(watch, logger); - result.Should().Be("105DF1302560C5F6AA64D1930284C126"); - } + // result.Should().Be("105DF1302560C5F6AA64D1930284C126"); + //} [Test] public void DownloadingFromNonExistingDomainThrows() @@ -208,7 +372,7 @@ public void DownloadingFromNonExistingDomainThrows() var fileSystem = Environment.FileSystem; - var downloadTask = new DownloadTextTask(TaskManager.Token, fileSystem, "http://ggggithub.com/robots.txt"); + var downloadTask = new DownloadTask(TaskManager.Token, fileSystem, "http://ggggithub.com/robots.txt"); var exceptionThrown = false; var autoResetEvent = new AutoResetEvent(false); @@ -227,46 +391,42 @@ public void DownloadingFromNonExistingDomainThrows() exceptionThrown.Should().BeTrue(); } - [Test] - public void DownloadingAFileWithHashValidationWorks() - { - Stopwatch watch; - ILogging logger; - StartTest(out watch, out logger); - - var fileSystem = Environment.FileSystem; - - var gitLfs = new UriString($"http://localhost:{server.Port}/git-lfs.zip"); - var gitLfsMd5 = new UriString($"http://localhost:{server.Port}/git-lfs.zip.MD5.txt"); - - var downloadGitLfsMd5Task = new DownloadTextTask(TaskManager.Token, fileSystem, gitLfsMd5, TestBasePath); - var downloadGitLfsTask = new DownloadTask(TaskManager.Token, fileSystem, gitLfs, TestBasePath); - - var result = true; - Exception exception = null; - - var autoResetEvent = new AutoResetEvent(false); - - StartTrackTime(watch); - downloadGitLfsMd5Task - .Then((b, s) => - { - downloadGitLfsTask.ValidationHash = s; - }) - .Then(downloadGitLfsTask) - .Finally((b, ex) => { - result = b; - exception = ex; - autoResetEvent.Set(); - }) - .Start(); - - autoResetEvent.WaitOne(Timeout).Should().BeTrue("Finally raised the signal");; - StopTrackTimeAndLog(watch, logger); - - result.Should().BeTrue(); - exception.Should().BeNull(); - } + //[Test] + //public void DownloadingAFileWithHashValidationWorks() + //{ + // Stopwatch watch; + // ILogging logger; + // StartTest(out watch, out logger); + + // var fileSystem = Environment.FileSystem; + + // var gitLfs = new UriString($"http://localhost:{server.Port}/git-lfs.zip"); + // var gitLfsMd5 = new UriString($"http://localhost:{server.Port}/git-lfs.zip.MD5.txt"); + + // var downloadGitLfsMd5Task = new DownloadTextTask(TaskManager.Token, fileSystem, gitLfsMd5, TestBasePath); + // var downloadGitLfsTask = new DownloadTask(TaskManager.Token, fileSystem, gitLfs, TestBasePath); + + // var result = true; + // Exception exception = null; + + // var autoResetEvent = new AutoResetEvent(false); + + // StartTrackTime(watch); + // downloadGitLfsMd5Task + // .Then(downloadGitLfsTask) + // .Finally((b, ex) => { + // result = b; + // exception = ex; + // autoResetEvent.Set(); + // }) + // .Start(); + + // autoResetEvent.WaitOne(Timeout).Should().BeTrue("Finally raised the signal");; + // StopTrackTimeAndLog(watch, logger); + + // result.Should().BeTrue(); + // exception.Should().BeNull(); + //} [Test] public void ShutdownTimeWhenTaskManagerDisposed() diff --git a/src/tests/IntegrationTests/UnzipTaskTests.cs b/src/tests/IntegrationTests/UnzipTaskTests.cs index 07a71afc5..afffeb183 100644 --- a/src/tests/IntegrationTests/UnzipTaskTests.cs +++ b/src/tests/IntegrationTests/UnzipTaskTests.cs @@ -14,64 +14,44 @@ namespace IntegrationTests class UnzipTaskTests : BaseTaskManagerTest { [Test] - public void TaskSucceeds() + public async Task UnzipWorks() { InitializeTaskManager(); var cacheContainer = Substitute.For(); Environment = new IntegrationTestEnvironment(cacheContainer, TestBasePath, SolutionDirectory); - var destinationPath = TestBasePath.Combine("git_zip").CreateDirectory(); - var archiveFilePath = AssemblyResources.ToFile(ResourceType.Platform, "git.zip", destinationPath, Environment); + var destinationPath = TestBasePath.Combine("gitlfs_zip").CreateDirectory(); + var archiveFilePath = AssemblyResources.ToFile(ResourceType.Platform, "git-lfs.zip", destinationPath, Environment); - var extractedPath = TestBasePath.Combine("git_zip_extracted").CreateDirectory(); + var extractedPath = TestBasePath.Combine("gitlfs_zip_extracted").CreateDirectory(); - var zipProgress = 0; - Logger.Trace("Pct Complete {0}%", zipProgress); - var unzipTask = new UnzipTask(CancellationToken.None, archiveFilePath, extractedPath, Environment.FileSystem, GitInstallDetails.GitExtractedMD5, - new Progress(zipFileProgress => { - var zipFileProgressInteger = (int) (zipFileProgress * 100); - if (zipProgress != zipFileProgressInteger) - { - zipProgress = zipFileProgressInteger; - Logger.Trace("Pct Complete {0}%", zipProgress); - } - })); + var unzipTask = new UnzipTask(CancellationToken.None, archiveFilePath, extractedPath, + Environment.FileSystem, GitInstallDetails.GitLfsExtractedMD5); - unzipTask.Start().Wait(); + await unzipTask.StartAwait(); extractedPath.DirectoryExists().Should().BeTrue(); } [Test] - public void TaskFailsWhenMD5Incorect() + public void FailsWhenMD5Incorrect() { InitializeTaskManager(); var cacheContainer = Substitute.For(); Environment = new IntegrationTestEnvironment(cacheContainer, TestBasePath, SolutionDirectory); - var destinationPath = TestBasePath.Combine("git_zip").CreateDirectory(); - var archiveFilePath = AssemblyResources.ToFile(ResourceType.Platform, "git.zip", destinationPath, Environment); + var destinationPath = TestBasePath.Combine("gitlfs_zip").CreateDirectory(); + var archiveFilePath = AssemblyResources.ToFile(ResourceType.Platform, "git-lfs.zip", destinationPath, Environment); - var extractedPath = TestBasePath.Combine("git_zip_extracted").CreateDirectory(); + var extractedPath = TestBasePath.Combine("gitlfs_zip_extracted").CreateDirectory(); + var unzipTask = new UnzipTask(CancellationToken.None, archiveFilePath, extractedPath, Environment.FileSystem, "AABBCCDD"); - var failed = false; - Exception exception = null; - - var unzipTask = new UnzipTask(CancellationToken.None, archiveFilePath, extractedPath, Environment.FileSystem, "AABBCCDD") - .Finally((b, ex) => { - failed = true; - exception = ex; - }); - - unzipTask.Start().Wait(); + Assert.Throws(async () => await unzipTask.StartAwait()); extractedPath.DirectoryExists().Should().BeFalse(); - failed.Should().BeTrue(); - exception.Should().NotBeNull(); - exception.Should().BeOfType(); } } } \ No newline at end of file diff --git a/src/tests/TaskSystemIntegrationTests/Tests.cs b/src/tests/TaskSystemIntegrationTests/Tests.cs index ae4b6e311..5a338c44b 100644 --- a/src/tests/TaskSystemIntegrationTests/Tests.cs +++ b/src/tests/TaskSystemIntegrationTests/Tests.cs @@ -136,7 +136,7 @@ public async Task ProcessOnStartOnEndTaskOrder() values.Add("OnStart"); }; - combinedTask.OnEnd += task => { + combinedTask.OnEnd += (task, success, ex) => { values.Add("OnEnd"); }; @@ -599,7 +599,7 @@ public async Task StartAndEndAreAlwaysRaised() var runOrder = new List(); ITask task = new ActionTask(Token, _ => { throw new Exception(); }); task.OnStart += _ => runOrder.Add("start"); - task.OnEnd += _ => runOrder.Add("end"); + task.OnEnd += (_, __, ___) => runOrder.Add("end"); task = task.Finally((_, __) => {}); await task.StartAndSwallowException(); diff --git a/src/tests/TestWebServer/HttpServer.cs b/src/tests/TestWebServer/HttpServer.cs index 0cd38bb5a..18614cdec 100644 --- a/src/tests/TestWebServer/HttpServer.cs +++ b/src/tests/TestWebServer/HttpServer.cs @@ -75,7 +75,8 @@ public void Start() abort = false; Logger.Info($"Waiting for a request..."); var context = listener.GetContext(); - Process(context); + var thread = new Thread(p => Process((HttpListenerContext)p)); + thread.Start(context); } catch (Exception ex) { @@ -98,7 +99,10 @@ public void Abort() private void Process(HttpListenerContext context) { + Logger.Info($"Handling request"); + var filename = context.Request.Url.AbsolutePath; + Logger.Info($"{filename}"); filename = filename.TrimStart('/'); filename = Path.Combine(rootDirectory, filename); From 197ce5c026a43d02ae119b3320de180f84acb936 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Fri, 2 Mar 2018 19:43:36 +0000 Subject: [PATCH 077/873] Get essential changes from fixes/prefer-local-resources (PR #590) --- src/GitHub.Api/Installer/GitInstaller.cs | 84 ++++++++++++++---------- 1 file changed, 49 insertions(+), 35 deletions(-) diff --git a/src/GitHub.Api/Installer/GitInstaller.cs b/src/GitHub.Api/Installer/GitInstaller.cs index c8e9e28c6..f2196c18a 100644 --- a/src/GitHub.Api/Installer/GitInstaller.cs +++ b/src/GitHub.Api/Installer/GitInstaller.cs @@ -26,13 +26,14 @@ class GitInstallDetails private readonly bool onWindows; - public GitInstallDetails(NPath pluginDataPath, bool onWindows) + public GitInstallDetails(NPath baseDataPath, bool onWindows) { this.onWindows = onWindows; - PluginDataPath = pluginDataPath; + ZipPath = baseDataPath.Combine("downloads"); + ZipPath.EnsureDirectoryExists(); - var gitInstallPath = PluginDataPath.Combine(PackageNameWithVersion); + var gitInstallPath = baseDataPath.Combine(PackageNameWithVersion); GitInstallationPath = gitInstallPath; if (onWindows) @@ -60,7 +61,7 @@ public NPath GetGitLfsExecutablePath(NPath gitInstallRoot) : gitInstallRoot.Combine("libexec", "git-core", GitLfsExecutable); } - public NPath PluginDataPath { get; } + public NPath ZipPath { get; } public NPath GitInstallationPath { get; } public string GitExecutable { get; } public NPath GitExecutablePath { get; } @@ -91,9 +92,8 @@ public GitInstaller(IEnvironment environment, CancellationToken cancellationToke public GitInstaller(IEnvironment environment, CancellationToken cancellationToken, GitInstallDetails installDetails, NPath gitArchiveFilePath, NPath gitLfsArchivePath) - : this( - environment, ZipHelper.Instance, cancellationToken, installDetails, gitArchiveFilePath, - gitLfsArchivePath) + : this(environment, ZipHelper.Instance, cancellationToken, installDetails, + gitArchiveFilePath, gitLfsArchivePath) {} public GitInstaller(IEnvironment environment, IZipHelper sharpZipLibHelper, CancellationToken cancellationToken, @@ -120,7 +120,10 @@ public void SetupGitIfNeeded(ActionTask onSuccess, ITask onFailure) var isGitExtractedTask = new FuncTask(cancellationToken, () => { if (!IsGitExtracted()) + { + GrabZipFromResources(); return null; + } Logger.Trace("SetupGitIfNeeded: Skipped"); return installDetails.GitExecutablePath; }); @@ -140,6 +143,43 @@ public void SetupGitIfNeeded(ActionTask onSuccess, ITask onFailure) isGitExtractedTask.Start(); } + private void GrabZipFromResources() + { + if (gitArchiveFilePath == null || !gitArchiveFilePath.FileExists()) + gitArchiveFilePath = AssemblyResources.ToFile(ResourceType.Platform, "git.zip", installDetails.ZipPath, environment); + if (!gitArchiveFilePath.FileExists()) + gitArchiveFilePath = null; + + if (gitLfsArchivePath == null || !gitLfsArchivePath.FileExists()) + gitLfsArchivePath = AssemblyResources.ToFile(ResourceType.Platform, "git-lfs.zip", installDetails.ZipPath, environment); + if (!gitLfsArchivePath.FileExists()) + gitLfsArchivePath = null; + } + + private ITask CreateDownloadTask() + { + gitArchiveFilePath = installDetails.ZipPath.Combine("git.zip"); + gitLfsArchivePath = installDetails.ZipPath.Combine("git-lfs.zip"); + + var downloader = new Downloader(); + downloader.QueueDownload(installDetails.GitZipUrl, installDetails.GitZipMd5Url, installDetails.ZipPath); + downloader.QueueDownload(installDetails.GitLfsZipUrl, installDetails.GitLfsZipMd5Url, installDetails.ZipPath); + return downloader; + } + + private FuncTask CreateUnzipTasks(NPath gitExtractPath, NPath gitLfsExtractPath, NPath tempZipExtractPath) + { + var unzipGitTask = new UnzipTask(cancellationToken, gitArchiveFilePath, gitExtractPath, sharpZipLibHelper, + environment.FileSystem, GitInstallDetails.GitExtractedMD5); + var unzipGitLfsTask = new UnzipTask(cancellationToken, gitLfsArchivePath, gitLfsExtractPath, sharpZipLibHelper, + environment.FileSystem, GitInstallDetails.GitLfsExtractedMD5); + + var moveGitTask = new FuncTask(cancellationToken, () => MoveGitAndLfs(gitExtractPath, gitLfsExtractPath, tempZipExtractPath)); + return unzipGitTask + .Then(unzipGitLfsTask) + .Then(moveGitTask); + } + private FuncTask ExtractPortableGit() { var tempZipExtractPath = NPath.CreateTempDirectory("git_zip_extract_zip_paths"); @@ -157,19 +197,6 @@ private FuncTask ExtractPortableGit() return unzipTasks; } - private FuncTask CreateUnzipTasks(NPath gitExtractPath, NPath gitLfsExtractPath, NPath tempZipExtractPath) - { - var unzipGitTask = new UnzipTask(cancellationToken, gitArchiveFilePath, gitExtractPath, sharpZipLibHelper, - environment.FileSystem, GitInstallDetails.GitExtractedMD5); - var unzipGitLfsTask = new UnzipTask(cancellationToken, gitLfsArchivePath, gitLfsExtractPath, sharpZipLibHelper, - environment.FileSystem, GitInstallDetails.GitLfsExtractedMD5); - - var moveGitTask = new FuncTask(cancellationToken, () => MoveGitAndLfs(gitExtractPath, gitLfsExtractPath, tempZipExtractPath)); - return unzipGitTask - .Then(unzipGitLfsTask) - .Then(moveGitTask); - } - private NPath MoveGitAndLfs(NPath gitExtractPath, NPath gitLfsExtractPath, NPath tempZipExtractPath) { var targetGitLfsExecPath = installDetails.GetGitLfsExecutablePath(gitExtractPath); @@ -193,19 +220,6 @@ private NPath MoveGitAndLfs(NPath gitExtractPath, NPath gitLfsExtractPath, NPath return installDetails.GitExecutablePath; } - private ITask CreateDownloadTask() - { - gitArchiveFilePath = installDetails.PluginDataPath.Combine("git.zip"); - gitLfsArchivePath = installDetails.PluginDataPath.Combine("git-lfs.zip"); - - var downloader = new Downloader(); - - downloader.QueueDownload(installDetails.GitZipUrl, installDetails.GitZipMd5Url, installDetails.PluginDataPath); - downloader.QueueDownload(installDetails.GitLfsZipUrl, installDetails.GitLfsZipMd5Url, installDetails.PluginDataPath); - - return downloader; - } - private bool IsGitExtracted() { if (!installDetails.GitInstallationPath.DirectoryExists()) @@ -214,7 +228,7 @@ private bool IsGitExtracted() return false; } - var gitExecutableMd5 = environment.FileSystem.CalculateFileMD5(installDetails.GitExecutablePath); + var gitExecutableMd5 = installDetails.GitExecutablePath.CalculateMD5(); var expectedGitExecutableMd5 = environment.IsWindows ? GitInstallDetails.WindowsGitExecutableMD5 : GitInstallDetails.MacGitExecutableMD5; if (!expectedGitExecutableMd5.Equals(gitExecutableMd5, StringComparison.InvariantCultureIgnoreCase)) @@ -223,7 +237,7 @@ private bool IsGitExtracted() return false; } - var gitLfsExecutableMd5 = environment.FileSystem.CalculateFileMD5(installDetails.GitLfsExecutablePath); + var gitLfsExecutableMd5 = installDetails.GitLfsExecutablePath.CalculateMD5(); var expectedGitLfsExecutableMd5 = environment.IsWindows ? GitInstallDetails.WindowsGitLfsExecutableMD5 : GitInstallDetails.MacGitLfsExecutableMD5; if (!expectedGitLfsExecutableMd5.Equals(gitLfsExecutableMd5, StringComparison.InvariantCultureIgnoreCase)) From 4ee058ad28918fed38ed52188864274c5f343c79 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Mon, 5 Mar 2018 11:57:02 +0100 Subject: [PATCH 078/873] Kill a bunch of unused code --- src/GitHub.Api/Tasks/TaskExtensions.cs | 118 ------------------ .../Editor/GitHub.Unity/UI/InitProjectView.cs | 2 +- 2 files changed, 1 insertion(+), 119 deletions(-) diff --git a/src/GitHub.Api/Tasks/TaskExtensions.cs b/src/GitHub.Api/Tasks/TaskExtensions.cs index b8a734e09..265033576 100644 --- a/src/GitHub.Api/Tasks/TaskExtensions.cs +++ b/src/GitHub.Api/Tasks/TaskExtensions.cs @@ -1,61 +1,11 @@ using GitHub.Logging; using System; -using System.Threading; using System.Threading.Tasks; namespace GitHub.Unity { static class TaskExtensions { - private static Task completedTask; - - public static Task CompletedTask - { - get - { - if (completedTask == null) - { - completedTask = TaskEx.FromResult(true); - } - return completedTask; - } - } - - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "task")] - public static void Forget(this Task task) - { - } - - public static async Task SafeAwait(this Task source, Action handler = null) - { - try - { - await source; - } - catch (Exception ex) - { - LogHelper.GetLogger().Error(ex); - if (handler == null) - throw; - handler(ex); - } - } - - public static async Task SafeAwait(this Task source, Func handler = null) - { - try - { - return await source; - } - catch (Exception ex) - { - LogHelper.GetLogger().Error(ex); - if (handler == null) - throw; - return handler(ex); - } - } - public static async Task StartAwait(this ITask source, Action handler = null) { try @@ -86,41 +36,6 @@ public static async Task StartAwait(this ITask source, Func Debounce(this Action func, int milliseconds = 300) - { - var last = 0; - return arg => - { - var current = Interlocked.Increment(ref last); - TaskEx.Delay(milliseconds).ContinueWith(task => - { - if (current == last) func(arg); - task.Dispose(); - }); - }; - } - - public static Action Debounce(this Action func, int milliseconds = 300) - { - var last = 0; - return () => - { - var current = Interlocked.Increment(ref last); - TaskEx.Delay(milliseconds).ContinueWith(task => - { - if (current == last) func(); - task.Dispose(); - }); - }; - } - public static ITask Then(this ITask task, Action continuation, TaskAffinity affinity = TaskAffinity.Concurrent, TaskRunOptions runOptions = TaskRunOptions.OnSuccess) { Guard.ArgumentNotNull(continuation, "continuation"); @@ -133,13 +48,6 @@ public static ITask Then(this ITask task, Action continuation, TaskAffinit return task.Then(new ActionTask(task.Token, continuation) { Affinity = affinity, Name = "Then" }, runOptions); } - public static ITask Then(this ITask task, ActionTask nextTask, T valueForNextTask, TaskAffinity affinity = TaskAffinity.Concurrent, TaskRunOptions runOptions = TaskRunOptions.OnSuccess) - { - Guard.ArgumentNotNull(nextTask, nameof(nextTask)); - nextTask.PreviousResult = valueForNextTask; - return task.Then(nextTask, runOptions); - } - public static ITask Then(this ITask task, Action continuation, TaskAffinity affinity = TaskAffinity.Concurrent, TaskRunOptions runOptions = TaskRunOptions.OnSuccess) { Guard.ArgumentNotNull(continuation, "continuation"); @@ -164,11 +72,6 @@ public static ITask Then(this ITask task, Task continuation, TaskAffini return task.Then(cont, runOptions); } - public static ITask Then(this ITask task, Func> continuation, TaskAffinity affinity = TaskAffinity.Concurrent, TaskRunOptions runOptions = TaskRunOptions.OnSuccess) - { - return task.Then(continuation(), affinity, runOptions); - } - public static ITask ThenInUI(this ITask task, Action continuation, TaskRunOptions runOptions = TaskRunOptions.OnSuccess) { return task.Then(continuation, TaskAffinity.UI, runOptions); @@ -184,11 +87,6 @@ public static ITask ThenInUI(this ITask task, Action continuation return task.Then(continuation, TaskAffinity.UI, runOptions); } - public static ITask ThenInUI(this ITask task, Func continuation, TaskRunOptions runOptions = TaskRunOptions.OnSuccess) - { - return task.Then(continuation, TaskAffinity.UI, runOptions); - } - public static ITask ThenInUI(this ITask task, Func continuation, TaskRunOptions runOptions = TaskRunOptions.OnSuccess) { return task.Then(continuation, TaskAffinity.UI, runOptions); @@ -200,27 +98,11 @@ public static ITask FinallyInUI(this T task, Action continua return task.Finally(continuation, TaskAffinity.UI); } - public static ITask FinallyInUI(this T task, Action continuation) - where T : ITask - { - return task.Finally((s, e) => continuation(), TaskAffinity.UI); - } - public static ITask FinallyInUI(this ITask task, Action continuation) { return task.Finally(continuation, TaskAffinity.UI); } - public static ITask FinallyInUI(this ITask task, Func continuation) - { - return task.Finally((s, e, r) => continuation(), TaskAffinity.UI); - } - - public static ITask FinallyInUI(this ITask task, Func continuation) - { - return task.Finally(continuation, TaskAffinity.UI); - } - public static Task StartAsAsync(this ITask task) { var tcs = new TaskCompletionSource(); diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/InitProjectView.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/InitProjectView.cs index dc889436f..37daba7cc 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/InitProjectView.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/InitProjectView.cs @@ -68,7 +68,7 @@ public override void OnGUI() { isBusy = true; Manager.InitializeRepository() - .FinallyInUI(() => isBusy = false) + .FinallyInUI((s, e) => isBusy = false) .Start(); } } From b465fc6db973314b82ca4a32ce12e2e92bbf82d0 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Mon, 5 Mar 2018 12:05:32 +0100 Subject: [PATCH 079/873] Kill some more unused code --- src/GitHub.Api/Events/RepositoryWatcher.cs | 6 --- src/GitHub.Api/Tasks/TaskBase.cs | 43 +--------------------- 2 files changed, 2 insertions(+), 47 deletions(-) diff --git a/src/GitHub.Api/Events/RepositoryWatcher.cs b/src/GitHub.Api/Events/RepositoryWatcher.cs index 7aeb49041..fc00ff014 100644 --- a/src/GitHub.Api/Events/RepositoryWatcher.cs +++ b/src/GitHub.Api/Events/RepositoryWatcher.cs @@ -169,12 +169,6 @@ private int ProcessEvents(Event[] fileEvents) var eventDirectory = new NPath(fileEvent.Directory); var fileA = eventDirectory.Combine(fileEvent.FileA); - NPath fileB = null; - if (fileEvent.FileB != null) - { - fileB = eventDirectory.Combine(fileEvent.FileB); - } - // handling events in .git/* if (fileA.IsChildOf(paths.DotGitPath)) { diff --git a/src/GitHub.Api/Tasks/TaskBase.cs b/src/GitHub.Api/Tasks/TaskBase.cs index a4a96c45d..a86bb48f2 100644 --- a/src/GitHub.Api/Tasks/TaskBase.cs +++ b/src/GitHub.Api/Tasks/TaskBase.cs @@ -33,8 +33,6 @@ public interface ITask : IAsyncResult ITask Start(TaskScheduler scheduler); ITask Progress(Action progressHandler); - void Wait(); - bool Wait(int milliseconds); bool Successful { get; } string Errors { get; } Task Task { get; } @@ -373,16 +371,6 @@ protected TaskBase GetTopMostTask(TaskBase ret, bool onlyCreatedState) return depends.GetTopMostTask(ret, onlyCreatedState); } - public virtual void Wait() - { - Task.Wait(Token); - } - - public virtual bool Wait(int milliseconds) - { - return Task.Wait(milliseconds, Token); - } - protected virtual void Run(bool success) { } @@ -443,8 +431,8 @@ protected Exception GetThrownException() if (DependsOn.Task.Status == TaskStatus.Faulted) { - var exception = DependsOn.Task.Exception; - return exception?.InnerException ?? exception; + var ex = DependsOn.Task.Exception; + return ex?.InnerException ?? ex; } return DependsOn.GetThrownException(); } @@ -707,33 +695,6 @@ protected void RaiseOnData(TData data) } } - static class TaskBaseExtensions - { - public static T Schedule(this T task, ITaskManager taskManager) - where T : ITask - { - return taskManager.Schedule(task); - } - - public static T ScheduleUI(this T task, ITaskManager taskManager) - where T : ITask - { - return taskManager.ScheduleUI(task); - } - - public static T ScheduleExclusive(this T task, ITaskManager taskManager) - where T : ITask - { - return taskManager.ScheduleExclusive(task); - } - - public static T ScheduleConcurrent(this T task, ITaskManager taskManager) - where T : ITask - { - return taskManager.ScheduleConcurrent(task); - } - } - public enum TaskAffinity { Concurrent, From ff27758c450c01ae3e1df47a604ee1d2d8bbe736 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Mon, 5 Mar 2018 12:18:17 +0100 Subject: [PATCH 080/873] Dedupe code --- .../Editor/GitHub.Unity/ApplicationCache.cs | 238 +++--------------- 1 file changed, 36 insertions(+), 202 deletions(-) diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationCache.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationCache.cs index a2ebed40b..34cece781 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationCache.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationCache.cs @@ -131,6 +131,9 @@ public IEnvironment Environment abstract class ManagedCacheBase : ScriptObjectSingleton where T : ScriptableObject, IManagedCache { + [SerializeField] private string lastUpdatedAtString = DateTimeOffset.MinValue.ToString(Constants.Iso8601Format); + [SerializeField] private string lastVerifiedAtString = DateTimeOffset.MinValue.ToString(Constants.Iso8601Format); + [SerializeField] private string initializedAtString = DateTimeOffset.MinValue.ToString(Constants.Iso8601Format); [NonSerialized] private DateTimeOffset? lastUpdatedAtValue; [NonSerialized] private DateTimeOffset? lastVerifiedAtValue; [NonSerialized] private DateTimeOffset? initializedAtValue; @@ -207,15 +210,26 @@ protected void SaveData(DateTimeOffset now, bool isUpdated) } public abstract TimeSpan DataTimeout { get; } - public abstract string LastUpdatedAtString { get; protected set; } - public abstract string LastVerifiedAtString { get; protected set; } - public abstract string InitializedAtString { get; protected set; } + public string LastUpdatedAtString + { + get { return lastUpdatedAtString; } + protected set { lastUpdatedAtString = value; } + } + + public string LastVerifiedAtString + { + get { return lastVerifiedAtString; } + protected set { lastVerifiedAtString = value; } + } - public bool IsInitialized + public string InitializedAtString { - get { return ApplicationCache.Instance.FirstRunAt <= InitializedAt; } + get { return initializedAtString; } + protected set { initializedAtString = value; } } + public bool IsInitialized { get { return ApplicationCache.Instance.FirstRunAt <= InitializedAt; } } + public DateTimeOffset LastUpdatedAt { get @@ -323,14 +337,12 @@ public class ArrayContainer } [Serializable] - public class StringArrayContainer: ArrayContainer - { - } + public class StringArrayContainer : ArrayContainer + {} [Serializable] public class ConfigBranchArrayContainer : ArrayContainer - { - } + {} [Serializable] class RemoteConfigBranchDictionary : Dictionary>, ISerializationCallbackReceiver, IRemoteConfigBranchDictionary @@ -348,8 +360,8 @@ public RemoteConfigBranchDictionary(Dictionary valuePair.Key, valuePair => valuePair.Value)); } - } - + } + // save the dictionary to lists public void OnBeforeSerialize() { @@ -435,9 +447,6 @@ public ConfigRemoteDictionary(IDictionary dictionary) [Location("cache/repoinfo.yaml", LocationAttribute.Location.LibraryFolder)] sealed class RepositoryInfoCache : ManagedCacheBase, IRepositoryInfoCache { - [SerializeField] private string lastUpdatedAtString = DateTimeOffset.MinValue.ToString(Constants.Iso8601Format); - [SerializeField] private string lastVerifiedAtString = DateTimeOffset.MinValue.ToString(Constants.Iso8601Format); - [SerializeField] private string firstInitializedAtString = DateTimeOffset.MinValue.ToString(Constants.Iso8601Format); [SerializeField] private GitRemote gitRemote; [SerializeField] private GitBranch gitBranch; @@ -492,24 +501,6 @@ public GitBranch? CurentGitBranch } } - public override string LastUpdatedAtString - { - get { return lastUpdatedAtString; } - protected set { lastUpdatedAtString = value; } - } - - public override string LastVerifiedAtString - { - get { return lastVerifiedAtString; } - protected set { lastVerifiedAtString = value; } - } - - public override string InitializedAtString - { - get { return firstInitializedAtString; } - protected set { firstInitializedAtString = value; } - } - public override TimeSpan DataTimeout { get { return TimeSpan.MaxValue; } @@ -519,10 +510,6 @@ public override TimeSpan DataTimeout [Location("cache/branches.yaml", LocationAttribute.Location.LibraryFolder)] sealed class BranchCache : ManagedCacheBase, IBranchCache { - [SerializeField] private string lastUpdatedAtString = DateTimeOffset.MinValue.ToString(Constants.Iso8601Format); - [SerializeField] private string lastVerifiedAtString = DateTimeOffset.MinValue.ToString(Constants.Iso8601Format); - [SerializeField] private string initializedAtString = DateTimeOffset.MinValue.ToString(Constants.Iso8601Format); - [SerializeField] private ConfigBranch gitConfigBranch; [SerializeField] private ConfigRemote gitConfigRemote; @@ -609,11 +596,6 @@ public GitBranch[] LocalBranches } } - public ILocalConfigBranchDictionary LocalConfigBranches - { - get { return localConfigBranches; } - } - public GitBranch[] RemoteBranches { get { return remoteBranches; } @@ -638,11 +620,6 @@ public GitBranch[] RemoteBranches } } - public IRemoteConfigBranchDictionary RemoteConfigBranches - { - get { return remoteConfigBranches; } - } - public GitRemote[] Remotes { get { return remotes; } @@ -667,11 +644,6 @@ public GitRemote[] Remotes } } - public IConfigRemoteDictionary ConfigRemotes - { - get { return configRemotes; } - } - public void RemoveLocalBranch(string branch) { if (LocalConfigBranches.ContainsKey(branch)) @@ -710,7 +682,7 @@ public void AddRemoteBranch(string remote, string branch) if (!branchList.ContainsKey(branch)) { var now = DateTimeOffset.Now; - branchList.Add(branch, new ConfigBranch(branch,ConfigRemotes[remote])); + branchList.Add(branch, new ConfigBranch(branch, ConfigRemotes[remote])); Logger.Trace("AddRemoteBranch {0} remote:{1} branch:{2} ", now, remote, branch); SaveData(now, true); } @@ -765,36 +737,15 @@ public void SetLocals(Dictionary branchDictionary) SaveData(now, true); } - public override string LastUpdatedAtString - { - get { return lastUpdatedAtString; } - protected set { lastUpdatedAtString = value; } - } - - public override string LastVerifiedAtString - { - get { return lastVerifiedAtString; } - protected set { lastVerifiedAtString = value; } - } - - public override string InitializedAtString - { - get { return initializedAtString; } - protected set { initializedAtString = value; } - } - - public override TimeSpan DataTimeout - { - get { return TimeSpan.MaxValue; } - } + public ILocalConfigBranchDictionary LocalConfigBranches { get { return localConfigBranches; } } + public IRemoteConfigBranchDictionary RemoteConfigBranches { get { return remoteConfigBranches; } } + public IConfigRemoteDictionary ConfigRemotes { get { return configRemotes; } } + public override TimeSpan DataTimeout { get { return TimeSpan.MaxValue; } } } [Location("cache/gitlog.yaml", LocationAttribute.Location.LibraryFolder)] sealed class GitLogCache : ManagedCacheBase, IGitLogCache { - [SerializeField] private string lastUpdatedAtString = DateTimeOffset.MinValue.ToString(Constants.Iso8601Format); - [SerializeField] private string lastVerifiedAtString = DateTimeOffset.MinValue.ToString(Constants.Iso8601Format); - [SerializeField] private string initializedAtString = DateTimeOffset.MinValue.ToString(Constants.Iso8601Format); [SerializeField] private List log = new List(); public GitLogCache() : base(true) @@ -824,36 +775,12 @@ public List Log } } - public override string LastUpdatedAtString - { - get { return lastUpdatedAtString; } - protected set { lastUpdatedAtString = value; } - } - - public override string LastVerifiedAtString - { - get { return lastVerifiedAtString; } - protected set { lastVerifiedAtString = value; } - } - - public override string InitializedAtString - { - get { return initializedAtString; } - protected set { initializedAtString = value; } - } - - public override TimeSpan DataTimeout - { - get { return TimeSpan.FromMinutes(1); } - } + public override TimeSpan DataTimeout { get { return TimeSpan.FromMinutes(1); } } } [Location("cache/gittrackingstatus.yaml", LocationAttribute.Location.LibraryFolder)] sealed class GitTrackingStatusCache : ManagedCacheBase, IGitTrackingStatusCache { - [SerializeField] private string lastUpdatedAtString = DateTimeOffset.MinValue.ToString(Constants.Iso8601Format); - [SerializeField] private string lastVerifiedAtString = DateTimeOffset.MinValue.ToString(Constants.Iso8601Format); - [SerializeField] private string initializedAtString = DateTimeOffset.MinValue.ToString(Constants.Iso8601Format); [SerializeField] private int ahead; [SerializeField] private int behind; @@ -908,36 +835,12 @@ public int Behind } } - public override string LastUpdatedAtString - { - get { return lastUpdatedAtString; } - protected set { lastUpdatedAtString = value; } - } - - public override string LastVerifiedAtString - { - get { return lastVerifiedAtString; } - protected set { lastVerifiedAtString = value; } - } - - public override string InitializedAtString - { - get { return initializedAtString; } - protected set { initializedAtString = value; } - } - - public override TimeSpan DataTimeout - { - get { return TimeSpan.FromMinutes(1); } - } + public override TimeSpan DataTimeout { get { return TimeSpan.FromMinutes(1); } } } - [Location("cache/gitstatusentries.yaml", LocationAttribute.Location.LibraryFolder)] + [Location("cache/gitstatusentries.yaml", LocationAttribute.Location.LibraryFolder)] sealed class GitStatusEntriesCache : ManagedCacheBase, IGitStatusEntriesCache { - [SerializeField] private string lastUpdatedAtString = DateTimeOffset.MinValue.ToString(Constants.Iso8601Format); - [SerializeField] private string lastVerifiedAtString = DateTimeOffset.MinValue.ToString(Constants.Iso8601Format); - [SerializeField] private string initializedAtString = DateTimeOffset.MinValue.ToString(Constants.Iso8601Format); [SerializeField] private List entries = new List(); public GitStatusEntriesCache() : base(true) @@ -967,36 +870,12 @@ public List Entries } } - public override string LastUpdatedAtString - { - get { return lastUpdatedAtString; } - protected set { lastUpdatedAtString = value; } - } - - public override string LastVerifiedAtString - { - get { return lastVerifiedAtString; } - protected set { lastVerifiedAtString = value; } - } - - public override string InitializedAtString - { - get { return initializedAtString; } - protected set { initializedAtString = value; } - } - - public override TimeSpan DataTimeout - { - get { return TimeSpan.FromMinutes(1); } - } + public override TimeSpan DataTimeout { get { return TimeSpan.FromMinutes(1); } } } [Location("cache/gitlocks.yaml", LocationAttribute.Location.LibraryFolder)] sealed class GitLocksCache : ManagedCacheBase, IGitLocksCache { - [SerializeField] private string lastUpdatedAtString = DateTimeOffset.MinValue.ToString(Constants.Iso8601Format); - [SerializeField] private string lastVerifiedAtString = DateTimeOffset.MinValue.ToString(Constants.Iso8601Format); - [SerializeField] private string initializedAtString = DateTimeOffset.MinValue.ToString(Constants.Iso8601Format); [SerializeField] private List gitLocks = new List(); public GitLocksCache() : base(true) @@ -1026,41 +905,17 @@ public List GitLocks } } - public override string LastUpdatedAtString - { - get { return lastUpdatedAtString; } - protected set { lastUpdatedAtString = value; } - } - - public override string LastVerifiedAtString - { - get { return lastVerifiedAtString; } - protected set { lastVerifiedAtString = value; } - } - - public override string InitializedAtString - { - get { return initializedAtString; } - protected set { initializedAtString = value; } - } - - public override TimeSpan DataTimeout - { - get { return TimeSpan.FromMinutes(1); } - } + public override TimeSpan DataTimeout { get { return TimeSpan.FromMinutes(1); } } } [Location("cache/gituser.yaml", LocationAttribute.Location.LibraryFolder)] sealed class GitUserCache : ManagedCacheBase, IGitUserCache { - [SerializeField] private string lastUpdatedAtString = DateTimeOffset.MinValue.ToString(Constants.Iso8601Format); - [SerializeField] private string lastVerifiedAtString = DateTimeOffset.MinValue.ToString(Constants.Iso8601Format); - [SerializeField] private string initializedAtString = DateTimeOffset.MinValue.ToString(Constants.Iso8601Format); [SerializeField] private string gitName; [SerializeField] private string gitEmail; public GitUserCache() : base(true) - { } + {} public string Name { @@ -1110,27 +965,6 @@ public string Email } } - public override string LastUpdatedAtString - { - get { return lastUpdatedAtString; } - protected set { lastUpdatedAtString = value; } - } - - public override string LastVerifiedAtString - { - get { return lastVerifiedAtString; } - protected set { lastVerifiedAtString = value; } - } - - public override string InitializedAtString - { - get { return initializedAtString; } - protected set { initializedAtString = value; } - } - - public override TimeSpan DataTimeout - { - get { return TimeSpan.FromMinutes(10); } - } + public override TimeSpan DataTimeout { get { return TimeSpan.FromMinutes(10); } } } } From fbff0719a86c7bfff7d1b0419fdef43259f2ef15 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Mon, 5 Mar 2018 12:26:19 +0100 Subject: [PATCH 081/873] Fix typo --- src/GitHub.Api/Cache/CacheInterfaces.cs | 4 ++-- src/GitHub.Api/Git/Repository.cs | 8 ++++---- .../Assets/Editor/GitHub.Unity/ApplicationCache.cs | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/GitHub.Api/Cache/CacheInterfaces.cs b/src/GitHub.Api/Cache/CacheInterfaces.cs index fd205f46d..414a71384 100644 --- a/src/GitHub.Api/Cache/CacheInterfaces.cs +++ b/src/GitHub.Api/Cache/CacheInterfaces.cs @@ -84,7 +84,7 @@ public interface IConfigRemoteDictionary : IDictionary public interface IBranchCache : IManagedCache { ConfigRemote? CurrentConfigRemote { get; set; } - ConfigBranch? CurentConfigBranch { get; set; } + ConfigBranch? CurrentConfigBranch { get; set; } GitBranch[] LocalBranches { get; set; } GitBranch[] RemoteBranches { get; set; } @@ -105,7 +105,7 @@ public interface IBranchCache : IManagedCache public interface IRepositoryInfoCache : IManagedCache { GitRemote? CurrentGitRemote { get; set; } - GitBranch? CurentGitBranch { get; set; } + GitBranch? CurrentGitBranch { get; set; } } public interface IGitLogCache : IManagedCache diff --git a/src/GitHub.Api/Git/Repository.cs b/src/GitHub.Api/Git/Repository.cs index 16e509c05..231c727cb 100644 --- a/src/GitHub.Api/Git/Repository.cs +++ b/src/GitHub.Api/Git/Repository.cs @@ -523,8 +523,8 @@ public GitBranch[] RemoteBranches private ConfigBranch? CurrentConfigBranch { - get { return this.cacheContainer.BranchCache.CurentConfigBranch; } - set { cacheContainer.BranchCache.CurentConfigBranch = value; } + get { return this.cacheContainer.BranchCache.CurrentConfigBranch; } + set { cacheContainer.BranchCache.CurrentConfigBranch = value; } } private ConfigRemote? CurrentConfigRemote @@ -553,8 +553,8 @@ public List CurrentChanges public GitBranch? CurrentBranch { - get { return cacheContainer.RepositoryInfoCache.CurentGitBranch; } - private set { cacheContainer.RepositoryInfoCache.CurentGitBranch = value; } + get { return cacheContainer.RepositoryInfoCache.CurrentGitBranch; } + private set { cacheContainer.RepositoryInfoCache.CurrentGitBranch = value; } } public string CurrentBranchName => CurrentConfigBranch?.Name; diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationCache.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationCache.cs index 34cece781..bb18ac9df 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationCache.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationCache.cs @@ -477,7 +477,7 @@ public GitRemote? CurrentGitRemote } } - public GitBranch? CurentGitBranch + public GitBranch? CurrentGitBranch { get { @@ -548,7 +548,7 @@ public ConfigRemote? CurrentConfigRemote } } - public ConfigBranch? CurentConfigBranch + public ConfigBranch? CurrentConfigBranch { get { From 24be3ee987c86aef9ff854deb57b833cc1cdbe5e Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Mon, 5 Mar 2018 12:33:41 +0100 Subject: [PATCH 082/873] DataTimeout should never be infinite, otherwise invalid data will never be fixed --- .../Assets/Editor/GitHub.Unity/ApplicationCache.cs | 7 ++----- .../Assets/Editor/GitHub.Unity/CacheContainer.cs | 2 ++ 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationCache.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationCache.cs index bb18ac9df..b65802528 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationCache.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationCache.cs @@ -501,10 +501,7 @@ public GitBranch? CurrentGitBranch } } - public override TimeSpan DataTimeout - { - get { return TimeSpan.MaxValue; } - } + public override TimeSpan DataTimeout { get { return TimeSpan.FromDays(1); } } } [Location("cache/branches.yaml", LocationAttribute.Location.LibraryFolder)] @@ -740,7 +737,7 @@ public void SetLocals(Dictionary branchDictionary) public ILocalConfigBranchDictionary LocalConfigBranches { get { return localConfigBranches; } } public IRemoteConfigBranchDictionary RemoteConfigBranches { get { return remoteConfigBranches; } } public IConfigRemoteDictionary ConfigRemotes { get { return configRemotes; } } - public override TimeSpan DataTimeout { get { return TimeSpan.MaxValue; } } + public override TimeSpan DataTimeout { get { return TimeSpan.FromDays(1); } } } [Location("cache/gitlog.yaml", LocationAttribute.Location.LibraryFolder)] diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/CacheContainer.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/CacheContainer.cs index e97090963..584a1c012 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/CacheContainer.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/CacheContainer.cs @@ -59,6 +59,7 @@ public void Validate(CacheType cacheType) public void ValidateAll() { + RepositoryInfoCache.ValidateData(); BranchCache.ValidateData(); GitLogCache.ValidateData(); GitTrackingStatusCache.ValidateData(); @@ -73,6 +74,7 @@ public void Invalidate(CacheType cacheType) public void InvalidateAll() { + RepositoryInfoCache.InvalidateData(); BranchCache.InvalidateData(); GitLogCache.InvalidateData(); GitTrackingStatusCache.InvalidateData(); From f2ee4ef04b4282109b2f0eca32e4cbf422d6a096 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Mon, 5 Mar 2018 13:45:38 +0100 Subject: [PATCH 083/873] Fix initialization sequence and cache invalidation on startup --- .../Application/ApplicationManagerBase.cs | 44 ++++++++++--------- src/GitHub.Api/Git/Repository.cs | 1 + src/GitHub.Api/Git/RepositoryManager.cs | 5 ++- src/GitHub.Api/Installer/GitInstaller.cs | 17 ++----- .../Editor/GitHub.Unity/ApplicationCache.cs | 9 ++-- 5 files changed, 33 insertions(+), 43 deletions(-) diff --git a/src/GitHub.Api/Application/ApplicationManagerBase.cs b/src/GitHub.Api/Application/ApplicationManagerBase.cs index 535614595..542e54c16 100644 --- a/src/GitHub.Api/Application/ApplicationManagerBase.cs +++ b/src/GitHub.Api/Application/ApplicationManagerBase.cs @@ -47,7 +47,7 @@ public void Run(bool firstRun) { Logger.Trace("Run - CurrentDirectory {0}", NPath.CurrentDirectory); - var gitExecutablePath = SystemSettings.Get(Constants.GitInstallPathKey)?.ToNPath(); + var gitExecutablePath = SystemSettings.Get(Constants.GitInstallPathKey)?.ToNPath(); if (gitExecutablePath != null && gitExecutablePath.FileExists()) // we have a git path { Logger.Trace("Using git install path from settings: {0}", gitExecutablePath); @@ -57,7 +57,10 @@ public void Run(bool firstRun) { Logger.Trace("No git path found in settings"); - var initEnvironmentTask = new ActionTask(CancellationToken, (b, path) => InitializeEnvironment(path)) { Affinity = TaskAffinity.UI }; + var initEnvironmentTask = new ActionTask(CancellationToken, (b, path) => + { + InitializeEnvironment(path); + }) { Affinity = TaskAffinity.UI }; var findExecTask = new FindExecTask("git", CancellationToken) .FinallyInUI((b, ex, path) => { if (b && path != null) @@ -72,8 +75,7 @@ public void Run(bool firstRun) } }); - var installDetails = new GitInstallDetails(Environment.UserCachePath, true); - var gitInstaller = new GitInstaller(Environment, CancellationToken, installDetails); + var gitInstaller = new GitInstaller(Environment, CancellationToken); // if successful, continue with environment initialization, otherwise try to find an existing git installation gitInstaller.SetupGitIfNeeded(initEnvironmentTask, findExecTask); @@ -171,34 +173,34 @@ protected void SetupMetrics(string unityVersion, bool firstRun) /// private void InitializeEnvironment(NPath gitExecutablePath) { - var afterGitSetup = new ActionTask(CancellationToken, RestartRepository) - .ThenInUI(InitializeUI); - Environment.GitExecutablePath = gitExecutablePath; Environment.User.Initialize(GitClient); + var afterGitSetup = new ActionTask(CancellationToken, RestartRepository) + .ThenInUI(InitializeUI); + + ITask task = afterGitSetup; if (Environment.IsWindows) { - var task = GitClient - .GetConfig("credential.helper", GitConfigSource.Global) - .Then((b, credentialHelper) => { - if (string.IsNullOrEmpty(credentialHelper)) + var credHelperTask = GitClient.GetConfig("credential.helper", GitConfigSource.Global); + credHelperTask.OnEnd += (thisTask, credentialHelper, success, exception) => + { + if (!success || string.IsNullOrEmpty(credentialHelper)) { Logger.Warning("No Windows CredentialHelper found: Setting to wincred"); - throw new ArgumentNullException(nameof(credentialHelper)); + thisTask + .Then(GitClient.SetConfig("credential.helper", "wincred", GitConfigSource.Global)) + .Then(afterGitSetup); } - }); - // if there's no credential helper, set it before restarting the repository - task.Then(GitClient.SetConfig("credential.helper", "wincred", GitConfigSource.Global), TaskRunOptions.OnFailure) - .Then(afterGitSetup, taskIsTopOfChain: true); - - // if there's a credential helper, we're good, restart the repository - task.Then(afterGitSetup, TaskRunOptions.OnSuccess, taskIsTopOfChain: true); + else + thisTask.Then(afterGitSetup); + }; + task = credHelperTask; } - - afterGitSetup.Start(); + task.Start(); } + private bool disposed = false; protected virtual void Dispose(bool disposing) { diff --git a/src/GitHub.Api/Git/Repository.cs b/src/GitHub.Api/Git/Repository.cs index 231c727cb..8157753d3 100644 --- a/src/GitHub.Api/Git/Repository.cs +++ b/src/GitHub.Api/Git/Repository.cs @@ -298,6 +298,7 @@ private void CacheContainer_OnCacheInvalidated(CacheType cacheType) break; case CacheType.RepositoryInfoCache: + repositoryManager?.UpdateRepositoryInfo(); break; case CacheType.GitStatusEntriesCache: diff --git a/src/GitHub.Api/Git/RepositoryManager.cs b/src/GitHub.Api/Git/RepositoryManager.cs index ca7113297..cdbb4bff7 100644 --- a/src/GitHub.Api/Git/RepositoryManager.cs +++ b/src/GitHub.Api/Git/RepositoryManager.cs @@ -46,6 +46,7 @@ public interface IRepositoryManager : IDisposable IGitConfig Config { get; } IGitClient GitClient { get; } bool IsBusy { get; } + void UpdateRepositoryInfo(); } interface IRepositoryPathConfiguration @@ -443,7 +444,7 @@ private void SetupWatcher() private void UpdateHead() { Logger.Trace("UpdateHead"); - UpdateCurrentBranchAndRemote(); + UpdateRepositoryInfo(); UpdateGitLog(); } @@ -452,7 +453,7 @@ private string GetCurrentHead() return repositoryPaths.DotGitHead.ReadAllLines().FirstOrDefault(); } - private void UpdateCurrentBranchAndRemote() + public void UpdateRepositoryInfo() { ConfigBranch? branch; ConfigRemote? remote; diff --git a/src/GitHub.Api/Installer/GitInstaller.cs b/src/GitHub.Api/Installer/GitInstaller.cs index f2196c18a..574530f78 100644 --- a/src/GitHub.Api/Installer/GitInstaller.cs +++ b/src/GitHub.Api/Installer/GitInstaller.cs @@ -86,23 +86,12 @@ class GitInstaller private NPath gitLfsArchivePath; public GitInstaller(IEnvironment environment, CancellationToken cancellationToken, - GitInstallDetails installDetails) - : this(environment, ZipHelper.Instance, cancellationToken, installDetails, null, null) - {} - - public GitInstaller(IEnvironment environment, CancellationToken cancellationToken, - GitInstallDetails installDetails, NPath gitArchiveFilePath, NPath gitLfsArchivePath) - : this(environment, ZipHelper.Instance, cancellationToken, installDetails, - gitArchiveFilePath, gitLfsArchivePath) - {} - - public GitInstaller(IEnvironment environment, IZipHelper sharpZipLibHelper, CancellationToken cancellationToken, - GitInstallDetails installDetails, NPath gitArchiveFilePath, NPath gitLfsArchivePath) + GitInstallDetails installDetails = null, NPath gitArchiveFilePath = null, NPath gitLfsArchivePath = null) { this.environment = environment; - this.sharpZipLibHelper = sharpZipLibHelper; + this.sharpZipLibHelper = ZipHelper.Instance; this.cancellationToken = cancellationToken; - this.installDetails = installDetails; + this.installDetails = installDetails ?? new GitInstallDetails(environment.UserCachePath, environment.IsWindows); this.gitArchiveFilePath = gitArchiveFilePath; this.gitLfsArchivePath = gitLfsArchivePath; } diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationCache.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationCache.cs index b65802528..cd5be9dea 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationCache.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/ApplicationCache.cs @@ -151,13 +151,10 @@ protected ManagedCacheBase(bool invalidOnFirstRun) public void ValidateData() { var initialized = ValidateInitialized(); - if (initialized) + if (!initialized || DateTimeOffset.Now - LastUpdatedAt > DataTimeout) { - if (DateTimeOffset.Now - LastUpdatedAt > DataTimeout) - { - Logger.Trace("Timeout Invalidation"); - InvalidateData(); - } + Logger.Trace("Timeout Invalidation"); + InvalidateData(); } } From 883ed16caeb7fa9eea31847f5060abc143c9d870 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Mon, 5 Mar 2018 13:47:59 +0100 Subject: [PATCH 084/873] GitInstallDetails is better off under GitInstaller --- src/GitHub.Api/Installer/GitInstaller.cs | 138 +++++++++--------- .../BasePlatformIntegrationTest.cs | 2 +- .../Installer/GitInstallerTests.cs | 10 +- src/tests/IntegrationTests/UnzipTaskTests.cs | 2 +- 4 files changed, 76 insertions(+), 76 deletions(-) diff --git a/src/GitHub.Api/Installer/GitInstaller.cs b/src/GitHub.Api/Installer/GitInstaller.cs index 574530f78..edd9f61cd 100644 --- a/src/GitHub.Api/Installer/GitInstaller.cs +++ b/src/GitHub.Api/Installer/GitInstaller.cs @@ -5,75 +5,6 @@ namespace GitHub.Unity { - class GitInstallDetails - { - public const string DefaultGitZipMd5Url = "https://ghfvs-installer.github.com/unity/portable_git/git.zip.MD5.txt"; - public const string DefaultGitZipUrl = "https://ghfvs-installer.github.com/unity/portable_git/git.zip"; - public const string DefaultGitLfsZipMd5Url = "https://ghfvs-installer.github.com/unity/portable_git/git-lfs.zip.MD5.txt"; - public const string DefaultGitLfsZipUrl = "https://ghfvs-installer.github.com/unity/portable_git/git-lfs.zip"; - - public const string GitExtractedMD5 = "e6cfc0c294a2312042f27f893dfc9c0a"; - public const string GitLfsExtractedMD5 = "36e3ae968b69fbf42dff72311040d24a"; - - public const string WindowsGitExecutableMD5 = "50570ed932559f294d1a1361801740b9"; - public const string MacGitExecutableMD5 = ""; - - public const string WindowsGitLfsExecutableMD5 = "177bb14d0c08f665a24f0d5516c3b080"; - public const string MacGitLfsExecutableMD5 = "f81a1a065a26a4123193e8fd96c561ad"; - - private const string PackageVersion = "f02737a78695063deace08e96d5042710d3e32db"; - private const string PackageName = "PortableGit"; - - private readonly bool onWindows; - - public GitInstallDetails(NPath baseDataPath, bool onWindows) - { - this.onWindows = onWindows; - - ZipPath = baseDataPath.Combine("downloads"); - ZipPath.EnsureDirectoryExists(); - - var gitInstallPath = baseDataPath.Combine(PackageNameWithVersion); - GitInstallationPath = gitInstallPath; - - if (onWindows) - { - GitExecutable += "git.exe"; - GitLfsExecutable += "git-lfs.exe"; - - GitExecutablePath = gitInstallPath.Combine("cmd", GitExecutable); - } - else - { - GitExecutable = "git"; - GitLfsExecutable = "git-lfs"; - - GitExecutablePath = gitInstallPath.Combine("bin", GitExecutable); - } - - GitLfsExecutablePath = GetGitLfsExecutablePath(gitInstallPath); - } - - public NPath GetGitLfsExecutablePath(NPath gitInstallRoot) - { - return onWindows - ? gitInstallRoot.Combine("mingw32", "libexec", "git-core", GitLfsExecutable) - : gitInstallRoot.Combine("libexec", "git-core", GitLfsExecutable); - } - - public NPath ZipPath { get; } - public NPath GitInstallationPath { get; } - public string GitExecutable { get; } - public NPath GitExecutablePath { get; } - public string GitLfsExecutable { get; } - public NPath GitLfsExecutablePath { get; } - public UriString GitZipMd5Url { get; set; } = DefaultGitZipMd5Url; - public UriString GitZipUrl { get; set; } = DefaultGitZipUrl; - public UriString GitLfsZipMd5Url { get; set; } = DefaultGitLfsZipMd5Url; - public UriString GitLfsZipUrl { get; set; } = DefaultGitLfsZipUrl; - public string PackageNameWithVersion => PackageName + "_" + PackageVersion; - } - class GitInstaller { private static readonly ILogging Logger = LogHelper.GetLogger(); @@ -238,5 +169,74 @@ private bool IsGitExtracted() Logger.Trace("Git Present"); return true; } + + public class GitInstallDetails + { + public const string DefaultGitZipMd5Url = "https://ghfvs-installer.github.com/unity/portable_git/git.zip.MD5.txt"; + public const string DefaultGitZipUrl = "https://ghfvs-installer.github.com/unity/portable_git/git.zip"; + public const string DefaultGitLfsZipMd5Url = "https://ghfvs-installer.github.com/unity/portable_git/git-lfs.zip.MD5.txt"; + public const string DefaultGitLfsZipUrl = "https://ghfvs-installer.github.com/unity/portable_git/git-lfs.zip"; + + public const string GitExtractedMD5 = "e6cfc0c294a2312042f27f893dfc9c0a"; + public const string GitLfsExtractedMD5 = "36e3ae968b69fbf42dff72311040d24a"; + + public const string WindowsGitExecutableMD5 = "50570ed932559f294d1a1361801740b9"; + public const string MacGitExecutableMD5 = ""; + + public const string WindowsGitLfsExecutableMD5 = "177bb14d0c08f665a24f0d5516c3b080"; + public const string MacGitLfsExecutableMD5 = "f81a1a065a26a4123193e8fd96c561ad"; + + private const string PackageVersion = "f02737a78695063deace08e96d5042710d3e32db"; + private const string PackageName = "PortableGit"; + + private readonly bool onWindows; + + public GitInstallDetails(NPath baseDataPath, bool onWindows) + { + this.onWindows = onWindows; + + ZipPath = baseDataPath.Combine("downloads"); + ZipPath.EnsureDirectoryExists(); + + var gitInstallPath = baseDataPath.Combine(PackageNameWithVersion); + GitInstallationPath = gitInstallPath; + + if (onWindows) + { + GitExecutable += "git.exe"; + GitLfsExecutable += "git-lfs.exe"; + + GitExecutablePath = gitInstallPath.Combine("cmd", GitExecutable); + } + else + { + GitExecutable = "git"; + GitLfsExecutable = "git-lfs"; + + GitExecutablePath = gitInstallPath.Combine("bin", GitExecutable); + } + + GitLfsExecutablePath = GetGitLfsExecutablePath(gitInstallPath); + } + + public NPath GetGitLfsExecutablePath(NPath gitInstallRoot) + { + return onWindows + ? gitInstallRoot.Combine("mingw32", "libexec", "git-core", GitLfsExecutable) + : gitInstallRoot.Combine("libexec", "git-core", GitLfsExecutable); + } + + public NPath ZipPath { get; } + public NPath GitInstallationPath { get; } + public string GitExecutable { get; } + public NPath GitExecutablePath { get; } + public string GitLfsExecutable { get; } + public NPath GitLfsExecutablePath { get; } + public UriString GitZipMd5Url { get; set; } = DefaultGitZipMd5Url; + public UriString GitZipUrl { get; set; } = DefaultGitZipUrl; + public UriString GitLfsZipMd5Url { get; set; } = DefaultGitLfsZipMd5Url; + public UriString GitLfsZipUrl { get; set; } = DefaultGitLfsZipUrl; + public string PackageNameWithVersion => PackageName + "_" + PackageVersion; } } +} diff --git a/src/tests/IntegrationTests/BasePlatformIntegrationTest.cs b/src/tests/IntegrationTests/BasePlatformIntegrationTest.cs index 37261448a..f943fed7b 100644 --- a/src/tests/IntegrationTests/BasePlatformIntegrationTest.cs +++ b/src/tests/IntegrationTests/BasePlatformIntegrationTest.cs @@ -30,7 +30,7 @@ protected void InitializePlatform(NPath repoPath, NPath environmentPath, bool en var autoResetEvent = new AutoResetEvent(false); var applicationDataPath = Environment.GetSpecialFolder(System.Environment.SpecialFolder.LocalApplicationData).ToNPath(); - var installDetails = new GitInstallDetails(applicationDataPath, true); + var installDetails = new GitInstaller.GitInstallDetails(applicationDataPath, true); var zipArchivesPath = TestBasePath.Combine("ZipArchives").CreateDirectory(); var gitArchivePath = AssemblyResources.ToFile(ResourceType.Platform, "git.zip", zipArchivesPath, Environment); diff --git a/src/tests/IntegrationTests/Installer/GitInstallerTests.cs b/src/tests/IntegrationTests/Installer/GitInstallerTests.cs index da8824978..e13cde9a8 100644 --- a/src/tests/IntegrationTests/Installer/GitInstallerTests.cs +++ b/src/tests/IntegrationTests/Installer/GitInstallerTests.cs @@ -40,12 +40,12 @@ public void GitInstallTest() { var gitInstallationPath = TestBasePath.Combine("GitInstall").CreateDirectory(); - var installDetails = new GitInstallDetails(gitInstallationPath, DefaultEnvironment.OnWindows) + var installDetails = new GitInstaller.GitInstallDetails(gitInstallationPath, DefaultEnvironment.OnWindows) { - GitZipMd5Url = $"http://localhost:{server.Port}/{new UriString(GitInstallDetails.DefaultGitZipMd5Url).Filename}", - GitZipUrl = $"http://localhost:{server.Port}/{new UriString(GitInstallDetails.DefaultGitZipUrl).Filename}", - GitLfsZipMd5Url = $"http://localhost:{server.Port}/{new UriString(GitInstallDetails.DefaultGitLfsZipMd5Url).Filename}", - GitLfsZipUrl = $"http://localhost:{server.Port}/{new UriString(GitInstallDetails.DefaultGitLfsZipUrl).Filename}", + GitZipMd5Url = $"http://localhost:{server.Port}/{new UriString(GitInstaller.GitInstallDetails.DefaultGitZipMd5Url).Filename}", + GitZipUrl = $"http://localhost:{server.Port}/{new UriString(GitInstaller.GitInstallDetails.DefaultGitZipUrl).Filename}", + GitLfsZipMd5Url = $"http://localhost:{server.Port}/{new UriString(GitInstaller.GitInstallDetails.DefaultGitLfsZipMd5Url).Filename}", + GitLfsZipUrl = $"http://localhost:{server.Port}/{new UriString(GitInstaller.GitInstallDetails.DefaultGitLfsZipUrl).Filename}", }; TestBasePath.Combine("git").CreateDirectory(); diff --git a/src/tests/IntegrationTests/UnzipTaskTests.cs b/src/tests/IntegrationTests/UnzipTaskTests.cs index afffeb183..634fdcf92 100644 --- a/src/tests/IntegrationTests/UnzipTaskTests.cs +++ b/src/tests/IntegrationTests/UnzipTaskTests.cs @@ -27,7 +27,7 @@ public async Task UnzipWorks() var extractedPath = TestBasePath.Combine("gitlfs_zip_extracted").CreateDirectory(); var unzipTask = new UnzipTask(CancellationToken.None, archiveFilePath, extractedPath, - Environment.FileSystem, GitInstallDetails.GitLfsExtractedMD5); + Environment.FileSystem, GitInstaller.GitInstallDetails.GitLfsExtractedMD5); await unzipTask.StartAwait(); From 732c52198ced735263d7453ad00d9cb244d8d661 Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Mon, 5 Mar 2018 10:00:54 -0500 Subject: [PATCH 085/873] Getting things working manually --- octorun/src/authentication.js | 98 ++++++++++++++++++++++++----------- 1 file changed, 68 insertions(+), 30 deletions(-) diff --git a/octorun/src/authentication.js b/octorun/src/authentication.js index ebaebd26e..bdf59c3d2 100644 --- a/octorun/src/authentication.js +++ b/octorun/src/authentication.js @@ -1,43 +1,81 @@ -var readlineSync = require("readline-sync"); var config = require("./configuration"); var octokitWrapper = require("./octokit"); var scopes = ["user", "repo", "gist", "write:public_key"]; +var stdIn = process.openStdin(); + +var awaiter = null; + +stdIn.addListener("data", function(d){ + var content = d.toString().trim(); + + if(awaiter) + { + var _awaiter = awaiter; + awaiter = null; + _awaiter(content); + } +}); + var handleBasicAuthentication = function (onSuccess, onRequiresTwoFa, onFailure) { - var user = readlineSync.question('User: '); - var pwd = readlineSync.question('Password: ', { - hideEchoBack: true - }); + var username = null; + var password = null; - var octokit = octokitWrapper.createOctokit(); + var withPassword = function(input) { + password = input; + } - octokit.authenticate({ - type: "basic", - username: user, - password: pwd - }); + var promptPassword = function(){ + awaiter = withPassword; + } - octokit.authorization.create({ - scopes: scopes, - note: config.appName, - client_id: config.clientId, - client_secret: config.clientSecret - }, function (err, res) { - if (err) { - if (err.message === '{"message":"Must specify two-factor authentication OTP code.","documentation_url":"https://developer.github.com/v3/auth#working-with-two-factor-authentication"}') { - onRequiresTwoFa(); - return; - } - else { - onFailure(err) - } - } - else { - onSuccess(res.data.token); - } - }); + var withUser = function(input) { + username = input; + promptPassword(); + } + + var promptUser = function() { + awaiter = withUser; + } + + promptUser(); + + + // var user = readlineSync.question('User: '); + + // var pwd = readlineSync.question('Password: ', { + // hideEchoBack: true + // }); + + // var octokit = octokitWrapper.createOctokit(); + + // octokit.authenticate({ + // type: "basic", + // username: user, + // password: pwd + // }); + + // octokit.authorization.create({ + // scopes: scopes, + // note: config.appName, + // client_id: config.clientId, + // client_secret: config.clientSecret + // }, function (err, res) { + // if (err) { + // if (err.message === '{"message":"Must specify two-factor authentication OTP code.","documentation_url":"https://developer.github.com/v3/auth#working-with-two-factor-authentication"}') { + // onRequiresTwoFa(); + // return; + // } + // else { + // onFailure(err) + // } + // } + // else { + // onSuccess(res.data.token); + // } + // }); } var handleTwoFactorAuthentication = function (onSuccess, onFailure) { From 76e34d4d89dc9e9b538695b0de3c6f90d67fe042 Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Mon, 5 Mar 2018 10:26:04 -0500 Subject: [PATCH 086/873] Removing readline-sync --- octorun/package.json | 3 +- octorun/src/authentication.js | 172 +++++++++++++++++++--------------- 2 files changed, 97 insertions(+), 78 deletions(-) diff --git a/octorun/package.json b/octorun/package.json index dc1ceee3e..f7237151e 100644 --- a/octorun/package.json +++ b/octorun/package.json @@ -12,7 +12,6 @@ "dependencies": { "commander": "^2.14.1", "dotenv": "^1.0.0", - "octokit-rest-for-node-v0.12": "1.0.1", - "readline-sync": "^1.4.9" + "octokit-rest-for-node-v0.12": "1.0.1" } } diff --git a/octorun/src/authentication.js b/octorun/src/authentication.js index bdf59c3d2..a8cdda693 100644 --- a/octorun/src/authentication.js +++ b/octorun/src/authentication.js @@ -7,11 +7,10 @@ var stdIn = process.openStdin(); var awaiter = null; -stdIn.addListener("data", function(d){ +stdIn.addListener("data", function (d) { var content = d.toString().trim(); - - if(awaiter) - { + + if (awaiter) { var _awaiter = awaiter; awaiter = null; _awaiter(content); @@ -19,98 +18,119 @@ stdIn.addListener("data", function(d){ }); var handleBasicAuthentication = function (onSuccess, onRequiresTwoFa, onFailure) { - var username = null; var password = null; - var withPassword = function(input) { + var withPassword = function (input) { password = input; + + var octokit = octokitWrapper.createOctokit(); + + octokit.authenticate({ + type: "basic", + username: username, + password: password + }); + + octokit.authorization.create({ + scopes: scopes, + note: config.appName, + client_id: config.clientId, + client_secret: config.clientSecret + }, function (err, res) { + if (err) { + if (err.message === '{"message":"Must specify two-factor authentication OTP code.","documentation_url":"https://developer.github.com/v3/auth#working-with-two-factor-authentication"}') { + onRequiresTwoFa(); + return; + } + else { + onFailure(err) + } + } + else { + onSuccess(res.data.token); + } + }); } - var promptPassword = function(){ + var promptPassword = function () { + process.stdout.write("Password: "); awaiter = withPassword; } - var withUser = function(input) { + var withUser = function (input) { username = input; promptPassword(); } - var promptUser = function() { + var promptUser = function () { + process.stdout.write("Username: "); awaiter = withUser; } promptUser(); - - - // var user = readlineSync.question('User: '); - - // var pwd = readlineSync.question('Password: ', { - // hideEchoBack: true - // }); - - // var octokit = octokitWrapper.createOctokit(); - - // octokit.authenticate({ - // type: "basic", - // username: user, - // password: pwd - // }); - - // octokit.authorization.create({ - // scopes: scopes, - // note: config.appName, - // client_id: config.clientId, - // client_secret: config.clientSecret - // }, function (err, res) { - // if (err) { - // if (err.message === '{"message":"Must specify two-factor authentication OTP code.","documentation_url":"https://developer.github.com/v3/auth#working-with-two-factor-authentication"}') { - // onRequiresTwoFa(); - // return; - // } - // else { - // onFailure(err) - // } - // } - // else { - // onSuccess(res.data.token); - // } - // }); } var handleTwoFactorAuthentication = function (onSuccess, onFailure) { - var user = readlineSync.question('User: '); - - var pwd = readlineSync.question('Password: ', { - hideEchoBack: true - }); - - var twofa = readlineSync.question('TwoFactor: '); - - var octokit = octokitWrapper.createOctokit(); - - octokit.authenticate({ - type: "basic", - username: user, - password: pwd - }); - - octokit.authorization.create({ - scopes: scopes, - note: config.appName, - client_id: config.clientId, - client_secret: config.clientSecret, - headers: { - "X-GitHub-OTP": twofa - } - }, function (err, res) { - if (err) { - onFailure(err) - } - else { - onSuccess(res.data.token); - } - }); + var username = null; + var password = null; + var twoFactor = null; + + var withTwoFactor = function (input) { + twoFactor = input; + + var octokit = octokitWrapper.createOctokit(); + + octokit.authenticate({ + type: "basic", + username: username, + password: password + }); + + octokit.authorization.create({ + scopes: scopes, + note: config.appName, + client_id: config.clientId, + client_secret: config.clientSecret, + headers: { + "X-GitHub-OTP": twoFactor + } + }, function (err, res) { + if (err) { + onFailure(err) + } + else { + onSuccess(res.data.token); + } + }); + } + + var promptTwoFactor = function () { + process.stdout.write("Two Factor: "); + awaiter = withTwoFactor; + } + + var withPassword = function (input) { + password = input; + promptTwoFactor(); + } + + var promptPassword = function () { + process.stdout.write("Password: "); + awaiter = withPassword; + } + + var withUser = function (input) { + username = input; + promptPassword(); + } + + var promptUser = function () { + process.stdout.write("Username: "); + awaiter = withUser; + } + + promptUser(); } module.exports = { From abcdb4ad256ddfbacf9c9d087bb25213940ff718 Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Mon, 5 Mar 2018 10:44:33 -0500 Subject: [PATCH 087/873] Attempting to use LoginManager to run octorun --- octorun/bin/octorun | 2 +- octorun/src/bin/app-login.js | 10 +++++----- octorun/src/bin/app-organizations.js | 4 ++-- octorun/src/bin/app-publish.js | 6 +++--- octorun/src/bin/app-usage.js | 2 +- octorun/src/bin/app-validate.js | 4 ++-- octorun/src/configuration.js | 2 +- src/GitHub.Api/Authentication/LoginManager.cs | 14 ++++++++++---- 8 files changed, 25 insertions(+), 19 deletions(-) diff --git a/octorun/bin/octorun b/octorun/bin/octorun index f7c15dc90..9c031d64f 100644 --- a/octorun/bin/octorun +++ b/octorun/bin/octorun @@ -1,5 +1,5 @@ #!/usr/bin/env node -console.log("node:", process.argv[0]); +process.stdout.write("node:", process.argv[0]); require('../src/bin/app.js'); diff --git a/octorun/src/bin/app-login.js b/octorun/src/bin/app-login.js index 19f2582fd..f90504f25 100644 --- a/octorun/src/bin/app-login.js +++ b/octorun/src/bin/app-login.js @@ -9,22 +9,22 @@ commander if (commander.twoFactor) { authentication.handleTwoFactorAuthentication(function (token) { - console.log(token); + process.stdout.write(token); process.exit(); }, function (err) { - console.log(err); + process.stdout.write(err); process.exit(); }); } else { authentication.handleBasicAuthentication(function (token) { - console.log(token); + process.stdout.write(token); process.exit(); }, function () { - console.log("Must specify two-factor authentication OTP code."); + process.stdout.write("Must specify two-factor authentication OTP code."); process.exit(); }, function (err) { - console.log(err); + process.stdout.write(err); process.exit(); }); } \ No newline at end of file diff --git a/octorun/src/bin/app-organizations.js b/octorun/src/bin/app-organizations.js index e57acc8d3..21a9b86ed 100644 --- a/octorun/src/bin/app-organizations.js +++ b/octorun/src/bin/app-organizations.js @@ -9,11 +9,11 @@ commander var apiWrapper = new ApiWrapper(); apiWrapper.getOrgs(function (error, result) { if (error) { - console.log(error); + process.stdout.write(error); process.exit(-1); } else { - console.log(result); + process.stdout.write(result); process.exit(); } }); \ No newline at end of file diff --git a/octorun/src/bin/app-publish.js b/octorun/src/bin/app-publish.js index a02033276..69757ee51 100644 --- a/octorun/src/bin/app-publish.js +++ b/octorun/src/bin/app-publish.js @@ -12,7 +12,7 @@ commander if(!commander.repository) { - console.log("repository required"); + process.stdout.write("repository required"); commander.help(); process.exit(-1); return; @@ -28,11 +28,11 @@ var apiWrapper = new ApiWrapper(); apiWrapper.publish(commander.repository, commander.description, private, commander.organization, function (error, result) { if (error) { - console.log(error); + process.stdout.write(error); process.exit(-1); } else { - console.log(result); + process.stdout.write(result); process.exit(); } }); \ No newline at end of file diff --git a/octorun/src/bin/app-usage.js b/octorun/src/bin/app-usage.js index c3f6ea5f6..a6279e411 100644 --- a/octorun/src/bin/app-usage.js +++ b/octorun/src/bin/app-usage.js @@ -21,7 +21,7 @@ var options = { }; var req = https.request(options, function (res) { - console.log('statusCode:', res.statusCode); + process.stdout.write('statusCode:', res.statusCode); res.on('data', function (d) { process.stdout.write(d); diff --git a/octorun/src/bin/app-validate.js b/octorun/src/bin/app-validate.js index 5e63750bd..55c5bf766 100644 --- a/octorun/src/bin/app-validate.js +++ b/octorun/src/bin/app-validate.js @@ -10,11 +10,11 @@ var apiWrapper = new ApiWrapper(); apiWrapper.verifyUser(function (error, result) { if (error) { - console.log(error); + process.stdout.write(error); process.exit(-1); } else { - console.log(result); + process.stdout.write(result); process.exit(); } }); \ No newline at end of file diff --git a/octorun/src/configuration.js b/octorun/src/configuration.js index 4d9474b40..ba5ad4447 100644 --- a/octorun/src/configuration.js +++ b/octorun/src/configuration.js @@ -1,4 +1,4 @@ -require("dotenv").config(); +require("dotenv").config({silent: true}); var clientId = process.env.OCTOKIT_CLIENT_ID; var clientSecret = process.env.OCTOKIT_CLIENT_SECRET; diff --git a/src/GitHub.Api/Authentication/LoginManager.cs b/src/GitHub.Api/Authentication/LoginManager.cs index fd83383d5..ffed03457 100644 --- a/src/GitHub.Api/Authentication/LoginManager.cs +++ b/src/GitHub.Api/Authentication/LoginManager.cs @@ -259,7 +259,7 @@ private async Task TryLogin( string password ) { - logger.Info("Login Username:{0} {1}", username, octorunScript); + logger.Info("Login Username:{0} Script:{1}", username, octorunScript); ApplicationAuthorization auth = null; var loginTask = new SimpleListProcessTask(taskManager.Token, nodeJsExecutablePath, $"{octorunScript} login"); @@ -270,11 +270,17 @@ string password proc.StandardInput.WriteLine(password); proc.StandardInput.Close(); }; - var ret = await loginTask.StartAwait(); - foreach (var result in ret) + loginTask.OnEndProcess += proc => { + logger.Trace("Exit Code: ", proc.Process.ExitCode); + }; + + var ret = (await loginTask.StartAwait()).ToArray(); + + for (var index = 0; index < ret.Length; index++) { - logger.Trace(result); + var result = ret[index]; + logger.Trace("line {0}: {1}", index, result); } throw new Exception("Authentication failed"); From 95f1cb7af208982d7e920604dd84b04cd06a58f8 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Mon, 5 Mar 2018 17:09:46 +0100 Subject: [PATCH 088/873] Fix a bunch of bugs in the git installation sequence and update progress --- .../Application/ApplicationManagerBase.cs | 21 +- src/GitHub.Api/Helpers/Progress.cs | 21 +- src/GitHub.Api/IO/Utils.cs | 2 - src/GitHub.Api/Installer/GitInstaller.cs | 352 ++++++++++-------- src/GitHub.Api/Installer/IZipHelper.cs | 2 +- src/GitHub.Api/Installer/UnzipTask.cs | 25 +- src/GitHub.Api/Installer/ZipHelper.cs | 56 ++- src/GitHub.Api/Tasks/DownloadTask.cs | 2 +- src/GitHub.Api/Tasks/TaskBase.cs | 21 +- .../Assets/Editor/GitHub.Unity/UI/Spinner.cs | 6 +- .../Assets/Editor/GitHub.Unity/UI/Window.cs | 4 +- .../BasePlatformIntegrationTest.cs | 21 +- .../Installer/GitInstallerTests.cs | 25 +- src/tests/IntegrationTests/UnzipTaskTests.cs | 2 +- 14 files changed, 307 insertions(+), 253 deletions(-) diff --git a/src/GitHub.Api/Application/ApplicationManagerBase.cs b/src/GitHub.Api/Application/ApplicationManagerBase.cs index c1e2112ef..418b5662f 100644 --- a/src/GitHub.Api/Application/ApplicationManagerBase.cs +++ b/src/GitHub.Api/Application/ApplicationManagerBase.cs @@ -12,11 +12,17 @@ abstract class ApplicationManagerBase : IApplicationManager protected static ILogging Logger { get; } = LogHelper.GetLogger(); private RepositoryManager repositoryManager; + private Progress progressReporter; protected bool isBusy; - public event Action OnProgress; + public event Action OnProgress + { + add { progressReporter.OnProgress += value; } + remove { progressReporter.OnProgress -= value; } + } public ApplicationManagerBase(SynchronizationContext synchronizationContext) { + progressReporter = new Progress(); SynchronizationContext = synchronizationContext; SynchronizationContext.SetSynchronizationContext(SynchronizationContext); ThreadingHelper.SetUIThread(); @@ -60,7 +66,8 @@ public void Run(bool firstRun) Logger.Trace("No git path found in settings"); isBusy = true; - var initEnvironmentTask = new ActionTask(CancellationToken, (b, path) => InitializeEnvironment(path)) { Affinity = TaskAffinity.UI }; + var initEnvironmentTask = new ActionTask(CancellationToken, + (b, path) => InitializeEnvironment(path)) { Affinity = TaskAffinity.UI }; var findExecTask = new FindExecTask("git", CancellationToken) .FinallyInUI((b, ex, path) => { @@ -80,7 +87,15 @@ public void Run(bool firstRun) var gitInstaller = new GitInstaller(Environment, CancellationToken); // if successful, continue with environment initialization, otherwise try to find an existing git installation - gitInstaller.SetupGitIfNeeded(initEnvironmentTask, findExecTask); + var setupTask = gitInstaller.SetupGitIfNeeded(); + setupTask.Progress(progressReporter.UpdateProgress); + setupTask.OnEnd += (thisTask, result, success, exception) => + { + if (success && result != null) + thisTask.Then(initEnvironmentTask); + else + thisTask.Then(findExecTask); + }; } } diff --git a/src/GitHub.Api/Helpers/Progress.cs b/src/GitHub.Api/Helpers/Progress.cs index 7aadf605f..4dc90a4a9 100644 --- a/src/GitHub.Api/Helpers/Progress.cs +++ b/src/GitHub.Api/Helpers/Progress.cs @@ -1,3 +1,4 @@ +using GitHub.Logging; using System; namespace GitHub.Unity @@ -11,25 +12,41 @@ public interface IProgress float Percentage { get; } long Value { get; } long Total { get; } + string Message { get; } + event Action OnProgress; } public class Progress : IProgress { + private static ILogging Logger = LogHelper.GetLogger(); public ITask Task { get; internal set; } public float Percentage { get { return Total > 0 ? (float)(double)Value / Total : 0f; } } public long Value { get; internal set; } public long Total { get; internal set; } + public string Message { get; internal set; } private long previousValue; private float averageSpeed = -1f; private float lastSpeed = 0f; private float smoothing = 0.005f; + public event Action OnProgress; - public void UpdateProgress(long value, long total) + public void UpdateProgress(IProgress progress) + { + Task = progress.Task; + UpdateProgress(progress.Value, progress.Total, progress.Message); + } + + public void UpdateProgress(long value, long total, string message = null) { - previousValue = Value; Total = total; Value = value; + Message = message ?? Message; + if (Total == 0 || ((float)(double)Value / Total) - ((float)(double)previousValue / Total) > 1f / 100f) + { // signal progress in 1% increments or if we don't know what the total is + previousValue = Value; + OnProgress?.Invoke(this); + } } } } diff --git a/src/GitHub.Api/IO/Utils.cs b/src/GitHub.Api/IO/Utils.cs index 34fcccdf0..fb4358dd9 100644 --- a/src/GitHub.Api/IO/Utils.cs +++ b/src/GitHub.Api/IO/Utils.cs @@ -14,7 +14,6 @@ public static bool Copy(Stream source, Stream destination, Func progress = null, int progressUpdateRate = 100) { - var logger = LogHelper.GetLogger("Copy"); byte[] buffer = new byte[chunkSize]; int bytesRead = 0; long totalRead = 0; @@ -62,7 +61,6 @@ public static bool Copy(Stream source, Stream destination, timeToFinish = Math.Max(1L, (long)((totalSize - totalRead) / (averageSpeed / progressUpdateRate))); - logger.Trace($"totalRead: {totalRead} of {totalSize}"); success = progress(totalRead, timeToFinish); if (!success) break; diff --git a/src/GitHub.Api/Installer/GitInstaller.cs b/src/GitHub.Api/Installer/GitInstaller.cs index edd9f61cd..0bbd2680c 100644 --- a/src/GitHub.Api/Installer/GitInstaller.cs +++ b/src/GitHub.Api/Installer/GitInstaller.cs @@ -13,230 +13,260 @@ class GitInstaller private readonly IEnvironment environment; private readonly GitInstallDetails installDetails; private readonly IZipHelper sharpZipLibHelper; - private NPath gitArchiveFilePath; - private NPath gitLfsArchivePath; + + ITask installationTask; public GitInstaller(IEnvironment environment, CancellationToken cancellationToken, - GitInstallDetails installDetails = null, NPath gitArchiveFilePath = null, NPath gitLfsArchivePath = null) + GitInstallDetails installDetails = null) { this.environment = environment; this.sharpZipLibHelper = ZipHelper.Instance; this.cancellationToken = cancellationToken; this.installDetails = installDetails ?? new GitInstallDetails(environment.UserCachePath, environment.IsWindows); - this.gitArchiveFilePath = gitArchiveFilePath; - this.gitLfsArchivePath = gitLfsArchivePath; } - public void SetupGitIfNeeded(ActionTask onSuccess, ITask onFailure) + public ITask SetupGitIfNeeded() { Logger.Trace("SetupGitIfNeeded"); + installationTask = new FuncTask(cancellationToken, (_, r) => installDetails.GitExecutablePath) + { Name = "Git Installation - Complete" }; + installationTask.OnStart += thisTask => thisTask.UpdateProgress(0, 100); + installationTask.OnEnd += (thisTask, result, success, exception) => thisTask.UpdateProgress(100, 100); + if (!environment.IsWindows) - { - onFailure.Start(); - return; - } + return installationTask; - var isGitExtractedTask = new FuncTask(cancellationToken, () => - { - if (!IsGitExtracted()) + var startTask = new FuncTask(cancellationToken, () => { - GrabZipFromResources(); - return null; - } - Logger.Trace("SetupGitIfNeeded: Skipped"); - return installDetails.GitExecutablePath; - }); - isGitExtractedTask.OnEnd += (t, res, _, __) => + var state = VerifyGitInstallation(); + if (!state.GitIsValid && !state.GitLfsIsValid) + state = GrabZipFromResources(state); + else + Logger.Trace("SetupGitIfNeeded: Skipped"); + return state; + }) + { Name = "Git Installation - Extract" }; + + + startTask.OnEnd += (thisTask, state, success, exception) => { - if (res == null) + if (!state.GitIsValid && !state.GitLfsIsValid) { - var extractTask = ExtractPortableGit(); - extractTask.Then(onSuccess, TaskRunOptions.OnSuccess, taskIsTopOfChain: true); - extractTask.Then(onFailure, TaskRunOptions.OnFailure, taskIsTopOfChain: true); - t.Then(extractTask); + if (!state.GitZipExists || !state.GitLfsZipExists) + thisTask = thisTask.Then(CreateDownloadTask(state)); + thisTask = thisTask.Then(ExtractPortableGit(state)); } - else - t.Then(onSuccess); + thisTask.Then(installationTask); }; - isGitExtractedTask.Start(); + // we want to start the startTask and not the installationTask because the latter only gets + // appended to the task chain when startTask ends, so calling Start() on it wouldn't work + startTask.Start(); + return installationTask; } - private void GrabZipFromResources() + private GitInstallationState VerifyGitInstallation() { - if (gitArchiveFilePath == null || !gitArchiveFilePath.FileExists()) - gitArchiveFilePath = AssemblyResources.ToFile(ResourceType.Platform, "git.zip", installDetails.ZipPath, environment); - if (!gitArchiveFilePath.FileExists()) - gitArchiveFilePath = null; - - if (gitLfsArchivePath == null || !gitLfsArchivePath.FileExists()) - gitLfsArchivePath = AssemblyResources.ToFile(ResourceType.Platform, "git-lfs.zip", installDetails.ZipPath, environment); - if (!gitLfsArchivePath.FileExists()) - gitLfsArchivePath = null; + var state = new GitInstallationState(); + state.GitExists = installDetails.GitExecutablePath?.FileExists() ?? false; + state.GitLfsExists = installDetails.GitLfsExecutablePath?.FileExists() ?? false; + state.GitZipExists = installDetails.GitZipPath.FileExists(); + state.GitLfsZipExists = installDetails.GitLfsZipPath.FileExists(); + + if (state.GitExists) + { + var actualmd5 = installDetails.GitExecutablePath.CalculateMD5(); + var expectedmd5 = environment.IsWindows ? GitInstallDetails.WindowsGitExecutableMD5 : GitInstallDetails.MacGitExecutableMD5; + state.GitIsValid = expectedmd5.Equals(actualmd5, StringComparison.InvariantCultureIgnoreCase); + if (!state.GitIsValid) + Logger.Trace($"Path {installDetails.GitExecutablePath} has MD5 {actualmd5} expected {expectedmd5}"); + } + else + Logger.Trace($"{installDetails.GitExecutablePath} does not exist"); + + if (state.GitLfsExists) + { + var actualmd5 = installDetails.GitLfsExecutablePath.CalculateMD5(); + var expectedmd5 = environment.IsWindows ? GitInstallDetails.WindowsGitLfsExecutableMD5 : GitInstallDetails.MacGitLfsExecutableMD5; + state.GitLfsIsValid = expectedmd5.Equals(actualmd5, StringComparison.InvariantCultureIgnoreCase); + if (!state.GitLfsIsValid) + Logger.Trace($"Path {installDetails.GitLfsExecutablePath} has MD5 {actualmd5} expected {expectedmd5}"); + } + else + Logger.Trace($"{installDetails.GitLfsExecutablePath} does not exist"); + installationTask.UpdateProgress(10, 100); + return state; } - private ITask CreateDownloadTask() + private GitInstallationState GrabZipFromResources(GitInstallationState state) { - gitArchiveFilePath = installDetails.ZipPath.Combine("git.zip"); - gitLfsArchivePath = installDetails.ZipPath.Combine("git-lfs.zip"); + if (!state.GitZipExists) + AssemblyResources.ToFile(ResourceType.Platform, "git.zip", installDetails.ZipPath, environment); + state.GitZipExists = installDetails.GitZipPath.FileExists(); + + if (!state.GitLfsZipExists) + AssemblyResources.ToFile(ResourceType.Platform, "git-lfs.zip", installDetails.ZipPath, environment); + state.GitLfsZipExists = installDetails.GitLfsZipPath.FileExists(); + installationTask.UpdateProgress(20, 100); + return state; + } + private ITask CreateDownloadTask(GitInstallationState state) + { var downloader = new Downloader(); downloader.QueueDownload(installDetails.GitZipUrl, installDetails.GitZipMd5Url, installDetails.ZipPath); downloader.QueueDownload(installDetails.GitLfsZipUrl, installDetails.GitLfsZipMd5Url, installDetails.ZipPath); - return downloader; - } - - private FuncTask CreateUnzipTasks(NPath gitExtractPath, NPath gitLfsExtractPath, NPath tempZipExtractPath) - { - var unzipGitTask = new UnzipTask(cancellationToken, gitArchiveFilePath, gitExtractPath, sharpZipLibHelper, - environment.FileSystem, GitInstallDetails.GitExtractedMD5); - var unzipGitLfsTask = new UnzipTask(cancellationToken, gitLfsArchivePath, gitLfsExtractPath, sharpZipLibHelper, - environment.FileSystem, GitInstallDetails.GitLfsExtractedMD5); - - var moveGitTask = new FuncTask(cancellationToken, () => MoveGitAndLfs(gitExtractPath, gitLfsExtractPath, tempZipExtractPath)); - return unzipGitTask - .Then(unzipGitLfsTask) - .Then(moveGitTask); + return downloader.Then((_, data) => + { + state.GitZipExists = installDetails.GitZipPath.FileExists(); + state.GitLfsZipExists = installDetails.GitLfsZipPath.FileExists(); + installationTask.UpdateProgress(40, 100); + return state; + }); } - private FuncTask ExtractPortableGit() + private FuncTask ExtractPortableGit(GitInstallationState state) { + ITask task = null; var tempZipExtractPath = NPath.CreateTempDirectory("git_zip_extract_zip_paths"); var gitExtractPath = tempZipExtractPath.Combine("git").CreateDirectory(); - var gitLfsExtractPath = tempZipExtractPath.Combine("git-lfs").CreateDirectory(); - - var unzipTasks = CreateUnzipTasks(gitExtractPath, gitLfsExtractPath, tempZipExtractPath); - if (gitArchiveFilePath == null || gitLfsArchivePath == null) + if (!state.GitIsValid) { - var downloadFilesTask = CreateDownloadTask(); - unzipTasks = downloadFilesTask.Then(unzipTasks); - } - - return unzipTasks; - } - - private NPath MoveGitAndLfs(NPath gitExtractPath, NPath gitLfsExtractPath, NPath tempZipExtractPath) - { - var targetGitLfsExecPath = installDetails.GetGitLfsExecutablePath(gitExtractPath); - var extractGitLfsExePath = gitLfsExtractPath.Combine(installDetails.GitLfsExecutable); - - Logger.Trace($"Moving Git LFS Exe:'{extractGitLfsExePath}' to target in tempDirectory:'{targetGitLfsExecPath}'"); + ITask unzipTask = new UnzipTask(cancellationToken, installDetails.GitZipPath, gitExtractPath, sharpZipLibHelper, + environment.FileSystem, GitInstallDetails.GitExtractedMD5); + unzipTask.Progress(p => installationTask.UpdateProgress(40 + (long)(20 * p.Percentage), 100, unzipTask.Name)); - extractGitLfsExePath.Move(targetGitLfsExecPath); - - Logger.Trace($"Moving tempDirectory:'{gitExtractPath}' to extractTarget:'{installDetails.GitInstallationPath}'"); + unzipTask = unzipTask.Then((s, path) => + { + var source = path; + var target = installDetails.GitInstallationPath; + target.DeleteIfExists(); + target.EnsureParentDirectoryExists(); + Logger.Trace($"Moving '{source}' to '{target}'"); + source.Move(target); + state.GitExists = installDetails.GitExecutablePath.FileExists(); + state.GitIsValid = s; + return path; + }); + task = unzipTask; + } - installDetails.GitInstallationPath.EnsureParentDirectoryExists(); - gitExtractPath.Move(installDetails.GitInstallationPath); + var gitLfsExtractPath = tempZipExtractPath.Combine("git-lfs").CreateDirectory(); - Logger.Trace($"Deleting targetGitLfsExecPath:'{targetGitLfsExecPath}'"); + if (!state.GitLfsIsValid) + { + ITask unzipTask = new UnzipTask(cancellationToken, installDetails.GitLfsZipPath, gitLfsExtractPath, sharpZipLibHelper, + environment.FileSystem, GitInstallDetails.GitLfsExtractedMD5); + unzipTask.Progress(p => installationTask.UpdateProgress(60 + (long)(20 * p.Percentage), 100, unzipTask.Name)); - targetGitLfsExecPath.DeleteIfExists(); + unzipTask = unzipTask.Then((s, path) => + { + var source = path.Combine(installDetails.GitLfsExecutable); + var target = installDetails.GetGitLfsExecutablePath(installDetails.GitInstallationPath); + target.DeleteIfExists(); + target.EnsureParentDirectoryExists(); + Logger.Trace($"Moving '{source}' to '{target}'"); + source.Move(target); + state.GitExists = target.FileExists(); + state.GitIsValid = s; + return path; + }); + task = task?.Then(unzipTask) ?? unzipTask; + } - Logger.Trace($"Deleting tempZipPath:'{tempZipExtractPath}'"); - tempZipExtractPath.DeleteIfExists(); - return installDetails.GitExecutablePath; + return task.Finally(new FuncTask(cancellationToken, (success) => + { + tempZipExtractPath.DeleteIfExists(); + return state; + })); } - private bool IsGitExtracted() + class GitInstallationState { - if (!installDetails.GitInstallationPath.DirectoryExists()) - { - Logger.Warning($"{installDetails.GitInstallationPath} does not exist"); - return false; - } - - var gitExecutableMd5 = installDetails.GitExecutablePath.CalculateMD5(); - var expectedGitExecutableMd5 = environment.IsWindows ? GitInstallDetails.WindowsGitExecutableMD5 : GitInstallDetails.MacGitExecutableMD5; - - if (!expectedGitExecutableMd5.Equals(gitExecutableMd5, StringComparison.InvariantCultureIgnoreCase)) - { - Logger.Warning($"Path {installDetails.GitExecutablePath} has MD5 {gitExecutableMd5} expected {expectedGitExecutableMd5}"); - return false; - } + public bool GitExists { get; set; } + public bool GitLfsExists { get; set; } + public bool GitIsValid { get; set; } + public bool GitLfsIsValid { get; set; } + public bool GitZipExists { get; set; } + public bool GitLfsZipExists { get; set; } + } - var gitLfsExecutableMd5 = installDetails.GitLfsExecutablePath.CalculateMD5(); - var expectedGitLfsExecutableMd5 = environment.IsWindows ? GitInstallDetails.WindowsGitLfsExecutableMD5 : GitInstallDetails.MacGitLfsExecutableMD5; + public class GitInstallDetails + { + public const string DefaultGitZipMd5Url = "https://ghfvs-installer.github.com/unity/portable_git/git.zip.MD5.txt"; + public const string DefaultGitZipUrl = "https://ghfvs-installer.github.com/unity/portable_git/git.zip"; + public const string DefaultGitLfsZipMd5Url = "https://ghfvs-installer.github.com/unity/portable_git/git-lfs.zip.MD5.txt"; + public const string DefaultGitLfsZipUrl = "https://ghfvs-installer.github.com/unity/portable_git/git-lfs.zip"; - if (!expectedGitLfsExecutableMd5.Equals(gitLfsExecutableMd5, StringComparison.InvariantCultureIgnoreCase)) - { - Logger.Warning($"Path {installDetails.GitLfsExecutablePath} has MD5 {gitLfsExecutableMd5} expected {expectedGitLfsExecutableMd5}"); - return false; - } + public const string GitExtractedMD5 = "e6cfc0c294a2312042f27f893dfc9c0a"; + public const string GitLfsExtractedMD5 = "36e3ae968b69fbf42dff72311040d24a"; - Logger.Trace("Git Present"); - return true; - } + public const string WindowsGitExecutableMD5 = "50570ed932559f294d1a1361801740b9"; + public const string MacGitExecutableMD5 = ""; - public class GitInstallDetails - { - public const string DefaultGitZipMd5Url = "https://ghfvs-installer.github.com/unity/portable_git/git.zip.MD5.txt"; - public const string DefaultGitZipUrl = "https://ghfvs-installer.github.com/unity/portable_git/git.zip"; - public const string DefaultGitLfsZipMd5Url = "https://ghfvs-installer.github.com/unity/portable_git/git-lfs.zip.MD5.txt"; - public const string DefaultGitLfsZipUrl = "https://ghfvs-installer.github.com/unity/portable_git/git-lfs.zip"; + public const string WindowsGitLfsExecutableMD5 = "177bb14d0c08f665a24f0d5516c3b080"; + public const string MacGitLfsExecutableMD5 = "f81a1a065a26a4123193e8fd96c561ad"; - public const string GitExtractedMD5 = "e6cfc0c294a2312042f27f893dfc9c0a"; - public const string GitLfsExtractedMD5 = "36e3ae968b69fbf42dff72311040d24a"; + private const string PackageVersion = "f02737a78695063deace08e96d5042710d3e32db"; + private const string PackageName = "PortableGit"; - public const string WindowsGitExecutableMD5 = "50570ed932559f294d1a1361801740b9"; - public const string MacGitExecutableMD5 = ""; + private const string gitZip = "git.zip"; + private const string gitLfsZip = "git-lfs.zip"; - public const string WindowsGitLfsExecutableMD5 = "177bb14d0c08f665a24f0d5516c3b080"; - public const string MacGitLfsExecutableMD5 = "f81a1a065a26a4123193e8fd96c561ad"; + private readonly bool onWindows; - private const string PackageVersion = "f02737a78695063deace08e96d5042710d3e32db"; - private const string PackageName = "PortableGit"; + public GitInstallDetails(NPath baseDataPath, bool onWindows) + { + this.onWindows = onWindows; - private readonly bool onWindows; + ZipPath = baseDataPath.Combine("downloads"); + ZipPath.EnsureDirectoryExists(); + GitZipPath = ZipPath.Combine(gitZip); + GitLfsZipPath = ZipPath.Combine(gitLfsZip); - public GitInstallDetails(NPath baseDataPath, bool onWindows) - { - this.onWindows = onWindows; + var gitInstallPath = baseDataPath.Combine(PackageNameWithVersion); + GitInstallationPath = gitInstallPath; - ZipPath = baseDataPath.Combine("downloads"); - ZipPath.EnsureDirectoryExists(); + if (onWindows) + { + GitExecutable += "git.exe"; + GitLfsExecutable += "git-lfs.exe"; - var gitInstallPath = baseDataPath.Combine(PackageNameWithVersion); - GitInstallationPath = gitInstallPath; + GitExecutablePath = gitInstallPath.Combine("cmd", GitExecutable); + } + else + { + GitExecutable = "git"; + GitLfsExecutable = "git-lfs"; - if (onWindows) - { - GitExecutable += "git.exe"; - GitLfsExecutable += "git-lfs.exe"; + GitExecutablePath = gitInstallPath.Combine("bin", GitExecutable); + } - GitExecutablePath = gitInstallPath.Combine("cmd", GitExecutable); + GitLfsExecutablePath = GetGitLfsExecutablePath(gitInstallPath); } - else - { - GitExecutable = "git"; - GitLfsExecutable = "git-lfs"; - GitExecutablePath = gitInstallPath.Combine("bin", GitExecutable); + public NPath GetGitLfsExecutablePath(NPath gitInstallRoot) + { + return onWindows + ? gitInstallRoot.Combine("mingw32", "libexec", "git-core", GitLfsExecutable) + : gitInstallRoot.Combine("libexec", "git-core", GitLfsExecutable); } - GitLfsExecutablePath = GetGitLfsExecutablePath(gitInstallPath); - } - - public NPath GetGitLfsExecutablePath(NPath gitInstallRoot) - { - return onWindows - ? gitInstallRoot.Combine("mingw32", "libexec", "git-core", GitLfsExecutable) - : gitInstallRoot.Combine("libexec", "git-core", GitLfsExecutable); + public NPath ZipPath { get; } + public NPath GitZipPath { get; } + public NPath GitLfsZipPath { get; } + public NPath GitInstallationPath { get; } + public string GitExecutable { get; } + public NPath GitExecutablePath { get; } + public string GitLfsExecutable { get; } + public NPath GitLfsExecutablePath { get; } + public UriString GitZipMd5Url { get; set; } = DefaultGitZipMd5Url; + public UriString GitZipUrl { get; set; } = DefaultGitZipUrl; + public UriString GitLfsZipMd5Url { get; set; } = DefaultGitLfsZipMd5Url; + public UriString GitLfsZipUrl { get; set; } = DefaultGitLfsZipUrl; + public string PackageNameWithVersion => PackageName + "_" + PackageVersion; } - - public NPath ZipPath { get; } - public NPath GitInstallationPath { get; } - public string GitExecutable { get; } - public NPath GitExecutablePath { get; } - public string GitLfsExecutable { get; } - public NPath GitLfsExecutablePath { get; } - public UriString GitZipMd5Url { get; set; } = DefaultGitZipMd5Url; - public UriString GitZipUrl { get; set; } = DefaultGitZipUrl; - public UriString GitLfsZipMd5Url { get; set; } = DefaultGitLfsZipMd5Url; - public UriString GitLfsZipUrl { get; set; } = DefaultGitLfsZipUrl; - public string PackageNameWithVersion => PackageName + "_" + PackageVersion; } } -} diff --git a/src/GitHub.Api/Installer/IZipHelper.cs b/src/GitHub.Api/Installer/IZipHelper.cs index a536dcadf..969d9e35c 100644 --- a/src/GitHub.Api/Installer/IZipHelper.cs +++ b/src/GitHub.Api/Installer/IZipHelper.cs @@ -5,7 +5,7 @@ namespace GitHub.Unity { interface IZipHelper { - void Extract(string archive, string outFolder, CancellationToken cancellationToken, + bool Extract(string archive, string outFolder, CancellationToken cancellationToken, Func onProgress = null); } } diff --git a/src/GitHub.Api/Installer/UnzipTask.cs b/src/GitHub.Api/Installer/UnzipTask.cs index 13620cd45..012fc6629 100644 --- a/src/GitHub.Api/Installer/UnzipTask.cs +++ b/src/GitHub.Api/Installer/UnzipTask.cs @@ -4,7 +4,7 @@ namespace GitHub.Unity { - class UnzipTask: TaskBase + class UnzipTask : TaskBase { private readonly string archiveFilePath; private readonly NPath extractedPath; @@ -12,13 +12,13 @@ class UnzipTask: TaskBase private readonly IFileSystem fileSystem; private readonly string expectedMD5; - public UnzipTask(CancellationToken token, string archiveFilePath, NPath extractedPath, IFileSystem fileSystem, string expectedMD5 = null) : + public UnzipTask(CancellationToken token, NPath archiveFilePath, NPath extractedPath, IFileSystem fileSystem, string expectedMD5 = null) : this(token, archiveFilePath, extractedPath, ZipHelper.Instance, fileSystem, expectedMD5) { } - public UnzipTask(CancellationToken token, string archiveFilePath, NPath extractedPath, IZipHelper zipHelper, IFileSystem fileSystem, string expectedMD5 = null) + public UnzipTask(CancellationToken token, NPath archiveFilePath, NPath extractedPath, IZipHelper zipHelper, IFileSystem fileSystem, string expectedMD5 = null) : base(token) { this.archiveFilePath = archiveFilePath; @@ -26,22 +26,23 @@ public UnzipTask(CancellationToken token, string archiveFilePath, NPath extracte this.zipHelper = zipHelper; this.fileSystem = fileSystem; this.expectedMD5 = expectedMD5; + Name = $"Unzip {archiveFilePath.FileName}"; } - protected void BaseRun(bool success) + protected NPath BaseRun(bool success) { - base.Run(success); + return base.RunWithReturn(success); } - protected override void Run(bool success) + protected override NPath RunWithReturn(bool success) { - BaseRun(success); + var ret = BaseRun(success); RaiseOnStart(); try { - RunUnzip(success); + ret = RunUnzip(success); } catch (Exception ex) { @@ -51,11 +52,12 @@ protected override void Run(bool success) } finally { - RaiseOnEnd(); + RaiseOnEnd(ret); } + return ret; } - protected virtual void RunUnzip(bool success) + protected virtual NPath RunUnzip(bool success) { Logger.Trace("Unzip File: {0} to Path: {1}", archiveFilePath, extractedPath); @@ -69,7 +71,7 @@ protected virtual void RunUnzip(bool success) exception = null; try { - zipHelper.Extract(archiveFilePath, extractedPath, Token, zipFileProgress, estimatedDurationProgress); + success = zipHelper.Extract(archiveFilePath, extractedPath, Token, (value, total) => { UpdateProgress(value, total); @@ -103,6 +105,7 @@ protected virtual void RunUnzip(bool success) Token.ThrowIfCancellationRequested(); throw new UnzipException("Error unzipping file", exception); } + return extractedPath; } protected int RetryCount { get; } } diff --git a/src/GitHub.Api/Installer/ZipHelper.cs b/src/GitHub.Api/Installer/ZipHelper.cs index 2e37a952a..769a34b74 100644 --- a/src/GitHub.Api/Installer/ZipHelper.cs +++ b/src/GitHub.Api/Installer/ZipHelper.cs @@ -3,6 +3,8 @@ using System.IO; using System.Threading; using ICSharpCode.SharpZipLib.Zip; +using GitHub.Logging; +using System.Collections.Generic; namespace GitHub.Unity { @@ -23,18 +25,17 @@ public static IZipHelper Instance } } - public void Extract(string archive, string outFolder, CancellationToken cancellationToken, + public bool Extract(string archive, string outFolder, CancellationToken cancellationToken, Func onProgress = null) { - ExtractZipFile(archive, outFolder, cancellationToken, onProgress); + return ExtractZipFile(archive, outFolder, cancellationToken, onProgress); } - public static void ExtractZipFile(string archive, string outFolder, CancellationToken cancellationToken, + public static bool ExtractZipFile(string archive, string outFolder, CancellationToken cancellationToken, Func onProgress) { const int chunkSize = 4096; // 4K is optimum ZipFile zf = null; - var startTime = DateTime.Now; var processed = 0; var totalBytes = 0L; @@ -42,15 +43,23 @@ public static void ExtractZipFile(string archive, string outFolder, Cancellation { var fs = File.OpenRead(archive); zf = new ZipFile(fs); - var totalSize = fs.Length; + long totalSize = 0; + var entries = new List((int)zf.Count); foreach (ZipEntry zipEntry in zf) { - cancellationToken.ThrowIfCancellationRequested(); if (zipEntry.IsDirectory) { continue; // Ignore directories } + entries.Add(zipEntry); + totalSize += zipEntry.Size; + } + + for (var i = 0; i < entries.Count; i++) + { + var zipEntry = entries[i]; + cancellationToken.ThrowIfCancellationRequested(); var entryFileName = zipEntry.Name; // to remove the folder from the entry:- entryFileName = Path.GetFileName(entryFileName); @@ -65,18 +74,18 @@ public static void ExtractZipFile(string archive, string outFolder, Cancellation { Directory.CreateDirectory(directoryName); } -//#if !WINDOWS -// if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX) -// { -// if (zipEntry.ExternalFileAttributes > 0) -// { -// int fd = Mono.Unix.Native.Syscall.open(fullZipToPath, -// Mono.Unix.Native.OpenFlags.O_CREAT | Mono.Unix.Native.OpenFlags.O_TRUNC, -// (Mono.Unix.Native.FilePermissions)zipEntry.ExternalFileAttributes); -// Mono.Unix.Native.Syscall.close(fd); -// } -// } -//#endif + //#if !WINDOWS + // if (Environment.OSVersion.Platform == PlatformID.Unix || Environment.OSVersion.Platform == PlatformID.MacOSX) + // { + // if (zipEntry.ExternalFileAttributes > 0) + // { + // int fd = Mono.Unix.Native.Syscall.open(fullZipToPath, + // Mono.Unix.Native.OpenFlags.O_CREAT | Mono.Unix.Native.OpenFlags.O_TRUNC, + // (Mono.Unix.Native.FilePermissions)zipEntry.ExternalFileAttributes); + // Mono.Unix.Native.Syscall.close(fd); + // } + // } + //#endif // Unzip file in buffered chunks. This is just as fast as unpacking to a buffer the full size // of the file, but does not waste memory. @@ -85,17 +94,23 @@ public static void ExtractZipFile(string archive, string outFolder, Cancellation using (var streamWriter = targetFile.OpenWrite()) { if (!Utils.Copy(zipStream, streamWriter, zipEntry.Size, chunkSize, - progress: (totalRead, timeToFinish) => { + progress: (totalRead, timeToFinish) => + { totalBytes += totalRead; return onProgress(totalBytes, totalSize); })) - return; + return false; } targetFile.LastWriteTime = zipEntry.DateTime; processed++; } } + catch (Exception ex) + { + LogHelper.GetLogger().Error(ex); + return false; + } finally { if (zf != null) @@ -104,6 +119,7 @@ public static void ExtractZipFile(string archive, string outFolder, Cancellation zf.Close(); // Ensure we release resources } } + return true; } } } diff --git a/src/GitHub.Api/Tasks/DownloadTask.cs b/src/GitHub.Api/Tasks/DownloadTask.cs index b253c0ec8..b66bd1d60 100644 --- a/src/GitHub.Api/Tasks/DownloadTask.cs +++ b/src/GitHub.Api/Tasks/DownloadTask.cs @@ -41,7 +41,7 @@ public DownloadTask(CancellationToken token, Url = url; Filename = filename ?? url.Filename; TargetDirectory = targetDirectory ?? NPath.CreateTempDirectory("ghu"); - Name = nameof(DownloadTask); + this.Name = $"Download {Url}"; } protected string BaseRunWithReturn(bool success) diff --git a/src/GitHub.Api/Tasks/TaskBase.cs b/src/GitHub.Api/Tasks/TaskBase.cs index a86bb48f2..efea6e506 100644 --- a/src/GitHub.Api/Tasks/TaskBase.cs +++ b/src/GitHub.Api/Tasks/TaskBase.cs @@ -28,7 +28,7 @@ public interface ITask : IAsyncResult /// /// Run another task at the end of the task execution, on a separate thread, regardless of execution state /// - ITask Finally(T taskToContinueWith) where T : ITask; + T Finally(T taskToContinueWith) where T : ITask; ITask Start(); ITask Start(TaskScheduler scheduler); ITask Progress(Action progressHandler); @@ -48,6 +48,8 @@ public interface ITask : IAsyncResult /// /// true if any task on the chain is marked as exclusive bool IsChainExclusive(); + + void UpdateProgress(long value, long total, string message = null); } public interface ITask : ITask @@ -101,9 +103,8 @@ public abstract class TaskBase : ITask protected event Func catchHandler; private event Action finallyHandler; - protected event Action progressHandler; - private Progress progress; + protected Progress progress; protected TaskBase(CancellationToken token) : this() @@ -236,14 +237,14 @@ public ITask Finally(Action actionToContinueWith, TaskAffinity /// /// Run another task at the end of the task execution, on a separate thread, regardless of execution state /// - public ITask Finally(T taskToContinueWith) + public T Finally(T taskToContinueWith) where T : ITask { Guard.ArgumentNotNull(taskToContinueWith, nameof(taskToContinueWith)); continuationOnAlways = (TaskBase)(object)taskToContinueWith; continuationOnAlways.SetDependsOn(this); DependsOn?.SetFaultHandler(continuationOnAlways); - return continuationOnAlways; + return taskToContinueWith; } /// @@ -266,7 +267,7 @@ internal void SetFaultHandler(TaskBase handler) public ITask Progress(Action handler) { Guard.ArgumentNotNull(handler, nameof(handler)); - this.progressHandler += handler; + progress.OnProgress += handler; return this; } @@ -437,10 +438,9 @@ protected Exception GetThrownException() return DependsOn.GetThrownException(); } - protected void UpdateProgress(long value, long total) + public void UpdateProgress(long value, long total, string message = null) { - progress.UpdateProgress(value, total); - progressHandler?.Invoke(progress); + progress.UpdateProgress(value, total, message); } public override string ToString() @@ -596,8 +596,7 @@ public ITask Finally(Action continuation, TaskAffinity /// public new ITask Progress(Action handler) { - Guard.ArgumentNotNull(handler, nameof(handler)); - this.progressHandler += handler; + base.Progress(handler); return this; } diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/Spinner.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/Spinner.cs index 33bf1708a..3af1c08c7 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/Spinner.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/Spinner.cs @@ -130,10 +130,10 @@ public void Render() GUI.matrix = matrix; } - private void PushRotation(float rotation, Vector2 center) + private void PushRotation(float rotation, Vector2 rotCenter) { - rotations.Push(new Rotation(rotation, center)); - GUIUtility.RotateAroundPivot(rotation, center); + rotations.Push(new Rotation(rotation, rotCenter)); + GUIUtility.RotateAroundPivot(rotation, rotCenter); } private void PopRotation() diff --git a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/Window.cs b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/Window.cs index 15ca9dc02..13a3d6118 100644 --- a/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/Window.cs +++ b/src/UnityExtension/Assets/Editor/GitHub.Unity/UI/Window.cs @@ -355,9 +355,9 @@ private void RepositoryOnCurrentBranchAndRemoteChanged(CacheUpdateEvent cacheUpd } } - private void OnProgress(IProgress progress) + private void OnProgress(IProgress progr) { - this.progress = progress; + progress = progr; } private void DetachHandlers(IRepository repository) diff --git a/src/tests/IntegrationTests/BasePlatformIntegrationTest.cs b/src/tests/IntegrationTests/BasePlatformIntegrationTest.cs index f943fed7b..f0d4089f8 100644 --- a/src/tests/IntegrationTests/BasePlatformIntegrationTest.cs +++ b/src/tests/IntegrationTests/BasePlatformIntegrationTest.cs @@ -33,22 +33,21 @@ protected void InitializePlatform(NPath repoPath, NPath environmentPath, bool en var installDetails = new GitInstaller.GitInstallDetails(applicationDataPath, true); var zipArchivesPath = TestBasePath.Combine("ZipArchives").CreateDirectory(); - var gitArchivePath = AssemblyResources.ToFile(ResourceType.Platform, "git.zip", zipArchivesPath, Environment); - var gitLfsArchivePath = AssemblyResources.ToFile(ResourceType.Platform, "git-lfs.zip", zipArchivesPath, Environment); + AssemblyResources.ToFile(ResourceType.Platform, "git.zip", zipArchivesPath, Environment); + AssemblyResources.ToFile(ResourceType.Platform, "git-lfs.zip", zipArchivesPath, Environment); - var gitInstaller = new GitInstaller(Environment, TaskManager.Token, installDetails, gitArchivePath, gitLfsArchivePath); + var gitInstaller = new GitInstaller(Environment, TaskManager.Token, installDetails); NPath result = null; Exception ex = null; - gitInstaller.SetupGitIfNeeded(new ActionTask(TaskManager.Token, (b, path) => { - result = path; - autoResetEvent.Set(); - }), - new ActionTask(TaskManager.Token, (b, exception) => { - ex = exception; - autoResetEvent.Set(); - })); + var setupTask = gitInstaller.SetupGitIfNeeded(); + setupTask.OnEnd += (thisTask, path, success, exception) => + { + result = path; + ex = exception; + autoResetEvent.Set(); + }; autoResetEvent.WaitOne(); diff --git a/src/tests/IntegrationTests/Installer/GitInstallerTests.cs b/src/tests/IntegrationTests/Installer/GitInstallerTests.cs index e13cde9a8..2d3d0b198 100644 --- a/src/tests/IntegrationTests/Installer/GitInstallerTests.cs +++ b/src/tests/IntegrationTests/Installer/GitInstallerTests.cs @@ -50,34 +50,11 @@ public void GitInstallTest() TestBasePath.Combine("git").CreateDirectory(); - //var gitArchivePath = AssemblyResources.ToFile(ResourceType.Platform, "git.zip", zipArchivesPath, Environment); - //var gitLfsArchivePath = AssemblyResources.ToFile(ResourceType.Platform, "git-lfs.zip", zipArchivesPath, Environment); - var gitInstaller = new GitInstaller(Environment, CancellationToken.None, installDetails); - var autoResetEvent = new AutoResetEvent(false); - - bool? result = null; NPath resultPath = null; - Exception ex = null; - - gitInstaller.SetupGitIfNeeded(new ActionTask(CancellationToken.None, (b, path) => { - result = true; - resultPath = path; - autoResetEvent.Set(); - }), - new ActionTask(CancellationToken.None, (b, exception) => { - result = false; - ex = exception; - autoResetEvent.Set(); - })); - - autoResetEvent.WaitOne(); - - result.HasValue.Should().BeTrue(); - result.Value.Should().BeTrue(); + Assert.DoesNotThrow(async () => resultPath = await gitInstaller.SetupGitIfNeeded().Task); resultPath.Should().NotBeNull(); - ex.Should().BeNull(); } } } \ No newline at end of file diff --git a/src/tests/IntegrationTests/UnzipTaskTests.cs b/src/tests/IntegrationTests/UnzipTaskTests.cs index 0aac87a1a..da788ec95 100644 --- a/src/tests/IntegrationTests/UnzipTaskTests.cs +++ b/src/tests/IntegrationTests/UnzipTaskTests.cs @@ -26,7 +26,7 @@ public async Task UnzipWorks() var extractedPath = TestBasePath.Combine("gitlfs_zip_extracted").CreateDirectory(); - var unzipTask = new UnzipTask(CancellationToken.None, archiveFilePath, extractedPath, Environment.FileSystem, GitInstallDetails.GitExtractedMD5) + var unzipTask = new UnzipTask(CancellationToken.None, archiveFilePath, extractedPath, Environment.FileSystem, GitInstaller.GitInstallDetails.GitExtractedMD5) .Progress(p => { }); From 4c1d33c6cf75a734febc4673a7b93b9a94185467 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Mon, 5 Mar 2018 17:18:08 +0100 Subject: [PATCH 089/873] This might be accessed before things have a chance to initialize --- src/GitHub.Api/Application/ApplicationManagerBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GitHub.Api/Application/ApplicationManagerBase.cs b/src/GitHub.Api/Application/ApplicationManagerBase.cs index 418b5662f..c425c9322 100644 --- a/src/GitHub.Api/Application/ApplicationManagerBase.cs +++ b/src/GitHub.Api/Application/ApplicationManagerBase.cs @@ -247,7 +247,7 @@ public void Dispose() public ISettings SystemSettings { get; protected set; } public ISettings UserSettings { get; protected set; } public IUsageTracker UsageTracker { get; protected set; } - public bool IsBusy { get { return isBusy || RepositoryManager.IsBusy; } } + public bool IsBusy { get { return isBusy || (RepositoryManager?.IsBusy ?? false); } } protected TaskScheduler UIScheduler { get; private set; } protected SynchronizationContext SynchronizationContext { get; private set; } protected IRepositoryManager RepositoryManager { get { return repositoryManager; } } From a85058433934b016b4beabee9a3c741420bee3e1 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Mon, 5 Mar 2018 17:18:15 +0100 Subject: [PATCH 090/873] Remove debug output --- src/GitHub.Api/Tasks/ConcurrentExclusiveInterleave.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/GitHub.Api/Tasks/ConcurrentExclusiveInterleave.cs b/src/GitHub.Api/Tasks/ConcurrentExclusiveInterleave.cs index 47e2cd871..33c5576b8 100644 --- a/src/GitHub.Api/Tasks/ConcurrentExclusiveInterleave.cs +++ b/src/GitHub.Api/Tasks/ConcurrentExclusiveInterleave.cs @@ -158,8 +158,6 @@ internal void NotifyOfNewWork() /// This has been separated out into its own method to improve the Parallel Tasks window experience. private void ConcurrentExclusiveInterleaveProcessor() { - Logging.LogHelper.GetLogger().Trace("ConcurrentExclusiveInterleaveProcessor"); - if (token.IsCancellationRequested) return; interleaveTaskScheduler.ThreadToExclude = Thread.CurrentThread.ManagedThreadId; From 447fd9c188c17f54ae932481f3d9727a0a95497d Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Mon, 5 Mar 2018 18:14:48 +0100 Subject: [PATCH 091/873] Replay any cache invalidation requests that happen before RepositoryManager is set --- .../Application/ApplicationManagerBase.cs | 1 + src/GitHub.Api/Git/IRepository.cs | 1 + src/GitHub.Api/Git/Repository.cs | 21 +++++++++++++++++-- src/GitHub.Api/Git/RepositoryManager.cs | 4 ++-- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/GitHub.Api/Application/ApplicationManagerBase.cs b/src/GitHub.Api/Application/ApplicationManagerBase.cs index c425c9322..d0658227a 100644 --- a/src/GitHub.Api/Application/ApplicationManagerBase.cs +++ b/src/GitHub.Api/Application/ApplicationManagerBase.cs @@ -150,6 +150,7 @@ public void RestartRepository() repositoryManager.Initialize(); Environment.Repository.Initialize(repositoryManager); repositoryManager.Start(); + Environment.Repository.Start(); Logger.Trace($"Got a repository? {Environment.Repository}"); } } diff --git a/src/GitHub.Api/Git/IRepository.cs b/src/GitHub.Api/Git/IRepository.cs index 7acf918f0..46a959d87 100644 --- a/src/GitHub.Api/Git/IRepository.cs +++ b/src/GitHub.Api/Git/IRepository.cs @@ -78,5 +78,6 @@ public interface IRepository : IEquatable event Action LocksChanged; event Action RemoteBranchListChanged; event Action LocalAndRemoteBranchListChanged; + void Start(); } } \ No newline at end of file diff --git a/src/GitHub.Api/Git/Repository.cs b/src/GitHub.Api/Git/Repository.cs index 8157753d3..89e4f088a 100644 --- a/src/GitHub.Api/Git/Repository.cs +++ b/src/GitHub.Api/Git/Repository.cs @@ -15,6 +15,7 @@ class Repository : IEquatable, IRepository private ICacheContainer cacheContainer; private UriString cloneUrl; private string name; + private HashSet cacheInvalidationRequests = new HashSet(); public event Action LogChanged; public event Action TrackingStatusChanged; @@ -39,7 +40,7 @@ public Repository(NPath localPath, ICacheContainer container) LocalPath = localPath; cacheContainer = container; - cacheContainer.CacheInvalidated += CacheContainer_OnCacheInvalidated; + cacheContainer.CacheInvalidated += InvalidateCache; cacheContainer.CacheUpdated += CacheContainer_OnCacheUpdated; } @@ -58,6 +59,14 @@ public void Initialize(IRepositoryManager initRepositoryManager) repositoryManager.RemoteBranchesUpdated += RepositoryManagerOnRemoteBranchesUpdated; } + public void Start() + { + foreach (var req in cacheInvalidationRequests) + { + InvalidateCache(req); + } + } + public ITask SetupRemote(string remote, string remoteUrl) { Guard.ArgumentNotNullOrWhiteSpace(remote, "remote"); @@ -275,8 +284,16 @@ private void CheckBranchCacheEvent(CacheUpdateEvent cacheUpdateEvent) } } - private void CacheContainer_OnCacheInvalidated(CacheType cacheType) + private void InvalidateCache(CacheType cacheType) { + if (repositoryManager == null) + { + if (!cacheInvalidationRequests.Contains(cacheType)) + cacheInvalidationRequests.Add(cacheType); + return; + } + + switch (cacheType) { case CacheType.BranchCache: diff --git a/src/GitHub.Api/Git/RepositoryManager.cs b/src/GitHub.Api/Git/RepositoryManager.cs index cdbb4bff7..e70d587e7 100644 --- a/src/GitHub.Api/Git/RepositoryManager.cs +++ b/src/GitHub.Api/Git/RepositoryManager.cs @@ -42,11 +42,11 @@ public interface IRepositoryManager : IDisposable void UpdateGitAheadBehindStatus(); void UpdateLocks(); int WaitForEvents(); + void UpdateRepositoryInfo(); IGitConfig Config { get; } IGitClient GitClient { get; } bool IsBusy { get; } - void UpdateRepositoryInfo(); } interface IRepositoryPathConfiguration @@ -400,7 +400,7 @@ private ITask HookupHandlers(ITask task, bool filesystemChangesExpected) var isExclusive = task.IsChainExclusive(); task.GetTopOfChain().OnStart += t => { - if (t.Affinity == TaskAffinity.Exclusive) + if (isExclusive) { Logger.Trace("Starting Operation - Setting Busy Flag"); IsBusy = true; From 6d17c4ba6a13fd58e581d7ca90e43e0a2cadbe4f Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Mon, 5 Mar 2018 18:52:05 +0100 Subject: [PATCH 092/873] Fix setting busy flag when tasks are done --- src/GitHub.Api/Tasks/ProcessTask.cs | 33 +++++++++++++++++++---------- src/GitHub.Api/Tasks/TaskBase.cs | 14 ++++++------ 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/GitHub.Api/Tasks/ProcessTask.cs b/src/GitHub.Api/Tasks/ProcessTask.cs index f02821999..7388cd428 100644 --- a/src/GitHub.Api/Tasks/ProcessTask.cs +++ b/src/GitHub.Api/Tasks/ProcessTask.cs @@ -101,6 +101,8 @@ public void Run() try { + if (!Process.StartInfo.Arguments.StartsWith("credential-")) + Logger.Trace($"Running '{Process.StartInfo.FileName} {Process.StartInfo.Arguments}'"); Process.Start(); } catch (Win32Exception ex) @@ -286,20 +288,29 @@ protected override T RunWithReturn(bool success) RaiseOnStart, () => { - if (outputProcessor != null) - result = outputProcessor.Result; + try + { + if (outputProcessor != null) + result = outputProcessor.Result; - if (result == null && !Process.StartInfo.CreateNoWindow && typeof(T) == typeof(string)) - result = (T)(object)"Process running"; + if (result == null && !Process.StartInfo.CreateNoWindow && typeof(T) == typeof(string)) + result = (T)(object)"Process running"; - RaiseOnEnd(result); - - if (Errors != null) - { - OnErrorData?.Invoke(Errors); - thrownException = thrownException ?? new ProcessException(this); - if (!RaiseFaultHandlers(thrownException)) + if (Errors != null) + { + OnErrorData?.Invoke(Errors); + thrownException = thrownException ?? new ProcessException(this); throw thrownException; + } + } + catch (Exception ex) + { + if (!RaiseFaultHandlers(ex)) + throw ex; + } + finally + { + RaiseOnEnd(result); } }, (ex, error) => diff --git a/src/GitHub.Api/Tasks/TaskBase.cs b/src/GitHub.Api/Tasks/TaskBase.cs index efea6e506..42e5f7d25 100644 --- a/src/GitHub.Api/Tasks/TaskBase.cs +++ b/src/GitHub.Api/Tasks/TaskBase.cs @@ -387,16 +387,16 @@ protected virtual void RaiseOnEnd() OnEnd?.Invoke(this, !taskFailed, exception); if (!taskFailed || exceptionWasHandled) { - if (continuationOnSuccess == null && continuationOnAlways == null) + if (continuationOnSuccess == null) CallFinallyHandler(); - else if (continuationOnSuccess != null) + else SetContinuation(continuationOnSuccess, runOnSuccessOptions); } else { - if (continuationOnFailure == null && continuationOnAlways == null) + if (continuationOnFailure == null) CallFinallyHandler(); - else if (continuationOnFailure != null) + else SetContinuation(continuationOnFailure, runOnSuccessOptions); } //Logger.Trace($"Finished {ToString()}"); @@ -404,7 +404,7 @@ protected virtual void RaiseOnEnd() protected void CallFinallyHandler() { - finallyHandler?.Invoke(Task.Status == TaskStatus.RanToCompletion); + finallyHandler?.Invoke(!taskFailed); } protected virtual bool RaiseFaultHandlers(Exception ex) @@ -617,9 +617,9 @@ protected virtual void RaiseOnEnd(TResult data) { this.result = data; OnEnd?.Invoke(this, result, !taskFailed, exception); - if (continuationOnSuccess == null && continuationOnFailure == null && continuationOnAlways == null) + if (continuationOnSuccess == null && continuationOnFailure == null) { - finallyHandler?.Invoke(Task.Status == TaskStatus.RanToCompletion, result); + finallyHandler?.Invoke(!taskFailed, result); CallFinallyHandler(); } else if (continuationOnSuccess != null) From 95449aa1f803950ed95393540b6a2fc2c548d817 Mon Sep 17 00:00:00 2001 From: Andreia Gaita Date: Mon, 5 Mar 2018 18:54:48 +0100 Subject: [PATCH 093/873] Fix the error and end pattern of process task --- src/GitHub.Api/Tasks/ProcessTask.cs | 33 ++++++++++++++++++----------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/GitHub.Api/Tasks/ProcessTask.cs b/src/GitHub.Api/Tasks/ProcessTask.cs index 7388cd428..894526044 100644 --- a/src/GitHub.Api/Tasks/ProcessTask.cs +++ b/src/GitHub.Api/Tasks/ProcessTask.cs @@ -306,7 +306,7 @@ protected override T RunWithReturn(bool success) catch (Exception ex) { if (!RaiseFaultHandlers(ex)) - throw ex; + throw; } finally { @@ -420,19 +420,28 @@ protected override List RunWithReturn(bool success) RaiseOnStart, () => { - if (outputProcessor != null) - result = outputProcessor.Result; - if (result == null) - result = new List(); - - RaiseOnEnd(result); - - if (Errors != null) + try { - OnErrorData?.Invoke(Errors); - thrownException = thrownException ?? new ProcessException(this); - if (!RaiseFaultHandlers(thrownException)) + if (outputProcessor != null) + result = outputProcessor.Result; + if (result == null) + result = new List(); + + if (Errors != null) + { + OnErrorData?.Invoke(Errors); + thrownException = thrownException ?? new ProcessException(this); throw thrownException; + } + } + catch (Exception ex) + { + if (!RaiseFaultHandlers(ex)) + throw; + } + finally + { + RaiseOnEnd(result); } }, (ex, error) => From f09a6687594c2440f9ca284573f407b5e0bf0722 Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Mon, 5 Mar 2018 18:12:27 -0500 Subject: [PATCH 094/873] Completed functionality to use octorun js --- octorun/bin/octorun | 2 - octorun/src/authentication.js | 176 ++++++------------ octorun/src/bin/app-login.js | 122 ++++++++++-- octorun/src/bin/app-usage.js | 77 +++++--- src/GitHub.Api/Authentication/LoginManager.cs | 87 ++++----- 5 files changed, 246 insertions(+), 218 deletions(-) diff --git a/octorun/bin/octorun b/octorun/bin/octorun index 9c031d64f..b6623d43e 100644 --- a/octorun/bin/octorun +++ b/octorun/bin/octorun @@ -1,5 +1,3 @@ #!/usr/bin/env node -process.stdout.write("node:", process.argv[0]); - require('../src/bin/app.js'); diff --git a/octorun/src/authentication.js b/octorun/src/authentication.js index a8cdda693..ab851c01f 100644 --- a/octorun/src/authentication.js +++ b/octorun/src/authentication.js @@ -1,136 +1,66 @@ +var endOfLine = require('os').EOL; var config = require("./configuration"); var octokitWrapper = require("./octokit"); var scopes = ["user", "repo", "gist", "write:public_key"]; -var stdIn = process.openStdin(); - -var awaiter = null; - -stdIn.addListener("data", function (d) { - var content = d.toString().trim(); - - if (awaiter) { - var _awaiter = awaiter; - awaiter = null; - _awaiter(content); - } -}); - -var handleBasicAuthentication = function (onSuccess, onRequiresTwoFa, onFailure) { - var username = null; - var password = null; - - var withPassword = function (input) { - password = input; - - var octokit = octokitWrapper.createOctokit(); - - octokit.authenticate({ - type: "basic", - username: username, - password: password - }); - - octokit.authorization.create({ - scopes: scopes, - note: config.appName, - client_id: config.clientId, - client_secret: config.clientSecret - }, function (err, res) { - if (err) { - if (err.message === '{"message":"Must specify two-factor authentication OTP code.","documentation_url":"https://developer.github.com/v3/auth#working-with-two-factor-authentication"}') { - onRequiresTwoFa(); - return; - } - else { - onFailure(err) - } +var lockedRegex = new RegExp("number of login attempts exceeded", "gi"); +var twoFactorRegex = new RegExp("must specify two-factor authentication OTP code", "gi"); + +var handleBasicAuthentication = function (username, password, onSuccess, onRequiresTwoFa, onLocked, onFailure) { + var octokit = octokitWrapper.createOctokit(); + + octokit.authenticate({ + type: "basic", + username: username, + password: password + }); + + octokit.authorization.create({ + scopes: scopes, + note: config.appName, + client_id: config.clientId, + client_secret: config.clientSecret + }, function (err, res) { + if (err) { + if (twoFactorRegex.test(err.message)) { + onRequiresTwoFa(); } else { - onSuccess(res.data.token); - } - }); - } - - var promptPassword = function () { - process.stdout.write("Password: "); - awaiter = withPassword; - } - - var withUser = function (input) { - username = input; - promptPassword(); - } - - var promptUser = function () { - process.stdout.write("Username: "); - awaiter = withUser; - } - - promptUser(); -} - -var handleTwoFactorAuthentication = function (onSuccess, onFailure) { - var username = null; - var password = null; - var twoFactor = null; - - var withTwoFactor = function (input) { - twoFactor = input; - - var octokit = octokitWrapper.createOctokit(); - - octokit.authenticate({ - type: "basic", - username: username, - password: password - }); - - octokit.authorization.create({ - scopes: scopes, - note: config.appName, - client_id: config.clientId, - client_secret: config.clientSecret, - headers: { - "X-GitHub-OTP": twoFactor - } - }, function (err, res) { - if (err) { onFailure(err) } - else { - onSuccess(res.data.token); - } - }); - } - - var promptTwoFactor = function () { - process.stdout.write("Two Factor: "); - awaiter = withTwoFactor; - } - - var withPassword = function (input) { - password = input; - promptTwoFactor(); - } - - var promptPassword = function () { - process.stdout.write("Password: "); - awaiter = withPassword; - } - - var withUser = function (input) { - username = input; - promptPassword(); - } - - var promptUser = function () { - process.stdout.write("Username: "); - awaiter = withUser; - } + } + else { + onSuccess(res.data.token); + } + }); +} - promptUser(); +var handleTwoFactorAuthentication = function (username, password, twoFactor, onSuccess, onLocked, onFailure) { + var octokit = octokitWrapper.createOctokit(); + + octokit.authenticate({ + type: "basic", + username: username, + password: password + }); + + octokit.authorization.create({ + scopes: scopes, + note: config.appName, + client_id: config.clientId, + client_secret: config.clientSecret, + headers: { + "X-GitHub-OTP": twoFactor + } + }, function (err, res) { + if (err) { + onFailure(err) + } + else { + onSuccess(res.data.token); + } + }); } module.exports = { diff --git a/octorun/src/bin/app-login.js b/octorun/src/bin/app-login.js index f90504f25..b763e3957 100644 --- a/octorun/src/bin/app-login.js +++ b/octorun/src/bin/app-login.js @@ -2,29 +2,117 @@ var commander = require("commander"); var package = require('../../package.json') var authentication = require('../authentication') +var endOfLine = require('os').EOL; + commander .version(package.version) .option('-t, --twoFactor') .parse(process.argv); +var encoding = 'utf-8'; + if (commander.twoFactor) { - authentication.handleTwoFactorAuthentication(function (token) { - process.stdout.write(token); - process.exit(); - }, function (err) { - process.stdout.write(err); - process.exit(); - }); + var handleTwoFactorAuthentication = function (username, password, token) { + authentication.handleTwoFactorAuthentication(username, password, token, function (token) { + process.stdout.write(token); + process.stdout.write(endOfLine); + process.exit(); + }, function () { + process.stdout.write("Account locked."); + process.stdout.write(endOfLine); + process.exit(); + }, function (err) { + process.stdout.write("Error"); + process.stdout.write(endOfLine); + process.stdout.write(err); + process.stdout.write(endOfLine); + process.exit(); + }); + } + + if (process.stdin.isTTY) { + var readlineSync = require("readline-sync"); + var username = readlineSync.question('User: '); + var password = readlineSync.question('Password: ', { + hideEchoBack: true + }); + + var twoFactor = readlineSync.question('Two Factor: '); + + handleTwoFactorAuthentication(username, password, twoFactor); + } + else { + var data = ''; + process.stdin.setEncoding(encoding); + + process.stdin.on('readable', function () { + var chunk; + while (chunk = process.stdin.read()) { + data += chunk; + } + }); + + process.stdin.on('end', function () { + var items = data.toString() + .split(/\r?\n/) + .filter(function (item) { return item; }); + + handleTwoFactorAuthentication(items[0], items[1], items[2]); + }); + } } else { - authentication.handleBasicAuthentication(function (token) { - process.stdout.write(token); - process.exit(); - }, function () { - process.stdout.write("Must specify two-factor authentication OTP code."); - process.exit(); - }, function (err) { - process.stdout.write(err); - process.exit(); - }); + + var handleTwoFactorAuthentication = function (username, password) { + authentication.handleBasicAuthentication(username, password, + function (token) { + process.stdout.write(token); + process.stdout.write(endOfLine); + process.exit(); + }, function () { + process.stdout.write("Must specify two-factor authentication OTP code."); + process.stdout.write(endOfLine); + process.exit(); + }, function () { + process.stdout.write("Account locked."); + process.stdout.write(endOfLine); + process.exit(); + }, function (err) { + process.stdout.write("Error"); + process.stdout.write(endOfLine); + process.stdout.write(err); + process.stdout.write(endOfLine); + process.exit(); + }); + } + + if (process.stdin.isTTY) { + var readlineSync = require("readline-sync"); + + var username = readlineSync.question('User: '); + var password = readlineSync.question('Password: ', { + hideEchoBack: true + }); + + handleTwoFactorAuthentication(username, password); + } + else { + var data = ''; + process.stdin.setEncoding(encoding); + + process.stdin.on('readable', function () { + var chunk; + while (chunk = process.stdin.read()) { + data += chunk; + } + }); + + process.stdin.on('end', function () { + var items = data.toString() + .split(/\r?\n/) + .filter(function (item) { return item; }); + + handleTwoFactorAuthentication(items[0], items[1]); + }); + } } \ No newline at end of file diff --git a/octorun/src/bin/app-usage.js b/octorun/src/bin/app-usage.js index a6279e411..6a00d2772 100644 --- a/octorun/src/bin/app-usage.js +++ b/octorun/src/bin/app-usage.js @@ -1,42 +1,67 @@ var commander = require("commander"); var package = require('../../package.json') -var readlineSync = require("readline-sync"); var endOfLine = require('os').EOL; commander .version(package.version) .parse(process.argv); -var postData = readlineSync.question(); +var processData = function (postData) { + var https = require('https'); -var https = require('https'); + var options = { + hostname: 'central.github.com', + path: '/api/usage/unity', + method: 'POST', + headers: { + 'Content-Type': 'application/json' + } + }; -var options = { - hostname: 'central.github.com', - path: '/api/usage/unity', - method: 'POST', - headers: { - 'Content-Type': 'application/json' - } -}; + var req = https.request(options, function (res) { + process.stdout.write('statusCode:', res.statusCode); -var req = https.request(options, function (res) { - process.stdout.write('statusCode:', res.statusCode); + res.on('data', function (d) { + process.stdout.write(d); + process.stdout.write(endOfLine); + }); - res.on('data', function (d) { - process.stdout.write(d); - process.stdout.write(endOfLine); + res.on('end', function (d) { + process.exit(); + }); }); - - res.on('end', function (d) { - process.exit(); + + req.on('error', function (e) { + console.error(e); + process.exit(-1); }); -}); -req.on('error', function (e) { - console.error(e); - process.exit(-1); -}); + req.write(postData); + req.end(); +} + +if (process.stdin.isTTY) { + var readlineSync = require("readline-sync"); + var postData = readlineSync.question(); -req.write(postData); -req.end(); \ No newline at end of file + processData(postData); +} +else { + var data = ''; + process.stdin.setEncoding(encoding); + + process.stdin.on('readable', function () { + var chunk; + while (chunk = process.stdin.read()) { + data += chunk; + } + }); + + process.stdin.on('end', function () { + var items = data.toString() + .split(/\r?\n/) + .filter(function (item) { return item; }); + + processData(items[0]); + }); +} \ No newline at end of file diff --git a/src/GitHub.Api/Authentication/LoginManager.cs b/src/GitHub.Api/Authentication/LoginManager.cs index ffed03457..e1fead259 100644 --- a/src/GitHub.Api/Authentication/LoginManager.cs +++ b/src/GitHub.Api/Authentication/LoginManager.cs @@ -263,7 +263,7 @@ string password ApplicationAuthorization auth = null; var loginTask = new SimpleListProcessTask(taskManager.Token, nodeJsExecutablePath, $"{octorunScript} login"); - loginTask.Configure(processManager, workingDirectory: octorunScript.Parent.Parent.Parent, withInput: true); + loginTask.Configure(processManager, workingDirectory: octorunScript.Parent.Parent, withInput: true); loginTask.OnStartProcess += proc => { proc.StandardInput.WriteLine(username); @@ -271,45 +271,35 @@ string password proc.StandardInput.Close(); }; - loginTask.OnEndProcess += proc => { - logger.Trace("Exit Code: ", proc.Process.ExitCode); - }; + var ret = (await loginTask.StartAwait()); - var ret = (await loginTask.StartAwait()).ToArray(); + if (ret.Count == 0) + { + throw new Exception("Authentication failed"); + } - for (var index = 0; index < ret.Length; index++) + if (ret.Count == 1) { - var result = ret[index]; - logger.Trace("line {0}: {1}", index, result); + if (ret[0] == ("Must specify two-factor authentication OTP code.")) + { + keychain.SetToken(host, ret[0]); + await keychain.Save(host); + throw new TwoFactorRequiredException(TwoFactorType.Unknown); + } + + if (ret[0] == "Account locked.") + { + throw new LoginAttemptsExceededException(null, null); + } + + auth = new ApplicationAuthorization(ret[0]); + } + else + { + throw new Exception("Authentication failed"); } - throw new Exception("Authentication failed"); - - // if (ret.Count == 0) - // { - // throw new Exception("Authentication failed"); - // } - // // success - // else if (ret.Count == 1) - // { - // auth = new ApplicationAuthorization(ret[0]); - // } - // else - // { - // if (ret[0] == "Must specify two-factor authentication OTP code.") - // { - // keychain.SetToken(host, ret[1]); - // await keychain.Save(host); - // throw new TwoFactorRequiredException(TwoFactorType.Unknown); - // } - // else if (ret[0] == "locked") - // { - // throw new LoginAttemptsExceededException(null, null); - // } - // else - // throw new Exception("Authentication failed"); - // } - // return auth; + return auth; } private async Task TryContinueLogin( @@ -324,7 +314,7 @@ string code ApplicationAuthorization auth = null; var loginTask = new SimpleListProcessTask(taskManager.Token, nodeJsExecutablePath, $"{octorunScript} login --twoFactor"); - loginTask.Configure(processManager, workingDirectory: nodeJsExecutablePath.Parent, withInput: true); + loginTask.Configure(processManager, workingDirectory: octorunScript.Parent.Parent, withInput: true); loginTask.OnStartProcess += proc => { proc.StandardInput.WriteLine(username); @@ -332,31 +322,28 @@ string code proc.StandardInput.WriteLine(code); proc.StandardInput.Close(); }; - var ret = await loginTask.StartAwait(); + + var ret = (await loginTask.StartAwait()); if (ret.Count == 0) { throw new Exception("Authentication failed"); } + // success - else if (ret.Count == 1) + if (ret.Count == 1) { + if (ret[0] == "Account locked.") + { + throw new LoginAttemptsExceededException(null, null); + } + auth = new ApplicationAuthorization(ret[0]); } else { - if (ret[0] == "2fa") - { - keychain.SetToken(host, ret[1]); - await keychain.Save(host); - throw new TwoFactorRequiredException(TwoFactorType.Unknown); - } - else if (ret[0] == "locked") - { - throw new LoginAttemptsExceededException(null, null); - } - else - throw new Exception("Authentication failed"); + throw new Exception("Authentication failed"); } + return auth; } From ff6511541ab857fc292d2cb141e818b03557aeb5 Mon Sep 17 00:00:00 2001 From: Stanley Goldman Date: Mon, 5 Mar 2018 18:13:10 -0500 Subject: [PATCH 095/873] Adding node_modules for safe keeping --- octorun/.gitignore | 1 - octorun/node_modules/commander/CHANGELOG.md | 350 + octorun/node_modules/commander/LICENSE | 22 + octorun/node_modules/commander/Readme.md | 408 + octorun/node_modules/commander/index.js | 1157 + octorun/node_modules/commander/package.json | 114 + .../node_modules/commander/typings/index.d.ts | 309 + octorun/node_modules/dotenv/.editorconfig | 13 + octorun/node_modules/dotenv/.npmignore | 12 + octorun/node_modules/dotenv/.travis.yml | 6 + octorun/node_modules/dotenv/Contributing.md | 25 + octorun/node_modules/dotenv/README.md | 198 + octorun/node_modules/dotenv/config.js | 11 + octorun/node_modules/dotenv/dotenv.png | 3 + octorun/node_modules/dotenv/lib/main.js | 92 + octorun/node_modules/dotenv/package.json | 94 + octorun/node_modules/dotenv/test/config.js | 38 + octorun/node_modules/dotenv/test/main.js | 204 + .../octokit-rest-for-node-v0.12/.travis.yml | 16 + .../octokit-rest-for-node-v0.12/LICENSE.md | 21 + .../octokit-rest-for-node-v0.12/README.md | 31 + .../octokit-rest-for-node-v0.12/build.js | 30518 ++++++++++++++++ .../octokit-rest-for-node-v0.12/index.js | 8 + .../octokit-rest-for-node-v0.12/package.json | 102 + .../octokit-rest-for-node-v0.12/test.js | 35 + 25 files changed, 33787 insertions(+), 1 deletion(-) create mode 100644 octorun/node_modules/commander/CHANGELOG.md create mode 100644 octorun/node_modules/commander/LICENSE create mode 100644 octorun/node_modules/commander/Readme.md create mode 100644 octorun/node_modules/commander/index.js create mode 100644 octorun/node_modules/commander/package.json create mode 100644 octorun/node_modules/commander/typings/index.d.ts create mode 100644 octorun/node_modules/dotenv/.editorconfig create mode 100644 octorun/node_modules/dotenv/.npmignore create mode 100644 octorun/node_modules/dotenv/.travis.yml create mode 100644 octorun/node_modules/dotenv/Contributing.md create mode 100644 octorun/node_modules/dotenv/README.md create mode 100644 octorun/node_modules/dotenv/config.js create mode 100644 octorun/node_modules/dotenv/dotenv.png create mode 100644 octorun/node_modules/dotenv/lib/main.js create mode 100644 octorun/node_modules/dotenv/package.json create mode 100644 octorun/node_modules/dotenv/test/config.js create mode 100644 octorun/node_modules/dotenv/test/main.js create mode 100644 octorun/node_modules/octokit-rest-for-node-v0.12/.travis.yml create mode 100644 octorun/node_modules/octokit-rest-for-node-v0.12/LICENSE.md create mode 100644 octorun/node_modules/octokit-rest-for-node-v0.12/README.md create mode 100644 octorun/node_modules/octokit-rest-for-node-v0.12/build.js create mode 100644 octorun/node_modules/octokit-rest-for-node-v0.12/index.js create mode 100644 octorun/node_modules/octokit-rest-for-node-v0.12/package.json create mode 100644 octorun/node_modules/octokit-rest-for-node-v0.12/test.js diff --git a/octorun/.gitignore b/octorun/.gitignore index ef4fcce9d..0319b67e3 100644 --- a/octorun/.gitignore +++ b/octorun/.gitignore @@ -1,3 +1,2 @@ .env -node_modules npm-debug.log diff --git a/octorun/node_modules/commander/CHANGELOG.md b/octorun/node_modules/commander/CHANGELOG.md new file mode 100644 index 000000000..29f0707c6 --- /dev/null +++ b/octorun/node_modules/commander/CHANGELOG.md @@ -0,0 +1,350 @@ + +2.14.1 / 2018-02-07 +================== + + * Fix typing of help function + +2.14.0 / 2018-02-05 +================== + + * only register the option:version event once + * Fixes issue #727: Passing empty string for option on command is set to undefined + * enable eqeqeq rule + * resolves #754 add linter configuration to project + * resolves #560 respect custom name for version option + * document how to override the version flag + * document using options per command + +2.13.0 / 2018-01-09 +================== + + * Do not print default for --no- + * remove trailing spaces in command help + * Update CI's Node.js to LTS and latest version + * typedefs: Command and Option types added to commander namespace + +2.12.2 / 2017-11-28 +================== + + * fix: typings are not shipped + +2.12.1 / 2017-11-23 +================== + + * Move @types/node to dev dependency + +2.12.0 / 2017-11-22 +================== + + * add attributeName() method to Option objects + * Documentation updated for options with --no prefix + * typings: `outputHelp` takes a string as the first parameter + * typings: use overloads + * feat(typings): update to match js api + * Print default value in option help + * Fix translation error + * Fail when using same command and alias (#491) + * feat(typings): add help callback + * fix bug when description is add after command with options (#662) + * Format js code + * Rename History.md to CHANGELOG.md (#668) + * feat(typings): add typings to support TypeScript (#646) + * use current node + +2.11.0 / 2017-07-03 +================== + + * Fix help section order and padding (#652) + * feature: support for signals to subcommands (#632) + * Fixed #37, --help should not display first (#447) + * Fix translation errors. (#570) + * Add package-lock.json + * Remove engines + * Upgrade package version + * Prefix events to prevent conflicts between commands and options (#494) + * Removing dependency on graceful-readlink + * Support setting name in #name function and make it chainable + * Add .vscode directory to .gitignore (Visual Studio Code metadata) + * Updated link to ruby commander in readme files + +2.10.0 / 2017-06-19 +================== + + * Update .travis.yml. drop support for older node.js versions. + * Fix require arguments in README.md + * On SemVer you do not start from 0.0.1 + * Add missing semi colon in readme + * Add save param to npm install + * node v6 travis test + * Update Readme_zh-CN.md + * Allow literal '--' to be passed-through as an argument + * Test subcommand alias help + * link build badge to master branch + * Support the alias of Git style sub-command + * added keyword commander for better search result on npm + * Fix Sub-Subcommands + * test node.js stable + * Fixes TypeError when a command has an option called `--description` + * Update README.md to make it beginner friendly and elaborate on the difference between angled and square brackets. + * Add chinese Readme file + +2.9.0 / 2015-10-13 +================== + + * Add option `isDefault` to set default subcommand #415 @Qix- + * Add callback to allow filtering or post-processing of help text #434 @djulien + * Fix `undefined` text in help information close #414 #416 @zhiyelee + +2.8.1 / 2015-04-22 +================== + + * Back out `support multiline description` Close #396 #397 + +2.8.0 / 2015-04-07 +================== + + * Add `process.execArg` support, execution args like `--harmony` will be passed to sub-commands #387 @DigitalIO @zhiyelee + * Fix bug in Git-style sub-commands #372 @zhiyelee + * Allow commands to be hidden from help #383 @tonylukasavage + * When git-style sub-commands are in use, yet none are called, display help #382 @claylo + * Add ability to specify arguments syntax for top-level command #258 @rrthomas + * Support multiline descriptions #208 @zxqfox + +2.7.1 / 2015-03-11 +================== + + * Revert #347 (fix collisions when option and first arg have same name) which causes a bug in #367. + +2.7.0 / 2015-03-09 +================== + + * Fix git-style bug when installed globally. Close #335 #349 @zhiyelee + * Fix collisions when option and first arg have same name. Close #346 #347 @tonylukasavage + * Add support for camelCase on `opts()`. Close #353 @nkzawa + * Add node.js 0.12 and io.js to travis.yml + * Allow RegEx options. #337 @palanik + * Fixes exit code when sub-command failing. Close #260 #332 @pirelenito + * git-style `bin` files in $PATH make sense. Close #196 #327 @zhiyelee + +2.6.0 / 2014-12-30 +================== + + * added `Command#allowUnknownOption` method. Close #138 #318 @doozr @zhiyelee + * Add application description to the help msg. Close #112 @dalssoft + +2.5.1 / 2014-12-15 +================== + + * fixed two bugs incurred by variadic arguments. Close #291 @Quentin01 #302 @zhiyelee + +2.5.0 / 2014-10-24 +================== + + * add support for variadic arguments. Closes #277 @whitlockjc + +2.4.0 / 2014-10-17 +================== + + * fixed a bug on executing the coercion function of subcommands option. Closes #270 + * added `Command.prototype.name` to retrieve command name. Closes #264 #266 @tonylukasavage + * added `Command.prototype.opts` to retrieve all the options as a simple object of key-value pairs. Closes #262 @tonylukasavage + * fixed a bug on subcommand name. Closes #248 @jonathandelgado + * fixed function normalize doesn’t honor option terminator. Closes #216 @abbr + +2.3.0 / 2014-07-16 +================== + + * add command alias'. Closes PR #210 + * fix: Typos. Closes #99 + * fix: Unused fs module. Closes #217 + +2.2.0 / 2014-03-29 +================== + + * add passing of previous option value + * fix: support subcommands on windows. Closes #142 + * Now the defaultValue passed as the second argument of the coercion function. + +2.1.0 / 2013-11-21 +================== + + * add: allow cflag style option params, unit test, fixes #174 + +2.0.0 / 2013-07-18 +================== + + * remove input methods (.prompt, .confirm, etc) + +1.3.2 / 2013-07-18 +================== + + * add support for sub-commands to co-exist with the original command + +1.3.1 / 2013-07-18 +================== + + * add quick .runningCommand hack so you can opt-out of other logic when running a sub command + +1.3.0 / 2013-07-09 +================== + + * add EACCES error handling + * fix sub-command --help + +1.2.0 / 2013-06-13 +================== + + * allow "-" hyphen as an option argument + * support for RegExp coercion + +1.1.1 / 2012-11-20 +================== + + * add more sub-command padding + * fix .usage() when args are present. Closes #106 + +1.1.0 / 2012-11-16 +================== + + * add git-style executable subcommand support. Closes #94 + +1.0.5 / 2012-10-09 +================== + + * fix `--name` clobbering. Closes #92 + * fix examples/help. Closes #89 + +1.0.4 / 2012-09-03 +================== + + * add `outputHelp()` method. + +1.0.3 / 2012-08-30 +================== + + * remove invalid .version() defaulting + +1.0.2 / 2012-08-24 +================== + + * add `--foo=bar` support [arv] + * fix password on node 0.8.8. Make backward compatible with 0.6 [focusaurus] + +1.0.1 / 2012-08-03 +================== + + * fix issue #56 + * fix tty.setRawMode(mode) was moved to tty.ReadStream#setRawMode() (i.e. process.stdin.setRawMode()) + +1.0.0 / 2012-07-05 +================== + + * add support for optional option descriptions + * add defaulting of `.version()` to package.json's version + +0.6.1 / 2012-06-01 +================== + + * Added: append (yes or no) on confirmation + * Added: allow node.js v0.7.x + +0.6.0 / 2012-04-10 +================== + + * Added `.prompt(obj, callback)` support. Closes #49 + * Added default support to .choose(). Closes #41 + * Fixed the choice example + +0.5.1 / 2011-12-20 +================== + + * Fixed `password()` for recent nodes. Closes #36 + +0.5.0 / 2011-12-04 +================== + + * Added sub-command option support [itay] + +0.4.3 / 2011-12-04 +================== + + * Fixed custom help ordering. Closes #32 + +0.4.2 / 2011-11-24 +================== + + * Added travis support + * Fixed: line-buffered input automatically trimmed. Closes #31 + +0.4.1 / 2011-11-18 +================== + + * Removed listening for "close" on --help + +0.4.0 / 2011-11-15 +================== + + * Added support for `--`. Closes #24 + +0.3.3 / 2011-11-14 +================== + + * Fixed: wait for close event when writing help info [Jerry Hamlet] + +0.3.2 / 2011-11-01 +================== + + * Fixed long flag definitions with values [felixge] + +0.3.1 / 2011-10-31 +================== + + * Changed `--version` short flag to `-V` from `-v` + * Changed `.version()` so it's configurable [felixge] + +0.3.0 / 2011-10-31 +================== + + * Added support for long flags only. Closes #18 + +0.2.1 / 2011-10-24 +================== + + * "node": ">= 0.4.x < 0.7.0". Closes #20 + +0.2.0 / 2011-09-26 +================== + + * Allow for defaults that are not just boolean. Default peassignment only occurs for --no-*, optional, and required arguments. [Jim Isaacs] + +0.1.0 / 2011-08-24 +================== + + * Added support for custom `--help` output + +0.0.5 / 2011-08-18 +================== + + * Changed: when the user enters nothing prompt for password again + * Fixed issue with passwords beginning with numbers [NuckChorris] + +0.0.4 / 2011-08-15 +================== + + * Fixed `Commander#args` + +0.0.3 / 2011-08-15 +================== + + * Added default option value support + +0.0.2 / 2011-08-15 +================== + + * Added mask support to `Command#password(str[, mask], fn)` + * Added `Command#password(str, fn)` + +0.0.1 / 2010-01-03 +================== + + * Initial release diff --git a/octorun/node_modules/commander/LICENSE b/octorun/node_modules/commander/LICENSE new file mode 100644 index 000000000..10f997ab1 --- /dev/null +++ b/octorun/node_modules/commander/LICENSE @@ -0,0 +1,22 @@ +(The MIT License) + +Copyright (c) 2011 TJ Holowaychuk + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/octorun/node_modules/commander/Readme.md b/octorun/node_modules/commander/Readme.md new file mode 100644 index 000000000..6a21b9009 --- /dev/null +++ b/octorun/node_modules/commander/Readme.md @@ -0,0 +1,408 @@ +# Commander.js + + +[![Build Status](https://api.travis-ci.org/tj/commander.js.svg?branch=master)](http://travis-ci.org/tj/commander.js) +[![NPM Version](http://img.shields.io/npm/v/commander.svg?style=flat)](https://www.npmjs.org/package/commander) +[![NPM Downloads](https://img.shields.io/npm/dm/commander.svg?style=flat)](https://www.npmjs.org/package/commander) +[![Join the chat at https://gitter.im/tj/commander.js](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/tj/commander.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + + The complete solution for [node.js](http://nodejs.org) command-line interfaces, inspired by Ruby's [commander](https://github.com/commander-rb/commander). + [API documentation](http://tj.github.com/commander.js/) + + +## Installation + + $ npm install commander --save + +## Option parsing + +Options with commander are defined with the `.option()` method, also serving as documentation for the options. The example below parses args and options from `process.argv`, leaving remaining args as the `program.args` array which were not consumed by options. + +```js +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +var program = require('commander'); + +program + .version('0.1.0') + .option('-p, --peppers', 'Add peppers') + .option('-P, --pineapple', 'Add pineapple') + .option('-b, --bbq-sauce', 'Add bbq sauce') + .option('-c, --cheese [type]', 'Add the specified type of cheese [marble]', 'marble') + .parse(process.argv); + +console.log('you ordered a pizza with:'); +if (program.peppers) console.log(' - peppers'); +if (program.pineapple) console.log(' - pineapple'); +if (program.bbqSauce) console.log(' - bbq'); +console.log(' - %s cheese', program.cheese); +``` + +Short flags may be passed as a single arg, for example `-abc` is equivalent to `-a -b -c`. Multi-word options such as "--template-engine" are camel-cased, becoming `program.templateEngine` etc. + +Note that multi-word options starting with `--no` prefix negate the boolean value of the following word. For example, `--no-sauce` sets the value of `program.sauce` to false. + +```js +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +var program = require('commander'); + +program + .option('--no-sauce', 'Remove sauce') + .parse(process.argv); + +console.log('you ordered a pizza'); +if (program.sauce) console.log(' with sauce'); +else console.log(' without sauce'); +``` + +## Version option + +Calling the `version` implicitly adds the `-V` and `--version` options to the command. +When either of these options is present, the command prints the version number and exits. + + $ ./examples/pizza -V + 0.0.1 + +If you want your program to respond to the `-v` option instead of the `-V` option, simply pass custom flags to the `version` method using the same syntax as the `option` method. + +```js +program + .version('0.0.1', '-v, --version') +``` + +The version flags can be named anything, but the long option is required. + +## Command-specific options + +You can attach options to a command. + +```js +#!/usr/bin/env node + +var program = require('commander'); + +program + .command('rm ') + .option('-r, --recursive', 'Remove recursively') + .action(function (dir, cmd) { + console.log('remove ' + dir + (cmd.recursive ? ' recursively' : '')) + }) + +program.parse(process.argv) +``` + +A command's options are validated when the command is used. Any unknown options will be reported as an error. However, if an action-based command does not define an action, then the options are not validated. + +## Coercion + +```js +function range(val) { + return val.split('..').map(Number); +} + +function list(val) { + return val.split(','); +} + +function collect(val, memo) { + memo.push(val); + return memo; +} + +function increaseVerbosity(v, total) { + return total + 1; +} + +program + .version('0.1.0') + .usage('[options] ') + .option('-i, --integer ', 'An integer argument', parseInt) + .option('-f, --float ', 'A float argument', parseFloat) + .option('-r, --range ..', 'A range', range) + .option('-l, --list ', 'A list', list) + .option('-o, --optional [value]', 'An optional value') + .option('-c, --collect [value]', 'A repeatable value', collect, []) + .option('-v, --verbose', 'A value that can be increased', increaseVerbosity, 0) + .parse(process.argv); + +console.log(' int: %j', program.integer); +console.log(' float: %j', program.float); +console.log(' optional: %j', program.optional); +program.range = program.range || []; +console.log(' range: %j..%j', program.range[0], program.range[1]); +console.log(' list: %j', program.list); +console.log(' collect: %j', program.collect); +console.log(' verbosity: %j', program.verbose); +console.log(' args: %j', program.args); +``` + +## Regular Expression +```js +program + .version('0.1.0') + .option('-s --size ', 'Pizza size', /^(large|medium|small)$/i, 'medium') + .option('-d --drink [drink]', 'Drink', /^(coke|pepsi|izze)$/i) + .parse(process.argv); + +console.log(' size: %j', program.size); +console.log(' drink: %j', program.drink); +``` + +## Variadic arguments + + The last argument of a command can be variadic, and only the last argument. To make an argument variadic you have to + append `...` to the argument name. Here is an example: + +```js +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +var program = require('commander'); + +program + .version('0.1.0') + .command('rmdir [otherDirs...]') + .action(function (dir, otherDirs) { + console.log('rmdir %s', dir); + if (otherDirs) { + otherDirs.forEach(function (oDir) { + console.log('rmdir %s', oDir); + }); + } + }); + +program.parse(process.argv); +``` + + An `Array` is used for the value of a variadic argument. This applies to `program.args` as well as the argument passed + to your action as demonstrated above. + +## Specify the argument syntax + +```js +#!/usr/bin/env node + +var program = require('commander'); + +program + .version('0.1.0') + .arguments(' [env]') + .action(function (cmd, env) { + cmdValue = cmd; + envValue = env; + }); + +program.parse(process.argv); + +if (typeof cmdValue === 'undefined') { + console.error('no command given!'); + process.exit(1); +} +console.log('command:', cmdValue); +console.log('environment:', envValue || "no environment given"); +``` +Angled brackets (e.g. ``) indicate required input. Square brackets (e.g. `[env]`) indicate optional input. + +## Git-style sub-commands + +```js +// file: ./examples/pm +var program = require('commander'); + +program + .version('0.1.0') + .command('install [name]', 'install one or more packages') + .command('search [query]', 'search with optional query') + .command('list', 'list packages installed', {isDefault: true}) + .parse(process.argv); +``` + +When `.command()` is invoked with a description argument, no `.action(callback)` should be called to handle sub-commands, otherwise there will be an error. This tells commander that you're going to use separate executables for sub-commands, much like `git(1)` and other popular tools. +The commander will try to search the executables in the directory of the entry script (like `./examples/pm`) with the name `program-command`, like `pm-install`, `pm-search`. + +Options can be passed with the call to `.command()`. Specifying `true` for `opts.noHelp` will remove the option from the generated help output. Specifying `true` for `opts.isDefault` will run the subcommand if no other subcommand is specified. + +If the program is designed to be installed globally, make sure the executables have proper modes, like `755`. + +### `--harmony` + +You can enable `--harmony` option in two ways: +* Use `#! /usr/bin/env node --harmony` in the sub-commands scripts. Note some os version don’t support this pattern. +* Use the `--harmony` option when call the command, like `node --harmony examples/pm publish`. The `--harmony` option will be preserved when spawning sub-command process. + +## Automated --help + + The help information is auto-generated based on the information commander already knows about your program, so the following `--help` info is for free: + +``` + $ ./examples/pizza --help + + Usage: pizza [options] + + An application for pizzas ordering + + Options: + + -h, --help output usage information + -V, --version output the version number + -p, --peppers Add peppers + -P, --pineapple Add pineapple + -b, --bbq Add bbq sauce + -c, --cheese Add the specified type of cheese [marble] + -C, --no-cheese You do not want any cheese + +``` + +## Custom help + + You can display arbitrary `-h, --help` information + by listening for "--help". Commander will automatically + exit once you are done so that the remainder of your program + does not execute causing undesired behaviours, for example + in the following executable "stuff" will not output when + `--help` is used. + +```js +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +var program = require('commander'); + +program + .version('0.1.0') + .option('-f, --foo', 'enable some foo') + .option('-b, --bar', 'enable some bar') + .option('-B, --baz', 'enable some baz'); + +// must be before .parse() since +// node's emit() is immediate + +program.on('--help', function(){ + console.log(' Examples:'); + console.log(''); + console.log(' $ custom-help --help'); + console.log(' $ custom-help -h'); + console.log(''); +}); + +program.parse(process.argv); + +console.log('stuff'); +``` + +Yields the following help output when `node script-name.js -h` or `node script-name.js --help` are run: + +``` + +Usage: custom-help [options] + +Options: + + -h, --help output usage information + -V, --version output the version number + -f, --foo enable some foo + -b, --bar enable some bar + -B, --baz enable some baz + +Examples: + + $ custom-help --help + $ custom-help -h + +``` + +## .outputHelp(cb) + +Output help information without exiting. +Optional callback cb allows post-processing of help text before it is displayed. + +If you want to display help by default (e.g. if no command was provided), you can use something like: + +```js +var program = require('commander'); +var colors = require('colors'); + +program + .version('0.1.0') + .command('getstream [url]', 'get stream URL') + .parse(process.argv); + +if (!process.argv.slice(2).length) { + program.outputHelp(make_red); +} + +function make_red(txt) { + return colors.red(txt); //display the help text in red on the console +} +``` + +## .help(cb) + + Output help information and exit immediately. + Optional callback cb allows post-processing of help text before it is displayed. + +## Examples + +```js +var program = require('commander'); + +program + .version('0.1.0') + .option('-C, --chdir ', 'change the working directory') + .option('-c, --config ', 'set config path. defaults to ./deploy.conf') + .option('-T, --no-tests', 'ignore test hook'); + +program + .command('setup [env]') + .description('run setup commands for all envs') + .option("-s, --setup_mode [mode]", "Which setup mode to use") + .action(function(env, options){ + var mode = options.setup_mode || "normal"; + env = env || 'all'; + console.log('setup for %s env(s) with %s mode', env, mode); + }); + +program + .command('exec ') + .alias('ex') + .description('execute the given remote cmd') + .option("-e, --exec_mode ", "Which exec mode to use") + .action(function(cmd, options){ + console.log('exec "%s" using %s mode', cmd, options.exec_mode); + }).on('--help', function() { + console.log(' Examples:'); + console.log(); + console.log(' $ deploy exec sequential'); + console.log(' $ deploy exec async'); + console.log(); + }); + +program + .command('*') + .action(function(env){ + console.log('deploying "%s"', env); + }); + +program.parse(process.argv); +``` + +More Demos can be found in the [examples](https://github.com/tj/commander.js/tree/master/examples) directory. + +## License + +MIT diff --git a/octorun/node_modules/commander/index.js b/octorun/node_modules/commander/index.js new file mode 100644 index 000000000..c467b10f7 --- /dev/null +++ b/octorun/node_modules/commander/index.js @@ -0,0 +1,1157 @@ +/** + * Module dependencies. + */ + +var EventEmitter = require('events').EventEmitter; +var spawn = require('child_process').spawn; +var path = require('path'); +var dirname = path.dirname; +var basename = path.basename; +var fs = require('fs'); + +/** + * Inherit `Command` from `EventEmitter.prototype`. + */ + +require('util').inherits(Command, EventEmitter); + +/** + * Expose the root command. + */ + +exports = module.exports = new Command(); + +/** + * Expose `Command`. + */ + +exports.Command = Command; + +/** + * Expose `Option`. + */ + +exports.Option = Option; + +/** + * Initialize a new `Option` with the given `flags` and `description`. + * + * @param {String} flags + * @param {String} description + * @api public + */ + +function Option(flags, description) { + this.flags = flags; + this.required = ~flags.indexOf('<'); + this.optional = ~flags.indexOf('['); + this.bool = !~flags.indexOf('-no-'); + flags = flags.split(/[ ,|]+/); + if (flags.length > 1 && !/^[[<]/.test(flags[1])) this.short = flags.shift(); + this.long = flags.shift(); + this.description = description || ''; +} + +/** + * Return option name. + * + * @return {String} + * @api private + */ + +Option.prototype.name = function() { + return this.long + .replace('--', '') + .replace('no-', ''); +}; + +/** + * Return option name, in a camelcase format that can be used + * as a object attribute key. + * + * @return {String} + * @api private + */ + +Option.prototype.attributeName = function() { + return camelcase(this.name()); +}; + +/** + * Check if `arg` matches the short or long flag. + * + * @param {String} arg + * @return {Boolean} + * @api private + */ + +Option.prototype.is = function(arg) { + return this.short === arg || this.long === arg; +}; + +/** + * Initialize a new `Command`. + * + * @param {String} name + * @api public + */ + +function Command(name) { + this.commands = []; + this.options = []; + this._execs = {}; + this._allowUnknownOption = false; + this._args = []; + this._name = name || ''; +} + +/** + * Add command `name`. + * + * The `.action()` callback is invoked when the + * command `name` is specified via __ARGV__, + * and the remaining arguments are applied to the + * function for access. + * + * When the `name` is "*" an un-matched command + * will be passed as the first arg, followed by + * the rest of __ARGV__ remaining. + * + * Examples: + * + * program + * .version('0.0.1') + * .option('-C, --chdir ', 'change the working directory') + * .option('-c, --config ', 'set config path. defaults to ./deploy.conf') + * .option('-T, --no-tests', 'ignore test hook') + * + * program + * .command('setup') + * .description('run remote setup commands') + * .action(function() { + * console.log('setup'); + * }); + * + * program + * .command('exec ') + * .description('run the given remote command') + * .action(function(cmd) { + * console.log('exec "%s"', cmd); + * }); + * + * program + * .command('teardown [otherDirs...]') + * .description('run teardown commands') + * .action(function(dir, otherDirs) { + * console.log('dir "%s"', dir); + * if (otherDirs) { + * otherDirs.forEach(function (oDir) { + * console.log('dir "%s"', oDir); + * }); + * } + * }); + * + * program + * .command('*') + * .description('deploy the given env') + * .action(function(env) { + * console.log('deploying "%s"', env); + * }); + * + * program.parse(process.argv); + * + * @param {String} name + * @param {String} [desc] for git-style sub-commands + * @return {Command} the new command + * @api public + */ + +Command.prototype.command = function(name, desc, opts) { + if (typeof desc === 'object' && desc !== null) { + opts = desc; + desc = null; + } + opts = opts || {}; + var args = name.split(/ +/); + var cmd = new Command(args.shift()); + + if (desc) { + cmd.description(desc); + this.executables = true; + this._execs[cmd._name] = true; + if (opts.isDefault) this.defaultExecutable = cmd._name; + } + cmd._noHelp = !!opts.noHelp; + this.commands.push(cmd); + cmd.parseExpectedArgs(args); + cmd.parent = this; + + if (desc) return this; + return cmd; +}; + +/** + * Define argument syntax for the top-level command. + * + * @api public + */ + +Command.prototype.arguments = function(desc) { + return this.parseExpectedArgs(desc.split(/ +/)); +}; + +/** + * Add an implicit `help [cmd]` subcommand + * which invokes `--help` for the given command. + * + * @api private + */ + +Command.prototype.addImplicitHelpCommand = function() { + this.command('help [cmd]', 'display help for [cmd]'); +}; + +/** + * Parse expected `args`. + * + * For example `["[type]"]` becomes `[{ required: false, name: 'type' }]`. + * + * @param {Array} args + * @return {Command} for chaining + * @api public + */ + +Command.prototype.parseExpectedArgs = function(args) { + if (!args.length) return; + var self = this; + args.forEach(function(arg) { + var argDetails = { + required: false, + name: '', + variadic: false + }; + + switch (arg[0]) { + case '<': + argDetails.required = true; + argDetails.name = arg.slice(1, -1); + break; + case '[': + argDetails.name = arg.slice(1, -1); + break; + } + + if (argDetails.name.length > 3 && argDetails.name.slice(-3) === '...') { + argDetails.variadic = true; + argDetails.name = argDetails.name.slice(0, -3); + } + if (argDetails.name) { + self._args.push(argDetails); + } + }); + return this; +}; + +/** + * Register callback `fn` for the command. + * + * Examples: + * + * program + * .command('help') + * .description('display verbose help') + * .action(function() { + * // output help here + * }); + * + * @param {Function} fn + * @return {Command} for chaining + * @api public + */ + +Command.prototype.action = function(fn) { + var self = this; + var listener = function(args, unknown) { + // Parse any so-far unknown options + args = args || []; + unknown = unknown || []; + + var parsed = self.parseOptions(unknown); + + // Output help if necessary + outputHelpIfNecessary(self, parsed.unknown); + + // If there are still any unknown options, then we simply + // die, unless someone asked for help, in which case we give it + // to them, and then we die. + if (parsed.unknown.length > 0) { + self.unknownOption(parsed.unknown[0]); + } + + // Leftover arguments need to be pushed back. Fixes issue #56 + if (parsed.args.length) args = parsed.args.concat(args); + + self._args.forEach(function(arg, i) { + if (arg.required && args[i] == null) { + self.missingArgument(arg.name); + } else if (arg.variadic) { + if (i !== self._args.length - 1) { + self.variadicArgNotLast(arg.name); + } + + args[i] = args.splice(i); + } + }); + + // Always append ourselves to the end of the arguments, + // to make sure we match the number of arguments the user + // expects + if (self._args.length) { + args[self._args.length] = self; + } else { + args.push(self); + } + + fn.apply(self, args); + }; + var parent = this.parent || this; + var name = parent === this ? '*' : this._name; + parent.on('command:' + name, listener); + if (this._alias) parent.on('command:' + this._alias, listener); + return this; +}; + +/** + * Define option with `flags`, `description` and optional + * coercion `fn`. + * + * The `flags` string should contain both the short and long flags, + * separated by comma, a pipe or space. The following are all valid + * all will output this way when `--help` is used. + * + * "-p, --pepper" + * "-p|--pepper" + * "-p --pepper" + * + * Examples: + * + * // simple boolean defaulting to false + * program.option('-p, --pepper', 'add pepper'); + * + * --pepper + * program.pepper + * // => Boolean + * + * // simple boolean defaulting to true + * program.option('-C, --no-cheese', 'remove cheese'); + * + * program.cheese + * // => true + * + * --no-cheese + * program.cheese + * // => false + * + * // required argument + * program.option('-C, --chdir ', 'change the working directory'); + * + * --chdir /tmp + * program.chdir + * // => "/tmp" + * + * // optional argument + * program.option('-c, --cheese [type]', 'add cheese [marble]'); + * + * @param {String} flags + * @param {String} description + * @param {Function|*} [fn] or default + * @param {*} [defaultValue] + * @return {Command} for chaining + * @api public + */ + +Command.prototype.option = function(flags, description, fn, defaultValue) { + var self = this, + option = new Option(flags, description), + oname = option.name(), + name = option.attributeName(); + + // default as 3rd arg + if (typeof fn !== 'function') { + if (fn instanceof RegExp) { + var regex = fn; + fn = function(val, def) { + var m = regex.exec(val); + return m ? m[0] : def; + }; + } else { + defaultValue = fn; + fn = null; + } + } + + // preassign default value only for --no-*, [optional], or + if (!option.bool || option.optional || option.required) { + // when --no-* we make sure default is true + if (!option.bool) defaultValue = true; + // preassign only if we have a default + if (defaultValue !== undefined) { + self[name] = defaultValue; + option.defaultValue = defaultValue; + } + } + + // register the option + this.options.push(option); + + // when it's passed assign the value + // and conditionally invoke the callback + this.on('option:' + oname, function(val) { + // coercion + if (val !== null && fn) { + val = fn(val, self[name] === undefined ? defaultValue : self[name]); + } + + // unassigned or bool + if (typeof self[name] === 'boolean' || typeof self[name] === 'undefined') { + // if no value, bool true, and we have a default, then use it! + if (val == null) { + self[name] = option.bool + ? defaultValue || true + : false; + } else { + self[name] = val; + } + } else if (val !== null) { + // reassign + self[name] = val; + } + }); + + return this; +}; + +/** + * Allow unknown options on the command line. + * + * @param {Boolean} arg if `true` or omitted, no error will be thrown + * for unknown options. + * @api public + */ +Command.prototype.allowUnknownOption = function(arg) { + this._allowUnknownOption = arguments.length === 0 || arg; + return this; +}; + +/** + * Parse `argv`, settings options and invoking commands when defined. + * + * @param {Array} argv + * @return {Command} for chaining + * @api public + */ + +Command.prototype.parse = function(argv) { + // implicit help + if (this.executables) this.addImplicitHelpCommand(); + + // store raw args + this.rawArgs = argv; + + // guess name + this._name = this._name || basename(argv[1], '.js'); + + // github-style sub-commands with no sub-command + if (this.executables && argv.length < 3 && !this.defaultExecutable) { + // this user needs help + argv.push('--help'); + } + + // process argv + var parsed = this.parseOptions(this.normalize(argv.slice(2))); + var args = this.args = parsed.args; + + var result = this.parseArgs(this.args, parsed.unknown); + + // executable sub-commands + var name = result.args[0]; + + var aliasCommand = null; + // check alias of sub commands + if (name) { + aliasCommand = this.commands.filter(function(command) { + return command.alias() === name; + })[0]; + } + + if (this._execs[name] && typeof this._execs[name] !== 'function') { + return this.executeSubCommand(argv, args, parsed.unknown); + } else if (aliasCommand) { + // is alias of a subCommand + args[0] = aliasCommand._name; + return this.executeSubCommand(argv, args, parsed.unknown); + } else if (this.defaultExecutable) { + // use the default subcommand + args.unshift(this.defaultExecutable); + return this.executeSubCommand(argv, args, parsed.unknown); + } + + return result; +}; + +/** + * Execute a sub-command executable. + * + * @param {Array} argv + * @param {Array} args + * @param {Array} unknown + * @api private + */ + +Command.prototype.executeSubCommand = function(argv, args, unknown) { + args = args.concat(unknown); + + if (!args.length) this.help(); + if (args[0] === 'help' && args.length === 1) this.help(); + + // --help + if (args[0] === 'help') { + args[0] = args[1]; + args[1] = '--help'; + } + + // executable + var f = argv[1]; + // name of the subcommand, link `pm-install` + var bin = basename(f, '.js') + '-' + args[0]; + + // In case of globally installed, get the base dir where executable + // subcommand file should be located at + var baseDir, + link = fs.lstatSync(f).isSymbolicLink() ? fs.readlinkSync(f) : f; + + // when symbolink is relative path + if (link !== f && link.charAt(0) !== '/') { + link = path.join(dirname(f), link); + } + baseDir = dirname(link); + + // prefer local `./` to bin in the $PATH + var localBin = path.join(baseDir, bin); + + // whether bin file is a js script with explicit `.js` extension + var isExplicitJS = false; + if (exists(localBin + '.js')) { + bin = localBin + '.js'; + isExplicitJS = true; + } else if (exists(localBin)) { + bin = localBin; + } + + args = args.slice(1); + + var proc; + if (process.platform !== 'win32') { + if (isExplicitJS) { + args.unshift(bin); + // add executable arguments to spawn + args = (process.execArgv || []).concat(args); + + proc = spawn(process.argv[0], args, { stdio: 'inherit', customFds: [0, 1, 2] }); + } else { + proc = spawn(bin, args, { stdio: 'inherit', customFds: [0, 1, 2] }); + } + } else { + args.unshift(bin); + proc = spawn(process.execPath, args, { stdio: 'inherit' }); + } + + var signals = ['SIGUSR1', 'SIGUSR2', 'SIGTERM', 'SIGINT', 'SIGHUP']; + signals.forEach(function(signal) { + process.on(signal, function() { + if (proc.killed === false && proc.exitCode === null) { + proc.kill(signal); + } + }); + }); + proc.on('close', process.exit.bind(process)); + proc.on('error', function(err) { + if (err.code === 'ENOENT') { + console.error('\n %s(1) does not exist, try --help\n', bin); + } else if (err.code === 'EACCES') { + console.error('\n %s(1) not executable. try chmod or run with root\n', bin); + } + process.exit(1); + }); + + // Store the reference to the child process + this.runningCommand = proc; +}; + +/** + * Normalize `args`, splitting joined short flags. For example + * the arg "-abc" is equivalent to "-a -b -c". + * This also normalizes equal sign and splits "--abc=def" into "--abc def". + * + * @param {Array} args + * @return {Array} + * @api private + */ + +Command.prototype.normalize = function(args) { + var ret = [], + arg, + lastOpt, + index; + + for (var i = 0, len = args.length; i < len; ++i) { + arg = args[i]; + if (i > 0) { + lastOpt = this.optionFor(args[i - 1]); + } + + if (arg === '--') { + // Honor option terminator + ret = ret.concat(args.slice(i)); + break; + } else if (lastOpt && lastOpt.required) { + ret.push(arg); + } else if (arg.length > 1 && arg[0] === '-' && arg[1] !== '-') { + arg.slice(1).split('').forEach(function(c) { + ret.push('-' + c); + }); + } else if (/^--/.test(arg) && ~(index = arg.indexOf('='))) { + ret.push(arg.slice(0, index), arg.slice(index + 1)); + } else { + ret.push(arg); + } + } + + return ret; +}; + +/** + * Parse command `args`. + * + * When listener(s) are available those + * callbacks are invoked, otherwise the "*" + * event is emitted and those actions are invoked. + * + * @param {Array} args + * @return {Command} for chaining + * @api private + */ + +Command.prototype.parseArgs = function(args, unknown) { + var name; + + if (args.length) { + name = args[0]; + if (this.listeners('command:' + name).length) { + this.emit('command:' + args.shift(), args, unknown); + } else { + this.emit('command:*', args); + } + } else { + outputHelpIfNecessary(this, unknown); + + // If there were no args and we have unknown options, + // then they are extraneous and we need to error. + if (unknown.length > 0) { + this.unknownOption(unknown[0]); + } + } + + return this; +}; + +/** + * Return an option matching `arg` if any. + * + * @param {String} arg + * @return {Option} + * @api private + */ + +Command.prototype.optionFor = function(arg) { + for (var i = 0, len = this.options.length; i < len; ++i) { + if (this.options[i].is(arg)) { + return this.options[i]; + } + } +}; + +/** + * Parse options from `argv` returning `argv` + * void of these options. + * + * @param {Array} argv + * @return {Array} + * @api public + */ + +Command.prototype.parseOptions = function(argv) { + var args = [], + len = argv.length, + literal, + option, + arg; + + var unknownOptions = []; + + // parse options + for (var i = 0; i < len; ++i) { + arg = argv[i]; + + // literal args after -- + if (literal) { + args.push(arg); + continue; + } + + if (arg === '--') { + literal = true; + continue; + } + + // find matching Option + option = this.optionFor(arg); + + // option is defined + if (option) { + // requires arg + if (option.required) { + arg = argv[++i]; + if (arg == null) return this.optionMissingArgument(option); + this.emit('option:' + option.name(), arg); + // optional arg + } else if (option.optional) { + arg = argv[i + 1]; + if (arg == null || (arg[0] === '-' && arg !== '-')) { + arg = null; + } else { + ++i; + } + this.emit('option:' + option.name(), arg); + // bool + } else { + this.emit('option:' + option.name()); + } + continue; + } + + // looks like an option + if (arg.length > 1 && arg[0] === '-') { + unknownOptions.push(arg); + + // If the next argument looks like it might be + // an argument for this option, we pass it on. + // If it isn't, then it'll simply be ignored + if ((i + 1) < argv.length && argv[i + 1][0] !== '-') { + unknownOptions.push(argv[++i]); + } + continue; + } + + // arg + args.push(arg); + } + + return { args: args, unknown: unknownOptions }; +}; + +/** + * Return an object containing options as key-value pairs + * + * @return {Object} + * @api public + */ +Command.prototype.opts = function() { + var result = {}, + len = this.options.length; + + for (var i = 0; i < len; i++) { + var key = this.options[i].attributeName(); + result[key] = key === this._versionOptionName ? this._version : this[key]; + } + return result; +}; + +/** + * Argument `name` is missing. + * + * @param {String} name + * @api private + */ + +Command.prototype.missingArgument = function(name) { + console.error(); + console.error(" error: missing required argument `%s'", name); + console.error(); + process.exit(1); +}; + +/** + * `Option` is missing an argument, but received `flag` or nothing. + * + * @param {String} option + * @param {String} flag + * @api private + */ + +Command.prototype.optionMissingArgument = function(option, flag) { + console.error(); + if (flag) { + console.error(" error: option `%s' argument missing, got `%s'", option.flags, flag); + } else { + console.error(" error: option `%s' argument missing", option.flags); + } + console.error(); + process.exit(1); +}; + +/** + * Unknown option `flag`. + * + * @param {String} flag + * @api private + */ + +Command.prototype.unknownOption = function(flag) { + if (this._allowUnknownOption) return; + console.error(); + console.error(" error: unknown option `%s'", flag); + console.error(); + process.exit(1); +}; + +/** + * Variadic argument with `name` is not the last argument as required. + * + * @param {String} name + * @api private + */ + +Command.prototype.variadicArgNotLast = function(name) { + console.error(); + console.error(" error: variadic arguments must be last `%s'", name); + console.error(); + process.exit(1); +}; + +/** + * Set the program version to `str`. + * + * This method auto-registers the "-V, --version" flag + * which will print the version number when passed. + * + * @param {String} str + * @param {String} [flags] + * @return {Command} for chaining + * @api public + */ + +Command.prototype.version = function(str, flags) { + if (arguments.length === 0) return this._version; + this._version = str; + flags = flags || '-V, --version'; + var versionOption = new Option(flags, 'output the version number'); + this._versionOptionName = versionOption.long.substr(2) || 'version'; + this.options.push(versionOption); + this.on('option:' + this._versionOptionName, function() { + process.stdout.write(str + '\n'); + process.exit(0); + }); + return this; +}; + +/** + * Set the description to `str`. + * + * @param {String} str + * @return {String|Command} + * @api public + */ + +Command.prototype.description = function(str) { + if (arguments.length === 0) return this._description; + this._description = str; + return this; +}; + +/** + * Set an alias for the command + * + * @param {String} alias + * @return {String|Command} + * @api public + */ + +Command.prototype.alias = function(alias) { + var command = this; + if (this.commands.length !== 0) { + command = this.commands[this.commands.length - 1]; + } + + if (arguments.length === 0) return command._alias; + + if (alias === command._name) throw new Error('Command alias can\'t be the same as its name'); + + command._alias = alias; + return this; +}; + +/** + * Set / get the command usage `str`. + * + * @param {String} str + * @return {String|Command} + * @api public + */ + +Command.prototype.usage = function(str) { + var args = this._args.map(function(arg) { + return humanReadableArgName(arg); + }); + + var usage = '[options]' + + (this.commands.length ? ' [command]' : '') + + (this._args.length ? ' ' + args.join(' ') : ''); + + if (arguments.length === 0) return this._usage || usage; + this._usage = str; + + return this; +}; + +/** + * Get or set the name of the command + * + * @param {String} str + * @return {String|Command} + * @api public + */ + +Command.prototype.name = function(str) { + if (arguments.length === 0) return this._name; + this._name = str; + return this; +}; + +/** + * Return the largest option length. + * + * @return {Number} + * @api private + */ + +Command.prototype.largestOptionLength = function() { + return this.options.reduce(function(max, option) { + return Math.max(max, option.flags.length); + }, 0); +}; + +/** + * Return help for options. + * + * @return {String} + * @api private + */ + +Command.prototype.optionHelp = function() { + var width = this.largestOptionLength(); + + // Append the help information + return this.options.map(function(option) { + return pad(option.flags, width) + ' ' + option.description + + ((option.bool && option.defaultValue !== undefined) ? ' (default: ' + option.defaultValue + ')' : ''); + }).concat([pad('-h, --help', width) + ' ' + 'output usage information']) + .join('\n'); +}; + +/** + * Return command help documentation. + * + * @return {String} + * @api private + */ + +Command.prototype.commandHelp = function() { + if (!this.commands.length) return ''; + + var commands = this.commands.filter(function(cmd) { + return !cmd._noHelp; + }).map(function(cmd) { + var args = cmd._args.map(function(arg) { + return humanReadableArgName(arg); + }).join(' '); + + return [ + cmd._name + + (cmd._alias ? '|' + cmd._alias : '') + + (cmd.options.length ? ' [options]' : '') + + (args ? ' ' + args : ''), + cmd._description + ]; + }); + + var width = commands.reduce(function(max, command) { + return Math.max(max, command[0].length); + }, 0); + + return [ + '', + ' Commands:', + '', + commands.map(function(cmd) { + var desc = cmd[1] ? ' ' + cmd[1] : ''; + return (desc ? pad(cmd[0], width) : cmd[0]) + desc; + }).join('\n').replace(/^/gm, ' '), + '' + ].join('\n'); +}; + +/** + * Return program help documentation. + * + * @return {String} + * @api private + */ + +Command.prototype.helpInformation = function() { + var desc = []; + if (this._description) { + desc = [ + ' ' + this._description, + '' + ]; + } + + var cmdName = this._name; + if (this._alias) { + cmdName = cmdName + '|' + this._alias; + } + var usage = [ + '', + ' Usage: ' + cmdName + ' ' + this.usage(), + '' + ]; + + var cmds = []; + var commandHelp = this.commandHelp(); + if (commandHelp) cmds = [commandHelp]; + + var options = [ + '', + ' Options:', + '', + '' + this.optionHelp().replace(/^/gm, ' '), + '' + ]; + + return usage + .concat(desc) + .concat(options) + .concat(cmds) + .join('\n'); +}; + +/** + * Output help information for this command + * + * @api public + */ + +Command.prototype.outputHelp = function(cb) { + if (!cb) { + cb = function(passthru) { + return passthru; + }; + } + process.stdout.write(cb(this.helpInformation())); + this.emit('--help'); +}; + +/** + * Output help information and exit. + * + * @api public + */ + +Command.prototype.help = function(cb) { + this.outputHelp(cb); + process.exit(); +}; + +/** + * Camel-case the given `flag` + * + * @param {String} flag + * @return {String} + * @api private + */ + +function camelcase(flag) { + return flag.split('-').reduce(function(str, word) { + return str + word[0].toUpperCase() + word.slice(1); + }); +} + +/** + * Pad `str` to `width`. + * + * @param {String} str + * @param {Number} width + * @return {String} + * @api private + */ + +function pad(str, width) { + var len = Math.max(0, width - str.length); + return str + Array(len + 1).join(' '); +} + +/** + * Output help information if necessary + * + * @param {Command} command to output help for + * @param {Array} array of options to search for -h or --help + * @api private + */ + +function outputHelpIfNecessary(cmd, options) { + options = options || []; + for (var i = 0; i < options.length; i++) { + if (options[i] === '--help' || options[i] === '-h') { + cmd.outputHelp(); + process.exit(0); + } + } +} + +/** + * Takes an argument an returns its human readable equivalent for help usage. + * + * @param {Object} arg + * @return {String} + * @api private + */ + +function humanReadableArgName(arg) { + var nameOutput = arg.name + (arg.variadic === true ? '...' : ''); + + return arg.required + ? '<' + nameOutput + '>' + : '[' + nameOutput + ']'; +} + +// for versions before node v0.8 when there weren't `fs.existsSync` +function exists(file) { + try { + if (fs.statSync(file).isFile()) { + return true; + } + } catch (e) { + return false; + } +} diff --git a/octorun/node_modules/commander/package.json b/octorun/node_modules/commander/package.json new file mode 100644 index 000000000..b33979d03 --- /dev/null +++ b/octorun/node_modules/commander/package.json @@ -0,0 +1,114 @@ +{ + "_args": [ + [ + "commander@^2.14.1", + "C:\\Users\\Spade\\Projects\\GitHub\\Unity\\octorun" + ] + ], + "_from": "commander@>=2.14.1 <3.0.0", + "_id": "commander@2.14.1", + "_inCache": true, + "_location": "/commander", + "_nodeVersion": "9.4.0", + "_npmOperationalInternal": { + "host": "s3://npm-registry-packages", + "tmp": "tmp/commander_2.14.1_1517989378540_0.7122613806538618" + }, + "_npmUser": { + "email": "abe@enzou.tokyo", + "name": "abetomo" + }, + "_npmVersion": "5.6.0", + "_phantomChildren": {}, + "_requested": { + "name": "commander", + "raw": "commander@^2.14.1", + "rawSpec": "^2.14.1", + "scope": null, + "spec": ">=2.14.1 <3.0.0", + "type": "range" + }, + "_requiredBy": [ + "/" + ], + "_resolved": "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz", + "_shasum": "2235123e37af8ca3c65df45b026dbd357b01b9aa", + "_shrinkwrap": null, + "_spec": "commander@^2.14.1", + "_where": "C:\\Users\\Spade\\Projects\\GitHub\\Unity\\octorun", + "author": { + "email": "tj@vision-media.ca", + "name": "TJ Holowaychuk" + }, + "bugs": { + "url": "https://github.com/tj/commander.js/issues" + }, + "dependencies": {}, + "description": "the complete solution for node.js command-line programs", + "devDependencies": { + "@types/node": "^7.0.52", + "eslint": "^3.19.0", + "should": "^11.2.1", + "sinon": "^2.4.1", + "standard": "^10.0.3", + "typescript": "^2.7.1" + }, + "directories": {}, + "dist": { + "fileCount": 6, + "integrity": "sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw==", + "shasum": "2235123e37af8ca3c65df45b026dbd357b01b9aa", + "tarball": "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz", + "unpackedSize": 58015 + }, + "files": [ + "index.js", + "typings/index.d.ts" + ], + "gitHead": "6b026a5c88a2c7f67db70831c015e9d11c7babca", + "homepage": "https://github.com/tj/commander.js#readme", + "installable": true, + "keywords": [ + "command", + "commander", + "option", + "parser" + ], + "license": "MIT", + "main": "index", + "maintainers": [ + { + "email": "abe@enzou.tokyo", + "name": "abetomo" + }, + { + "email": "rkoutnik@gmail.com", + "name": "somekittens" + }, + { + "email": "tj@vision-media.ca", + "name": "tjholowaychuk" + }, + { + "email": "romain.vanesyan@gmail.com", + "name": "vanesyan" + }, + { + "email": "zhiyelee@gmail.com", + "name": "zhiyelee" + } + ], + "name": "commander", + "optionalDependencies": {}, + "repository": { + "type": "git", + "url": "git+https://github.com/tj/commander.js.git" + }, + "scripts": { + "lint": "eslint index.js", + "test": "make test && npm run test-typings", + "test-typings": "node_modules/typescript/bin/tsc -p tsconfig.json" + }, + "typings": "typings/index.d.ts", + "version": "2.14.1" +} diff --git a/octorun/node_modules/commander/typings/index.d.ts b/octorun/node_modules/commander/typings/index.d.ts new file mode 100644 index 000000000..483076741 --- /dev/null +++ b/octorun/node_modules/commander/typings/index.d.ts @@ -0,0 +1,309 @@ +// Type definitions for commander 2.11 +// Project: https://github.com/visionmedia/commander.js +// Definitions by: Alan Agius , Marcelo Dezem , vvakame , Jules Randolph +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +declare namespace local { + + class Option { + flags: string; + required: boolean; + optional: boolean; + bool: boolean; + short?: string; + long: string; + description: string; + + /** + * Initialize a new `Option` with the given `flags` and `description`. + * + * @param {string} flags + * @param {string} [description] + */ + constructor(flags: string, description?: string); + } + + class Command extends NodeJS.EventEmitter { + [key: string]: any; + + args: string[]; + + /** + * Initialize a new `Command`. + * + * @param {string} [name] + */ + constructor(name?: string); + + /** + * Set the program version to `str`. + * + * This method auto-registers the "-V, --version" flag + * which will print the version number when passed. + * + * @param {string} str + * @param {string} [flags] + * @returns {Command} for chaining + */ + version(str: string, flags?: string): Command; + + /** + * Add command `name`. + * + * The `.action()` callback is invoked when the + * command `name` is specified via __ARGV__, + * and the remaining arguments are applied to the + * function for access. + * + * When the `name` is "*" an un-matched command + * will be passed as the first arg, followed by + * the rest of __ARGV__ remaining. + * + * @example + * program + * .version('0.0.1') + * .option('-C, --chdir ', 'change the working directory') + * .option('-c, --config ', 'set config path. defaults to ./deploy.conf') + * .option('-T, --no-tests', 'ignore test hook') + * + * program + * .command('setup') + * .description('run remote setup commands') + * .action(function() { + * console.log('setup'); + * }); + * + * program + * .command('exec ') + * .description('run the given remote command') + * .action(function(cmd) { + * console.log('exec "%s"', cmd); + * }); + * + * program + * .command('teardown [otherDirs...]') + * .description('run teardown commands') + * .action(function(dir, otherDirs) { + * console.log('dir "%s"', dir); + * if (otherDirs) { + * otherDirs.forEach(function (oDir) { + * console.log('dir "%s"', oDir); + * }); + * } + * }); + * + * program + * .command('*') + * .description('deploy the given env') + * .action(function(env) { + * console.log('deploying "%s"', env); + * }); + * + * program.parse(process.argv); + * + * @param {string} name + * @param {string} [desc] for git-style sub-commands + * @param {CommandOptions} [opts] command options + * @returns {Command} the new command + */ + command(name: string, desc?: string, opts?: commander.CommandOptions): Command; + + /** + * Define argument syntax for the top-level command. + * + * @param {string} desc + * @returns {Command} for chaining + */ + arguments(desc: string): Command; + + /** + * Parse expected `args`. + * + * For example `["[type]"]` becomes `[{ required: false, name: 'type' }]`. + * + * @param {string[]} args + * @returns {Command} for chaining + */ + parseExpectedArgs(args: string[]): Command; + + /** + * Register callback `fn` for the command. + * + * @example + * program + * .command('help') + * .description('display verbose help') + * .action(function() { + * // output help here + * }); + * + * @param {(...args: any[]) => void} fn + * @returns {Command} for chaining + */ + action(fn: (...args: any[]) => void): Command; + + /** + * Define option with `flags`, `description` and optional + * coercion `fn`. + * + * The `flags` string should contain both the short and long flags, + * separated by comma, a pipe or space. The following are all valid + * all will output this way when `--help` is used. + * + * "-p, --pepper" + * "-p|--pepper" + * "-p --pepper" + * + * @example + * // simple boolean defaulting to false + * program.option('-p, --pepper', 'add pepper'); + * + * --pepper + * program.pepper + * // => Boolean + * + * // simple boolean defaulting to true + * program.option('-C, --no-cheese', 'remove cheese'); + * + * program.cheese + * // => true + * + * --no-cheese + * program.cheese + * // => false + * + * // required argument + * program.option('-C, --chdir ', 'change the working directory'); + * + * --chdir /tmp + * program.chdir + * // => "/tmp" + * + * // optional argument + * program.option('-c, --cheese [type]', 'add cheese [marble]'); + * + * @param {string} flags + * @param {string} [description] + * @param {((arg1: any, arg2: any) => void) | RegExp} [fn] function or default + * @param {*} [defaultValue] + * @returns {Command} for chaining + */ + option(flags: string, description?: string, fn?: ((arg1: any, arg2: any) => void) | RegExp, defaultValue?: any): Command; + option(flags: string, description?: string, defaultValue?: any): Command; + + /** + * Allow unknown options on the command line. + * + * @param {boolean} [arg] if `true` or omitted, no error will be thrown for unknown options. + * @returns {Command} for chaining + */ + allowUnknownOption(arg?: boolean): Command; + + /** + * Parse `argv`, settings options and invoking commands when defined. + * + * @param {string[]} argv + * @returns {Command} for chaining + */ + parse(argv: string[]): Command; + + /** + * Parse options from `argv` returning `argv` void of these options. + * + * @param {string[]} argv + * @returns {ParseOptionsResult} + */ + parseOptions(argv: string[]): commander.ParseOptionsResult; + + /** + * Return an object containing options as key-value pairs + * + * @returns {{[key: string]: string}} + */ + opts(): { [key: string]: string }; + + /** + * Set the description to `str`. + * + * @param {string} str + * @return {(Command | string)} + */ + description(str: string): Command; + description(): string; + + /** + * Set an alias for the command. + * + * @param {string} alias + * @return {(Command | string)} + */ + alias(alias: string): Command; + alias(): string; + + /** + * Set or get the command usage. + * + * @param {string} str + * @return {(Command | string)} + */ + usage(str: string): Command; + usage(): string; + + /** + * Set the name of the command. + * + * @param {string} str + * @return {Command} + */ + name(str: string): Command; + + /** + * Get the name of the command. + * + * @return {string} + */ + name(): string; + + /** + * Output help information for this command. + * + * @param {(str: string) => string} [cb] + */ + outputHelp(cb?: (str: string) => string): void; + + /** Output help information and exit. + * + * @param {(str: string) => string} [cb] + */ + help(cb?: (str: string) => string): void; + } + +} + +declare namespace commander { + + type Command = local.Command + + type Option = local.Option + + interface CommandOptions { + noHelp?: boolean; + isDefault?: boolean; + } + + interface ParseOptionsResult { + args: string[]; + unknown: string[]; + } + + interface CommanderStatic extends Command { + Command: typeof local.Command; + Option: typeof local.Option; + CommandOptions: CommandOptions; + ParseOptionsResult: ParseOptionsResult; + } + +} + +declare const commander: commander.CommanderStatic; +export = commander; diff --git a/octorun/node_modules/dotenv/.editorconfig b/octorun/node_modules/dotenv/.editorconfig new file mode 100644 index 000000000..5d1263484 --- /dev/null +++ b/octorun/node_modules/dotenv/.editorconfig @@ -0,0 +1,13 @@ +# editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false diff --git a/octorun/node_modules/dotenv/.npmignore b/octorun/node_modules/dotenv/.npmignore new file mode 100644 index 000000000..519e4f277 --- /dev/null +++ b/octorun/node_modules/dotenv/.npmignore @@ -0,0 +1,12 @@ +# Coverage directory used by tools like istanbul +coverage + +# Dependency directory +# Commenting this out is preferred by some people, see +# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- +node_modules + +# Users Environment Variables +.lock-wscript + +.DS_Store diff --git a/octorun/node_modules/dotenv/.travis.yml b/octorun/node_modules/dotenv/.travis.yml new file mode 100644 index 000000000..ba0b1445c --- /dev/null +++ b/octorun/node_modules/dotenv/.travis.yml @@ -0,0 +1,6 @@ +language: node_js + +node_js: + - iojs + - 0.12 + - 0.10 diff --git a/octorun/node_modules/dotenv/Contributing.md b/octorun/node_modules/dotenv/Contributing.md new file mode 100644 index 000000000..04552a9e0 --- /dev/null +++ b/octorun/node_modules/dotenv/Contributing.md @@ -0,0 +1,25 @@ +# Contributing + +1. Fork it +2. `npm install` +3. Create your feature branch (`git checkout -b my-new-feature`) +4. Commit your changes (`git commit -am 'Added some feature'`) +5. `npm test` +6. Push to the branch (`git push origin my-new-feature`) +7. Create new Pull Request + +## Testing + +We use [lab](https://github.com/hapijs/lab) and [should](https://github.com/shouldjs/should.js) to write BDD test. Run our test suite with this command: + +``` +npm test +``` + +## Code Style + +We use [standard](https://www.npmjs.com/package/standard) and [editorconfig](http://editorconfig.org) to maintain code style and best practices. Please make sure your PR adheres to the guides by running: + +``` +npm run lint +``` diff --git a/octorun/node_modules/dotenv/README.md b/octorun/node_modules/dotenv/README.md new file mode 100644 index 000000000..de324261a --- /dev/null +++ b/octorun/node_modules/dotenv/README.md @@ -0,0 +1,198 @@ +# dotenv + +dotenv + +Dotenv loads environment variables from `.env` into `ENV` (process.env). + +[![BuildStatus](https://img.shields.io/travis/motdotla/dotenv/master.svg?style=flat-square)](https://travis-ci.org/motdotla/dotenv) +[![NPM version](https://img.shields.io/npm/v/dotenv.svg?style=flat-square)](https://www.npmjs.com/package/dotenv) +[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/feross/standard) + +> "Storing [configuration in the environment](http://www.12factor.net/config) +> is one of the tenets of a [twelve-factor app](http://www.12factor.net/). +> Anything that is likely to change between deployment environments–such as +> resource handles for databases or credentials for external services–should be +> extracted from the code into environment variables. +> +> But it is not always practical to set environment variables on development +> machines or continuous integration servers where multiple projects are run. +> Dotenv loads variables from a `.env` file into ENV when the environment is +> bootstrapped." +> +> [Brandon Keepers' Dotenv in Ruby](https://github.com/bkeepers/dotenv) + +## Install + +```bash +npm install dotenv --save +``` + +## Usage + +As early as possible in your application, require and load dotenv. + +```javascript +require('dotenv').load(); +``` + +Create a `.env` file in the root directory of your project. Add +environment-specific variables on new lines in the form of `NAME=VALUE`. +For example: + +``` +DB_HOST=localhost +DB_USER=root +DB_PASS=s1mpl3 +``` + +That's it. + +`process.env` now has the keys and values you defined in your `.env` file. + +```javascript +db.connect({ + host: process.env.DB_HOST, + username: process.env.DB_USER, + password: process.env.DB_PASS +}); +``` + +### Preload + +If you are using iojs-v1.6.0 or later, you can use the `--require` (`-r`) command line option to preload dotenv. By doing this, you do not need to require and load dotenv in your application code. + + +```bash +$ node -r dotenv/config your_script.js +``` + +The configuration options below are supported as command line arguments in the format `dotenv_config_