Giter Club home page Giter Club logo

cursegradle's People

Contributors

dshadowwolf avatar herocc avatar jriwanek avatar matthewprenger avatar thiakil avatar wyn-price avatar

Stargazers

 avatar

Watchers

 avatar

Forkers

integerlimit

cursegradle's Issues

requiredLibrary is being ignored

It looks like the required library relation is being ignored by this plugin.
The script does not seem to give any errors with the curseforge declaration found here: https://github.com/CyclopsMC/EvilCraft/blob/master-1.8/gradle/deploy.gradle#L13-L17
But any uploaded files do not show the required library on the curseforge file download page.

Am I missing something? Or is something going wrong with in plugin?
This used to work just fine with the integrated ForgeGradle system.

No support for "non-minecraft" CurseForge sites

Hi, I'm using this plugin in a multi-version spanning Minecraft mod, that also has a Bukkit version.

The bukkit version doesn't upload correctly because the API's base URL is dev.bukkit.org instead of minecraft.curseforge.com.
If this was made settable, it would allow not only bukkit plugins, but also all other sites, such as Terraria, KSP and others.

Please consider adding support,
Thanks in advance,
Dries

Building and uploading the wrong artifact

I got strange NoSuchMethodErrors with a Forge mod, and it turned out that CurseGradle 1.0.1 was building and uploading the deobfuscated jar (from the "jar" task), rather than the correct one that could be used as mod (from the "build" task).

Cannot deploy to new CurseForge Project (HTTP 302)

I'm trying to setup a CI/CD pipeline, which is something I personally think must be done before writing code.

I've setup a project on CurseForge and marked it experimental. I don't see a place to find a numeric ID, and when using my project name (The value that shows up in https://minecraft.curseforge.com/projects/NAME) I get a 302 redirect that causes the upload to fail.

PS D:\PROJECT-NAME> ./gradlew.bat curseforge --stacktrace
To honour the JVM settings for this build a new JVM will be forked. Please consider using the daemon: https://docs.gradle.org/2.14/userguide/gradle_daemon.html.
This mapping 'snapshot_20171003' was designed for MC 1.12! Use at your own peril.
#################################################
         ForgeGradle 2.3-SNAPSHOT-ee3e3df
  https://github.com/MinecraftForge/ForgeGradle
#################################################
                 Powered by MCP
             http://modcoderpack.com
     by: Searge, ProfMobius, R4wk, ZeuX
     Fesh0r, IngisKahn, bspkrs, LexManos
#################################################
:deobfCompileDummyTask
:deobfProvidedDummyTask
:sourceApiJava UP-TO-DATE
:compileApiJava UP-TO-DATE
:processApiResources UP-TO-DATE
:apiClasses UP-TO-DATE
:sourceMainJava UP-TO-DATE
:compileJava
:processResources UP-TO-DATE
:classes
:jar
:extractMcpData SKIPPED
:extractMcpMappings SKIPPED
:getVersionJson
:extractUserdev UP-TO-DATE
:genSrgs SKIPPED
:reobfJar
:extractAnnotationsJar
:curseforgePROJECT-NAME FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':curseforgePROJECT-NAME'.
> [CurseForge PROJECT-NAME] HTTP Error Code 302: Found

* Try:
Run with --info or --debug option to get more log output.

* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':curseforgePROJECT-NAME'.
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:69)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46)
        at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:35)
        at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:66)
        at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
        at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:52)
        at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
        at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53)
        at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:203)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:185)
        at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:66)
        at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:50)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:25)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:110)
        at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:37)
        at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
        at org.gradle.execution.DefaultBuildExecuter.access$000(DefaultBuildExecuter.java:23)
        at org.gradle.execution.DefaultBuildExecuter$1.proceed(DefaultBuildExecuter.java:43)
        at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
        at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
        at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:30)
        at org.gradle.initialization.DefaultGradleLauncher$4.run(DefaultGradleLauncher.java:153)
        at org.gradle.internal.Factories$1.create(Factories.java:22)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:53)
        at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:150)
        at org.gradle.initialization.DefaultGradleLauncher.access$200(DefaultGradleLauncher.java:32)
        at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:98)
        at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:92)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
        at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:63)
        at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:92)
        at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:83)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:99)
        at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:28)
        at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:48)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:30)
        at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:81)
        at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:46)
        at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:52)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:37)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
        at org.gradle.util.Swapper.swap(Swapper.java:38)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.health.DaemonHealthTracker.execute(DaemonHealthTracker.java:40)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:60)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:72)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.health.HintGCAfterBuild.execute(HintGCAfterBuild.java:41)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
        at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
        at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:237)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
        at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
