Пример #1
0
        /// <summary>
        /// Start scanning at the time the form is first shown
        /// </summary>
        private void FormNewRepoScanAddShown(object sender, EventArgs e)
        {
            enableAdd = true;
            int count = 1;

            // Create each of the repos for the selected directories
            foreach (var d in dirs)
            {
                if (enableAdd == false)
                {
                    return;
                }
                try
                {
                    // Update progress bar and make sure it gets painted
                    progressBar.Value = count++;
                    Thread.Sleep(1);

                    textRepo.Text = d;
                    Application.DoEvents();
                    Directory.SetCurrentDirectory(d);
                    if (ClassGit.Run("init").Success() == false)
                    {
                        throw new ClassException("init failed.");
                    }
                    App.Repos.Add(d);
                }
                catch (Exception ex)
                {
                    App.PrintLogMessage("Unable to add repo: " + ex.Message, MessageType.Error);
                    App.PrintStatusMessage(ex.Message, MessageType.Error);
                }
            }
            DialogResult = DialogResult.OK;
        }
Пример #2
0
 /// <summary>
 /// This function is run on a separate thread. It checks for a new version.
 /// </summary>
 private void AltThreadVersionCheck()
 {
     // A lot of things can go wrong here...
     try
     {
         StringBuilder file = new StringBuilder();
         using (WebResponse response = altRequest.GetResponse())
         {
             using (StreamReader reader = new StreamReader(response.GetResponseStream()))
             {
                 file.Append(reader.ReadToEnd());
             }
         }
         // TODO...
         if (file.ToString().Length > 0)
         {
             Thread.Sleep(2000); // Make sure this message is shown after all other messages in the view pane
             App.PrintStatusMessage(file.ToString(), MessageType.NewVersion);
         }
     }
     catch (Exception ex)
     {
         App.PrintStatusMessage("Version check: " + ex.Message, MessageType.Error);
     }
 }
