Skip to content

Commit

Permalink
Merge pull request #353 from brunobowden/update
Browse files Browse the repository at this point in the history
xcodeTarget to also automatically match Tests and WatchKit App
  • Loading branch information
brunobowden committed Aug 17, 2015
2 parents b8f0b76 + d254168 commit 0c621b7
Show file tree
Hide file tree
Showing 4 changed files with 209 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import org.gradle.util.ConfigureUtil
*
* j2objcConfig {
* xcodeProjectDir '../ios'
* xcodeTarget 'IosApp'
* xcodeTarget 'IOS-APP'
* finalConfigure()
* }
*
Expand Down Expand Up @@ -432,6 +432,7 @@ class J2objcConfig {
* @param extraObjcSrcDirs add directories for Objective-C source to be compiled
*/
void extraObjcSrcDirs(String... extraObjcSrcDirs) {
verifyNoSpaceArgs('extraObjcSrcDirs', extraObjcSrcDirs)
for (String arg in extraObjcSrcDirs) {
this.extraObjcSrcDirs += arg
}
Expand All @@ -447,6 +448,7 @@ class J2objcConfig {
* @param extraObjcCompilerArgs add arguments to pass to the native compiler.
*/
void extraObjcCompilerArgs(String... extraObjcCompilerArgs) {
verifyNoSpaceArgs('extraObjcCompilerArgs', extraObjcCompilerArgs)
for (String arg in extraObjcCompilerArgs) {
this.extraObjcCompilerArgs += arg
}
Expand All @@ -462,6 +464,7 @@ class J2objcConfig {
* @param extraLinkerArgs add arguments to pass to the native linker.
*/
void extraLinkerArgs(String... extraLinkerArgs) {
verifyNoSpaceArgs('extraLinkerArgs', extraLinkerArgs)
for (String arg in extraLinkerArgs) {
this.extraLinkerArgs += arg
}
Expand Down Expand Up @@ -495,6 +498,11 @@ class J2objcConfig {
String xcodeProjectDir = null
/**
* Xcode app target the generated library should be linked to.
*
* This will automatically add linkage for any target that starts with the
* same name. This should include any Test and Watch targets. For the example of
* xcodeTarget == 'IOS-APP', it will add targets for 'IOS-APPTests',
* 'IOS-APP WatchKit App' & 'IOS-APP WatchKit Extension' (if they exist).
*/
String xcodeTarget = null

Expand All @@ -517,7 +525,6 @@ class J2objcConfig {
assert destSrcMainDir != null
assert destSrcTestDir != null


// Disable only if explicitly present and not true.
boolean debugEnabled = Boolean.parseBoolean(Utils.getLocalProperty(project, 'debug.enabled', 'true'))
boolean releaseEnabled = Boolean.parseBoolean(Utils.getLocalProperty(project, 'release.enabled', 'true'))
Expand Down Expand Up @@ -565,8 +572,15 @@ class J2objcConfig {
// }
@VisibleForTesting
static void appendArgs(List<String> listArgs, String nameArgs, String... args) {
verifyNoSpaceArgs(nameArgs, args)
listArgs.addAll(Arrays.asList(args))
}

// Verify that no argument contains a space
@VisibleForTesting
static void verifyNoSpaceArgs(String nameArgs, String... args) {
if (args == null) {
throw new InvalidUserDataException("args == null!")
throw new InvalidUserDataException("$nameArgs == null!")
}
for (String arg in args) {
if (arg.contains(' ')) {
Expand All @@ -576,6 +590,5 @@ class J2objcConfig {
"$nameArgs $rewrittenArgs")
}
}
listArgs.addAll(Arrays.asList(args))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction

import java.util.regex.Matcher

/**
* Updates the Xcode project with j2objc generated files and resources.
* <p/>
Expand Down Expand Up @@ -184,11 +186,11 @@ class XcodeTask extends DefaultTask {
"Xcode settings need to be configured in this project's build.gradle.\n" +
"The directory should point to the location containing your Xcode project,\n" +
"including the .xccodeproj and .xcworkspace files. The target is the name,\n" +
"of the iOS app within Xcode (not the tests or watch extension targets).\n" +
"of the iOS app within Xcode (not the tests or watch app target).\n" +
"\n" +
"j2objcConfig {\n" +
" xcodeProjectDir '../ios'\n" +
" xcodeTarget 'IOS-APP-TARGET'\n" +
" xcodeTarget 'IOS-APP'\n" +
"}\n" +
"\n" +
"Also see the guidelines for the folder structure:\n" +
Expand Down Expand Up @@ -250,6 +252,27 @@ class XcodeTask extends DefaultTask {
"end\n"
}

/**
* Extracts all target names that start with xcodeTarget.
*
* For xcodeTarget == 'IOS-APP', likely extracted names are:
* IOS-APP
* IOS-APPTests
* IOS-APP WatchKit App
* IOS-APP WatchKit Extension
*/
@VisibleForTesting
static List<String> extractXcodeTargets(String xcodeTarget, List<String> podFileLines) {
List<String> xcodeTargets = new ArrayList<>()
for (line in podFileLines) {
Matcher matcher = (line =~ /^target '($xcodeTarget[^']*)' do$/)
if (matcher.find()) {
xcodeTargets.add(matcher.group(1))
}
}
return xcodeTargets
}

/**
* Modify in place the existing podFile.
*/
Expand All @@ -260,12 +283,22 @@ class XcodeTask extends DefaultTask {

List<String> oldPodFileLines = podFile.readLines()
List<String> newPodFileLines = new ArrayList<String>(oldPodFileLines)
newPodFileLines = updatePodFileLines(
newPodFileLines, xcodeTarget,
podNameDebug, ['Debug'], podPath)
newPodFileLines = updatePodFileLines(
newPodFileLines, xcodeTarget,
podNameRelease, ['Release'], podPath)
List<String> xcodeTargets = extractXcodeTargets(xcodeTarget, oldPodFileLines)

if (! xcodeTargets.contains(xcodeTarget)) {
throw new InvalidUserDataException(
"Can't find iOS App Target '$xcodeTarget' in Podfile: ${podFile.absolutePath}")
}

// Iterate over all the xcodeTargets for Debug and Release
for (xcodeTargetName in xcodeTargets) {
newPodFileLines = updatePodFileLines(
newPodFileLines, xcodeTargetName,
podNameDebug, ['Debug'], podPath)
newPodFileLines = updatePodFileLines(
newPodFileLines, xcodeTargetName,
podNameRelease, ['Release'], podPath)
}

// Write file only if it's changed
if (!oldPodFileLines.equals(newPodFileLines)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ import org.gradle.api.Project
import org.gradle.testfixtures.ProjectBuilder
import org.gradle.util.ConfigureUtil
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.ExpectedException

/**
* J2objcConfig tests.
Expand All @@ -33,6 +35,9 @@ class J2objcConfigTest {

private Project proj

@Rule
public ExpectedException expectedException = ExpectedException.none();

@Before
void setUp() {
proj = ProjectBuilder.builder().build()
Expand Down Expand Up @@ -101,7 +106,7 @@ class J2objcConfigTest {
}

@Test
void testconfigureArgs() {
void testAppendArgs() {
List<String> args = new ArrayList()
J2objcConfig.appendArgs(args, 'testArgs', '-arg1', '-arg2')

Expand All @@ -110,14 +115,41 @@ class J2objcConfigTest {
}

@Test(expected = InvalidUserDataException.class)
void testconfigureArgs_Null() {
void testAppendArgs_Null() {
List<String> args = new ArrayList()
J2objcConfig.appendArgs(args, 'testArgs', null)
}

@Test(expected = InvalidUserDataException.class)
void testconfigureArgs_Spaces() {
void testAppendArgs_Spaces() {
List<String> args = new ArrayList()
J2objcConfig.appendArgs(args, 'testArgs', '-arg1 -arg2')
}

@Test
void testVerifyNoSpaceArgs_NoSpace() {
J2objcConfig.verifyNoSpaceArgs('testArgs', '-arg1', '-arg2')
}

@Test
void testVerifyNoSpaceArgs_Space() {
expectedException.expect(InvalidUserDataException.class)
expectedException.expectMessage('argument should not contain spaces and be written out as distinct entries')
expectedException.expectMessage("testArgs '-arg1', '-arg2'")

J2objcConfig.verifyNoSpaceArgs('testArgs', '-arg1 -arg2')
}

// A small number of the configuration variable must be String[]
// instead of List<String>, this tests 'extraLinkerArgs' as an example.
@Test
void testStringArrayArgs() {
J2objcConfig j2objcConfig = new J2objcConfig(proj)
j2objcConfig.extraLinkerArgs = ['-arg1']

j2objcConfig.extraLinkerArgs('-arg2', '-arg3')

String[] expected = ['-arg1', '-arg2', '-arg3']
assert Arrays.equals(expected, j2objcConfig.extraLinkerArgs)
}
}
Loading

0 comments on commit 0c621b7

Please sign in to comment.