Caused by: java.lang.RuntimeException: [CurseForge PROJECT-NAME] HTTP Error Code 302: Found
        at com.matthewprenger.cursegradle.CurseUploadTask.uploadFile(CurseUploadTask.groovy:94)
        at com.matthewprenger.cursegradle.CurseUploadTask.run(CurseUploadTask.groovy:47)
        at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:75)
        at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.doExecute(AnnotationProcessingTaskFactory.java:228)
        at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:221)
        at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:210)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:621)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:604)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
        ... 68 more


BUILD FAILED

Total time: 8.657 secs

Curse API changed

uploading jars via CurseGradle does no longer work, because curse changed their API.

quoting Technostar:
requiredLibrary and optionalLibrary are going to become requiredDependency and optionalDependency

Invalid release type (alpha)

When setting the release type value using a config file, I get an error that looks like the following:

Invalid release type (alpha) for project . Valid options are: [alpha, beta, release]

in my config file I have:
`curse_release_type=alpha``

In my build.gradle I have:

curseforge  {
    apiKey = "${priv.curse_api_key}"
    project {
        id = "${config.curse_proj_id}"
        releaseType = "${config.curse_release_type}"
        mainArtifact jar
        addArtifact deobfJar
        addGameVersion "${config.minecraft_version}"
    }
}

If I change the "releaseType" line to
releaseType="alpha"
it works just fine.

Error when attempting to push MC 1.12 mod to Curse

I'm getting the following error:
Error Code 1009: Invalid game version ID: 6588 belongs to an invalid dependency.

Looking at the Curse API there appear to be two entries of 1.12:

    {
        "id": 6580,
        "gameVersionTypeID": 628,
        "name": "1.12",
        "slug": "1-12"
    },
    {
        "id": 6588,
        "gameVersionTypeID": 1,
        "name": "1.12",
        "slug": "1-12"
    }

Any ideas on how to get this to push?

curseforge {
	apiKey = ''
	project {
		id = ''
		changelogType = 'markdown'
		changelog = file('Change_v2.x.md')
		releaseType = 'release'
		addGameVersion 1.12
		mainArtifact jar
		addArtifact srcJar
		addArtifact deobfJar
	}
}

Thanks

java.lang.NoSuchMethodError when including cursegradle

Hello,

I would like to use Cursegradle to automate uploading of my cross-platform library mod. Unfortunately, when I add the plugin to my project, I get the following error on syncing the project:

Caused by: java.lang.NoSuchMethodError: 'com.google.common.io.ByteSource com.google.common.io.CharSource.asByteSource(java.nio.charset.Charset)'

The full crashlog is here.

I have done nothing but paste id "com.matthewprenger.cursegradle" version "1.4.0" into my plugins block.

Error: "Cannot add task ':curseforge' as a task with that name already exists."

I'm using the ForgeGradle-2.1 snapshots and for some reason I get this error on my local machine and on CircleCI for one project: Cannot add task ':curseforge' as a task with that name already exists.
But another project on CircleCI with the exact same configuration does not get this error.

Full error: http://pastebin.com/2rXcH2Wc
Build scripts:

Examples on CircleCI:

Can not upload file

build.gradle
curseforge {
    def envApiKey = ENV.CURSEFORGE_TOKEN
    apiKey = envApiKey == null ? 'nope' : envApiKey
    project {
        id = project.curse_id
        releaseType = project.curse_type
        changelog = project.curse_changelog
        project.curse_versions.split(", ").each {
            String gameVersion -> addGameVersion gameVersion
        }
        mainArtifact(jar) {
            displayName = "$project.name v$SemVer_version for mc$project.mc_version"
        }
    }
}
$ gradle curseforge
> Configure project :
[MixinGradle] Skipping eclipse integration, extension not found
Java: 17.0.1 JVM: 17.0.1+12(Eclipse Adoptium) Arch: amd64

> Task :downloadMcpConfig
> Task :extractSrg UP-TO-DATE
> Task :createMcpToSrg UP-TO-DATE
> Task :compileJava UP-TO-DATE
> Task :addMixinsToJar
> Task :processResources UP-TO-DATE
> Task :classes UP-TO-DATE
> Task :jar
> Task :configureReobfTaskForReobfJar
> Task :reobfJar
> Task :assemble
> Task :curseforge547361 FAILED

Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0.

You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.

See https://docs.gradle.org/7.3.3/userguide/command_line_interface.html#sec:command_line_warnings
10 actionable tasks: 6 executed, 4 up-to-date

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':curseforge547361'.
> [CurseForge] HTTP Error Code 403: Forbidden

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 12s

Keep reporting errors [CurseForge] HTTP Error Code 403: Forbidden

ForgeGradle SignJar task executed after the upload task

when uploading a mod to curseforge the project-specific task is executed before the sign jar task(s) are invoked, leading to uploading unsigned jars.

my current gradle configuration can be found here

Gradle Wrapper 2.14.1
CurseGradle 1.0-SNAPSHOT (also tried 1.0.9 and 1.0.10)
ForgeGradle 2.0-SNAPSHOT
Forge Mapings: stable_18
MC 1.8.0
Forge 11.14.4.1577

This is a recent gradle build log:
gradle.log

I don't really know if this is a real issue or if I just derped when configuring gradle, so sorry if this is my fault, and thanks for the help anyways ;D

Could not get unknown property 'ContentType' for task ':curseforge308769' of type com.matthewprenger.cursegradle.CurseUploadTask.

Trying to use CurseGradle on a project that does not use forgegradle

configured like this:

val CURSEFORGE_API_TOKEN: String? by project
if (CURSEFORGE_API_TOKEN != null) {
    curseforge {
        val CURSEFORGE_RELEASE_TYPE: String by project
        val CURSEFORGE_ID: String by project
        options(closureOf<Options> {
            forgeGradleIntegration = false
        })
        apiKey = CURSEFORGE_API_TOKEN
        project(closureOf<CurseProject> {
            id = CURSEFORGE_ID
            releaseType = CURSEFORGE_RELEASE_TYPE
            mainArtifact(shadowJar.archivePath, closureOf<CurseArtifact> {
                displayName = "MatterLink $version"
            })
        })
    }
    project.afterEvaluate {
        tasks.getByName<CurseUploadTask>("curseforge308769") {
            dependsOn(remapJar)
        }
    }
}

it needs to run remapJar which is configured to work on the shadowjar output,
but this kind of error happens

* What went wrong:
Execution failed for task ':curseforge308769'.
> Could not get unknown property 'ContentType' for task ':curseforge308769' of type com.matthewprenger.cursegradle.CurseUploadTask.

* Try:
Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':curseforge308769'.
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:96)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:65)
        at org.gradle.api.internal.tasks.execution.ActionEventFiringTaskExecuter.execute(ActionEventFiringTaskExecuter.java:44)
        at org.gradle.api.internal.tasks.execution.TimeoutTaskExecuter.execute(TimeoutTaskExecuter.java:53)
        at org.gradle.api.internal.tasks.execution.SnapshotAfterExecutionTaskExecuter.execute(SnapshotAfterExecutionTaskExecuter.java:38)
        at org.gradle.api.internal.tasks.execution.OutputDirectoryCreatingTaskExecuter.execute(OutputDirectoryCreatingTaskExecuter.java:51)
        at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:59)
        at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:49)
        at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:61)
        at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:101)
        at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:91)
        at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:44)
        at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:62)
        at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:55)
        at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:54)
        at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:35)
        at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.run(EventFiringTaskExecuter.java:49)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:301)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:293)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
        at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:44)
        at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:43)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:337)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:325)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:318)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:304)
        at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker$1.execute(DefaultPlanExecutor.java:134)
        at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker$1.execute(DefaultPlanExecutor.java:129)
        at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:202)
        at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:193)
        at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:129)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
        at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
        at java.lang.Thread.run(Thread.java:745)
Caused by: groovy.lang.MissingPropertyException: Could not get unknown property 'ContentType' for task ':curseforge308769' of type com.matthewprenger.cursegradle.CurseUploadTask.
        at org.gradle.internal.metaobject.AbstractDynamicObject.getMissingProperty(AbstractDynamicObject.java:83)
        at org.gradle.internal.metaobject.AbstractDynamicObject.getProperty(AbstractDynamicObject.java:61)
        at com.matthewprenger.cursegradle.CurseUploadTask_Decorated.getProperty(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.PogoGetPropertySite.getProperty(PogoGetPropertySite.java:49)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGroovyObjectGetProperty(AbstractCallSite.java:309)
        at com.matthewprenger.cursegradle.CurseUploadTask.uploadFile(CurseUploadTask.groovy:74)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.codehaus.groovy.runtime.callsite.PlainObjectMetaMethodSite.doInvoke(PlainObjectMetaMethodSite.java:43)
        at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSite.invoke(PogoMetaMethodSite.java:167)
        at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:58)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:176)
        at com.matthewprenger.cursegradle.CurseUploadTask.run(CurseUploadTask.groovy:46)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73)
        at org.gradle.api.internal.project.taskfactory.StandardTaskAction.doExecute(StandardTaskAction.java:48)
        at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:41)
        at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:28)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:704)
        at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:671)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$1.run(ExecuteActionsTaskExecuter.java:117)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:301)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:293)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:106)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:85)
        ... 38 more


* Get more help at https://help.gradle.org

Deprecated Gradle features were used in this build, making it incompatible with Gradle 6.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/5.0/userguide/command_line_interface.html#sec:command_line_warnings

BUILD FAILED in 14s
9 actionable tasks: 9 executed

Add emoji support to changelogs

When uploading changelogs using CurseGradle, it replaces emojis with question marks. However, when I edit the description on CurseForge, it allows emojis to be used.

I tested this with ๐Ÿฑ๐Ÿ‘ค

Provide a way to get URL of the upload

I think it would be amazing if there was a way to get the URL of the uploaded artifact(s), so it can be processed further down the line.

For example I push a Discord message on release of a new version. So having that URL means I can add that to the message.

Project Description

Hey,
I don't know the extent of the API that you are using for CurseForge, but it would be awesome if it could be added to change the Project Description through CurseGradle, this way I could automate the readme from github getting updated to the Project Description.
Thanks,
Erin

Could not get unknown property 'jar' for task ':remapJar' of type net.fabricmc.loom.task.RemapJarTask.

After loading gradle changes this error message is showing:
Could not get unknown property 'jar' for task ':remapJar' of type net.fabricmc.loom.task.RemapJarTask.

Fabric Mod Project

curseforge {
	if (project.hasProperty("curseForgeApiKey")) {
		apiKey = project.properties.curseForgeApiKey
	}

	project {
		id = "423726"
		addGameVersion "1.16.4"
		mainArtifact(remapJar.jar) {
			displayName = "GG Enchantment version:$project.version"
		}
	}
	options {
		forgeGradleIntegration = false
	}
}

How to get uploaded File ID

How do i go about getting the file id of the uploaded artifact?

This is my build.gradle:
curseforge { apiKey = key project { id = '386017' changelog = changeLog releaseType = modReleaseType relations { requiredDependency 'heroes-united' } addGameVersion mcVersion mainArtifact(jar) { displayName = title } } }

NPE Uploading files

build.gradle
curseforge {
    apply from: 'curseforge.gradle'  // apiKey
    apiKey = project.apiKey
    project {
        id = "350123"
        releaseType = "beta"
        changelogType = "markdown"
        changelog = "Testing auto-upload from gradle"
        addGameVersion project.minecraft
        addGameVersion "Fabric"
        addGameVersion "Java 8"

        afterEvaluate {
            // Main jar as main artifact
            mainArtifact file("${project.buildDir}/libs/$archivesBaseName-${project.version}.jar")

            subprojects.each { sub ->
                // Add built modules
                addArtifact file("${project.buildDir}/libs/$sub.archivesBaseName-${project.version}.jar")
            }
            uploadTask.dependsOn(remapJar)
        }
    }
    options {
        forgeGradleIntegration = false
    }
}
$ gradle curseforge
> Configure project :essentials-api
:setting up loom dependencies
:setting up mappings (yarn 1.15.2+build.15)

> Configure project :

    =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    Building Essentials
    Version: 0.0.1
    Minecraft Version: 1.15.2
    Fabric-Loader Version: 0.8.2+build.194

    Using:
    Fabric-API Version: 0.5.1+build.294-1.15
    PlayerAbilityLib Version: 1.1.0
    
    Output files will be in /build/libs
    =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

Fabric Loom: 0.4.3 Build(jenkins #3)
Fabric Loom: 0.4.3 Build(jenkins #3)
Fabric Loom: 0.4.3 Build(jenkins #3)
Fabric Loom: 0.4.3 Build(jenkins #3)
Fabric Loom: 0.4.3 Build(jenkins #3)
Fabric Loom: 0.4.3 Build(jenkins #3)
Fabric Loom: 0.4.3 Build(jenkins #3)
Fabric Loom: 0.4.3 Build(jenkins #3)
Fabric Loom: 0.4.3 Build(jenkins #3)
:setting up loom dependencies
:setting up mappings (yarn 1.15.2+build.15)
:remapping essentials-api-0.0.1+1.15.2.jar (TinyRemapper, intermediary -> named)

> Configure project :essentials-base
:setting up loom dependencies
:setting up mappings (yarn 1.15.2+build.15)

> Configure project :essentials-module-chat
:setting up loom dependencies
:setting up mappings (yarn 1.15.2+build.15)

> Configure project :essentials-module-currency
:setting up loom dependencies
:setting up mappings (yarn 1.15.2+build.15)

> Configure project :essentials-module-dynmap
:setting up loom dependencies
:setting up mappings (yarn 1.15.2+build.15)

> Configure project :essentials-module-market
:setting up loom dependencies
:setting up mappings (yarn 1.15.2+build.15)

> Configure project :essentials-module-teleport
:setting up loom dependencies
:setting up mappings (yarn 1.15.2+build.15)

> Configure project :essentials-module-utilities
:setting up loom dependencies
:setting up mappings (yarn 1.15.2+build.15)

> Task :essentials-api:compileKotlin
w: /home/mart/git/Essentials/essentials-api/src/main/kotlin/io/github/nyliummc/essentials/api/builders/ChestGui.kt: (39, 28): 'build(): Container' is deprecated. Used internally, do not use.
w: /home/mart/git/Essentials/essentials-api/src/main/kotlin/io/github/nyliummc/essentials/api/builders/ChestGui.kt: (48, 25): 'build(): Container' is deprecated. Used internally, do not use.
w: /home/mart/git/Essentials/essentials-api/src/main/kotlin/io/github/nyliummc/essentials/api/builders/Command.kt: (41, 21): 'setDispatcher(CommandDispatcher<ServerCommandSource>): Unit' is deprecated. Used internally, do not use.
w: /home/mart/git/Essentials/essentials-api/src/main/kotlin/io/github/nyliummc/essentials/api/builders/TeleportRequest.kt: (48, 28): 'build(): TeleportRequest' is deprecated. Used internally, do not use.
w: /home/mart/git/Essentials/essentials-api/src/main/kotlin/io/github/nyliummc/essentials/api/builders/Text.kt: (40, 28): 'build(): Text' is deprecated. Used internally, do not use.

> Task :essentials-api:compileJava
:setting java compiler args
Could not find refmap definition, will be using default name: essentials-api-refmap.json
Note: SpongePowered MIXIN Annotation Processor Version=0.8
Note: ObfuscationServiceFabric supports type: "official:intermediary"
Note: ObfuscationServiceFabric supports type: "official:named"
Note: ObfuscationServiceFabric supports type: "intermediary:official"
Note: ObfuscationServiceFabric supports type: "intermediary:named"
Note: ObfuscationServiceFabric supports type: "named:official"
Note: ObfuscationServiceFabric supports type: "named:intermediary"
Note: ObfuscationServiceMCP supports type: "searge"
Note: ObfuscationServiceMCP supports type: "notch"

> Task :essentials-api:processResources
> Task :essentials-api:classes
> Task :essentials-api:shadowJar SKIPPED
> Task :essentials-api:inspectClassesForKotlinIC UP-TO-DATE
> Task :essentials-api:jar

> Task :essentials-base:compileKotlin
w: /home/mart/git/Essentials/essentials-base/src/main/kotlin/io/github/nyliummc/essentials/entities/EssentialsRegistry.kt: (109, 38): Unchecked cast: Any! to T
w: /home/mart/git/Essentials/essentials-base/src/main/kotlin/io/github/nyliummc/essentials/entities/EssentialsRegistry.kt: (113, 43): Unchecked cast: Any! to T
w: /home/mart/git/Essentials/essentials-base/src/main/kotlin/io/github/nyliummc/essentials/entities/builders/Command.kt: (45, 17): Variable 'aliases' is never used
w: /home/mart/git/Essentials/essentials-base/src/main/kotlin/io/github/nyliummc/essentials/entities/builders/Command.kt: (50, 21): Variable 'baseNode' is never used
w: /home/mart/git/Essentials/essentials-base/src/main/kotlin/io/github/nyliummc/essentials/mod/AbstractEssentialsMod.kt: (78, 66): Parameter 'server' is never used, could be renamed to _
w: /home/mart/git/Essentials/essentials-base/src/main/kotlin/io/github/nyliummc/essentials/mod/AbstractEssentialsMod.kt: (87, 64): Parameter 'server' is never used, could be renamed to _

> Task :essentials-base:compileJava NO-SOURCE
> Task :essentials-base:processResources
> Task :essentials-base:classes
> Task :essentials-base:shadowJar UP-TO-DATE
> Task :essentials-module-chat:compileKotlin

> Task :essentials-module-chat:compileJava
:setting java compiler args
Could not find refmap definition, will be using default name: essentials-module-chat-refmap.json
Note: SpongePowered MIXIN Annotation Processor Version=0.8
Note: ObfuscationServiceFabric supports type: "official:intermediary"
Note: ObfuscationServiceFabric supports type: "official:named"
Note: ObfuscationServiceFabric supports type: "intermediary:official"
Note: ObfuscationServiceFabric supports type: "intermediary:named"
Note: ObfuscationServiceFabric supports type: "named:official"
Note: ObfuscationServiceFabric supports type: "named:intermediary"
Note: ObfuscationServiceMCP supports type: "searge"
Note: ObfuscationServiceMCP supports type: "notch"
Note: Loading named:intermediary mappings from /home/mart/.gradle/caches/fabric-loom/mappings/yarn-1.15.2+build.15-v2.tiny
Note: Writing refmap to /home/mart/git/Essentials/build/classes/java/main/essentials-module-chat-refmap.json
Note: Writing refmap to /home/mart/git/Essentials/build/classes/java/main/essentials-module-chat-refmap.json
Note: Writing named:intermediary output TinyMappings to /home/mart/git/Essentials/build/loom-cache/mixin-map-1.15.2-1.15.2+build.15-v2.tiny
Note: Writing refmap to /home/mart/git/Essentials/build/classes/java/main/essentials-module-chat-refmap.json
Note: Writing refmap to /home/mart/git/Essentials/build/classes/java/main/essentials-module-chat-refmap.json
Note: Writing named:intermediary output TinyMappings to /home/mart/git/Essentials/build/loom-cache/mixin-map-1.15.2-1.15.2+build.15-v2.tiny

> Task :essentials-module-chat:processResources
> Task :essentials-module-chat:classes
> Task :essentials-module-chat:shadowJar UP-TO-DATE

> Task :essentials-module-currency:compileKotlin
w: /home/mart/git/Essentials/essentials-module-currency/src/main/kotlin/io/github/nyliummc/essentials/modelhandlers/BalanceHandler.kt: (62, 17): Variable 'userObj' is never used

> Task :essentials-module-currency:compileJava NO-SOURCE
> Task :essentials-module-currency:processResources
> Task :essentials-module-currency:classes
> Task :essentials-module-currency:shadowJar UP-TO-DATE

> Task :essentials-module-dynmap:compileKotlin
w: /home/mart/git/Essentials/essentials-module-dynmap/src/main/kotlin/io/github/nyliummc/essentials/EssentialsDynmapModule.kt: (87, 28): Parameter 'minecraftServer' is never used
w: /home/mart/git/Essentials/essentials-module-dynmap/src/main/kotlin/io/github/nyliummc/essentials/entities/FabricDynmapMapChunkCache.kt: (74, 13): Name shadowed: maxToLoad
w: /home/mart/git/Essentials/essentials-module-dynmap/src/main/kotlin/io/github/nyliummc/essentials/entities/FabricDynmapMapChunkCache.kt: (221, 17): Variable 'poso' is never used

> Task :essentials-module-dynmap:compileJava
:setting java compiler args
Could not find refmap definition, will be using default name: essentials-module-dynmap-refmap.json
Note: SpongePowered MIXIN Annotation Processor Version=0.8
Note: ObfuscationServiceFabric supports type: "official:intermediary"
Note: ObfuscationServiceFabric supports type: "official:named"
Note: ObfuscationServiceFabric supports type: "intermediary:official"
Note: ObfuscationServiceFabric supports type: "intermediary:named"
Note: ObfuscationServiceFabric supports type: "named:official"
Note: ObfuscationServiceFabric supports type: "named:intermediary"
Note: ObfuscationServiceMCP supports type: "searge"
Note: ObfuscationServiceMCP supports type: "notch"
Note: Writing refmap to /home/mart/git/Essentials/build/classes/java/main/essentials-module-dynmap-refmap.json
Note: Writing refmap to /home/mart/git/Essentials/build/classes/java/main/essentials-module-dynmap-refmap.json
Note: Writing named:intermediary output TinyMappings to /home/mart/git/Essentials/build/loom-cache/mixin-map-1.15.2-1.15.2+build.15-v2.tiny
Note: Writing refmap to /home/mart/git/Essentials/build/classes/java/main/essentials-module-dynmap-refmap.json
Note: Writing refmap to /home/mart/git/Essentials/build/classes/java/main/essentials-module-dynmap-refmap.json
Note: Writing named:intermediary output TinyMappings to /home/mart/git/Essentials/build/loom-cache/mixin-map-1.15.2-1.15.2+build.15-v2.tiny

> Task :essentials-module-dynmap:processResources
> Task :essentials-module-dynmap:classes
> Task :essentials-module-dynmap:shadowJar UP-TO-DATE
> Task :essentials-module-market:compileKotlin
> Task :essentials-module-market:compileJava NO-SOURCE
> Task :essentials-module-market:processResources
> Task :essentials-module-market:classes
> Task :essentials-module-market:shadowJar UP-TO-DATE

> Task :essentials-module-teleport:compileKotlin
w: /home/mart/git/Essentials/essentials-module-teleport/src/main/kotlin/io/github/nyliummc/essentials/EssentialsTeleportModule.kt: (52, 80): Parameter 'request' is never used, could be renamed to _
w: /home/mart/git/Essentials/essentials-module-teleport/src/main/kotlin/io/github/nyliummc/essentials/commands/WarpCommand.kt: (162, 22): Parameter 'context' is never used

> Task :essentials-module-teleport:compileJava NO-SOURCE
> Task :essentials-module-teleport:processResources
> Task :essentials-module-teleport:classes
> Task :essentials-module-teleport:shadowJar UP-TO-DATE
> Task :essentials-module-utilities:compileKotlin

> Task :essentials-module-utilities:compileJava
:setting java compiler args
Could not find refmap definition, will be using default name: essentials-module-utilities-refmap.json
Note: SpongePowered MIXIN Annotation Processor Version=0.8
Note: ObfuscationServiceFabric supports type: "official:intermediary"
Note: ObfuscationServiceFabric supports type: "official:named"
Note: ObfuscationServiceFabric supports type: "intermediary:official"
Note: ObfuscationServiceFabric supports type: "intermediary:named"
Note: ObfuscationServiceFabric supports type: "named:official"
Note: ObfuscationServiceFabric supports type: "named:intermediary"
Note: ObfuscationServiceMCP supports type: "searge"
Note: ObfuscationServiceMCP supports type: "notch"
Note: Loading named:intermediary mappings from /home/mart/.gradle/caches/fabric-loom/mappings/yarn-1.15.2+build.15-v2.tiny
Note: Writing refmap to /home/mart/git/Essentials/build/classes/java/main/essentials-module-utilities-refmap.json
Note: Writing refmap to /home/mart/git/Essentials/build/classes/java/main/essentials-module-utilities-refmap.json
Note: Writing named:intermediary output TinyMappings to /home/mart/git/Essentials/build/loom-cache/mixin-map-1.15.2-1.15.2+build.15-v2.tiny
Note: Writing refmap to /home/mart/git/Essentials/build/classes/java/main/essentials-module-utilities-refmap.json
Note: Writing refmap to /home/mart/git/Essentials/build/classes/java/main/essentials-module-utilities-refmap.json
Note: Writing named:intermediary output TinyMappings to /home/mart/git/Essentials/build/loom-cache/mixin-map-1.15.2-1.15.2+build.15-v2.tiny

> Task :essentials-module-utilities:processResources
> Task :essentials-module-utilities:classes
> Task :essentials-module-utilities:shadowJar UP-TO-DATE
> Task :compileKotlin NO-SOURCE
> Task :compileJava NO-SOURCE
> Task :processResources
> Task :classes
> Task :inspectClassesForKotlinIC UP-TO-DATE
> Task :jar SKIPPED
> Task :shadowJar UP-TO-DATE
> Task :sourcesJar UP-TO-DATE
> Task :essentials-api:sourcesJar UP-TO-DATE

> Task :essentials-api:remapJar
:remapping essentials-api-0.0.1+1.15.2-dev.jar

> Task :essentials-base:inspectClassesForKotlinIC UP-TO-DATE
> Task :essentials-base:jar SKIPPED
> Task :essentials-base:sourcesJar UP-TO-DATE
> Task :essentials-base:remapJar UP-TO-DATE
> Task :essentials-module-chat:inspectClassesForKotlinIC UP-TO-DATE
> Task :essentials-module-chat:jar SKIPPED
> Task :essentials-module-chat:sourcesJar UP-TO-DATE
> Task :essentials-module-chat:remapJar UP-TO-DATE
> Task :essentials-module-currency:inspectClassesForKotlinIC UP-TO-DATE
> Task :essentials-module-currency:jar SKIPPED
> Task :essentials-module-currency:sourcesJar UP-TO-DATE
> Task :essentials-module-currency:remapJar UP-TO-DATE
> Task :essentials-module-dynmap:inspectClassesForKotlinIC UP-TO-DATE
> Task :essentials-module-dynmap:jar SKIPPED
> Task :essentials-module-dynmap:sourcesJar UP-TO-DATE
> Task :essentials-module-dynmap:remapJar UP-TO-DATE
> Task :essentials-module-market:inspectClassesForKotlinIC UP-TO-DATE
> Task :essentials-module-market:jar SKIPPED
> Task :essentials-module-market:sourcesJar UP-TO-DATE
> Task :essentials-module-market:remapJar UP-TO-DATE
> Task :essentials-module-teleport:inspectClassesForKotlinIC UP-TO-DATE
> Task :essentials-module-teleport:jar SKIPPED
> Task :essentials-module-teleport:sourcesJar UP-TO-DATE
> Task :essentials-module-teleport:remapJar UP-TO-DATE
> Task :essentials-module-utilities:inspectClassesForKotlinIC UP-TO-DATE
> Task :essentials-module-utilities:jar SKIPPED
> Task :essentials-module-utilities:sourcesJar UP-TO-DATE
> Task :essentials-module-utilities:remapJar UP-TO-DATE
> Task :remapJar UP-TO-DATE
> Task :assemble UP-TO-DATE

> Task :curseforge350123 FAILED
Uploaded /home/mart/git/Essentials/build/libs/essentials-0.0.1+1.15.2.jar to CurseForge Project: 350123, with ID: 2952296

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':curseforge350123'.
> java.lang.NullPointerException (no error message)

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.3/userguide/command_line_interface.html#sec:command_line_warnings

BUILD FAILED in 26s
58 actionable tasks: 24 executed, 34 up-to-date

Only the main jar gets uploaded, the additional files do not.

use shadowJar / reobfShadowJar

i am shading in libraries and relocating them with shadowJar

i tried

mainArtifact(shadowJar) {
    displayName = "MatterLink $version"
}

and tasks.reobfShadowJar.mustRunAfter shadowJar
but it seems that task does not reobsfucate the jar properly
and the reobfShadowJar task does not return a file

Java 9 detection is too eager

Not sure what else to say. It marks my uploads as Java 9 compatible when I do not even have Java 9 on my system, nor is the source compatibility set that high. I believe the compareTo logic is backwards...

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.