Skip to content

Commit 9f78884

Browse files
committed
Schema Tests
1 parent 879647c commit 9f78884

File tree

5 files changed

+318
-30
lines changed

5 files changed

+318
-30
lines changed

app/build.gradle.kts

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform
22
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
3+
import org.jetbrains.compose.desktop.application.tasks.AbstractJPackageTask
34
import org.jetbrains.compose.internal.de.undercouch.gradle.tasks.download.Download
45

56
plugins{
@@ -30,6 +31,11 @@ sourceSets{
3031
srcDirs("src")
3132
}
3233
}
34+
test{
35+
kotlin{
36+
srcDirs("test")
37+
}
38+
}
3339
}
3440

3541
compose.desktop {
@@ -99,12 +105,177 @@ dependencies {
99105

100106
implementation(libs.compottie)
101107
implementation(libs.kaml)
108+
109+
testImplementation(kotlin("test"))
110+
testImplementation(libs.mockitoKotlin)
111+
testImplementation(libs.junitJupiter)
112+
testImplementation(libs.junitJupiterParams)
102113
}
103114

104115
tasks.compileJava{
105116
options.encoding = "UTF-8"
106117
}
107118

119+
tasks.test {
120+
useJUnitPlatform()
121+
workingDir = file("build/test")
122+
workingDir.mkdirs()
123+
}
124+
125+
tasks.register<Exec>("installCreateDmg") {
126+
onlyIf { org.gradle.internal.os.OperatingSystem.current().isMacOsX }
127+
commandLine("arch", "-arm64", "brew", "install", "--quiet", "create-dmg")
128+
}
129+
tasks.register<Exec>("packageCustomDmg"){
130+
onlyIf { org.gradle.internal.os.OperatingSystem.current().isMacOsX }
131+
group = "compose desktop"
132+
133+
val distributable = tasks.named<AbstractJPackageTask>("createDistributable").get()
134+
dependsOn(distributable, "installCreateDmg")
135+
136+
val packageName = distributable.packageName.get()
137+
val dir = distributable.destinationDir.get()
138+
val dmg = dir.file("../dmg/$packageName-$version.dmg").asFile
139+
val app = dir.file("$packageName.app").asFile
140+
141+
dmg.parentFile.deleteRecursively()
142+
dmg.parentFile.mkdirs()
143+
144+
val extra = mutableListOf<String>()
145+
val isSigned = compose.desktop.application.nativeDistributions.macOS.signing.sign.get()
146+
147+
if(!isSigned) {
148+
val content = """
149+
run 'xattr -d com.apple.quarantine Processing-${version}.dmg' to remove the quarantine flag
150+
""".trimIndent()
151+
val instructions = dmg.parentFile.resolve("INSTRUCTIONS.txt")
152+
instructions.writeText(content)
153+
extra.add("--add-file")
154+
extra.add("INSTRUCTIONS.txt")
155+
extra.add(instructions.path)
156+
extra.add("200")
157+
extra.add("25")
158+
}
159+
160+
commandLine("brew", "install", "--quiet", "create-dmg")
161+
162+
commandLine("create-dmg",
163+
"--volname", packageName,
164+
"--volicon", file("macos/volume.icns"),
165+
"--background", file("macos/background.png"),
166+
"--icon", "$packageName.app", "200", "200",
167+
"--window-pos", "200", "200",
168+
"--window-size", "775", "485",
169+
"--app-drop-link", "500", "200",
170+
"--hide-extension", "$packageName.app",
171+
*extra.toTypedArray(),
172+
dmg,
173+
app
174+
)
175+
}
176+
177+
tasks.register<Exec>("packageCustomMsi"){
178+
onlyIf { org.gradle.internal.os.OperatingSystem.current().isWindows }
179+
dependsOn("createDistributable")
180+
workingDir = file("windows")
181+
group = "compose desktop"
182+
183+
commandLine(
184+
"dotnet",
185+
"build",
186+
"/p:Platform=x64",
187+
"/p:Version=$version",
188+
"/p:DefineConstants=\"Version=$version;\""
189+
)
190+
}
191+
192+
tasks.register("generateSnapConfiguration"){
193+
onlyIf { org.gradle.internal.os.OperatingSystem.current().isLinux }
194+
val distributable = tasks.named<AbstractJPackageTask>("createDistributable").get()
195+
dependsOn(distributable)
196+
197+
val arch = when (System.getProperty("os.arch")) {
198+
"amd64", "x86_64" -> "amd64"
199+
"aarch64" -> "arm64"
200+
else -> System.getProperty("os.arch")
201+
}
202+
203+
val dir = distributable.destinationDir.get()
204+
val content = """
205+
name: ${rootProject.name}
206+
version: ${rootProject.version}
207+
base: core22
208+
summary: A creative coding editor
209+
description: |
210+
Processing is a flexible software sketchbook and a programming language designed for learning how to code.
211+
confinement: strict
212+
213+
apps:
214+
processing:
215+
command: opt/processing/bin/Processing
216+
desktop: opt/processing/lib/processing-Processing.desktop
217+
plugs:
218+
- desktop
219+
- desktop-legacy
220+
- wayland
221+
- x11
222+
223+
parts:
224+
processing:
225+
plugin: dump
226+
source: deb/processing_$version-1_$arch.deb
227+
source-type: deb
228+
stage-packages:
229+
- openjdk-17-jdk
230+
override-prime: |
231+
snapcraftctl prime
232+
chmod -R +x opt/processing/lib/app/resources/jdk-*
233+
""".trimIndent()
234+
dir.file("../snapcraft.yaml").asFile.writeText(content)
235+
}
236+
237+
tasks.register<Exec>("packageSnap"){
238+
onlyIf { org.gradle.internal.os.OperatingSystem.current().isLinux }
239+
dependsOn("packageDeb", "generateSnapConfiguration")
240+
group = "compose desktop"
241+
242+
val distributable = tasks.named<AbstractJPackageTask>("createDistributable").get()
243+
workingDir = distributable.destinationDir.dir("../").get().asFile
244+
245+
commandLine("snapcraft")
246+
}
247+
tasks.register<Zip>("zipDistributable"){
248+
dependsOn("createDistributable")
249+
group = "compose desktop"
250+
251+
val distributable = tasks.named<AbstractJPackageTask>("createDistributable").get()
252+
val dir = distributable.destinationDir.get()
253+
val packageName = distributable.packageName.get()
254+
255+
from(dir){ eachFile{ permissions{ unix("755") } } }
256+
archiveBaseName.set(packageName)
257+
destinationDirectory.set(dir.file("../").asFile)
258+
}
259+
260+
afterEvaluate{
261+
tasks.named("createDistributable").configure{
262+
finalizedBy("zipDistributable")
263+
}
264+
tasks.named("packageDmg").configure{
265+
dependsOn("packageCustomDmg")
266+
group = "compose desktop"
267+
actions = emptyList()
268+
}
269+
tasks.named("packageMsi").configure{
270+
dependsOn("packageCustomMsi")
271+
group = "compose desktop"
272+
actions = emptyList()
273+
}
274+
tasks.named("packageDistributionForCurrentOS").configure {
275+
dependsOn("packageSnap")
276+
}
277+
}
278+
108279

109280
// LEGACY TASKS
110281
// Most of these are shims to be compatible with the old build system

app/src/processing/app/Base.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1364,10 +1364,10 @@ private File moveLikeSketchFolder(File pdeFile, String baseName) throws IOExcept
13641364
* @param schemeUri the full URI, including pde://
13651365
*/
13661366
public Editor handleScheme(String schemeUri) {
1367-
// var result = Schema.handleSchema(schemeUri, this);
1368-
// if (result != null) {
1369-
// return result;
1370-
// }
1367+
var result = Schema.handleSchema(schemeUri, this);
1368+
if (result != null) {
1369+
return result;
1370+
}
13711371

13721372
String location = schemeUri.substring(6);
13731373
if (location.length() > 0) {

app/src/processing/app/Schema.kt

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,11 @@ class Schema {
5353
private fun handleSketchUrl(uri: URI): Editor?{
5454
val url = File(uri.path.replace("/url/", ""))
5555

56-
val tempSketchFolder = File(Base.untitledFolder, url.nameWithoutExtension)
56+
val rand = (1..6)
57+
.map { (('a'..'z') + ('A'..'Z')).random() }
58+
.joinToString("")
59+
60+
val tempSketchFolder = File(File(Base.untitledFolder, rand), url.nameWithoutExtension)
5761
tempSketchFolder.mkdirs()
5862
val tempSketchFile = File(tempSketchFolder, "${tempSketchFolder.name}.pde")
5963

@@ -81,15 +85,15 @@ class Schema {
8185
downloadFiles(uri, code, File(sketchFolder, "code"))
8286
}
8387
options["pde"]?.let{ pde ->
84-
downloadFiles(uri, pde, sketchFolder)
88+
downloadFiles(uri, pde, sketchFolder, "pde")
8589
}
8690
options["mode"]?.let{ mode ->
8791
val modeFile = File(sketchFolder, "sketch.properties")
8892
modeFile.writeText("mode.id=$mode")
8993
}
9094

9195
}
92-
private fun downloadFiles(uri: URI, urlList: String, targetFolder: File){
96+
private fun downloadFiles(uri: URI, urlList: String, targetFolder: File, extension: String = ""){
9397
Thread{
9498
targetFolder.mkdirs()
9599

@@ -101,37 +105,31 @@ class Schema {
101105
val files = urlList.split(",")
102106

103107
files.filter { it.isNotBlank() }
104-
.map{ it.split(":", limit = 2) }
105-
.map{ segments ->
106-
if(segments.size == 2){
107-
if(segments[0].isBlank()){
108-
return@map listOf(null, segments[1])
109-
}
110-
return@map segments
111-
}
112-
return@map listOf(null, segments[0])
108+
.map {
109+
if (it.contains(":")) it
110+
else "$it:$it"
113111
}
112+
.map{ it.split(":", limit = 2) }
114113
.forEach { (name, content) ->
114+
var target = File(targetFolder, name)
115+
if(extension.isNotBlank() && target.extension != extension){
116+
target = File(targetFolder, "$name.$extension")
117+
}
115118
try{
116-
// Try to decode the content as base64
117119
val file = Base64.getDecoder().decode(content)
118-
if(name == null){
120+
if(name.isBlank()){
119121
Messages.err("Base64 files needs to start with a file name followed by a colon")
120122
return@forEach
121123
}
122-
File(targetFolder, name).writeBytes(file)
124+
target.writeBytes(file)
123125
}catch(_: IllegalArgumentException){
124-
// Assume it's a URL and download it
125-
var url = URI.create(content)
126-
if(url.host == null){
127-
url = URI.create("https://$base/$content")
128-
}
129-
if(url.scheme == null){
130-
url = URI.create("https://$content")
131-
}
132-
133-
val target = File(targetFolder, name ?: url.path.split("/").last())
134-
url.toURL().openStream().use { input ->
126+
val url = URL(when{
127+
content.startsWith("https://") -> content
128+
content.startsWith("http://") -> content.replace("http://", "https://")
129+
URL("https://$content").path.isNotBlank() -> "https://$content"
130+
else -> "https://$base/$content"
131+
})
132+
url.openStream().use { input ->
135133
target.outputStream().use { output ->
136134
input.copyTo(output)
137135
}

0 commit comments

Comments
 (0)