split bootstrap into two stages

git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@344329 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Brett Leslie Porter 2005-11-15 08:06:13 +00:00
parent eb1651be3c
commit 36f39fc926
39 changed files with 343 additions and 104 deletions

View File

@ -0,0 +1,16 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.maven.bootstrap</groupId>
<artifactId>bootstrap-installer</artifactId>
<version>2.0.1-SNAPSHOT</version>
<name>Maven Bootstrap Installer</name>
<description>Tool used to bootstrap m2.</description>
<dependencies>
<dependency>
<groupId>org.apache.maven.bootstrap</groupId>
<artifactId>bootstrap-mini</artifactId>
<version>2.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,121 @@
package org.apache.maven.bootstrap.installer;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* 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.
*/
import org.apache.maven.bootstrap.model.Dependency;
import org.apache.maven.bootstrap.model.ModelReader;
import org.apache.maven.bootstrap.util.FileUtils;
import org.apache.maven.bootstrap.Bootstrap;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
/**
* Main class for bootstrap module.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public class BootstrapInstaller
{
private final Bootstrap bootstrapper;
public BootstrapInstaller( String[] args )
throws Exception
{
this.bootstrapper = new Bootstrap( args );
}
public static void main( String[] args )
throws Exception
{
BootstrapInstaller bootstrap = new BootstrapInstaller( args );
bootstrap.run();
}
private void run()
throws Exception
{
Date fullStart = new Date();
String basedir = System.getProperty( "user.dir" );
// TODO: only build this guy, then move the next part to a new phase using it for resolution
// Root POM
// buildProject( basedir, "", resolver, false );
// buildProject( basedir, "maven-artifact-manager", resolver );
bootstrapper.buildProject( new File( basedir ), true );
createInstallation( new File( basedir, "target/installation" ) );
Bootstrap.stats( fullStart, new Date() );
}
private void createInstallation( File dir )
throws IOException
{
FileUtils.deleteDirectory( dir );
dir.mkdirs();
File libDirectory = new File( dir, "lib" );
libDirectory.mkdir();
File binDirectory = new File( dir, "bin" );
File coreDirectory = new File( dir, "core" );
coreDirectory.mkdir();
File bootDirectory = new File( coreDirectory, "boot" );
bootDirectory.mkdir();
ModelReader reader = bootstrapper.getCachedModel( "org.apache.maven", "maven-core" );
for ( Iterator i = reader.getDependencies().iterator(); i.hasNext(); )
{
Dependency dep = (Dependency) i.next();
if ( dep.getArtifactId().equals( "classworlds" ) )
{
FileUtils.copyFileToDirectory( bootstrapper.getArtifactFile( dep ), bootDirectory );
}
else if ( dep.getArtifactId().equals( "plexus-container-default" ) ||
dep.getArtifactId().equals( "plexus-utils" ) )
{
FileUtils.copyFileToDirectory( bootstrapper.getArtifactFile( dep ), coreDirectory );
}
else
{
FileUtils.copyFileToDirectory( bootstrapper.getArtifactFile( dep ), libDirectory );
}
}
Dependency coreAsDep = new Dependency( reader.getGroupId(), reader.getArtifactId(), reader.getVersion(),
reader.getPackaging(), Collections.EMPTY_LIST );
FileUtils.copyFileToDirectory( bootstrapper.getArtifactFile( coreAsDep ), libDirectory );
File srcBinDirectory = new File( reader.getProjectFile().getParentFile(), "src/bin" );
FileUtils.copyDirectory( srcBinDirectory, binDirectory, null, "**/.svn/**" );
}
}

View File

@ -0,0 +1,2 @@
Manifest-Version: 1.0
Main-Class: org.apache.maven.bootstrap.installer.BootstrapInstaller

View File

@ -10,4 +10,4 @@ mkdir -p ${classesDir}
"$JAVA_HOME/bin/javac" -g -d ${classesDir} `find ${srcDir} -name '*.java'`
( cd ${classesDir} ; "$JAVA_HOME/bin/jar" -cfm ../bootstrap.jar ../../src/main/resources/META-INF/MANIFEST.MF * )
( cd ${classesDir} ; "$JAVA_HOME/bin/jar" -cfm ../bootstrap-mini.jar ../../src/main/resources/META-INF/MANIFEST.MF * )

View File

@ -15,5 +15,5 @@ dir /B /s %srcDir%\*.java >sources
del /F/Q sources
cd %classesDir%
"%JAVA_HOME%\bin\jar" -cfm ..\bootstrap.jar ..\..\src\main\resources\META-INF\MANIFEST.MF *.*
"%JAVA_HOME%\bin\jar" -cfm ..\bootstrap-mini.jar ..\..\src\main\resources\META-INF\MANIFEST.MF *.*
cd ..\..

View File

@ -0,0 +1,9 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.maven.bootstrap</groupId>
<artifactId>bootstrap-mini</artifactId>
<version>2.0.1-SNAPSHOT</version>
<name>Maven Bootstrap Mini Builder</name>
<description>Tool used to bootstrap m2.</description>
</project>

View File

@ -21,6 +21,7 @@ import org.apache.maven.bootstrap.compile.JavacCompiler;
import org.apache.maven.bootstrap.download.ArtifactResolver;
import org.apache.maven.bootstrap.download.OfflineArtifactResolver;
import org.apache.maven.bootstrap.download.OnlineArtifactDownloader;
import org.apache.maven.bootstrap.download.RepositoryMetadata;
import org.apache.maven.bootstrap.model.Dependency;
import org.apache.maven.bootstrap.model.ModelReader;
import org.apache.maven.bootstrap.model.Plugin;
@ -45,7 +46,6 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
@ -55,6 +55,7 @@ import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TimeZone;
import java.util.Collections;
/**
* Main class for bootstrap module.
@ -72,12 +73,45 @@ public class Bootstrap
private Map modelCache = new HashMap();
private final ArtifactResolver resolver;
public Bootstrap( String[] args )
throws Exception
{
String userHome = System.getProperty( "user.home" );
File settingsXml = getSettingsPath( userHome, args );
System.out.println( "Using settings from " + settingsXml );
Settings settings = Settings.read( userHome, settingsXml );
// TODO: have an alternative implementation of ArtifactResolver for source compiles
// - if building from source, checkout and build then resolve to built jar (still download POM?)
resolver = setupRepositories( settings );
}
public static void main( String[] args )
throws Exception
{
Bootstrap bootstrap = new Bootstrap();
Bootstrap bootstrap = new Bootstrap( args );
bootstrap.run( args );
String goal = null;
for ( int i = 0; i < args.length && goal == null; i++ )
{
if ( args[i].equals( "install" ) || args[i].equals( "package" ) )
{
goal = args[i];
}
}
if ( goal == null )
{
System.err.println( "Goal 'package' or 'install' must be specified" );
return;
}
bootstrap.run( goal );
}
private static File getSettingsPath( String userHome, String[] args )
@ -97,88 +131,78 @@ public class Bootstrap
return new File( userHome, ".m2/settings.xml" );
}
private void run( String[] args )
private void run( String goal )
throws Exception
{
Date fullStart = new Date();
String userHome = System.getProperty( "user.home" );
File settingsXml = getSettingsPath( userHome, args );
System.out.println( "Using settings from " + settingsXml );
Settings settings = Settings.read( userHome, settingsXml );
// TODO: have an alternative implementation of ArtifactDownloader for source compiles
// - if building from source, checkout and build then resolve to built jar (still download POM?)
ArtifactResolver resolver = setupRepositories( settings );
String basedir = System.getProperty( "user.dir" );
// TODO: only build this guy, then move the next part to a new phase using it for resolution
// Root POM
// buildProject( basedir, "", resolver, false );
// buildProject( basedir, "maven-artifact-manager", resolver );
// Pre-cache models so we know where they are for dependencies
cacheModels( new File( basedir ), resolver );
buildProject( new File( basedir ), resolver, true );
createInstallation( new File( basedir, "target/installation" ), resolver );
if ( "install".equals( goal ) )
{
File pom = new File( basedir, "pom.xml" );
ModelReader reader = readModel( resolver, pom, true );
File jar = buildProject( reader );
install( reader, pom, jar );
}
else
{
buildProject( new File( basedir ), false );
}
stats( fullStart, new Date() );
}
private void createInstallation( File dir, ArtifactResolver resolver )
private void install( ModelReader reader, File pom, File jar )
throws Exception
{
String artifactId = reader.getArtifactId();
String version = reader.getVersion();
String groupId = reader.getGroupId();
String type = reader.getPackaging();
Repository localRepository = resolver.getLocalRepository();
File file = localRepository.getArtifactFile(
new Dependency( groupId, artifactId, version, type, Collections.EMPTY_LIST ) );
System.out.println( "Installing: " + file );
FileUtils.copyFile( jar, file );
installPomFile( reader, pom );
RepositoryMetadata metadata = new RepositoryMetadata();
metadata.setReleaseVersion( version );
metadata.setLatestVersion( version );
file = localRepository.getMetadataFile( groupId, artifactId, null, type, "maven-metadata-local.xml" );
metadata.write( file );
metadata = new RepositoryMetadata();
metadata.setLocalCopy( true );
metadata.setLastUpdated( getCurrentUtcDate() );
file = localRepository.getMetadataFile( groupId, artifactId, version, type, "maven-metadata-local.xml" );
metadata.write( file );
}
private void installPomFile( ModelReader reader, File source )
throws IOException
{
FileUtils.deleteDirectory( dir );
String artifactId = reader.getArtifactId();
dir.mkdirs();
String version = reader.getVersion();
File libDirectory = new File( dir, "lib" );
libDirectory.mkdir();
String groupId = reader.getGroupId();
File binDirectory = new File( dir, "bin" );
Repository localRepository = resolver.getLocalRepository();
File pom = localRepository.getMetadataFile( groupId, artifactId, version, reader.getPackaging(),
artifactId + "-" + version + ".pom" );
File coreDirectory = new File( dir, "core" );
coreDirectory.mkdir();
System.out.println( "Installing POM: " + pom );
File bootDirectory = new File( coreDirectory, "boot" );
bootDirectory.mkdir();
ModelReader reader = (ModelReader) modelCache.get( "org.apache.maven:maven-core" );
for ( Iterator i = reader.getDependencies().iterator(); i.hasNext(); )
{
Dependency dep = (Dependency) i.next();
if ( dep.getArtifactId().equals( "classworlds" ) )
{
FileUtils.copyFileToDirectory( resolver.getArtifactFile( dep ), bootDirectory );
}
else if ( dep.getArtifactId().equals( "plexus-container-default" ) ||
dep.getArtifactId().equals( "plexus-utils" ) )
{
FileUtils.copyFileToDirectory( resolver.getArtifactFile( dep ), coreDirectory );
}
else
{
FileUtils.copyFileToDirectory( resolver.getArtifactFile( dep ), libDirectory );
}
}
Dependency coreAsDep = new Dependency( reader.getGroupId(), reader.getArtifactId(), reader.getVersion(),
reader.getPackaging(), Collections.EMPTY_LIST );
FileUtils.copyFileToDirectory( resolver.getArtifactFile( coreAsDep ), libDirectory );
File srcBinDirectory = (File) modelFileCache.get( "org.apache.maven:maven-core" );
srcBinDirectory = new File( srcBinDirectory.getParentFile(), "src/bin" );
FileUtils.copyDirectory( srcBinDirectory, binDirectory, null, "**/.svn/**" );
FileUtils.copyFile( source, pom );
}
private void cacheModels( File basedir, ArtifactResolver resolver )
@ -194,9 +218,15 @@ public class Bootstrap
}
}
private void buildProject( File basedir, ArtifactResolver resolver, boolean buildModules )
public void buildProject( File basedir, boolean buildModules )
throws Exception
{
if ( buildModules )
{
// Pre-cache models so we know where they are for dependencies
cacheModels( basedir, resolver );
}
System.setProperty( "basedir", basedir.getAbsolutePath() );
File file = new File( basedir, "pom.xml" );
@ -217,7 +247,7 @@ public class Bootstrap
{
String module = (String) i.next();
buildProject( new File( basedir, module ), resolver, true );
buildProject( new File( basedir, module ), true );
}
}
@ -231,6 +261,16 @@ public class Bootstrap
return;
}
buildProject( reader );
inProgress.remove( key );
}
private File buildProject( ModelReader reader )
throws Exception
{
File basedir = reader.getProjectFile().getParentFile();
String sources = new File( basedir, "src/main/java" ).getAbsolutePath();
String resources = new File( basedir, "src/main/resources" ).getAbsolutePath();
@ -248,7 +288,7 @@ public class Bootstrap
if ( modelFileCache.containsKey( dep.getId() ) )
{
buildProject( resolver.getArtifactFile( dep.getPomDependency() ).getParentFile(), resolver, false );
buildProject( resolver.getArtifactFile( dep.getPomDependency() ).getParentFile(), false );
}
}
@ -336,7 +376,7 @@ public class Bootstrap
line();
inProgress.remove( key );
return jarFile;
}
private ModelReader readModel( ArtifactResolver resolver, File file, boolean resolveTransitiveDependencies )
@ -528,7 +568,7 @@ public class Bootstrap
}
}
private void stats( Date fullStart, Date fullStop )
public static void stats( Date fullStart, Date fullStop )
{
long fullDiff = fullStop.getTime() - fullStart.getTime();
@ -696,4 +736,14 @@ public class Bootstrap
return cl;
}
public ModelReader getCachedModel( String groupId, String artifactId )
{
return (ModelReader) modelCache.get( groupId + ":" + artifactId );
}
public File getArtifactFile( Dependency dep )
{
return resolver.getArtifactFile( dep );
}
}

View File

@ -16,13 +16,14 @@ package org.apache.maven.bootstrap.model;
* limitations under the License.
*/
import org.apache.maven.bootstrap.download.DownloadFailedException;
import org.apache.maven.bootstrap.download.ArtifactResolver;
import org.apache.maven.bootstrap.download.DownloadFailedException;
import org.apache.maven.bootstrap.util.AbstractReader;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
@ -34,8 +35,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import com.sun.corba.se.impl.ior.ObjectAdapterIdArray;
/**
* Parse a POM.
*
@ -276,7 +275,7 @@ public class ModelReader
}
// actually, these should be transtive (see MNG-77) - but some projects have circular deps that way
ModelReader p = retrievePom( parentGroupId, parentArtifactId, parentVersion, "pom", inheritedScope, false,
ModelReader p = retrievePom( parentGroupId, parentArtifactId, parentVersion, inheritedScope, false,
excluded, Collections.EMPTY_LIST );
addDependencies( p.getDependencies(), parentDependencies, inheritedScope, excluded );
@ -529,7 +528,7 @@ public class ModelReader
excluded.addAll( dependency.getExclusions() );
ModelReader p = retrievePom( dependency.getGroupId(), dependency.getArtifactId(),
dependency.getVersion(), dependency.getType(),
dependency.getVersion(),
dependency.getScope(), resolveTransitiveDependencies, excluded,
dependency.getChain() );
@ -586,9 +585,8 @@ public class ModelReader
return false;
}
private ModelReader retrievePom( String groupId, String artifactId, String version, String type,
String inheritedScope, boolean resolveTransitiveDependencies, Set excluded,
List chain )
private ModelReader retrievePom( String groupId, String artifactId, String version, String inheritedScope,
boolean resolveTransitiveDependencies, Set excluded, List chain )
throws SAXException
{
String key = groupId + ":" + artifactId + ":" + version;
@ -657,4 +655,9 @@ public class ModelReader
{
return modules;
}
public File getProjectFile()
{
return pomFile;
}
}

View File

@ -32,6 +32,8 @@ public class JarMojo
{
private byte[] buffer = new byte[4096];
private static final String MF = "META-INF/MANIFEST.MF";
public void execute( File basedir, File jarFile )
throws Exception
{
@ -48,7 +50,8 @@ public class JarMojo
* @param includes a map <String, File> of items to be include in the outpur
* @param baseDir the directory to add
*/
protected void addDirectory( Map includes, File baseDir ) throws IOException
protected void addDirectory( Map includes, File baseDir )
throws IOException
{
addDirectory( includes, "", baseDir );
}
@ -60,7 +63,8 @@ public class JarMojo
* @param prefix value to be added to the front of jar entry names
* @param baseDir the directory to add
*/
protected void addDirectory( Map includes, String prefix, File baseDir ) throws IOException
protected void addDirectory( Map includes, String prefix, File baseDir )
throws IOException
{
addDirectory( includes, null, null, prefix, baseDir );
}
@ -74,7 +78,8 @@ public class JarMojo
* @param prefix value to be added to the front of jar entry names
* @param baseDir the directory to add
*/
protected void addDirectory( Map includes, String includesPattern, String excludesPattern, String prefix, File baseDir )
protected void addDirectory( Map includes, String includesPattern, String excludesPattern, String prefix,
File baseDir )
throws IOException
{
if ( !baseDir.exists() )
@ -110,14 +115,15 @@ public class JarMojo
* @param includes a Map<String, File>of items to include; the key is the jar entry name
* @throws IOException if there is a problem writing the archive or reading the sources
*/
protected void createJar( File jarFile, Map includes ) throws IOException
protected void createJar( File jarFile, Map includes )
throws IOException
{
File parentJarFile = jarFile.getParentFile();
if ( !parentJarFile.exists() )
{
parentJarFile.mkdirs();
}
JarOutputStream jos = createJar( jarFile, createManifest() );
JarOutputStream jos = createJar( jarFile, includes.containsKey( "META-INF/MANIFEST.MF" ) );
try
{
addEntries( jos, includes );
@ -138,7 +144,7 @@ public class JarMojo
Manifest mf = new Manifest();
Attributes attrs = mf.getMainAttributes();
attrs.putValue( Attributes.Name.MANIFEST_VERSION.toString(), "1.0" );
attrs.putValue( "Created-By", "2.0 (Apache Maven)" );
attrs.putValue( "Created-By", "Apache Maven Bootstrap Mini" );
return mf;
}
@ -146,17 +152,25 @@ public class JarMojo
* Create the specified jar file and return a JarOutputStream to it
*
* @param jarFile the jar file to create
* @param mf the manifest to use
* @param manifestIncluded if the manifest is included
* @return a JarOutputStream that can be used to write to that file
* @throws IOException if there was a problem opening the file
*/
protected JarOutputStream createJar( File jarFile, Manifest mf ) throws IOException
protected JarOutputStream createJar( File jarFile, boolean manifestIncluded )
throws IOException
{
jarFile.getParentFile().mkdirs();
FileOutputStream fos = new FileOutputStream( jarFile );
try
{
return new JarOutputStream( fos, mf );
if ( manifestIncluded )
{
return new JarOutputStream( fos );
}
else
{
return new JarOutputStream( fos, createManifest() );
}
}
catch ( IOException e )
{
@ -180,7 +194,8 @@ public class JarMojo
* @param includes a Map<String, File> of entries to add
* @throws IOException if there is a problem writing the archive or reading the sources
*/
protected void addEntries( JarOutputStream jos, Map includes ) throws IOException
protected void addEntries( JarOutputStream jos, Map includes )
throws IOException
{
for ( Iterator i = includes.entrySet().iterator(); i.hasNext(); )
{
@ -199,7 +214,8 @@ public class JarMojo
* @param source the file to add
* @throws IOException if there is a problem writing the archive or reading the sources
*/
protected void addEntry( JarOutputStream jos, String name, File source ) throws IOException
protected void addEntry( JarOutputStream jos, String name, File source )
throws IOException
{
FileInputStream fis = new FileInputStream( source );
try

22
bootstrap/bootstrap.sh Executable file
View File

@ -0,0 +1,22 @@
#!/bin/sh
# TODO: error checking
(
cd bootstrap-mini
./build
java -jar target/bootstrap-mini.jar install
)
BOOTSTRAP_JAR=../bootstrap-mini/target/bootstrap-mini-2.0.1-SNAPSHOT.jar
(
cd bootstrap-installer
java -jar $BOOTSTRAP_JAR package
)
(
cd ..
java -classpath bootstrap/bootstrap-installer/target/bootstrap-installer-2.0.1-SNAPSHOT.jar:bootstrap/bootstrap-mini/target/bootstrap-mini-2.0.1-SNAPSHOT.jar org.apache.maven.bootstrap.installer.BootstrapInstaller
)