Пример #3
0
        /// <summary>
        /// Load .netrc file into internal data structure
        /// </summary>
        private void LoadNetrc(string filename)
        {
            try
            {
                using (StreamReader file = new StreamReader(filename))
                {
                    do
                    {
                        string line = file.ReadLine();

                        if (line == null)
                        {
                            break;
                        }
                        if (line == string.Empty)
                        {
                            continue;
                        }

                        List <string> keys = line.Split((" ").ToCharArray(), StringSplitOptions.RemoveEmptyEntries).ToList();
                        if ((keys.Count() != 6) || (keys[0] != "machine") || (keys[2] != "login") || (keys[4] != "password"))
                        {
                            throw new Exception("Bad entry: " + line);
                        }

                        netrc[keys[1]] = new Tuple <string, string>(keys[3], keys[5]); // [machine] = (login, password)
                    } while (true);
                }
            }
            catch (Exception ex)
            {
                App.PrintStatusMessage(ex.Message, MessageType.Error);
                MessageBox.Show(ex.Message, "Error reading .netrc file", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
Пример #4
0
        /// <summary>
        /// Open a file browser/Explorer at the specific directory, optionally selecting a file
        /// </summary>
        public static void ExplorerHere(string where, string selFile)
        {
            try
            {
                App.PrintStatusMessage("Opening a file browser at " + where, MessageType.General);

                // WAR: Opening an "Explorer" is platform-specific
                if (IsMono())
                {
                    // TODO: Start a Linux (Ubuntu?) file explorer in a more flexible way
                    Process.Start(@"/usr/bin/nautilus", "--browser " + where);
                }
                else
                {
                    string path = selFile == string.Empty
                                      ? "/e,\"" + where + "\""
                                      : "/e, /select,\"" + selFile + "\"";
                    App.PrintLogMessage(path, MessageType.Command);
                    Process.Start("explorer.exe", path);
                }
            }
            catch (Exception ex)
            {
                App.PrintLogMessage(ex.Message, MessageType.Error);
                MessageBox.Show(ex.Message, "Explorer Here error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
Пример #5
0
        /// <summary>
        /// Add a new repository with the root at the given path. Create a directory if it does not exist.
        /// This function throws exceptions!
        /// </summary>
        /// <param name="root">The root path of a new repository</param>
        /// <returns>Newly created repository class or null if a repo already exists at that root directory</returns>
        public ClassRepo Add(string root)
        {
            // Detect a repository with the same root path (case insensitive directory name compare)
            if (Repos.Exists(r => r.Path.Equals(root, StringComparison.CurrentCultureIgnoreCase)))
            {
                throw new ClassException("Repository with the same name already exists!");
            }

            Directory.CreateDirectory(root);
            ClassRepo repo = new ClassRepo(root);

            if (!repo.Init())
            {
                throw new ClassException("Unable to initialize git repository!");
            }

            Repos.Add(repo);
            App.PrintStatusMessage("Adding repo " + repo, MessageType.General);

            // If this is a very first repo, set it as default and current
            if (Repos.Count == 1)
            {
                Current = Default = repo;
            }

            return(repo);
        }
Пример #6
0
        /// <summary>
        /// Commit a list of files.
        /// Returns true if commit succeeded, false otherwise.
        /// </summary>
        public bool GitCommit(string cmd, bool isAmend, List <string> files)
        {
            ExecResult result;
            string     list = QuoteAndFlattenPaths(files);

            App.PrintStatusMessage("Submit " + list, MessageType.General);

            // See below Run() for the description of the problem with long commands.
            // The Run() function breaks any command into chunks of 2000 characters or less
            // and issues them separately. This can be done on every command except 'commit'
            // since that would introduce multiple commits, which is probably not what the user
            // wants. Hence, we break commit at this level into an initial commit of a single
            // file (the first file on the list), and append for each successive chunk.
            if (isAmend == false && list.Length >= 2000)
            {
                result = RunCmd("commit " + cmd + " -- " + "\"" + files[0] + "\"");
                if (result.Success() == false)
                {
                    return(false);
                }
                isAmend = true;
                files.RemoveAt(0);
                list = QuoteAndFlattenPaths(files);
            }
            result = RunCmd(string.Format("commit {0} {1} -- {2}", cmd, isAmend ? "--amend" : "", list));
            return(result.Success());
        }
Пример #7
0
        /// <summary>
        /// Reset a list of files to a specific head.
        /// Returns true if a git command succeeded, false otherwise.
        /// </summary>
        public bool GitReset(string head, List <string> files)
        {
            string list = QuoteAndFlattenPaths(files);

            App.PrintStatusMessage(string.Format("Resetting to {0}: {1}", head, list), MessageType.General);
            return(RunCmd("reset " + head + " -- " + list).Success());
        }
Пример #8
0
        /// <summary>
        /// Callback on the command line text ready.
        /// We execute a custom (immediate) command which can be either a direct git
        /// command or a shell (command prompt?) command.
        /// Several commands may be separated by "&&" token. This accomodates Gerrit
        /// code review process and its shortcuts that can be easily pasted.
        /// </summary>
        private void CmdBoxTextReady(object sender, string cmd)
        {
            foreach (string command in cmd.Split(new[] { " && " }, StringSplitOptions.RemoveEmptyEntries))
            {
                // Print out the command itself
                App.PrintStatusMessage(command, MessageType.Command);

                // If the command text started with a command 'git', remove it
                string[] tokens = command.Split(' ');
                string   args   = String.Join(" ", tokens, 1, tokens.Count() - 1);

                // We are guaranteed to have at least one token (by the TextBoxEx control)
                string run;
                if (tokens[0].ToLower() == "git")
                {
                    // Command is a git command: execute it
                    run = ClassGit.Run(args).ToString();
                }
                else
                {
                    // Command is an arbitrary (command line type) command
                    // Use the command shell to execute it
                    run = ClassUtils.ExecuteShellCommand(tokens[0], args);
                }
                App.PrintStatusMessage(run, MessageType.Output);
            }
        }
Пример #9
0
        /// <summary>
        /// Checkout a list of files
        /// </summary>
        public void GitCheckout(string options, List <string> files)
        {
            string list = QuoteAndFlattenPaths(files);

            App.PrintStatusMessage("Checkout " + options + " " + list, MessageType.General);
            RunCmd("checkout " + options + " -- " + list);
        }
Пример #10
0
        /// <summary>
        /// Revert a list of files
        /// </summary>
        public void GitRevert(List <string> files)
        {
            string list = QuoteAndFlattenPaths(files);

            App.PrintStatusMessage("Reverting " + list, MessageType.General);
            RunCmd("checkout -- " + list);
        }
Пример #11
0
        public void GitDelete(string tag, List <string> files)
        {
            string list = QuoteAndFlattenPaths(files);

            App.PrintStatusMessage("Removing " + list, MessageType.General);
            RunCmd("rm " + tag + " -- " + list);
        }
Пример #12
0
        public void GitDiff(string tag, List <string> files)
        {
            string list = QuoteAndFlattenPaths(files);

            App.PrintStatusMessage("Diffing " + list, MessageType.General);
            RunCmd("difftool " + ClassDiff.GetDiffCmd() + " " + tag + " -- " + list, true);
        }
Пример #13
0
        public static ExecResult Run(string gitcmd, bool async)
        {
            // Pick up git commands that take long time to execute and run them
            // using a threaded execution
            if (gitcmd.StartsWith("clone --progress") ||
                gitcmd.StartsWith("fetch") ||
                gitcmd.StartsWith("pull ") ||
                gitcmd.StartsWith("push "))
            {
                FormGitRun formGitRun = new FormGitRun(Properties.Settings.Default.GitPath, gitcmd);
                formGitRun.ShowDialog();
                return(formGitRun.GetResult());
            }

            if (!async)
            {
                return(Exec.Run(Properties.Settings.Default.GitPath, gitcmd));
            }

            var job = new Exec(Properties.Settings.Default.GitPath, gitcmd);

            job.AsyncRun(s => App.PrintStatusMessage(s, MessageType.Output),
                         s => App.PrintStatusMessage(s, MessageType.Error),
                         null);
            return(new ExecResult());
        }
Пример #14
0
        /// <summary>
        /// Open a command prompt at the specific directory
        /// </summary>
        public static void CommandPromptHere(string where)
        {
            try
            {
                Directory.SetCurrentDirectory(where);
                App.PrintStatusMessage("Command prompt at " + where, MessageType.General);
                Process proc = new Process();
                proc.StartInfo.UseShellExecute = false;

                // Add all environment variables listed
                foreach (var envar in Env)
                {
                    proc.StartInfo.EnvironmentVariables.Add(envar.Key, envar.Value);
                }

                // WAR: Opening a command window/terminal is platform-specific
                if (IsMono())
                {
                    // TODO: This may not work on a non-Ubuntu system?
                    proc.StartInfo.FileName  = @"/usr/bin/gnome-terminal";
                    proc.StartInfo.Arguments = "--working-directory=" + where;
                }
                else
                {
                    proc.StartInfo.FileName = "cmd.exe";
                }
                proc.Start();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Command Prompt Here error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
Пример #15
0
 /// <summary>
 /// Callback that handles process printing to stderr
 /// Print to the application status pane.
 /// </summary>
 private void ProcErrorDataReceived(object sender, DataReceivedEventArgs e)
 {
     if (String.IsNullOrEmpty(e.Data))
     {
         return;
     }
     App.PrintStatusMessage(e.Data + Environment.NewLine, MessageType.Error);
 }
Пример #16
0
        /// <summary>
        /// Rename a list of files
        /// </summary>
        public void GitRename(List <string> files)
        {
            string list = QuoteAndFlattenPaths(files);

            App.PrintStatusMessage("Renaming " + list, MessageType.General);
            RunCmd("add -- " + list);
            // Any git command that adds/updates files in the index might cause file check for TABs
            ClassTabCheck.CheckForTabs(files);
        }
Пример #17
0
        /// <summary>
        /// Parses the response string from new version check sites
        /// </summary>
        private void ParseNewVersionResponse(StringBuilder answer)
        {
            if (MessageAlreadySent) // Print only one message for multiple site's checks
            {
                return;
            }
            // Search for the version string, for example:
            // [assembly: AssemblyFileVersion(&quot;1.0.11&quot;)]
            string sPattern = @"GitForce-(?<major>\d+).(?<minor>\d+).(?<build>\d+).exe";
            Regex  r        = new Regex(sPattern, RegexOptions.Compiled);

            if (r.IsMatch(answer.ToString()))
            {
                // Get the version numbers from the latest version checked in github
                string major    = r.Match(answer.ToString()).Result("${major}");
                string minor    = r.Match(answer.ToString()).Result("${minor}");
                string build    = r.Match(answer.ToString()).Result("${build}");
                int    webMajor = Convert.ToInt32(major);
                int    webMinor = Convert.ToInt32(minor);
                int    webBuild = Convert.ToInt32(build);

                // Get the current version numbers
                string[] current   = GetVersion().Split('.');
                int      thisMajor = Convert.ToInt32(current[0]);
                int      thisMinor = Convert.ToInt32(current[1]);
                int      thisBuild = Convert.ToInt32(current[2]);

                // Compare two versions and set flag if the current one is less
                if (thisMajor < webMajor)
                {
                    NewVersionAvailable = true;
                }
                else if (thisMinor < webMinor)
                {
                    NewVersionAvailable = true;
                }
                else if (thisBuild < webBuild)
                {
                    NewVersionAvailable = true;
                }

                // By now we have log window availabe, so print out what's going on
                if (NewVersionAvailable)
                {
                    App.PrintStatusMessage("**** A new version of GitForce is available! ****", MessageType.NewVersion);
                }
                else
                {
                    App.PrintStatusMessage("Version check OK - this version is up-to-date.", MessageType.General);
                }
                MessageAlreadySent = true;
            }
            else
            {
                App.PrintStatusMessage("Version check: Unable to match pattern!", MessageType.Error);
            }
        }
Пример #18
0
 /// <summary>
 /// Export current set of custom tools to a file
 /// </summary>
 private void ExportToolMenuItemClick(object sender, EventArgs e)
 {
     if (saveTools.ShowDialog() == DialogResult.OK)
     {
         if (App.CustomTools.Save(saveTools.FileName))
         {
             App.PrintStatusMessage("Saved custom tools to " + saveTools.FileName, MessageType.General);
         }
     }
 }
Пример #19
0
 /// <summary>
 /// Open a file browser/Explorer at the specific directory, optionally selecting a file
 /// </summary>
 public static void ExplorerHere(string where, string selFile)
 {
     try
     {
         App.PrintStatusMessage("Opening a file browser at " + where, MessageType.General);
         if (IsMono())
         {
             // Opening an "Explorer" is platform-specific and depends on the desktop environment which you use,
             // each desktop environment comes with its own default file- manager.
             //   Ubuntu: nautilus
             //   Cinnamon: nemo
             //   Mate: caja
             //   xfce: thunar
             //   KDE: dolphin
             if (File.Exists(@"/usr/bin/nautilus"))
             {
                 Process.Start(@"/usr/bin/nautilus", "--browser " + where);
             }
             else if (File.Exists(@"/usr/bin/nemo"))
             {
                 Process.Start(@"/usr/bin/nemo", where);
             }
             else if (File.Exists(@"/usr/bin/caja"))
             {
                 Process.Start(@"/usr/bin/caja", where);
             }
             else if (File.Exists(@"/usr/bin/thunar"))
             {
                 Process.Start(@"/usr/bin/thunar", where);
             }
             else if (File.Exists(@"/usr/bin/dolphin"))
             {
                 Process.Start(@"/usr/bin/dolphin", where);
             }
             else
             {
                 throw new Exception("Unable to identify a file browser program for this distro. Please report this issue - thank you!");
             }
         }
         else
         {
             string path = selFile == string.Empty
                               ? "/e,\"" + where + "\""
                               : "/e, /select,\"" + selFile + "\"";
             App.PrintLogMessage(path, MessageType.Command);
             Process.Start("explorer.exe", path);
         }
     }
     catch (Exception ex)
     {
         App.PrintLogMessage(ex.Message, MessageType.Error);
         MessageBox.Show(ex.Message, "Explorer Here error", MessageBoxButtons.OK, MessageBoxIcon.Error);
     }
 }
Пример #20
0
 /// <summary>
 /// Given the topic, open the relevant help page online
 /// </summary>
 public static void Handler(string topic)
 {
     if (Webhelp.ContainsKey(topic))
     {
         Process.Start(Webhelp[topic]);
     }
     else
     {
         App.PrintStatusMessage("Internal Error: Please report that `topic " + topic + "` not found!", MessageType.Error);
     }
 }
Пример #21
0
        /// <summary>
        /// Run the external diff command on a given file or a list of files
        /// </summary>
        public void GitDiff(string tag, List <string> files)
        {
            string list = QuoteAndFlattenPaths(files);

            if (list == "\"\"") // For now, we don't want to match all paths but only diff selected files
            {
                App.PrintStatusMessage("Diffing: No files selected and we don't want to match all paths.", MessageType.General);
                return;
            }
            App.PrintStatusMessage("Diffing " + list, MessageType.General);
            RunCmd("difftool " + ClassDiff.GetDiffCmd() + " " + tag + " -- " + list, true);
        }
Пример #22
0
 /// <summary>
 /// Import a set of custom tools from a file
 /// </summary>
 private void ImportToolMenuItemClick(object sender, EventArgs e)
 {
     if (openTools.ShowDialog() == DialogResult.OK)
     {
         ClassCustomTools newTools = ClassCustomTools.Load(openTools.FileName);
         if (newTools != null)
         {
             App.CustomTools = newTools;
             App.PrintStatusMessage("Loaded custom tools from " + openTools.FileName, MessageType.General);
         }
     }
 }
Пример #23
0
        /// <summary>
        /// Loads username/email for all repos in this workspace.
        /// Removes repos that are not valid.
        /// </summary>
        public void InitAll()
        {
            // Get the user name and email for each repo adding invalid ones to the list
            List <ClassRepo> invalidRepos = Repos.Where(r => r.Init() == false).ToList();

            // Remove all invalid repos from the workspace
            foreach (var r in invalidRepos)
            {
                App.PrintStatusMessage("Removing invalid repo " + r, MessageType.General);
                Delete(r);
            }
        }
Пример #24
0
 /// <summary>
 /// Load workspace given the workspace file name.
 /// </summary>
 public static bool Load(string name)
 {
     App.PrintStatusMessage("Loading workspace: " + name, MessageType.General);
     if (App.Repos.Load(name, false))    // Load operation (not merge)
     {
         AddLRU(name);
         Properties.Settings.Default.WorkspaceFile = name;
         return(true);
     }
     App.PrintStatusMessage("Load cancelled. Current workspace file: " + Properties.Settings.Default.WorkspaceFile, MessageType.General);
     return(false);
 }
Пример #25
0
        /// <summary>
        /// Open a command prompt at the specific directory
        /// </summary>
        public static void CommandPromptHere(string where)
        {
            try
            {
                Directory.SetCurrentDirectory(where);
                App.PrintStatusMessage("Command prompt at " + where, MessageType.General);
                Process proc = new Process();
                proc.StartInfo.UseShellExecute = false;

                // Add all environment variables listed
                foreach (var envar in Env)
                {
                    proc.StartInfo.EnvironmentVariables.Add(envar.Key, envar.Value);
                }

                if (IsMono())
                {
                    // Opening an command terminal is platform-specific and depends on the desktop environment which you use,
                    // and which terminal application is installed
                    if (File.Exists(@"/usr/bin/gnome-terminal"))
                    {
                        proc.StartInfo.FileName  = @"/usr/bin/gnome-terminal";
                        proc.StartInfo.Arguments = "--working-directory=" + where;
                    }
                    else if (File.Exists(@"/usr/bin/konsole"))
                    {
                        proc.StartInfo.FileName  = @"/usr/bin/konsole";
                        proc.StartInfo.Arguments = "--workdir " + where;
                    }
                    else if (File.Exists(@"/usr/bin/xterm"))
                    {
                        proc.StartInfo.FileName  = @"/usr/bin/xterm";
                        proc.StartInfo.Arguments = "-e \"cd " + where + "; bash\"";
                    }
                    else
                    {
                        throw new Exception("Unable to identify a terminal shell program for this distro. Please report this issue - thank you!");
                    }
                }
                else
                {
                    proc.StartInfo.FileName = "cmd.exe";
                }
                proc.Start();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Command Prompt Here error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
Пример #26
0
        /// <summary>
        /// Executes a shell command
        /// </summary>
        public static string ExecuteShellCommand(string cmd, string args)
        {
            App.PrintStatusMessage("Shell execute: " + cmd + " " + args, MessageType.Command);

            // WAR: Shell execute is platform-specific
            if (IsMono())
            {
                return(Exec.Run(cmd, args).ToString());
            }
            else
            {
                args = "/c " + cmd + " " + args;
                return(Exec.Run("cmd.exe", args).ToString());
            }
        }
Пример #27
0
        /// <summary>
        /// Import workspace given the file name.
        /// If the file name is null, return false.
        /// </summary>
        public static bool Import(string name)
        {
            if (name == null)
            {
                return(false);
            }

            App.PrintStatusMessage("Importing workspace: " + name, MessageType.General);
            if (App.Repos.Load(name, true))     // Merge loaded repos with the current set
            {
                AddLRU(name);
                return(true);
            }
            App.PrintStatusMessage("Import cancelled. Current workspace file: " + Properties.Settings.Default.WorkspaceFile, MessageType.General);
            return(false);
        }
Пример #28
0
        /// <summary>
        /// Save workspace given the file name.
        /// If the file name is null, save the current workspace.
        /// </summary>
        public static bool Save(string name)
        {
            if (name == null)
            {
                name = Properties.Settings.Default.WorkspaceFile;
            }

            App.PrintStatusMessage("Saving workspace: " + name, MessageType.General);
            if (App.Repos.Save(name))
            {
                AddLRU(name);
                Properties.Settings.Default.WorkspaceFile = name;
                return(true);
            }
            return(false);
        }
Пример #29
0
 /// <summary>
 /// Save current set of tools to a given file.
 /// Returns true if save successful.
 /// If save failed, return false and print the error message to a main pane.
 /// </summary>
 public bool Save(string name)
 {
     try
     {
         XmlSerializer serializer = new XmlSerializer(typeof(ClassCustomTools));
         using (TextWriter textWriter = new StreamWriter(name))
         {
             serializer.Serialize(textWriter, this);
         }
     }
     catch (Exception ex)
     {
         App.PrintStatusMessage("Error saving custom tools: " + ex.Message, MessageType.Error);
         return(false);
     }
     return(true);
 }
Пример #30
0
 /// <summary>
 /// Write back internal data into .netrc file
 /// </summary>
 private void SaveNetrc(string filename)
 {
     try
     {
         using (StreamWriter file = new StreamWriter(filename))
         {
             foreach (var machine in netrc)
             {
                 file.WriteLine(string.Format("machine {0} login {1} password {2}", machine.Key, machine.Value.Item1, machine.Value.Item2));
             }
         }
     }
     catch (Exception ex)
     {
         App.PrintStatusMessage(ex.Message, MessageType.Error);
         MessageBox.Show(ex.Message, "Error writing .netrc file", MessageBoxButtons.OK, MessageBoxIcon.Error);
     }
 }