git: Pass auth info to objects that need it instead of global

This commit is contained in:
Hylke Bons 2016-04-04 10:27:20 +01:00
parent c677df8c51
commit c7a2e163b3
6 changed files with 123 additions and 96 deletions

View file

@ -22,7 +22,6 @@ using System.Linq;
using System.Threading;
using Sparkles;
using Sparkles.Git;
namespace SparkleShare {
@ -213,7 +212,7 @@ namespace SparkleShare {
public virtual void Initialize ()
{
Logger.LogInfo ("Environment", "SparkleShare " + InstallationInfo.Version);
Logger.LogInfo ("Environment", "Git " + GitCommand.GitVersion);
Logger.LogInfo ("Environment", "Git " + Sparkles.Git.GitCommand.GitVersion);
Logger.LogInfo ("Environment", InstallationInfo.Platform + " (" + Environment.OSVersion + ")");
Preset.PresetsPath = PresetsPath;
@ -391,13 +390,13 @@ namespace SparkleShare {
void AddRepository (string folder_path)
{
BaseRepository repo = null;
string folder_name = Path.GetFileName (folder_path);
string backend = Config.GetBackendForFolder (folder_name);
string folder_name = Path.GetFileName (folder_path);
string backend = Config.GetBackendForFolder (folder_name);
try {
repo = (BaseRepository) Activator.CreateInstance (
Type.GetType ("Sparkles." + backend + "." + backend + "Repository, Sparkles." + backend),
new object [] { folder_path, Config });
new object [] { folder_path, Config, SSHAuthenticationInfo.DefaultAuthenticationInfo });
} catch (Exception e) {
Logger.LogInfo ("Controller", "Failed to load backend '" + backend + "' for '" + folder_name + "': ", e);

View file

@ -156,9 +156,7 @@ namespace Sparkles {
Logger.LogInfo ("Fetcher", "Finished");
IsActive = false;
bool repo_is_encrypted = (RemoteUrl.AbsolutePath.Contains ("-crypto") ||
RemoteUrl.Host.Equals ("sparkleshare.net"));
bool repo_is_encrypted = RemoteUrl.AbsolutePath.Contains ("-crypto");
Finished (repo_is_encrypted, IsFetchedRepoEmpty, Warnings);

View file

@ -82,12 +82,12 @@ namespace Sparkles {
public readonly string LocalPath;
public readonly string Name;
public readonly Uri RemoteUrl;
public List<ChangeSet> ChangeSets { get; private set; }
public SyncStatus Status { get; private set; }
public List<ChangeSet> ChangeSets { get; set; }
public SyncStatus Status { get; set; }
public ErrorStatus Error { get; protected set; }
public bool IsBuffering { get; private set; }
public double ProgressPercentage { get; private set; }
public double ProgressSpeed { get; private set; }
public bool IsBuffering { get; set; }
public double ProgressPercentage { get; set; }
public double ProgressSpeed { get; set; }
public DateTime LastSync {
get {
@ -132,21 +132,20 @@ namespace Sparkles {
protected Configuration local_config;
string identifier;
BaseListener listener;
Watcher watcher;
TimeSpan poll_interval = PollInterval.Short;
DateTime last_poll = DateTime.Now;
DateTime progress_last_change = DateTime.Now;
Timers.Timer remote_timer = new Timers.Timer () { Interval = 5000 };
DisconnectReason last_disconnect_reason = DisconnectReason.None;
private string identifier;
private BaseListener listener;
private Watcher watcher;
private TimeSpan poll_interval = PollInterval.Short;
private DateTime last_poll = DateTime.Now;
private DateTime progress_last_change = DateTime.Now;
private Timers.Timer remote_timer = new Timers.Timer () { Interval = 5000 };
private DisconnectReason last_disconnect_reason = DisconnectReason.None;
private bool is_syncing {
bool is_syncing {
get { return (Status == SyncStatus.SyncUp || Status == SyncStatus.SyncDown || IsBuffering); }
}
private static class PollInterval {
static class PollInterval {
public static readonly TimeSpan Short = new TimeSpan (0, 0, 5, 0);
public static readonly TimeSpan Long = new TimeSpan (0, 0, 15, 0);
}
@ -182,7 +181,7 @@ namespace Sparkles {
}
private void RemoteTimerElapsedDelegate (object sender, EventArgs args)
void RemoteTimerElapsedDelegate (object sender, EventArgs args)
{
if (this.is_syncing || IsBuffering || Status == SyncStatus.Paused)
return;
@ -239,7 +238,7 @@ namespace Sparkles {
}
private Object buffer_lock = new Object ();
Object buffer_lock = new Object ();
public void OnFileActivity (FileSystemEventArgs args)
{
@ -355,7 +354,7 @@ namespace Sparkles {
}
private void SyncUpBase ()
void SyncUpBase ()
{
if (!UseCustomWatcher)
this.watcher.Disable ();
@ -411,7 +410,7 @@ namespace Sparkles {
}
private void SyncDownBase ()
void SyncDownBase ()
{
if (!UseCustomWatcher)
this.watcher.Disable ();
@ -484,7 +483,7 @@ namespace Sparkles {
}
private void CreateListener ()
void CreateListener ()
{
this.listener = ListenerFactory.CreateListener (Name, Identifier);
@ -500,7 +499,7 @@ namespace Sparkles {
}
private void ListenerConnectedDelegate ()
void ListenerConnectedDelegate ()
{
if (this.last_disconnect_reason == DisconnectReason.SystemSleep) {
this.last_disconnect_reason = DisconnectReason.None;
@ -513,7 +512,7 @@ namespace Sparkles {
}
private void ListenerDisconnectedDelegate (DisconnectReason reason)
void ListenerDisconnectedDelegate (DisconnectReason reason)
{
Logger.LogInfo (Name, "Falling back to regular polling");
this.poll_interval = PollInterval.Short;
@ -538,7 +537,7 @@ namespace Sparkles {
}
private void ListenerAnnouncementReceivedDelegate (Announcement announcement)
void ListenerAnnouncementReceivedDelegate (Announcement announcement)
{
string identifier = Identifier;
@ -560,7 +559,7 @@ namespace Sparkles {
// Recursively gets a folder's size in bytes
private long CalculateSize (DirectoryInfo parent)
long CalculateSize (DirectoryInfo parent)
{
if (ExcludePaths.Contains (parent.Name))
return 0;

View file

@ -13,6 +13,7 @@
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
namespace Sparkles.Git {
@ -20,10 +21,25 @@ namespace Sparkles.Git {
public class GitCommand : Command {
public static string SSHPath;
public static string GitPath;
public static string ExecPath;
static string git_path;
public static string GitPath {
get {
if (git_path == null)
git_path = LocateCommand ("git");
return git_path;
}
set {
git_path = value;
}
}
public static string GitVersion {
get {
if (GitPath == null)
@ -35,27 +51,32 @@ namespace Sparkles.Git {
}
public GitCommand (string path, string args) : base (path, args)
public GitCommand (string working_dir, string args) : this (working_dir, args, null)
{
if (GitPath == null)
GitPath = LocateCommand ("git");
}
StartInfo.FileName = GitPath;
StartInfo.WorkingDirectory = path;
public GitCommand (string working_dir, string args, SSHAuthenticationInfo auth_info) : base (GitPath, args)
{
StartInfo.WorkingDirectory = working_dir;
if (string.IsNullOrEmpty (SSHPath))
SSHPath = "ssh";
string GIT_SSH_COMMAND = SSHPath + " " +
"-i \"" + SSHAuthenticationInfo.DefaultAuthenticationInfo.PrivateKeyFilePath + "\" " +
"-o UserKnownHostsFile=\"" + SSHAuthenticationInfo.DefaultAuthenticationInfo.KnownHostsFilePath + "\" " +
"-o PasswordAuthentication=no " +
"-F /dev/null"; // Ignore the environment's SSH config file
string GIT_SSH_COMMAND = SSHPath;
if (auth_info != null) {
GIT_SSH_COMMAND = SSHPath + " " +
"-i \"" + auth_info.PrivateKeyFilePath + "\" " +
"-o UserKnownHostsFile=\"" + auth_info.KnownHostsFilePath + "\" " +
"-o PasswordAuthentication=no " +
"-F /dev/null"; // Ignore the environment's SSH config file
}
if (ExecPath == null)
SetEnvironmentVariable ("GIT_EXEC_PATH", ExecPath);
SetEnvironmentVariable ("GIT_SSH_COMMAND", GIT_SSH_COMMAND);
SetEnvironmentVariable ("GIT_SSH_COMMAND", GIT_SSH_COMMAND);
SetEnvironmentVariable ("GIT_TERMINAL_PROMPT", "0");
SetEnvironmentVariable ("LANG", "en_US");
}

View file

@ -25,6 +25,7 @@ namespace Sparkles.Git {
public class GitFetcher : SSHFetcher {
SSHAuthenticationInfo auth_info;
GitCommand git;
Regex progress_regex = new Regex (@"([0-9]+)%", RegexOptions.Compiled);
@ -43,8 +44,10 @@ namespace Sparkles.Git {
}
public GitFetcher (SparkleFetcherInfo info) : base (info)
public GitFetcher (SparkleFetcherInfo fetcher_info, SSHAuthenticationInfo auth_info) : base (fetcher_info)
{
this.auth_info = auth_info;
if (RemoteUrl.ToString ().StartsWith ("ssh+"))
RemoteUrl = new Uri ("ssh" + RemoteUrl.ToString ().Substring (RemoteUrl.ToString ().IndexOf ("://")));
@ -92,11 +95,11 @@ namespace Sparkles.Git {
if (FetchPriorHistory) {
this.git = new GitCommand (Configuration.DefaultConfig.TmpPath,
"clone --progress --no-checkout \"" + RemoteUrl + "\" \"" + TargetFolder + "\"");
"clone --progress --no-checkout \"" + RemoteUrl + "\" \"" + TargetFolder + "\"", auth_info);
} else {
this.git = new GitCommand (Configuration.DefaultConfig.TmpPath,
"clone --progress --no-checkout --depth=1 \"" + RemoteUrl + "\" \"" + TargetFolder + "\"");
"clone --progress --no-checkout --depth=1 \"" + RemoteUrl + "\" \"" + TargetFolder + "\"", auth_info);
}
this.git.StartInfo.RedirectStandardError = true;

View file

@ -27,33 +27,34 @@ namespace Sparkles.Git {
public class GitRepository : BaseRepository {
private bool user_is_set;
private bool is_encrypted;
SSHAuthenticationInfo auth_info;
bool user_is_set;
bool is_encrypted;
private string cached_branch;
string cached_branch;
private Regex progress_regex = new Regex (@"([0-9]+)%", RegexOptions.Compiled);
private Regex speed_regex = new Regex (@"([0-9\.]+) ([KM])iB/s", RegexOptions.Compiled);
Regex progress_regex = new Regex (@"([0-9]+)%", RegexOptions.Compiled);
Regex speed_regex = new Regex (@"([0-9\.]+) ([KM])iB/s", RegexOptions.Compiled);
private Regex log_regex = new Regex (@"commit ([a-f0-9]{40})*\n" +
Regex log_regex = new Regex (@"commit ([a-f0-9]{40})*\n" +
"Author: (.+) <(.+)>\n" +
"Date: ([0-9]{4})-([0-9]{2})-([0-9]{2}) " +
"([0-9]{2}):([0-9]{2}):([0-9]{2}) (.[0-9]{4})\n" +
"*", RegexOptions.Compiled);
private Regex merge_regex = new Regex (@"commit ([a-f0-9]{40})\n" +
Regex merge_regex = new Regex (@"commit ([a-f0-9]{40})\n" +
"Merge: [a-f0-9]{7} [a-f0-9]{7}\n" +
"Author: (.+) <(.+)>\n" +
"Date: ([0-9]{4})-([0-9]{2})-([0-9]{2}) " +
"([0-9]{2}):([0-9]{2}):([0-9]{2}) (.[0-9]{4})\n" +
"*", RegexOptions.Compiled);
private string branch {
string branch {
get {
if (!string.IsNullOrEmpty (this.cached_branch))
return this.cached_branch;
GitCommand git = new GitCommand (LocalPath, "config core.ignorecase true");
var git = new GitCommand (LocalPath, "config core.ignorecase true");
git.StartAndWaitForExit ();
while (this.in_merge && HasLocalChanges) {
@ -76,7 +77,7 @@ namespace Sparkles.Git {
}
private bool in_merge {
bool in_merge {
get {
string merge_file_path = Path.Combine (LocalPath, ".git", "MERGE_HEAD");
return File.Exists (merge_file_path);
@ -84,9 +85,11 @@ namespace Sparkles.Git {
}
public GitRepository (string path, Configuration config) : base (path, config)
public GitRepository (string path, Configuration config, SSHAuthenticationInfo auth_info) : base (path, config)
{
GitCommand git = new GitCommand (LocalPath, "config core.ignorecase false");
this.auth_info = auth_info;
var git = new GitCommand (LocalPath, "config core.ignorecase false");
git.StartAndWaitForExit ();
git = new GitCommand (LocalPath, "config remote.origin.url \"" + RemoteUrl + "\"");
@ -139,7 +142,7 @@ namespace Sparkles.Git {
}
private void UpdateSizes ()
void UpdateSizes ()
{
double size = CalculateSizes (new DirectoryInfo (LocalPath));
double history_size = CalculateSizes (new DirectoryInfo (Path.Combine (LocalPath, ".git")));
@ -154,13 +157,13 @@ namespace Sparkles.Git {
public override string CurrentRevision {
get {
GitCommand git = new GitCommand (LocalPath, "rev-parse HEAD");
var git = new GitCommand (LocalPath, "rev-parse HEAD");
string output = git.StartAndReadStandardOutput ();
if (git.ExitCode == 0)
return output;
else
return null;
return null;
}
}
@ -170,7 +173,9 @@ namespace Sparkles.Git {
Logger.LogInfo ("Git", Name + " | Checking for remote changes...");
string current_revision = CurrentRevision;
GitCommand git = new GitCommand (LocalPath, "ls-remote --heads --exit-code \"" + RemoteUrl + "\" " + this.branch);
var git = new GitCommand (LocalPath,
"ls-remote --heads --exit-code \"" + RemoteUrl + "\" " + this.branch, auth_info);
string output = git.StartAndReadStandardOutput ();
if (git.ExitCode != 0)
@ -216,7 +221,7 @@ namespace Sparkles.Git {
if (message != null)
Commit (message);
GitCommand git = new GitCommand (LocalPath, "push --progress \"" + RemoteUrl + "\" " + this.branch);
var git = new GitCommand (LocalPath, "push --progress \"" + RemoteUrl + "\" " + this.branch, auth_info);
git.StartInfo.RedirectStandardError = true;
git.Start ();
@ -287,7 +292,7 @@ namespace Sparkles.Git {
public override bool SyncDown ()
{
GitCommand git = new GitCommand (LocalPath, "fetch --progress \"" + RemoteUrl + "\" " + this.branch);
var git = new GitCommand (LocalPath, "fetch --progress \"" + RemoteUrl + "\" " + this.branch, auth_info);
git.StartInfo.RedirectStandardError = true;
git.Start ();
@ -367,7 +372,7 @@ namespace Sparkles.Git {
get {
PrepareDirectories (LocalPath);
GitCommand git = new GitCommand (LocalPath, "status --porcelain");
var git = new GitCommand (LocalPath, "status --porcelain");
string output = git.StartAndReadStandardOutput ();
return !string.IsNullOrEmpty (output);
@ -393,9 +398,9 @@ namespace Sparkles.Git {
// Stages the made changes
private bool Add ()
bool Add ()
{
GitCommand git = new GitCommand (LocalPath, "add --all");
var git = new GitCommand (LocalPath, "add --all");
git.StartAndWaitForExit ();
return (git.ExitCode == 0);
@ -403,7 +408,7 @@ namespace Sparkles.Git {
// Commits the made changes
private void Commit (string message)
void Commit (string message)
{
GitCommand git;
@ -425,7 +430,7 @@ namespace Sparkles.Git {
// Merges the fetched changes
private bool Merge ()
bool Merge ()
{
string message = FormatCommitMessage ();
@ -493,7 +498,7 @@ namespace Sparkles.Git {
}
private void ResolveConflict ()
void ResolveConflict ()
{
// This is a list of conflict status codes that Git uses, their
// meaning, and how SparkleShare should handle them.
@ -507,7 +512,7 @@ namespace Sparkles.Git {
// UU unmerged, both modified -> Use server's, save ours as a timestamped copy
// ?? unmerged, new files -> Stage the new files
GitCommand git_status = new GitCommand (LocalPath, "status --porcelain");
var git_status = new GitCommand (LocalPath, "status --porcelain");
string output = git_status.StartAndReadStandardOutput ();
string [] lines = output.Split ("\n".ToCharArray ());
@ -534,7 +539,7 @@ namespace Sparkles.Git {
Logger.LogInfo ("Git", Name + " | Ignoring conflict in special file: " + conflicting_path);
// Recover local version
GitCommand git_ours = new GitCommand (LocalPath, "checkout --ours \"" + conflicting_path + "\"");
var git_ours = new GitCommand (LocalPath, "checkout --ours \"" + conflicting_path + "\"");
git_ours.StartAndWaitForExit ();
string abs_conflicting_path = Path.Combine (LocalPath, conflicting_path);
@ -552,7 +557,7 @@ namespace Sparkles.Git {
line.StartsWith ("AU") || line.StartsWith ("UA")) {
// Recover local version
GitCommand git_ours = new GitCommand (LocalPath, "checkout --ours \"" + conflicting_path + "\"");
var git_ours = new GitCommand (LocalPath, "checkout --ours \"" + conflicting_path + "\"");
git_ours.StartAndWaitForExit ();
// Append a timestamp to local version.
@ -569,7 +574,7 @@ namespace Sparkles.Git {
File.Move (abs_conflicting_path, abs_our_path);
// Recover server version
GitCommand git_theirs = new GitCommand (LocalPath, "checkout --theirs \"" + conflicting_path + "\"");
var git_theirs = new GitCommand (LocalPath, "checkout --theirs \"" + conflicting_path + "\"");
git_theirs.StartAndWaitForExit ();
trigger_conflict_event = true;
@ -580,7 +585,7 @@ namespace Sparkles.Git {
// The modified local version is already in the checkout, so it just needs to be added.
// We need to specifically mention the file, so we can't reuse the Add () method
GitCommand git_add = new GitCommand (LocalPath, "add \"" + conflicting_path + "\"");
var git_add = new GitCommand (LocalPath, "add \"" + conflicting_path + "\"");
git_add.StartAndWaitForExit ();
@ -588,7 +593,7 @@ namespace Sparkles.Git {
} else if (line.StartsWith ("UD")) {
// Recover server version
GitCommand git_theirs = new GitCommand (LocalPath, "checkout --theirs \"" + conflicting_path + "\"");
var git_theirs = new GitCommand (LocalPath, "checkout --theirs \"" + conflicting_path + "\"");
git_theirs.StartAndWaitForExit ();
@ -607,7 +612,7 @@ namespace Sparkles.Git {
Add ();
GitCommand git = new GitCommand (LocalPath, "commit --message \"Conflict resolution by SparkleShare\"");
var git = new GitCommand (LocalPath, "commit --message \"Conflict resolution by SparkleShare\"");
git.StartInfo.RedirectStandardOutput = false;
git.StartAndWaitForExit ();
@ -630,7 +635,7 @@ namespace Sparkles.Git {
// files from the index. This is a suboptimal workaround but it does the job
if (this.is_encrypted) {
// Restore the older file...
GitCommand git = new GitCommand (LocalPath, "checkout " + revision + " \"" + path + "\"");
var git = new GitCommand (LocalPath, "checkout " + revision + " \"" + path + "\"");
git.StartAndWaitForExit ();
string local_file_path = Path.Combine (LocalPath, path);
@ -652,7 +657,7 @@ namespace Sparkles.Git {
} else {
path = path.Replace ("\"", "\\\"");
GitCommand git = new GitCommand (LocalPath, "show " + revision + ":\"" + path + "\"");
var git = new GitCommand (LocalPath, "show " + revision + ":\"" + path + "\"");
git.Start ();
FileStream stream = File.OpenWrite (target_file_path);
@ -667,7 +672,7 @@ namespace Sparkles.Git {
}
private bool FindError (string line)
bool FindError (string line)
{
Error = ErrorStatus.None;
@ -722,9 +727,9 @@ namespace Sparkles.Git {
return GetChangeSetsInternal (path);
}
private List<ChangeSet> GetChangeSetsInternal (string path)
List<ChangeSet> GetChangeSetsInternal (string path)
{
List <ChangeSet> change_sets = new List <ChangeSet> ();
var change_sets = new List <ChangeSet> ();
GitCommand git;
if (path == null) {
@ -939,7 +944,7 @@ namespace Sparkles.Git {
}
private string EnsureSpecialCharacters (string path)
string EnsureSpecialCharacters (string path)
{
// The path is quoted if it contains special characters
if (path.StartsWith ("\""))
@ -949,7 +954,7 @@ namespace Sparkles.Git {
}
private string ResolveSpecialChars (string s)
string ResolveSpecialChars (string s)
{
StringBuilder builder = new StringBuilder (s.Length);
List<byte> codes = new List<byte> ();
@ -982,7 +987,7 @@ namespace Sparkles.Git {
//
// It also prevents git repositories from becoming
// git submodules by renaming the .git/HEAD file
private void PrepareDirectories (string path)
void PrepareDirectories (string path)
{
try {
foreach (string child_path in Directory.GetDirectories (path)) {
@ -1028,11 +1033,11 @@ namespace Sparkles.Git {
private List<Change> ParseStatus ()
List<Change> ParseStatus ()
{
List<Change> changes = new List<Change> ();
GitCommand git_status = new GitCommand (LocalPath, "status --porcelain");
var git_status = new GitCommand (LocalPath, "status --porcelain");
git_status.Start ();
while (!git_status.StandardOutput.EndOfStream) {
@ -1078,7 +1083,7 @@ namespace Sparkles.Git {
// Creates a pretty commit message based on what has changed
private string FormatCommitMessage ()
string FormatCommitMessage ()
{
string message = "";
@ -1088,14 +1093,16 @@ namespace Sparkles.Git {
message += "> " + EnsureSpecialCharacters (change.MovedToPath) + "\n";
} else {
if (change.Type == ChangeType.Edited) {
switch (change.Type) {
case ChangeType.Edited:
message += "/";
} else if (change.Type == ChangeType.Deleted) {
break;
case ChangeType.Deleted:
message += "-";
} else if (change.Type == ChangeType.Added) {
break;
case ChangeType.Added:
message += "+";
break;
}
message += " " + change.Path + "\n";