Q7FXTHVUPVAFMNY277C3NFJO3VXLZU5G6C6UYSD5QPURHSG3A7OQC MTPTFTHGAOKQGRUDXC55AM6XJHZZZ5EF6FPVXKFVCUYVXJNEANYQC FRFFQV7VNYKGCA7ZAOSRPC2HHYTAIZ6AGGR7A5QEV6QPAQGFDYGAC GGYFPXND4VBCROZZXTKAP7Y4JOP2OOYQAFVLMUE7SLFM225EUSIAC QXUEMZ3B2FUHFUC7ZZHJMH5FVWLEMEYXUMFA6JNXTJKIVZNMRIOAC FNNW5IEAXQ43WKB6QSQB7DFLG3Y3T5FYPXIUX7KQ2URR2GU3QLTAC 6CR2EFUN7JXFHCBTNX3WWOOP4WFOCFO6KSPEBN6V6J5HFZO2LHNQC OPFG6CZ26PPTGTH7ULLRQGZGR3YEIEJOV5W2E3WN7PFRZS62CVLQC @OptIn(ExperimentalPathApi::class)fun loadStateInRevision(revisionHash: String,project: Project,root: Path,filePath: Path): String {val tmpTarget = Paths.get(project.baseDir.path, ".idea", "dracon_diffs", revisionHash)if (Files.exists(tmpTarget)) {Files.walk(tmpTarget).use { walk ->walk.sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete)}}Files.createDirectories(tmpTarget)copyFolder(root, tmpTarget, StandardCopyOption.COPY_ATTRIBUTES, StandardCopyOption.REPLACE_EXISTING)val revisions = pijul(project).latestRevisionNumber(project, tmpTarget).resultif (revisions != null && revisions.hash == revisionHash) {val rollbackOp = pijul(project).reset(project, tmpTarget)} else {val resetOp = pijul(project).reset(project, tmpTarget)val rollbackOp = pijul(project).rollbackTo(revisionHash, project, tmpTarget)}
@OptIn(ExperimentalPathApi::class)constructor(project: Project,vcsRoot: Path,filePath: FilePath,revision: PijulRevisionNumber,author_: String?,message: String?,branch: String?): this(project, vcsRoot, Paths.get(filePath.path).relativeTo(vcsRoot), revision, author_, message, branch)
package com.github.jonathanxd.dracon.providerimport com.github.jonathanxd.dracon.content.PijulContentRevisionimport com.github.jonathanxd.dracon.pijul.pijulimport com.github.jonathanxd.dracon.revision.PijulRevisionNumberimport com.intellij.openapi.components.Serviceimport com.intellij.openapi.project.Projectimport com.intellij.openapi.vcs.FilePathimport com.intellij.openapi.vcs.FileStatusimport com.intellij.openapi.vcs.ProjectLevelVcsManagerimport com.intellij.openapi.vcs.changes.ContentRevisionimport com.intellij.openapi.vcs.diff.DiffProviderimport com.intellij.openapi.vcs.diff.ItemLatestStateimport com.intellij.openapi.vcs.history.VcsRevisionNumberimport com.intellij.openapi.vfs.VirtualFileimport java.nio.file.Pathsimport kotlin.io.path.ExperimentalPathApiimport kotlin.io.path.relativeTo@Serviceclass PijulDiffProvider(val project: Project) : DiffProvider {override fun getCurrentRevision(file: VirtualFile): VcsRevisionNumber? {val root = ProjectLevelVcsManager.getInstance(this.project).getVcsRootFor(file)?.toNioPath() ?: return nullreturn pijul(project).latestRevisionNumberForPath(this.project, root, file.toNioPath()).result}@OptIn(ExperimentalPathApi::class)fun getCurrentRevision(path: FilePath): VcsRevisionNumber? {val root = ProjectLevelVcsManager.getInstance(this.project).getVcsRootFor(path)?.toNioPath() ?: return nullval filePath = path.ioFile.toPath().relativeTo(root)return pijul(project).latestRevisionNumberForPath(this.project, root, filePath).result}override fun getLastRevision(virtualFile: VirtualFile): ItemLatestState? {val current = this.getCurrentRevision(virtualFile) ?: return nullreturn ItemLatestState(current, virtualFile.exists(), true)}override fun getLastRevision(filePath: FilePath): ItemLatestState? {val current = this.getCurrentRevision(filePath) ?: return nullreturn ItemLatestState(current, filePath.ioFile.exists(), true)}override fun createFileContent(revisionNumber: VcsRevisionNumber, selectedFile: VirtualFile): ContentRevision? {val root = ProjectLevelVcsManager.getInstance(this.project).getVcsRootFor(selectedFile)?.toNioPath() ?: return nullreturn PijulContentRevision(root,selectedFile.toNioPath(),revisionNumber as? PijulRevisionNumber ?: return null,this.project)}override fun getLatestCommittedRevision(vcsRoot: VirtualFile?): VcsRevisionNumber? {return null}}
package com.github.jonathanxd.dracon.configimport com.intellij.dvcs.branch.DvcsCompareSettingsimport com.intellij.dvcs.branch.DvcsSyncSettingsimport com.intellij.openapi.components.*import com.intellij.util.xmlb.annotations.OptionTagimport com.intellij.vcs.log.VcsUser@State(name = "Pijul.Settings", storages = [Storage(StoragePathMacros.WORKSPACE_FILE)])class PijulSettings : SimplePersistentStateComponent<PijulOptions>(PijulOptions()), DvcsSyncSettings, DvcsCompareSettings {override fun getSyncSetting(): DvcsSyncSettings.Value =this.state.rootSyncfun getAuthor(): String? {return this.state.author}fun saveAuthor(author: VcsUser) { // Pijul still does not support specifying emails?this.state.author = author.name}override fun setSyncSetting(syncSetting: DvcsSyncSettings.Value) {this.state.rootSync = syncSetting}override fun shouldSwapSidesInCompareBranches(): Boolean =this.state.isSwapSidesInCompareBranchesoverride fun setSwapSidesInCompareBranches(value: Boolean) {this.state.isSwapSidesInCompareBranches = value}}class PijulOptions : BaseState() {@get:OptionTag("PATH_TO_PIJUL")var pathToGit by string()@get:OptionTag("AUTHOR")var author by string()@get:OptionTag("ROOT_SYNC")var rootSync by enum(DvcsSyncSettings.Value.NOT_DECIDED)@get:OptionTag("SWAP_SIDES_IN_COMPARE_BRANCHES")var isSwapSidesInCompareBranches by property(false)}
}}override fun record(project: Project,root: Path,files: List<Path>,author: VcsUser?,message: String): PijulOperationResult<Boolean> {val arguments = mutableListOf<String>("record")if (author != null) {arguments.add("--author")arguments.add(author.name)}arguments.add("--message")arguments.add(message)if (files.isNotEmpty()) {arguments.add("--")arguments.addAll(files.map { it.toString() })} else {return PijulOperationResult("record", NonZeroExitStatusCode(-1, "Empty list of paths to record"), false)
override fun latestRevisionNumberForPath(project: Project,root: Path,filePath: Path): PijulOperationResult<PijulRevisionNumber> {val log = this.log(project, root)return PijulOperationResult(log.operation, log.statusCode,log.result?.entries?.firstOrNull {it.hunks.filterIsInstance<HunkWithPath>().firstOrNull {filePath.toString().equals(it.resolvedPath, ignoreCase = true)} != null}?.let {PijulRevisionNumber(it.changeHash, it.date)})}
package com.github.jonathanxd.dracon.checkinimport com.github.jonathanxd.dracon.config.PijulSettingsimport com.github.jonathanxd.dracon.i18n.DraconBundleimport com.github.jonathanxd.dracon.pijul.SuccessStatusCodeimport com.github.jonathanxd.dracon.pijul.pijulimport com.intellij.openapi.Disposableimport com.intellij.openapi.components.Serviceimport com.intellij.openapi.components.serviceimport com.intellij.openapi.project.Projectimport com.intellij.openapi.ui.popup.Balloonimport com.intellij.openapi.util.Keyimport com.intellij.openapi.vcs.CheckinProjectPanelimport com.intellij.openapi.vcs.FilePathimport com.intellij.openapi.vcs.ProjectLevelVcsManagerimport com.intellij.openapi.vcs.VcsExceptionimport com.intellij.openapi.vcs.changes.*import com.intellij.openapi.vcs.checkin.CheckinChangeListSpecificComponentimport com.intellij.openapi.vcs.checkin.CheckinEnvironmentimport com.intellij.openapi.vcs.ui.RefreshableOnComponentimport com.intellij.openapi.vfs.VirtualFileimport com.intellij.ui.components.JBLabelimport com.intellij.util.ui.GridBagimport com.intellij.util.ui.JBUIimport com.intellij.vcs.commit.*import com.intellij.vcs.log.VcsUserimport com.intellij.vcs.log.VcsUserEditorimport java.awt.GridBagConstraintsimport java.awt.GridBagLayoutimport java.awt.event.*import java.util.*import javax.swing.JComponentimport javax.swing.JPanelimport kotlin.io.path.ExperimentalPathApiimport kotlin.io.path.relativeToval COMMIT_AUTHOR_KEY = Key.create<VcsUser>("Pijul.Commit.Author")val COMMIT_AUTHOR_DATE_KEY = Key.create<Date>("Pijul.Commit.AuthorDate")internal var CommitContext.commitAuthor: VcsUser? by commitProperty(COMMIT_AUTHOR_KEY, null)internal var CommitContext.commitAuthorDate: Date? by commitProperty(COMMIT_AUTHOR_DATE_KEY, null)@Serviceclass PijulCheckingEnvironment(val project: Project) : CheckinEnvironment {override fun createCommitOptions(commitPanel: CheckinProjectPanel,commitContext: CommitContext): RefreshableOnComponent? {return PijulCheckinOptions(commitPanel, commitContext)}override fun getHelpId(): String? = nulloverride fun getCheckinOperationName(): String =DraconBundle.Record.nameoverride fun scheduleMissingFileForDeletion(files: MutableList<out FilePath>): MutableList<VcsException> {return mutableListOf()}override fun scheduleUnversionedFilesForAddition(files: MutableList<out VirtualFile>): MutableList<VcsException> {return mutableListOf()}override fun isRefreshAfterCommitNeeded(): Boolean = true@OptIn(ExperimentalPathApi::class)override fun commit(changes: MutableList<out Change>,commitMessage: String,commitContext: CommitContext,feedback: MutableSet<in String>): MutableList<VcsException>? {val vcsManager = ProjectLevelVcsManager.getInstance(this.project)val root = vcsManager.allVcsRoots.first().path.toNioPath()val paths = changes.map {val root = vcsManager.getVcsRootFor(it.afterRevision!!.file)!!.toNioPath()val relative = it.afterRevision!!.file.ioFile.toPath().relativeTo(root)relative}println(paths)val author = commitContext.commitAuthorval record = pijul(project).record(project, root, paths, author, commitMessage)return if (record.statusCode !is SuccessStatusCode) {mutableListOf(VcsException("Operation ${record.operation}, failed with statusCode: ${record.statusCode}"))} else {super.commit(changes, commitMessage, commitContext, feedback)}}class PijulCheckinOptions(val commitPanel: CheckinProjectPanel, val commitContext: CommitContext) : RefreshableOnComponent, Disposable {val optionsUi = PijulOptionsUi(commitPanel, commitContext)override fun refresh() {optionsUi.refresh()}override fun saveState() {optionsUi.saveState()}override fun restoreState() {optionsUi.restoreState()}override fun getComponent(): JComponent {return optionsUi.component}override fun dispose() {optionsUi.dispose()}}class PijulOptionsUi(private val commitPanel: CheckinProjectPanel,private val commitContext: CommitContext) : RefreshableOnComponent,CheckinChangeListSpecificComponent,CommitAuthorListener,Disposable {private val CheckinProjectPanel.commitAuthorTracker: CommitAuthorTracker? get() = commitWorkflowHandler as? CommitAuthorTrackerprivate val project get() = commitPanel.projectprivate val settings = project.service<PijulSettings>()private var authorDate: Date? = nullprivate val panel = JPanel(GridBagLayout())private val authorField = VcsUserEditor(project, getKnownCommitAuthors())init {authorField.addFocusListener(object : FocusAdapter() {override fun focusLost(e: FocusEvent) {updateCurrentCommitAuthor()}})buildLayout()}private fun buildLayout() = panel.apply {val gb = GridBag().setDefaultAnchor(GridBagConstraints.WEST).setDefaultInsets(JBUI.insets(2))val authorLabel = JBLabel(DraconBundle.message("record.author")).apply { labelFor = authorField }add(authorLabel, gb.nextLine().next())add(authorField, gb.next().fillCellHorizontally().weightx(1.0))}override fun dispose() = Unitoverride fun getComponent(): JComponent = paneloverride fun restoreState() {if (commitPanel.isNonModalCommit) {commitPanel.commitAuthorTracker?.addCommitAuthorListener(this, this)}refresh()}override fun refresh() {refresh(null)commitAuthorChanged()}override fun saveState() {val author = getAuthor()commitContext.apply {commitAuthor = authorcommitAuthorDate = authorDate}settings.apply {author?.let { saveAuthor(it) }}}override fun onChangeListSelected(list: LocalChangeList) {refresh(list)panel.revalidate()panel.repaint()}private fun refresh(changeList: LocalChangeList?) {setAuthor(changeList?.author)authorDate = changeList?.authorDate}fun getAuthor(): VcsUser? = authorField.userprivate fun setAuthor(author: VcsUser?) {val isAuthorNull = author == nullauthorField.user = author.takeUnless { isAuthorNull }}private fun updateCurrentCommitAuthor() {commitPanel.commitAuthorTracker?.commitAuthor = getAuthor()}override fun commitAuthorChanged() {val newAuthor = commitPanel.commitAuthorTracker?.commitAuthorif (getAuthor() != newAuthor) setAuthor(newAuthor)}private fun getKnownCommitAuthors(): List<String> =(VcsUserEditor.getAllUsers(project) + settings.getAuthor()?.let { listOf(it) }.orEmpty()).distinct().sorted()}}