Commit 444a47ce authored by Neil Drumm's avatar Neil Drumm 👋
Browse files

Issue #3300976: Simplify and correct Git instructions

parent e72802e9
Loading
Loading
Loading
Loading
+0 −38
Original line number Diff line number Diff line
<?php

/**
 * @file
 *   Provides the administrative interface changing git documentation in the database.
 */

/**
 * Provide the settings form.
 */
function project_git_instructions_settings_form($form, &$form_state) {
  $form['project_git_instructions_git_repository_url_authenticated'] = array(
    '#title' => t('Repository URL for Authenticated Users'),
    '#description' => t('The preferred URL style. You can use variables here.'),
    '#type' => 'textfield',
    '#default_value' => variable_get('project_git_instructions_git_repository_url_authenticated', '@git_username@git.drupal.org:project/@project_name'),
  );
  $form['project_git_instructions_git_repository_url_anonymous'] = array(
    '#title' => t('Repository URL for Anonymous Users'),
    '#description' => t('The preferred URL style. You can use variables here.'),
    '#type' => 'textfield',
    '#default_value' => variable_get('project_git_instructions_git_repository_url_anonymous', 'http://git.drupal.org/project/@project_name'),
  );
  $form['project_git_instructions_git_sandbox_repository_url_authenticated'] = array(
    '#title' => t('Repository URL for Authenticated Users (Sandbox)'),
    '#description' => t('The preferred URL style. You can use variables here.'),
    '#type' => 'textfield',
    '#default_value' => variable_get('project_git_instructions_git_sandbox_repository_url_authenticated', '@git_username@git.drupal.org:sandbox/@project_username/@project_name'),
  );
  $form['project_git_instructions_git_sandbox_repository_url_anonymous'] = array(
    '#title' => t('Repository URL for Anonymous Users (Sandbox)'),
    '#description' => t('The preferred URL style. You can use variables here.'),
    '#type' => 'textfield',
    '#default_value' => variable_get('project_git_instructions_git_sandbox_repository_url_anonymous', 'http://git.drupal.org/sandbox/@project_username/@project_name'),
  );

  return system_settings_form($form);
}
+13 −207
Original line number Diff line number Diff line
@@ -14,14 +14,7 @@ function project_git_instructions_menu() {
    'page arguments' => array(1),
    'type' => MENU_LOCAL_TASK,
  );
  $items['admin/config/project/project-git-instructions'] = array(
    'title' => 'Project Git Instructions Configuration',
    'description' => 'Change the documentation in the database.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('project_git_instructions_settings_form'),
    'access arguments' => array('administer site configuration'),
    'file' => 'project_git_instructions.admin.inc',
  );

  return $items;
}

