[Title] Add command, enhance help page, and add makefile command in native-gen
authorho.namkoong <ho.namkoong@samsung.com>
Sat, 30 Mar 2013 13:23:41 +0000 (22:23 +0900)
committerho.namkoong <ho.namkoong@samsung.com>
Mon, 1 Apr 2013 01:54:59 +0000 (10:54 +0900)
[Type]
[Module]
[Priority]
[Jira#]
[Redmine#] 8901, 8871
[Problem]
[Cause]
[Solution]
[TestCase]

Change-Id: I830c52c5a421e3c7428b6f218e4e619ad2145658

org.tizen.cli/META-INF/MANIFEST.MF
org.tizen.cli/src/org/tizen/cli/exec/AbstractLauncher.java
org.tizen.cli/src/org/tizen/cli/exec/Help.java
org.tizen.cli/src/org/tizen/cli/exec/gen/NativeMain.java
org.tizen.cli/src/org/tizen/cli/exec/gen/messages.properties

index 5030c6e..7106b22 100755 (executable)
@@ -22,6 +22,7 @@ Import-Package: org.tizen.nativecommon,
  org.tizen.nativecommon.templateengine,
  org.tizen.nativecommon.templateengine.build,
  org.tizen.nativecommon.templateengine.build.model,
+ org.tizen.nativecommon.templateengine.build.util,
  org.tizen.nativecommon.templateengine.model,
  org.tizen.nativecommon.templateengine.process,
  org.tizen.nativecommon.templateengine.util,
index 55d84cd..505b37e 100755 (executable)
@@ -175,6 +175,11 @@ AbstractLauncher
        protected Executor executor; 
 
        /**
+        * A command user inputs
+        */
+       protected String inputCmd = "";
+       
+       /**
         * Convert <code>path</code> to canonical path
         * 
         * @param path relative or abstract path
@@ -223,6 +228,19 @@ AbstractLauncher
                return options;
        }
 
+       /**
+        * {@link Options} for usage. A command does not use short option name and argument.
+        * 
+        * @return defined {@line Options}
+        */
+       protected
+       Options
+       getCommands()
+       {
+               final Options options = new Options();
+               return options;
+       }
+       
        
        /**
         * <p>
@@ -247,38 +265,38 @@ AbstractLauncher
        Help
        getHelp()
        {
-           if ( null == help )
-           {
-               this.help = createHelp();
-               final ClassLoader cl = getClass().getClassLoader();
-               final String resourceName = getClass().getName().replace( '.', '/' ) + SUFFIX_CONFIG;
-               
-               logger.trace( "Resource name :{}", resourceName );
-               try
-            {
-                final Enumeration<URL> iter = cl.getResources( resourceName );
-                while ( iter.hasMoreElements() )
-                {
-                    final URL url = iter.nextElement();
-                    logger.trace( "URL :{}", url );
-                    final Properties properties = PropertyUtil.loadProperties( url.openStream() );
-                    logger.debug( "Properties :{}", properties );
-                    
-                    for ( final Object key : properties.keySet() )
-                    {
-                        final String value = properties.getProperty( (String) key );
-                        byte[] contents = IOUtil.getBytes( cl.getResourceAsStream( value ), true );
-                        this.help.addHelpDetail( (String) key, new String( contents, Charset.forName( "utf8" ) ) );
-                    }
-                }
-            }
-               catch ( final IOException e )
-            {
-                logger.warn( "Can't load help", e );
-            }
-           }
-           
-           return this.help;
+               if ( null == help )
+               {
+                       this.help = createHelp();
+                       final ClassLoader cl = getClass().getClassLoader();
+                       final String resourceName = getClass().getName().replace( '.', '/' ) + SUFFIX_CONFIG;
+                       
+                       logger.trace( "Resource name :{}", resourceName );
+                       try
+                       {
+                               final Enumeration<URL> iter = cl.getResources( resourceName );
+                               while ( iter.hasMoreElements() )
+                               {
+                                       final URL url = iter.nextElement();
+                                       logger.trace( "URL :{}", url );
+                                       final Properties properties = PropertyUtil.loadProperties( url.openStream() );
+                                       logger.debug( "Properties :{}", properties );
+                                       
+                                       for ( final Object key : properties.keySet() )
+                                       {
+                                               final String value = properties.getProperty( (String) key );
+                                               byte[] contents = IOUtil.getBytes( cl.getResourceAsStream( value ), true );
+                                               this.help.addHelpDetail( (String) key, new String( contents, Charset.forName( "utf8" ) ) );
+                                       }
+                               }
+                       }
+                       catch ( final IOException e )
+                       {
+                               logger.warn( "Can't load help", e );
+                       }
+               }
+               
+               return this.help;
        }
        
        /**
@@ -290,9 +308,9 @@ AbstractLauncher
        String
        printHelpDetail( String option )
        {
-           final String detailStr = getHelp().getHelpDetail( option );
-           getPrompter().error( detailStr );
-           return detailStr;
+               final String detailStr = getHelp().getHelpDetail( option );
+               getPrompter().error( detailStr );
+               return detailStr;
        }
        
        /**
@@ -304,7 +322,7 @@ AbstractLauncher
        String
        printHelp()
        {
-           final String helpStr = getHelp().getHelp();
+               final String helpStr = getHelp().getHelp();
                getPrompter().error( helpStr );
                return helpStr;
        }
@@ -339,21 +357,34 @@ AbstractLauncher
        )
        throws Exception
        {
-           Preference.register( "OS", new EnvironmentProvider() );
-           Preference.register( "JVM", new SystemPropertiesProvider() );
+               Preference.register( "OS", new EnvironmentProvider() );
+               Preference.register( "JVM", new SystemPropertiesProvider() );
                executor = new CommandLineExecutor(
                        new ConsolePrompter( System.out, new InputStreamReader( System.in ) )
                );
                if ( logger.isTraceEnabled() )
                {
-                   logger.trace( "OS Environment :\n{}", MapUtil.toString( System.getenv() ) );
+                       logger.trace( "OS Environment :\n{}", MapUtil.toString( System.getenv() ) );
                        logger.trace( "System properties :\n{}", MapUtil.toString( System.getProperties() ) );
                        logger.trace( "Args :{}", CollectionUtil.concatenate( Arrays.asList( args ), "," ) );
                }
                
                try
                {
-                       this.cmd = parse( args );
+                       Options cmds = this.getCommands();
+                       
+                       if(args.length == 0 && isPrintHelp()) {
+                               printHelp();
+                               return;
+                       }
+                       if(cmds.getOptions().size() > 0 && args.length > 0 && cmds.hasOption(args[0])) {
+                               this.inputCmd = args[0];
+                               String[] newArgs = Arrays.copyOfRange(args, 1, args.length);
+                               this.cmd = parse( newArgs);
+                       }
+                       else {
+                               this.cmd = parse( args );
+                       }
                        
                        if ( cmd.hasOption( OPT_QUIET ) )
                        {
@@ -374,7 +405,7 @@ AbstractLauncher
                                
                                for ( String keyword : cmd.getArgs() )
                                {
-                                   printHelpDetail( keyword );
+                                       printHelpDetail( keyword );
                                }
                                return ;
                        }
@@ -417,6 +448,15 @@ AbstractLauncher
                }
        }
        
+          /**
+        * Gets a command that user inputs.
+        *
+        * @return a command user inputs
+        */
+       protected String getInputCmd() {
+               return this.inputCmd;
+       }
+
        /**
         * Handle uncaught exception
         * 
@@ -428,26 +468,26 @@ AbstractLauncher
                final Throwable e
        )
        {
-           getPrompter().error( e.getMessage() );
-           logger.error( "Command stop because of exception", e );
-           Throwable iter = e;
-           while ( null != iter )
-           {
-               final String localMessage = iter.getLocalizedMessage();
-               if ( null != localMessage )
-               {
-                   logger.error( localMessage );
-                   exit( 1 );
-               }
+               getPrompter().error( e.getMessage() );
+               logger.error( "Command stop because of exception", e );
+               Throwable iter = e;
+               while ( null != iter )
+               {
+                       final String localMessage = iter.getLocalizedMessage();
+                       if ( null != localMessage )
+                       {
+                               logger.error( localMessage );
+                               exit( 1 );
+                       }
 
-               final String message = iter.getMessage();
-               if ( null != message )
-               {
-                   logger.error( message );
-                   exit( 1 );
-               }
-               iter = iter.getCause();
-           }
+                       final String message = iter.getMessage();
+                       if ( null != message )
+                       {
+                               logger.error( message );
+                               exit( 1 );
+                       }
+                       iter = iter.getCause();
+               }
        }
 
        /**
@@ -630,6 +670,26 @@ AbstractLauncher
        }
 
        /**
+        * Returns whether print help or not if argument is empty.
+        * 
+        * @return returns </code>true</code> if it prints help. Else, <code>false</code>.
+        */
+       protected
+       boolean
+       isPrintHelp() {
+               return false;
+       }
+       
+       /**
+        * Gets the uses description of the CLI. 
+        * 
+        * @return returns usage description string.
+        */
+       protected String getUsageDescription() {
+               return StringUtil.EMPTY_STRING;
+       }
+       
+       /**
         * Terminates the currently running command line interface.<p>
         * The argument serves as a status code<br>
         * by convention, a nonzero status code indicates abnormal termination.<br>
index 3263b9a..fa5c069 100755 (executable)
@@ -29,9 +29,7 @@ import static org.tizen.common.util.StringUtil.nvl;
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
-import java.util.Collection;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 
 import org.apache.commons.cli.HelpFormatter;
@@ -40,6 +38,7 @@ import org.apache.commons.cli.Options;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.tizen.common.util.FilenameUtil;
+import org.tizen.common.util.StringUtil;
 
 /**
  * <p>
@@ -63,6 +62,11 @@ public class Help
      */
     protected static final String PROP_PRG = "cli.name";
     
+    //TODO Other Main classes already modified syntax like: $(script_name) [options].
+    //Therefore, we cannot use syntax using getSyntax()
+    private static final String DEFAULT_SYNTAX = (System.getProperty( PROP_PRG ) != null) ?
+            FilenameUtil.getTailingPath( System.getProperty( PROP_PRG ), 1 ) : StringUtil.EMPTY_STRING;
+    
     /**
      * {@link Options} for Help print-out
      */
@@ -82,6 +86,21 @@ public class Help
     protected HashMap<String, String> keyword2help = new HashMap<String, String>();
     
     /**
+     * commands for Help print-out
+     */
+    protected final Options cmds;
+    
+    /**
+     * a command user inputs.
+     */
+    protected final String inputCmd;
+    
+    /**
+     * a description for usage.
+     */
+    protected final String usageDescription;
+    
+    /**
      * Constructor with {@link Options}
      * 
      * @param opts {@link Options}
@@ -91,7 +110,28 @@ public class Help
         final Options opts
     )
     {
+        this(opts, null, "", "");
+    }
+    
+    /**
+     * A constructor with options, commands, input command and usage description.
+     * 
+     * @param opts
+     * @param cmds
+     * @param inputCmd
+     * @param usageDes
+     */
+    public
+    Help(
+            final Options opts, 
+            final Options cmds, 
+            final String inputCmd, 
+            final String usageDes)
+    {
         this.opts = opts;
+        this.cmds = cmds;
+        this.inputCmd = inputCmd;
+        this.usageDescription = usageDes;
     }
     
     /**
@@ -163,36 +203,179 @@ public class Help
      * 
      * @return usage
      */
-    @SuppressWarnings( "deprecation" )
        public String getHelp()
     {
-        final HelpFormatter formatter = new HelpFormatter();
-        formatter.defaultSyntaxPrefix = "Usage: ";
-        final StringWriter writer = new StringWriter();
-
-        final PrintWriter stream = new PrintWriter( writer );
-
-        final Options options = getOptions();
+        StringBuffer helpBuffer = new StringBuffer();
+        
+        helpBuffer.append("\n");
+        getUsage(helpBuffer);
+        helpBuffer.append("\n");
+        
+        boolean cmdDes = getCmds() != null  & StringUtil.isEmpty(this.getInputCmd());
+        if(cmdDes) {
+            getCommandDescription(helpBuffer);
+            helpBuffer.append("\n");
+        }
+        
+        if(getOptions().getOptions().size() > 0) {
+            getOptionDescription(helpBuffer);
+            helpBuffer.append("\n");
+        }
+        
+        if(cmdDes) {
+            getHelpUsage(helpBuffer);
+            helpBuffer.append("\n");
+        }
+        
+        return helpBuffer.toString();
+    }
+    
+       /**
+        * <p>
+        * Returns a usage for help.
+        * </p> 
+        * 
+        * @param buffer to store help usage
+        * @return help usage
+        */
+    public StringBuffer getHelpUsage(StringBuffer buffer) {
+        String syntax = nvl(DEFAULT_SYNTAX, getSyntax());
+        
+        buffer.append(String.format("For more information on a specific command: '%s <command> -h'" , syntax));
+        return buffer;
+    }
 
-        // print usage
-        formatter.printUsage(stream, formatter.getWidth(), getSyntax() );
+    /**
+     * <p>
+     * Returns a command description.
+     * </p>
+     * 
+     * @param buffer to store a command description
+     * @return a command description
+     */
+    public StringBuffer getCommandDescription(StringBuffer buffer) {
+        Options cmds = getCmds();
+        buffer.append("Commands:\n");
+        getOptionDescriptionWithPrefix(cmds, StringUtil.EMPTY_STRING, StringUtil.EMPTY_STRING, buffer);
+        
+        return buffer;
+    }
 
-        // print options
-        writer.append( "\nOptions:\n" );
+    /**
+     * <p>
+     * Returns a option description.
+     * </p>
+     * 
+     * @param buffer to store a option description
+     * @return a option description
+     */
+    public StringBuffer getOptionDescription(StringBuffer buffer) {
+        Options opts = getOptions();
+        buffer.append("Options:\n");
+        getOptionDescriptionWithPrefix(opts, "-", "--", buffer);
+        
+        return buffer;
+    }
+    
+    /**
+     * <p>
+     * Returns a option description with option prefix and long option prefix.
+     * </p>
+     * 
+     * @param opts options description will describe about
+     * @param optPrefix option prefix
+     * @param longOptPrefix long option prefix
+     * @param buffer to store a option description
+     * @return
+     */
+    public StringBuffer getOptionDescriptionWithPrefix(Options opts, String optPrefix, String longOptPrefix, StringBuffer buffer) {
+        
+        if(opts == null || opts.getOptions().size() == 0) {
+            return buffer;
+        }
+        
+        final StringWriter writer = new StringWriter();
+        final PrintWriter stream = new PrintWriter( writer );
+        final HelpFormatter formatter = new HelpFormatter();
+        
+        formatter.setOptPrefix(optPrefix);
+        formatter.setLongOptPrefix(longOptPrefix);
         formatter.printOptions(
                 stream,
                 formatter.getWidth(),
-                options,
+                opts,
                 formatter.getLeftPadding(),
                 formatter.getDescPadding()
         );
-
-        final String help = writer.toString();
         
-        return help;
+        return buffer.append(writer.toString());
     }
     
     /**
+     * Returns a usage.
+     * 
+     * @param usageBuffer to store usage
+     * @return a usage
+     */
+    public StringBuffer getUsage(StringBuffer usageBuffer) {
+        String syntax = nvl(DEFAULT_SYNTAX, getSyntax());
+        
+        usageBuffer.append(String.format("Usage: %s ", syntax));
+        Options opts = getOptions();
+        Options cmds = getCmds();
+        String inputCmd = getInputCmd();
+        
+        String description = "";
+        if(cmds != null) {
+            Option cmd = cmds.getOption(inputCmd);
+            
+            if(cmd != null) {
+                usageBuffer.append(inputCmd + " ");
+                description = cmd.getDescription();
+            }
+            else {
+                usageBuffer.append("<command> ");
+                description = usageDescription;
+            }
+        }
+        int optionSize = opts.getOptions().size();
+        int reqOptSize = opts.getRequiredOptions().size();
+        
+        if(optionSize > 0 && optionSize != reqOptSize) {
+            usageBuffer.append("[options] ");
+        }
+        
+        getRequiredOptionInUsage(usageBuffer);
+        usageBuffer.append(String.format("\n%s\n", description));
+        return usageBuffer;
+    }
+    
+    private StringBuffer getRequiredOptionInUsage(StringBuffer buffer) {
+        Options opts = getOptions();
+        @SuppressWarnings("unchecked")
+        List<String> requiredOptKeys = opts.getRequiredOptions();
+        
+        for(String key: requiredOptKeys) {
+            Option opt = opts.getOption(key);
+            buffer.append(String.format("-%s ", opt.getOpt()));
+            
+            if(opt.hasArg()) {
+                buffer.append(String.format("<%s> ", opt.getArgName()));
+            }
+        }
+        
+        return buffer;
+    }
+    
+    public Options getCmds() {
+        return cmds;
+    }
+    
+    public String getInputCmd() {
+        return inputCmd;
+    }
+
+    /**
      * <p>
      * Return detail help for <code>keyword</code>
      * </p>
index 35e49cf..ddd43dd 100644 (file)
@@ -29,11 +29,15 @@ package org.tizen.cli.exec.gen;
 
 import java.io.File;
 import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
 
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.OptionBuilder;
 import org.apache.commons.cli.Options;
 import org.tizen.cli.exec.AbstractLauncher;
+import org.tizen.cli.exec.Help;
 import org.tizen.cli.exec.pack.CLIMultiPackager;
 import org.tizen.common.core.application.InstallPathConfig;
 import org.tizen.common.core.command.Prompter;
@@ -42,27 +46,69 @@ import org.tizen.common.core.command.prompter.Option;
 import org.tizen.common.util.FileUtil;
 import org.tizen.common.util.StringUtil;
 import org.tizen.nativecommon.templateengine.TizenTemplateEngine;
+import org.tizen.nativecommon.templateengine.build.BuildPluginManagerForCLI;
+import org.tizen.nativecommon.templateengine.build.model.BuildProperty;
+import org.tizen.nativecommon.templateengine.build.model.DevPackageModel;
+import org.tizen.nativecommon.templateengine.build.model.RootstrapModel;
+import org.tizen.nativecommon.templateengine.build.model.TargetModel;
+import org.tizen.nativecommon.templateengine.build.util.BuildPluginUtil;
 import org.tizen.nativecommon.templateengine.model.TizenTemplate;
 
 public class NativeMain extends AbstractLauncher {
-
-    public boolean printHelp = false;
+    
+    private static final String PROJECTTYPE_APP = "app";
+    private static final String PROJECTTYPE_STATIC = "static";
+    private static final String PROJECTTYPE_SHARED = "shared";
+    
+    private static final String SAMPLE_EMPTY = "empty";
+    private static final String SAMPLE_FORM = "form";
+    private static final String SAMPLE_SERVICE = "service";
+    private static final String SAMPLE_SHARED = "shared";
+    private static final String SAMPLE_STATIC = "static";
+    private static final String SAMPLE_TAB = "tab";
     
     private static final String OPTION_PROJECTPATH = "path";
     private static final String OPTION_PROJECTNAME = "name";
     private static final String OPTION_SAMPLE = "sample";
     
+    private static final String OPTION_MAKE_PROJECTTYPE = "type";
+    private static final String OPTION_MAKE_BINARY = "binary";
+    private static final String OPTION_CMD_PROJECT = "project";
+    private static final String OPTION_CMD_MAKEFILE = "makefile";
+    
     private static final String DESC_PROJECTPATH = Messages.getString("NativeMain.DESC_PROJECTPATH"); //$NON-NLS-1$
     private static final String DESC_PROJECTNAME = Messages.getString("NativeMain.DESC_PROJECTNAME"); //$NON-NLS-1$
-    private static final String DESC_SAMPLE = Messages.getString("NativeMain.DESC_SAMPLE"); //$NON-NLS-1$
+    private static final String DESC_SAMPLE = MessageFormat.format(Messages.getString("NativeMain.DESC_SAMPLE"), 
+            SAMPLE_EMPTY, SAMPLE_FORM, SAMPLE_SERVICE, SAMPLE_SHARED, SAMPLE_STATIC, SAMPLE_TAB); //$NON-NLS-1$
+    private static final String DESC_CMD_PROJECT = Messages.getString("NativeMain.DESC_CMD_PROJECT"); //$NON-NLS-1$
+    private static final String DESC_CMD_MAKEFILE = Messages.getString("NativeMain.DESC_CMD_MAKEFILE"); //$NON-NLS-1$
+    
+    private static final String DESC_MAKE_PROJECTTYPE = MessageFormat.format(Messages.getString("NativeMain.DESC_MAKE_PROJECTTYPE"), PROJECTTYPE_APP, PROJECTTYPE_STATIC, PROJECTTYPE_SHARED); //$NON-NLS-1$
+    private static final String DESC_MAKE_BINARY = Messages.getString("NativeMain.DESC_MAKE_BINARY"); //$NON-NLS-1$
     
     private static final String TEMPLATE_DIRECTORY = "native/cpp/Template/Tizen Native";
-    private static final String SAMPLE_EMPTYPROJECT = TEMPLATE_DIRECTORY + "/Empty Application/empty";
-    private static final String SAMPLE_FORM = TEMPLATE_DIRECTORY + "/Form-based Application/formapp";
-    private static final String SAMPLE_SHARED = TEMPLATE_DIRECTORY + "/Library/sharedlibrary";
-    private static final String SAMPLE_STATIC = TEMPLATE_DIRECTORY + "/Library/staticlibrary";
-    private static final String SAMPLE_SERVICE = TEMPLATE_DIRECTORY + "/Service Application/serviceapp";
-    private static final String SAMPLE_TAB = TEMPLATE_DIRECTORY + "/Tab-based Application/tabapp";
+    private static final String SAMPLE_DIR_EMPTYPROJECT = TEMPLATE_DIRECTORY + "/Empty Application/empty";
+    private static final String SAMPLE_DIR_FORM = TEMPLATE_DIRECTORY + "/Form-based Application/formapp";
+    private static final String SAMPLE_DIR_SHARED = TEMPLATE_DIRECTORY + "/Library/sharedlibrary";
+    private static final String SAMPLE_DIR_STATIC = TEMPLATE_DIRECTORY + "/Library/staticlibrary";
+    private static final String SAMPLE_DIR_SERVICE = TEMPLATE_DIRECTORY + "/Service Application/serviceapp";
+    private static final String SAMPLE_DIR_TAB = TEMPLATE_DIRECTORY + "/Tab-based Application/tabapp";
+    
+    private static final HashMap<String, String> SAMPLE_DIR_MAP = new HashMap<String, String>();
+    private static final HashMap<String, String> PROJECTTYPE_MAP = new HashMap<String, String>();
+    
+    static {
+        SAMPLE_DIR_MAP.put(SAMPLE_EMPTY, SAMPLE_DIR_EMPTYPROJECT);
+        SAMPLE_DIR_MAP.put(SAMPLE_FORM, SAMPLE_DIR_FORM);
+        SAMPLE_DIR_MAP.put(SAMPLE_SERVICE, SAMPLE_DIR_SERVICE);
+        SAMPLE_DIR_MAP.put(SAMPLE_SHARED, SAMPLE_DIR_SHARED);
+        SAMPLE_DIR_MAP.put(SAMPLE_STATIC, SAMPLE_DIR_STATIC);
+        SAMPLE_DIR_MAP.put(SAMPLE_TAB, SAMPLE_DIR_TAB);
+        
+        PROJECTTYPE_MAP.put(PROJECTTYPE_APP, TizenTemplateEngine.PROJECTTYPE_APP);
+        PROJECTTYPE_MAP.put(PROJECTTYPE_SHARED, TizenTemplateEngine.PROJECTTYPE_SHARED);
+        PROJECTTYPE_MAP.put(PROJECTTYPE_STATIC, TizenTemplateEngine.PROJECTTYPE_STATIC);
+    }
     
     /**
      * Entry point for cli main
@@ -75,58 +121,36 @@ public class NativeMain extends AbstractLauncher {
         
         final NativeMain instance = new NativeMain();
         
-        if(args.length == 0) {
-            instance.printHelp = true;
-        }
-        
         instance.run( args );
     }
 
     @Override
     protected void execute(CommandLine cmdLine) throws Exception {
         
-        if(printHelp) {
-            printHelp();
-            return;
+        if(getInputCmd().equals(OPTION_CMD_MAKEFILE)) {
+            executeMakefile(cmdLine);
         }
-        
+        else {
+            executeProject(cmdLine);
+        }
+    }
+    
+    private void executeProject(CommandLine cmdLine) throws Exception {
         final Prompter prompter = getPrompter();
         logger.trace("get user input");
         
         String sampleName = cmdLine.getOptionValue(OPTION_SAMPLE);
         
-        if(StringUtil.isEmpty(sampleName)) {
-            prompter.error(Messages.getString("NativeMain.EXCEPTION_SAMPLE_TYPE_MISSING"));
-            return;
-        }
-        
-        String sampleDir = "";
         String samplePath = InstallPathConfig.getSamplesPath();
-        if(StringUtil.isEmpty(sampleName) || sampleName.equals("empty")) {
-            sampleName = "empty";
-            sampleDir = FileUtil.appendPath(samplePath, SAMPLE_EMPTYPROJECT);
-        }
-        else if(sampleName.equals("form")) {
-            sampleDir = FileUtil.appendPath(samplePath, SAMPLE_FORM);
-        }
-        else if(sampleName.equals("service")) {
-            sampleDir = FileUtil.appendPath(samplePath, SAMPLE_SERVICE);
-        }
-        else if(sampleName.equals("shared")) {
-            sampleDir = FileUtil.appendPath(samplePath, SAMPLE_SHARED);
-        }
-        else if(sampleName.equals("static")) {
-            sampleDir = FileUtil.appendPath(samplePath, SAMPLE_STATIC);
-        }
-        else if(sampleName.equals("tab"))
-        {
-            sampleDir = FileUtil.appendPath(samplePath, SAMPLE_TAB);
-        }
-        else {
-            prompter.error(MessageFormat.format(Messages.getString("NativeMain.EXCEPTION_SAMPLE_NOT_SUPPORT"), sampleDir) );
+        String sampleDir = SAMPLE_DIR_MAP.get(sampleName);
+        
+        if(null == sampleDir) {
+            prompter.error(MessageFormat.format(Messages.getString("NativeMain.EXCEPTION_SAMPLE_NOT_SUPPORT"), sampleName) );
             return;
         }
         
+        sampleDir = FileUtil.appendPath(samplePath, sampleDir);
+        
         String projectName = cmdLine.getOptionValue(OPTION_PROJECTNAME);
         if(StringUtil.isEmpty(projectName)) {
             projectName = sampleName;
@@ -161,25 +185,115 @@ public class NativeMain extends AbstractLauncher {
         prompter.notify(MessageFormat.format(Messages.getString("NativeMain.CREATE_SUCCESS"), 
                 template.getProjectPath(), template.getProjectPath() + File.separatorChar + CLIMultiPackager.BIN_FOLDER_NAME));
     }
+
+    private void executeMakefile(CommandLine cmdLine) throws Exception {
+        Prompter prompter = getPrompter();
+        
+        String projectType = cmdLine.getOptionValue(OPTION_MAKE_PROJECTTYPE);
+        String projectId = PROJECTTYPE_MAP.get(projectType);
+        
+        if(StringUtil.isEmpty(projectId)) {
+            prompter.error(MessageFormat.format(Messages.getString("NativeMain.EXCEPTION_WRONG_PROJECT_TYPE"), projectType) );
+            return;
+        }
+        
+        String binaryName = cmdLine.getOptionValue(OPTION_MAKE_BINARY);
+        
+        if(StringUtil.isEmpty(binaryName)) {
+            binaryName = new File(StringUtil.EMPTY_STRING).getName();
+        }
+        
+        String projectPath = new File(StringUtil.EMPTY_STRING).getAbsolutePath();
+        
+        TargetModel target = BuildPluginManagerForCLI.getDefaultTarget(projectId, BuildPluginUtil.ARCH_I386);
+        RootstrapModel rootstrap = target.getRootstrap();
+        HashMap<String, DevPackageModel> devPkgMap = BuildPluginManagerForCLI.DEVPKG_MAP.get(rootstrap.getId());
+        
+        ArrayList<DevPackageModel> devPkgList = new ArrayList<DevPackageModel>();
+        for(DevPackageModel devPkg: devPkgMap.values()) {
+            devPkgList.add(devPkg);
+        }
+        
+        TizenTemplate template = new TizenTemplate("", binaryName, projectPath);
+        template.setProperty(TizenTemplate.PROPERTY_KEY_PROJECTTYPE, projectId);
+        template.setProperty(TizenTemplate.PROPERTY_KEY_EMUL_TARGET, target);
+        template.setProperty(TizenTemplate.PROPERTY_KEY_DEV_TARGET, target);
+        
+        CLIProjectGenerator generator = new CLIProjectGenerator();
+        BuildProperty buildProperty = BuildPluginManagerForCLI.getBuildPropertyFromDevPkgs(devPkgList, template, target, new CLIProjectGenerator());
+        
+        template.setProperty(TizenTemplate.PROPERTY_KEY_EMUL_BUILD_PROPERTY, buildProperty);
+        template.setProperty(TizenTemplate.PROPERTY_KEY_DEV_BUILD_PROPERTY, buildProperty);
+        
+        generator.doRemainingJob(devPkgList, template, target);
+        
+        Map<String, String> valueStore = new HashMap<String, String>();
+        generator.pressDefaultPostValueStore(valueStore, template);
+        generator.pressPostValueStoreFromDevPkg(valueStore, template);
+        generator.createBuildFiles(valueStore, template);
+        
+        prompter.notify(MessageFormat.format(Messages.getString("NativeMain.MAKE_CREATE_SUCCESS"), 
+                projectPath + File.separatorChar + CLIMultiPackager.BIN_FOLDER_NAME));
+    }
     
+    @SuppressWarnings("static-access")
     @Override
-    protected String printHelp() {
-        StringBuffer helpBuffer = new StringBuffer();
-        helpBuffer.append(Messages.getString("NativeMain.USAGE")); //$NON-NLS-1$
-        helpBuffer.append(getHelp().getHelp());
-        String helpStr = helpBuffer.toString();
-        getPrompter().error(helpStr);
-        return helpStr;
+    protected Options getCommands() {
+        Options result = super.getCommands();
+        
+        result.addOption(OptionBuilder.hasArg().withLongOpt(OPTION_CMD_PROJECT).hasArg(false).withDescription(DESC_CMD_PROJECT).create());
+        result.addOption(OptionBuilder.hasArg().withLongOpt(OPTION_CMD_MAKEFILE).hasArg(false).withDescription(DESC_CMD_MAKEFILE).create());
+        
+        return result;
     }
     
     @SuppressWarnings("static-access")
     @Override
     protected Options getOptions() {
         Options result = super.getOptions();
-        result.addOption(OptionBuilder.hasArg().withLongOpt(OPTION_SAMPLE).withDescription(DESC_SAMPLE).create("s"));
-        result.addOption(OptionBuilder.hasArg().withLongOpt(OPTION_PROJECTPATH).withDescription(DESC_PROJECTPATH).create("p"));
-        result.addOption(OptionBuilder.hasArg().withLongOpt(OPTION_PROJECTNAME).withDescription(DESC_PROJECTNAME).create("n"));
+        
+        if(getInputCmd().equals(OPTION_CMD_MAKEFILE)){
+            result.addOption(OptionBuilder.hasArg().withLongOpt(OPTION_MAKE_PROJECTTYPE).withDescription(DESC_MAKE_PROJECTTYPE).isRequired().create("t"));
+            result.addOption(OptionBuilder.hasArg().withLongOpt(OPTION_MAKE_BINARY).withDescription(DESC_MAKE_BINARY).create("b"));
+        }
+        else {
+            result.addOption(OptionBuilder.hasArg().withLongOpt(OPTION_SAMPLE).withDescription(DESC_SAMPLE).isRequired().create("s"));
+            result.addOption(OptionBuilder.hasArg().withLongOpt(OPTION_PROJECTPATH).withDescription(DESC_PROJECTPATH).create("p"));
+            result.addOption(OptionBuilder.hasArg().withLongOpt(OPTION_PROJECTNAME).withDescription(DESC_PROJECTNAME).create("n"));
+        }
         return result;
     }
-
+    
+    @Override
+    protected boolean isPrintHelp() {
+        return true;
+    }
+    
+    @Override
+    protected String getUsageDescription() {
+        return "Create a native project or a makefile";
+    }
+    
+    private Options getSuperOptions() {
+        return super.getOptions();
+    }
+    
+    @Override
+    protected Help createHelp() {
+        return new Help(getOptions(), getCommands(), getInputCmd(), getUsageDescription()) {
+            
+            NativeMain outer = NativeMain.this;
+            private Help defaultHelp = new Help(outer.getSuperOptions(), outer.getCommands(), outer.getInputCmd(), outer.getUsageDescription());
+            
+            @Override
+            public String getHelp() {
+                Options cmds = this.getCmds();
+                if(cmds.getOption(this.getInputCmd()) == null) {
+                    return defaultHelp.getHelp();
+                }
+                else return super.getHelp();
+            }
+            
+        };
+    }
 }
\ No newline at end of file
index d749f4b..5ffeec7 100644 (file)
@@ -1,13 +1,18 @@
-CLIProjectGenerator.EXCEPTION_CREATING_CLASS=Exception occurred while creating a class: {0}
-CLIProjectGenerator.EXCEPTION_CREATING_MAKEFILE=Exception occurred while creating a makefile
-CLIProjectGenerator.EXCEPTION_UNEXPECTED_PROJECTTYPE=Unexpected project type: {0}
+CLIProjectGenerator.EXCEPTION_CREATING_CLASS=Exception occurred while creating a class: {0}.
+CLIProjectGenerator.EXCEPTION_CREATING_MAKEFILE=Exception occurred while creating a makefile.
+CLIProjectGenerator.EXCEPTION_UNEXPECTED_PROJECTTYPE=Unexpected project type: {0}.
 NativeMain.CREATE_A_PROJECT=Creating a project: {0}...
-NativeMain.CREATE_SUCCESS=A project is created successfully in {0} \nTo build a project, run native-make in {1}.
+NativeMain.CREATE_SUCCESS=A project was created successfully in {0} \nTo build a project, run native-make in {1}.
 NativeMain.DESC_PROJECTNAME=Specify a project name. (Default: <sample type>)
 NativeMain.DESC_PROJECTPATH=Specify a project path. (Default: <current directory>/<project name>)
-NativeMain.DESC_SAMPLE=Specify a sample type \n\t\t\t  empty: empty application\n\t\t\t  form: form-based application\n\t\t\t  shared: shared library\n\t\t\t  static: static library\n\t\t\t  service: service application\n\t\t\t  tab: tab-based application
+NativeMain.DESC_SAMPLE=Specify a sample type. \n\t\t\t  {0}: empty application\n\t\t\t  {1}: form-based application\n\t\t\t  {2}: shared library\n\t\t\t  {3}: static library\n\t\t\t  {4}: service application\n\t\t\t  {5}: tab-based application
 NativeMain.DIR_EXIST={0} already exist(s).\nDo you want to overwrite and continue?
 NativeMain.EXCEPTION_SAMPLE_NOT_SUPPORT=Sample: {0} is not supported. Choose another sample.
+NativeMain.EXCEPTION_WRONG_PROJECT_TYPE=Wrong project type: {0}.
 NativeMain.PROCESS_CANCEL=Process is canceled.
 NativeMain.USAGE=usage: native-gen -s <sample_type> [OPTION]\nCreate a project\n\n
-NativeMain.EXCEPTION_SAMPLE_TYPE_MISSING=A sample type is missing. Specify a sample type.
\ No newline at end of file
+NativeMain.DESC_CMD_PROJECT=Create a native project. This is a default command.
+NativeMain.DESC_CMD_MAKEFILE=Create build files.
+NativeMain.DESC_MAKE_PROJECTTYPE=Specify a project type. ({0} | {1} | {2})
+NativeMain.DESC_MAKE_BINARY=Specify a output binary name. (Default: <project folder name>)
+NativeMain.MAKE_CREATE_SUCCESS=A makefile was created successfully in {0}.\nTo build a project, run native-make in {0}.
\ No newline at end of file