/// <summary> /// Constructor creates a shell executable file that echoes the PASSWORD /// environment variable when called. When GIT_ASKPASS is present, Git /// obtains a password for its HTTPS operations by calling it. /// </summary> public ClassHttpsPasswd() { // WAR: Do a different kind of shell script dependent on the OS) string pathPasswordBatchHelper; if (ClassUtils.IsMono()) { // Mono: Use the Shell script which tests if $PASSWORD is defined and echoes it, // and if not defined, it calls GitForce application with a special argument that opens // only password dialog pathPasswordBatchHelper = Path.Combine(App.AppHome, "passwd.sh"); File.WriteAllText(pathPasswordBatchHelper, "#!/bin/sh" + Environment.NewLine + "if [ \"$PASSWORD\" = \"\" ]; then" + Environment.NewLine + App.AppPath + " --passwd" + Environment.NewLine + "else" + Environment.NewLine + "echo $PASSWORD" + Environment.NewLine + "fi"); // Set the execute bit if (Exec.Run("chmod", "+x " + pathPasswordBatchHelper).Success() == false) { App.PrintLogMessage("ClassHttpsPasswd: Unable to chmod +x on " + pathPasswordBatchHelper, MessageType.Error); } } else { // Windows: Use the CMD BAT script // Note: Using "App.AppHome" directory to host the batch helper file // fails on XP where that directory has spaces in the name ("Documents and Settings") // which git cannot handle in this context. Similarly, git will fail with // any other path that contains a space. // This redirection is used to provide the password in an automated way. pathPasswordBatchHelper = Path.Combine(Path.GetTempPath(), "passwd.bat"); File.WriteAllText(pathPasswordBatchHelper, "@echo %PASSWORD%" + Environment.NewLine); pathPasswordBatchHelper = ClassUtils.GetShortPathName(pathPasswordBatchHelper); } ClassUtils.AddEnvar("GIT_ASKPASS", pathPasswordBatchHelper); App.PrintLogMessage("Created HTTP password helper file: " + pathPasswordBatchHelper, MessageType.General); }
public FormLog() { InitializeComponent(); ClassWinGeometry.Restore(this); // Add our main print function callback delegate App.PrintLogMessage += Print; // WAR: On Linux, remove status bar resizing grip (since it does not work under X) if (ClassUtils.IsMono()) { statusStrip.SizingGrip = false; } if (App.AppLog != null) { Print("Logging: " + App.AppLog, MessageType.General); } // Prints only in Debug build... Debug("Debug build."); }
public FormEditTools(ClassTool tool) { InitializeComponent(); ClassWinGeometry.Restore(this); Tool = (ClassTool)tool.Clone(); textName.Text = tool.Name; textCmd.Text = tool.Cmd; textArgs.Text = tool.Args; textDir.Text = tool.Dir; textDesc.Text = tool.Desc; checkAddToContextMenu.Checked = tool.IsAddToContextMenu; checkConsoleApp.Checked = tool.IsConsoleApp; checkWriteToStatus.Checked = tool.IsWriteOutput; checkCloseUponExit.Checked = tool.IsCloseWindowOnExit; checkRefresh.Checked = tool.IsRefresh; checkPrompt.Checked = tool.IsPromptForArgs; checkBrowse.Checked = tool.IsAddBrowse; // TODO: Running a command line tool largely does not work on Linux at the moment if (ClassUtils.IsMono()) { checkWriteToStatus.Enabled = checkCloseUponExit.Enabled = false; checkWriteToStatus.Checked = checkCloseUponExit.Checked = false; checkConsoleApp.Checked = true; // FIXME: Some success when this is checked } // Adjust the enables (in this order) CheckCloseUponExitCheckedChanged(null, null); CheckConsoleAppCheckedChanged(null, null); // Set the width of drop-down portions of help combo box so when it expands (down) // it will show horizontally the complete text from all pre-defined lines. // Also set their tags to point to the buddy edit boxes into which to insert selected tokens. SetComboBoxWidth(comboHelpArg); comboHelpArg.Tag = textArgs; SetComboBoxWidth(comboHelpDir); comboHelpDir.Tag = textDir; }
/// <summary> /// Class constructor that also pre-sets the command and argument to be run /// </summary> public FormGitRun(string cmd, string args) { InitializeComponent(); ClassWinGeometry.Restore(this); checkAutoclose.Checked = Properties.Settings.Default.AutoCloseGitOnSuccess; // WAR: On Linux, remove status bar resizing grip (since it does not work under X) if (ClassUtils.IsMono()) { statusStrip.SizingGrip = false; } // Detect URL in this text box textStdout.DetectUrls = true; job = new Exec(cmd, args); // Reuse the same font selected as fixed-pitch textStdout.Font = Properties.Settings.Default.commitFont; textStdout.Text += cmd + Environment.NewLine; textStdout.Text += args + Environment.NewLine; }
/// <summary> /// This function is called when text boxes name and URL changed. /// It calls delegate back to the caller. /// </summary> private void SomeTextChanged(object sender, EventArgs e) { // Call the delegate and also reparse our fetch and push URLs AnyTextChanged(IsValid()); // Enable SSH button if one of the URLs uses SSH connection btSsh.Enabled = false; if (_fetchUrl.Ok && _fetchUrl.Type == ClassUrl.UrlType.Ssh) { btSsh.Enabled = true; } if (_pushUrl.Ok && _pushUrl.Type == ClassUrl.UrlType.Ssh) { btSsh.Enabled = true; } btWWW1.Enabled = _fetchUrl.Ok; btWWW2.Enabled = _pushUrl.Ok; textPassword.ReadOnly = !(_fetchUrl.Type == ClassUrl.UrlType.Https || _pushUrl.Type == ClassUrl.UrlType.Https); // WAR: Permanently disable SSH button if not on Windows OS btSsh.Enabled = !ClassUtils.IsMono(); }
/// <summary> /// The main execution function for command line arguments. /// Returns 'false' if the main program should not continue with the execution, in which /// case ReturnCode contains the return code to return to the OS. /// </summary> public static bool Execute(Arguments commandLine) { // WAR: On Windows, re-attach the console so we can print. Mono does not need that to use Console class. if (!ClassUtils.IsMono()) { NativeMethods.AttachConsole(); Console.WriteLine(Environment.NewLine); } if (commandLine["help"] == "true" || commandLine["?"] == "true") { Console.WriteLine(Environment.NewLine + "GitForce optional arguments:" + Environment.NewLine + " --version Show the application version number." + Environment.NewLine + " --reset-windows Reset stored locations of windows and dialogs." + Environment.NewLine + " --reset-config Reset program configuration (repos etc.)." + Environment.NewLine + " --log Logs debug output to file." + Environment.NewLine); ReturnCode = 0; runGitForce = false; } // --version Show the application version number and quit if (commandLine["version"] == "true") { Console.WriteLine("GitForce version " + ClassVersion.GetVersion()); ReturnCode = 0; runGitForce = false; } // --reset-windows Reset stored locations and sizes of all windows and dialogs if (commandLine["reset-windows"] == "true") { Properties.Settings.Default.WindowsGeometries = new StringCollection(); Properties.Settings.Default.Save(); Console.WriteLine("GitForce windows and dialogs geometries have been reset."); ReturnCode = 0; runGitForce = true; } // --reset-config Reset stored configuration items (repos, settings) if (commandLine["reset-config"] == "true") { List <string> toWhack = new List <string>(); // This is very much dependent on the platform, load a list of directories to whack appropriately if (ClassUtils.IsMono()) { string home = Environment.GetEnvironmentVariable("HOME"); if (!string.IsNullOrEmpty(home)) { toWhack.Add(Path.Combine(home, ".config/GitForce")); toWhack.Add(Path.Combine(home, ".local/share/GitForce")); } } else { toWhack.Add(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "GitForce")); toWhack.Add(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "GitForce")); } // Now that we have a list of directories to remove, delete them foreach (var dir in toWhack) { DirectoryInfo dirInfo = new DirectoryInfo(dir); if (ClassUtils.DeleteFolder(dirInfo, false, false) == false) { Console.Write("Unable to delete some files!"); } } Console.WriteLine("Configuration has been reset."); ReturnCode = 0; runGitForce = false; } // --log Create a log file and append all debug log messages to it if (commandLine["log"] == "true") { App.AppLog = Path.Combine(App.AppHome, "gitforce.log"); File.WriteAllText(App.AppLog, "Log created on " + DateTime.Now.ToShortDateString() + Environment.NewLine); Console.WriteLine("Logging: " + App.AppLog); } // --passwd This is not a user option. It is used when the app is called to provide password echoed on a command line. if (commandLine["passwd"] == "true") { ReturnCode = -1; FormHttpsAuth httpsAuth = new FormHttpsAuth(false); if (httpsAuth.ShowDialog() == DialogResult.OK) { Console.WriteLine(httpsAuth.Password); ReturnCode = 0; } runGitForce = false; } // WAR: On Windows, detach the console when we are done. Mono does not need that to use Console class. if (!ClassUtils.IsMono()) { NativeMethods.FreeConsole(); } return(runGitForce); }
static int Main(string[] args) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); // Upgrade application settings across the version increment ClassUtils.UpgradeApplicationSettingsIfNecessary(); // Make sure the application data folder directory exists Directory.CreateDirectory(AppHome); // Get and process command line arguments Arguments commandLine = new Arguments(args); // If the processing requested program termination, // return using the error code created by that class if (ClassCommandLine.Execute(commandLine) == false) { return(ClassCommandLine.ReturnCode); } // Check that only one application instance is running bool mAcquired; Mutex mAppMutex = new Mutex(true, "gitforce", out mAcquired); if (!mAcquired && Properties.Settings.Default.WarnMultipleInstances) { if (MessageBox.Show("GitForce is already running.\n\nDo you want to open a new instance?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.No) { return(-1); } } // Check if the application has been run as Admin/root if (ClassUtils.IsAdmin()) { if (MessageBox.Show("GitForce has been run with elevated privileges which is not a recomended way to run it.\n\nDo you still want to continue?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.No) { return(-1); } } // Initialize logging and git execute support Log = new FormLog(); Log.ShowWindow(Properties.Settings.Default.ShowLogWindow); Git = new ClassGit(); // Before we can start, we need to have a functional git executable); if (Git.Initialize()) { // Initialize external diff program Diff = new ClassDiff(); if (Diff.Initialize()) { Merge = new ClassMerge(); // Initialize external Merge program if (Merge.Initialize()) { // Add known text editors Settings.Panels.ControlViewEdit.AddKnownEditors(); if (ClassUtils.IsMono()) { Ssh = new ClassSSH(); // Instantiate SSH support only on Linux (Mono) } else { Putty = new ClassPutty(); // Instantiate PuTTY support only on Windows } HttpsPasswd = new ClassHttpsPasswd(); // Create HTTPS password helper file Repos = new ClassRepos(); // Create repository canvas Version = new ClassVersion(); // Start the new version check process MainForm = new FormMain(); // Create the main form MainForm.Show(); // Show the main window so the handles get created if (MainForm.Initialize()) // Load repos, custom tools etc. { DoRefresh(); // Initial global refresh Application.Run(MainForm); // Run the main form Properties.Settings.Default.Save(); GC.KeepAlive(mAppMutex); return(0); } } } } return(-1); }
/// <summary> /// This is the main entry point to the application main form. /// </summary> public FormMain() { InitializeComponent(); ClassWinGeometry.Restore(this); // WAR: On Linux, remove status bar resizing grip (since it does not work under X) if (ClassUtils.IsMono()) { statusStrip.SizingGrip = false; } // Initialize panels // Left panel: splitContainer2.Panel1.Controls.Add(PanelView); PanelView.Dock = DockStyle.Fill; // Right set of panels: foreach (var panel in PanelsR) { var tabPage = new TabPage(panel.Key) { Name = panel.Key, Tag = panel.Key, ToolTipText = panel.Key + " (" + PanelsRShortcuts[panel.Key] + ")" }; panel.Value.Dock = DockStyle.Fill; tabPage.Controls.Add(panel.Value); rightTabControl.TabPages.Add(tabPage); } // Show or hide command line menuViewCommandLine.Checked = cmdBox.Visible = Properties.Settings.Default.ShowCommandLine; UpdateRightPaneTabsShowState(); // Enable SSH only if the PuTTY support class has been instantiated if (App.Putty != null) { btSsh.Enabled = true; menuMainManageKeys.Enabled = true; } // We prevent Log window form closing by getting a FormClosing event within which we set "e.Cancel" to True App.Log.FormClosing += LogWindowToolStripMenuItemClick; menuViewLogWindow.Checked = Properties.Settings.Default.ShowLogWindow; // Add all callback handlers App.Refresh += FormMainRefresh; // Refresh, when any component wants to update the global state App.PrintStatusMessage += PrintStatus; // Print a line of status message App.StatusBusy += SetBusy; // Busy flag set or reset // Register toolbar file buttons with the View panel PanelView.RegisterToolstripFileButtons(new Dictionary <PanelView.FileOps, ToolStripButton> { { PanelView.FileOps.Add, btAdd }, { PanelView.FileOps.Update, btUpdate }, { PanelView.FileOps.UpdateAll, btUpdateAll }, { PanelView.FileOps.Revert, btRevert }, { PanelView.FileOps.Delete, btDelete }, { PanelView.FileOps.DeleteFs, btDeleteFs }, { PanelView.FileOps.Edit, btEdit } }); PrintStatus("GitForce version " + ClassVersion.GetVersion(), MessageType.General); // Arm the timer that will check for the result of the new version test // Since the network access, implemented in ClassVersion, can take some time to // provide with the version check result, we will simply repaint our icon after a delay Timer versionCheckTimer = new Timer { Interval = 10000, Enabled = true }; versionCheckTimer.Tick += VersionCheckTimerTick; }