aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/main/java/com/zeapo/pwdstore/git/log
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/com/zeapo/pwdstore/git/log')
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/git/log/GitCommit.kt18
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/git/log/GitLogActivity.kt38
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/git/log/GitLogAdapter.kt56
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/git/log/GitLogModel.kt53
4 files changed, 165 insertions, 0 deletions
diff --git a/app/src/main/java/com/zeapo/pwdstore/git/log/GitCommit.kt b/app/src/main/java/com/zeapo/pwdstore/git/log/GitCommit.kt
new file mode 100644
index 00000000..d2425592
--- /dev/null
+++ b/app/src/main/java/com/zeapo/pwdstore/git/log/GitCommit.kt
@@ -0,0 +1,18 @@
+/*
+ * Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved.
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+package com.zeapo.pwdstore.git.log
+
+import java.util.Date
+
+/**
+ * Basic information about a git commit.
+ *
+ * @property hash full-length hash of the commit object.
+ * @property shortMessage the commit's short message (i.e. title line).
+ * @property authorName name of the commit's author without email address.
+ * @property time time when the commit was created.
+ */
+data class GitCommit(val hash: String, val shortMessage: String, val authorName: String, val time: Date)
diff --git a/app/src/main/java/com/zeapo/pwdstore/git/log/GitLogActivity.kt b/app/src/main/java/com/zeapo/pwdstore/git/log/GitLogActivity.kt
new file mode 100644
index 00000000..8c1c0f09
--- /dev/null
+++ b/app/src/main/java/com/zeapo/pwdstore/git/log/GitLogActivity.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved.
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+package com.zeapo.pwdstore.git.log
+
+import android.os.Bundle
+import androidx.recyclerview.widget.DividerItemDecoration
+import androidx.recyclerview.widget.LinearLayoutManager
+import com.zeapo.pwdstore.databinding.ActivityGitLogBinding
+import com.zeapo.pwdstore.git.BaseGitActivity
+import com.zeapo.pwdstore.utils.viewBinding
+
+/**
+ * Displays the repository's git commits in git-log fashion.
+ *
+ * It provides basic information about each commit by way of a non-interactive RecyclerView.
+ */
+class GitLogActivity : BaseGitActivity() {
+
+ private val binding by viewBinding(ActivityGitLogBinding::inflate)
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(binding.root)
+ supportActionBar?.setDisplayHomeAsUpEnabled(true)
+ createRecyclerView()
+ }
+
+ private fun createRecyclerView() {
+ binding.gitLogRecyclerView.apply {
+ setHasFixedSize(true)
+ addItemDecoration(DividerItemDecoration(context, LinearLayoutManager.VERTICAL))
+ adapter = GitLogAdapter()
+ }
+ }
+}
diff --git a/app/src/main/java/com/zeapo/pwdstore/git/log/GitLogAdapter.kt b/app/src/main/java/com/zeapo/pwdstore/git/log/GitLogAdapter.kt
new file mode 100644
index 00000000..a15e7f7e
--- /dev/null
+++ b/app/src/main/java/com/zeapo/pwdstore/git/log/GitLogAdapter.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved.
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+package com.zeapo.pwdstore.git.log
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.github.ajalt.timberkt.e
+import com.zeapo.pwdstore.databinding.GitLogRowLayoutBinding
+import java.text.DateFormat
+import java.util.Date
+
+private fun shortHash(hash: String): String {
+ return hash.substring(0 until 8)
+}
+
+private fun stringFrom(date: Date): String {
+ return DateFormat.getDateTimeInstance().format(date)
+}
+
+/**
+ * @see GitLogActivity
+ */
+class GitLogAdapter : RecyclerView.Adapter<GitLogAdapter.ViewHolder>() {
+
+ private val model = GitLogModel()
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ val inflater = LayoutInflater.from(parent.context)
+ val binding = GitLogRowLayoutBinding.inflate(inflater, parent, false)
+ return ViewHolder(binding)
+ }
+
+ override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
+ val commit = model.get(position)
+ if (commit == null) {
+ e { "There is no git commit for view holder at position $position." }
+ return
+ }
+ viewHolder.bind(commit)
+ }
+
+ override fun getItemCount() = model.size
+
+ class ViewHolder(private val binding: GitLogRowLayoutBinding) : RecyclerView.ViewHolder(binding.root) {
+
+ fun bind(commit: GitCommit) = with(binding) {
+ gitLogRowMessage.text = commit.shortMessage
+ gitLogRowHash.text = shortHash(commit.hash)
+ gitLogRowTime.text = stringFrom(commit.time)
+ }
+ }
+}
diff --git a/app/src/main/java/com/zeapo/pwdstore/git/log/GitLogModel.kt b/app/src/main/java/com/zeapo/pwdstore/git/log/GitLogModel.kt
new file mode 100644
index 00000000..22c1ec78
--- /dev/null
+++ b/app/src/main/java/com/zeapo/pwdstore/git/log/GitLogModel.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved.
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+package com.zeapo.pwdstore.git.log
+
+import com.github.ajalt.timberkt.e
+import com.zeapo.pwdstore.utils.PasswordRepository
+import com.zeapo.pwdstore.utils.hash
+import com.zeapo.pwdstore.utils.time
+import org.eclipse.jgit.api.Git
+import org.eclipse.jgit.revwalk.RevCommit
+
+private fun commits(): Iterable<RevCommit> {
+ val repo = PasswordRepository.getRepository(null)
+ if (repo == null) {
+ e { "Could not access git repository" }
+ return listOf()
+ }
+ return try {
+ Git(repo).log().call()
+ } catch (exc: Exception) {
+ e(exc) { "Failed to obtain git commits" }
+ listOf()
+ }
+}
+
+/**
+ * Provides [GitCommit]s from a git-log of the password git repository.
+ *
+ * All commits are acquired on the first request to this object.
+ */
+class GitLogModel {
+
+ // All commits are acquired here at once. Acquiring the commits in batches would not have been
+ // entirely sensible because the amount of computation required to obtain commit number n from
+ // the log includes the amount of computation required to obtain commit number n-1 from the log.
+ // This is because the commit graph is walked from HEAD to the last commit to obtain.
+ // Additionally, tests with 1000 commits in the log have not produced a significant delay in the
+ // user experience.
+ private val cache: MutableList<GitCommit> by lazy {
+ commits().map {
+ GitCommit(it.hash, it.shortMessage, it.authorIdent.name, it.time)
+ }.toMutableList()
+ }
+ val size = cache.size
+
+ fun get(index: Int): GitCommit? {
+ if (index >= size) e { "Cannot get git commit with index $index. There are only $size." }
+ return cache.getOrNull(index)
+ }
+}