Skip to content

Add mybuildtoolplugin #37

New issue

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

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

Already on GitHub? Sign in to your account

Open
wants to merge 28 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
06ba908
Create .DS_Store
Illidian4368 Jan 31, 2025
d259a18
Create MyBuildToolPlugin.swift
Illidian4368 Feb 1, 2025
ce3b621
Create .gitignore
Illidian4368 Feb 1, 2025
fc19317
Create Package.swift
Illidian4368 Feb 1, 2025
a065c35
Create Package.swift
Illidian4368 Feb 1, 2025
56a16b8
Create 2qw.xcscheme
Illidian4368 Feb 1, 2025
ee6173b
Create _qw.swift
Illidian4368 Feb 1, 2025
747a22e
Delete _qwApp.swift
Illidian4368 Feb 1, 2025
31c63eb
Merge branch 'master' of https://github.com/Illidian4368/studio
Illidian4368 Feb 1, 2025
bb50b97
Update xcschememanagement.plist
Illidian4368 Feb 1, 2025
27696f4
Delete Contents.json
Illidian4368 Feb 1, 2025
8186c54
Create _qwProtocol.swift
Illidian4368 Feb 1, 2025
10a48c7
* Add a section mentioning the new `MyBuildToolPlugin`
Illidian4368 Feb 1, 2025
c595924
Merge branch 'master' of https://github.com/Illidian4368/studio
Illidian4368 Feb 1, 2025
5646394
Update project.pbxproj
Illidian4368 Feb 1, 2025
cc5629e
Delete Contents.json
Illidian4368 Feb 1, 2025
6282461
Delete Contents.json
Illidian4368 Feb 1, 2025
0819120
Update UserInterfaceState.xcuserstate
Illidian4368 Feb 1, 2025
f389a5c
Create Info.plist
Illidian4368 Feb 1, 2025
7403d41
Update _qw.entitlements
Illidian4368 Feb 1, 2025
8f4adf7
Delete _qwTests.swift
Illidian4368 Feb 1, 2025
309d66d
Delete x.swift
Illidian4368 Feb 1, 2025
88c606f
Delete Contents.json
Illidian4368 Feb 1, 2025
064af12
Create main.swift
Illidian4368 Feb 1, 2025
85c33e2
Delete _qwUITests.swift
Illidian4368 Feb 1, 2025
9a435da
Delete Item.swift
Illidian4368 Feb 1, 2025
29f86d3
Delete _qwUITestsLaunchTests.swift
Illidian4368 Feb 1, 2025
e511679
Add MyBuildToolPlugin to the project
Illidian4368 Feb 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
413 changes: 413 additions & 0 deletions 2qw/2qw.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions 2qw/2qw.xcodeproj/project.xcworkspace/contents.xcworkspacedata

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.
113 changes: 113 additions & 0 deletions 2qw/2qw.xcodeproj/xcshareddata/xcschemes/2qw.xcscheme
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1620"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES"
buildArchitectures = "Automatic">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4D4C76A42D4E9104005E2F9B"
BuildableName = "2qw.xpc"
BlueprintName = "2qw"
ReferencedContainer = "container:2qw.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4D4C76A52D4E9104005E2F9B"
BuildableName = "MyBuildToolPlugin"
BlueprintName = "MyBuildToolPlugin"
ReferencedContainer = "container:2qw.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4D4C76A52D4E9104005E2F9B"
BuildableName = "MyBuildToolPlugin"
BlueprintName = "MyBuildToolPlugin"
ReferencedContainer = "container:2qw.xcodeproj">
</BuildableReference>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4D4C76A52D4E9104005E2F9B"
BuildableName = "MyBuildToolPlugin"
BlueprintName = "MyBuildToolPlugin"
ReferencedContainer = "container:2qw.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4D4C76A52D4E9104005E2F9B"
BuildableName = "MyBuildToolPlugin"
BlueprintName = "MyBuildToolPlugin"
ReferencedContainer = "container:2qw.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4D4C76A52D4E9104005E2F9B"
BuildableName = "MyBuildToolPlugin"
BlueprintName = "MyBuildToolPlugin"
ReferencedContainer = "container:2qw.xcodeproj">
</BuildableReference>
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4D4C76A52D4E9104005E2F9B"
BuildableName = "MyBuildToolPlugin"
BlueprintName = "MyBuildToolPlugin"
ReferencedContainer = "container:2qw.xcodeproj">
</BuildableReference>
</ArchiveAction>
</Scheme>
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>2qw.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
<key>MyBuildToolPlugin.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>1</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>4D4C76A42D4E9104005E2F9B</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>4D4C76A52D4E9104005E2F9B</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>
11 changes: 11 additions & 0 deletions 2qw/2qw/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>XPCService</key>
<dict>
<key>ServiceType</key>
<string>Application</string>
</dict>
</dict>
</plist>
8 changes: 8 additions & 0 deletions 2qw/2qw/_qw.entitlements
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
</dict>
</plist>
18 changes: 18 additions & 0 deletions 2qw/2qw/_qw.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// _qw.swift
// 2qw
//
// Created by PF on 01/02/2025.
//

