All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sap.prd.mobile.ios.mios.XCodeChangeAppIDMojo Maven / Gradle / Ivy

Go to download

This plugin is used to run iOS Xcode builds with Maven. It also uses the Maven integration with a central artifact repository and the dependency resolution.

There is a newer version: 1.14.7
Show newest version
/*
 * #%L
 * xcode-maven-plugin
 * %%
 * Copyright (C) 2012 SAP AG
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
package com.sap.prd.mobile.ios.mios;

import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.logging.LogManager;
import java.util.logging.Logger;

import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;

/**
 * Appends a suffix to the appId. No actions are taken if the suffix is not specified or the suffix
 * has zero length.
 * 
 * @goal change-app-id
 * 
 */
public class XCodeChangeAppIDMojo extends BuildContextAwareMojo
{

	private final static Logger LOGGER = LogManager.getLogManager().getLogger(XCodePluginLogger.getLoggerName());
	/**
	* This suffix gets appended to the appId as '.<appIdSuffix>' in the Info.plist
	* before the signing takes place.
	*
	* @parameter expression="${xcode.appIdSuffix}"
	* @since 1.2.0
	*/
	private static String appIdSuffix;

	/**
	* appType helps to inject the appIdSuffix in to appropriate location of appId in the Info.plist
	* before the signing takes place.
	* Without type appId will be suffixed with the given value, with type we are injecting value at appropriate location
	* @parameter expression="${xcode.appType}"
	*/
	private String appType;

	/**
	* watchkitAppPlist helps to know the location of watchkitApp plist file
	* appIdSuffix will be injected to this plist file
	*  @parameter expression="${xcode.watchkitAppPlist}"
	*/
	private static String watchkitAppPlist;

	/**
	* watchkitExtensionPlist helps to know the location of watchkitExtension plist file
	* appIdSuffix will be injected to this plist file
	*  @parameter expression="${xcode.watchkitExtentionPlist}"
	*/
	private static String watchkitExtentionPlist;

	/**
	* This is a variable in plist file of Watchkitapp
	* This variable reference to the Bundle Identifier of the iphone app
	*/
	private static String wkCompanionAppBundleIdentifier;


	/**
	* This is a variable in plist file of watchkitextention
	* This variable reference to the Bundle Identifier of the Watchkitapp
	*/
	private static String wkAppBundleIdentifier;

	/**
	* This is common variable in all the plist files, we need to make sure values are same in all plist files
	*/
	private static String cfBundleShortVersionString;

	/**
	* This is common variable in all the plist files, we need to make sure values are same in all plist files
	*/
	private static String cfBundleVersion;

	/**
	* This is a watchkit apps modified bundle identifier value, this needs to be extended for the watchkitextension bundle identifier
	* Requirement for the watchos2.0 applications, without with build fails
	*/

