This commit is contained in:
Dale Myers 2021-03-23 17:28:13 +00:00
Родитель 11f92cc0f3
Коммит 49553339c9
11 изменённых файлов: 1017 добавлений и 2 удалений

Просмотреть файл

@ -2,7 +2,7 @@
`xcodeproj` is a utility for interacting with Xcode's xcodeproj bundle format. `xcodeproj` is a utility for interacting with Xcode's xcodeproj bundle format.
It expects some level of understanding of the internals of the pbxproj format and, in the future, schemes, etc. Note that this tool only reads projects. It does not write out any changes. If you are looking for more advanced functionality like this, I recommend looking at the Ruby gem of the same name (which is unaffiliated in anyway). It expects some level of understanding of the internals of the pbxproj format and schemes. Note that this tool only reads projects. It does not write out any changes. If you are looking for more advanced functionality like this, I recommend looking at the Ruby gem of the same name (which is unaffiliated in anyway).
To learn more about the format, you can look at any of these locations: To learn more about the format, you can look at any of these locations:
@ -26,7 +26,7 @@ for target in project.targets:
print(target.name) print(target.name)
# Print from the root level, 2 levels deep (.project is a property on the root # Print from the root level, 2 levels deep (.project is a property on the root
# project as in the future more surfaces, such as schemes, will be exposed) # project as other properties such as .schemes are also available)
for item1 in project.project.main_group.children: for item1 in project.project.main_group.children:
print(item1) print(item1)
if not isinstance(item1, xcodeproj.PBXGroup): if not isinstance(item1, xcodeproj.PBXGroup):
@ -49,6 +49,9 @@ key = obj.object_key
Note: This library is "lazy". Many things aren't calculated until they are used. This time will be inconsequential on smaller projects, but on larger ones, it can save quite a bit of time due to not parsing the entire project on load. These properties are usually stored though so that subsequent accesses are instant. Note: This library is "lazy". Many things aren't calculated until they are used. This time will be inconsequential on smaller projects, but on larger ones, it can save quite a bit of time due to not parsing the entire project on load. These properties are usually stored though so that subsequent accesses are instant.
## Note on Scheme Support
There's no DTD for xcscheme files, so the implementation has been guessed. There will definitely be holes that still need to be patched in it though. Please open an issue if you find any, along with a sample xcscheme file.
## Contributing ## Contributing
This project welcomes contributions and suggestions. Most contributions require you to agree to a This project welcomes contributions and suggestions. Most contributions require you to agree to a

Просмотреть файл

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1240"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4E937CAB25891E8C00FFE74E"
BuildableName = "CalendarColors.framework"
BlueprintName = "CalendarColors"
ReferencedContainer = "container:app-ios.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES"
onlyGenerateCoverageForSpecifiedTargets = "YES">
<CodeCoverageTargets>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4E937CAB25891E8C00FFE74E"
BuildableName = "CalendarColors.framework"
BlueprintName = "CalendarColors"
ReferencedContainer = "container:app-ios.xcodeproj">
</BuildableReference>
</CodeCoverageTargets>
<Testables>
</Testables>
</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">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4E937CAB25891E8C00FFE74E"
BuildableName = "CalendarColors.framework"
BlueprintName = "CalendarColors"
ReferencedContainer = "container:app-ios.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

Просмотреть файл

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1240"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "56306FF323FC984E0086380C"
BuildableName = "CalendarMeetNow.framework"
BlueprintName = "CalendarMeetNow"
ReferencedContainer = "container:app-ios.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES"
onlyGenerateCoverageForSpecifiedTargets = "YES">
<CodeCoverageTargets>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "56306FF323FC984E0086380C"
BuildableName = "CalendarMeetNow.framework"
BlueprintName = "CalendarMeetNow"
ReferencedContainer = "container:app-ios.xcodeproj">
</BuildableReference>
</CodeCoverageTargets>
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "5622269E242D068A001FAE6D"
BuildableName = "CalendarMeetNowTests.xctest"
BlueprintName = "CalendarMeetNowTests"
ReferencedContainer = "container:app-ios.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</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">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "56306FF323FC984E0086380C"
BuildableName = "CalendarMeetNow.framework"
BlueprintName = "CalendarMeetNow"
ReferencedContainer = "container:app-ios.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

Просмотреть файл

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1240"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8275D1CA2497CEA0002476AF"
BuildableName = "libCalendarMeetingDateTimePicker.a"
BlueprintName = "CalendarMeetingDateTimePicker"
ReferencedContainer = "container:app-ios.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8275D1D52497CEBC002476AF"
BuildableName = "CalendarMeetingDateTimePickerTests.xctest"
BlueprintName = "CalendarMeetingDateTimePickerTests"
ReferencedContainer = "container:app-ios.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</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">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8275D1CA2497CEA0002476AF"
BuildableName = "libCalendarMeetingDateTimePicker.a"
BlueprintName = "CalendarMeetingDateTimePicker"
ReferencedContainer = "container:app-ios.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

Просмотреть файл

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1240"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8335C4CB240F07C4009D26E2"
BuildableName = "libCalendarMeetingInsights.a"
BlueprintName = "CalendarMeetingInsights"
ReferencedContainer = "container:app-ios.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES"
onlyGenerateCoverageForSpecifiedTargets = "YES">
<CodeCoverageTargets>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8335C4CB240F07C4009D26E2"
BuildableName = "libCalendarMeetingInsights.a"
BlueprintName = "CalendarMeetingInsights"
ReferencedContainer = "container:app-ios.xcodeproj">
</BuildableReference>
</CodeCoverageTargets>
<Testables>
</Testables>
</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">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "8335C4CB240F07C4009D26E2"
BuildableName = "libCalendarMeetingInsights.a"
BlueprintName = "CalendarMeetingInsights"
ReferencedContainer = "container:app-ios.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

Просмотреть файл

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1240"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "5BC71AC3246DE8560076BEC7"
BuildableName = "libCalendarUpNext.a"
BlueprintName = "CalendarUpNext"
ReferencedContainer = "container:app-ios.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "NO"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "5BEDD2C02485D8E70046698C"
BuildableName = "CalendarUpNextTests.xctest"
BlueprintName = "CalendarUpNextTests"
ReferencedContainer = "container:app-ios.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "5BEDD2C02485D8E70046698C"
BuildableName = "CalendarUpNextTests.xctest"
BlueprintName = "CalendarUpNextTests"
ReferencedContainer = "container:app-ios.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</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">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "5BC71AC3246DE8560076BEC7"
BuildableName = "libCalendarUpNext.a"
BlueprintName = "CalendarUpNext"
ReferencedContainer = "container:app-ios.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

Просмотреть файл

@ -0,0 +1,163 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1240"
wasCreatedForAppExtension = "YES"
version = "2.0">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4E9E69B924B678EE00586106"
BuildableName = "CalendarWidgetExt.appex"
BlueprintName = "CalendarWidgetExt"
ReferencedContainer = "container:app-ios.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "108C005117751FBB000738E6"
BuildableName = "Outlook-iOS.app"
BlueprintName = "Outlook-iOS-App"
ReferencedContainer = "container:app-ios.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<CodeCoverageTargets>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4E9E69B924B678EE00586106"
BuildableName = "CalendarWidgetExt.appex"
BlueprintName = "CalendarWidgetExt"
ReferencedContainer = "container:app-ios.xcodeproj">
</BuildableReference>
</CodeCoverageTargets>
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4E3630A6258AB14000344381"
BuildableName = "OLMColorsKitTests.xctest"
BlueprintName = "OLMColorsKitTests"
ReferencedContainer = "container:app-ios.xcodeproj">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "837FD5EF25D45A8000B6AF0F"
BuildableName = "PartnerSDKManagerTests.xctest"
BlueprintName = "PartnerSDKManagerTests"
ReferencedContainer = "container:app-ios.xcodeproj">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4E081AEC25D1D4B400BB35DB"
BuildableName = "MailDraftDataUICopyTests.xctest"
BlueprintName = "MailDraftDataUICopyTests"
ReferencedContainer = "container:app-ios.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = ""
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
launchStyle = "0"
askForAppToLaunch = "Yes"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES"
launchAutomaticallySubstyle = "2">
<RemoteRunnable
runnableDebuggingMode = "2"
BundleIdentifier = "com.apple.springboard">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4E9E69B924B678EE00586106"
BuildableName = "CalendarWidgetExt.appex"
BlueprintName = "CalendarWidgetExt"
ReferencedContainer = "container:app-ios.xcodeproj">
</BuildableReference>
</RemoteRunnable>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "108C005117751FBB000738E6"
BuildableName = "Outlook-iOS.app"
BlueprintName = "Outlook-iOS-App"
ReferencedContainer = "container:app-ios.xcodeproj">
</BuildableReference>
</MacroExpansion>
<EnvironmentVariables>
<EnvironmentVariable
key = "_XCWidgetKind"
value = "com.microsoft.office.outlook.calendar-widget-kit.up-next-agenda"
isEnabled = "YES">
</EnvironmentVariable>
<EnvironmentVariable
key = "_XCWidgetDefaultView"
value = "timeline"
isEnabled = "YES">
</EnvironmentVariable>
<EnvironmentVariable
key = "_XCWidgetFamily"
value = "medium"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES"
launchAutomaticallySubstyle = "2">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "108C005117751FBB000738E6"
BuildableName = "Outlook-iOS.app"
BlueprintName = "Outlook-iOS-App"
ReferencedContainer = "container:app-ios.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

Просмотреть файл

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1240"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4EFF304824F3BEDF00DEEDE2"
BuildableName = "CalendarWidgetExtDataSourceKit.framework"
BlueprintName = "CalendarWidgetExtDataSourceKit"
ReferencedContainer = "container:app-ios.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES"
onlyGenerateCoverageForSpecifiedTargets = "YES">
<CodeCoverageTargets>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4EFF304824F3BEDF00DEEDE2"
BuildableName = "CalendarWidgetExtDataSourceKit.framework"
BlueprintName = "CalendarWidgetExtDataSourceKit"
ReferencedContainer = "container:app-ios.xcodeproj">
</BuildableReference>
</CodeCoverageTargets>
<Testables>
</Testables>
</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">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4EFF304824F3BEDF00DEEDE2"
BuildableName = "CalendarWidgetExtDataSourceKit.framework"
BlueprintName = "CalendarWidgetExtDataSourceKit"
ReferencedContainer = "container:app-ios.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

24
tests/test_schemes.py Normal file
Просмотреть файл

@ -0,0 +1,24 @@
"""Tests for the package."""
import os
import sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.abspath(__file__), "..", "..")))
import xcodeproj
# Fixtures work by redefining names, so we need to disable this
# pylint: disable=redefined-outer-name
COLLATERAL_PATH = os.path.join(
os.path.abspath(os.path.join(os.path.abspath(__file__), "..")), "collateral"
)
SCHEMES_PATH = os.path.join(COLLATERAL_PATH, "schemes")
def test_load_schemes() -> None:
"""Test that loading schemes works"""
for scheme_file in os.listdir(SCHEMES_PATH):
scheme_path = os.path.join(SCHEMES_PATH, scheme_file)
_ = xcodeproj.Scheme.from_file(scheme_path)

Просмотреть файл

@ -40,6 +40,7 @@ from .pathobjects import (
) )
from .pbxproject import PBXProject from .pbxproject import PBXProject
from .other import PBXTargetDependency, PBXContainerItemProxy from .other import PBXTargetDependency, PBXContainerItemProxy
from .schemes import Scheme
from .targets import PBXAggregateTarget, PBXNativeTarget, PBXProductType from .targets import PBXAggregateTarget, PBXNativeTarget, PBXProductType
from .xcobjects import XCBuildConfiguration, XCConfigurationList from .xcobjects import XCBuildConfiguration, XCConfigurationList
@ -85,6 +86,7 @@ class XcodeProject:
objects: Objects objects: Objects
project: PBXProject project: PBXProject
_cached_items: Dict[str, Dict[str, PBXObject]] _cached_items: Dict[str, Dict[str, PBXObject]]
_schemes: Optional[List[Scheme]]
def __init__(self, path: str) -> None: def __init__(self, path: str) -> None:
self.path = path self.path = path
@ -105,6 +107,7 @@ class XcodeProject:
self.project = self.objects[tree["rootObject"]] self.project = self.objects[tree["rootObject"]]
self._cached_items = {} self._cached_items = {}
self._schemes = None
self._set_weak_refs() self._set_weak_refs()
@ -239,3 +242,29 @@ class XcodeProject:
return native_target.build_configuration_list return native_target.build_configuration_list
return None return None
@property
def schemes(self) -> List[Scheme]:
"""Load the schemes for the project.
:returns: A list of schemes
"""
if self._schemes is not None:
return self._schemes
scheme_paths = []
for path, _, files in os.walk(self.path):
for file_path in files:
if not file_path.endswith(".xcscheme"):
continue
scheme_paths.append(os.path.join(path, file_path))
all_schemes: List[Scheme] = []
for scheme_path in scheme_paths:
all_schemes.append(Scheme.from_file(scheme_path))
self._schemes = all_schemes
return all_schemes

304
xcodeproj/schemes.py Executable file
Просмотреть файл

