From 9a983b6f6af06877f36bfed81a4d26c63da2f185 Mon Sep 17 00:00:00 2001 From: Michael Aigner Date: Wed, 31 Jan 2024 23:25:57 +0100 Subject: [PATCH 1/6] add swift support --- package.json | 11 +++++- src/cmds.ts | 2 ++ src/commands/swiftSupport.ts | 65 ++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 src/commands/swiftSupport.ts diff --git a/package.json b/package.json index b245c77..6cee468 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "raycast", "displayName": "Raycast", "description": "", - "version": "0.15.0", + "version": "0.16.0", "engines": { "vscode": "^1.67.0" }, @@ -128,6 +128,11 @@ "title": "Publish", "category": "Raycast" }, + { + "command": "raycast.addswiftsupport", + "title": "Add Swift Support", + "category": "Raycast" + }, { "command": "raycast.attachdebugger", "title": "Attach Debugger", @@ -233,6 +238,10 @@ "command": "raycast.publish", "when": "raycast.workspaceEnabled" }, + { + "command": "raycast.addswiftsupport", + "when": "raycast.workspaceEnabled" + }, { "command": "raycast.attachdebugger", "when": "raycast.workspaceEnabled" diff --git a/src/cmds.ts b/src/cmds.ts index e599695..c7cbdc1 100644 --- a/src/cmds.ts +++ b/src/cmds.ts @@ -24,6 +24,7 @@ import { addCommandArgumentCmd } from "./commands/addCommandArgument"; import { updateInternalState } from "./commands/updateInternalState"; import { gotoCommandDisabledByDefaultManifestLocationCmd } from "./commands/goto/disabledByDefault"; import { extensionIssuesCmd } from "./commands/extensionIssues"; +import { addSwiftSupportCmd } from "./commands/swiftSupport"; export function registerAllCommands(manager: ExtensionManager) { manager.registerCommand("lint", async () => lintCmd(manager)); @@ -61,4 +62,5 @@ export function registerAllCommands(manager: ExtensionManager) { gotoCommandArgumentManifestLocationCmd(manager, args), ); manager.registerCommand("command.arguments.add", async (...args: any[]) => addCommandArgumentCmd(manager, args)); + manager.registerCommand("addswiftsupport", async () => addSwiftSupportCmd(manager)); } diff --git a/src/commands/swiftSupport.ts b/src/commands/swiftSupport.ts new file mode 100644 index 0000000..9cdb43a --- /dev/null +++ b/src/commands/swiftSupport.ts @@ -0,0 +1,65 @@ +import * as afs from "fs/promises"; +import { ExtensionManager } from "../manager"; +import * as vscode from "vscode"; +import { fileExists } from "../utils"; +import path = require("path"); +import { readManifestFile } from "../manifest"; + +async function addSwiftSupport(manager: ExtensionManager, rootFolder: string) { + const manifest = await readManifestFile(manager.getActiveWorkspacePackageFilename()); + const packageName = manifest?.name; + if (!packageName) { + throw new Error("Could not get name from manifest"); + } + const gitignoreFilename = path.join(rootFolder, ".gitignore"); + const gitignore = [".DS_Store", ".build/", ".swiftpm/", ".vscode/", "Package.resolved"]; + const sourcesFolder = path.join(rootFolder, "Sources"); + await afs.mkdir(sourcesFolder, { recursive: true }); + await afs.writeFile(gitignoreFilename, gitignore.join("\n")); + const swiftPackageFilename = path.join(rootFolder, "Package.swift"); + const swiftPackage = `// swift-tools-version: 5.9 + +import PackageDescription + +let package = Package( + name: "${packageName}", + platforms: [.macOS(.v12)], + dependencies: [ + .package(url: "https://github.com/raycast/extensions-swift-tools.git", from: "1.0.1"), + ], + targets: [ + .executableTarget( + name: "${packageName}", + dependencies: [ + .product(name: "RaycastSwiftMacros", package: "extensions-swift-tools"), + .product(name: "RaycastSwiftPlugin", package: "extensions-swift-tools"), + .product(name: "RaycastTypeScriptPlugin", package: "extensions-swift-tools"), + ] + ), + ] +)`; + await afs.writeFile(swiftPackageFilename, swiftPackage); + + const source = `import Foundation +import RaycastSwiftMacros + +@raycast func hello() -> String { + "Hello from Swift" +} +`; + await afs.writeFile(path.join(sourcesFolder, `${packageName}.swift`), source); +} + +export async function addSwiftSupportCmd(manager: ExtensionManager) { + manager.logger.debug("Add Swift support"); + const ws = manager.getActiveWorkspace(); + if (!ws) { + throw new Error("No active workspace"); + } + const swiftRootFolder = path.join(ws.uri.fsPath, "swift"); + if (await fileExists(swiftRootFolder)) { + throw new Error("Swift folder already exists"); + } + await addSwiftSupport(manager, swiftRootFolder); + vscode.window.showInformationMessage("Swift Support added successfully"); +} From 53be57a7779d6845b1f171a08940d7c10fa10c32 Mon Sep 17 00:00:00 2001 From: Michael Aigner Date: Thu, 1 Feb 2024 00:10:06 +0100 Subject: [PATCH 2/6] add how to import --- src/commands/swiftSupport.ts | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/commands/swiftSupport.ts b/src/commands/swiftSupport.ts index 9cdb43a..274e435 100644 --- a/src/commands/swiftSupport.ts +++ b/src/commands/swiftSupport.ts @@ -1,7 +1,7 @@ import * as afs from "fs/promises"; import { ExtensionManager } from "../manager"; import * as vscode from "vscode"; -import { fileExists } from "../utils"; +import { fileExists, showTextDocumentAtPosition } from "../utils"; import path = require("path"); import { readManifestFile } from "../manifest"; @@ -47,7 +47,9 @@ import RaycastSwiftMacros "Hello from Swift" } `; - await afs.writeFile(path.join(sourcesFolder, `${packageName}.swift`), source); + const swiftCodeFilename = path.join(sourcesFolder, `${packageName}.swift`); + await afs.writeFile(swiftCodeFilename, source); + return swiftCodeFilename; } export async function addSwiftSupportCmd(manager: ExtensionManager) { @@ -60,6 +62,27 @@ export async function addSwiftSupportCmd(manager: ExtensionManager) { if (await fileExists(swiftRootFolder)) { throw new Error("Swift folder already exists"); } - await addSwiftSupport(manager, swiftRootFolder); - vscode.window.showInformationMessage("Swift Support added successfully"); + const swiftFilename = await addSwiftSupport(manager, swiftRootFolder); + showTextDocumentAtPosition(vscode.Uri.file(swiftFilename)); + vscode.window + .showInformationMessage("Swift Support added successfully", ...["How to Import", "More Info"]) + .then((selected) => { + if (selected === "How to Import") { + const lines = [ + "// How to Import", + 'import { hello } from "swift:../swift" // relative path to the swift directory from the workspace root', + "", + "async function exampleFunction() {", + "\tconsole.log(await hello());", + "}", + ]; + vscode.workspace + .openTextDocument({ language: "typescript", content: lines.join("\n").replaceAll("\t", " ") }) + .then((doc) => { + vscode.window.showTextDocument(doc, 1, false); + }); + } else if (selected === "More Info") { + vscode.env.openExternal(vscode.Uri.parse("https://github.com/raycast/extensions-swift-tools")); + } + }); } From 23c706c6384caf62b92e030ded8fec77d1c953a8 Mon Sep 17 00:00:00 2001 From: Michael Aigner Date: Thu, 1 Feb 2024 11:37:41 +0100 Subject: [PATCH 3/6] add comments --- CHANGELOG.md | 4 ++++ README.md | 1 + src/commands/swiftSupport.ts | 46 ++++++++++++++++++++---------------- 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c5e8e6..89adbaa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## 0.16 + +- Add `Add Swift Support` command + ## 0.15 - `Name` is now checked for non allowed characters for Command, Preference and Argument diff --git a/README.md b/README.md index 98cbf56..e924306 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ and more - ✅ Raycast Tree-view for easy navigation - ✅ Auto Completion for script directives - ✅ Open the Extension Issues Dashboard +- ✅ Add Swift support with one command ## Requirements diff --git a/src/commands/swiftSupport.ts b/src/commands/swiftSupport.ts index 274e435..92f972b 100644 --- a/src/commands/swiftSupport.ts +++ b/src/commands/swiftSupport.ts @@ -5,6 +5,8 @@ import { fileExists, showTextDocumentAtPosition } from "../utils"; import path = require("path"); import { readManifestFile } from "../manifest"; +const raycastSwiftUrl = "https://github.com/raycast/extensions-swift-tools"; + async function addSwiftSupport(manager: ExtensionManager, rootFolder: string) { const manifest = await readManifestFile(manager.getActiveWorkspacePackageFilename()); const packageName = manifest?.name; @@ -40,9 +42,27 @@ let package = Package( )`; await afs.writeFile(swiftPackageFilename, swiftPackage); + const comments = [ + "How to Import from TypeScript file", + 'import { hello } from "swift:../swift" // relative path to the swift directory from the workspace root', + "", + "async function exampleFunction() {", + " await hello();", + "}", + "", + "Write a global swift function and add @raycast before to make it available in TypeScript", + "", + "Warning: You shouldn't have a main.swift file in your project nor a structure marked with @main.", + " These are reserved for the Swift-to-TypeScript plugins.", + "", + `For more details goto the official repository ${raycastSwiftUrl}`, + ]; + const source = `import Foundation import RaycastSwiftMacros +${comments.map((c) => `// ${c}`).join("\n")} + @raycast func hello() -> String { "Hello from Swift" } @@ -64,25 +84,9 @@ export async function addSwiftSupportCmd(manager: ExtensionManager) { } const swiftFilename = await addSwiftSupport(manager, swiftRootFolder); showTextDocumentAtPosition(vscode.Uri.file(swiftFilename)); - vscode.window - .showInformationMessage("Swift Support added successfully", ...["How to Import", "More Info"]) - .then((selected) => { - if (selected === "How to Import") { - const lines = [ - "// How to Import", - 'import { hello } from "swift:../swift" // relative path to the swift directory from the workspace root', - "", - "async function exampleFunction() {", - "\tconsole.log(await hello());", - "}", - ]; - vscode.workspace - .openTextDocument({ language: "typescript", content: lines.join("\n").replaceAll("\t", " ") }) - .then((doc) => { - vscode.window.showTextDocument(doc, 1, false); - }); - } else if (selected === "More Info") { - vscode.env.openExternal(vscode.Uri.parse("https://github.com/raycast/extensions-swift-tools")); - } - }); + vscode.window.showInformationMessage("Swift Support added successfully", ...["More Info"]).then((selected) => { + if (selected === "More Info") { + vscode.env.openExternal(vscode.Uri.parse(raycastSwiftUrl)); + } + }); } From 667a7ff16ebf82c064e37839fb4268f179843235 Mon Sep 17 00:00:00 2001 From: Michael Aigner Date: Thu, 1 Feb 2024 12:01:48 +0100 Subject: [PATCH 4/6] add better comments --- package.json | 1 + src/commands/swiftSupport.ts | 46 +++++++++++++++++++++++++++++------- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 6cee468..f466397 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "onCommand:raycast.goto.command.interval", "onCommand:raycast.updateinternalstate", "onCommand:raycast.opencommand", + "onCommand:raycast.addswiftsupport", "onView:raycast", "workspaceContains:package.json" ], diff --git a/src/commands/swiftSupport.ts b/src/commands/swiftSupport.ts index 92f972b..d958dd0 100644 --- a/src/commands/swiftSupport.ts +++ b/src/commands/swiftSupport.ts @@ -7,6 +7,10 @@ import { readManifestFile } from "../manifest"; const raycastSwiftUrl = "https://github.com/raycast/extensions-swift-tools"; +function commentify(lines: string[]) { + return lines.map((c) => `//${c.length > 0 ? " " : ""}${c}`).join("\n"); +} + async function addSwiftSupport(manager: ExtensionManager, rootFolder: string) { const manifest = await readManifestFile(manager.getActiveWorkspacePackageFilename()); const packageName = manifest?.name; @@ -42,30 +46,56 @@ let package = Package( )`; await afs.writeFile(swiftPackageFilename, swiftPackage); - const comments = [ - "How to Import from TypeScript file", + const example = [ + "", + "# How to Import from TypeScript file", + "", + "Example TypeScript file src/mycommand.tsx :", + "", 'import { hello } from "swift:../swift" // relative path to the swift directory from the workspace root', "", "async function exampleFunction() {", " await hello();", "}", - "", - "Write a global swift function and add @raycast before to make it available in TypeScript", - "", + ]; + + const warning = [ "Warning: You shouldn't have a main.swift file in your project nor a structure marked with @main.", " These are reserved for the Swift-to-TypeScript plugins.", + ]; + + const generalInstructions = [ + "", + "# How to make a Swift function available in TypeScript", + "", + "Write global Swift functions and mark them with the @raycast attribute.", + "Global functions marked with @raycast are exported to TypeScript.", + "These functions can have any number of parameters, and one or no return type.", + "Exported functions can also be asynchronous (async) or throw errors (throws).", + "", + "The only restrictions are:", + "", + "- Parameters must conform to Decodable", + "- The return type (if any) must conform to Encodable (or be Void or ()).", + "- Variadic parameters and parameter packs are not supported.", + "- Only global functions will be exported. Methods or functions within structs, classes, or enums won't be exported.", "", - `For more details goto the official repository ${raycastSwiftUrl}`, + `For more details check out the official repository ${raycastSwiftUrl}`, ]; const source = `import Foundation import RaycastSwiftMacros -${comments.map((c) => `// ${c}`).join("\n")} - @raycast func hello() -> String { "Hello from Swift" } + +${commentify(example)} + +${commentify(warning)} + +${commentify(generalInstructions)} + `; const swiftCodeFilename = path.join(sourcesFolder, `${packageName}.swift`); await afs.writeFile(swiftCodeFilename, source); From 2a3ed9e066a407f2ce3184291521fb6e16433501 Mon Sep 17 00:00:00 2001 From: Michael Aigner Date: Thu, 1 Feb 2024 12:41:28 +0100 Subject: [PATCH 5/6] detect xcode --- package-lock.json | 133 +++++++++++++++++++++++++++++------ package.json | 4 +- src/commands/swiftSupport.ts | 36 +++++++++- 3 files changed, 146 insertions(+), 27 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6ae8838..8f6b8b1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,18 @@ { "name": "raycast", - "version": "0.15.0", + "version": "0.16.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "raycast", - "version": "0.15.0", + "version": "0.16.0", "license": "MIT", "dependencies": { "edit-json-file": "^1.7.0", "json-to-ast": "^2.1.0", - "node-fetch": "^3.3.2" + "node-fetch": "^3.3.2", + "which": "^4.0.0" }, "devDependencies": { "@types/edit-json-file": "^1.7.0", @@ -21,6 +22,7 @@ "@types/node": "14.x", "@types/semver": "^7.3.13", "@types/vscode": "^1.67.0", + "@types/which": "^3.0.3", "@typescript-eslint/eslint-plugin": "^5.21.0", "@typescript-eslint/parser": "^5.21.0", "@vscode/test-cli": "^0.0.4", @@ -398,6 +400,12 @@ "integrity": "sha512-GH8BDf8cw9AC9080uneJfulhSa7KHSMI2s/CyKePXoGNos9J486w2V4YKoeNUqIEkW4hKoEAWp6/cXTwyGj47g==", "dev": true }, + "node_modules/@types/which": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/which/-/which-3.0.3.tgz", + "integrity": "sha512-2C1+XoY0huExTbs8MQv1DuS5FS86+SEjdM9F/+GS61gg5Hqbtj8ZiDSx8MfWcyei907fIPbfPGCOrNUTnVHY1g==", + "dev": true + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "5.25.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.25.0.tgz", @@ -1467,6 +1475,27 @@ "node": ">= 8" } }, + "node_modules/cross-spawn/node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/data-uri-to-buffer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz", @@ -2487,10 +2516,12 @@ "dev": true }, "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "engines": { + "node": ">=16" + } }, "node_modules/isobject": { "version": "3.0.1", @@ -2872,6 +2903,12 @@ "node": "*" } }, + "node_modules/mocha/node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, "node_modules/mocha/node_modules/minimatch": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", @@ -2905,6 +2942,21 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/mocha/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -4098,18 +4150,17 @@ } }, "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", "dependencies": { - "isexe": "^2.0.0" + "isexe": "^3.1.1" }, "bin": { - "node-which": "bin/node-which" + "node-which": "bin/which.js" }, "engines": { - "node": ">= 8" + "node": "^16.13.0 || >=18.0.0" } }, "node_modules/wildcard": { @@ -4529,6 +4580,12 @@ "integrity": "sha512-GH8BDf8cw9AC9080uneJfulhSa7KHSMI2s/CyKePXoGNos9J486w2V4YKoeNUqIEkW4hKoEAWp6/cXTwyGj47g==", "dev": true }, + "@types/which": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/which/-/which-3.0.3.tgz", + "integrity": "sha512-2C1+XoY0huExTbs8MQv1DuS5FS86+SEjdM9F/+GS61gg5Hqbtj8ZiDSx8MfWcyei907fIPbfPGCOrNUTnVHY1g==", + "dev": true + }, "@typescript-eslint/eslint-plugin": { "version": "5.25.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.25.0.tgz", @@ -5317,6 +5374,23 @@ "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" + }, + "dependencies": { + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } } }, "data-uri-to-buffer": { @@ -6070,10 +6144,9 @@ "dev": true }, "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==" }, "isobject": { "version": "3.0.1", @@ -6362,6 +6435,12 @@ } } }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, "minimatch": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", @@ -6385,6 +6464,15 @@ "requires": { "has-flag": "^4.0.0" } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } } } }, @@ -7207,12 +7295,11 @@ "dev": true }, "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", "requires": { - "isexe": "^2.0.0" + "isexe": "^3.1.1" } }, "wildcard": { diff --git a/package.json b/package.json index f466397..b531c45 100644 --- a/package.json +++ b/package.json @@ -416,6 +416,7 @@ "@typescript-eslint/parser": "^5.21.0", "@vscode/test-cli": "^0.0.4", "@vscode/test-electron": "^2.3.9", + "@types/which": "^3.0.3", "eslint": "^8.14.0", "glob": "^8.0.1", "mocha": "^9.2.2", @@ -438,6 +439,7 @@ "dependencies": { "edit-json-file": "^1.7.0", "json-to-ast": "^2.1.0", - "node-fetch": "^3.3.2" + "node-fetch": "^3.3.2", + "which": "^4.0.0" } } diff --git a/src/commands/swiftSupport.ts b/src/commands/swiftSupport.ts index d958dd0..4e27e2f 100644 --- a/src/commands/swiftSupport.ts +++ b/src/commands/swiftSupport.ts @@ -4,9 +4,19 @@ import * as vscode from "vscode"; import { fileExists, showTextDocumentAtPosition } from "../utils"; import path = require("path"); import { readManifestFile } from "../manifest"; +import which = require("which"); const raycastSwiftUrl = "https://github.com/raycast/extensions-swift-tools"; +async function isXcodeInstalled() { + const resolved = await which("xcode-select", { nothrow: true }); + return resolved ? true : false; +} + +async function openXcodeInAppStore() { + await vscode.env.openExternal(vscode.Uri.parse("https://apps.apple.com/app/xcode/id497799835")); +} + function commentify(lines: string[]) { return lines.map((c) => `//${c.length > 0 ? " " : ""}${c}`).join("\n"); } @@ -52,10 +62,11 @@ let package = Package( "", "Example TypeScript file src/mycommand.tsx :", "", - 'import { hello } from "swift:../swift" // relative path to the swift directory from the workspace root', + 'import { hello, helloName } from "swift:../swift" // relative path to the swift directory from the workspace root', "", "async function exampleFunction() {", " await hello();", + ' await helloName("Michael");', "}", ]; @@ -90,6 +101,10 @@ import RaycastSwiftMacros "Hello from Swift" } +@raycast func helloName(name:String) -> String{ + "Hello \(name)" +} + ${commentify(example)} ${commentify(warning)} @@ -109,8 +124,8 @@ export async function addSwiftSupportCmd(manager: ExtensionManager) { throw new Error("No active workspace"); } const swiftRootFolder = path.join(ws.uri.fsPath, "swift"); - if (await fileExists(swiftRootFolder)) { - throw new Error("Swift folder already exists"); + if (await fileExists(path.join(swiftRootFolder, "Package.swift"))) { + throw new Error("Swift Support already exist"); } const swiftFilename = await addSwiftSupport(manager, swiftRootFolder); showTextDocumentAtPosition(vscode.Uri.file(swiftFilename)); @@ -119,4 +134,19 @@ export async function addSwiftSupportCmd(manager: ExtensionManager) { vscode.env.openExternal(vscode.Uri.parse(raycastSwiftUrl)); } }); + const xcodeInstalled = await isXcodeInstalled(); + if (!xcodeInstalled) { + vscode.window + .showWarningMessage( + "You need to install Xcode because it is required for Swift for Raycast", + ...["More Info", "AppStore"], + ) + .then((selected) => { + if (selected === "More Info") { + vscode.env.openExternal(vscode.Uri.parse(raycastSwiftUrl + "#requirements")); + } else if (selected === "AppStore") { + openXcodeInAppStore(); + } + }); + } } From ba5140c71ce0dc04cfefeb95727184e185e23087 Mon Sep 17 00:00:00 2001 From: Michael Aigner Date: Thu, 1 Feb 2024 12:53:31 +0100 Subject: [PATCH 6/6] add logger statements --- src/commands/swiftSupport.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/commands/swiftSupport.ts b/src/commands/swiftSupport.ts index 4e27e2f..84f580f 100644 --- a/src/commands/swiftSupport.ts +++ b/src/commands/swiftSupport.ts @@ -31,6 +31,7 @@ async function addSwiftSupport(manager: ExtensionManager, rootFolder: string) { const gitignore = [".DS_Store", ".build/", ".swiftpm/", ".vscode/", "Package.resolved"]; const sourcesFolder = path.join(rootFolder, "Sources"); await afs.mkdir(sourcesFolder, { recursive: true }); + manager.logger.debug(`Write ${gitignoreFilename}`); await afs.writeFile(gitignoreFilename, gitignore.join("\n")); const swiftPackageFilename = path.join(rootFolder, "Package.swift"); const swiftPackage = `// swift-tools-version: 5.9 @@ -54,6 +55,7 @@ let package = Package( ), ] )`; + manager.logger.debug(`Write ${swiftPackageFilename}`); await afs.writeFile(swiftPackageFilename, swiftPackage); const example = [ @@ -110,9 +112,9 @@ ${commentify(example)} ${commentify(warning)} ${commentify(generalInstructions)} - `; const swiftCodeFilename = path.join(sourcesFolder, `${packageName}.swift`); + manager.logger.debug(`Write ${swiftCodeFilename}`); await afs.writeFile(swiftCodeFilename, source); return swiftCodeFilename; } @@ -125,7 +127,7 @@ export async function addSwiftSupportCmd(manager: ExtensionManager) { } const swiftRootFolder = path.join(ws.uri.fsPath, "swift"); if (await fileExists(path.join(swiftRootFolder, "Package.swift"))) { - throw new Error("Swift Support already exist"); + throw new Error("Swift Support already exists"); } const swiftFilename = await addSwiftSupport(manager, swiftRootFolder); showTextDocumentAtPosition(vscode.Uri.file(swiftFilename));