class ManageGitIgnoreTest

Same name in other branches
  1. 8.9.x core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Functional/ManageGitIgnoreTest.php \Drupal\Tests\Composer\Plugin\Scaffold\Functional\ManageGitIgnoreTest
  2. 10 core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Functional/ManageGitIgnoreTest.php \Drupal\Tests\Composer\Plugin\Scaffold\Functional\ManageGitIgnoreTest
  3. 11.x core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Functional/ManageGitIgnoreTest.php \Drupal\Tests\Composer\Plugin\Scaffold\Functional\ManageGitIgnoreTest

Tests to see whether .gitignore files are correctly managed.

The purpose of this test file is to run a scaffold operation and confirm that the files that were scaffolded are added to the repository's .gitignore file.

@group Scaffold

Hierarchy

Expanded class hierarchy of ManageGitIgnoreTest

File

core/tests/Drupal/Tests/Composer/Plugin/Scaffold/Functional/ManageGitIgnoreTest.php, line 20

Namespace

Drupal\Tests\Composer\Plugin\Scaffold\Functional
View source
class ManageGitIgnoreTest extends TestCase {
    use ExecTrait;
    use AssertUtilsTrait;
    
    /**
     * The root of this project.
     *
     * Used to substitute this project's base directory into composer.json files
     * so Composer can find it.
     *
     * @var string
     */
    protected $projectRoot;
    
    /**
     * Directory to perform the tests in.
     *
     * @var string
     */
    protected $fixturesDir;
    
    /**
     * The Symfony FileSystem component.
     *
     * @var \Symfony\Component\Filesystem\Filesystem
     */
    protected $fileSystem;
    
    /**
     * The Fixtures object.
     *
     * @var \Drupal\Tests\Composer\Plugin\Scaffold\Fixtures
     */
    protected $fixtures;
    
    /**
     * {@inheritdoc}
     */
    protected function setUp() : void {
        $this->fileSystem = new Filesystem();
        $this->fixtures = new Fixtures();
        $this->fixtures
            ->createIsolatedComposerCacheDir();
        $this->projectRoot = $this->fixtures
            ->projectRoot();
    }
    
    /**
     * {@inheritdoc}
     */
    protected function tearDown() : void {
        // Remove any temporary directories et. al. that were created.
        $this->fixtures
            ->tearDown();
    }
    
    /**
     * Creates a system-under-test and initialize a git repository for it.
     *
     * @param string $fixture_name
     *   The name of the fixture to use from
     *   core/tests/Drupal/Tests/Component/Scaffold/fixtures.
     *
     * @return string
     *   The path to the fixture directory.
     */
    protected function createSutWithGit($fixture_name) {
        $this->fixturesDir = $this->fixtures
            ->tmpDir($this->getName());
        $sut = $this->fixturesDir . '/' . $fixture_name;
        $replacements = [
            'SYMLINK' => 'false',
            'PROJECT_ROOT' => $this->projectRoot,
        ];
        $this->fixtures
            ->cloneFixtureProjects($this->fixturesDir, $replacements);
        // .gitignore files will not be managed unless there is a git repository.
        $this->mustExec('git init', $sut);
        // Add some user info so git does not complain.
        $this->mustExec('git config user.email "test@example.com"', $sut);
        $this->mustExec('git config user.name "Test User"', $sut);
        $this->mustExec('git add .', $sut);
        $this->mustExec('git commit -m "Initial commit."', $sut);
        // Run composer install, but suppress scaffolding.
        $this->fixtures
            ->runComposer("install --no-ansi --no-scripts --no-plugins", $sut);
        return $sut;
    }
    
    /**
     * Tests scaffold command correctly manages the .gitignore file.
     */
    public function testManageGitIgnore() {
        // Note that the drupal-composer-drupal-project fixture does not
        // have any configuration settings related to .gitignore management.
        $sut = $this->createSutWithGit('drupal-composer-drupal-project');
        $this->assertFileDoesNotExist($sut . '/docroot/autoload.php');
        $this->assertFileDoesNotExist($sut . '/docroot/index.php');
        $this->assertFileDoesNotExist($sut . '/docroot/sites/.gitignore');
        // Run the scaffold command.
        $this->fixtures
            ->runScaffold($sut);
        $this->assertFileExists($sut . '/docroot/autoload.php');
        $this->assertFileExists($sut . '/docroot/index.php');
        $expected = <<<EOT
/build
/.csslintrc
/.editorconfig
/.eslintignore
/.eslintrc.json
/.gitattributes
/.ht.router.php
/autoload.php
/index.php
/robots.txt
/update.php
/web.config
EOT;
        // At this point we should have a .gitignore file, because although we did
        // not explicitly ask for .gitignore tracking, the vendor directory is not
        // tracked, so the default in that instance is to manage .gitignore files.
        $this->assertScaffoldedFile($sut . '/docroot/.gitignore', FALSE, $expected);
        $this->assertScaffoldedFile($sut . '/docroot/sites/.gitignore', FALSE, 'example.settings.local.php');
        $this->assertScaffoldedFile($sut . '/docroot/sites/default/.gitignore', FALSE, 'default.services.yml');
        $expected = <<<EOT
M docroot/.gitignore
?? docroot/sites/.gitignore
?? docroot/sites/default/.gitignore
EOT;
        // Check to see whether there are any untracked files. We expect that
        // only the .gitignore files themselves should be untracked.
        $stdout = $this->mustExec('git status --porcelain', $sut);
        $this->assertEquals(trim($expected), trim($stdout));
    }
    
    /**
     * Tests scaffold command does not manage the .gitignore file when disabled.
     */
    public function testUnmanagedGitIgnoreWhenDisabled() {
        // Note that the drupal-drupal fixture has a configuration setting
        // `"gitignore": false,` which disables .gitignore file handling.
        $sut = $this->createSutWithGit('drupal-drupal');
        $this->assertFileDoesNotExist($sut . '/docroot/autoload.php');
        $this->assertFileDoesNotExist($sut . '/docroot/index.php');
        // Run the scaffold command.
        $this->fixtures
            ->runScaffold($sut);
        $this->assertFileExists($sut . '/autoload.php');
        $this->assertFileExists($sut . '/index.php');
        $this->assertFileDoesNotExist($sut . '/.gitignore');
        $this->assertFileDoesNotExist($sut . '/docroot/sites/default/.gitignore');
    }
    
    /**
     * Tests appending to an unmanaged file, and confirm it is not .gitignored.
     *
     * If we append to an unmanaged (not scaffolded) file, and we are managing
     * .gitignore files, then we expect that the unmanaged file should not be
     * added to the .gitignore file, because unmanaged files should be committed.
     */
    public function testAppendToEmptySettingsIsUnmanaged() {
        $sut = $this->createSutWithGit('drupal-drupal-append-settings');
        $this->assertFileDoesNotExist($sut . '/autoload.php');
        $this->assertFileDoesNotExist($sut . '/index.php');
        $this->assertFileDoesNotExist($sut . '/sites/.gitignore');
        // Run the scaffold command.
        $this->fixtures
            ->runScaffold($sut);
        $this->assertFileExists($sut . '/autoload.php');
        $this->assertFileExists($sut . '/index.php');
        $this->assertScaffoldedFile($sut . '/sites/.gitignore', FALSE, 'example.sites.php');
        $this->assertScaffoldedFileDoesNotContain($sut . '/sites/.gitignore', 'settings.php');
    }
    
    /**
     * Tests scaffold command disables .gitignore management when git not present.
     *
     * The scaffold operation should still succeed if there is no 'git'
     * executable.
     */
    public function testUnmanagedGitIgnoreWhenGitNotAvailable() {
        // Note that the drupal-composer-drupal-project fixture does not have any
        // configuration settings related to .gitignore management.
        $sut = $this->createSutWithGit('drupal-composer-drupal-project');
        $this->assertFileDoesNotExist($sut . '/docroot/sites/default/.gitignore');
        $this->assertFileDoesNotExist($sut . '/docroot/index.php');
        $this->assertFileDoesNotExist($sut . '/docroot/sites/.gitignore');
        // Confirm that 'git' is available (n.b. if it were not, createSutWithGit()
        // would fail).
        $output = [];
        exec('git --help', $output, $status);
        $this->assertEquals(0, $status);
        // Modify our $PATH so that it begins with a path that contains an
        // executable script named 'git' that always exits with 127, as if git were
        // not found. Note that we run our tests using process isolation, so we do
        // not need to restore the PATH when we are done.
        $unavailableGitPath = $sut . '/bin';
        mkdir($unavailableGitPath);
        $bash = <<<SH
#!/bin/bash
exit 127

SH;
        file_put_contents($unavailableGitPath . '/git', $bash);
        chmod($unavailableGitPath . '/git', 0755);
        $oldPath = getenv('PATH');
        putenv('PATH=' . $unavailableGitPath . ':' . getenv('PATH'));
        // Confirm that 'git' is no longer available.
        $output = [];
        exec('git --help', $output, $status);
        $this->assertEquals(127, $status);
        // Run the scaffold command.
        $output = $this->mustExec('composer drupal:scaffold 2>&1', NULL);
        putenv('PATH=' . $oldPath . ':' . getenv('PATH'));
        $expected = <<<EOT
Scaffolding files for fixtures/drupal-assets-fixture:
  - Copy [web-root]/.csslintrc from assets/.csslintrc
  - Copy [web-root]/.editorconfig from assets/.editorconfig
  - Copy [web-root]/.eslintignore from assets/.eslintignore
  - Copy [web-root]/.eslintrc.json from assets/.eslintrc.json
  - Copy [web-root]/.gitattributes from assets/.gitattributes
  - Copy [web-root]/.ht.router.php from assets/.ht.router.php
  - Skip [web-root]/.htaccess: overridden in fixtures/drupal-composer-drupal-project
  - Copy [web-root]/sites/default/default.services.yml from assets/default.services.yml
  - Skip [web-root]/sites/default/default.settings.php: overridden in fixtures/scaffold-override-fixture
  - Copy [web-root]/sites/example.settings.local.php from assets/example.settings.local.php
  - Copy [web-root]/sites/example.sites.php from assets/example.sites.php
  - Copy [web-root]/index.php from assets/index.php
  - Skip [web-root]/robots.txt: overridden in fixtures/drupal-composer-drupal-project
  - Copy [web-root]/update.php from assets/update.php
  - Copy [web-root]/web.config from assets/web.config
Scaffolding files for fixtures/scaffold-override-fixture:
  - Copy [web-root]/sites/default/default.settings.php from assets/override-settings.php
Scaffolding files for fixtures/drupal-composer-drupal-project:
  - Skip [web-root]/.htaccess: disabled
  - Copy [web-root]/robots.txt from assets/robots-default.txt

EOT;
        $this->assertEquals($expected, $output);
        $this->assertFileExists($sut . '/docroot/index.php');
        $this->assertFileDoesNotExist($sut . '/docroot/sites/default/.gitignore');
    }

}

Members

Title Sort descending Modifiers Object type Summary
AssertUtilsTrait::assertScaffoldedFile protected function Asserts that a given file exists and is/is not a symlink.
AssertUtilsTrait::assertScaffoldedFileDoesNotContain protected function Asserts that a file does not exist or exists and does not contain a value.
ExecTrait::mustExec protected function Runs an arbitrary command.
ManageGitIgnoreTest::$fileSystem protected property The Symfony FileSystem component.
ManageGitIgnoreTest::$fixtures protected property The Fixtures object.
ManageGitIgnoreTest::$fixturesDir protected property Directory to perform the tests in.
ManageGitIgnoreTest::$projectRoot protected property The root of this project.
ManageGitIgnoreTest::createSutWithGit protected function Creates a system-under-test and initialize a git repository for it.
ManageGitIgnoreTest::setUp protected function
ManageGitIgnoreTest::tearDown protected function
ManageGitIgnoreTest::testAppendToEmptySettingsIsUnmanaged public function Tests appending to an unmanaged file, and confirm it is not .gitignored.
ManageGitIgnoreTest::testManageGitIgnore public function Tests scaffold command correctly manages the .gitignore file.
ManageGitIgnoreTest::testUnmanagedGitIgnoreWhenDisabled public function Tests scaffold command does not manage the .gitignore file when disabled.
ManageGitIgnoreTest::testUnmanagedGitIgnoreWhenGitNotAvailable public function Tests scaffold command disables .gitignore management when git not present.
PhpUnitWarnings::$deprecationWarnings private static property Deprecation warnings from PHPUnit to raise with @trigger_error().
PhpUnitWarnings::addWarning public function Converts PHPUnit deprecation warnings to E_USER_DEPRECATED.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.