diff --git a/Docs/ProjectSpec.md b/Docs/ProjectSpec.md
index 326e17f3c..85d1ddf7d 100644
--- a/Docs/ProjectSpec.md
+++ b/Docs/ProjectSpec.md
@@ -35,6 +35,7 @@ You can also use environment variables in your configuration file, by using `${S
- [Legacy Target](#legacy-target)
- [Aggregate Target](#aggregate-target)
- [Target Template](#target-template)
+- [Global Template Attributes](#global-template-attributes)
- [Scheme](#scheme)
- [Build](#build)
- [Common Build Action options](#common-build-action-options)
@@ -973,6 +974,15 @@ targetTemplates:
- ${frameworkName}/${target_name}
```
+## Global template attributes
+
+This is place to define global variables used to resolve missing `${target_name}` within each template. This also helps share attributes between yaml files.
+
+```yaml
+globalTemplateAttributes:
+ version: legacy
+```
+
## Scheme
Schemes allows for more control than the convenience [Target Scheme](#target-scheme) on [Target](#target)
diff --git a/Sources/ProjectSpec/Template.swift b/Sources/ProjectSpec/Template.swift
index 71f16b1f2..8a0bf988a 100644
--- a/Sources/ProjectSpec/Template.swift
+++ b/Sources/ProjectSpec/Template.swift
@@ -66,6 +66,10 @@ private func resolveTemplates(jsonDictionary: JSONDictionary, templateStructure:
if let templateAttributes = reference["templateAttributes"] as? [String: String] {
reference = reference.expand(variables: templateAttributes)
}
+
+ if let globalVariables = jsonDictionary["globalTemplateAttributes"] as? [String: String] {
+ reference = reference.expand(variables: globalVariables)
+ }
}
baseDictionary[referenceName] = reference
}
diff --git a/Tests/Fixtures/TestProject/ContentBlocker/Configs/legacy/Debug.xcconfig b/Tests/Fixtures/TestProject/ContentBlocker/Configs/legacy/Debug.xcconfig
new file mode 100644
index 000000000..9a239976f
--- /dev/null
+++ b/Tests/Fixtures/TestProject/ContentBlocker/Configs/legacy/Debug.xcconfig
@@ -0,0 +1 @@
+API_PATH = https://dev.google.com
diff --git a/Tests/Fixtures/TestProject/ContentBlocker/Configs/legacy/Release.xcconfig b/Tests/Fixtures/TestProject/ContentBlocker/Configs/legacy/Release.xcconfig
new file mode 100644
index 000000000..4353da07a
--- /dev/null
+++ b/Tests/Fixtures/TestProject/ContentBlocker/Configs/legacy/Release.xcconfig
@@ -0,0 +1 @@
+API_PATH = https://release.google.com
diff --git a/Tests/Fixtures/TestProject/ContentBlocker/ContentBlockerRequestHandler.swift b/Tests/Fixtures/TestProject/ContentBlocker/ContentBlockerRequestHandler.swift
new file mode 100644
index 000000000..6f680e4e8
--- /dev/null
+++ b/Tests/Fixtures/TestProject/ContentBlocker/ContentBlockerRequestHandler.swift
@@ -0,0 +1,15 @@
+import UIKit
+import MobileCoreServices
+
+class ContentBlockerRequestHandler: NSObject, NSExtensionRequestHandling {
+
+ func beginRequest(with context: NSExtensionContext) {
+ let attachment = NSItemProvider(contentsOf: Bundle.main.url(forResource: "blockerList", withExtension: "json"))!
+
+ let item = NSExtensionItem()
+ item.attachments = [attachment]
+
+ context.completeRequest(returningItems: [item], completionHandler: nil)
+ }
+
+}
diff --git a/Tests/Fixtures/TestProject/ContentBlocker/Info.plist b/Tests/Fixtures/TestProject/ContentBlocker/Info.plist
new file mode 100644
index 000000000..a2f64a60d
--- /dev/null
+++ b/Tests/Fixtures/TestProject/ContentBlocker/Info.plist
@@ -0,0 +1,13 @@
+
+
+
+
+ NSExtension
+
+ NSExtensionPointIdentifier
+ com.apple.Safari.content-blocker
+ NSExtensionPrincipalClass
+ $(PRODUCT_MODULE_NAME).ContentBlockerRequestHandler
+
+
+
diff --git a/Tests/Fixtures/TestProject/ContentBlocker/blockerList.json b/Tests/Fixtures/TestProject/ContentBlocker/blockerList.json
new file mode 100644
index 000000000..a0fd0c72d
--- /dev/null
+++ b/Tests/Fixtures/TestProject/ContentBlocker/blockerList.json
@@ -0,0 +1,10 @@
+[
+ {
+ "action": {
+ "type": "block"
+ },
+ "trigger": {
+ "url-filter": "webkit.svg"
+ }
+ }
+]
diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj
index 5cdebf96f..06030f99f 100644
--- a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj
+++ b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj
@@ -76,6 +76,7 @@
3BBCA6F76E5F212E9C55FB78 /* BundleX.bundle in Copy Bundle Resources */ = {isa = PBXBuildFile; fileRef = 45C12576F5AA694DD0CE2132 /* BundleX.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
3C5134EE524310ACF7B7CD6E /* ExtensionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CAF6C55B555E3E1352645B6 /* ExtensionDelegate.swift */; };
3DF22C477446669094AC7C8C /* ExternalTarget.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = F6ADE654A3459AFDA2CC0CD3 /* ExternalTarget.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ 419BA91BBFD0053822D29F8B /* ContentBlockerRequestHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFD19E77891EFBB771E7C1F6 /* ContentBlockerRequestHandler.swift */; };
447D59BE2E0993D7245EA247 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3797E591F302ECC0AA2FC607 /* Assets.xcassets */; };
45E6702CD9C088FF1FC25F34 /* App_watchOS.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = A680BE9F68A255B0FB291AE6 /* App_watchOS.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
470D3493CDBFE56E2083A5FD /* BundleY.bundle in Copy Bundle Resources */ = {isa = PBXBuildFile; fileRef = E3958AB20082EA12D4D5E60C /* BundleY.bundle */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
@@ -99,6 +100,7 @@
61401517ECCEB2362582B5DA /* libEndpointSecurity.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BC75409252FF15F540FBB7B /* libEndpointSecurity.tbd */; };
61516CAC12B2843FBC4572E6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 59DA55A04FA2366B5D0BEEFF /* Assets.xcassets */; };
61601545B6BE00CA74A4E38F /* SceneKitCatalog.scnassets in Resources */ = {isa = PBXBuildFile; fileRef = C9E358FBE2B54D2B5C7FD609 /* SceneKitCatalog.scnassets */; };
+ 61E7E700A540CA86CFE30987 /* blockerList.json in Resources */ = {isa = PBXBuildFile; fileRef = B003E6782AAF80CE3DC662F4 /* blockerList.json */; };
6241507B4947B0B65429587C /* ExternalTarget.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = F6ADE654A3459AFDA2CC0CD3 /* ExternalTarget.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
632774E7F21CCB386A76B2A8 /* MessagesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B198242976C3395E31FE000A /* MessagesViewController.swift */; };
63D8E7F00276736EDA62D227 /* Framework2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3EF21DF245F66BEF5446AAEF /* Framework2.framework */; platformFilter = ios; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
@@ -723,6 +725,7 @@
/* Begin PBXFileReference section */
0095836FE59395511E0CB4F0 /* CrossOverlayFramework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CrossOverlayFramework.framework; sourceTree = BUILT_PRODUCTS_DIR; };
01E6934B571B91EAAFF0EDCB /* Resource.abc */ = {isa = PBXFileReference; path = Resource.abc; sourceTree = ""; };
+ 020B4FF64D029A2F6B13984D /* Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; };
020E4DA91C9132845CAFDC5D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = ""; };
039F208D1138598CE060F140 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; };
03CD22B8CD2E91BB97CC534E /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; };
@@ -762,6 +765,7 @@
2F430AABE04B7499B458D9DB /* SwiftFileInDotPath.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftFileInDotPath.swift; sourceTree = ""; };
3096A0760969873D46F80A92 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
325F18855099386B08DD309B /* Resource.abcd */ = {isa = PBXFileReference; path = Resource.abcd; sourceTree = ""; };
+ 334B75B25BEE708C56586797 /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; };
33F6DCDC37D2E66543D4965D /* App_macOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = App_macOS.app; sourceTree = BUILT_PRODUCTS_DIR; };
34F13B632328979093CE6056 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; };
3571E41E19A5AB8AAAB04109 /* StandaloneAssets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = StandaloneAssets.xcassets; sourceTree = ""; };
@@ -773,6 +777,8 @@
3ED831531AA349CCC19B258B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
3EF21DF245F66BEF5446AAEF /* Framework2.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Framework2.framework; sourceTree = BUILT_PRODUCTS_DIR; };
3FC04772130400920D68A167 /* App_Clip_Tests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = App_Clip_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4060DCDEBE331FD9C0D33D14 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; };
+ 40707675B7DC5C5158C16329 /* ContentBlocker.appex */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "wrapper.app-extension"; path = ContentBlocker.appex; sourceTree = BUILT_PRODUCTS_DIR; };
407C3F0009FDCE5B1B7DC2A8 /* App_supportedDestinations.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = App_supportedDestinations.app; sourceTree = BUILT_PRODUCTS_DIR; };
40863AE6202CFCD0529D8438 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; };
41FC82ED1C4C3B7B3D7B2FB7 /* Framework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Framework.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -839,6 +845,7 @@
AB055761199DF36DB0C629A6 /* Framework2.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Framework2.framework; sourceTree = BUILT_PRODUCTS_DIR; };
AEBCA8CFF769189C0D52031E /* App_iOS.xctestplan */ = {isa = PBXFileReference; path = App_iOS.xctestplan; sourceTree = ""; };
AEEFDE76B5FEC833403C0869 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; };
+ B003E6782AAF80CE3DC662F4 /* blockerList.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = blockerList.json; sourceTree = ""; };
B17B8D9C9B391332CD176A35 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LocalizedStoryboard.storyboard; sourceTree = ""; };
B198242976C3395E31FE000A /* MessagesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagesViewController.swift; sourceTree = ""; };
B1C33BB070583BE3B0EC0E68 /* App_iOS.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = App_iOS.app; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -871,6 +878,7 @@
D7E73F4E11A4B74449E7FDFE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; };
D8A016580A3B8F72B820BFBF /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
DAA7880242A9DE61E68026CC /* Folder */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Folder; sourceTree = SOURCE_ROOT; };
+ DFD19E77891EFBB771E7C1F6 /* ContentBlockerRequestHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentBlockerRequestHandler.swift; sourceTree = ""; };
DFE6A6FAAFF701FE729293DE /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
E0F31A9DE15B210D101AFC81 /* CrossOverlayFramework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CrossOverlayFramework.framework; sourceTree = BUILT_PRODUCTS_DIR; };
E3958AB20082EA12D4D5E60C /* BundleY.bundle */ = {isa = PBXFileReference; lastKnownFileType = wrapper.cfbundle; path = BundleY.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -1124,6 +1132,7 @@
BAE6C12745737019DC9E98BF /* App_watchOS */,
795B8D70B674C850B57DD39D /* App_watchOS Extension */,
6DBE0EE90642BB3F6E58AD43 /* Configs */,
+ F1FBA0D5C2FF5CB9E3DF1C94 /* ContentBlocker */,
3F2E22B7AB20FA42CD205C2A /* CopyFiles */,
ED8625A7E716E1BA50AB88AB /* CrossOverlayFramework */,
FCC084D4F8992BBC49983A38 /* CustomGroup */,
@@ -1403,6 +1412,7 @@
A680BE9F68A255B0FB291AE6 /* App_watchOS.app */,
84317819C92F78425870E483 /* BundleX.bundle */,
BB677D970923F663D846D7E0 /* BundleY.bundle */,
+ 40707675B7DC5C5158C16329 /* ContentBlocker.appex */,
8FE05BF7897ECFD58B7AC8B1 /* CrossOverlayFramework.framework */,
E0F31A9DE15B210D101AFC81 /* CrossOverlayFramework.framework */,
0095836FE59395511E0CB4F0 /* CrossOverlayFramework.framework */,
@@ -1435,6 +1445,15 @@
name = Products;
sourceTree = "";
};
+ AF78B31F5BDF95A9589B3879 /* legacy */ = {
+ isa = PBXGroup;
+ children = (
+ 020B4FF64D029A2F6B13984D /* Debug.xcconfig */,
+ 334B75B25BEE708C56586797 /* Release.xcconfig */,
+ );
+ path = legacy;
+ sourceTree = "";
+ };
BAE6C12745737019DC9E98BF /* App_watchOS */ = {
isa = PBXGroup;
children = (
@@ -1466,6 +1485,14 @@
path = iMessageExtension;
sourceTree = "";
};
+ C273E3A2CF5F0D2308907EB1 /* Configs */ = {
+ isa = PBXGroup;
+ children = (
+ AF78B31F5BDF95A9589B3879 /* legacy */,
+ );
+ path = Configs;
+ sourceTree = "";
+ };
C81493FAD71E9A9A19E00AD5 /* App_Clip */ = {
isa = PBXGroup;
children = (
@@ -1546,6 +1573,17 @@
path = App_macOS;
sourceTree = "";
};
+ F1FBA0D5C2FF5CB9E3DF1C94 /* ContentBlocker */ = {
+ isa = PBXGroup;
+ children = (
+ C273E3A2CF5F0D2308907EB1 /* Configs */,
+ B003E6782AAF80CE3DC662F4 /* blockerList.json */,
+ DFD19E77891EFBB771E7C1F6 /* ContentBlockerRequestHandler.swift */,
+ 4060DCDEBE331FD9C0D33D14 /* Info.plist */,
+ );
+ path = ContentBlocker;
+ sourceTree = "";
+ };
FC1515684236259C50A7747F /* Frameworks */ = {
isa = PBXGroup;
children = (
@@ -2323,6 +2361,22 @@
productReference = 3EF21DF245F66BEF5446AAEF /* Framework2.framework */;
productType = "com.apple.product-type.framework";
};
+ CE850EC53E9530D777ED6B31 /* ContentBlocker */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = E52CEBE94EB3DA1F6DECC49F /* Build configuration list for PBXNativeTarget "ContentBlocker" */;
+ buildPhases = (
+ 3EF36228A8A64153AF4A166C /* Sources */,
+ F0E27F118501847320425EB6 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = ContentBlocker;
+ productName = ContentBlocker;
+ productReference = 40707675B7DC5C5158C16329 /* ContentBlocker.appex */;
+ productType = "com.apple.product-type.app-extension";
+ };
D137C04B64B7052419A2DF4E /* App_Clip */ = {
isa = PBXNativeTarget;
buildConfigurationList = 07B4E73E56B7C2C80DE2A378 /* Build configuration list for PBXNativeTarget "App_Clip" */;
@@ -2505,6 +2559,7 @@
307AE3FA155FFD09B74AE351 /* App_watchOS Extension */,
DA40AB367B606CCE2FDD398D /* BundleX */,
271CAC331D24F4F7E12C819C /* BundleY */,
+ CE850EC53E9530D777ED6B31 /* ContentBlocker */,
0CE8BE7C80651629EC056066 /* CrossOverlayFramework_iOS */,
2F4FEAEFD7EE82DC49D899FC /* CrossOverlayFramework_macOS */,
3BF66A4668DFAF9338791F60 /* CrossOverlayFramework_tvOS */,
@@ -2641,6 +2696,14 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ F0E27F118501847320425EB6 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 61E7E700A540CA86CFE30987 /* blockerList.json in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
@@ -2899,6 +2962,14 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 3EF36228A8A64153AF4A166C /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 419BA91BBFD0053822D29F8B /* ContentBlockerRequestHandler.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
40A4456A24F99A01E340C032 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -4013,6 +4084,23 @@
};
name = "Production Release";
};
+ 18AA8BA9237D5BC52525C664 /* Production Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 334B75B25BEE708C56586797 /* Release.xcconfig */;
+ buildSettings = {
+ CODE_SIGN_IDENTITY = "Apple Development";
+ INFOPLIST_FILE = ContentBlocker/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@executable_path/../../Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.project.ContentBlocker;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = "Production Release";
+ };
18B5349AE18B7183BE4B4363 /* Staging Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -4127,6 +4215,23 @@
};
name = "Test Release";
};
+ 1D6D36790F00BE5A86FF54A4 /* Staging Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 334B75B25BEE708C56586797 /* Release.xcconfig */;
+ buildSettings = {
+ CODE_SIGN_IDENTITY = "Apple Development";
+ INFOPLIST_FILE = ContentBlocker/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@executable_path/../../Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.project.ContentBlocker;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = "Staging Release";
+ };
1FB2AFB2F45076B4A047499E /* Staging Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -7037,6 +7142,23 @@
};
name = "Production Debug";
};
+ B2D62E426DBC2DE731C9790D /* Test Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 020B4FF64D029A2F6B13984D /* Debug.xcconfig */;
+ buildSettings = {
+ CODE_SIGN_IDENTITY = "Apple Development";
+ INFOPLIST_FILE = ContentBlocker/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@executable_path/../../Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.project.ContentBlocker;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = "Test Debug";
+ };
B3B2FEA08FA4ACD18FDF9BC2 /* Production Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -7794,6 +7916,40 @@
};
name = "Staging Debug";
};
+ D69E04FC7BE3A6968EF236C1 /* Staging Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 020B4FF64D029A2F6B13984D /* Debug.xcconfig */;
+ buildSettings = {
+ CODE_SIGN_IDENTITY = "Apple Development";
+ INFOPLIST_FILE = ContentBlocker/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@executable_path/../../Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.project.ContentBlocker;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = "Staging Debug";
+ };
+ D6A2E246E9EEDAA18B76937A /* Production Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 020B4FF64D029A2F6B13984D /* Debug.xcconfig */;
+ buildSettings = {
+ CODE_SIGN_IDENTITY = "Apple Development";
+ INFOPLIST_FILE = ContentBlocker/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@executable_path/../../Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.project.ContentBlocker;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = "Production Debug";
+ };
D70B7AB6D219453ABF475EED /* Production Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -8760,6 +8916,23 @@
};
name = "Staging Release";
};
+ FFA29E0E53E5B870627E1A2C /* Test Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 334B75B25BEE708C56586797 /* Release.xcconfig */;
+ buildSettings = {
+ CODE_SIGN_IDENTITY = "Apple Development";
+ INFOPLIST_FILE = ContentBlocker/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@executable_path/../../Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.project.ContentBlocker;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = "Test Release";
+ };
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@@ -9309,6 +9482,19 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = "Production Debug";
};
+ E52CEBE94EB3DA1F6DECC49F /* Build configuration list for PBXNativeTarget "ContentBlocker" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ D6A2E246E9EEDAA18B76937A /* Production Debug */,
+ 18AA8BA9237D5BC52525C664 /* Production Release */,
+ D69E04FC7BE3A6968EF236C1 /* Staging Debug */,
+ 1D6D36790F00BE5A86FF54A4 /* Staging Release */,
+ B2D62E426DBC2DE731C9790D /* Test Debug */,
+ FFA29E0E53E5B870627E1A2C /* Test Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = "Production Debug";
+ };
ED1A174BA92C6E5172B519B7 /* Build configuration list for PBXNativeTarget "iMessageExtension" */ = {
isa = XCConfigurationList;
buildConfigurations = (
diff --git a/Tests/Fixtures/TestProject/project.yml b/Tests/Fixtures/TestProject/project.yml
index dcef8e1e0..5fea502fb 100644
--- a/Tests/Fixtures/TestProject/project.yml
+++ b/Tests/Fixtures/TestProject/project.yml
@@ -16,6 +16,8 @@ options:
buildPhase: none
abcd:
buildPhase: none
+globalTemplateAttributes:
+ version: legacy
fileGroups:
- Configs
- FileGroup
@@ -79,7 +81,9 @@ targets:
legacy:
toolPath: /usr/bin/true
passSettings: true
-
+ ContentBlocker:
+ templates:
+ - ContentBlockerTemplate
App_macOS:
type: application
platform: macOS
@@ -520,6 +524,20 @@ schemes:
targetTemplates:
MyTemplate:
scheme: {}
+ ContentBlockerTemplate:
+ platform: iOS
+ type: app-extension
+ settings:
+ CODE_SIGN_IDENTITY: Apple Development
+ configFiles:
+ Test Debug: ContentBlocker/Configs/${version}/Debug.xcconfig
+ Staging Debug: ContentBlocker/Configs/${version}/Debug.xcconfig
+ Production Debug: ContentBlocker/Configs/${version}/Debug.xcconfig
+ Test Release: ContentBlocker/Configs/${version}/Release.xcconfig
+ Staging Release: ContentBlocker/Configs/${version}/Release.xcconfig
+ Production Release: ContentBlocker/Configs/${version}/Release.xcconfig
+ sources:
+ - ContentBlocker
aggregateTargets:
SuperTarget:
attributes:
diff --git a/Tests/Fixtures/global_template_attributes_test.yml b/Tests/Fixtures/global_template_attributes_test.yml
new file mode 100644
index 000000000..3cd560b37
--- /dev/null
+++ b/Tests/Fixtures/global_template_attributes_test.yml
@@ -0,0 +1,32 @@
+targetTemplates:
+ ContentBlockerTemplate:
+ platform: iOS
+ type: app-extension
+ settings:
+ CODE_SIGN_IDENTITY: Apple Development
+ configFiles:
+ Test Debug: ContentBlocker/Configs/${version}/Debug.xcconfig
+ Staging Debug: ContentBlocker/Configs/${version}/Debug.xcconfig
+ Production Debug: ContentBlocker/Configs/${version}/Debug.xcconfig
+ Test Release: ContentBlocker/Configs/${version}/Release.xcconfig
+ Staging Release: ContentBlocker/Configs/${version}/Release.xcconfig
+ Production Release: ContentBlocker/Configs/${version}/Release.xcconfig
+ sources:
+ - ContentBlocker
+
+globalTemplateAttributes:
+ version: legacy
+
+name: Demo
+options:
+ createIntermediateGroups: True
+targets:
+ Demo:
+ type: application
+ platform: iOS
+ deploymentTarget: "10.0"
+ sources:
+ - DemoXcodeGenGlobalTemplateAttribute
+ ContentBlocker:
+ templates:
+ - ContentBlockerTemplate
\ No newline at end of file
diff --git a/Tests/ProjectSpecTests/SpecLoadingTests.swift b/Tests/ProjectSpecTests/SpecLoadingTests.swift
index 6a81c0907..5cf7d09ff 100644
--- a/Tests/ProjectSpecTests/SpecLoadingTests.swift
+++ b/Tests/ProjectSpecTests/SpecLoadingTests.swift
@@ -285,6 +285,15 @@ class SpecLoadingTests: XCTestCase {
]
try expect(project.targets.last?.sources) == ["SomeTarget", "doesWin", "templateVariable"]
}
+
+ $0.it("lookup global template attributes") {
+ let path = fixturePath + "global_template_attributes_test.yml"
+
+ let project = try loadSpec(path: path)
+ let extensionTarget = project.targets.first!
+ try expect(extensionTarget.configFiles["Production Debug"]) == "ContentBlocker/Configs/legacy/Debug.xcconfig"
+ try expect(extensionTarget.configFiles["Production Release"]) == "ContentBlocker/Configs/legacy/Release.xcconfig"
+ }
}
}