private async Task <string> DownloadFromScpAsync(GerritSettings settings)
        {
            // This is a very quick and dirty "implementation" of the scp
            // protocol. By sending the 0's as input, we trigger scp to
            // send the file.

            string content = await GerritUtil.RunGerritCommandAsync(
                _mainForm,
                _gitUiCommands.GitModule,
                "scp -f hooks/commit-msg",
                settings.DefaultRemote,
                new byte[] { 0, 0, 0, 0, 0, 0, 0 }).ConfigureAwait(false);

            // The first line of the output contains the file we're receiving
            // in a format like "C0755 4248 commit-msg".

            if (string.IsNullOrEmpty(content))
            {
                return(null);
            }

            int index = content.IndexOf('\n');

            if (index == -1)
            {
                return(null);
            }

            string header = content.Substring(0, index);

            if (!header.EndsWith(" commit-msg"))
            {
                return(null);
            }

            // This looks like a valid scp response; return the rest of the
            // response.

            content = content.Substring(index + 1);

            // The file should be terminated by a nul.

            index = content.LastIndexOf((char)0);

            Debug.Assert(index == content.Length - 1, "index == content.Length - 1");

            if (index != -1)
            {
                content = content.Substring(0, index);
            }

            return(content);
        }
Пример #2
0
        protected override void OnLoad(EventArgs e)
        {
            if (DesignMode)
            {
                return;
            }

            Settings = GerritSettings.Load(Module);

            if (Settings == null)
            {
                Dispose();
                return;
            }

            base.OnLoad(e);
        }
        public static GerritSettings Load([CanBeNull] IWin32Window owner, [NotNull] IGitModule module)
        {
            if (module == null)
            {
                throw new ArgumentNullException(nameof(module));
            }

            string path = module.WorkingDir + ".gitreview";

            var result = new GerritSettings(module);

            try
            {
                if (!File.Exists(path))
                {
                    throw new GerritSettingsException(result._settingsErrorFileNotFound.Text);
                }

                bool inHeader = false;

                foreach (string line in File.ReadLines(path))
                {
                    string trimmed = line.Trim();

                    // Skip empty lines and comments.

                    if (trimmed.Length == 0 || trimmed[0] == '#')
                    {
                        continue;
                    }

                    // Look for the section header.

                    if (trimmed[0] == '[')
                    {
                        inHeader = trimmed.Trim('[', ']').Equals("gerrit", StringComparison.OrdinalIgnoreCase);
                    }
                    else if (inHeader)
                    {
                        // Split on the = and trim the parts.

                        string[] parts = trimmed.Split(new[] { '=' }, 2).Select(p => p.Trim()).ToArray();

                        // Ignore invalid lines.

                        if (parts.Length != 2 || parts[1].Length == 0)
                        {
                            continue;
                        }

                        // Get the parts of the config file.

                        switch (parts[0].ToLowerInvariant())
                        {
                        case "host": result.Host = parts[1]; break;

                        case "project": result.Project = parts[1]; break;

                        case "defaultbranch": result.DefaultBranch = parts[1]; break;

                        case "defaultremote": result.DefaultRemote = parts[1]; break;

                        case "defaultrebase": result.DefaultRebase = parts[1] != "0"; break;

                        case "port":
                            if (!int.TryParse(parts[1], out var value))
                            {
                                throw new GerritSettingsException(result._settingsErrorPortNotNumeric.Text);
                            }

                            result.Port = value;
                            break;
                        }
                    }
                }

                result.Validate();
            }
            catch (GerritSettingsException ex)
            {
                MessageBox.Show(owner, ex.Message, result._settingsError.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);

                return(null);
            }

            return(result);
        }
        private async Task InstallCommitMsgHookAsync()
        {
            await _mainForm.SwitchToMainThreadAsync();

            var settings = GerritSettings.Load(_mainForm, _gitUiCommands.GitModule);

            if (settings == null)
            {
                return;
            }

            var hooksFolderPath = _gitUiCommands.GitModule.ResolveGitInternalPath(HooksFolderName);

            if (!Directory.Exists(hooksFolderPath))
            {
                try
                {
                    Directory.CreateDirectory(hooksFolderPath);
                }
                catch
                {
                    MessageBox.Show(
                        _mainForm,
                        _installCommitMsgHookFolderCreationFailed.Text,
                        _installCommitMsgHookShortText.Text,
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Error);

                    return;
                }
            }

            var commitMessageHookPath = Path.Combine(hooksFolderPath, CommitMessageHookFileName);

            string content;

            try
            {
                content = await DownloadFromScpAsync(settings);
            }
            catch
            {
                content = null;
            }

            await _mainForm.SwitchToMainThreadAsync();

            if (content == null)
            {
                MessageBox.Show(
                    _mainForm,
                    _installCommitMsgHookDownloadFileFailed.Text,
                    _installCommitMsgHookShortText.Text,
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
            }
            else
            {
                File.WriteAllText(commitMessageHookPath, content);

                // Update the cache.

                HaveValidCommitMsgHook(_gitUiCommands.GitModule, true);
            }
        }