Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions app/lib/model/PatchBomb.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import java.text.NumberFormat

import lib.Email
import lib.Email.Addresses
import lib.model.PatchBomb.countTextFor
import lib.model.PatchBomb.{fromBodyPrefixOpt, countTextFor}

case class PatchBomb(
patchCommits: Seq[PatchCommit],
Expand All @@ -13,25 +13,33 @@ case class PatchBomb(
additionalPrefix: Option[String] = None,
footer: String
) {

lazy val emails: Seq[Email] = {
for ((patchCommit, index) <- patchCommits.zipWithIndex) yield {
val patchDescriptionAndIndex = (Seq(shortDescription) ++ countTextFor(index + 1, patchCommits.size)).mkString(" ")
val prefixes = (additionalPrefix.toSeq :+ patchDescriptionAndIndex).map("["+_+"]")

val authorEmailString = patchCommit.commit.author.userEmailString
val fromBodyPrefixOpt = Some(s"From: $authorEmailString\n").filterNot(_ => authorEmailString == addresses.from)

Email(
addresses,
subject = (prefixes :+ patchCommit.commit.subject).mkString(" "),
bodyText = (fromBodyPrefixOpt.toSeq :+ s"${patchCommit.patch.body}\n--\n$footer").mkString("\n")
bodyText =
(fromBodyPrefixOpt(patchCommit, addresses).toSeq :+ s"${patchCommit.patch.body}\n--\n$footer").mkString("\n")
)
}
}
}

object PatchBomb {

def fromBodyPrefixOpt(patchCommit: PatchCommit, addresses: Addresses): Option[String] = {
val author = patchCommit.commit.author

val shouldAddFromBodyPrefix =
author.email == addresses.from.getAddress || author.email.contains("noreply")

if (shouldAddFromBodyPrefix) None else Some(s"From: ${author.userEmailString}\n")
}

def numberFormatFor(size: Int) = {
val nf = NumberFormat.getIntegerInstance
nf.setMinimumIntegerDigits(size.toString.length)
Expand Down
31 changes: 24 additions & 7 deletions test/lib/model/PatchBombSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,42 @@ import org.eclipse.jgit.lib.ObjectId
import org.scalatestplus.play.PlaySpec

class PatchBombSpec extends PlaySpec {
val patchCommit = {
val author = UserIdent("bob", "bob@x.com")

val bob = UserIdent("bob", "bob@x.com")
val fred = UserIdent("fred", "fred@y.com")

def patchCommitAuthoredBy(author: UserIdent) =
PatchCommit(Patch(ObjectId.zeroId, "PATCHBODY"), Commit(ObjectId.zeroId, author, author, "COMMITMESSAGE"))
}

def patchBombFrom(text: String) = PatchBomb(

def patchBombFrom(user: UserIdent, patchCommit: PatchCommit) = PatchBomb(
Seq(patchCommit),
Addresses(from = new InternetAddress(text)),
Addresses(from = new InternetAddress(user.userEmailString)),
footer = "FOOTER"
)

"Patch bomb" should {
"add a in-body 'From' header when commit author differs from email sender" in {
patchBombFrom("fred <fred@y.com>").emails.head.bodyText must startWith(s"From: bob <bob@x.com>\n\n${patchCommit.patch.body}")
val patchCommit = patchCommitAuthoredBy(bob)
val patchBomb = patchBombFrom(fred, patchCommit)

patchBomb.emails.head.bodyText must startWith(s"From: bob <bob@x.com>\n\n${patchCommit.patch.body}")
}

"not add an in-body 'From' header when the commit author matches the email sender" in {
patchBombFrom("bob <bob@x.com>").emails.head.bodyText must not contain "From:"
val patchBomb = patchBombFrom(bob, patchCommitAuthoredBy(bob))

patchBomb.emails.head.bodyText must not include "From:"
}

"not add an in-body 'From' header when the commit author used a 'noreply' address" in {
// http://article.gmane.org/gmane.comp.version-control.git/286879
val mrNoReply = UserIdent("Peter Dave Hello", "peterdavehello@users.noreply.github.com")
val patchBomb = patchBombFrom(bob, patchCommitAuthoredBy(mrNoReply))

val text = patchBomb.emails.head.bodyText

text must not include "From:"
}
}
}