Reputation: 24447
The JCenter Maven repository will be down in some month.
How can I migrate all artifact to Sonatype before it will be deleted.
Upvotes: 2
Views: 350
Reputation: 24447
I have solve this with multiple steps:
The follow code snippet which I have used will not work out of the box because it used internal private API. But it can help as start point. Of course you need an sonatype account and a gpg ring file. The secret properties are saved in the gradle.properties. You need also to customize the group name that the company used in all 3 files.
package tool;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nonnull;
import com.inet.lib.util.IOFunctions;
public class DownloadJCenter {
// this path will be cut on save
private static String basePath;
private static File root;
public static void main( String[] args ) throws IOException {
basePath = "/";
URL startURL = new URL( "https://jcenter.bintray.com/com/company/" );
root = new File( "jcenter" );
load( startURL );
}
/**
* Load the URL iterative
*
* @param parent the URL to load
* @throws IOException if any error occur
*/
static void load( @Nonnull URL parent ) throws IOException {
System.err.println( parent );
InputStream input = IOFunctions.openStreamSupportingRedirect( parent, 5000 );
String content = IOFunctions.readString( input, StandardCharsets.UTF_8 );
List<URL> urls = extractUrls( parent, content );
for( URL url : urls ) {
String path = url.getPath();
if( path.endsWith( "/" ) ) {
load( url );
} else {
input = IOFunctions.openStreamSupportingRedirect( url, 5000 );
byte[] bytes = IOFunctions.readBytes( input );
File file = new File( root, path.substring( basePath.length() ) );
file.getParentFile().mkdirs();
try (FileOutputStream fos = new FileOutputStream( file )) {
fos.write( bytes );
}
}
}
}
/**
* Extract the URLs from the content of page
*
* @param parent the parent URL for relative URLs
* @param content the page content
* @return list of found URLs
* @throws IOException if any error occur
*/
@Nonnull
static List<URL> extractUrls( URL parent, @Nonnull String content ) throws IOException {
ArrayList<URL> result = new ArrayList<>();
int idx = 0;
while( true ) {
int idx1 = content.indexOf( "href=\"", idx );
if( idx1 < 0 ) {
break;
}
idx1 += 6;
int idx2 = content.indexOf( "\"", idx1 );
String urlStr = content.substring( idx1, idx2 );
if( !urlStr.startsWith( ".." ) ) {
result.add( new URL( parent, urlStr ) );
}
idx = idx2;
}
return result;
}
}
package tool;
import java.io.File;
import java.io.IOException;
import java.lang.ProcessBuilder.Redirect;
import java.util.ArrayList;
import java.util.HashMap;
import com.inet.error.ErrorCode;
import com.inet.lib.util.IOFunctions;
import com.inet.shared.utils.Version;
/**
* Deploy to the Sonatype server.
*/
public class DeploySonatype {
private static final String gradle = "C:/Users/...../gradle-6.7.1/bin/gradle.bat";
public static void main( String[] args ) throws IOException {
File root = new File( "jcenter/com/company" );
for( File file : root.listFiles() ) {
if( file.isDirectory() ) {
String archivesBaseName = file.getName();
deployLibrary( archivesBaseName, file );
}
}
}
static void deployLibrary( String archivesBaseName, File libraryDir ) throws IOException {
HashMap<Version,File> versionDirs = new HashMap<>();
for( File file : libraryDir.listFiles() ) {
if( file.isDirectory() ) {
versionDirs.put( new Version( file.getName()), file );
}
}
ArrayList<Version> versions = new ArrayList( versionDirs.keySet() );
versions.sort( null );// old versions first
for( Version version : versions ) {
File dir = versionDirs.get( version );
deployVersion( archivesBaseName, version, dir );
}
}
static void deployVersion( String archivesBaseName, Version version, File dir ) throws IOException {
System.err.println( archivesBaseName + " " + version + " " + dir );
File script = IOFunctions.getFile( DeploySonatype.class.getResource( "deploy.gradle" ) );
IOFunctions.deleteDir( new File( script.getParent(), "build" ) ); // clean from previous run
ArrayList<String> command = new ArrayList<>();
command.add( gradle );
command.add( "-b" );
command.add( "\"" + script.getPath() + "\"" );
command.add( "--stacktrace" );
command.add( "-ParchivesBaseName=" + archivesBaseName );
command.add( "-Pversion=" + version );
command.add( "-PartifactDir=" + dir.getAbsolutePath() );
command.add( "uploadArchives" );
System.err.println( command );
ProcessBuilder processBuilder = new ProcessBuilder( command );
processBuilder.redirectOutput( Redirect.INHERIT );
processBuilder.redirectError( Redirect.INHERIT );
processBuilder.environment().put( "JAVA_HOME", System.getProperty( "java.home" ) );
Process start = processBuilder.start();
try {
int exitValue = start.waitFor();
if( exitValue != 0 ) {
throw new IOException( "Exit Value: " + exitValue );
}
} catch( InterruptedException ex ) {
ErrorCode.throwAny( ex );
}
}
}
/****************************************
* Deploy to Maven
****************************************/
apply plugin: 'maven'
apply plugin: 'signing'
group = 'com.company'
println archivesBaseName + "/" + version + " -> " + artifactDir // come from Java as parameter
task copyArtifact(type: Copy) {
from file( artifactDir )
into file("$buildDir/artifacts" )
}
task setupArchives {
dependsOn copyArtifact
doLast {
artifacts {
fileTree( dir: file( "$buildDir/artifacts" ) ).each {
archives file: it
println "\t" + it
}
}
signing {
if (project.hasProperty("signing.keyId") ){
sign configurations.archives
}
}
}
}
uploadArchives {
dependsOn setupArchives
repositories {
mavenDeployer {
beforeDeployment { MavenDeployment deployment ->
signing {
fileTree( dir: file( "$buildDir/artifacts" ) ).each {
sign it
println "sign: " + it
}
}
}
if (project.hasProperty("ossrhUsername") ){
repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") {
authentication(userName: project["ossrhUsername"], password: project["ossrhPassword"])
}
}
}
}
}
Upvotes: 1