Skip to content

Commit 9e87491

Browse files
Add alert if project file has no build settings
- Add NSDictionary category the checks for build settings - Add test for new NSDictionary category - Resolves #18
1 parent 4fe04ec commit 9e87491

File tree

4 files changed

+76
-2
lines changed

4 files changed

+76
-2
lines changed

BuildSettingExtractor/BuildSettingExtractor.m

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,18 +117,28 @@ - (BOOL)extractBuildSettingsFromProject:(NSURL *)projectWrapperURL toDestination
117117
NSDictionary *projectSettings = [self buildSettingStringsByConfigurationForBuildConfigurationListID:buildConfigurationListID];
118118

119119
self.buildSettingsByTarget[validatedProjectConfigName] = projectSettings;
120+
121+
// Begin check that the project file has some settings
122+
BOOL projectFileHasSettings = projectSettings.containsBuildSettings;
120123

121124
// Add project targets
122125
for (NSDictionary *target in targets) {
123126
NSString *targetName = target[@"name"];
124127
buildConfigurationListID = target[@"buildConfigurationList"];
125128
NSDictionary *targetSettings = [self buildSettingStringsByConfigurationForBuildConfigurationListID:buildConfigurationListID];
129+
if (!projectFileHasSettings) { projectFileHasSettings = targetSettings.containsBuildSettings; }
126130

127131
self.buildSettingsByTarget[targetName] = targetSettings;
128132

129133
}
130134

131-
[self writeConfigFilesToDestinationFolder:folderURL];
135+
if (projectFileHasSettings) {
136+
[self writeConfigFilesToDestinationFolder:folderURL];
137+
} else {
138+
[self presentErrorForNoSettingsFoundInProject: [projectWrapperURL lastPathComponent]];
139+
success = NO;
140+
}
141+
132142
}
133143
}
134144
return success;
@@ -160,6 +170,20 @@ - (void)presentErrorForNameConflictWithName:(NSString *)conflictedName validated
160170

161171
}
162172

173+
// Notify the user we did not find any settings in the project.
174+
- (void)presentErrorForNoSettingsFoundInProject:(NSString *)projectName {
175+
NSString *errorDescription = [NSString stringWithFormat:@"No settings found."];
176+
NSString *errorRecoverySuggestion = [NSString stringWithFormat:@"No settings were found in the project \'%@\'.\n\nThe project may already be using .xcconfig files for its build settings.\n\nNo xcconfig files will be written. ", projectName];
177+
NSDictionary *errorUserInfo = @{NSLocalizedDescriptionKey:errorDescription, NSLocalizedRecoverySuggestionErrorKey: errorRecoverySuggestion};
178+
179+
NSError *error = [NSError errorWithDomain:[[NSBundle mainBundle] bundleIdentifier] code:NoSettingsFoundInProjectFile userInfo:errorUserInfo];
180+
181+
dispatch_async(dispatch_get_main_queue(), ^{
182+
[NSApp presentError:error];
183+
});
184+
185+
}
186+
163187
/* Writes an xcconfig file for each target / configuration combination to the specified directory.
164188
*/
165189
- (void)writeConfigFilesToDestinationFolder:(NSURL *)destinationURL {

BuildSettingExtractor/Constants+Categories.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ typedef NS_ENUM(NSUInteger, AppErrorCodes) {
1212
UnsupportedXcodeVersion = 100,
1313
DirectoryContainsBuildConfigFiles = 101,
1414
ProjectSettingsNamingConflict = 102,
15+
NoSettingsFoundInProjectFile = 103,
1516
};
1617

1718
extern NSString *const TPSOpenDirectoryInFinder;
@@ -39,3 +40,13 @@ extern NSString *const TPSOutputFileNameSeparator;
3940
@interface NSString (TPS_BuildSettingAdditions)
4041
- (NSString *)tps_baseBuildSettingName; // Removes any conditional section of a build setting
4142
@end
43+
44+
#pragma mark -
45+
46+
@interface NSDictionary (TPS_BuildSettingAdditions)
47+
// Assumes that a dictionary of build settings always has NSString values
48+
// Returns NO if all the values in a dictionary are an empty string
49+
// Raises an exception if used on a dictionary with any non-NSString value
50+
- (BOOL)containsBuildSettings;
51+
@end
52+

BuildSettingExtractor/Constants+Categories.m

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,26 @@ - (NSString *)tps_baseBuildSettingName {
7777
return baseBuildSettingName;
7878
}
7979

80-
@end
80+
@end
81+
82+
#pragma mark -
83+
84+
@implementation NSDictionary (TPS_BuildSettingAdditions)
85+
86+
- (BOOL)containsBuildSettings {
87+
BOOL foundNonEmptyString = NO;
88+
for (id value in self.allValues) {
89+
if ([value isKindOfClass:[NSString class]]) {
90+
if (![(NSString *)value isEqualToString:@""]) {
91+
foundNonEmptyString = YES;
92+
break;
93+
}
94+
} else {
95+
[NSException raise:(NSInternalInconsistencyException) format:@"-containsBuildSetting is expected to be called on a dictionary with NSString values."];
96+
}
97+
}
98+
return foundNonEmptyString;
99+
}
100+
101+
@end
102+

BuildSettingExtractorTests/BuildSettingExtractorTests.m

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#import <XCTest/XCTest.h>
1010
#import "BuildSettingExtractor.h"
11+
#import "Constants+Categories.h"
1112

1213
@interface NSObject (BuildSettingExtractorMethods)
1314
- (NSDictionary *)buildSettingsByConfigurationForConfigurations:(NSArray *)buildConfigurations;
@@ -35,4 +36,20 @@ - (void)testThreeBuildConfigurations
3536
XCTAssert([sharedBuildSettings isEqualToDictionary:expectedBuildSettings], @"Build settings should match");
3637
}
3738

39+
- (void)testDictionaryBuildSettingsCategory
40+
{
41+
NSDictionary *dictionaryWithBuildSettings = @{ @"Shared": @"COPY_PHASE_STRIP = NO", @"Release": @"COPY_PHASE_STRIP = NO", @"Debug": @"COPY_PHASE_STRIP = NO" };
42+
XCTAssertTrue(dictionaryWithBuildSettings.containsBuildSettings);
43+
44+
NSDictionary *dictionaryWithMinimalBuildSettings = @{ @"Shared": @"", @"Release": @"", @"Debug": @"COPY_PHASE_STRIP = NO" };
45+
XCTAssertTrue(dictionaryWithMinimalBuildSettings.containsBuildSettings);
46+
47+
NSDictionary *dictionaryWithoutBuildSettings = @{ @"Shared": @"", @"Release": @"", @"Debug": @"" };
48+
XCTAssertFalse(dictionaryWithoutBuildSettings.containsBuildSettings);
49+
50+
NSDictionary *badDictionary = @{@"Shared":@"", @"Release":@"", @"Debug":[NSDate date] };
51+
BOOL result = NO;
52+
XCTAssertThrows(result = badDictionary.containsBuildSettings);
53+
}
54+
3855
@end

0 commit comments

Comments
 (0)