A7IL6I3VCB3F3QMYQFPXBL33DN5XDGGQPZIBZRHYSQBSIUBBFQJQC 37OJKSWJFDRHNWQW6P7HSZX6OWZWVNCJ2IFT42O5TANQF7VOVX6AC GGYFPXND4VBCROZZXTKAP7Y4JOP2OOYQAFVLMUE7SLFM225EUSIAC ISO7J5ZH5UB7NFZKTKKJQHQHCP4DWQ3F7SM2NDMVYJAGGIKDLX4QC EAGIDXOLFTHZMZ77ZWAM7MVVUBBXJMZD7RZUNBHJPYRFGGKILGVAC FNNW5IEAXQ43WKB6QSQB7DFLG3Y3T5FYPXIUX7KQ2URR2GU3QLTAC OPFG6CZ26PPTGTH7ULLRQGZGR3YEIEJOV5W2E3WN7PFRZS62CVLQC ZCRW57C5MSBXYGUMGQTZNHGHO4HGHFBICW53X5I2IMGP3H2CKWRQC FRFFQV7VNYKGCA7ZAOSRPC2HHYTAIZ6AGGR7A5QEV6QPAQGFDYGAC B43WNBLFFR2UQIH3C6KIZAQTAEQOQM3J3IYLGQMVGJHYOME73OKQC <vcsRepositoryCreator implementation="com.github.jonathanxd.dracon.repository.PijulRepositoryCreator"/><vcsRepositoryInitializer implementation="com.github.jonathanxd.dracon.repository.PijulRepositoryInit"/><vcs.ignoredFilesHolder implementation="com.github.jonathanxd.dracon.ignore.PijulIgnoredFileHolderProvider"/><ignoredFileContentProvider implementation="com.github.jonathanxd.dracon.ignore.PijulIgnoredFileContentProvider"/>
package com.github.jonathanxd.dracon.repositoryimport com.github.jonathanxd.dracon.PijulVcsimport com.github.jonathanxd.dracon.pijulVcsimport com.intellij.dvcs.repo.AbstractRepositoryManagerimport com.intellij.openapi.components.Serviceimport com.intellij.openapi.components.serviceimport com.intellij.openapi.project.Project@Serviceclass PijulRepositoryManager(project: Project) : AbstractRepositoryManager<PijulRepository>(pijulVcs(project), ".pijul") {override fun getRepositories(): MutableList<PijulRepository> =this.getRepositories(PijulRepository::class.java)override fun isSyncEnabled(): Boolean =true}
package com.github.jonathanxd.dracon.repositoryimport com.github.jonathanxd.dracon.PijulVcsimport com.github.jonathanxd.dracon.pijul.Pijulimport com.github.jonathanxd.dracon.pijul.SuccessStatusCodeimport com.github.jonathanxd.dracon.pijul.pijulimport com.intellij.dvcs.repo.Repositoryimport com.intellij.dvcs.repo.VcsRepositoryCreatorimport com.intellij.openapi.Disposableimport com.intellij.openapi.project.Projectimport com.intellij.openapi.project.ProjectManagerimport com.intellij.openapi.vcs.VcsExceptionimport com.intellij.openapi.vcs.VcsKeyimport com.intellij.openapi.vfs.VirtualFileimport com.intellij.vcs.VcsRepositoryInitializerimport java.io.Fileclass PijulRepositoryInit : VcsRepositoryInitializer {override fun initRepository(rootDir: File) {val project = ProjectManager.getInstance().defaultProjectval result = pijul(project).init(project, rootDir.toPath())if (result.statusCode !is SuccessStatusCode) {throw VcsException(result.toString())}}override fun getSupportedVcs(): VcsKey =PijulVcs.KEY}
package com.github.jonathanxd.dracon.repositoryimport com.github.jonathanxd.dracon.PijulVcsimport com.github.jonathanxd.dracon.pijul.Pijulimport com.intellij.dvcs.repo.Repositoryimport com.intellij.dvcs.repo.VcsRepositoryCreatorimport com.intellij.openapi.Disposableimport com.intellij.openapi.project.Projectimport com.intellij.openapi.vcs.VcsKeyimport com.intellij.openapi.vfs.VirtualFileclass PijulRepositoryCreator : VcsRepositoryCreator {override fun createRepositoryIfValid(project: Project,root: VirtualFile,parentDisposable: Disposable): Repository? =if (Pijul.isUnderPijul(root)) PijulRepository(project, root, parentDisposable) else nulloverride fun getVcsKey(): VcsKey = PijulVcs.KEY}
package com.github.jonathanxd.dracon.repositoryimport com.github.jonathanxd.dracon.PijulVcsimport com.github.jonathanxd.dracon.ignore.PijulLocalIgnoredFileHolderimport com.github.jonathanxd.dracon.pijul.pijulimport com.github.jonathanxd.dracon.pijulVcsimport com.intellij.dvcs.ignore.VcsIgnoredHolderUpdateListenerimport com.intellij.dvcs.ignore.VcsRepositoryIgnoredFilesHolderimport com.intellij.dvcs.repo.Repositoryimport com.intellij.dvcs.repo.RepositoryImplimport com.intellij.openapi.Disposableimport com.intellij.openapi.components.serviceimport com.intellij.openapi.project.Projectimport com.intellij.openapi.util.Disposerimport com.intellij.openapi.vcs.AbstractVcsimport com.intellij.openapi.vcs.FilePathimport com.intellij.openapi.vcs.changes.ChangesViewIimport com.intellij.openapi.vcs.changes.ChangesViewManagerimport com.intellij.openapi.vfs.VirtualFileimport org.jetbrains.annotations.NotNullclass PijulRepository(project: @NotNull Project, dir: @NotNull VirtualFile, parentDisposable: @NotNull Disposable) :RepositoryImpl(project, dir, parentDisposable) {private val vcs = pijulVcs(project)private val localIgnoredHolder: PijulLocalIgnoredFileHolder by lazy {PijulLocalIgnoredFileHolder(this, project.service())}init {localIgnoredHolder.setupListeners()Disposer.register(this, localIgnoredHolder)localIgnoredHolder.addUpdateStateListener(MyIgnoredHolderAsyncListener(getProject()))update()}companion object {fun getInstance(root: VirtualFile,project: Project,parentDisposable: Disposable): PijulRepository {val repository = PijulRepository(project, root, parentDisposable)return repository}}override fun getState(): Repository.State = Repository.State.NORMALoverride fun getCurrentBranchName(): String? =pijul(this.project).channel(project, project.baseDir).result?.channels?.firstOrNull { it.current }?.nameoverride fun getVcs(): AbstractVcs =this.vcsoverride fun getCurrentRevision(): String? =pijul(this.project).latestRevisionNumber(project, project.baseDir).result?.hashoverride fun update() {}fun getIgnoredFilesHolder(): VcsRepositoryIgnoredFilesHolder =this.localIgnoredHolderoverride fun toLogString(): String ="PijulRepository ${this.root}"private class MyIgnoredHolderAsyncListener(project: Project) :VcsIgnoredHolderUpdateListener {private val changesViewI: ChangesViewIprivate val project: Projectoverride fun updateStarted() {changesViewI.scheduleRefresh()}override fun updateFinished(ignoredPaths: Collection<FilePath>, isFullRescan: Boolean) {if (project.isDisposed) returnchangesViewI.scheduleRefresh()}init {changesViewI = ChangesViewManager.getInstance(project)this.project = project}}}
}
fun <Y> andThen(other: (R) -> PijulOperationResult<Y>): PijulOperationResult<Y> {return if (this.statusCode !is SuccessStatusCode) {this as PijulOperationResult<Y>} else {other(this.result!!)}}fun <Y> andThenValue(other: (R) -> Y): PijulOperationResult<Y> {return if (this.statusCode !is SuccessStatusCode) {this as PijulOperationResult<Y>} else {PijulOperationResult(operation, statusCode, other(this.result!!))}}}fun <R, Y> PijulOperationResult<List<R>>.mapEvery(f: (R) -> Y): PijulOperationResult<List<Y>> =this.map { it.map(f) }
package com.github.jonathanxd.dracon.ignoreimport com.github.jonathanxd.dracon.context.PijulVcsContextimport com.github.jonathanxd.dracon.repository.PijulRepositoryimport com.github.jonathanxd.dracon.repository.PijulRepositoryManagerimport com.intellij.dvcs.ignore.VcsRepositoryIgnoredFilesHolderBaseimport com.intellij.openapi.components.serviceimport com.intellij.openapi.project.ProjectManagerimport com.intellij.openapi.util.registry.Registryimport com.intellij.openapi.vcs.FilePathimport com.intellij.openapi.vcs.LocalFilePathimport com.intellij.openapi.vcs.VcsExceptionimport java.nio.file.Filesimport java.nio.file.Pathsimport java.util.ArrayListimport java.util.HashSetclass PijulLocalIgnoredFileHolder(repository: PijulRepository, repositoryManager: PijulRepositoryManager) :VcsRepositoryIgnoredFilesHolderBase<PijulRepository>(repository, repositoryManager) {@Throws(VcsException::class)override fun requestIgnored(paths: Collection<FilePath>?): Set<FilePath> {val ctx = repository.project.service<PijulVcsContext>()val ignored: MutableSet<FilePath> = HashSet()ignored.addAll(IgnoreUtil.ignoredFiles(ctx.root, paths?.map { Paths.get(it.path) }.orEmpty()).map { LocalFilePath(it, Files.isDirectory(it)) })return ignored}override fun scanTurnedOff(): Boolean {return false}}
package com.github.jonathanxd.dracon.ignoreimport com.github.jonathanxd.dracon.PijulVcsimport com.github.jonathanxd.dracon.pijulVcsimport com.github.jonathanxd.dracon.repository.PijulRepositoryimport com.github.jonathanxd.dracon.repository.PijulRepositoryManagerimport com.intellij.dvcs.ignore.VcsIgnoredFilesHolderBaseimport com.intellij.dvcs.ignore.VcsRepositoryIgnoredFilesHolderimport com.intellij.openapi.components.serviceimport com.intellij.openapi.project.Projectimport com.intellij.openapi.vcs.AbstractVcsimport com.intellij.openapi.vcs.changes.ChangesViewRefresherimport com.intellij.openapi.vcs.changes.FileHolderimport com.intellij.openapi.vcs.changes.VcsIgnoredFilesHolderclass PijulIgnoredFileHolder(private val project: Project, val manager: PijulRepositoryManager) :VcsIgnoredFilesHolderBase<PijulRepository>(manager) {override fun getHolder(repository: PijulRepository): VcsRepositoryIgnoredFilesHolder {return repository.getIgnoredFilesHolder()}override fun copy(): FileHolder {return PijulIgnoredFileHolder(project, manager) // re-scan roots on refresh}}class PijulIgnoredFileHolderProvider(private val project: Project) : VcsIgnoredFilesHolder.Provider,ChangesViewRefresher {private val vcs = pijulVcs(project)private val manager by lazy {project.service<PijulRepositoryManager>()}override fun getVcs(): AbstractVcs {return vcs}override fun createHolder(): VcsIgnoredFilesHolder {return PijulIgnoredFileHolder(project, manager)}override fun refresh(project: Project) {manager.repositories.forEach { r -> r.getIgnoredFilesHolder().startRescan() }}}
package com.github.jonathanxd.dracon.ignoreimport com.github.jonathanxd.dracon.PijulVcsimport com.github.jonathanxd.dracon.pijul.Pijulimport com.github.jonathanxd.dracon.pijul.pijulimport com.intellij.openapi.diagnostic.loggerimport com.intellij.openapi.project.Projectimport com.intellij.openapi.util.Comparingimport com.intellij.openapi.util.NlsSafeimport com.intellij.openapi.util.io.FileUtilimport com.intellij.openapi.vcs.FilePathimport com.intellij.openapi.vcs.LocalFilePathimport com.intellij.openapi.vcs.VcsExceptionimport com.intellij.openapi.vcs.VcsKeyimport com.intellij.openapi.vcs.actions.VcsContextFactoryimport com.intellij.openapi.vcs.changes.IgnoreSettingsTypeimport com.intellij.openapi.vcs.changes.IgnoredFileContentProviderimport com.intellij.openapi.vcs.changes.IgnoredFileDescriptorimport com.intellij.openapi.vcs.changes.IgnoredFileProviderimport com.intellij.openapi.vfs.VirtualFileimport com.intellij.vcsUtil.VcsUtilimport java.nio.file.Filesimport java.nio.file.Pathsprivate val LOG = logger<PijulIgnoredFileContentProvider>()class PijulIgnoredFileContentProvider(private val project: Project) : IgnoredFileContentProvider {override fun getSupportedVcs(): VcsKey = PijulVcs.KEYoverride fun getFileName() = ".ignore"override fun buildIgnoreFileContent(ignoreFileRoot: VirtualFile,ignoredFileProviders: Array<IgnoredFileProvider>): String {if (!Pijul.isUnderPijul(ignoreFileRoot)) return ""val repoRoot = VcsUtil.getVcsRootFor(project, ignoreFileRoot)if (repoRoot == null || repoRoot != ignoreFileRoot) return ""val content = StringBuilder()val lineSeparator = System.lineSeparator()val untrackedFiles = getUntrackedFiles(repoRoot, VcsUtil.getFilePath(ignoreFileRoot))if (untrackedFiles.isEmpty()) return ""for (provider in ignoredFileProviders) {val ignoredFiles =provider.getIgnoredFiles(project).ignoreBeansToRelativePaths(ignoreFileRoot, untrackedFiles)if (ignoredFiles.isEmpty()) continueif (content.isNotEmpty()) {content.append(lineSeparator).append(lineSeparator)}val description = provider.ignoredGroupDescriptionif (description.isNotBlank()) {content.append(buildIgnoreGroupDescription(provider))content.append(lineSeparator)}content.append(ignoredFiles.joinToString(lineSeparator))}return content.toString()//if (content.isNotEmpty()) "syntax: glob$lineSeparator$lineSeparator$content" else ""}private fun getUntrackedFiles(root: VirtualFile, ignoreFileRoot: FilePath): Set<FilePath> =try {val rootPath = Paths.get(VcsUtil.getFilePath(root).path)HashSet(pijul(project).untrackedFiles(project, rootPath).result!!.map {LocalFilePath(it, Files.isDirectory(it))}.filter {isAncestor(ignoreFileRoot, it, true)})} catch (e: VcsException) {LOG.warn("Cannot get untracked files: ", e)emptySet()}fun isAncestor(ancestor: FilePath, file: FilePath, strict: Boolean): Boolean {var parent = if (strict) file.parentPath else filewhile (true) {if (parent == null) return falseif (parent == ancestor) return trueparent = parent.parentPath}}private fun Iterable<IgnoredFileDescriptor>.ignoreBeansToRelativePaths(ignoreFileRoot: VirtualFile,untrackedFiles: Set<FilePath>): List<String> {val vcsRoot = VcsUtil.getVcsRootFor(project, ignoreFileRoot)val vcsContextFactory = VcsContextFactory.SERVICE.getInstance()return filter { ignoredBean ->when (ignoredBean.type) {IgnoreSettingsType.UNDER_DIR -> shouldIgnoreUnderDir(ignoredBean,untrackedFiles,ignoreFileRoot,vcsRoot,vcsContextFactory)IgnoreSettingsType.FILE -> shouldIgnoreFile(ignoredBean,untrackedFiles,ignoreFileRoot,vcsRoot,vcsContextFactory)IgnoreSettingsType.MASK -> shouldIgnoreByMask(ignoredBean, untrackedFiles)}}.map { ignoredBean ->when (ignoredBean.type) {IgnoreSettingsType.MASK -> ignoredBean.mask!!IgnoreSettingsType.UNDER_DIR -> buildIgnoreEntryContent(ignoreFileRoot, ignoredBean)IgnoreSettingsType.FILE -> buildIgnoreEntryContent(ignoreFileRoot, ignoredBean)}}}private fun shouldIgnoreUnderDir(ignoredBean: IgnoredFileDescriptor,untrackedFiles: Set<FilePath>,ignoreFileRoot: VirtualFile,vcsRoot: VirtualFile?,vcsContextFactory: VcsContextFactory) =FileUtil.exists(ignoredBean.path)&& untrackedFiles.any { FileUtil.isAncestor(ignoredBean.path!!, it.path, true) }&& FileUtil.isAncestor(ignoreFileRoot.path, ignoredBean.path!!, false)&& Comparing.equal(vcsRoot,VcsUtil.getVcsRootFor(project, vcsContextFactory.createFilePath(ignoredBean.path!!, true)))private fun shouldIgnoreFile(ignoredBean: IgnoredFileDescriptor,untrackedFiles: Set<FilePath>,ignoreFileRoot: VirtualFile,vcsRoot: VirtualFile?,vcsContextFactory: VcsContextFactory) =FileUtil.exists(ignoredBean.path)&& untrackedFiles.any { ignoredBean.matchesFile(it) }&& FileUtil.isAncestor(ignoreFileRoot.path, ignoredBean.path!!, false)&& Comparing.equal(vcsRoot,VcsUtil.getVcsRootFor(project, vcsContextFactory.createFilePath(ignoredBean.path!!, false)))private fun shouldIgnoreByMask(ignoredBean: IgnoredFileDescriptor, untrackedFiles: Set<FilePath>) =untrackedFiles.any { ignoredBean.matchesFile(it) }override fun buildUnignoreContent(ignorePattern: String) = throw UnsupportedOperationException()override fun buildIgnoreGroupDescription(ignoredFileProvider: IgnoredFileProvider) =prependCommentHashCharacterIfNeeded(ignoredFileProvider.ignoredGroupDescription)override fun buildIgnoreEntryContent(ignoreEntryRoot: VirtualFile, ignoredFileDescriptor: IgnoredFileDescriptor) =FileUtil.getRelativePath(ignoreEntryRoot.path, ignoredFileDescriptor.path!!, '/') ?: ""override fun supportIgnoreFileNotInVcsRoot() = falseprivate fun prependCommentHashCharacterIfNeeded(description: @NlsSafe String): @NlsSafe String =if (description.startsWith("#")) description else "# $description"}
package com.github.jonathanxd.dracon.ignoreimport java.nio.file.FileVisitOptionimport java.nio.file.Filesimport java.nio.file.Pathimport kotlin.io.path.ExperimentalPathApiimport kotlin.io.path.relativeToimport kotlin.streams.toListobject IgnoreUtil {@OptIn(ExperimentalPathApi::class)fun ignoredFiles(root: Path, paths: List<Path>): List<Path> {val ignore = root.resolve(".ignore")return if (Files.exists(ignore) && Files.isRegularFile(ignore)) {val lines = Files.readAllLines(ignore, Charsets.UTF_8)Files.walk(root, FileVisitOption.FOLLOW_LINKS).filter {paths.isEmpty() || paths.contains(it)}.filter {val relative = it.toAbsolutePath().relativeTo(root).toString()lines.any { line -> relative.startsWith(line) }}.toList()} else {emptyList()}}}