Coder Social home page Coder Social logo

jooq-mcve's Issues

'build.plugins.plugin.version' for org.apache.maven.plugins:maven-surefire-plugin is missing

This warning is logged when running the mcve build:

[WARNING] Some problems were encountered while building the effective model for org.jooq:jooq-mcve-java-mariadb:jar:1.0
[WARNING] 'build.plugins.plugin.version' for org.apache.maven.plugins:maven-surefire-plugin is missing. @ line 220, column 21
[WARNING]
[WARNING] Some problems were encountered while building the effective model for org.jooq:jooq-mcve-java-mysql:jar:1.0
[WARNING] 'build.plugins.plugin.version' for org.apache.maven.plugins:maven-surefire-plugin is missing. @ line 220, column 21
[WARNING]
[WARNING] Some problems were encountered while building the effective model for org.jooq:jooq-mcve-java-oracle:jar:1.0
[WARNING] 'build.plugins.plugin.version' for org.apache.maven.plugins:maven-surefire-plugin is missing. @ line 233, column 21
[WARNING]
[WARNING] Some problems were encountered while building the effective model for org.jooq:jooq-mcve-java-postgres:jar:1.0
[WARNING] 'build.plugins.plugin.version' for org.apache.maven.plugins:maven-surefire-plugin is missing. @ line 213, column 21

Upgrade H2 to 2.1.214

The version mismatch warning appears in the logs:

15:42:53,418  WARN [jooq.impl.DefaultExecuteContext.logVersionSupport ] - Version mismatch         : Database version is older than what dialect H2 supports: 2.1.210 (2022-01-17). Consider https://www.jooq.org/download/support-matrix to see what jOOQ version and edition supports which RDBMS versions.

And indeed, we're not using the latest H2 version. Let's upgrade to 2.1.214

Directories are case-sensitive in root pom.xml

diff --git a/pom.xml b/pom.xml
index bce6874..407642f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -14,8 +14,8 @@
     </properties>
 
     <modules>
-        <module>jooq-mcve-java</module>
-        <module>jooq-mcve-kotlin</module>
-        <module>jooq-mcve-scala</module>
+        <module>jOOQ-mcve-java</module>
+        <module>jOOQ-mcve-kotlin</module>
+        <module>jOOQ-mcve-scala</module>
     </modules>
 </project>

This is a problem on Linux where case matters.

Add template projects for MariaDB, Oracle, SQL Server usage

In addition to supporting PostgreSQL with testcontainers (#21), let's support templates as well for:

  • MariaDB
  • Oracle
  • SQL Server

These won't be part of the modules listed in the parent project, as the commercial dependency won't be available from Maven Central (users tend to build only the relevant child module, so we should be fine)

Add explicit maven central repository configuration after repo.jooq.org

We're now using the commercial artifact repository in the jOOQ-mcve repo:
723533a

But given that:

  • Most people use the jOOQ Open Source Edition
  • Tons of third parties are also downloaded

It would probably be better to list Maven Central first, only then the commercial repo, also as a hint that end users should do things this way.

Insert Batch issue

When using the batch insert, the process just used the first bind parameter for all the batch statements

(Cosmetic?) Exceptions in build

When running a mvn clean install on the repository, this is the last output:

Exception in thread "Thread-26" Exception in thread "Thread-46" Exception in thread "Thread-34" java.lang.NoClassDefFoundError: org/testcontainers/utility/PathUtils
        at org.testcontainers.utility.MountableFile.lambda$deleteOnExit$0(MountableFile.java:318)
        at java.base/java.lang.Thread.run(Thread.java:1589)
Caused by: java.lang.ClassNotFoundException: org.testcontainers.utility.PathUtils
        ... 2 more
java.lang.NoClassDefFoundError: org/testcontainers/utility/PathUtils
        at org.testcontainers.utility.MountableFile.lambda$deleteOnExit$0(MountableFile.java:318)
        at java.base/java.lang.Thread.run(Thread.java:1589)
Caused by: java.lang.ClassNotFoundException: org.testcontainers.utility.PathUtils
        at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:50)
        at org.codehaus.plexus.classworlds.realm.ClassRealm.unsynchronizedLoadClass(ClassRealm.java:271)
        at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:247)
        at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:239)
        ... 2 more
