Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

airframe-log: Dotty support #1381

Merged
merged 17 commits into from Dec 5, 2020
4 changes: 3 additions & 1 deletion .github/workflows/release.yml
Expand Up @@ -32,7 +32,9 @@ jobs:
- name: Build bundle
env:
PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }}
run: ./sbt "; + projectJVM/publishSigned; sbtAirframe/publishSigned;"
run: |
./sbt "; + projectJVM/publishSigned; sbtAirframe/publishSigned;"
DOTTY=true ./sbt projectDotty/publishSigned
- name: Release to Sonatype
env:
SONATYPE_USERNAME: '${{ secrets.SONATYPE_USER }}'
Expand Down
15 changes: 15 additions & 0 deletions .github/workflows/test.yml
Expand Up @@ -55,6 +55,21 @@ jobs:
restore-keys: ${{ runner.os }}-scala-2.13-
- name: Scala 2.13 test
run: ./sbt ++2.13.4 projectJVM/test
test_3:
name: Scala 3.x (Dotty)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: olafurpg/setup-scala@v10
with:
java-version: adopt@1.11
- uses: actions/cache@v1
with:
path: ~/.cache
key: ${{ runner.os }}-scala-3-${{ hashFiles('**/*.sbt') }}
restore-keys: ${{ runner.os }}-scala-3-
- name: Scala 3.x test
run: DOTTY=true ./sbt dottyTest/run
test_js:
name: Scala.js / Scala 2.12
runs-on: ubuntu-latest
Expand Down
12 changes: 12 additions & 0 deletions README.md
Expand Up @@ -36,6 +36,18 @@ Airframe https://wvlet.org/airframe is a collection of [lightweight building blo
<p><img src="https://github.com/wvlet/airframe/raw/master/logos/airframe-overview.png" alt="logo" width="800px"></p>


## Build

### Dotty (Scala 3.0)

For developing with Dotty, use DOTTY=true environment variable:
```
$ DOTTY=true ./sbt
> logJVM/test
```

Here is the list of milestones for Dotty support: [#1077](https://github.com/wvlet/airframe/issues/1077)

## LICENSE

[Apache v2](https://github.com/wvlet/airframe/blob/master/LICENSE)
39 changes: 39 additions & 0 deletions airframe-dotty-test/src/main/scala/dotty/test/LogTest.scala
@@ -0,0 +1,39 @@
package dotty.test

import wvlet.log.{LogFormatter, LogLevel, LogSupport, Logger}

object LogTest extends LogSupport {

def main(args: Array[String]): Unit = {
//Logger.setDefaultFormatter(LogFormatter.SourceCodeLogFormatter)
info("Hello airframe-log")
debug("Hello airframe-log")
error("Hello airframe-log")
warn("Hello airframe-log")
trace("Hello airframe-log")

logger.info("direct log")
logger.debug("direct log")
logger.trace("direct log")
logger.warn("direct log")
logger.error("direct log")

logger.setLogLevel(LogLevel.TRACE)
logger.info("direct log")
logger.debug("direct log")
logger.trace("direct log")
logger.warn("direct log")
logger.error("direct log")

logger.setLogLevel(LogLevel.WARN)
info("Hello airframe-log")
debug("Hello airframe-log")
error("Hello airframe-log")
warn("Hello airframe-log")
trace("Hello airframe-log")

warn("exception log test", new IllegalArgumentException("invalid arg"))

Logger.setDefaultLogLevel(LogLevel.INFO)
}
}
Expand Up @@ -18,7 +18,7 @@ object AirframeLogManager {
private[log] var instance: Option[AirframeLogManager] = None

private[wvlet] def resetFinally: Unit = {
instance.map(_.reset0)
instance.map(_.reset0())
instance = None
}
}
Expand Down
Expand Up @@ -51,7 +51,7 @@ class AsyncHandler(parent: jl.Handler) extends jl.Handler with Guard with AutoCl
}
}

records.result.map(parent.publish _)
records.result().map(parent.publish _)
parent.flush()
}

