Skip to content

Commit 547ca6e

Browse files
committed
Merge pull request #111 from adamretter/scalaz-update
Update the version of Scalaz and associated libraries
2 parents b5f6900 + 7a99751 commit 547ca6e

File tree

57 files changed

+572
-364
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+572
-364
lines changed

csv-validator-cmd/pom.xml

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@
2929
<configuration>
3030
<recompileMode>incremental</recompileMode> <!-- NOTE: incremental compilation although faster requires passing to MAVEN_OPTS="-XX:MaxPermSize=128m" -->
3131
<useZincServer>true</useZincServer> <!-- NOTE: if you have Zinc server installed and running, you can get faster compilation by enabling this -->
32+
<args>
33+
<arg>-Yrangepos</arg> <!-- recommended for Specs2 -->
34+
<arg>-feature</arg>
35+
<arg>-deprecation</arg>
36+
</args>
3237
<javacArgs>
3338
<javacArg>-Xlint:unchecked</javacArg>
3439
<javacArg>-Xlint:deprecation</javacArg>
@@ -52,17 +57,13 @@
5257
</executions>
5358
</plugin>
5459
<plugin>
55-
<groupId>com.mmakowski</groupId>
56-
<artifactId>maven-specs2-plugin</artifactId>
57-
<executions>
58-
<execution>
59-
<id>verify</id>
60-
<phase>verify</phase>
61-
<goals>
62-
<goal>run-specs</goal>
63-
</goals>
64-
</execution>
65-
</executions>
60+
<groupId>org.apache.maven.plugins</groupId>
61+
<artifactId>maven-surefire-plugin</artifactId>
62+
<configuration>
63+
<includes>
64+
<include>**/*Spec.*</include>
65+
</includes>
66+
</configuration>
6667
</plugin>
6768
<plugin>
6869
<groupId>org.codehaus.mojo</groupId>
@@ -135,7 +136,27 @@
135136
</dependency>
136137
<dependency>
137138
<groupId>org.specs2</groupId>
138-
<artifactId>specs2_${scala.version}</artifactId>
139+
<artifactId>specs2-core_${scala.version}</artifactId>
140+
<scope>test</scope>
141+
</dependency>
142+
<dependency>
143+
<groupId>org.specs2</groupId>
144+
<artifactId>specs2-common_${scala.version}</artifactId>
145+
<scope>test</scope>
146+
</dependency>
147+
<dependency>
148+
<groupId>org.specs2</groupId>
149+
<artifactId>specs2-matcher_${scala.version}</artifactId>
150+
<scope>test</scope>
151+
</dependency>
152+
<dependency>
153+
<groupId>org.specs2</groupId>
154+
<artifactId>specs2-junit_${scala.version}</artifactId>
155+
<scope>test</scope>
156+
</dependency>
157+
<dependency>
158+
<groupId>junit</groupId>
159+
<artifactId>junit</artifactId>
139160
<scope>test</scope>
140161
</dependency>
141162
</dependencies>

csv-validator-cmd/src/main/scala/uk/gov/nationalarchives/csv/validator/cmd/CsvValidatorCmdApp.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -149,16 +149,16 @@ object CsvValidatorCmdApp extends App {
149149

150150
private def containsError(l: NonEmptyList[FailMessage]) : Boolean = {
151151
l.list.find(_ match {
152-
case ErrorMessage(_, _, _) => true
152+
case FailMessage(ValidationError, _, _, _) => true
153153
case _ => false
154154
}).nonEmpty
155155
}
156156

157157
private def prettyPrint(l: NonEmptyList[FailMessage]): String = l.list.map { i =>
158158
i match {
159-
case WarningMessage(err,_,_) => "Warning: " + err
160-
case ErrorMessage(err,_,_) => "Error: " + err
161-
case SchemaMessage(err,_,_) => err
159+
case FailMessage(ValidationWarning, err,_,_) => "Warning: " + err
160+
case FailMessage(ValidationError, err,_,_) => "Error: " + err
161+
case FailMessage(SchemaDefinitionError, err,_,_) => err
162162
}
163-
}.mkString(sys.props("line.separator"))
163+
}.toList.mkString(sys.props("line.separator"))
164164
}

csv-validator-cmd/src/test/scala/uk/gov/nationalarchives/csv/validator/cmd/CsvValidatorCmdAppSpec.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@
88
*/
99
package uk.gov.nationalarchives.csv.validator.cmd
1010

