CLI: added the 'package web project cli module' 06/13706/1
authorshingil.kang <shingil.kang@samsung.com>
Thu, 12 Dec 2013 14:53:48 +0000 (23:53 +0900)
committershingil.kang <shingil.kang@samsung.com>
Thu, 12 Dec 2013 14:56:37 +0000 (23:56 +0900)
initial commit

Change-Id: I444eadb7c446e3d944af40e04e51441ecbb45b7a
Signed-off-by: shingil.kang <shingil.kang@samsung.com>
org.tizen.ncli.ide/src/org/tizen/ncli/ide/autocomplete/TizenAutoComplete.java
org.tizen.ncli.ide/src/org/tizen/ncli/ide/shell/Main.java
org.tizen.ncli.ide/src/org/tizen/ncli/ide/shell/PackageCLI.java [new file with mode: 0644]
org.tizen.ncli.ide/src/org/tizen/ncli/ide/subcommands/PackageCLICommand.java [new file with mode: 0644]
org.tizen.ncli.ide/src/org/tizen/ncli/ide/subcommands/PackageCLICommandData.java [new file with mode: 0644]

index 44057fd..d3bb59e 100644 (file)
@@ -77,6 +77,7 @@ public class TizenAutoComplete {
         architecture(options[1][0], "--arch", "x86 arm"),
         compiler(options[1][0], "--compiler", "llvm gcc"),
         configuration(options[1][0], "--configuration", "Debug Release DA"),
+        type(options[4][0], "--type", "wgt tpk"),
         webtemplate(subCommands[1][0], optionsForSub[0][0], "-t", ""),
         nativetemplate(subCommands[1][0], optionsForSub[1][0], "-t", "");
 
@@ -306,6 +307,7 @@ public class TizenAutoComplete {
         case architecture:
         case compiler:
         case configuration:
+        case type:
             suggestion = optionFortSuggestion.getSuggestion();
             break;
         case webtemplate:
index 0e93e77..c082af9 100644 (file)
@@ -44,6 +44,7 @@ public class Main {
             @SubCommand(name = "build-web", impl = BuildWebCLI.class),
             @SubCommand(name = "sign", impl = SignCLI.class),
             @SubCommand(name = "cli-config", impl = ConfigCLI.class),
+            @SubCommand(name = "package", impl = PackageCLI.class),
             @SubCommand(name = "install", impl = InstallCLI.class),
             @SubCommand(name = "uninstall", impl = UninstallCLI.class),
             @SubCommand(name = "run", impl = RunCLI.class),
diff --git a/org.tizen.ncli.ide/src/org/tizen/ncli/ide/shell/PackageCLI.java b/org.tizen.ncli.ide/src/org/tizen/ncli/ide/shell/PackageCLI.java
new file mode 100644 (file)
index 0000000..656968e
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * IDE
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Shingil Kang <shingil.kang@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ * 
+ * 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.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ */
+package org.tizen.ncli.ide.shell;
+
+import java.io.IOException;
+
+import org.kohsuke.args4j.Option;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.tizen.ncli.core.TizenSubCommand;
+import org.tizen.ncli.ide.subcommands.PackageCLICommand;
+import org.tizen.ncli.ide.subcommands.PackageCLICommandData;
+
+@TizenSubCommand(name = "Package", usage = "Package tizen project")
+public class PackageCLI extends AbstractCLI
+{
+    private Logger log = LoggerFactory.getLogger(getClass());
+    
+    @Option(name = "--type", metaVar = "tpk | wgt", usage = "packaging type")
+    private String type;
+
+    @Option(name = "--sign", usage = "Specify profile name")
+    private String sign;
+
+    @Override
+    public void execute()
+    {
+        log.trace("Execute PackageCLI...");
+        PackageCLICommand packageCommand = new PackageCLICommand();
+        
+        log.trace("getRealWorkingPath: {}",getRealWorkingPath());
+        packageCommand.setWorkingDir(getRealWorkingPath());
+        
+        PackageCLICommandData data = null;
+
+        if (type.equals("wgt"))
+        {
+            data = packageCommand.runCommand();
+        }
+        else if (type.equals("tpk"))
+        {
+            // todo
+        }
+        if (null != data)
+        {
+            String wgtPath = data.getWgtPath();
+            if (null != wgtPath)
+                progressLog.info("Package File Location: {}", data.getWgtPath());
+        }
+    }
+
+}
diff --git a/org.tizen.ncli.ide/src/org/tizen/ncli/ide/subcommands/PackageCLICommand.java b/org.tizen.ncli.ide/src/org/tizen/ncli/ide/subcommands/PackageCLICommand.java
new file mode 100644 (file)
index 0000000..6d86ef5
--- /dev/null
@@ -0,0 +1,326 @@
+/*
+ * IDE
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Shingil Kang <shingil.kang@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ *
+ * 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.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ */
+package org.tizen.ncli.ide.subcommands;
+
+import static org.tizen.common.util.FilenameUtil.getRelativePath;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.tizen.common.Factory;
+import org.tizen.common.FactoryWithArgument;
+import org.tizen.common.builder.Resource;
+import org.tizen.common.builder.ResourceLayer;
+import org.tizen.common.core.command.ExecutionContext;
+import org.tizen.common.core.command.Executor;
+import org.tizen.common.core.command.policy.PolicyRegistry;
+import org.tizen.common.core.command.prompter.NopPrompter;
+import org.tizen.common.core.command.zip.ZipCommand;
+import org.tizen.common.file.FileHandler;
+import org.tizen.common.file.Filter;
+import org.tizen.common.file.SimpleFileFilter;
+import org.tizen.common.file.StandardFileHandler;
+import org.tizen.common.file.VirtualFileHandler;
+import org.tizen.common.file.FileHandler.Attribute;
+import org.tizen.common.file.filter.WildCardFilterFactory;
+import org.tizen.common.util.CollectionUtil;
+import org.tizen.common.util.FileUtil;
+import org.tizen.common.util.FilenameUtil;
+import org.tizen.common.util.IOUtil;
+import org.tizen.web.common.WebConstant;
+
+public class PackageCLICommand extends AbstractSubCommand<PackageCLICommandData>
+{
+    protected FileHandler fileHandler = new StandardFileHandler();
+    protected String projectPath;
+    protected String projectName;
+    protected static final String TIZEN_WEB_CONFIG_FILE = "config.xml";
+    protected static final String SIGNATURE_FILE = "signature1.xml";
+    protected static final String AUTHOR_SIGNATURE_FILE = "author-signature.xml";
+
+    protected PackageCLICommandData data = new PackageCLICommandData();
+    protected SimpleFileFilter filter = new SimpleFileFilter(true);
+    protected FactoryWithArgument<Filter, String> filterFactory = new WildCardFilterFactory();
+
+    protected static final String RESOURCE_LAYER_START = "start";
+
+    @Override
+    protected PackageCLICommandData call()
+    {
+        // get project path
+        try
+        {
+            projectPath = workingDir.getCanonicalPath();
+        } catch (IOException e)
+        {
+            log.error("Error occured during setting working directory", e.getMessage());
+        }
+        log.debug("Base project directory: {}", projectPath);
+
+        // get project name
+        projectName = findAndGetFileName(workingDir, TIZEN_WEB_CONFIG_FILE);
+        if (projectName == null)
+        {
+            progressLog.error("Not found tizen web project directory");
+            return null;
+        }
+
+        // check if signature files exist
+        String fileName = findAndGetFileName(workingDir, SIGNATURE_FILE);
+        if (fileName == null)
+            progressLog.info("Warning: Not found tizen signature file");
+
+        String authorFileName = findAndGetFileName(workingDir, AUTHOR_SIGNATURE_FILE);
+        if (authorFileName == null)
+            progressLog.info("Warning: Not found tizen author signature file");
+
+        // set wgt file path
+        String wgtPath = projectPath + File.separatorChar + projectName + "." + WebConstant.WIDGET_FILE_EXTENSION;
+        data.setWgtPath(wgtPath);
+        log.debug("Widget path: {}", wgtPath);
+
+        // set excluding files
+        String[] excludes = getDefaultExcludes();
+        log.debug("Excludes File Pattern: {}", CollectionUtil.toString(excludes));
+        progressLog.info("Excludes File Pattern: {}", CollectionUtil.toString(excludes));
+
+        ResourceLayer startLayer = new ResourceLayer("start", new VirtualFileHandler());
+
+        // get resource file
+        Resource[] resources = null;
+        try
+        {
+            resources = getResources(projectPath, startLayer, null, excludes);
+        } catch (IOException e)
+        {
+            log.error("Error occured during reading resource", e.getMessage());
+        }
+
+        // zip files
+        zipFiles(wgtPath, projectPath, resources);
+
+        return data;
+    }
+
+    private String findAndGetFileName(File baseDir, String fileName)
+    {
+        File[] filesAndDirs = baseDir.listFiles();
+
+        if (null == filesAndDirs)
+        {
+            return null;
+        }
+
+        for (File file : filesAndDirs)
+        {
+            String name = file.getName();
+            if (name.equals(fileName) && file.isFile())
+            {
+                return baseDir.getName();
+            }
+        }
+        return null;
+    }
+
+    private Resource[] getResources(String baseDir, ResourceLayer resourceLayer, String[] includes, String[] excludes) throws IOException
+    {
+        List<File> files = FileUtil.findFiles(new File(baseDir), ".*", true);
+        List<Resource> resources = new ArrayList<Resource>();
+        FileHandler fh = resourceLayer.getFileHandler();
+
+        setIncludes(includes);
+        setExcludes(excludes);
+
+        for (File file : files)
+        {
+            String filePath = file.getPath();
+            if (!FilenameUtil.equals(filePath, baseDir) && !filter.accept(baseDir, getRelativePath(baseDir, filePath)))
+            {
+                log.debug("Ignore File: {}", filePath);
+                progressLog.info("Ignore File: {}", filePath);
+                continue;
+            }
+
+            Resource resource = new Resource(resourceLayer, filePath);
+
+            String dir = null;
+            if (file.isFile())
+            {
+                dir = file.getParent();
+            }
+            else
+            {
+                dir = filePath;
+            }
+
+            if (!fh.is(dir, Attribute.EXISTS))
+            {
+                fh.makeDirectory(dir, true);
+            }
+
+            InputStream is = null;
+            try
+            {
+                is = new FileInputStream(file);
+                resource.setContents(is);
+                resources.add(resource);
+            } finally
+            {
+                IOUtil.tryClose(is);
+            }
+        }
+        return resources.toArray(new Resource[resources.size()]);
+    }
+
+    /**
+     * Set including file name patterns
+     *
+     * @param includes
+     *            including file name patterns
+     */
+    public void setIncludes(final String[] includes)
+    {
+        filter.clearIncludes();
+        if (null != includes)
+        {
+            for (final String include : includes)
+            {
+                filter.addIncludes(filterFactory.create(include));
+            }
+        }
+    }
+
+    /**
+     * Set excluding file name patterns
+     *
+     * @param excludes
+     *            excluding file name patterns
+     */
+    public void setExcludes(final String[] excludes)
+    {
+        filter.clearExcludes();
+        if (null != excludes)
+        {
+            for (final String exclude : excludes)
+            {
+                filter.addExcludes(filterFactory.create(exclude));
+            }
+        }
+    }
+
+    /**
+     * Archive <code>baseDir</code> to <code>wgtPath</code> including
+     * <code>includes</code> and excluding <code>excludes</code>
+     *
+     * @param wgtPath
+     *            wgt file path
+     * @param baseDir
+     *            directory to root
+     * @param includes
+     *            includes file pattern
+     * @param excludes
+     *            excludes file pattern
+     */
+    private void zipFiles(final String wgtPath, final String baseDir, final Resource[] resources)
+    {
+        final ZipCommand command = new ZipCommand(baseDir, resources, wgtPath);
+
+        // get Executor
+        final Executor executor = new Executor(new Factory<ExecutionContext>()
+        {
+            public ExecutionContext create()
+            {
+                return new ExecutionContext(new PolicyRegistry(), new NopPrompter(), fileHandler);
+            }
+        });
+
+        executor.execute(command);
+    }
+
+    /**
+     * Check if <code>path</code> exists
+     *
+     * @param path
+     *            file path
+     *
+     * @return <code>true</code> if <code>path</code> exists
+     *
+     * @throws IOException
+     *             If <code>path</code> can't be accessed
+     */
+    protected boolean exists(final String path) throws IOException
+    {
+        return fileHandler.is(path, Attribute.EXISTS);
+    }
+
+    /**
+     * Check if <code>path</code> is Tizen web project root
+     *
+     * @param path
+     *            directory path to check
+     *
+     * @return <code>true</code> if <code>path</code> is Tize web project root
+     * @throws IOException
+     *             If <code>path</code>'s sub files can't be accessed
+     */
+    protected boolean isValidRoot(final String path) throws IOException
+    {
+        final String projectFilePath = FilenameUtil.addTailingPath(path, ".project");
+        return fileHandler.is(projectFilePath, Attribute.EXISTS);
+    }
+
+    /**
+     * Return default excludes file patterns
+     *
+     * @return default excludes file patterns
+     */
+    protected String[] getDefaultExcludes()
+    {
+        return new String[] { ".*", "*.wgt", "*~" };
+    }
+
+    /**
+     * Archive <code>baseDir</code> to <code>wgtPath</code>
+     *
+     * including <code>includes</code> and excluding <code>excludes</code>
+     *
+     * @param wgtPath
+     *            wgt file path
+     * @param baseDir
+     *            directory to root
+     * @param includes
+     *            includes file pattern
+     * @param excludes
+     *            excludes file pattern
+     */
+    protected void zipFiles(final String wgtPath, final String baseDir)
+    {
+        zipFiles(wgtPath, baseDir, null);
+    }
+}
\ No newline at end of file
diff --git a/org.tizen.ncli.ide/src/org/tizen/ncli/ide/subcommands/PackageCLICommandData.java b/org.tizen.ncli.ide/src/org/tizen/ncli/ide/subcommands/PackageCLICommandData.java
new file mode 100644 (file)
index 0000000..fb77ac0
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * IDE
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Shingil Kang <shingil.kang@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ *
+ * 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.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ */
+package org.tizen.ncli.ide.subcommands;
+
+public class PackageCLICommandData
+{
+    protected String wgtPath;
+
+    public String getWgtPath()
+    {
+        return wgtPath;
+    }
+
+    public void setWgtPath(String projectPath)
+    {
+        this.wgtPath = projectPath;
+    }
+}