import Foundation

/// This object implements the protocol which we have defined. It provides the actual behavior for the service. It is 'exported' by the service to make it available to the process hosting the service over an NSXPCConnection.
class _qw: NSObject, _qwProtocol {

/// This implements the example protocol. Replace the body of this class with the implementation of this service's protocol.
@objc func performCalculation(firstNumber: Int, secondNumber: Int, with reply: @escaping (Int) -> Void) {
let response = firstNumber + secondNumber
reply(response)
}
}
35 changes: 35 additions & 0 deletions 2qw/2qw/_qwProtocol.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// _qwProtocol.swift
// 2qw
//
// Created by PF on 01/02/2025.
//

import Foundation

/// The protocol that this service will vend as its API. This protocol will also need to be visible to the process hosting the service.
@objc protocol _qwProtocol {

/// Replace the API of this protocol with an API appropriate to the service you are vending.
func performCalculation(firstNumber: Int, secondNumber: Int, with reply: @escaping (Int) -> Void)
}

/*
To use the service from an application or other process, use NSXPCConnection to establish a connection to the service by doing something like this:

connectionToService = NSXPCConnection(serviceName: "p.-qw")
connectionToService.remoteObjectInterface = NSXPCInterface(with: _qwProtocol.self)
connectionToService.resume()

Once you have a connection to the service, you can use it like this:

if let proxy = connectionToService.remoteObjectProxy as? _qwProtocol {
proxy.performCalculation(firstNumber: 23, secondNumber: 19) { result in
NSLog("Result of calculation is: \(result)")
}
}

And, when you are finished with the service, clean up the connection like this:

connectionToService.invalidate()
*/
39 changes: 39 additions & 0 deletions 2qw/2qw/main.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// main.swift
// 2qw
//
// Created by PF on 01/02/2025.
//

import Foundation

class ServiceDelegate: NSObject, NSXPCListenerDelegate {

/// This method is where the NSXPCListener configures, accepts, and resumes a new incoming NSXPCConnection.
func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool {

// Configure the connection.
// First, set the interface that the exported object implements.
newConnection.exportedInterface = NSXPCInterface(with: _qwProtocol.self)

// Next, set the object that the connection exports. All messages sent on the connection to this service will be sent to the exported object to handle. The connection retains the exported object.
let exportedObject = _qw()
newConnection.exportedObject = exportedObject

// Resuming the connection allows the system to deliver more incoming messages.
newConnection.resume()

// Returning true from this method tells the system that you have accepted this connection. If you want to reject the connection for some reason, call invalidate() on the connection and return false.
return true
}
}

// Create the delegate for the service.
let delegate = ServiceDelegate()

// Set up the one NSXPCListener for this service. It will handle all incoming connections.
let listener = NSXPCListener.service()
listener.delegate = delegate

// Resuming the serviceListener starts this service. This method does not return.
listener.resume()
8 changes: 8 additions & 0 deletions MyBuildToolPlugin/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.DS_Store
/.build
/Packages
xcuserdata/
DerivedData/
.swiftpm/configuration/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc
22 changes: 22 additions & 0 deletions MyBuildToolPlugin/Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import PackageDescription