	private static String watchkitAppBundleIdentifier;
	/**
	* @parameter expression="${xcode.watchapp}"
	* For watchos2.0 we should not send the sdk value to xcodebuild, To differentiate between regular app and watch2.0 (Now it's specific)
	* expecting this property from developer in pom.xml, on demand this will be considered.
	*
	* pom.xml entry:
	*
	* 
	* {@code
	* 
	*  watchos2.0
	* 
	* }
	* 
* * @since 1.14.3 */ private String watchapp; @Override public void execute() throws MojoExecutionException, MojoFailureException { if (appIdSuffix == null || "".equals(appIdSuffix.trim())) { return; } LOGGER.info("appIdSuffix=" + appIdSuffix); final Collection alreadyUpdatedPlists = new HashSet(); for (final String configuration : getConfigurations()) { for (final String sdk : getSDKs()) { File infoPlistFile = null; File srcRoot = null; PListAccessor infoPlistAccessor = null; /* * Add appIdSuffix to the info.plist of Application */ try { infoPlistFile = getPListFile(XCodeContext.SourceCodeLocation.WORKING_COPY, configuration, sdk); } catch (XCodeException e) { throw new MojoExecutionException(e.getMessage(), e); } infoPlistAccessor = new PListAccessor(infoPlistFile); if (alreadyUpdatedPlists.contains(infoPlistFile)) { LOGGER.finer("PList file '" + infoPlistFile.getName() + "' was already updated for another configuration. This file will be skipped."); } else { changeAppId(infoPlistAccessor, appIdSuffix, null); try { setCFBundleShortVersionString(infoPlistAccessor.getStringValue(PListAccessor.KEY_BUNDLE_SHORT_VERSION_STRING)); setCFBundleVersion(infoPlistAccessor.getStringValue(PListAccessor.KEY_BUNDLE_VERSION)); } catch (IOException e) { throw new MojoExecutionException(e.getMessage(), e); } alreadyUpdatedPlists.add(infoPlistFile); } /** * If appType provided explicitly; User also needs to specify the additional plist files for appId injection * Currently no strict check for the appType which can be extended for specific checks in future. * For watchkit Application support: User has to pass parameters as below in pom.xml * *
				 * {@code
				 * 
				 *  watchKit
				 *  ${watchkitApp-plist-file-path}
				 *  ${watchkitExtention-plist-file-path}
				 * 
				 * }
				 * 
* * Sample: * * Provide the relative paths of the plist files: Project_Root_Dir\{plist-file-path} * Ex: * AppName: "TodoList" * WatchKit App plist file: "TodoList WatchKit App\Info.plist" * WatchKit Extension plist file: "TodoList WatchKit Extension\Info.plist" * pom.xml entry should look like, * *
				 * {@code
				 * 
				 *  watchKit
				 *  TodoList WatchKit App\Info.plist
				 *  TodoList WatchKit Extension\Info.plist
				 * 
				 * }
				 * 
* */ if (!(appType == null || "".equals(appType.trim()))) { LOGGER.info("appType: " + appType + " value provided, needs to consider additional plist files for appIdSuffix injection"); try { srcRoot = getProjectRootDirectory(XCodeContext.SourceCodeLocation.WORKING_COPY, configuration, sdk); if (watchkitAppPlist != null || "".equals(watchkitAppPlist.trim())) { LOGGER.info("location of watchkitAppPlist: " + watchkitAppPlist); infoPlistFile = new File(srcRoot, watchkitAppPlist); infoPlistAccessor = new PListAccessor(infoPlistFile); if (alreadyUpdatedPlists.contains(infoPlistFile)) { LOGGER.finer("PList file '" + infoPlistFile.getName() + "' was already updated for another configuration. This file will be skipped."); } else { try { changeAppId(infoPlistAccessor, appIdSuffix, appType); changePlistKeyValue(infoPlistFile,PListAccessor.KEY_WK_COMPANION_APP_BUNDLE_IDENTIFIER,getWKCompanionAppBundleIdentifier()); changePlistKeyValue(infoPlistFile,PListAccessor.KEY_BUNDLE_SHORT_VERSION_STRING,getCFBundleShortVersionString()); changePlistKeyValue(infoPlistFile,PListAccessor.KEY_BUNDLE_VERSION,getCFBundleVersion()); } catch (IOException e) { throw new MojoExecutionException(e.getMessage(), e); } } setWKAppBundleIdentifier(infoPlistAccessor.getStringValue(PListAccessor.KEY_BUNDLE_IDENTIFIER)); alreadyUpdatedPlists.add(infoPlistFile); } if (watchkitExtentionPlist != null || "".equals(watchkitExtentionPlist.trim())) { LOGGER.info("location of watchkitExtentionPlist: " + watchkitExtentionPlist); infoPlistFile = new File(srcRoot, watchkitExtentionPlist); infoPlistAccessor = new PListAccessor(infoPlistFile); if (alreadyUpdatedPlists.contains(infoPlistFile)) { LOGGER.finer("PList file '" + infoPlistFile.getName() + "' was already updated for another configuration. This file will be skipped."); } else { changeAppIdForExtension(infoPlistFile, appIdSuffix, appType); changePlistKeyValue(infoPlistFile,PListAccessor.KEY_WK_APP_BUNDLE_IDENTIFIER,getWKAppBundleIdentifier()); changePlistKeyValue(infoPlistFile,PListAccessor.KEY_BUNDLE_SHORT_VERSION_STRING,getCFBundleShortVersionString()); changePlistKeyValue(infoPlistFile,PListAccessor.KEY_BUNDLE_VERSION,getCFBundleVersion()); alreadyUpdatedPlists.add(infoPlistFile); } } } catch (XCodeException e) { throw new MojoExecutionException(e.getMessage(), e); } catch (IOException e) { throw new MojoExecutionException(e.getMessage(), e); } } } } } static void changeAppIdForExtension(File plist, String appIdSuffix, String appType) throws MojoExecutionException { PListAccessor infoPlistAccessor = new PListAccessor(plist); ensurePListFileIsWritable(infoPlistAccessor.getPlistFile()); try { LOGGER.info("Watchkit extension bundle ID is combination of WatchkitApp BI and extension string"); LOGGER.info("WatchApp Bundle Identifier Value: "+getWKAppBundleIdentifier()); //String watchkitExtensionBI= getWKAppBundleIdentifier()+"."+appIdSuffix+".watchkitextension"; String watchkitExtensionBI= getWKAppBundleIdentifier()+".watchkitextension"; LOGGER.info("So watchkitExtention BI: "+watchkitExtensionBI); infoPlistAccessor.updateStringValue(PListAccessor.KEY_BUNDLE_IDENTIFIER, watchkitExtensionBI); } catch (IOException e) { throw new MojoExecutionException(e.getMessage(), e); } } static void changeAppId(PListAccessor infoPlistAccessor, String appIdSuffix, String appType) throws MojoExecutionException{ ensurePListFileIsWritable(infoPlistAccessor.getPlistFile()); try { appendAppIdSuffix(infoPlistAccessor, appIdSuffix, appType); } catch (IOException e) { throw new MojoExecutionException(e.getMessage(), e); } } private static void ensurePListFileIsWritable(File pListFile) throws MojoExecutionException { if (!pListFile.canWrite()) { if (!pListFile.setWritable(true, true)) throw new MojoExecutionException("Could not make plist file '" + pListFile + "' writable."); LOGGER.info("Made PList file '" + pListFile + "' writable."); } } private static void appendAppIdSuffix(PListAccessor infoPlistAccessor, String appIdSuffix, String appType) throws IOException { String newAppId; if (appType == null || "".equals(appType.trim())) { String originalAppId = infoPlistAccessor.getStringValue(PListAccessor.KEY_BUNDLE_IDENTIFIER); newAppId = originalAppId + "." + appIdSuffix; LOGGER.info("Original AppId value : "+ originalAppId); LOGGER.info("New upated AppID value: "+ newAppId); setWKCompanionAppBundleIdentifier(newAppId); String CFBundleName = infoPlistAccessor.getStringValue("CFBundleName"); LOGGER.info("CFBundleName : "+ CFBundleName); }else{ newAppId = injectAppIdSuffix(appIdSuffix, infoPlistAccessor); } infoPlistAccessor.updateStringValue(PListAccessor.KEY_BUNDLE_IDENTIFIER, newAppId); LOGGER.info("PList file '" + infoPlistAccessor.getPlistFile() + "' updated: Set AppId to '" + newAppId + "'."); } private static String injectAppIdSuffix(String appIdSuffix, PListAccessor infoPlistAccessor) throws IOException { String originalAppId = infoPlistAccessor.getStringValue(PListAccessor.KEY_BUNDLE_IDENTIFIER); String firstPart= originalAppId.substring(0,originalAppId.lastIndexOf(".")); String lastPart = originalAppId.substring(originalAppId.lastIndexOf(".")+ 1); String newAppId = firstPart + "." + appIdSuffix + "." + lastPart; LOGGER.info("Original AppId value : "+ originalAppId); LOGGER.info("New updated AppID value: "+ newAppId); return newAppId; } private static void changePlistKeyValue(File plist, String key, String value) throws MojoExecutionException, IOException{ PListAccessor infoPlistAccessor = new PListAccessor(plist); ensurePListFileIsWritable(infoPlistAccessor.getPlistFile()); infoPlistAccessor.updateStringValue(key, value); LOGGER.info("PList file '" + plist.getAbsolutePath() + "' updated: Set " + "Key " + key + "and Value " + value); } public static String getWKCompanionAppBundleIdentifier() { return wkCompanionAppBundleIdentifier; } public static void setWKCompanionAppBundleIdentifier(String wKCompanionAppBundleIdentifier) { wkCompanionAppBundleIdentifier = wKCompanionAppBundleIdentifier; } public static String getWKAppBundleIdentifier() { return wkAppBundleIdentifier; } public static void setWKAppBundleIdentifier(String wKAppBundleIdentifier) { wkAppBundleIdentifier = wKAppBundleIdentifier; } public static String getCFBundleShortVersionString() { return cfBundleShortVersionString; } public static void setCFBundleShortVersionString(String cFBundleShortVersionString) { cfBundleShortVersionString = cFBundleShortVersionString; } public static String getCFBundleVersion() { return cfBundleVersion; } public static void setCFBundleVersion(String cFBundleVersion) { cfBundleVersion = cFBundleVersion; } public static String getWatchkitAppBundleIdentifier() { return watchkitAppBundleIdentifier; } public static void setWatchkitAppBundleIdentifier(String watchkitAppBundleIdentifier) { XCodeChangeAppIDMojo.watchkitAppBundleIdentifier = watchkitAppBundleIdentifier; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy