Skip to content

Commit

Permalink
feature/dynamicversion: added support for remote config files
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonJPegg committed Jul 4, 2019
1 parent 1832499 commit 4a04808
Show file tree
Hide file tree
Showing 13 changed files with 311 additions and 44 deletions.
1 change: 0 additions & 1 deletion .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
version = "1.5.1"
maxColumn = 120
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ Note: `version.scala.binary` refers to major releases of scala ie. 2.11 or 2.12
</plugin>
```

`configLocation` Can either be a local path (e.g. `${project.basedir}/.scalafmt.conf`) or a HTTP url (e.g `https://raw.githubusercontent.com/jozic/scalafmt-config/master/.scalafmt.conf`)

make sure you have set a version in your scalafmt.conf
```yaml
version = "1.5.1"
Expand Down
42 changes: 11 additions & 31 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<groupId>org.antipathy</groupId>
<artifactId>mvn-scalafmt_${version.scala.binary}</artifactId>
<packaging>maven-plugin</packaging>
<version>1.0.0-RC1</version>
<version>1.0.0-RC2</version>
<name>ScalaFmt Maven Plugin (${version.scala.binary})</name>
<description>Maven plugin for ScalaFmt</description>
<url>https://github.com/SimonJPegg/mvn_scalafmt</url>
Expand Down Expand Up @@ -35,13 +35,16 @@
<properties>
<version.commonsio>2.6</version.commonsio>
<version.commonslang>3.8</version.commonslang>
<version.commonsvalidator>1.4.0</version.commonsvalidator>
<version.java>1.8</version.java>
<version.maven.annotations>3.5.2</version.maven.annotations>
<version.maven.plugin.compiler>3.8.0</version.maven.plugin.compiler>
<version.maven.plugin.gpg>1.6</version.maven.plugin.gpg>
<version.maven.plugin.javadoc>3.1.0</version.maven.plugin.javadoc>
<version.maven.plugin.nexus.staging>1.6.8</version.maven.plugin.nexus.staging>
<version.maven.plugin.plugin>3.5.2</version.maven.plugin.plugin>
<version.maven.plugin.scala>3.4.2</version.maven.plugin.scala>
<version.maven.plugin.source>3.1.0</version.maven.plugin.source>
<version.maven.plugin.scalatest>1.0</version.maven.plugin.scalatest>
<version.maven.plugin.surefire>2.7</version.maven.plugin.surefire>
<version.maven>3.5.4</version.maven>
Expand Down Expand Up @@ -87,6 +90,11 @@
<version>${version.commonsio}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId>
<version>${version.commonsvalidator}</version>
</dependency>
<dependency>
<groupId>org.scalatest</groupId>
<artifactId>scalatest_${version.scala.binary}</artifactId>
Expand Down Expand Up @@ -162,33 +170,6 @@
<artifactId>maven-plugin-plugin</artifactId>
<version>${version.maven.plugin.plugin}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<configuration>
<additionalparam>-Xdoclint:none</additionalparam>
</configuration>
</plugin>
<plugin>
<groupId>org.antipathy</groupId>
<artifactId>mvn-scalafmt_${version.scala.binary}</artifactId>
Expand Down Expand Up @@ -222,6 +203,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>${version.maven.plugin.source}</version>
<executions>
<execution>
<id>attach-sources</id>
Expand All @@ -234,6 +216,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${version.maven.plugin.javadoc}</version>
<executions>
<execution>
<id>attach-javadocs</id>
Expand All @@ -242,9 +225,6 @@
</goals>
</execution>
</executions>
<configuration>
<additionalparam>-Xdoclint:none</additionalparam>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ import org.antipathy.mvn_scalafmt.format.{Formatter, SourceFileFormatter}
import org.antipathy.mvn_scalafmt.io.{FormattedFileWriter, Writer}
import org.antipathy.mvn_scalafmt.logging.MavenLogReporter
import org.antipathy.mvn_scalafmt.model.FormatResult
import org.antipathy.mvn_scalafmt.validation.ConfigFileValidator
import org.apache.maven.plugin.logging.Log
import org.scalafmt.interfaces.Scalafmt

import org.antipathy.mvn_scalafmt.builder.LocalConfigBuilder
import scala.collection.JavaConverters._

/**
Expand Down Expand Up @@ -43,7 +42,7 @@ class ScalaFormatter(
object ScalaFormatter {

def apply(configLocation: String, log: Log, respectVersion: Boolean): ScalaFormatter = {
val config = new ConfigFileValidator(log).validate(configLocation)
val config = LocalConfigBuilder(log).build(configLocation)
val sourceBuilder = new SourceFileSequenceBuilder(log)
val scalafmt = Scalafmt
.create(this.getClass.getClassLoader)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package org.antipathy.mvn_scalafmt.builder

import java.nio.file.Path

import org.antipathy.mvn_scalafmt.io.{Reader, Writer}
import org.antipathy.mvn_scalafmt.model.RemoteConfig
import org.antipathy.mvn_scalafmt.validation.Validator
import org.apache.commons.validator.routines.UrlValidator
import org.antipathy.mvn_scalafmt.validation.ConfigFileValidator
import org.apache.maven.plugin.logging.Log
import org.antipathy.mvn_scalafmt.io.{RemoteConfigReader, RemoteConfigWriter}

/**
* Class for building a local config from a remote location and validating the path is correct
* @param urlValidator Class for validating if string is a valid url
* @param configValidator Class for validating a local config's path
* @param remoteConfigReader Class for reading a remote config
* @param remoteConfigWriter Class for writing a remote config to a local path
* @param log The maven logger
*/
class LocalConfigBuilder(
urlValidator: UrlValidator,
configValidator: Validator[String, Path],
remoteConfigReader: Reader[String, RemoteConfig],
remoteConfigWriter: Writer[RemoteConfig],
log: Log
) extends Builder[String, Path] {

/**
* Read an object from the specified location
*
* @param location The location to read from
* @return The object at the location
*/
override def build(location: String): Path =
if (urlValidator.isValid(location)) {
val remoteConfig = remoteConfigReader.read(location)
remoteConfigWriter.write(remoteConfig)
configValidator.validate(remoteConfig.location.toAbsolutePath.toString)
} else {
configValidator.validate(location)
}
}

object LocalConfigBuilder {

def apply(
log: Log
): LocalConfigBuilder =
new LocalConfigBuilder(
new UrlValidator(Array("http", "https")),
new ConfigFileValidator(log),
new RemoteConfigReader(log),
new RemoteConfigWriter(log),
log
)
}
16 changes: 16 additions & 0 deletions src/main/scala/org/antipathy/mvn_scalafmt/io/Reader.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.antipathy.mvn_scalafmt.io

/**
* Base trait for reading
* @tparam I The input type
* @tparam O The output type
*/
trait Reader[I, O] {

/**
* Read an object from the specified location
* @param location The location to read from
* @return The object at the location
*/
def read(location: I): O
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.antipathy.mvn_scalafmt.io

import java.net.URL

import org.antipathy.mvn_scalafmt.model.RemoteConfig
import org.apache.maven.plugin.logging.Log
import scala.util.{Failure, Success, Try}

/**
* Class for retrieving a config from a remote location
*
* @param log The maven logger
*/
class RemoteConfigReader(log: Log) extends Reader[String, RemoteConfig] {

/**
* Read an object from the specified location
*
* @param location The url to read from
* @return A remote config
*/
override def read(location: String): RemoteConfig =
Try {
log.info(s"Reading config from $location")
RemoteConfig(
contents = scala.io.Source.fromURL(new URL(location)).mkString
)
} match {
case Success(value) => value
case Failure(exception) =>
log.error(s"error retrieving remote config: ${exception.getMessage}", exception)
throw exception
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.antipathy.mvn_scalafmt.io

import org.antipathy.mvn_scalafmt.model.RemoteConfig
import java.io.File
import java.nio.charset.StandardCharsets
import org.apache.commons.io.FileUtils
import org.apache.maven.plugin.logging.Log
import java.nio.file.Files

/**
* Class for writing a remote config to a local path
* @param log The maven logger
*/
class RemoteConfigWriter(log: Log) extends Writer[RemoteConfig] {

/**
* Write the passed in remote config to a local file
*
* @param input The input to write
*/
override def write(input: RemoteConfig): Unit = {

log.info(s"Writing remote config to ${input.location.toAbsolutePath}")

if (Files.exists(input.location)) {
Files.delete(input.location)
}

FileUtils.writeStringToFile(
new File(input.location.toAbsolutePath.toString),
input.contents,
StandardCharsets.UTF_8
)
}
}
11 changes: 11 additions & 0 deletions src/main/scala/org/antipathy/mvn_scalafmt/model/RemoteConfig.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.antipathy.mvn_scalafmt.model

import java.nio.file.{Path, Paths}

/**
* Container class for a remote scalafmt config
*
* @param contents The contents of the config
* @param location The local path where the config will be stored
*/
case class RemoteConfig(contents: String, location: Path = Paths.get(".scalafmt.conf"))
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import org.apache.maven.plugin.logging.Log
* Class for validating the ScalaFmt config
* @param log The maven logger
*/
class ConfigFileValidator(log: Log) extends Validator[String, Path] {
class ConfigFileValidator(
log: Log
) extends Validator[String, Path] {

/**
* Validate the passed in input
Expand All @@ -18,12 +20,16 @@ class ConfigFileValidator(log: Log) extends Validator[String, Path] {
* @return The validated output
*/
@throws[IllegalArgumentException]
override def validate(location: String): Path =
if (location == null || location.trim().equals("") || !Files.exists(Paths.get(location))) {
val exception = new IllegalArgumentException(s"Config path is invalid: $location")
log.error(exception)
throw exception
} else {
Paths.get(location)
}
override def validate(location: String): Path = location match {
case "" | null => throw buildException(s"Config path is null or empty")
case invalidPath if !Files.exists(Paths.get(invalidPath)) =>
throw buildException(s"Config path is invalid: $location")
case _ => Paths.get(location)
}

private def buildException(message: String): Exception = {
val exception = new IllegalArgumentException(message)
log.error(exception)
exception
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.antipathy.mvn_scalafmt.builder

import org.scalatest.{FlatSpec, GivenWhenThen, Matchers}
import org.apache.maven.plugin.logging.SystemStreamLog
import java.io.File

class LocalConfigBuilderSpec extends FlatSpec with GivenWhenThen with Matchers {

behavior of "LocalConfigBuilder"

it should "Ensure a local config is correct" in {

val builder = LocalConfigBuilder(new SystemStreamLog)
val path = ".scalafmt.conf"

val resultPath = builder.build(path)

resultPath.toString should be(path)
}

it should "Retrieve a remote config and store it locally" in {

val builder = LocalConfigBuilder(new SystemStreamLog)
val path = "https://raw.githubusercontent.com/SimonJPegg/mvn_scalafmt/master/.scalafmt.conf"
val expectedContent = scala.io.Source
.fromURL("https://raw.githubusercontent.com/SimonJPegg/mvn_scalafmt/master/.scalafmt.conf")
.mkString

builder.build(path)

val result = scala.io.Source.fromFile(new File(".scalafmt.conf")).getLines().mkString

result.trim should be(expectedContent.trim)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.antipathy.mvn_scalafmt.io

import org.scalatest.{FlatSpec, GivenWhenThen, Matchers}
import org.apache.maven.plugin.logging.SystemStreamLog
import java.net.MalformedURLException

class RemoteConfigReaderSpec extends FlatSpec with GivenWhenThen with Matchers {

behavior of "RemoteConfigReader"

it should "read a config from a remote location" in {

val url =
"https://raw.githubusercontent.com/SimonJPegg/mvn_scalafmt/35f3863c501b43beb59d84cb49fe124ee99c70a5/.scalafmt.conf"
val reader = new RemoteConfigReader(new SystemStreamLog)
val expectedResult = "maxColumn = 120\n"

reader.read(url).contents should be(expectedResult)
}

it should "raise an exception when unable to retrieve a config" in {
val url = "Skyrim belongs to the Nords"
val reader = new RemoteConfigReader(new SystemStreamLog)

an[MalformedURLException] should be thrownBy {
reader.read(url)
}
}

}
Loading

0 comments on commit 4a04808

Please sign in to comment.