11+
import org.junit.runner.RunWith
1112
import org.specs2.mutable.Specification
13+
import org.specs2.runner.JUnitRunner
1214

15+
@RunWith(classOf[JUnitRunner])
1316
class CsvValidatorCmdAppSpec extends Specification with TestResources {
1417

1518
val schemaPath = relResourcePath("schema.csvs")

csv-validator-core/pom.xml

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@
3030
<configuration>
3131
<recompileMode>incremental</recompileMode> <!-- NOTE: incremental compilation although faster requires passing to MAVEN_OPTS="-XX:MaxPermSize=128m" -->
3232
<useZincServer>true</useZincServer> <!-- NOTE: if you have Zinc server installed and running, you can get faster compilation by enabling this -->
33+
<args>
34+
<arg>-Yrangepos</arg> <!-- recommended for Specs2 -->
35+
<arg>-feature</arg>
36+
<arg>-deprecation</arg>
37+
</args>
3338
<javacArgs>
3439
<javacArg>-Xlint:unchecked</javacArg>
3540
<javacArg>-Xlint:deprecation</javacArg>
@@ -68,17 +73,17 @@
6873
</executions>
6974
</plugin>
7075
<plugin>
71-
<groupId>com.mmakowski</groupId>
72-
<artifactId>maven-specs2-plugin</artifactId>
73-
<executions>
74-
<execution>
75-
<id>verify</id>
76-
<phase>verify</phase>
77-
<goals>
78-
<goal>run-specs</goal>
79-
</goals>
80-
</execution>
81-
</executions>
76+
<groupId>org.apache.maven.plugins</groupId>
77+
<artifactId>maven-surefire-plugin</artifactId>
78+
<configuration>
79+
<includes>
80+
<include>**/*Spec.*</include>
81+
</includes>
82+
</configuration>
83+
</plugin>
84+
<plugin>
85+
<groupId>org.apache.maven.plugins</groupId>
86+
<artifactId>maven-surefire-report-plugin</artifactId>
8287
</plugin>
8388
</plugins>
8489
</build>
@@ -100,18 +105,13 @@
100105
<dependency>
101106
<groupId>org.scalaz.stream</groupId>
102107
<artifactId>scalaz-stream_${scala.version}</artifactId>
103-
<version>0.6a</version> <!-- version 0.5a is compatible with scalaz-core 7.1.0 -->
108+
<version>0.7.3a</version>
104109
</dependency>
105110
<dependency>
106-
<groupId>org.typelevel</groupId>
107-
<artifactId>scodec-bits_${scala.version}</artifactId>
108-
<version>1.0.4</version>
109-
</dependency>
110-
<!-- dependency>
111111
<groupId>org.scodec</groupId>
112112
<artifactId>scodec-bits_${scala.version}</artifactId>
113113
<version>1.0.6</version>
114-
</dependency -->
114+
</dependency>
115115
<dependency>
116116
<groupId>org.scalaz</groupId>
117117
<artifactId>scalaz-concurrent_${scala.version}</artifactId>
@@ -156,7 +156,27 @@
156156
</dependency>
157157
<dependency>
158158
<groupId>org.specs2</groupId>
159-
<artifactId>specs2_${scala.version}</artifactId>
159+
<artifactId>specs2-core_${scala.version}</artifactId>
160+
<scope>test</scope>
161+
</dependency>
162+
<dependency>
163+
<groupId>org.specs2</groupId>
164+
<artifactId>specs2-common_${scala.version}</artifactId>
165+
<scope>test</scope>
166+
</dependency>
167+
<dependency>
168+
<groupId>org.specs2</groupId>
169+
<artifactId>specs2-matcher_${scala.version}</artifactId>
170+
<scope>test</scope>
171+
</dependency>
172+
<dependency>
173+
<groupId>org.specs2</groupId>
174+
<artifactId>specs2-junit_${scala.version}</artifactId>
175+
<scope>test</scope>
176+
</dependency>
177+
<dependency>
178+
<groupId>junit</groupId>
179+
<artifactId>junit</artifactId>
160180
<scope>test</scope>
161181
</dependency>
162182
</dependencies>

csv-validator-core/src/main/scala/uk/gov/nationalarchives/csv/validator/FailFastMetaDataValidator.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ import uk.gov.nationalarchives.csv.validator.metadata.Row
2222

2323
trait FailFastMetaDataValidator extends MetaDataValidator {
2424

25+
//TODO(AR) work on removing use of `Any`
26+
2527
override def validateRows(rows: Iterator[Row], schema: Schema): MetaDataValidation[Any] = {
2628

27-
def containsErrors(e: MetaDataValidation[Any]): Boolean = e.fold(_.list.exists(_.isInstanceOf[ErrorMessage]), _ => false)
29+
def containsErrors(e: MetaDataValidation[Any]): Boolean = e.fold(_.list.collectFirst(FailMessage.isError).nonEmpty, _ => false)
2830

2931
@tailrec
3032
def validateRows(results: List[MetaDataValidation[Any]] = List.empty[MetaDataValidation[Any]]) : List[MetaDataValidation[Any]] = {

csv-validator-core/src/main/scala/uk/gov/nationalarchives/csv/validator/MetaDataValidator.scala

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ package uk.gov.nationalarchives.csv.validator
1111

1212
import uk.gov.nationalarchives.utf8.validator.{Utf8Validator, ValidationHandler}
1313

14-
import scala.language.postfixOps
14+
import scala.language.{postfixOps, reflectiveCalls}
1515
import scala.util.Try
1616
import scalaz._, Scalaz._
1717
import java.io.{IOException, Reader => JReader, InputStreamReader => JInputStreamReader, FileInputStream => JFileInputStream, LineNumberReader => JLineNumberReader}
@@ -25,10 +25,26 @@ import uk.gov.nationalarchives.csv.validator.metadata.Row
2525
import scala.annotation.tailrec
2626
import uk.gov.nationalarchives.csv.validator.api.TextFile
2727

28-
sealed abstract class FailMessage(val msg:String, val lineNr:Option[Int], val colIdx:Option[Int])
29-
case class WarningMessage(message:String, lineNumber: Option[Int] = None, columnIndex: Option[Int] = None) extends FailMessage(message, lineNumber, columnIndex)
30-
case class ErrorMessage(message:String, lineNumber: Option[Int] = None, columnIndex: Option[Int] = None) extends FailMessage(message, lineNumber, columnIndex)
31-
case class SchemaMessage(message:String, lineNumber: Option[Int] = None, columnIndex: Option[Int] = None) extends FailMessage(message, lineNumber, columnIndex)
28+
29+
//error reporting classes
30+
sealed trait ErrorType
31+
case object ValidationWarning extends ErrorType
32+
case object ValidationError extends ErrorType
33+
case object SchemaDefinitionError extends ErrorType
34+
case class FailMessage(`type`: ErrorType, message : String, lineNumber: Option[Int] = None, columnIndex: Option[Int] = None) //TODO(AR) consider a better name, e.g. CsvValidationFailure
35+
object FailMessage {
36+
def isWarning : PartialFunction[FailMessage, FailMessage] = {
37+
case fm @ FailMessage(ValidationWarning, _, _, _) => fm
38+
}
39+
40+
def isError : PartialFunction[FailMessage, FailMessage] = {
41+
case fm @ FailMessage(ValidationError, _, _, _) => fm
42+
}
43+
44+
def isSchemaDefinitionError : PartialFunction[FailMessage, FailMessage] = {
45+
case fm @ FailMessage(SchemaDefinitionError, _, _, _) => fm
46+
}
47+
}
3248

3349
case class ProgressFor(rowsToValidate: Int, progress: ProgressCallback)
3450

@@ -88,16 +104,16 @@ trait MetaDataValidator {
88104
val maybeNoData =
89105
if (schema.globalDirectives.contains(NoHeader())) {
90106
if (!rowIt.hasNext && !schema.globalDirectives.contains(PermitEmpty())) {
91-
Some(ErrorMessage("metadata file is empty but this has not been permitted").failNel[Any])
107+
Some(FailMessage(ValidationError, "metadata file is empty but this has not been permitted").failureNel[Any])
92108
} else {
93109
None
94110
}
95111
} else {
96112
if(!rowIt.hasNext) {
97-
Some(ErrorMessage("metadata file is empty but should contain at least a header").failNel[Any])
113+
Some(FailMessage(ValidationError, "metadata file is empty but should contain at least a header").failureNel[Any])
98114
} else {
99115
if(!rowIt.hasNext && !schema.globalDirectives.contains(PermitEmpty())) {
100-
Some(ErrorMessage("metadata file has a header but no data and this has not been permitted").failNel[Any])
116+
Some(FailMessage(ValidationError, "metadata file has a header but no data and this has not been permitted").failureNel[Any])
101117
} else {
102118
None
103119
}
@@ -143,19 +159,19 @@ trait MetaDataValidator {
143159
val maybeNoData =
144160
if (schema.globalDirectives.contains(NoHeader())) {
145161
if (!rowIt.hasNext && !schema.globalDirectives.contains(PermitEmpty())) {
146-
Some(ErrorMessage("metadata file is empty but this has not been permitted").failureNel[Any])
162+
Some(FailMessage(ValidationError, "metadata file is empty but this has not been permitted").failureNel[Any])
147163
} else {
148164
None
149165
}
150166
} else {
151167
if(!rowIt.hasNext) {
152-
Some(ErrorMessage("metadata file is empty but should contain at least a header").failureNel[Any])
168+
Some(FailMessage(ValidationError, "metadata file is empty but should contain at least a header").failureNel[Any])
153169
} else {
154170
val header = rowIt.skipHeader()
155171
val headerValidation = validateHeader(header, schema)
156-
headerValidation.orElse{
172+
headerValidation.orElse {
157173
if(!rowIt.hasNext && !schema.globalDirectives.contains(PermitEmpty())) {
158-
Some(ErrorMessage("metadata file has a header but no data and this has not been permitted").failureNel[Any])
174+
Some(FailMessage(ValidationError, "metadata file has a header but no data and this has not been permitted").failureNel[Any])
159175
} else {
160176
None
161177
}
@@ -175,9 +191,9 @@ trait MetaDataValidator {
175191
metadataValidation
176192

177193
case Left(ts) =>
178-
//TODO emit all errors not just first!
179-
ErrorMessage(ts(0).toString).failureNel[Any]
180-
//ts.toList.map(t => ErrorMessage(t.toString).failureNel[Any]).sequence[MetaDataValidation, Any]
194+
//TODO(AR) emit all errors not just first!
195+
FailMessage(ValidationError, ts(0).toString).failureNel[Any]
196+
// ts.toList.map(t => FailMessage(ValidationError, t.toString).failureNel[Any]).sequence[MetaDataValidation, Any]
181197
}
182198
}
183199

@@ -211,7 +227,7 @@ trait MetaDataValidator {
211227
if (headerList.sameElements(schemaHeader))
212228
None
213229
else
214-
Some(ErrorMessage(s"Metadata header, cannot find the column headers - ${Util.diff(schemaHeader.toSet, headerList.toSet).mkString(", ")} - .${if (icnc.isEmpty) " (Case sensitive)" else ""}").failNel[Any])
230+
Some(FailMessage(ValidationError, s"Metadata header, cannot find the column headers - ${Util.diff(schemaHeader.toSet, headerList.toSet).mkString(", ")} - .${if (icnc.isEmpty) " (Case sensitive)" else ""}").failureNel[Any])
215231
}
216232

217233
def validateRow(row: Row, schema: Schema, mayBeLast: Option[Boolean] = None): MetaDataValidation[Any] = {
@@ -236,7 +252,7 @@ trait MetaDataValidator {
236252
case None => true.successNel
237253
case Some(nel) => {
238254
val ret = nel.reverse.map {
239-
case (offset, message) => ErrorMessage(s"[UTF-8 Error][@$offset] ${message}")
255+
case (offset, message) => FailMessage(ValidationError, s"[UTF-8 Error][@$offset] ${message}")
240256
}
241257
ret.failure
242258
}
@@ -249,20 +265,20 @@ trait MetaDataValidator {
249265
}
250266

251267
if (tc.isEmpty || tc.get.numberOfColumns == row.cells.length) true.successNel[FailMessage]
252-
else ErrorMessage(s"Expected @totalColumns of ${tc.get.numberOfColumns} and found ${row.cells.length} on line ${row.lineNumber}", Some(row.lineNumber), Some(row.cells.length)).failureNel[Any]
268+
else FailMessage(ValidationError, s"Expected @totalColumns of ${tc.get.numberOfColumns} and found ${row.cells.length} on line ${row.lineNumber}", Some(row.lineNumber), Some(row.cells.length)).failureNel[Any]
253269
}
254270

255271
protected def rules(row: Row, schema: Schema, mayBeLast: Option[Boolean] = None): MetaDataValidation[List[Any]]
256272

257273
protected def validateCell(columnIndex: Int, cells: (Int) => Option[Cell], row: Row, schema: Schema, mayBeLast: Option[Boolean] = None): MetaDataValidation[Any] = {
258274
cells(columnIndex) match {
259275
case Some(c) => rulesForCell(columnIndex, row, schema, mayBeLast)
260-
case _ => ErrorMessage(s"Missing value at line: ${row.lineNumber}, column: ${schema.columnDefinitions(columnIndex).id}", Some(row.lineNumber), Some(columnIndex)).failureNel[Any]
276+
case _ => FailMessage(ValidationError, s"Missing value at line: ${row.lineNumber}, column: ${schema.columnDefinitions(columnIndex).id}", Some(row.lineNumber), Some(columnIndex)).failureNel[Any]
261277
}
262278
}
263279

264-
protected def toWarnings(results: Rule#RuleValidation[Any], lineNumber: Int, columnIndex: Int): MetaDataValidation[Any] = results.leftMap(_.map(WarningMessage(_, Some(lineNumber), Some(columnIndex))))
265-
protected def toErrors(results: Rule#RuleValidation[Any], lineNumber: Int, columnIndex: Int): MetaDataValidation[Any] = results.leftMap(_.map(ErrorMessage(_, Some(lineNumber), Some(columnIndex))))
280+
protected def toWarnings(results: Rule#RuleValidation[Any], lineNumber: Int, columnIndex: Int): MetaDataValidation[Any] = results.leftMap(_.map(FailMessage(ValidationWarning, _, Some(lineNumber), Some(columnIndex))))
281+
protected def toErrors(results: Rule#RuleValidation[Any], lineNumber: Int, columnIndex: Int): MetaDataValidation[Any] = results.leftMap(_.map(FailMessage(ValidationError, _, Some(lineNumber), Some(columnIndex))))
266282

267283
protected def rulesForCell(columnIndex: Int, row: Row, schema: Schema, mayBeLast: Option[Boolean] = None): MetaDataValidation[Any]
268284

csv-validator-core/src/main/scala/uk/gov/nationalarchives/csv/validator/Util.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*/
99
package uk.gov.nationalarchives.csv.validator
1010

11-
import scala.collection.mutable
11+
import scala.language.postfixOps
1212
import scalax.file.Path
1313
import scalaz._
1414
import Scalaz._
@@ -26,9 +26,9 @@ object Util {
2626

2727
def checkFilesReadable(files: List[Path]) = files.map(fileReadable).sequence[AppValidation, FailMessage]
2828

29-
def fileReadable(file: Path): AppValidation[FailMessage] = if (file.exists && file.canRead) SchemaMessage(file.path).successNel[FailMessage] else fileNotReadableMessage(file).failureNel[FailMessage]
29+
def fileReadable(file: Path): AppValidation[FailMessage] = if (file.exists && file.canRead) FailMessage(SchemaDefinitionError, file.path).successNel[FailMessage] else fileNotReadableMessage(file).failureNel[FailMessage]
3030

31-
def fileNotReadableMessage(file: Path) = SchemaMessage("Unable to read file : " + file.path)
31+
def fileNotReadableMessage(file: Path) = FailMessage(SchemaDefinitionError, "Unable to read file : " + file.path)
3232

3333
/**
3434
* Check if the list l1 contain all element in l2

csv-validator-core/src/main/scala/uk/gov/nationalarchives/csv/validator/schema/SchemaParser.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@ import java.io.Reader
1818
import scalaz._
1919
import Scalaz._
2020

21-
import uk.gov.nationalarchives.csv.validator.{SchemaMessage, FailMessage}
21+
import uk.gov.nationalarchives.csv.validator.{SchemaDefinitionError, FailMessage}
2222

2323
/**
2424
* CSV Schema Parser
2525
*
2626
* Uses Scala Parser Combinators to parse the CSV Schema language defined in
2727
* the specification document
28+
*
2829
* @see http://digital-preservation.github.io/csv-validator/csv-schema-1.0.html
2930
*/
3031
trait SchemaParser extends RegexParsers
@@ -122,9 +123,9 @@ with TraceableParsers {
122123
parse(reader) match {
123124
case s @ Success(schema: Schema, next) => {
124125
val errors = SchemaValidator.validate(schema)
125-
if (errors.isEmpty) schema.successNel[FailMessage] else SchemaMessage(errors).failureNel[Schema]
126+
if (errors.isEmpty) schema.successNel[FailMessage] else FailMessage(SchemaDefinitionError, errors).failureNel[Schema]
126127
}
127-
case n: NoSuccess => SchemaMessage(formatNoSuccessMessageForPlatform(n.toString)).failureNel[Schema]
128+
case n: NoSuccess => FailMessage(SchemaDefinitionError, formatNoSuccessMessageForPlatform(n.toString)).failureNel[Schema]
128129
}
129130
}
130131

0 commit comments

Comments
 (0)