diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -150,6 +150,8 @@ 'PhutilDocblockParserTestCase' => 'parser/__tests__/PhutilDocblockParserTestCase.php', 'PhutilEditDistanceMatrix' => 'utils/PhutilEditDistanceMatrix.php', 'PhutilEditDistanceMatrixTestCase' => 'utils/__tests__/PhutilEditDistanceMatrixTestCase.php', + 'PhutilEditorConfig' => 'parser/PhutilEditorConfig.php', + 'PhutilEditorConfigTestCase' => 'parser/__tests__/PhutilEditorConfigTestCase.php', 'PhutilEmailAddress' => 'parser/PhutilEmailAddress.php', 'PhutilEmailAddressTestCase' => 'parser/__tests__/PhutilEmailAddressTestCase.php', 'PhutilEmptyAuthAdapter' => 'auth/PhutilEmptyAuthAdapter.php', @@ -587,6 +589,7 @@ 'PhutilDisqusAuthAdapter' => 'PhutilOAuthAuthAdapter', 'PhutilDocblockParserTestCase' => 'PhutilTestCase', 'PhutilEditDistanceMatrixTestCase' => 'PhutilTestCase', + 'PhutilEditorConfigTestCase' => 'PhutilTestCase', 'PhutilEmailAddressTestCase' => 'PhutilTestCase', 'PhutilEmptyAuthAdapter' => 'PhutilAuthAdapter', 'PhutilErrorHandlerTestCase' => 'PhutilTestCase', diff --git a/src/parser/PhutilEditorConfig.php b/src/parser/PhutilEditorConfig.php new file mode 100644 --- /dev/null +++ b/src/parser/PhutilEditorConfig.php @@ -0,0 +1,97 @@ +rootPath = $root; + + $paths = id(new FileFinder($root)) + ->withType('f') + ->withName('.editorconfig') + ->find(); + + foreach ($paths as $path) { + $this->addEditorConfigFile(Filesystem::resolvePath($path, $root)); + } + } + + private function addEditorConfigFile($path) { + $file = Filesystem::readFile($path); + $config = phutil_ini_decode($file); + + $path = dirname($path); + $this->configs[$path] = array(); + + foreach ($config as $key => $value) { + if (preg_match('@/@', $key)) { + $this->configs[$path][phutil_glob_to_regex('**/'.$key)] = $value; + } else if (preg_match('@^/@', $key)) { + $this->configs[$path][phutil_glob_to_regex(substr($key, 1))] = $value; + } else { + $this->configs[$path][phutil_glob_to_regex($key)] = $value; + } + } + } + + public function getConfig($path, $key) { + $config = $this->config; + $parts = explode(DIRECTORY_SEPARATOR, $path); + + foreach ($parts as $part) { + $config = idx($config, $part); + } + } + + public function setConfig($path, $key, $value) { + foreach ($this->configs as $config_path => $config) { + if (Filesystem::isDescendant($path, $config_path)) { + foreach ($config as $config_key => $config_value) { + + } + } + } + } + + public function matches($path) { + + } + + + + + /** + * Return the paths of all EditorConfig files that were found. + * + * @return list + */ + public function getPaths() { + $paths = array(); + + foreach (array_keys($this->configs) as $path) { + $paths[] = $path.'/.editorconfig'; + } + + return $paths; + } + + /** + * Return the root path. + * + * @return string + */ + public function getRootPath() { + return $this->rootPath; + } + +} diff --git a/src/parser/__tests__/PhutilEditorConfigTestCase.php b/src/parser/__tests__/PhutilEditorConfigTestCase.php new file mode 100644 --- /dev/null +++ b/src/parser/__tests__/PhutilEditorConfigTestCase.php @@ -0,0 +1,50 @@ + array( + dirname(__FILE__).'/editorconfig/.editorconfig', + dirname(__FILE__).'/editorconfig/subdir1/.editorconfig', + dirname(__FILE__).'/editorconfig/subdir2/.editorconfig', + ), + dirname(__FILE__).'/editorconfig/subdir1' => array( + dirname(__FILE__).'/editorconfig/subdir1/.editorconfig', + ), + dirname(__FILE__).'/editorconfig/subdir2' => array( + dirname(__FILE__).'/editorconfig/subdir2/.editorconfig', + ), + dirname(__FILE__).'/../../../' => array( + Filesystem::resolvePath('.editorconfig', dirname(__FILE__).'/../../..'), + dirname(__FILE__).'/editorconfig/.editorconfig', + dirname(__FILE__).'/editorconfig/subdir1/.editorconfig', + dirname(__FILE__).'/editorconfig/subdir2/.editorconfig', + ), + ); + + foreach ($tests as $input => $expect) { + $editorconfig = new PhutilEditorConfig($input); + $this->assertEqual($expect, $editorconfig->getPaths()); + } + } + + public function testGetRootPath() { + $tests = array( + dirname(__FILE__) => dirname(__FILE__), + dirname(__FILE__).'/editorconfig/subdir1' + => dirname(__FILE__).'/editorconfig/subdir1', + dirname(__FILE__).'/editorconfig/subdir2' + => dirname(__FILE__).'/editorconfig/subdir2', + ); + + foreach ($tests as $input => $expect) { + $editorconfig = new PhutilEditorConfig($input); + $this->assertEqual($expect, $editorconfig->getRootPath()); + } + } + +} diff --git a/src/parser/__tests__/editorconfig/.editorconfig b/src/parser/__tests__/editorconfig/.editorconfig new file mode 100644 diff --git a/src/parser/__tests__/editorconfig/subdir1/.editorconfig b/src/parser/__tests__/editorconfig/subdir1/.editorconfig new file mode 100644 diff --git a/src/parser/__tests__/editorconfig/subdir2/.editorconfig b/src/parser/__tests__/editorconfig/subdir2/.editorconfig new file mode 100644 --- /dev/null +++ b/src/parser/__tests__/editorconfig/subdir2/.editorconfig @@ -0,0 +1 @@ +root = true