/******************************************************************************* * Copyright (c) 2013, 2016 Red Hat, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Red Hat Inc. - initial API and implementation and/or initial documentation *******************************************************************************/ package org.eclipse.thym.ios.core.xcode; import java.io.File; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubMonitor; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.IStreamListener; import org.eclipse.debug.core.model.IStreamMonitor; import org.eclipse.thym.core.HybridProject; import org.eclipse.thym.core.internal.cordova.CordovaCLI; import org.eclipse.thym.core.internal.cordova.ErrorDetectingCLIResult; import org.eclipse.thym.core.internal.util.ExternalProcessUtility; import org.eclipse.thym.core.platform.AbstractNativeBinaryBuildDelegate; import org.eclipse.thym.ios.core.IOSCore; /** * Wrapper around ios build for Cordova CLI * * @author Gorkem Ercan * */ public class XCodeBuild extends AbstractNativeBinaryBuildDelegate{ public static final String MIN_REQUIRED_VERSION = "6.0.0"; private static class SDKListParser implements IStreamListener{ private StringBuffer buffer = new StringBuffer(); @Override public void streamAppended(String text, IStreamMonitor monitor) { buffer.append(text); } ArrayList<XCodeSDK> getSDKList(){ ArrayList<XCodeSDK> sdkList=new ArrayList<XCodeSDK>(5); if(buffer.indexOf("-sdk")>0){ String text = buffer.toString(); text = text.replaceAll("[ a-zA-Z1-9.1-9]*:", ""); text = text.replaceAll("-sdk [a-z]*[0-9]*.[0-9]*", ""); String[] sdks = text.split("\n"); for (String string : sdks) { String clean = string.trim(); if(!clean.isEmpty()){ sdkList.add(new XCodeSDK(clean)); } } } return sdkList; } } private static class XCodeVersionParser implements IStreamListener{ private static final int START_LOC = "XCode".length()+1; private StringBuffer buffer = new StringBuffer(); @Override public void streamAppended(String text, IStreamMonitor monitor) { buffer.append(text); } public String getVersion(){ if(buffer.length()<START_LOC){ return ""; } return buffer.substring(START_LOC, buffer.indexOf("\n")); } } private ILaunchConfiguration launchConfiguration; @Override public void buildNow(IProgressMonitor monitor) throws CoreException { if (monitor.isCanceled()) { return; } SubMonitor sm = SubMonitor.convert(monitor, "Build project for iOS", 100); try { HybridProject hybridProject = HybridProject.getHybridProject(this.getProject()); if (hybridProject == null) { throw new CoreException(new Status(IStatus.ERROR, IOSCore.PLUGIN_ID, "Not a hybrid mobile project, can not generate files")); } String buildType = "--emulator"; if(isRelease()){ buildType = "--device"; } if (sm.isCanceled()) { return; } IStatus status = CordovaCLI.newCLIforProject(hybridProject).build(sm.newChild(70), "ios",buildType).convertTo(ErrorDetectingCLIResult.class).asStatus(); this.getProject().refreshLocal(IResource.DEPTH_INFINITE, sm.newChild(20)); if(status.getSeverity() == IStatus.ERROR){ throw new CoreException(status); } String name = hybridProject.getAppName(); IFolder buildFolder = hybridProject.getProject().getFolder("platforms/ios/build"); IFolder artifactFolder = null; if(isRelease()){ artifactFolder = buildFolder.getFolder("device"); }else{ artifactFolder = buildFolder.getFolder("emulator"); } setBuildArtifact(new File(artifactFolder.getLocation().toFile(), name + ".app")); if (!getBuildArtifact().exists()) { throw new CoreException(new Status(IStatus.ERROR, IOSCore.PLUGIN_ID, "xcodebuild has failed: build artifact does not exist")); } } finally { sm.done(); } } public ILaunchConfiguration getLaunchConfiguration() { return launchConfiguration; } public void setLaunchConfiguration(ILaunchConfiguration launchConfiguration) { this.launchConfiguration = launchConfiguration; } public List<XCodeSDK> showSdks() throws CoreException { ExternalProcessUtility processUtility = new ExternalProcessUtility(); SDKListParser parser = new SDKListParser(); processUtility.execSync("xcodebuild -showsdks ", null, parser, parser, new NullProgressMonitor(), null, null); return parser.getSDKList(); } public String version() throws CoreException{ ExternalProcessUtility processUtility = new ExternalProcessUtility(); XCodeVersionParser parser = new XCodeVersionParser(); processUtility.execSync("xcodebuild -version", null, parser, parser, new NullProgressMonitor(), null, null); return parser.getVersion(); } }