@ -0,0 +1,304 @@
"""Schemes"""
import xml.etree.ElementTree as ET
# pylint: disable=too-many-instance-attributes
class Action:
"""Base class for actions."""
def __init__(self, node) -> None:
self.command_line_arguments = []
self.environment_variables = []
self._understood_tags = {"CommandLineArguments", "EnvironmentVariables", "MacroExpansion"}
for child in node:
if child.tag == "CommandLineArguments":
for argument in child:
self.command_line_arguments.append(CommandLineArgument(argument))
elif child.tag == "EnvironmentVariables":
for variable in child:
self.environment_variables.append(EnvironmentVariable(variable))
elif child.tag == "MacroExpansion":
self.macro_expansion = MacroExpansion(child)
def _understands_tag(self, tag: str) -> bool:
return tag in self._understood_tags
class RunAction(Action):
"""Base class for runnable actions."""
def __init__(self, node) -> None:
super().__init__(node)
self._understood_tags.add("RemoteRunnable")
for child in node:
if child.tag == "RemoteRunnable":
self.remote_runnable = RemoteRunnable(child)
class BuildableReference:
"""BuildableReference"""
def __init__(self, node) -> None:
self.buildable_identifier = node.attrib.get("BuildableIdentifier")
self.blueprint_identifier = node.attrib.get("BlueprintIdentifier")
self.buildable_name = node.attrib.get("BuildableName")
self.blueprint_name = node.attrib.get("BlueprintName")
self.referenced_container = node.attrib.get("ReferencedContainer")
class BuildActionEntry:
"""BuildActionEntry"""
def __init__(self, node) -> None:
self.build_for_testing = node.attrib.get("buildForTesting") == "YES"
self.build_for_running = node.attrib.get("buildForRunning") == "YES"
self.build_for_profiling = node.attrib.get("buildForProfiling") == "YES"
self.build_for_archiving = node.attrib.get("buildForArchiving") == "YES"
self.build_for_analyzing = node.attrib.get("buildForAnalyzing") == "YES"
self.buildable_references = []
for child in node:
self.buildable_references.append(BuildableReference(child))
class MacroExpansion:
"""MacroExpansion"""
def __init__(self, node) -> None:
self.buildable_references = []
for child in node:
self.buildable_references.append(BuildableReference(child))
class CodeCoverageTargets:
"""CodeCoverageTargets"""
def __init__(self, node) -> None:
self.buildable_references = []
for child in node:
self.buildable_references.append(BuildableReference(child))
class TestableReference:
"""TestableReference"""
def __init__(self, node) -> None:
self.skipped = node.attrib.get("skipped") == "YES"
self.test_execution_ordering = node.attrib.get("testExecutionOrdering")
self.buildable_references = []
for child in node:
self.buildable_references.append(BuildableReference(child))
class TestPlanReference:
"""TestPlanReference"""
def __init__(self, node) -> None:
assert node.tag == "TestPlanReference"
self.reference = node.attrib.get("reference")
self.default = node.attrib.get("default") == "YES"
class RemoteRunnable:
"""RemoteRunnable"""
def __init__(self, node) -> None:
self.runnable_debugging_mode = node.attrib.get("runnableDebuggingMode")
self.bundle_identifier = node.attrib.get("BundleIdentifier")
self.buildable_references = []
for child in node:
self.buildable_references.append(BuildableReference(child))
class EnvironmentVariable:
"""EnvironmentVariable"""
def __init__(self, node) -> None:
self.key = node.attrib.get("key")
self.value = node.attrib.get("value")
self.is_enabled = node.attrib.get("isEnabled") == "YES"
class BuildableProductRunnable:
"""BuildableProductRunnable"""
def __init__(self, node) -> None:
assert node.tag == "BuildableProductRunnable"
self.runnable_debugging_mode = node.attrib.get("runnableDebuggingMode")
self.buildable_references = []
for child in node:
self.buildable_references.append(BuildableReference(child))
class CommandLineArgument:
"""CommandLineArgument"""
def __init__(self, node) -> None:
assert node.tag == "CommandLineArgument"
self.argument = node.attrib.get("argument")
self.is_enabled = node.attrib.get("isEnabled") == "YES"
class BuildAction(Action):
"""BuildAction"""
def __init__(self, node) -> None:
assert node.tag == "BuildAction"
super().__init__(node)
self.parallelize_buildables = node.attrib.get("parallelizeBuildables") == "YES"
self.build_implicit_dependencies = node.attrib.get("buildImplicitDependencies") == "YES"
self.build_action_entries = []
for child in node:
if child.tag == "BuildActionEntries":
for entry in child:
assert entry.tag == "BuildActionEntry"
self.build_action_entries.append(BuildActionEntry(entry))
else:
assert self._understands_tag(child.tag)
class TestAction(Action):
"""TestAction"""
def __init__(self, node) -> None:
assert node.tag == "TestAction"
super().__init__(node)
self.build_configuration = node.attrib.get("buildConfiguration")
self.selected_debugger_identifier = node.attrib.get("selectedDebuggerIdentifier")
self.selected_launcher_identifier = node.attrib.get("selectedLauncherIdentifier")
self.should_use_launch_scheme_args_env = (
node.attrib.get("shouldUseLaunchSchemeArgsEnv") == "YES"
)
self.code_coverage_enabled = node.attrib.get("codeCoverageEnabled") == "YES"
self.only_generate_coverage_for_specific_targets = (
node.attrib.get("onlyGenerateCoverageForSpecifiedTargets") == "YES"
)
self.test_plans = []
for child in node:
if child.tag == "CodeCoverageTargets":
self.code_coverage_targets = CodeCoverageTargets(child)
elif child.tag == "Testables":
self.testables = []
for testable in child:
self.testables.append(TestableReference(testable))
elif child.tag == "TestPlans":
for plan in child:
self.test_plans.append(TestPlanReference(plan))
else:
assert self._understands_tag(child.tag)
class LaunchAction(RunAction):
"""LaunchAction"""
def __init__(self, node) -> None:
assert node.tag == "LaunchAction"
super().__init__(node)
self.build_configuration = node.attrib.get("buildConfiguration")
self.selected_debugger_identifier = node.attrib.get("selectedDebuggerIdentifier")
self.selected_launcher_identifier = node.attrib.get("selectedLauncherIdentifier")
self.launch_style = node.attrib.get("launchStyle")
self.use_custom_working_directory = node.attrib.get("useCustomWorkingDirectory") == "YES"
self.ignores_persistent_state_on_launch = (
node.attrib.get("ignoresPersistentStateOnLaunch") == "YES"
)
self.debug_document_versioning = node.attrib.get("debugDocumentVersioning") == "YES"
self.debug_service_extension = node.attrib.get("debugServiceExtension")
self.allow_location_simulation = node.attrib.get("allowLocationSimulation") == "YES"
self.ask_for_app_to_launch = node.attrib.get("askForAppToLaunch") == "YES"
self.launch_automatically_substyle = node.attrib.get("launchAutomaticallySubstyle") == "YES"
for child in node:
if child.tag == "BuildableProductRunnable":
self.buildable_product_runnable = BuildableProductRunnable(child)
else:
assert self._understands_tag(child.tag)
class ProfileAction(RunAction):
"""ProfileAction"""
def __init__(self, node) -> None:
assert node.tag == "ProfileAction"
super().__init__(node)
self.build_configuration = node.attrib.get("buildConfiguration")
self.should_use_launch_scheme_args_env = (
node.attrib.get("shouldUseLaunchSchemeArgsEnv") == "YES"
)
self.saved_tool_identifier = node.attrib.get("savedToolIdentifier")
self.use_custom_working_directory = node.attrib.get("useCustomWorkingDirectory") == "YES"
self.debug_document_versioning = node.attrib.get("debugDocumentVersioning") == "YES"
for child in node:
if child.tag == "BuildableProductRunnable":
self.buildable_product_runnable = BuildableProductRunnable(child)
else:
assert self._understands_tag(child.tag)
class AnalyzeAction(Action):
"""AnalyzeAction"""
def __init__(self, node) -> None:
assert node.tag == "AnalyzeAction"
super().__init__(node)
self.build_configuration = node.attrib.get("buildConfiguration")
class ArchiveAction(Action):
"""ArchiveAction"""
def __init__(self, node) -> None:
assert node.tag == "ArchiveAction"
super().__init__(node)
self.build_configuration = node.attrib.get("buildConfiguration")
self.reveal_archive_in_organizer = node.attrib.get("revealArchiveInOrganizer") == "YES"
class Scheme:
"""Represents an Xcode scheme."""
def __init__(self, node) -> None:
assert node.tag == "Scheme"
self.last_upgrade_version = node.attrib.get("LastUpgradeVersion")
self.version = node.attrib.get("version")
self.was_created_for_app_extension = node.attrib.get("wasCreatedForAppExtension") == "YES"
for child in node:
if child.tag == "BuildAction":
self.build_action = BuildAction(child)
elif child.tag == "TestAction":
self.test_action = TestAction(child)
elif child.tag == "LaunchAction":
self.launch_action = LaunchAction(child)
elif child.tag == "ProfileAction":
self.profile_action = ProfileAction(child)
elif child.tag == "AnalyzeAction":
self.analyze_action = AnalyzeAction(child)
elif child.tag == "ArchiveAction":
self.archive_action = ArchiveAction(child)
else:
assert False
@staticmethod
def from_file(path: str) -> "Scheme":
"""Load a scheme from a file.
:param path: The path of the scheme file
:returns: A loaded scheme
"""
tree = ET.parse(path)
root = tree.getroot()
return Scheme(root)