@@ -73,8 +66,6 @@ function project_git_instructions_visibility($node) {
 * @return array Default replacements formatted for t().
 */
function project_git_instructions_get_defaults($node, $version = NULL) {
  global $user;

  if ($repo = versioncontrol_project_repository_load($node->nid)) {
    $repo_name = $repo->name;
  }
@@ -82,44 +73,20 @@ function project_git_instructions_get_defaults($node, $version = NULL) {
    // Fallback, just after creation the repo object above might not be available.
    $repo_name = $node->field_project_machine_name[LANGUAGE_NONE][0]['value'];
  }
  $project_url_name = check_plain(drupal_encode_path($repo_name));

  // Make the most common set of default replacement variables we can.
  $defaults = [
    '@project_nid' => $node->nid,
    '@project_name' => $project_url_name,
    '@uri' => $repo_name,
    '%title' => $node->title,
    '@project_fullname' => preg_replace('#\W#', '_', drupal_strtolower($node->title)),
    '@newbranch' => '1.0.x',
    '@branch' => '',
    '@auth_project_url' => $repo ? $repo->remoteUrl('ssh') : '',
    '@anon_project_url' => $repo ? $repo->remoteUrl() : '',
    '!git_access_link' => l('Git access page', 'user/' . $GLOBALS['user']->uid . '/git'),
  ];
  if ($version) {
    $defaults['@branch'] = ' --branch ' . escapeshellarg($version);
  }

  if (isset($user->git_username)) {
    $defaults['@git_username'] = $user->git_username;
  }

  $defaults['@uid'] = $user->uid;

  if (isset($user->mail)) {
    $defaults['@email'] = $user->mail;
  }
  $defaults['!git_access_link'] = l('Git access page', 'user/' . $user->uid . '/git');

  // URLs now contain the creator's git username so grab that
  $project_user = user_load($node->uid);
  $defaults['@project_username'] = $project_user->git_username;

  // These are special variables and need to be run through t() in advance.
  // We generate an auth url even for non-maintainers. Of course it won't work if they see it and use it.
  $defaults['@auth_project_url'] = t(variable_get('project_git_instructions_git_repository_url_authenticated', '@git_username@git.drupal.org:project/@project_name'), $defaults);
  $defaults['@anon_project_url'] = t(variable_get('project_git_instructions_git_repository_url_anonymous', 'http://git.drupal.org/project/@project_name'), $defaults);
  $defaults['@auth_sandbox_url'] = t(variable_get('project_git_instructions_git_sandbox_repository_url_authenticated', '@git_username@git.drupal.org:sandbox/@project_username/@project_name'), $defaults);
  $defaults['@anon_sandbox_url'] = t(variable_get('project_git_instructions_git_sandbox_repository_url_anonymous', 'http://git.drupal.org/sandbox/@project_username/@project_name'), $defaults);

  return $defaults;
}

@@ -127,8 +94,6 @@ function project_git_instructions_get_defaults($node, $version = NULL) {
 * Produce html code for the instructions tab.
 */
function project_git_instructions_project_tab($node, $version = NULL, $do_nonmaintainer = NULL) {
  global $user;

  if ($version === '^') {
    $version = NULL;
  }
@@ -146,8 +111,7 @@ function project_git_instructions_project_tab($node, $version = NULL, $do_nonmai
  // Handle the nonmaintainer parameter.
  $do_nonmaintainer = !empty($do_nonmaintainer) && $do_nonmaintainer == 'nonmaintainer';

  $is_maintainer = project_git_instructions_version_is_privileged($node, $user);
  $is_sandbox = project_promote_project_is_sandbox($node);
  $is_maintainer = project_git_instructions_version_is_privileged($node, $GLOBALS['user']);

  // Load array of versions, all branches for dev releases.
  $result = (new EntityFieldQuery())
@@ -199,81 +163,12 @@ function project_git_instructions_project_tab($node, $version = NULL, $do_nonmai

  // Grab the default replacement patterns.
  $defaults = project_git_instructions_get_defaults($node, $version);
  if ($is_maintainer && empty($defaults['@git_username'])) {
  if ($is_maintainer && empty($GLOBALS['user']->git_username)) {
    return t('<h1>Account Settings Missing</h1>
<p>Your Git username has not been set yet. Please set one at the !git_access_link.</p>', $defaults);
  }
  elseif ($has_versions) {
    if ($is_maintainer && $is_sandbox) {
      $content[] = ['#markup' => t('<h2>One-Time Only</h2>
<h3>Setting up repository for the first time</h3>
<div class="codeblock">
<code>git clone@branch @auth_sandbox_url @project_fullname</code><br>
<code>cd @project_fullname</code><br />
</div>
Not working for you? See <a href="/node/1065850">Troubleshooting Git clone</a>.

<h2>Routinely</h2>
The headings below are not sequential. What you choose to do depends on where you are in your process.
<h3>Checking your repository status</h3>
To see what you will commit by running <code>git commit</code> and what you could commit by running <code>git add</code> before running <code>git commit</code>.
<div class="codeblock">
<code>git status</code><br />
</div>
<h3>Switching to a different branch</h3>
When you clone the repository you have access to all the branches and tags. The first command shows your choices. The second command makes the switch. See <a href="/node/1066342">branching and tagging</a> for details.
<div class="codeblock">
<code>git branch -a</code><br />
<code>git checkout [branchname]</code><br />
</div>
<h3>Committing all changes locally</h3>
After making changes, add and commit them. Do not begin commit messages with the # symbol. See <a href="/node/52287">Commit messages</a> for details.
<div class="codeblock">
<code>git add -A</code><br />
<code>git commit -m &quot;Issue #[issue number] by [comma-separated usernames]: [Short summary of the change].&quot;</code>
</div>
<h3>Pushing your code back to the repository on Drupal.org</h3>
<div class="codeblock">
<code>git push -u origin HEAD</code>
</div>
<h2>Patching</h2>
<p>Contributing changes with patches is being replaced with <a href="/docs/develop/git/using-git-to-contribute-to-drupal/creating-issue-forks-and-merge-requests">issue forks and merge requests</a>.</p>
<h3>Getting ready to create or apply patches</h3>
If you have not already cloned the repository, follow the directions above for setting up this repository in your local environment. Be sure you are on the branch you wish to patch, then ensure it is up-to-date with the following command:
<div class="codeblock">
<code>git pull origin</code>
</div>

<h3>Creating a patch</h3>
For most improvements, use the following command after making your changes:
<div class="codeblock">
<code>git diff > [description]-[issue-number]-[comment-number].patch</code><br />
</div>
For more complex improvements that require adding/removing files, work over the course of multiple days including Git commits, or collaboration with others, see the <a href="/node/1054616">Advanced patch workflow</a>.

<h3>Applying a patch </h3>
Download the patch to your working directory. Apply the patch with the following command:
<div class="codeblock">
<code>git apply -v [patchname.patch]</code><br />
</div>

To avoid accidentally including the patch file in future commits, remove it:
<div class="codeblock">
<code>rm [patchname.patch]</code><br />
</div>

<h3>When you’re done: Reverting uncommited changes</h3>
Revert changes to a specific file:
<div class="codeblock">
<code>git checkout [filename]</code><br />
</div>

Revert changes to the whole working tree:
<div class="codeblock">
<code>git reset --hard</code><br />
</div>', $defaults)];
    }
    if ($is_maintainer && !$is_sandbox) {
    if ($is_maintainer) {
      $content[] = ['#markup' => t('<h2>One-Time Only</h2>
<h3>Setting up this repository in your local environment for the first time</h3>
If you have just created a project or you already have a local repository, skip this step.
@@ -359,66 +254,8 @@ git push origin tag [tag name]</code></div>

<p>Once you’ve pushed the properly-formed tag or branch, see <a href="/node/1068944">Creating a project release</a> for directions to actually create the release node.</p>', $defaults)];
    }
    if (!$is_maintainer && $is_sandbox) {
      $content[] = ['#markup' => t('<h2>One-Time Only</h2>
<h3>Setting up this repository locally for the first time</h3>
<div class="codeblock">
<code>git clone@branch @anon_sandbox_url @project_fullname</code><br>
<code>cd @project_fullname</code>
</div>
Not working for you? See <a href="/node/1065850">Troubleshooting Git clone</a>.

<h2>Routinely</h2>
The headings below are not sequential. What you choose to do depends on where you are in your process.
<h3>Checking your repository status</h3>
To see what you will commit by running <code>git commit</code> and what you could commit by running <code>git add</code> before running <code>git commit</code>.
<div class="codeblock">
<code>git status</code><br />
</div>
<h3>Switching to a different branch</h3>
When you clone the repository you have access to all the branches and tags. The first command shows your choices. The second command makes the switch. See <a href="/node/1066342">branching and tagging</a> for details.
<div class="codeblock">
<code>git branch -a</code><br />
<code>git checkout [branchname]</code><br />
</div>
<h2>Patching</h2>
<p>Contributing changes with patches is being replaced with <a href="/docs/develop/git/using-git-to-contribute-to-drupal/creating-issue-forks-and-merge-requests">issue forks and merge requests</a>.</p>
<h3>Getting ready to create or apply patches</h3>
If you have not already cloned the repository, follow the directions above for setting up this repository in your local environment. Be sure you are on the branch you wish to patch, then ensure it is up-to-date with the following command:
<div class="codeblock">
<code>git pull origin</code>
</div>

<h3>Creating a patch</h3>
For most improvements, use the following command after making your changes:
<div class="codeblock">
<code>git diff > [description]-[issue-number]-[comment-number].patch</code><br />
</div>
For more complex improvements that require adding/removing files, work over the course of multiple days including Git commits, or collaboration with others, see the <a href="/node/1054616">Advanced patch workflow</a>.

<h3>Applying a patch </h3>
Download the patch to your working directory. Apply the patch with the following command:
<div class="codeblock">
<code>git apply -v [patchname.patch]</code><br />
</div>

To avoid accidentally including the patch file in future commits, remove it:
<div class="codeblock">
<code>rm [patchname.patch]</code><br />
</div>

<h3>When you’re done: Reverting uncommited changes</h3>
Revert changes to a specific file:
<div class="codeblock">
<code>git checkout [filename]</code><br />
</div>

Revert changes to the whole working tree:
<div class="codeblock">
<code>git reset --hard</code><br />
</div>', $defaults)];
    }
    if (!$is_maintainer && !$is_sandbox) {
    else {
      // Is not maintainer.
      $content[] = ['#markup' => t('<h2>One-Time Only</h2>
<h3>Setting up repository for the first time</h3>
<div class="codeblock">
@@ -478,36 +315,10 @@ Revert changes to the whole working tree:
    }
  }
  else { // !$has_versions
    if ($is_maintainer && $is_sandbox) {
      $content[] = ['#markup' => t('<h2>Empty Sandbox Repository</h2>
<h3>Setting up this repository for the first time:</h3>
<p>You will be prompted to enter your Drupal.org password after the last step (and any time you make requests from Drupal.org) if you have not uploaded an SSH key or if your SSH key fails. See <a href="/node/1027094">Authenticate with Git on Drupal.org</a> for details.</p>
<div class="codeblock">
<code>mkdir @project_fullname</code><br /><br />
<code>cd @project_fullname</code><br /><br />
<code>git init</code><br /><br />
<code>git checkout -b @newbranch</code><br /><br />
<code>echo "%title" > README.txt</code><br /><br />
<code>git add README.txt</code><br /><br />
<code>git commit -m "Initial commit."</code><br /><br />
<code>git remote add origin @auth_sandbox_url</code><br /><br />
<code>git push origin @newbranch</code><br />
</div>
<br />
<h3>A note about your sandbox and function names:</h3>
<p>Contributed modules on Drupal.org typically use their project’s shortname as the prefix to the module’s functions. Sandbox shortnames are numbers, which are not valid function names. If you intend to release your code for Drupal.org someday, choose a prefix that isn’t being used on Drupal.org already. There is, unfortunately, no guarantee it will still be available when you’re ready to release, but you’ll save a step if it is. To check, type https://www.drupal.org/project/[the_name_you_want].</p>

<p>When you’ve completed these steps, <a href="">refresh this page</a> for further direction.</p>

<p><strong>Note:</strong> You have created a local repository. You will not need to complete the One-Time clone on the next page unless you delete your local repository or set up on a different machine. Then, you’ll need to perform the One-time setup, as will co-maintainers.</p>', $defaults)];
    }
    if ($is_maintainer && !$is_sandbox) {
    if ($is_maintainer) {
      $content[] = ['#markup' => t('<h2>Empty Repository</h2>
<h3>Setting up this repository for the first time</h3>
<p>You will be prompted to enter your Drupal.org password after the
first and last step if you have not uploaded an SSH Key or if your SSH
key fails. See <a href="/node/1027094">Authenticating with Git on
Drupal.org</a> for details.</p>
<p>See <a href="/node/1027094">Git Authentication for Drupal.org Projects</a> for information about setting up SSH keys and other ways to authenticate.</p>
<div class="codeblock">
<code>mkdir @uri</code><br /><br />
<code>cd @uri</code><br /><br />
@@ -523,7 +334,7 @@ Drupal.org</a> for details.</p>

<p><strong>Note:</strong> You have created a local repository. You will not need to complete the One-Time clone on the next page unless you delete your local repository or set up on a different machine. Then, you’ll need to perform the One-time setup, as will co-maintainers.</p>', $defaults)];
    }
    if (!$is_maintainer) {
    else {
      $content[] = ['#markup' => t('<h2>Empty Repository</h2>
<p>No code is available for %title. <a href="/project/issues/@uri?categories=All">File an issue</a> or contact a maintainer if you have questions.</p>', $defaults)];
    }
@@ -605,12 +416,7 @@ function project_git_instructions_version_picker_form_submit($form, &$form_state
 * @param $project The project name
 * @return boolean Weather the current user is privileged
 */
function project_git_instructions_version_is_privileged($project, $account = NULL) {
  if (is_null($account)) {
    global $user;
    $account = $user;
  }

function project_git_instructions_version_is_privileged($project, $account) {
  $repo = versioncontrol_project_repository_load($project->nid);
  if ($repo === FALSE || !$repo instanceof VersioncontrolGitRepository) {
    // Couldn't find a git repo on this project, so definitely a no-go.