let package = Package(
name: "MyBuildToolPlugin",
products: [
// Products can be used to vend plugins, making them visible to other packages.
.plugin(
name: "MyBuildToolPlugin",
targets: ["MyBuildToolPlugin"]),
],
dependencies: [
.package(url: "https://github.com/apple/swift-tools-support-core.git", from: "0.1.0"),
],
targets: [
// Targets are the basic building blocks of a package, defining a module or a test suite.
// Targets can depend on other targets in this package and products from dependencies.
.plugin(
name: "MyBuildToolPlugin",
capability: .buildTool()
),
]
)
88 changes: 88 additions & 0 deletions MyBuildToolPlugin/Plugins/MyBuildToolPlugin.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import PackagePlugin

@main
struct MyBuildToolPlugin: BuildToolPlugin {
/// Entry point for creating build commands for targets in Swift packages.
func createBuildCommands(context: PluginContext, target: Target) async throws -> [Command] {
// This plugin only runs for package targets that can have source files.
guard let sourceFiles = target.sourceModule?.sourceFiles else { return [] }

// Find the code generator tool to run (replace this with the actual one).
let generatorTool = try context.tool(named: "my-code-generator")

// Construct a build command for each source file with a particular suffix.
return sourceFiles.map(\.path).compactMap {
createBuildCommand(for: $0, in: context.pluginWorkDirectory, with: generatorTool.path)
}
}

/// New function to create test commands for MyBuildToolPlugin
func createTestCommands(context: PluginContext, target: Target) async throws -> [Command] {
// This plugin only runs for package targets that can have source files.
guard let sourceFiles = target.sourceModule?.sourceFiles else { return [] }

// Find the test tool to run (replace this with the actual one).
let testTool = try context.tool(named: "my-test-tool")

// Construct a test command for each source file with a particular suffix.
return sourceFiles.map(\.path).compactMap {
createTestCommand(for: $0, in: context.pluginWorkDirectory, with: testTool.path)
}
}
}

#if canImport(XcodeProjectPlugin)
import XcodeProjectPlugin

extension MyBuildToolPlugin: XcodeBuildToolPlugin {
// Entry point for creating build commands for targets in Xcode projects.
func createBuildCommands(context: XcodePluginContext, target: XcodeTarget) throws -> [Command] {
// Find the code generator tool to run (replace this with the actual one).
let generatorTool = try context.tool(named: "my-code-generator")

// Construct a build command for each source file with a particular suffix.
return target.inputFiles.map(\.path).compactMap {
createBuildCommand(for: $0, in: context.pluginWorkDirectory, with: generatorTool.path)
}
}
}

#endif

extension MyBuildToolPlugin {
/// Shared function that returns a configured build command if the input files is one that should be processed.
func createBuildCommand(for inputPath: Path, in outputDirectoryPath: Path, with generatorToolPath: Path) -> Command? {
// Skip any file that doesn't have the extension we're looking for (replace this with the actual one).
guard inputPath.extension == "my-input-suffix" else { return .none }

// Return a command that will run during the build to generate the output file.
let inputName = inputPath.lastComponent
let outputName = inputPath.stem + ".swift"
let outputPath = outputDirectoryPath.appending(outputName)
return .buildCommand(
displayName: "Generating \(outputName) from \(inputName)",
executable: generatorToolPath,
arguments: ["\(inputPath)", "-o", "\(outputPath)"],
inputFiles: [inputPath],
outputFiles: [outputPath]
)
}

/// Shared function that returns a configured test command if the input files is one that should be processed.
func createTestCommand(for inputPath: Path, in outputDirectoryPath: Path, with testToolPath: Path) -> Command? {
// Skip any file that doesn't have the extension we're looking for (replace this with the actual one).
guard inputPath.extension == "my-input-suffix" else { return .none }

// Return a command that will run during the build to generate the output file.
let inputName = inputPath.lastComponent
let outputName = inputPath.stem + ".test"
let outputPath = outputDirectoryPath.appending(outputName)
return .buildCommand(
displayName: "Testing \(outputName) from \(inputName)",
executable: testToolPath,
arguments: ["\(inputPath)", "-o", "\(outputPath)"],
inputFiles: [inputPath],
outputFiles: [outputPath]
)
}
}
Loading