Skip to content
5 changes: 3 additions & 2 deletions src/main/kotlin/app/api/Api.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ interface Api {

fun authorize(): Result<Unit>
fun getUser(): Result<User>
fun getRepo(repoRehash: String): Result<Repo>
fun postRepo(repo: Repo): Result<Unit>
fun postUser(user: User): Result<Unit>
fun postRepo(repo: Repo): Result<Repo>
fun postComplete(): Result<Unit>
fun postCommits(commitsList: List<Commit>): Result<Unit>
fun deleteCommits(commitsList: List<Commit>): Result<Unit>
fun postFacts(factsList: List<Fact>): Result<Unit>
Expand Down
19 changes: 14 additions & 5 deletions src/main/kotlin/app/api/MockApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class MockApi( // GET requests.
var receivedAddedCommits: MutableList<Commit> = mutableListOf()
var receivedFacts: MutableList<Fact> = mutableListOf()
var receivedAuthors: MutableList<Author> = mutableListOf()
var receivedUsers: MutableList<User> = mutableListOf()
var receivedComplete: Int = 0

// DELETE requests.
var receivedDeletedCommits: MutableList<Commit> = mutableListOf()
Expand All @@ -33,14 +35,21 @@ class MockApi( // GET requests.
return Result(mockUser)
}

override fun getRepo(repoRehash: String): Result<Repo> {
Logger.debug { "MockApi: getRepo request" }
return Result(mockRepo)
override fun postUser(user: User): Result<Unit> {
Logger.debug { "MockApi: postUser request" }
receivedUsers.add(user)
return Result()
}

override fun postRepo(repo: Repo): Result<Unit> {
Logger.debug { "MockApi: postRepo request ($repo)" }
override fun postRepo(repo: Repo): Result<Repo> {
Logger.debug { "MockApi: postRepo request" }
receivedRepos.add(repo)
return Result(mockRepo)
}

override fun postComplete(): Result<Unit> {
Logger.debug { "MockApi: postComplete request " }
receivedComplete++
return Result()
}

Expand Down
27 changes: 18 additions & 9 deletions src/main/kotlin/app/api/ServerApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -76,22 +76,27 @@ class ServerApi (private val configurator: Configurator) : Api {

private fun createRequestGetToken(): Request {
return post("/auth").authenticate(username, password)
.header(getVersionCodeHeader())
.header(getVersionCodeHeader())
}

private fun createRequestGetUser(): Request {
return get("/user")
}

private fun createRequestGetRepo(repoRehash: String): Request {
return get("/repo/$repoRehash")
private fun createRequestPostUser(user: User): Request {
return post("/user").header(getContentTypeHeader())
.body(user.serialize())
}

private fun createRequestPostRepo(repo: Repo): Request {
return post("/repo").header(getContentTypeHeader())
.body(repo.serialize())
}

private fun createRequestPostComplete(): Request {
return post("/complete").header(getContentTypeHeader())
}

private fun createRequestPostCommits(commits: CommitGroup): Request {
return post("/commits").header(getContentTypeHeader())
.body(commits.serialize())
Expand Down Expand Up @@ -154,18 +159,22 @@ class ServerApi (private val configurator: Configurator) : Api {
{ body -> User(body) })
}

override fun getRepo(repoRehash: String): Result<Repo> {
if (repoRehash.isBlank()) {
override fun postUser(user: User): Result<Unit> {
return makeRequest(createRequestPostUser(user), "postUser", {})
}

override fun postRepo(repo: Repo): Result<Repo> {
if (repo.rehash.isBlank()) {
throw IllegalArgumentException()
}

return makeRequest(createRequestGetRepo(repoRehash), "getRepo",
return makeRequest(createRequestPostRepo(repo), "getRepo",
{ body -> Repo(body) })
}

override fun postRepo(repo: Repo): Result<Unit> {
return makeRequest(createRequestPostRepo(repo),
"postRepo", {})
override fun postComplete(): Result<Unit> {
return makeRequest(createRequestPostComplete(),
"postComplete", {})
}

override fun postCommits(commitsList: List<Commit>): Result<Unit> {
Expand Down
6 changes: 3 additions & 3 deletions src/main/kotlin/app/config/Configurator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
package app.config

import app.model.LocalRepo
import app.model.Repo
import app.model.User
import app.utils.Options

interface Configurator {
Expand All @@ -13,15 +13,15 @@ interface Configurator {
fun getPassword(): String
fun isValidCredentials(): Boolean
fun getLocalRepos(): List<LocalRepo>
fun getRepos(): List<Repo>
fun getUser(): User
fun setUsernameCurrent(username: String)
fun setPasswordCurrent(password: String)
fun getUuidPersistent(): String
fun setUsernamePersistent(username: String)
fun setPasswordPersistent(password: String)
fun addLocalRepoPersistent(localRepo: LocalRepo)
fun removeLocalRepoPersistent(localRepo: LocalRepo)
fun setRepos(repos: List<Repo>)
fun setUser(user: User)
fun isFirstLaunch(): Boolean
fun loadFromFile()
fun saveToFile()
Expand Down
15 changes: 8 additions & 7 deletions src/main/kotlin/app/config/FileConfigurator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package app.config
import app.Logger
import app.model.LocalRepo
import app.model.Repo
import app.model.User
import app.utils.Options
import app.utils.PasswordHelper
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility
Expand Down Expand Up @@ -62,7 +63,7 @@ class FileConfigurator : Configurator {
/**
* Used to temporarily save list of repos that known by server.
*/
private var repos: List<Repo> = listOf()
private var user: User = User()

/**
* User directory path is where persistent config stored.
Expand Down Expand Up @@ -143,10 +144,10 @@ class FileConfigurator : Configurator {
}

/**
* Gets list of temprorary saved repos.
* Gets temprorary saved user information.
*/
override fun getRepos(): List<Repo> {
return repos
override fun getUser(): User {
return user
}

/**
Expand Down Expand Up @@ -199,10 +200,10 @@ class FileConfigurator : Configurator {
}

/**
* Temporarily sets list of repos.
* Temporarily sets info about user.
*/
override fun setRepos(repos: List<Repo>) {
this.repos = repos
override fun setUser(user: User) {
this.user = user
}

/**
Expand Down
12 changes: 6 additions & 6 deletions src/main/kotlin/app/config/MockConfigurator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
package app.config

import app.model.LocalRepo
import app.model.Repo
import app.model.User
import app.utils.Options

class MockConfigurator(var mockUsername: String = "",
var mockPassword: String = "",
var mockIsValidCredentials: Boolean = true,
var mockIsFirstLaunch: Boolean = true,
var mockRepos: MutableList<Repo> = mutableListOf(),
var mockUser: User = User(),
var mockLocalRepos: MutableList<LocalRepo> =
mutableListOf(),
var uuid: String = "") : Configurator {
Expand Down Expand Up @@ -39,8 +39,8 @@ class MockConfigurator(var mockUsername: String = "",
return mockLocalRepos
}

override fun getRepos(): List<Repo> {
return mockRepos
override fun getUser(): User {
return mockUser
}

override fun setUsernameCurrent(username: String) {
Expand Down Expand Up @@ -72,8 +72,8 @@ class MockConfigurator(var mockUsername: String = "",
mockPersistent.localRepos.remove(localRepo)
}

override fun setRepos(repos: List<Repo>) {
mockRepos = repos.toMutableList()
override fun setUser(user: User) {
mockUser = user
}

override fun isFirstLaunch(): Boolean {
Expand Down
46 changes: 11 additions & 35 deletions src/main/kotlin/app/hashers/RepoHasher.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,26 +38,18 @@ class RepoHasher(private val localRepo: LocalRepo, private val api: Api,
val (rehashes, emails) = fetchRehashesAndEmails(git)

localRepo.parseGitConfig(git.repository.config)
if (localRepo.author.email.isBlank()) {
throw IllegalStateException("Can't load email from Git config")
}

initServerRepo(rehashes.last)
Logger.debug { "Local repo path: ${localRepo.path}" }
Logger.debug { "Repo remote: ${localRepo.remoteOrigin}" }
Logger.debug { "Repo rehash: ${serverRepo.rehash}" }

val filteredEmails = filterEmails(emails)

if (!isKnownRepo()) {
// Notify server about new contributor and his email.
postRepoToServer()
}
// Get repo setup (commits, emails to hash) from server.
postRepoFromServer()

// Send all repo emails for invites.
postAuthorsToServer(emails)

// Get repo setup (commits, emails to hash) from server.
getRepoFromServer()
val filteredEmails = filterEmails(emails)

// Common error handling for subscribers.
// Exceptions can't be thrown out of reactive chain.
Expand Down Expand Up @@ -87,9 +79,6 @@ class RepoHasher(private val localRepo: LocalRepo, private val api: Api,
onError(e)
}

// Confirm hashing completion.
postRepoToServer()

if (errors.isNotEmpty()) {
throw HashingException(errors)
}
Expand All @@ -116,37 +105,25 @@ class RepoHasher(private val localRepo: LocalRepo, private val api: Api,
git.close()
}

private fun isKnownRepo(): Boolean {
return configurator.getRepos()
.find { it.rehash == serverRepo.rehash } != null
}

private fun getRepoFromServer() {
val repo = api.getRepo(serverRepo.rehash).getOrThrow()
private fun postRepoFromServer() {
val repo = api.postRepo(serverRepo).getOrThrow()
serverRepo.commits = repo.commits
Logger.info{
Logger.info {
"Received repo from server with ${serverRepo.commits.size} commits"
}
Logger.debug { serverRepo.toString() }
}

private fun postRepoToServer() {
serverRepo.commits = listOf()
api.postRepo(serverRepo).onErrorThrow()
Logger.debug { serverRepo.toString() }
}

private fun postAuthorsToServer(emails: HashSet<String>) {
api.postAuthors(emails.map { email ->
Author(email=email, repo=serverRepo)
}).onErrorThrow()
}

private fun initServerRepo(initCommitRehash: String) {
serverRepo = Repo(userEmail = localRepo.author.email)
serverRepo.initialCommitRehash = initCommitRehash
serverRepo.rehash = RepoHelper.calculateRepoRehash(
serverRepo.initialCommitRehash, localRepo)
serverRepo = Repo(initialCommitRehash = initCommitRehash,
rehash = RepoHelper.calculateRepoRehash(
initCommitRehash, localRepo))
}

private fun fetchRehashesAndEmails(git: Git):
Expand Down Expand Up @@ -178,8 +155,7 @@ class RepoHasher(private val localRepo: LocalRepo, private val api: Api,
}

val knownEmails = hashSetOf<String>()
knownEmails.add(localRepo.author.email)
knownEmails.add(serverRepo.userEmail)
knownEmails.addAll(configurator.getUser().emails.map { it.email })
knownEmails.addAll(serverRepo.emails)

return knownEmails.filter { emails.contains(it) }.toHashSet()
Expand Down
4 changes: 0 additions & 4 deletions src/main/kotlin/app/model/Repo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ data class Repo(
var rehash: String = "",
var initialCommitRehash: String = "",

var userEmail: String = "",

// Authors' email filter for hashed commits. If empty list then hash
// only commits that created by current user.
var emails: List<String> = listOf(),
Expand All @@ -28,7 +26,6 @@ data class Repo(
constructor(proto: Protos.Repo) : this() {
rehash = proto.rehash
initialCommitRehash = proto.initialCommitRehash
userEmail = proto.userEmail
emails = proto.emailsList
commits = proto.commitsList.map { Commit(it) }
}
Expand All @@ -42,7 +39,6 @@ data class Repo(
return Protos.Repo.newBuilder()
.setRehash(rehash)
.setInitialCommitRehash(rehash)
.setUserEmail(userEmail)
.addAllEmails(emails)
.addAllCommits(commits.map { it.getProto() })
.build()
Expand Down
11 changes: 7 additions & 4 deletions src/main/kotlin/app/model/User.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ import java.security.InvalidParameterException
* User information.
*/
data class User (
var repos: MutableList<Repo> = mutableListOf()
var repos: MutableList<Repo> = mutableListOf(),
var emails: HashSet<UserEmail> = hashSetOf<UserEmail>()
) {
@Throws(InvalidParameterException::class)
constructor(proto: Protos.User) : this() {
repos = proto.reposList.map { repo -> Repo(repo) }
.toMutableList()
.toMutableList()
emails = proto.emailsList.map { email -> UserEmail(email) }.toHashSet()
}

@Throws(InvalidProtocolBufferException::class)
Expand All @@ -26,8 +28,9 @@ data class User (

fun getProto(): Protos.User {
return Protos.User.newBuilder()
.addAllRepos(repos.map { repo -> repo.getProto() })
.build()
.addAllRepos(repos.map { repo -> repo.getProto() })
.addAllEmails(emails.map { email -> email.getProto() })
.build()
}

fun serialize(): ByteArray {
Expand Down
Loading