Expand Down
32 changes: 24 additions & 8 deletions airframe-log/jvm/src/main/scala/wvlet/log/io/Resource.scala
Expand Up @@ -112,7 +112,12 @@ object Resource {
* @return
*/
def find(absoluteResourcePath: String): Option[URL] =
find("", if (absoluteResourcePath.startsWith("/")) absoluteResourcePath.substring(1) else absoluteResourcePath)
find(
"",
if (absoluteResourcePath.startsWith("/"))
absoluteResourcePath.substring(1)
else absoluteResourcePath
)

/**
* Finds the java.net.URL of the resource
Expand All @@ -133,7 +138,7 @@ object Resource {
urlClassLoader.getResource(resourcePath) match {
case path: URL =>
Some(path)
case _ =>
case null =>
loop(urlClassLoader.getParent)
}
case None => None
Expand Down Expand Up @@ -291,7 +296,7 @@ object Resource {
throw new UnsupportedOperationException("resources other than file or jar are not supported: " + resourceURL)
}

fileList.result
fileList.result()
}

/**
Expand All @@ -301,7 +306,12 @@ object Resource {
* @return
*/
def listResources(packageName: String): Seq[VirtualFile] =
listResources(packageName, { f: String => true })
listResources(
packageName,
{ (f: String) =>
true
}
)

/**
* Collect resources under the given package
Expand All @@ -320,7 +330,7 @@ object Resource {
for (u <- findResourceURLs(classLoader, packageName)) {
b ++= listResources(u, packageName, resourceFilter)
}
b.result
b.result()
}

/**
Expand Down Expand Up @@ -350,15 +360,21 @@ object Resource {
}

loop(currentClassLoader)
b.result
b.result()
}

def findClasses[A](
packageName: String,
toSearch: Class[A],
classLoader: ClassLoader = Thread.currentThread.getContextClassLoader
): Seq[Class[A]] = {
val classFileList = listResources(packageName, { f: String => f.endsWith(".class") }, classLoader)
val classFileList = listResources(
packageName,
{ (f: String) =>
f.endsWith(".class")
},
classLoader
)

def componentName(path: String): Option[String] = {
val dot: Int = path.lastIndexOf(".")
Expand All @@ -384,7 +400,7 @@ object Resource {
}
}
}
b.result
b.result()
}

def findClasses[A](searchPath: Package, toSearch: Class[A], classLoader: ClassLoader): Seq[Class[A]] = {
Expand Down
67 changes: 67 additions & 0 deletions airframe-log/shared/src/main/scala-2/wvlet/log/LoggerBase.scala
@@ -0,0 +1,67 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package wvlet.log
import scala.language.experimental.macros

/**
*/
trait LoggerBase {
import LogMacros._

def error(message: Any): Unit = macro errorLogMethod
def error(message: Any, cause: Throwable): Unit =
macro errorLogMethodWithCause

def warn(message: Any): Unit = macro warnLogMethod
def warn(message: Any, cause: Throwable): Unit = macro warnLogMethodWithCause

def info(message: Any): Unit = macro infoLogMethod
def info(message: Any, cause: Throwable): Unit = macro infoLogMethodWithCause

def debug(message: Any): Unit = macro debugLogMethod
def debug(message: Any, cause: Throwable): Unit =
macro debugLogMethodWithCause

def trace(message: Any): Unit = macro traceLogMethod
def trace(message: Any, cause: Throwable): Unit =
macro traceLogMethodWithCause
}

/**
*/
trait LoggingMethods extends Serializable {
import wvlet.log.LogMacros._

protected def error(message: Any): Unit = macro errorLog
protected def error(message: Any, cause: Throwable): Unit =
macro errorLogWithCause

protected def warn(message: Any): Unit = macro warnLog
protected def warn(message: Any, cause: Throwable): Unit =
macro warnLogWithCause

protected def info(message: Any): Unit = macro infoLog
protected def info(message: Any, cause: Throwable): Unit =
macro infoLogWithCause

protected def debug(message: Any): Unit = macro debugLog
protected def debug(message: Any, cause: Throwable): Unit =
macro debugLogWithCause

protected def trace(message: Any): Unit = macro traceLog
protected def trace(message: Any, cause: Throwable): Unit =
macro traceLogWithCause

protected def logAt(logLevel: LogLevel, message: Any): Unit = macro logAtImpl
}