java.lang.NoClassDefFoundError: org/testcontainers/utility/PathUtils
        at org.testcontainers.utility.MountableFile.lambda$deleteOnExit$0(MountableFile.java:318)
        at java.base/java.lang.Thread.run(Thread.java:1589)
Caused by: java.lang.ClassNotFoundException: org.testcontainers.utility.PathUtils
        ... 2 more

It appears to be irrelevant to the MCVE, but is still a distraction worth solving.

Add testcontainers based MCVE for PostgreSQL

The default MCVE uses H2, which can be sufficient for a lot of cases that aren't really vendor specific. However, when users want to show something vendor specific, a testcontainers based PostgreSQL MCVE would be more useful. In the future, we might support other dialects, too, but as an example, PostgreSQL should be fine.

Can't find init.sql script when run from IntelliJ

This error appears when running the PostgreSQL mcve from within IntelliJ:

org.testcontainers.containers.ContainerLaunchException: Container startup failed

	at org.testcontainers.containers.GenericContainer.doStart(GenericContainer.java:349)
	at org.testcontainers.containers.GenericContainer.start(GenericContainer.java:322)
	at org.jooq.mcve.test.java.postgres.JavaTest.init(JavaTest.java:42)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at org.junit.internal.runners.statements.RunBefores.invokeMethod(RunBefores.java:33)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
	at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Caused by: org.rnorth.ducttape.RetryCountExceededException: Retry limit hit with exception
	at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:88)
	at org.testcontainers.containers.GenericContainer.doStart(GenericContainer.java:334)
	... 21 more
Caused by: org.testcontainers.containers.ContainerLaunchException: Could not create/start container
	at org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:542)
	at org.testcontainers.containers.GenericContainer.lambda$doStart$0(GenericContainer.java:344)
	at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:81)
	... 22 more
Caused by: org.testcontainers.ext.ScriptUtils$ScriptLoadException: Could not load classpath init script: /db/migration/init.sql. Resource not found.
	at org.testcontainers.ext.ScriptUtils.runInitScript(ScriptUtils.java:357)
	at org.testcontainers.containers.JdbcDatabaseContainer.runInitScriptIfRequired(JdbcDatabaseContainer.java:323)
	at org.testcontainers.containers.JdbcDatabaseContainer.containerIsStarted(JdbcDatabaseContainer.java:188)
	at org.testcontainers.containers.GenericContainer.containerIsStarted(GenericContainer.java:701)
	at org.testcontainers.containers.GenericContainer.tryStart(GenericContainer.java:521)
	... 24 more

Add the usual branches to this project

Some users can't upgrade to the latest version of jOOQ for good reasons, so it would be useful to have the usual branches in this project as well.

This would allow:

  • For keeping latest patch version dependency per branch up to date in each branch
  • Referencing the latest supported third party versions (e.g. H2, etc.)
  • Using the latest features (e.g. jOOQ-migrations starting from jOOQ 3.19, instead of Flyway)

`NullPointerException` with jOOQ 3.15.0

This template project works with jOOQ up to v3.14.12. With jOOQ v3.15.0 a mvn verify will end in a NullPointerException.

Steps to reproduce:

  1. clone this repository
  2. run mvn verify -> success
  3. change jOOQ version to 3.15.0 in pom.xml line 16
  4. run mvn verify -> NullPointerException

This is the stacktrace:

[INFO] --- scala-maven-plugin:4.3.0:compile (default) @ jooq-mcve ---
[INFO] Using incremental compilation using Mixed compile order
[INFO] Compiler bridge file: /Users/mcpringle/.sbt/1.0/zinc/org.scala-sbt/org.scala-sbt-compiler-bridge_2.13-1.3.1-bin_2.13.1__55.0-1.3.1_20191012T045515.jar
[INFO] Compiling 6 Scala sources and 6 Java sources to /Users/mcpringle/IdeaProjects/jOOQ-mcve/target/classes ...
[ERROR] ## Exception when compiling 12 sources to /Users/mcpringle/IdeaProjects/jOOQ-mcve/target/classes
java.lang.NullPointerException
scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon$4.preErase(Erasure.scala:1273)
scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon$4.transform(Erasure.scala:1328)
scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon$4.transform(Erasure.scala:988)
scala.reflect.internal.Trees$Apply.transform(Trees.scala:759)
scala.tools.nsc.transform.TypingTransformers$TypingTransformer.transform(TypingTransformers.scala:51)
scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon$4.transform(Erasure.scala:1364)
scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon$4.transform(Erasure.scala:988)
scala.reflect.internal.Trees$DefDef.$anonfun$transform$5(Trees.scala:427)
scala.reflect.api.Trees$Transformer.atOwner(Trees.scala:2625)
scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:37)
scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:32)
scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:24)
scala.reflect.internal.Trees$DefDef.transform(Trees.scala:425)
scala.tools.nsc.transform.TypingTransformers$TypingTransformer.transform(TypingTransformers.scala:51)
scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon$4.transform(Erasure.scala:1354)
scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon$4.transform(Erasure.scala:988)
scala.reflect.api.Trees$Transformer.$anonfun$transformStats$1(Trees.scala:2614)
scala.reflect.api.Trees$Transformer.transformStats(Trees.scala:2612)
scala.reflect.internal.Trees$Template.transform(Trees.scala:517)
scala.tools.nsc.transform.TypingTransformers$TypingTransformer.$anonfun$transform$1(TypingTransformers.scala:47)
scala.reflect.api.Trees$Transformer.atOwner(Trees.scala:2625)
scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:37)
scala.tools.nsc.transform.TypingTransformers$TypingTransformer.transform(TypingTransformers.scala:32)
scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon$4.transform(Erasure.scala:1364)
scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon$4.transform(Erasure.scala:988)
scala.reflect.api.Trees$Transformer.transformTemplate(Trees.scala:2587)
scala.reflect.internal.Trees$ClassDef.$anonfun$transform$2(Trees.scala:335)
scala.reflect.api.Trees$Transformer.atOwner(Trees.scala:2625)
scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:37)
scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:32)
scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:24)
scala.reflect.internal.Trees$ClassDef.transform(Trees.scala:334)
scala.tools.nsc.transform.TypingTransformers$TypingTransformer.transform(TypingTransformers.scala:51)
scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon$4.transform(Erasure.scala:1364)
scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon$4.transform(Erasure.scala:988)
scala.reflect.api.Trees$Transformer.$anonfun$transformStats$1(Trees.scala:2614)
scala.reflect.api.Trees$Transformer.transformStats(Trees.scala:2612)
scala.reflect.internal.Trees$PackageDef.$anonfun$transform$1(Trees.scala:316)
scala.reflect.api.Trees$Transformer.atOwner(Trees.scala:2625)
scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:37)
scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:32)
scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:24)
scala.reflect.internal.Trees$PackageDef.transform(Trees.scala:316)
scala.tools.nsc.transform.TypingTransformers$TypingTransformer.$anonfun$transform$2(TypingTransformers.scala:49)
scala.reflect.api.Trees$Transformer.atOwner(Trees.scala:2625)
scala.tools.nsc.transform.TypingTransformers$TypingTransformer.atOwner(TypingTransformers.scala:37)
scala.tools.nsc.transform.TypingTransformers$TypingTransformer.transform(TypingTransformers.scala:32)
scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon$4.transform(Erasure.scala:1364)
scala.tools.nsc.transform.Erasure$ErasureTransformer.transform(Erasure.scala:1374)
scala.tools.nsc.ast.Trees$Transformer.transformUnit(Trees.scala:162)
scala.tools.nsc.transform.Transform$Phase.apply(Transform.scala:36)
scala.tools.nsc.Global$GlobalPhase.applyPhase(Global.scala:452)
scala.tools.nsc.Global$GlobalPhase.run(Global.scala:397)
scala.tools.nsc.Global$Run.compileUnitsInternal(Global.scala:1506)
scala.tools.nsc.Global$Run.compileUnits(Global.scala:1490)
scala.tools.nsc.Global$Run.compileSources(Global.scala:1482)
scala.tools.nsc.Global$Run.compile(Global.scala:1614)
xsbt.CachedCompiler0.run(CompilerInterface.scala:153)
xsbt.CachedCompiler0.run(CompilerInterface.scala:125)
xsbt.CompilerInterface.run(CompilerInterface.scala:39)
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base/java.lang.reflect.Method.invoke(Method.java:566)
sbt.internal.inc.AnalyzingCompiler.call(AnalyzingCompiler.scala:248)
sbt.internal.inc.AnalyzingCompiler.compile(AnalyzingCompiler.scala:122)
sbt.internal.inc.AnalyzingCompiler.compile(AnalyzingCompiler.scala:95)
sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$4(MixedAnalyzingCompiler.scala:91)
scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
sbt.internal.inc.MixedAnalyzingCompiler.timed(MixedAnalyzingCompiler.scala:186)
sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$3(MixedAnalyzingCompiler.scala:82)
sbt.internal.inc.MixedAnalyzingCompiler.$anonfun$compile$3$adapted(MixedAnalyzingCompiler.scala:77)
sbt.internal.inc.JarUtils$.withPreviousJar(JarUtils.scala:215)
sbt.internal.inc.MixedAnalyzingCompiler.compileScala$1(MixedAnalyzingCompiler.scala:77)
sbt.internal.inc.MixedAnalyzingCompiler.compile(MixedAnalyzingCompiler.scala:146)
sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileInternal$1(IncrementalCompilerImpl.scala:343)
sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileInternal$1$adapted(IncrementalCompilerImpl.scala:343)
sbt.internal.inc.Incremental$.doCompile(Incremental.scala:120)
sbt.internal.inc.Incremental$.$anonfun$compile$4(Incremental.scala:100)
sbt.internal.inc.IncrementalCommon.recompileClasses(IncrementalCommon.scala:180)
sbt.internal.inc.IncrementalCommon.cycle(IncrementalCommon.scala:98)
sbt.internal.inc.Incremental$.$anonfun$compile$3(Incremental.scala:102)
sbt.internal.inc.Incremental$.manageClassfiles(Incremental.scala:155)
sbt.internal.inc.Incremental$.compile(Incremental.scala:92)
sbt.internal.inc.IncrementalCompile$.apply(Compile.scala:75)
sbt.internal.inc.IncrementalCompilerImpl.compileInternal(IncrementalCompilerImpl.scala:348)
sbt.internal.inc.IncrementalCompilerImpl.$anonfun$compileIncrementally$1(IncrementalCompilerImpl.scala:301)
sbt.internal.inc.IncrementalCompilerImpl.handleCompilationError(IncrementalCompilerImpl.scala:168)
sbt.internal.inc.IncrementalCompilerImpl.compileIncrementally(IncrementalCompilerImpl.scala:248)
sbt.internal.inc.IncrementalCompilerImpl.compile(IncrementalCompilerImpl.scala:74)
sbt_inc.SbtIncrementalCompiler.compile(SbtIncrementalCompiler.java:173)
scala_maven.ScalaCompilerSupport.incrementalCompile(ScalaCompilerSupport.java:297)
scala_maven.ScalaCompilerSupport.compile(ScalaCompilerSupport.java:109)
scala_maven.ScalaCompilerSupport.doExecute(ScalaCompilerSupport.java:91)
scala_maven.ScalaMojoSupport.execute(ScalaMojoSupport.java:554)
org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:137)
org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:210)
org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:156)
org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:148)
org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:117)
org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:81)
org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:56)
org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:305)
org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:192)
org.apache.maven.DefaultMaven.execute(DefaultMaven.java:105)
org.apache.maven.cli.MavenCli.execute(MavenCli.java:957)
org.apache.maven.cli.MavenCli.doMain(MavenCli.java:289)
org.apache.maven.cli.MavenCli.main(MavenCli.java:193)
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base/java.lang.reflect.Method.invoke(Method.java:566)
org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:282)
org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:225)
org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:406)
org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:347)
           
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  27.307 s
[INFO] Finished at: 2021-07-07T18:28:17+02:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal net.alchim31.maven:scala-maven-plugin:4.3.0:compile (default) on project jooq-mcve: Execution default of goal net.alchim31.maven:scala-maven-plugin:4.3.0:compile failed.: NullPointerException -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginExecutionException

Tested with AdoptOpenJDK-11.0.11+9 on macOS Big Sur 11.4 (M1).

Add Maven wrapper scripts

Gradle users may have issues setting up an MCVE using Maven. If the problem is purely jOOQ related, then a Maven wrapper might help those users, without them having to set up a Gradle scripts.

(Obviously, it might still be worth supporting Gradle as well, but that's another task for another day).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.