Maven Archetype
  1. Maven Archetype
  2. ARCHETYPE-371

Add a command line argument to filter/limit the archetypes returned by mvn archetype:generate

    Details

    • Type: New Feature New Feature
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.0
    • Fix Version/s: 2.1
    • Component/s: Plugin
    • Labels:
      None
    • Environment:

      Description

      Currently, running mvn archetype:generate returns 390 archetypes, on my machine.
      By default, th window buffer of my terminal isn't set big enough so I can see the first archetypes in the list.

      So, I think it would be really useful to have a CLI arg allowing us to filter the archetypes containing a string.
      Ex: running

      mvn archetype:generate -Dfilter=webapp

      would return only the archetypes having webapp in their artifactId.

      What do you think?

        Activity

        Hide
        Fred Bricon added a comment - - edited

        After a bit of hacking, I managed to get the following results :

        [fbricon@fbricon Temp]$ mvn org.apache.maven.plugins:maven-archetype-plugin:2.1-SNAPSHOT:generate -Dfilter=jee
        [INFO] Scanning for projects...
        [INFO]                                                                         
        [INFO] ------------------------------------------------------------------------
        [INFO] Building Maven Stub Project (No POM) 1
        [INFO] ------------------------------------------------------------------------
        [INFO] 
        [INFO] >>> maven-archetype-plugin:2.1-SNAPSHOT:generate (default-cli) @ standalone-pom >>>
        [INFO] 
        [INFO] <<< maven-archetype-plugin:2.1-SNAPSHOT:generate (default-cli) @ standalone-pom <<<
        [INFO] 
        [INFO] --- maven-archetype-plugin:2.1-SNAPSHOT:generate (default-cli) @ standalone-pom ---
        [INFO] Generating project in Interactive mode
        [INFO] No archetype defined. Using maven-archetype-quickstart (org.apache.maven.archetypes:maven-archetype-quickstart:1.0)
        Choose archetype:
        1: remote -> ear-jee5 (-)
        2: remote -> ejb-jee5 (-)
        3: remote -> webapp-jee5 (-)
        4: remote -> jee6-basic-archetype (-)
        5: remote -> jee6-minimal-archetype (-)
        6: remote -> jee6-sandbox-archetype (-)
        7: remote -> jee6-sandbox-demo-archetype (-)
        8: remote -> jee6-servlet-basic-archetype (-)
        9: remote -> jee6-servlet-demo-archetype (-)
        10: remote -> jee6-servlet-minimal-archetype (-)
        11: remote -> jee6-servlet-sandbox-archetype (-)
        12: remote -> imixs-workflow-jee-archetype (Imixs Workflow JEE Archetype provides a JEE Sample Application)
        13: remote -> weld-jsf-jee (Weld archetype for creating a Java EE 6 application using JSF 2.0, CDI 1.0, EJB 3.1 and JPA 2.0 (persistence unit included))
        14: remote -> weld-jsf-jee-minimal (Weld archetype for creating a minimal Java EE 6 application using JSF 2.0, CDI 1.0 and EJB 3.1 (persistence unit not included))
        Choose a number: : 13
        Downloading: http://repo1.maven.org/maven2/org/jboss/weld/archetypes/weld-jsf-jee/1.0.0-BETA1/weld-jsf-jee-1.0.0-BETA1.jar
        Downloaded: http://repo1.maven.org/maven2/org/jboss/weld/archetypes/weld-jsf-jee/1.0.0-BETA1/weld-jsf-jee-1.0.0-BETA1.jar (138 KB at 121.2 KB/sec)
        Downloading: http://repo1.maven.org/maven2/org/jboss/weld/archetypes/weld-jsf-jee/1.0.0-BETA1/weld-jsf-jee-1.0.0-BETA1.pom
        Downloaded: http://repo1.maven.org/maven2/org/jboss/weld/archetypes/weld-jsf-jee/1.0.0-BETA1/weld-jsf-jee-1.0.0-BETA1.pom (2 KB at 1.9 KB/sec)
        Define value for property 'groupId': : foo.bar
        Define value for property 'artifactId': : weldy
        [INFO] Using property: version = 1.0.0-SNAPSHOT
        Define value for property 'package':  foo.bar: : 
        Confirm properties configuration:
        groupId: foo.bar
        artifactId: weldy
        version: 1.0.0-SNAPSHOT
        package: foo.bar
         Y: : 
        [INFO] ------------------------------------------------------------------------
        [INFO] BUILD SUCCESS
        [INFO] ------------------------------------------------------------------------
        [INFO] Total time: 31.635s
        [INFO] Finished at: Sun May 01 00:09:10 CEST 2011
        [INFO] Final Memory: 6M/245M
        [INFO] ------------------------------------------------------------------------
        
        

        Basically, the code in org.apache.maven.archetype.ui.DefaultArchetypeSelector looks like :

            public void selectArchetype( ArchetypeGenerationRequest request, Boolean interactiveMode, String catalogs )
                throws ArchetypeNotDefined, UnknownArchetype, UnknownGroup, IOException, PrompterException,
                ArchetypeSelectionFailure
            {
                ...
                Map<String, List<Archetype>> archetypes = getFilteredArchetypes(getArchetypesByCatalog( catalogs ), 
                                                                                                        request.getFilter() );
                ...
        
            private Map<String, List<Archetype>> getFilteredArchetypes(	Map<String, List<Archetype>> archetypesByCatalog, 
            															final String filter) {
            	
            	if (StringUtils.isNotEmpty(filter) && !archetypesByCatalog.isEmpty()) 
            	{
            		Iterator<Map.Entry<String, List<Archetype>>> ite = archetypesByCatalog.entrySet().iterator();
            		while (ite.hasNext()) {
            			Map.Entry<String, List<Archetype>> entry = ite.next();
            			List<Archetype> archetypes  = entry.getValue();
            			CollectionUtils.filter(archetypes, new Predicate() 
                    	{
        					public boolean evaluate(Object archetype) 
        					{
        						return ((Archetype) archetype).getArtifactId().contains(filter);
        					}
        				});
            			if (archetypes.isEmpty()) {
            				ite.remove();
            			}
            		}
            	}
        		return archetypesByCatalog;
        	}
        

        This implementation has a minimum impact on the code. However, doing the actual filtering would probably be more appropriate directly in the ArchetypeCatalog class, but that would require more code change. It's debatable.

        If this implementation suits you, I can add some test cases and attach a patch here. You tell me

        Show
        Fred Bricon added a comment - - edited After a bit of hacking, I managed to get the following results : [fbricon@fbricon Temp]$ mvn org.apache.maven.plugins:maven-archetype-plugin:2.1-SNAPSHOT:generate -Dfilter=jee [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building Maven Stub Project (No POM) 1 [INFO] ------------------------------------------------------------------------ [INFO] [INFO] >>> maven-archetype-plugin:2.1-SNAPSHOT:generate (default-cli) @ standalone-pom >>> [INFO] [INFO] <<< maven-archetype-plugin:2.1-SNAPSHOT:generate (default-cli) @ standalone-pom <<< [INFO] [INFO] --- maven-archetype-plugin:2.1-SNAPSHOT:generate (default-cli) @ standalone-pom --- [INFO] Generating project in Interactive mode [INFO] No archetype defined. Using maven-archetype-quickstart (org.apache.maven.archetypes:maven-archetype-quickstart:1.0) Choose archetype: 1: remote -> ear-jee5 (-) 2: remote -> ejb-jee5 (-) 3: remote -> webapp-jee5 (-) 4: remote -> jee6-basic-archetype (-) 5: remote -> jee6-minimal-archetype (-) 6: remote -> jee6-sandbox-archetype (-) 7: remote -> jee6-sandbox-demo-archetype (-) 8: remote -> jee6-servlet-basic-archetype (-) 9: remote -> jee6-servlet-demo-archetype (-) 10: remote -> jee6-servlet-minimal-archetype (-) 11: remote -> jee6-servlet-sandbox-archetype (-) 12: remote -> imixs-workflow-jee-archetype (Imixs Workflow JEE Archetype provides a JEE Sample Application) 13: remote -> weld-jsf-jee (Weld archetype for creating a Java EE 6 application using JSF 2.0, CDI 1.0, EJB 3.1 and JPA 2.0 (persistence unit included)) 14: remote -> weld-jsf-jee-minimal (Weld archetype for creating a minimal Java EE 6 application using JSF 2.0, CDI 1.0 and EJB 3.1 (persistence unit not included)) Choose a number: : 13 Downloading: http://repo1.maven.org/maven2/org/jboss/weld/archetypes/weld-jsf-jee/1.0.0-BETA1/weld-jsf-jee-1.0.0-BETA1.jar Downloaded: http://repo1.maven.org/maven2/org/jboss/weld/archetypes/weld-jsf-jee/1.0.0-BETA1/weld-jsf-jee-1.0.0-BETA1.jar (138 KB at 121.2 KB/sec) Downloading: http://repo1.maven.org/maven2/org/jboss/weld/archetypes/weld-jsf-jee/1.0.0-BETA1/weld-jsf-jee-1.0.0-BETA1.pom Downloaded: http://repo1.maven.org/maven2/org/jboss/weld/archetypes/weld-jsf-jee/1.0.0-BETA1/weld-jsf-jee-1.0.0-BETA1.pom (2 KB at 1.9 KB/sec) Define value for property 'groupId': : foo.bar Define value for property 'artifactId': : weldy [INFO] Using property: version = 1.0.0-SNAPSHOT Define value for property 'package': foo.bar: : Confirm properties configuration: groupId: foo.bar artifactId: weldy version: 1.0.0-SNAPSHOT package: foo.bar Y: : [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 31.635s [INFO] Finished at: Sun May 01 00:09:10 CEST 2011 [INFO] Final Memory: 6M/245M [INFO] ------------------------------------------------------------------------ Basically, the code in org.apache.maven.archetype.ui.DefaultArchetypeSelector looks like : public void selectArchetype( ArchetypeGenerationRequest request, Boolean interactiveMode, String catalogs ) throws ArchetypeNotDefined, UnknownArchetype, UnknownGroup, IOException, PrompterException, ArchetypeSelectionFailure { ... Map<String, List<Archetype>> archetypes = getFilteredArchetypes(getArchetypesByCatalog( catalogs ), request.getFilter() ); ... private Map<String, List<Archetype>> getFilteredArchetypes( Map<String, List<Archetype>> archetypesByCatalog, final String filter) { if (StringUtils.isNotEmpty(filter) && !archetypesByCatalog.isEmpty()) { Iterator<Map.Entry<String, List<Archetype>>> ite = archetypesByCatalog.entrySet().iterator(); while (ite.hasNext()) { Map.Entry<String, List<Archetype>> entry = ite.next(); List<Archetype> archetypes = entry.getValue(); CollectionUtils.filter(archetypes, new Predicate() { public boolean evaluate(Object archetype) { return ((Archetype) archetype).getArtifactId().contains(filter); } }); if (archetypes.isEmpty()) { ite.remove(); } } } return archetypesByCatalog; } This implementation has a minimum impact on the code. However, doing the actual filtering would probably be more appropriate directly in the ArchetypeCatalog class, but that would require more code change. It's debatable. If this implementation suits you, I can add some test cases and attach a patch here. You tell me
        Hide
        Hervé Boutemy added a comment -

        I'm interested in this feature: yes, please provide patch with test cases

        Show
        Hervé Boutemy added a comment - I'm interested in this feature: yes, please provide patch with test cases
        Hide
        Olivier Lamy (*$^¨%`£) added a comment -

        an idea I have is to have the possibility of more "complicated" search query

        // g for groupId a for artifactId
        -Dfilter=g:maven,a:plugin
        // default on artifactId
        -Dfilter=plugin
        

        WDYT ?

        Show
        Olivier Lamy (*$^¨%`£) added a comment - an idea I have is to have the possibility of more "complicated" search query // g for groupId a for artifactId -Dfilter=g:maven,a:plugin // default on artifactId -Dfilter=plugin WDYT ?
        Hide
        Fred Bricon added a comment -

        Could be useful indeed.
        I'm sorry I didn't follow up on this issue so far, I've been swamped IRL
        I haven't lost hope of being able to provide a patch yet

        Show
        Fred Bricon added a comment - Could be useful indeed. I'm sorry I didn't follow up on this issue so far, I've been swamped IRL I haven't lost hope of being able to provide a patch yet
        Hide
        Olivier Lamy (*$^¨%`£) added a comment -

        no worries I will push the first simple implementation

        Show
        Olivier Lamy (*$^¨%`£) added a comment - no worries I will push the first simple implementation
        Hide
        Olivier Lamy (*$^¨%`£) added a comment -

        first simple impl in rev 1143127
        I leave the issue open until :

        • filtering with g: and a:
        • provide test.
        Show
        Olivier Lamy (*$^¨%`£) added a comment - first simple impl in rev 1143127 I leave the issue open until : filtering with g: and a: provide test.
        Hide
        Olivier Lamy (*$^¨%`£) added a comment -

        for simplicity something like -Dfilter=groupId:artifactId
        Both must be included in groupId and artifactId.
        Seems more simple than the g:,a:

        Show
        Olivier Lamy (*$^¨%`£) added a comment - for simplicity something like -Dfilter=groupId:artifactId Both must be included in groupId and artifactId. Seems more simple than the g:,a:
        Hide
        Hervé Boutemy added a comment -

        Idea: at the prompt, propose "Choose a number or filter:"
        if data entered is not a number, then assume it's a filter and display newly filtered archetypes
        then you don't really need to know -Dfilter, you can interactively test filters

        I didn't if it is really hard to implement or not...

        Show
        Hervé Boutemy added a comment - Idea: at the prompt, propose "Choose a number or filter:" if data entered is not a number, then assume it's a filter and display newly filtered archetypes then you don't really need to know -Dfilter, you can interactively test filters I didn't if it is really hard to implement or not...
        Hide
        Olivier Lamy (*$^¨%`£) added a comment -

        nice idea to not having to know this magic -Dfiler= .
        BTW the first goal was more to remove the HUGE list of archetype.
        We can certainly do both .
        Agree on the format ? : groupId:artifactId ?
        Samples :

        • org.apache: -> display all archetypes which contains org.apache in groupId
        • :jee or jee -> display all archetypes which contains jee in artifactId
        • org.apache:jee -> display all archetypes which contains org.apache in groupId AND jee in artifactId

        makes sense ?

        Show
        Olivier Lamy (*$^¨%`£) added a comment - nice idea to not having to know this magic -Dfiler= . BTW the first goal was more to remove the HUGE list of archetype. We can certainly do both . Agree on the format ? : groupId:artifactId ? Samples : org.apache: -> display all archetypes which contains org.apache in groupId :jee or jee -> display all archetypes which contains jee in artifactId org.apache:jee -> display all archetypes which contains org.apache in groupId AND jee in artifactId makes sense ?
        Hide
        Hervé Boutemy added a comment -

        seems easy and efficient

        Show
        Hervé Boutemy added a comment - seems easy and efficient
        Hide
        Olivier Lamy (*$^¨%`£) added a comment -

        both supported in r1144639.
        Leave it open until I have review documentation.

        Show
        Olivier Lamy (*$^¨%`£) added a comment - both supported in r1144639. Leave it open until I have review documentation.
        Hide
        Olivier Lamy (*$^¨%`£) added a comment -

        documentation added.
        I have take care of case where filter doesn't return any values.
        Have Fun

        Show
        Olivier Lamy (*$^¨%`£) added a comment - documentation added. I have take care of case where filter doesn't return any values. Have Fun

          People

          • Assignee:
            Olivier Lamy (*$^¨%`£)
            Reporter:
            Fred Bricon
          • Votes:
            5 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development