diff --git a/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala b/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala index 81d4e86..9a4a713 100644 --- a/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala +++ b/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala @@ -318,7 +318,7 @@ getPathObjectId(git, path, revCommit).map { objectId => val paths = path.split("/") - val props = EditorConfigUtil.readProperties(git, branch, path) + val info = EditorConfigUtil.getEditorConfigInfo(git, branch, path) html.editor( branch = branch, @@ -328,9 +328,9 @@ content = JGitUtil.getContentInfo(git, path, objectId), protectedBranch = protectedBranch, commit = revCommit.getName, - newLineMode = EditorConfigUtil.getNewLineMode(props), - useSoftTabs = EditorConfigUtil.getUseSoftTabs(props), - tabSize = EditorConfigUtil.getTabWidth(props) + newLineMode = info.newLineMode, + useSoftTabs = info.useSoftTabs, + tabSize = info.tabSize ) } getOrElse NotFound() } @@ -442,8 +442,7 @@ // Download (This route is left for backword compatibility) responseRawFile(git, objectId, path, repository) } else { - val props = EditorConfigUtil.readProperties(git, id, path) - val tabSize = EditorConfigUtil.getTabWidth(props) + val info = EditorConfigUtil.getEditorConfigInfo(git, id, path) html.blob( branch = id, repository = repository, @@ -453,7 +452,7 @@ hasWritePermission = hasDeveloperRole(repository.owner, repository.name, context.loginAccount), isBlame = request.paths(2) == "blame", isLfsFile = isLfsFile(git, objectId), - tabSize = tabSize + tabSize = info.tabSize ) } } getOrElse NotFound() diff --git a/src/main/scala/gitbucket/core/util/EditorConfigUtil.scala b/src/main/scala/gitbucket/core/util/EditorConfigUtil.scala index edc13d8..3d9bac5 100644 --- a/src/main/scala/gitbucket/core/util/EditorConfigUtil.scala +++ b/src/main/scala/gitbucket/core/util/EditorConfigUtil.scala @@ -1,46 +1,53 @@ package gitbucket.core.util -import java.nio.charset.StandardCharsets +import java.io.IOException import editorconfig.{JGitResource, JGitResourcePath} import org.ec4j.core.model.PropertyType.{EndOfLineValue, IndentStyleValue} import org.ec4j.core.model.{PropertyType, Version} +import org.ec4j.core.parser.ParseException import org.ec4j.core.{EditorConfigConstants, EditorConfigLoader, ResourceProperties, ResourcePropertiesService} import org.eclipse.jgit.api.Git -import collection.JavaConverters._ - object EditorConfigUtil { - def readProperties(git: Git, rev: String, path: String): ResourceProperties = { - val resourcePropertiesService = ResourcePropertiesService - .builder() - .configFileName(EditorConfigConstants.EDITORCONFIG) - .rootDirectory(JGitResourcePath.RootDirectory(git, rev)) - .loader(EditorConfigLoader.of(Version.CURRENT)) - .keepUnset(true) - .build() + val TabSizeDefault: Int = 8 + val NewLineModeDefault: String = "auto" + val UseSoftTabsDefault = false - resourcePropertiesService.queryProperties(new JGitResource(git, rev, path)) - } + case class EditorConfigInfo( + tabSize: Int, + newLineMode: String, + useSoftTabs: Boolean + ) - def getTabWidth(props: ResourceProperties): Int = { - props.getValue[Integer](PropertyType.tab_width, 8, false) - } + def getEditorConfigInfo(git: Git, rev: String, path: String): EditorConfigInfo = { + try { + val resourcePropertiesService = ResourcePropertiesService + .builder() + .configFileName(EditorConfigConstants.EDITORCONFIG) + .rootDirectory(JGitResourcePath.RootDirectory(git, rev)) + .loader(EditorConfigLoader.of(Version.CURRENT)) + .keepUnset(true) + .build() - def getNewLineMode(props: ResourceProperties): String = { - props.getValue[EndOfLineValue](PropertyType.end_of_line, null, false) match { - case EndOfLineValue.cr => "cr" - case EndOfLineValue.lf => "lf" - case EndOfLineValue.crlf => "crlf" - case _ => "auto" - } - } - - def getUseSoftTabs(props: ResourceProperties): Boolean = { - props.getValue[IndentStyleValue](PropertyType.indent_style, IndentStyleValue.tab, false) match { - case IndentStyleValue.space => true - case IndentStyleValue.tab => false - case _ => false + val props = resourcePropertiesService.queryProperties(new JGitResource(git, rev, path)) + EditorConfigInfo( + tabSize = props.getValue[Integer](PropertyType.tab_width, TabSizeDefault, false), + newLineMode = props.getValue[EndOfLineValue](PropertyType.end_of_line, null, false) match { + case EndOfLineValue.cr => "cr" + case EndOfLineValue.lf => "lf" + case EndOfLineValue.crlf => "crlf" + case _ => "auto" + }, + props.getValue[IndentStyleValue](PropertyType.indent_style, null, false) match { + case IndentStyleValue.space => true + case IndentStyleValue.tab => false + case _ => false + } + ) + } catch { + case e: ParseException => EditorConfigInfo(TabSizeDefault, NewLineModeDefault, UseSoftTabsDefault) + case e: IOException => EditorConfigInfo(TabSizeDefault, NewLineModeDefault, UseSoftTabsDefault) } } } diff --git a/src/test/scala/gitbucket/core/util/EditorConfigUtilSpec.scala b/src/test/scala/gitbucket/core/util/EditorConfigUtilSpec.scala index b0bf60b..791a797 100644 --- a/src/test/scala/gitbucket/core/util/EditorConfigUtilSpec.scala +++ b/src/test/scala/gitbucket/core/util/EditorConfigUtilSpec.scala @@ -12,15 +12,15 @@ test("no EditorConfig file") { withTestRepository { git => createFile(git, "master", "README.md", "body", message = "commit1") - val props = EditorConfigUtil.readProperties(git, "master", "test.txt") - assert(EditorConfigUtil.getTabWidth(props) == 8) - assert(EditorConfigUtil.getUseSoftTabs(props) == false) - assert(EditorConfigUtil.getNewLineMode(props) == "auto") + val info = EditorConfigUtil.getEditorConfigInfo(git, "master", "test.txt") + assert(info.tabSize == 8) + assert(info.useSoftTabs == false) + assert(info.newLineMode == "auto") - val subdirProps = EditorConfigUtil.readProperties(git, "master", "dir1/dir2/dir3/dir4/test.txt") - assert(EditorConfigUtil.getTabWidth(subdirProps) == 8) - assert(EditorConfigUtil.getUseSoftTabs(subdirProps) == false) - assert(EditorConfigUtil.getNewLineMode(subdirProps) == "auto") + val subdirInfo = EditorConfigUtil.getEditorConfigInfo(git, "master", "dir1/dir2/dir3/dir4/test.txt") + assert(subdirInfo.tabSize == 8) + assert(subdirInfo.useSoftTabs == false) + assert(subdirInfo.newLineMode == "auto") } } @@ -28,11 +28,22 @@ withTestRepository { git => createFile(git, "master", ".editorconfig", simpleConfig, message = "commit1") - val props = EditorConfigUtil.readProperties(git, "master", "test.txt") - assert(EditorConfigUtil.getTabWidth(props) == 4) + val info = EditorConfigUtil.getEditorConfigInfo(git, "master", "test.txt") + assert(info.tabSize == 4) - val subdirProps = EditorConfigUtil.readProperties(git, "master", "dir1/dir2/dir3/dir4/test.txt") - assert(EditorConfigUtil.getTabWidth(subdirProps) == 4) + val subdirInfo = EditorConfigUtil.getEditorConfigInfo(git, "master", "dir1/dir2/dir3/dir4/test.txt") + assert(subdirInfo.tabSize == 4) + } + } + + test(".editorconfig parse error") { + withTestRepository { git => + createFile(git, "master", ".editorconfig", "equal_missing", message = "commit1") + + val info = EditorConfigUtil.getEditorConfigInfo(git, "master", "test.txt") + assert(info.tabSize == 8) + assert(info.useSoftTabs == false) + assert(info.newLineMode == "auto") } } }