private static void RunLockRequest(string[] args, bool unattended, LockRequestDelegate requestToRun) { try { if (ShouldLock(args)) { using (NamedPipeClient pipeClient = new NamedPipeClient(enlistmentPipename)) { if (!pipeClient.Connect()) { ExitWithError("The repo does not appear to be mounted. Use 'gvfs status' to check."); } int pid = GetParentPid(args); if (pid == Program.InvalidProcessId || !GVFSHooksPlatform.IsProcessActive(pid)) { ExitWithError("GVFS.Hooks: Unable to find parent git.exe process " + "(PID: " + pid + ")."); } requestToRun(unattended, args, pid, pipeClient); } } } catch (Exception exc) { ExitWithError( "Unable to initialize Git command.", "Ensure that GVFS is running.", exc.ToString()); } }
public static void Main(string[] args) { try { if (args.Length < 2) { ExitWithError("Usage: gvfs.hooks.exe --git-pid=<pid> <hook> <git verb> [<other arguments>]"); } bool unattended = GVFSEnlistment.IsUnattended(tracer: null); string errorMessage; string normalizedCurrentDirectory; if (!GVFSHooksPlatform.TryGetNormalizedPath(Environment.CurrentDirectory, out normalizedCurrentDirectory, out errorMessage)) { ExitWithError($"Failed to determine final path for current directory {Environment.CurrentDirectory}. Error: {errorMessage}"); } if (!GVFSHooksPlatform.TryGetGVFSEnlistmentRoot(Environment.CurrentDirectory, out enlistmentRoot, out errorMessage)) { // Nothing to hook when being run outside of a GVFS repo. // This is also the path when run with --git-dir outside of a GVFS directory, see Story #949665 Environment.Exit(0); } enlistmentPipename = GVFSHooksPlatform.GetNamedPipeName(enlistmentRoot); switch (GetHookType(args)) { case PreCommandHook: CheckForLegalCommands(args); RunLockRequest(args, unattended, AcquireGVFSLockForProcess); RunPreCommands(args); break; case PostCommandHook: // Do not release the lock if this request was only run to see if it could acquire the GVFSLock, // but did not actually acquire it. if (!CheckGVFSLockAvailabilityOnly(args)) { RunLockRequest(args, unattended, ReleaseGVFSLock); } RunPostCommands(args, unattended); break; default: ExitWithError("Unrecognized hook: " + string.Join(" ", args)); break; } } catch (Exception ex) { ExitWithError("Unexpected exception: " + ex.ToString()); } }
private static void CheckForLegalCommands(string[] args) { string command = GetGitCommand(args); switch (command) { case "gui": ExitWithError(GVFSHooksPlatform.GetGitGuiBlockedMessage()); break; } }
private static void RemindUpgradeAvailable() { // The idea is to generate a random number between 0 and 100. To make // sure that the reminder is displayed only 10% of the times a git // command is run, check that the random number is between 0 and 10, // which will have a probability of 10/100 == 10%. int reminderFrequency = 10; int randomValue = random.Next(0, 100); if ((IsUpgradeMessageDeterministic() || randomValue <= reminderFrequency) && ProductUpgraderInfo.IsLocalUpgradeAvailable(tracer: null, highestAvailableVersionDirectory: GVFSHooksPlatform.GetUpgradeHighestAvailableVersionDirectory())) { Console.WriteLine(Environment.NewLine + GVFSHooksPlatform.GetUpgradeReminderNotification()); } }
private static void ReleaseGVFSLock(bool unattended, string[] args, int pid, NamedPipeClient pipeClient) { string fullCommand = GenerateFullCommand(args); GVFSLock.ReleaseGVFSLock( unattended, pipeClient, fullCommand, pid, GVFSHooksPlatform.IsElevated(), GVFSHooksPlatform.IsConsoleOutputRedirectedToFile(), response => { if (response == null || response.ResponseData == null) { Console.WriteLine("\nError communicating with GVFS: Run 'gvfs status' to check the status of your repo"); } else if (response.ResponseData.HasFailures) { if (response.ResponseData.FailureCountExceedsMaxFileNames) { Console.WriteLine( "\nGVFS failed to update {0} files, run 'git status' to check the status of files in the repo", response.ResponseData.FailedToDeleteCount + response.ResponseData.FailedToUpdateCount); } else { string deleteFailuresMessage = BuildUpdatePlaceholderFailureMessage(response.ResponseData.FailedToDeleteFileList, "delete", "git clean -f "); if (deleteFailuresMessage.Length > 0) { Console.WriteLine(deleteFailuresMessage); } string updateFailuresMessage = BuildUpdatePlaceholderFailureMessage(response.ResponseData.FailedToUpdateFileList, "update", "git checkout -- "); if (updateFailuresMessage.Length > 0) { Console.WriteLine(updateFailuresMessage); } } } }, gvfsEnlistmentRoot: null, waitingMessage: "Waiting for GVFS to parse index and update placeholder files", spinnerDelay: PostCommandSpinnerDelayMs); }
private static void AcquireGVFSLockForProcess(bool unattended, string[] args, int pid, NamedPipeClient pipeClient) { string result; bool checkGvfsLockAvailabilityOnly = CheckGVFSLockAvailabilityOnly(args); string fullCommand = GenerateFullCommand(args); if (!GVFSLock.TryAcquireGVFSLockForProcess( unattended, pipeClient, fullCommand, pid, GVFSHooksPlatform.IsElevated(), isConsoleOutputRedirectedToFile: GVFSHooksPlatform.IsConsoleOutputRedirectedToFile(), checkAvailabilityOnly: checkGvfsLockAvailabilityOnly, gvfsEnlistmentRoot: null, result: out result)) { ExitWithError(result); } }
private static void RemindUpgradeAvailable() { // The idea is to generate a random number between 0 and 100. To make // sure that the reminder is displayed only 10% of the times a git // command is run, check that the random number is between 0 and 10, // which will have a probability of 10/100 == 10%. int reminderFrequency = 10; int randomValue = random.Next(0, 100); if (randomValue <= reminderFrequency && ProductUpgrader.IsLocalUpgradeAvailable(GVFSHooksPlatform.GetInstallerExtension())) { Console.WriteLine(Environment.NewLine + GVFSConstants.UpgradeVerbMessages.ReminderNotification); } }