From 8c5c47202f3ea84aa122c7ebbcc0ffb5a3df9155 Mon Sep 17 00:00:00 2001 From: Taeyoung Son Date: Mon, 7 Oct 2013 15:14:49 +0900 Subject: [PATCH] BUILD: WEB: Supported hybrid multi app Supported building hybrid multi app. Modified web-build cli's option. Added NativeMultiPackager class. Added build/install dependency for using native multi packager Signed-off-by: Taeyoung Son Conflicts: package/pkginfo.manifest Change-Id: I795968f7f3478239a3012c9dc1c2f6ea2579316c --- .../org/tizen/cli/exec/pack/CLIMultiPackager.java | 16 +- .../src/org/tizen/cli/exec/web/build/Main.java | 175 ++++++++++++++++----- .../cli/exec/web/build/NativeMultiPackager.java | 154 ++++++++++++++++++ package/build.linux | 2 + package/pkginfo.manifest | 20 +-- 5 files changed, 311 insertions(+), 56 deletions(-) create mode 100644 org.tizen.cli/src/org/tizen/cli/exec/web/build/NativeMultiPackager.java diff --git a/org.tizen.cli/src/org/tizen/cli/exec/pack/CLIMultiPackager.java b/org.tizen.cli/src/org/tizen/cli/exec/pack/CLIMultiPackager.java index f105f6e..67ed20b 100644 --- a/org.tizen.cli/src/org/tizen/cli/exec/pack/CLIMultiPackager.java +++ b/org.tizen.cli/src/org/tizen/cli/exec/pack/CLIMultiPackager.java @@ -37,15 +37,19 @@ import org.tizen.nativecpp.misc.core.NewAppXmlStore; public class CLIMultiPackager extends AbstractMultiPackager{ public static final String BIN_FOLDER_NAME = "CommandLineBuild"; - private String rootPrjPath; - private String[] refPrjPath; - - CLIMultiPackager(String rootPrjPath, String[] refPrjPath, Executor executor) { - super(executor); + protected String rootPrjPath; + protected String[] refPrjPath; + + public CLIMultiPackager(String outputPath, String rootPrjPath, String[] refPrjPath, Executor executor) { + super(executor, outputPath); this.rootPrjPath = rootPrjPath; this.refPrjPath = refPrjPath; } - + + public CLIMultiPackager(String rootPrjPath, String[] refPrjPath, Executor executor) { + this(null, rootPrjPath, refPrjPath, executor); + } + @Override protected String getBinaryFolder() { return BIN_FOLDER_NAME; diff --git a/org.tizen.cli/src/org/tizen/cli/exec/web/build/Main.java b/org.tizen.cli/src/org/tizen/cli/exec/web/build/Main.java index dd2118e..c5afc84 100755 --- a/org.tizen.cli/src/org/tizen/cli/exec/web/build/Main.java +++ b/org.tizen.cli/src/org/tizen/cli/exec/web/build/Main.java @@ -36,12 +36,14 @@ import org.apache.commons.cli.Options; import org.apache.tools.ant.BuildException; import org.tizen.cli.exec.AbstractLauncher; import org.tizen.cli.exec.Help; +import org.tizen.cli.exec.pack.CLIMultiPackager; import org.tizen.common.FactoryWithArgument; import org.tizen.common.builder.BuildProcess; import org.tizen.common.builder.Builder; import org.tizen.common.builder.Resource; import org.tizen.common.builder.ResourceLayer; import org.tizen.common.builder.core.CopyBuilder; +import org.tizen.common.core.command.CommandCancelException; import org.tizen.common.file.FileHandler; import org.tizen.common.file.FileHandler.Attribute; import org.tizen.common.file.Filter; @@ -72,7 +74,9 @@ extends AbstractLauncher private static final String SUCCEED_MSG = "Build completed. In sequence you can sign on your build output folder(default:{0}) using the web-signing command."; private String cwd = "."; - private String output = ".buildResult"; //default output directory + + private String BUILD_DEFAULT_OUTPUT = ".buildResult"; + private String output = BUILD_DEFAULT_OUTPUT; //default output directory private SimpleFileFilter filter = new SimpleFileFilter(true); private FactoryWithArgument filterFactory = new WildCardFilterFactory(); @@ -109,15 +113,18 @@ extends AbstractLauncher protected static final String RESOURCE_LAYER_END = "end"; // file filter. If you want to exclude a directory, append '/*' - private static final String[] DEFAULT_EXCLUDES = {".build"+File.separator+"*" + private static final String[] DEFAULT_EXCLUDES = {".build/*" , ".project" - , ".settings" + File.separator + "*" + , ".settings/*" , ".sdk_delta.info" - , "*.wgt"}; + , "*.wgt" + , ".buildResult/*"}; // excluding file list private List excludes = new ArrayList(); + private String[] referenceProjects = null; + /** * Entry point for cli main * @@ -160,7 +167,6 @@ extends AbstractLauncher * @see org.tizen.cli.exec.AbstractLauncher#execute(org.apache.commons.cli.CommandLine) */ @Override - @SuppressWarnings("unchecked") protected void execute( @@ -168,13 +174,59 @@ extends AbstractLauncher ) throws Exception { + init(cmdLine); + + CLIMultiPackager nativePackager = null; + + nativePackager = createNativeMultiAppStructure(output, getReferenceProjects()); + + BuildProcess buildProcess = new BuildProcess(); + + // Set start layer + FileHandler fh = new StandardFileHandler(); + fh.setCurrentWorkingDirectory(cwd); + ResourceLayer startLayer = new ResourceLayer(RESOURCE_LAYER_START, fh); + + // Get resource list for build + Resource[] resources = getBuildResources(cmdLine + , startLayer + , null + , excludes.toArray(new String[excludes.size()])); + + // Generate web builders to build process + generateAllBuilders(cmdLine, buildProcess, startLayer); + + if (buildProcess.getLastBuilder() != null) { + logger.debug("start build process"); + try { + buildProcess.build(resources); + } catch (MinifyException e) { + StringBuffer msg = new StringBuffer(); + msg.append("Optimization failed.\n"); + msg.append("Error: "+ e.getPath()+"("+e.getLineNumber()+"): "+e.getLineSource()+"\n"); + msg.append("Cause: "+e.getMessage()+"\n"); + getPrompter().notify(msg.toString()); + return; + } + + if (nativePackager != null) { + nativePackager.removeMutilAppResources(); + } + + // check succeeding status. + checkProcessComplete( buildProcess ); + } + } + + @SuppressWarnings("unchecked") + private void init(CommandLine cmdLine) throws Exception{ final List args = cmdLine.getArgList(); logger.trace( "arguments :{}", args ); // input path's argument will be set. if (args.size() < 1) { printHelp(); - return; + throw new BuildException("Could not find project path."); } // set absolute path @@ -197,40 +249,70 @@ extends AbstractLauncher logger.info( "{} directory deleted", output); } + if (!FileUtil.createDirectory(output)) { + throw new BuildException("Could not create "+output+" directory..."); + } + // Set exclude file list initExcludes(cmdLine); + setReferenceProjects(cmdLine); + } - BuildProcess buildProcess = new BuildProcess(); + /** + * Create native multi application structure. + * @param output output path + * @param refProjectPaths array's first value is root reference project. + * @return If refProjectPaths's length is 1, it return null. or, it return {@link CLIMultiPackager}. + * @throws Exception + */ + private CLIMultiPackager createNativeMultiAppStructure(String output, String ... refProjectPaths) throws Exception { + if ((refProjectPaths == null) + || (refProjectPaths.length <= 1)) { + return null; + } - // Set start layer - FileHandler fh = new StandardFileHandler(); - fh.setCurrentWorkingDirectory(cwd); - ResourceLayer startLayer = new ResourceLayer(RESOURCE_LAYER_START, fh); - - // Get resource list for build - Resource[] resources = getBuildResources(cmdLine - , startLayer - , null - , excludes.toArray(new String[excludes.size()])); + String rootRefProjectPath = refProjectPaths[0]; - // Generate web builders to build process - generateAllBuilders(cmdLine, buildProcess, startLayer); - if (buildProcess.getLastBuilder() != null) { - logger.debug("start build process"); - try { - buildProcess.build(resources); - } catch (MinifyException e) { - StringBuffer msg = new StringBuffer(); - msg.append("Optimization failed.\n"); - msg.append("Error: "+ e.getPath()+"("+e.getLineNumber()+"): "+e.getLineSource()+"\n"); - msg.append("Cause: "+e.getMessage()+"\n"); - getPrompter().notify(msg.toString()); - return; - } + List subRefProjectPaths = new ArrayList(); + for (int i=1;i 1)) { + refPath = FileUtil.appendPath(output, NativeMultiPackager.FOLDER_MULTIAPP_TEMP); + } else { + refPath = convertPath(cmdLine.getOptionValue(OPT_NAME_REFERENCE_PROJECT)); + } + HybridAppCLIBuilder hybridAppBuilder = new HybridAppCLIBuilder( layer, refPath ); buildProcess.addBuilder(hybridAppBuilder); } @@ -427,11 +515,18 @@ extends AbstractLauncher ResourceLayer referenceLayer = new ResourceLayer(HybridAppCLIBuilder.RESOURCE_LAYER_REFERENCE_NAME , refFh); layer.setParent(referenceLayer); - String refPath = convertPath(cmdLine.getOptionValue(OPT_NAME_REFERENCE_PROJECT)); - refFh.setCurrentWorkingDirectory(refPath); + String refRootPath = null; + String[] refProjects = getReferenceProjects(); + if ((refProjects != null) + && refProjects.length > 1) { + refRootPath = FileUtil.appendPath(output, NativeMultiPackager.FOLDER_MULTIAPP_TEMP); + } else { + refRootPath = convertPath(cmdLine.getOptionValue(OPT_NAME_REFERENCE_PROJECT)); + } + refFh.setCurrentWorkingDirectory(refRootPath); - resources.addAll(getResources(refPath - , FilenameUtil.getRelativePath(refPath, refPath) + resources.addAll(getResources(refRootPath + , FilenameUtil.getRelativePath(refRootPath, refRootPath) , referenceLayer)); } diff --git a/org.tizen.cli/src/org/tizen/cli/exec/web/build/NativeMultiPackager.java b/org.tizen.cli/src/org/tizen/cli/exec/web/build/NativeMultiPackager.java new file mode 100644 index 0000000..c2e78f5 --- /dev/null +++ b/org.tizen.cli/src/org/tizen/cli/exec/web/build/NativeMultiPackager.java @@ -0,0 +1,154 @@ +package org.tizen.cli.exec.web.build; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +import org.apache.tools.ant.BuildException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.tizen.cli.exec.pack.CLIMultiPackager; +import org.tizen.common.TizenPlatformConstants; +import org.tizen.common.core.command.CommandCancelException; +import org.tizen.common.core.command.Executor; +import org.tizen.common.util.FileUtil; +import org.tizen.nativecpp.misc.core.NewAppXmlStore; +import org.tizen.web.builder.HybridAppCLIBuilder; + +public class NativeMultiPackager extends CLIMultiPackager { + Logger logger = LoggerFactory.getLogger(getClass()); + + public static final String FILE_NAME_MANIFEST = TizenPlatformConstants.MANIFEST_XML_FILE_NAME; + + public NativeMultiPackager(String outputPath, String rootPrjPath, String[] refPrjPath, + Executor executor) { + super(outputPath, rootPrjPath, refPrjPath, executor); + } + + @Override + protected void mergeApplicationXML() throws Exception{ + super.mergeApplicationXML(); + + //Rename multi manifest file + String srcPath = FileUtil.appendPath(getOutputPath(), FILE_NAME_MULTI_MANIFEST); + String destPath = FileUtil.appendPath(getOutputPath(), FOLDER_MULTIAPP_TEMP); + File destDir = new File(destPath); + destDir.mkdir(); + + destPath = FileUtil.appendPath(destPath, FILE_NAME_MANIFEST); + + File srcFile = new File(srcPath); + srcFile.renameTo(new File(destPath)); + } + + @Override + protected void copyBinaries() throws IOException { + super.copyBinaries(); + + // copy root reference project's binaries. + String tempMultiPath = FileUtil.appendPath(getOutputPath(), FOLDER_MULTIAPP_TEMP); + String tempBinPath = FileUtil.appendPath(tempMultiPath, FOLDER_MULTIAPP_TEMP_BIN); + + File tempBinDir = new File(tempBinPath); + tempBinDir.mkdirs(); + + String rootPrjPath = getRootPrjPath(); + List binaryList = getExecutableBinaries(rootPrjPath); + + String binaryFolder = getBinaryFolder(rootPrjPath); + String rootPrjBinaryFolder = FileUtil.appendPath(rootPrjPath, binaryFolder); + + for(String binary: binaryList) { + String binaryName = binary + EXT_BINARY_EXECUTABLE; + String binaryPath = FileUtil.appendPath(rootPrjBinaryFolder, binaryName); + File binaryFile = new File(binaryPath); + if(!binaryFile.exists()) { + String message = String.format("binary file '%s' does not exist", binaryPath); + logger.error(message); + throw new CommandCancelException(message); + } + FileUtil.copyTo(binaryFile.getAbsolutePath(), FileUtil.appendPath(tempBinPath, binaryName)); + } + } + + /** + * Get executable binary list from manifest file + * @param rootPrjPath + * @return executable binary list + */ + private List getExecutableBinaries(String rootPrjPath) { + NewAppXmlStore store = new NewAppXmlStore(); + + String manifestPath = FileUtil.appendPath(rootPrjPath, FILE_NAME_MANIFEST); + store.setManifestFile(manifestPath); + store.loadXml(); + return store.getExecutableNames(); + } + + @Override + public void doMultiPreProcess() throws Exception { + super.doMultiPreProcess(); + + //Rename folder + String tempOutputPath = FileUtil.appendPath(getOutputPath(), FOLDER_MULTIAPP_TEMP); + + String srcPath = FileUtil.appendPath(tempOutputPath, FOLDER_MULTIAPP_TEMP_BIN); + String destPath = FileUtil.appendPath(tempOutputPath, FOLDER_BIN); + renameTo(srcPath, destPath); + + srcPath = FileUtil.appendPath(tempOutputPath, FOLDER_MULTIAPP_TEMP_RES); + destPath = FileUtil.appendPath(tempOutputPath, FOLDER_RES); + renameTo(srcPath, destPath); + + srcPath = FileUtil.appendPath(tempOutputPath, FOLDER_MULTIAPP_TEMP_DATA); + destPath = FileUtil.appendPath(tempOutputPath, FOLDER_DATA); + renameTo(srcPath, destPath); + + srcPath = FileUtil.appendPath(tempOutputPath, FOLDER_MULTIAPP_TEMP_SHARE); + destPath = FileUtil.appendPath(tempOutputPath, FOLDER_SHARE); + renameTo(srcPath, destPath); + } + + /** + * rename directory or file + * @param srcPath + * @param destPath + */ + private void renameTo(String srcPath, String destPath) { + if ((srcPath==null) + || (destPath==null)) { + throw new BuildException("Could not rename path"); + } + + File srcFile = new File(srcPath); + if (srcFile.exists() && (!srcFile.renameTo(new File(destPath)))) { + throw new BuildException("Could not rename path"); + } + } + + /** + * Get binary folder + * @param prjPath project's root path + * @return binary folder what have latest binary file. + * If the project does not have binary file, it return default binary folder. + */ + @Override + protected String getBinaryFolder(String prjPath) { + List binaryList = getExecutableBinaries(prjPath); + String result = BIN_FOLDER_NAME; + long tmpDate = 0; + + for (String tmpBin : HybridAppCLIBuilder.NATIVE_BINARY_FOLDER) { + String binaryDir = FileUtil.appendPath(prjPath, tmpBin); + for (int i=0; itmpDate)) { + tmpDate = f.lastModified(); + result = tmpBin; + } + } + } + return result; + } +} diff --git a/package/build.linux b/package/build.linux index 10fd8a7..9126836 100755 --- a/package/build.linux +++ b/package/build.linux @@ -81,6 +81,8 @@ build() org.tizen.common.verrari_* org.tizen.common.verrari.realm_* org.tizen.common.sdblib_* + org.tizen.nativecommon_* + org.tizen.nativecpp.misc_* org.tizen.web.builder_* org.tizen.web.compressor.minifier.core_* org.tizen.web.zimlaunch_* diff --git a/package/pkginfo.manifest b/package/pkginfo.manifest index aa36c5e..ba49448 100644 --- a/package/pkginfo.manifest +++ b/package/pkginfo.manifest @@ -4,36 +4,36 @@ Maintainer: Bon-Yong Lee, gyeongseok seo