Skip to content

Instantly share code, notes, and snippets.

@emsifa
Last active August 16, 2018 03:04
Show Gist options
  • Save emsifa/447d072e4af538c65bc0b39a5467c0db to your computer and use it in GitHub Desktop.
Save emsifa/447d072e4af538c65bc0b39a5467c0db to your computer and use it in GitHub Desktop.
PHP class to detect ignored files by .gitignore
<?php
namespace Emsifa\Stuble;
class Gitignore
{
protected $gitignoreFile;
protected $patterns = [];
public function __construct($gitignoreFile)
{
$this->gitignoreFile = $gitignoreFile;
$this->patterns = $this->parseFile($gitignoreFile);
}
public function getBaseDirectory()
{
return realpath(dirname($this->gitignoreFile));
}
public function getParsedPatterns()
{
return $this->patterns;
}
public function isIgnoring($filepath)
{
foreach ($this->getParsedPatterns() as $pattern) {
if ($pattern['regex']) {
$match = (bool) preg_match($pattern['regex'], $filepath);
} elseif ($pattern['is_dir']) {
$match = strpos($filepath, $pattern['path']) === 0;
} else {
$match = $pattern['path'] == $filepath;
}
if ($match) {
return !$pattern['is_negate'];
}
}
return false;
}
protected function parseFile($file)
{
$content = file_get_contents($file);
$lines = explode("\n", $content);
$patterns = [];
foreach ($lines as $line) {
$line = trim($line);
$isEmpty = empty($line);
$isComment = substr($line, 0, 1) == "#";
if ($isEmpty || $isComment) {
continue;
}
$line = explode("#", $line)[0];
$pattern = $this->parsePattern($line);
if ($pattern['is_negate']) {
// Make negation as priority
array_unshift($patterns, $pattern);
} else {
array_push($patterns, $pattern);
}
}
return $patterns;
}
protected function parsePattern($line)
{
$dir = $this->getBaseDirectory();
$isNegate = substr($line, 0, 1) == "!";
$hasAsterisk = is_int(strpos($line, "*"));
$path = $isNegate ? $dir.'/'.trim(substr($line, 1), '/') : $dir.'/'.trim($line, '/');
$regex = $hasAsterisk ? "/".str_replace("\\*", "[^\/]+", preg_quote($path, "/"))."/" : null;
return [
'pattern' => $line,
'path' => $path,
'regex' => $regex,
'is_negate' => $isNegate,
'is_dir' => !$hasAsterisk ? is_dir($path) : false,
];
}
}
<?php
$gitignore = new Gitignore(__DIR__.'/.gitignore');
$isIgnoringAutoload = $gitignore->isIgnoring(__DIR__.'/vendor/autoload.php'); // true|false
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment