Brian O'Connor

Adding BuckLibGenerator to autogenerate lib/BUCK

Change-Id: I7eab26f57d4f5886b1512b687fca75d684938d46
1 -# ***** This file was auto-generated at Mon May 02 11:42:36 PDT 2016. Do not edit this file manually. ***** 1 +# ***** This file was auto-generated at Wed May 04 19:19:10 PDT 2016. Do not edit this file manually. *****
2 osgi_feature_group( 2 osgi_feature_group(
3 name = 'COMPILE', 3 name = 'COMPILE',
4 visibility = ['PUBLIC'], 4 visibility = ['PUBLIC'],
...@@ -187,9 +187,9 @@ remote_jar ( ...@@ -187,9 +187,9 @@ remote_jar (
187 187
188 remote_jar ( 188 remote_jar (
189 name = 'onos-atomix', 189 name = 'onos-atomix',
190 - out = 'atomix-1.0.onos-20160502.173651-190.jar', 190 + out = 'atomix-1.0.onos-20160505.013719-220.jar',
191 - url = 'https://oss.sonatype.org/content/repositories/snapshots/org/onosproject/atomix/1.0.onos-SNAPSHOT/atomix-1.0.onos-20160502.173651-190.jar', 191 + url = 'https://oss.sonatype.org/content/repositories/snapshots/org/onosproject/atomix/1.0.onos-SNAPSHOT/atomix-1.0.onos-20160505.013719-220.jar',
192 - sha1 = '763da0295d060271ae223db474dd024a7e84c629', 192 + sha1 = '9dabad079e1fcd15f58cf995b84eda562b8de21e',
193 maven_coords = 'org.onosproject:atomix:1.0.onos-SNAPSHOT', 193 maven_coords = 'org.onosproject:atomix:1.0.onos-SNAPSHOT',
194 visibility = [ 'PUBLIC' ], 194 visibility = [ 'PUBLIC' ],
195 ) 195 )
......
1 +#FIXME build this dynamically
2 +
3 +URL = 'https://oss.sonatype.org/content/repositories/snapshots/org/onosproject/libgen/1.0-SNAPSHOT/libgen-1.0-20160505.022015-2.jar'
4 +SHA = 'fa29f6f5432587df65e55a7d0c99d1454577dcfd'
5 +
6 +prebuilt_jar(
7 + name = 'libgen',
8 + binary_jar = ':libgen-jar',
9 + visibility = [ 'PUBLIC' ],
10 +)
11 +
12 +remote_file (
13 + name = 'libgen-jar',
14 + out = 'libgen.jar',
15 + url = URL,
16 + sha1 = SHA,
17 +)
...\ No newline at end of file ...\ No newline at end of file
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<!--
3 + ~ Copyright 2016-present Open Networking Laboratory
4 + ~
5 + ~ Licensed under the Apache License, Version 2.0 (the "License");
6 + ~ you may not use this file except in compliance with the License.
7 + ~ You may obtain a copy of the License at
8 + ~
9 + ~ http://www.apache.org/licenses/LICENSE-2.0
10 + ~
11 + ~ Unless required by applicable law or agreed to in writing, software
12 + ~ distributed under the License is distributed on an "AS IS" BASIS,
13 + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 + ~ See the License for the specific language governing permissions and
15 + ~ limitations under the License.
16 + -->
17 +<project xmlns="http://maven.apache.org/POM/4.0.0"
18 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
19 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
20 + <modelVersion>4.0.0</modelVersion>
21 +
22 + <parent>
23 + <groupId>org.onosproject</groupId>
24 + <artifactId>onos-base</artifactId>
25 + <version>1</version>
26 + <relativePath/>
27 + </parent>
28 +
29 + <groupId>org.onosproject</groupId>
30 + <artifactId>libgen</artifactId>
31 + <packaging>jar</packaging>
32 + <version>1.0-SNAPSHOT</version>
33 +
34 + <description>Buck third-party library generator</description>
35 + <url>http://onosproject.org/</url>
36 +
37 + <scm>
38 + <connection>scm:git:https://gerrit.onosproject.org/onos</connection>
39 + <developerConnection>scm:git:https://gerrit.onosproject.org/onos</developerConnection>
40 + <url>http://gerrit.onosproject.org/</url>
41 + </scm>
42 +
43 + <licenses>
44 + <license>
45 + <name>Apache License, Version 2.0</name>
46 + <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
47 + </license>
48 + </licenses>
49 +
50 + <dependencies>
51 + <dependency>
52 + <groupId>com.fasterxml.jackson.core</groupId>
53 + <artifactId>jackson-core</artifactId>
54 + <version>2.7.0</version>
55 + </dependency>
56 + <dependency>
57 + <groupId>com.fasterxml.jackson.core</groupId>
58 + <artifactId>jackson-databind</artifactId>
59 + <version>2.7.0</version>
60 + </dependency>
61 + <dependency>
62 + <groupId>org.eclipse.aether</groupId>
63 + <artifactId>aether-api</artifactId>
64 + <version>1.1.0</version>
65 + </dependency>
66 + <dependency>
67 + <groupId>org.eclipse.aether</groupId>
68 + <artifactId>aether-util</artifactId>
69 + <version>1.1.0</version>
70 + </dependency>
71 + <!--<dependency>-->
72 + <!--<groupId>commons-configuration</groupId>-->
73 + <!--<artifactId>commons-configuration</artifactId>-->
74 + <!--<version>1.10</version>-->
75 + <!--</dependency>-->
76 + <!--<dependency>-->
77 + <!--<groupId>commons-collections</groupId>-->
78 + <!--<artifactId>commons-collections</artifactId>-->
79 + <!--<version>3.2.2</version>-->
80 + <!--</dependency>-->
81 + <dependency>
82 + <groupId>org.apache.maven</groupId>
83 + <artifactId>maven-aether-provider</artifactId>
84 + <version>3.3.9</version>
85 + </dependency>
86 + <dependency>
87 + <groupId>org.eclipse.aether</groupId>
88 + <artifactId>aether-connector-basic</artifactId>
89 + <version>1.1.0</version>
90 + </dependency>
91 + <dependency>
92 + <groupId>org.eclipse.aether</groupId>
93 + <artifactId>aether-transport-file</artifactId>
94 + <version>1.1.0</version>
95 + </dependency>
96 + <dependency>
97 + <groupId>org.eclipse.aether</groupId>
98 + <artifactId>aether-transport-http</artifactId>
99 + <version>1.1.0</version>
100 + </dependency>
101 + <dependency>
102 + <groupId>org.slf4j</groupId>
103 + <artifactId>slf4j-simple</artifactId>
104 + <version>1.6.2</version>
105 + <scope>runtime</scope>
106 + </dependency>
107 + </dependencies>
108 +
109 + <build>
110 + <plugins>
111 + <plugin>
112 + <groupId>org.apache.maven.plugins</groupId>
113 + <artifactId>maven-compiler-plugin</artifactId>
114 + <version>2.5.1</version>
115 + <configuration>
116 + <source>1.8</source>
117 + <target>1.8</target>
118 + </configuration>
119 + </plugin>
120 +
121 + <plugin>
122 + <groupId>org.apache.maven.plugins</groupId>
123 + <artifactId>maven-shade-plugin</artifactId>
124 + <version>2.4.2</version>
125 + <configuration>
126 + <transformers>
127 + <transformer
128 + implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
129 + <mainClass>org.onosproject.libgen.BuckLibGenerator</mainClass>
130 + </transformer>
131 + </transformers>
132 + <filters>
133 + <filter>
134 + <artifact>*</artifact>
135 + </filter>
136 + </filters>
137 + </configuration>
138 + <executions>
139 + <execution>
140 + <phase>package</phase>
141 + <goals>
142 + <goal>shade</goal>
143 + </goals>
144 + </execution>
145 + </executions>
146 + </plugin>
147 +
148 + <plugin>
149 + <groupId>org.apache.maven.plugins</groupId>
150 + <artifactId>maven-dependency-plugin</artifactId>
151 + <version>2.10</version>
152 + </plugin>
153 + </plugins>
154 + </build>
155 +
156 +</project>
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.libgen;
17 +
18 +import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
19 +import org.eclipse.aether.DefaultRepositorySystemSession;
20 +import org.eclipse.aether.RepositorySystem;
21 +import org.eclipse.aether.RepositorySystemSession;
22 +import org.eclipse.aether.artifact.Artifact;
23 +import org.eclipse.aether.artifact.DefaultArtifact;
24 +import org.eclipse.aether.collection.CollectRequest;
25 +import org.eclipse.aether.collection.CollectResult;
26 +import org.eclipse.aether.collection.DependencyCollectionException;
27 +import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
28 +import org.eclipse.aether.graph.Dependency;
29 +import org.eclipse.aether.graph.DependencyFilter;
30 +import org.eclipse.aether.graph.DependencyNode;
31 +import org.eclipse.aether.impl.DefaultServiceLocator;
32 +import org.eclipse.aether.repository.LocalRepository;
33 +import org.eclipse.aether.repository.RemoteRepository;
34 +import org.eclipse.aether.repository.RepositoryPolicy;
35 +import org.eclipse.aether.resolution.ArtifactRequest;
36 +import org.eclipse.aether.resolution.ArtifactResult;
37 +import org.eclipse.aether.resolution.DependencyRequest;
38 +import org.eclipse.aether.resolution.VersionRangeRequest;
39 +import org.eclipse.aether.resolution.VersionRangeResolutionException;
40 +import org.eclipse.aether.resolution.VersionRangeResult;
41 +import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
42 +import org.eclipse.aether.spi.connector.transport.TransporterFactory;
43 +import org.eclipse.aether.transport.file.FileTransporterFactory;
44 +import org.eclipse.aether.transport.http.HttpTransporterFactory;
45 +import org.eclipse.aether.util.artifact.JavaScopes;
46 +import org.eclipse.aether.util.filter.DependencyFilterUtils;
47 +import org.eclipse.aether.version.Version;
48 +
49 +import java.io.BufferedReader;
50 +import java.io.FileReader;
51 +import java.io.Reader;
52 +import java.nio.file.Paths;
53 +import java.util.Arrays;
54 +import java.util.Collections;
55 +import java.util.List;
56 +import java.util.jar.Attributes;
57 +import java.util.jar.JarFile;
58 +
59 +import static org.eclipse.aether.repository.RepositoryPolicy.CHECKSUM_POLICY_WARN;
60 +import static org.eclipse.aether.repository.RepositoryPolicy.UPDATE_POLICY_ALWAYS;
61 +
62 +/**
63 + * Resolver capable of resolving Maven coordinates to a Maven artifact.
64 + */
65 +public class AetherResolver {
66 + private static final String CENTRAL_URL = "http://repo1.maven.org/maven2/";
67 +
68 + private static RepositorySystem system;
69 + private static RepositorySystemSession session;
70 + private static final RemoteRepository CENTRAL =
71 + new RemoteRepository.Builder("central", "default", CENTRAL_URL).build();
72 +
73 + private final String repoUrl;
74 +
75 + static {
76 + DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
77 + locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class );
78 + locator.addService(TransporterFactory.class, FileTransporterFactory.class );
79 + locator.addService(TransporterFactory.class, HttpTransporterFactory.class );
80 +
81 + locator.setErrorHandler( new DefaultServiceLocator.ErrorHandler()
82 + {
83 + @Override
84 + public void serviceCreationFailed( Class<?> type, Class<?> impl, Throwable exception )
85 + {
86 + exception.printStackTrace();
87 + }
88 + } );
89 +
90 + AetherResolver.system = locator.getService( RepositorySystem.class );
91 +
92 + DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
93 +
94 + LocalRepository localRepo = new LocalRepository("target/local-repo" );
95 + session.setLocalRepositoryManager( system.newLocalRepositoryManager( session, localRepo ) );
96 +
97 + //session.setTransferListener( new ConsoleTransferListener() );
98 + //session.setRepositoryListener( new ConsoleRepositoryListener() );
99 + AetherResolver.session = session;
100 + }
101 +
102 + public static BuckArtifact getArtifact(String name, String uri, String repo) {
103 + return new AetherResolver(repo).build(name, uri);
104 + }
105 +
106 + private AetherResolver(String repoUrl) {
107 + this.repoUrl = repoUrl;
108 + }
109 +
110 + private BuckArtifact build(String name, String uri) {
111 + uri = uri.replaceFirst("mvn:", "");
112 + Artifact artifact = new DefaultArtifact(uri);
113 + String originalVersion = artifact.getVersion();
114 + try {
115 + artifact = artifact.setVersion(newestVersion(artifact));
116 + artifact = resolveArtifact(artifact);
117 + String sha = getSha(artifact);
118 + boolean osgiReady = isOsgiReady(artifact);
119 +
120 + if (originalVersion.endsWith("-SNAPSHOT")) {
121 + String url = String.format("%s/%s/%s/%s/%s-%s.%s",
122 + repoUrl,
123 + artifact.getGroupId().replace('.', '/'),
124 + artifact.getArtifactId(),
125 + originalVersion,
126 + artifact.getArtifactId(),
127 + artifact.getVersion(),
128 + artifact.getExtension());
129 + String mavenCoords = String.format("%s:%s:%s",
130 + artifact.getGroupId(),
131 + artifact.getArtifactId(),
132 + originalVersion);
133 + return BuckArtifact.getArtifact(name, url, sha, mavenCoords, osgiReady);
134 + }
135 + return BuckArtifact.getArtifact(name, artifact, sha, repoUrl, osgiReady);
136 + } catch (Exception e) {
137 + throw new RuntimeException(e);
138 + }
139 + }
140 +
141 + private Artifact resolveArtifact(Artifact artifact) throws Exception {
142 + ArtifactRequest request = new ArtifactRequest();
143 + request.setArtifact(artifact);
144 + request.setRepositories(repositories());
145 + ArtifactResult result = system.resolveArtifact(session, request);
146 + return result.getArtifact();
147 + }
148 +
149 + private boolean isOsgiReady(Artifact artifact) throws Exception {
150 + JarFile jar = new JarFile(artifact.getFile());
151 + Attributes attrs = jar.getManifest().getMainAttributes();
152 + return attrs.getValue("Bundle-SymbolicName") != null &&
153 + attrs.getValue("Bundle-Version") != null;
154 + }
155 +
156 + private String getSha(Artifact artifact) throws Exception {
157 + String directory = artifact.getFile().getParent();
158 + String file = String.format("%s-%s.%s.sha1",
159 + artifact.getArtifactId(),
160 + artifact.getVersion(),
161 + artifact.getExtension());
162 + String shaPath = Paths.get(directory, file).toString();
163 +
164 + try (Reader reader = new FileReader(shaPath)) {
165 + return new BufferedReader(reader).readLine().trim().split(" ", 2)[0];
166 + }
167 + }
168 +
169 + private String newestVersion(Artifact artifact) throws VersionRangeResolutionException {
170 + VersionRangeRequest rangeRequest = new VersionRangeRequest();
171 + rangeRequest.setArtifact(artifact);
172 + rangeRequest.setRepositories(repositories());
173 +
174 + VersionRangeResult rangeResult = system.resolveVersionRange(session, rangeRequest );
175 +
176 + Version newestVersion = rangeResult.getHighestVersion();
177 +
178 + return newestVersion.toString();
179 + }
180 +
181 + public List<RemoteRepository> repositories()
182 + {
183 + if (repoUrl != null && repoUrl.length() > 0) {
184 + RepositoryPolicy policy = new RepositoryPolicy(true,
185 + UPDATE_POLICY_ALWAYS,
186 + CHECKSUM_POLICY_WARN);
187 + RemoteRepository repository =
188 + new RemoteRepository.Builder("temp", "default", repoUrl)
189 + .setSnapshotPolicy(policy).build();
190 + return Arrays.asList(CENTRAL, repository);
191 + }
192 +
193 + return Collections.singletonList(CENTRAL);
194 + }
195 +}
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.libgen;
17 +
18 +import org.eclipse.aether.artifact.Artifact;
19 +
20 +/**
21 + * Representation of a remote artifact for Buck.
22 + */
23 +public abstract class BuckArtifact {
24 +
25 + private final String name;
26 + private final String sha;
27 + private final boolean osgiReady;
28 +
29 + public static BuckArtifact getArtifact(String name, Artifact artifact, String sha, String repo, boolean osgiReady) {
30 + return new MavenArtifact(name, artifact, sha, repo, osgiReady);
31 + }
32 + public static BuckArtifact getArtifact(String name, String url, String sha, String mavenCoords, boolean osgiReady) {
33 + return new HTTPArtifact(name, url, sha, mavenCoords, osgiReady);
34 + }
35 + public static BuckArtifact getArtifact(String name, String url, String sha) {
36 + return new HTTPArtifact(name, url, sha, null, true);
37 + }
38 +
39 + public BuckArtifact(String name, String sha, boolean osgiReady) {
40 + this.name = name;
41 + this.sha = sha;
42 + this.osgiReady = osgiReady;
43 + }
44 +
45 + public String name() {
46 + return name;
47 + }
48 +
49 + abstract String fileName();
50 +
51 + abstract String url();
52 +
53 + private String jarTarget() {
54 + return name != null ? name : fileName();
55 + }
56 +
57 + private boolean isPublic() {
58 + return name != null;
59 + }
60 +
61 + boolean isOsgiReady() {
62 + return osgiReady;
63 + }
64 +
65 + String mavenCoords() {
66 + return null;
67 + }
68 +
69 + public String getBuckFragment() {
70 + String visibility = isPublic() ? "[ 'PUBLIC' ]" : "[]";
71 +
72 + boolean isJar = fileName().endsWith(".jar");
73 + String output = (isJar ? "remote_jar" : "remote_file") + " (\n" +
74 + " name = '%s',\n" + // jar target
75 + " out = '%s',\n" + // jar file name
76 + " url = '%s',\n" + // maven url
77 + " sha1 = '%s',\n" + // artifact sha
78 + ( isJar && mavenCoords() != null ?
79 + " maven_coords = '"+ mavenCoords()+"',\n" : "" ) +
80 + " visibility = %s,\n" +
81 + ")\n\n";
82 +
83 + return String.format(output, jarTarget(), fileName(), url(), sha, visibility);
84 + }
85 +
86 + private static class HTTPArtifact extends BuckArtifact {
87 + private final String url;
88 + private final String mavenCoords;
89 +
90 + public HTTPArtifact(String name, String url, String sha, String mavenCoords, boolean osgiReady) {
91 + super(name, sha, osgiReady);
92 + this.url = url;
93 + this.mavenCoords = mavenCoords;
94 + }
95 +
96 + @Override
97 + String fileName() {
98 + String[] parts = url.split("/");
99 + return parts[parts.length - 1];
100 + }
101 +
102 + @Override
103 + String mavenCoords() {
104 + return mavenCoords;
105 + }
106 +
107 + @Override
108 + String url() {
109 + return url;
110 + }
111 + }
112 +
113 + private static class MavenArtifact extends BuckArtifact {
114 + private final Artifact artifact;
115 + private final String repo;
116 +
117 + private MavenArtifact(String name, Artifact artifact, String sha, String repo, boolean osgiReady) {
118 + super(name, sha, osgiReady);
119 + this.artifact = artifact;
120 + this.repo = repo;
121 + }
122 +
123 + @Override
124 + String url() {
125 + //mvn:[repo:]groupId:artifactId:[extension:[classifier:]]:version
126 + StringBuilder mvnUrl = new StringBuilder("mvn:");
127 + if (repo != null && repo.length() > 0) {
128 + mvnUrl.append(repo).append(':');
129 + }
130 + mvnUrl.append(artifact.getGroupId()).append(':')
131 + .append(artifact.getArtifactId()).append(':')
132 + .append(artifact.getExtension()).append(':');
133 + if (artifact.getClassifier() != null && artifact.getClassifier().length() > 0) {
134 + mvnUrl.append(artifact.getClassifier()).append(':');
135 + }
136 + mvnUrl.append(artifact.getVersion());
137 + return mvnUrl.toString();
138 + }
139 +
140 + //FIXME get sources jars
141 +
142 + @Override
143 + String mavenCoords() {
144 + String classifer = artifact.getClassifier();
145 + if (!isOsgiReady()) {
146 + classifer = "NON-OSGI" + classifer;
147 + }
148 +
149 + if ("jar".equals(artifact.getExtension().toLowerCase()) &&
150 + classifer.length() == 0) {
151 + // shorter form
152 + return String.format("%s:%s:%s",
153 + artifact.getGroupId(),
154 + artifact.getArtifactId(),
155 + artifact.getVersion());
156 + }
157 + return String.format("%s:%s:%s:%s:%s",
158 + artifact.getGroupId(),
159 + artifact.getArtifactId(),
160 + artifact.getExtension(),
161 + classifer,
162 + artifact.getVersion());
163 + }
164 +
165 + @Override
166 + String fileName() {
167 + return String.format("%s-%s.%s",
168 + artifact.getArtifactId(),
169 + artifact.getVersion(),
170 + artifact.getExtension());
171 + }
172 + }
173 +}
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.libgen;
17 +
18 +import com.fasterxml.jackson.core.JsonParser;
19 +import com.fasterxml.jackson.databind.JsonNode;
20 +import com.fasterxml.jackson.databind.ObjectMapper;
21 +import com.fasterxml.jackson.databind.node.ObjectNode;
22 +
23 +import java.io.File;
24 +import java.io.FileInputStream;
25 +import java.io.FileNotFoundException;
26 +import java.io.IOException;
27 +import java.io.InputStream;
28 +import java.io.PrintWriter;
29 +import java.net.URL;
30 +import java.net.URLConnection;
31 +import java.security.MessageDigest;
32 +import java.security.NoSuchAlgorithmException;
33 +import java.util.ArrayList;
34 +import java.util.Date;
35 +import java.util.HashMap;
36 +import java.util.List;
37 +import java.util.Map;
38 +
39 +/**
40 + * Generates a BUCK file from a JSON file containing third-party library
41 + * dependencies.
42 + */
43 +public class BuckLibGenerator {
44 +
45 +// public static final String MAVEN_COORDS = "maven_coords";
46 +// public static final String COMPILE_ONLY = "compile_only";
47 +// public static final String RUNTIME_ONLY = "runtime_only";
48 +
49 + private final ObjectNode jsonRoot;
50 + private final List<BuckArtifact> artifacts = new ArrayList<>();
51 + private final List<BuckLibrary> libraries = new ArrayList<>();
52 +
53 + /**
54 + * Main entry point.
55 + *
56 + * @param args command-line arguments; JSON input file and BUCK output file
57 + */
58 + public static void main(String[] args) throws Exception {
59 + if (args.length < 2) {
60 + System.err.println("Not enough args.\n\nUSAGE: <json file> <output>");
61 + System.exit(5);
62 + }
63 +
64 + // Parse args
65 + String jsonFilePath = args[0];
66 + String outputBuckPath = args[1];
67 +
68 + // Load and parse input JSON file
69 + ObjectMapper mapper = new ObjectMapper();
70 + mapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
71 + ObjectNode json = (ObjectNode) mapper.reader()
72 + .readTree(new FileInputStream(jsonFilePath));
73 +
74 + // Traverse dependencies and build a dependency graph (DAG)
75 + BuckLibGenerator generator = new BuckLibGenerator(json).resolve();
76 +
77 + // Write the output BUCK file
78 + generator.write(outputBuckPath);
79 + System.out.printf("\nFinish writing %s\n", outputBuckPath);
80 + }
81 +
82 + public BuckLibGenerator(ObjectNode root) {
83 + this.jsonRoot = root;
84 + }
85 +
86 + private BuckArtifact parseArtifact(Map.Entry<String, JsonNode> entry) {
87 + String name = entry.getKey();
88 + JsonNode value = entry.getValue();
89 + String uri;
90 + String repo = null;
91 + if (value.isTextual()) {
92 + uri = value.asText();
93 + } else if (value.isObject()) {
94 + uri = value.get("uri").asText();
95 + repo = value.get("repo").asText("");
96 + } else {
97 + throw new RuntimeException("Unknown element for name: " + name +
98 + " of type: " + value.getNodeType());
99 + }
100 +
101 + System.out.print(name + " ");
102 + System.out.flush();
103 + BuckArtifact buckArtifact;
104 + if (uri.startsWith("http")) {
105 + String sha = getHttpSha(uri);
106 + buckArtifact = BuckArtifact.getArtifact(name, uri, sha);
107 + } else if (uri.startsWith("mvn")) {
108 + uri = uri.replaceFirst("mvn:", "");
109 +// if (repo != null) {
110 +// System.out.println(name + " " + repo);
111 +// }
112 + buckArtifact = AetherResolver.getArtifact(name, uri, repo);
113 + } else {
114 + throw new RuntimeException("Unsupported artifact uri: " + uri);
115 + }
116 + System.out.println(buckArtifact.url());
117 + return buckArtifact;
118 + }
119 +
120 + private BuckLibrary parseLibrary(Map.Entry<String, JsonNode> entry) {
121 + String libraryName = entry.getKey();
122 + JsonNode list = entry.getValue();
123 + if (list.size() == 0) {
124 + throw new RuntimeException("Empty library: " + libraryName);
125 + }
126 +
127 + List<String> libraryTargets = new ArrayList<>(list.size());
128 + list.forEach(node -> {
129 + String name;
130 + if (node.isObject()) {
131 + name = node.get("name").asText();
132 + } else if (node.isTextual()) {
133 + name = node.asText();
134 + } else {
135 + throw new RuntimeException("Unknown node type: " + node.getNodeType());
136 + }
137 + if (!name.contains(":")) {
138 + name = ':' + name;
139 + }
140 + libraryTargets.add(name);
141 + });
142 +
143 + return BuckLibrary.getLibrary(libraryName, libraryTargets);
144 + }
145 +
146 + public BuckLibGenerator resolve() {
147 + jsonRoot.get("artifacts").fields().forEachRemaining(entry -> {
148 + BuckArtifact buckArtifact = parseArtifact(entry);
149 + artifacts.add(buckArtifact);
150 +// String artifactName = buckArtifact.name();
151 +// if (artifacts.putIfAbsent(artifactName, buckArtifact) != null) {
152 +// error("Duplicate artifact: %s", artifactName);
153 +// }
154 + });
155 +
156 + jsonRoot.get("libraries").fields().forEachRemaining(entry -> {
157 + BuckLibrary library = parseLibrary(entry);
158 + libraries.add(library);
159 +// String libraryName = library.name();
160 +// if (libraries.putIfAbsent(libraryName, library) != null) {
161 +// error("Duplicate library: %s", libraryName);
162 +// }
163 + });
164 +
165 + return this;
166 + }
167 +
168 + void write(String outputFilePath) {
169 + File outputFile = new File(outputFilePath);
170 + if (!outputFile.setWritable(true)) {
171 + error("Failed to make %s to writeable.", outputFilePath);
172 + }
173 + try (PrintWriter writer = new PrintWriter(outputFile)) {
174 + writer.write(String.format(
175 + "# ***** This file was auto-generated at %s. Do not edit this file manually. *****\n",
176 + new Date().toString()));
177 + libraries.forEach(library -> writer.print(library.getBuckFragment()));
178 + artifacts.forEach(artifact -> writer.print(artifact.getBuckFragment()));
179 + writer.flush();
180 + } catch (FileNotFoundException e) {
181 + error("File not found: %s", outputFilePath);
182 + }
183 + if (!outputFile.setReadOnly()) {
184 + error("Failed to set %s to read-only.", outputFilePath);
185 + }
186 + }
187 +
188 + String getHttpSha(String url) {
189 + //TODO look in buck-out/gen first
190 + //FIXME need http download cache
191 + try {
192 + URLConnection connection = new URL(url).openConnection();
193 + connection.connect();
194 + InputStream stream = connection.getInputStream();
195 + MessageDigest md = MessageDigest.getInstance("SHA-1");
196 +
197 + byte[] buffer = new byte[8192];
198 + int read;
199 + while ((read = stream.read(buffer)) >= 0) {
200 + md.update(buffer, 0, read);
201 + }
202 + StringBuilder result = new StringBuilder();
203 + byte[] digest = md.digest();
204 + for (byte b : digest) {
205 + result.append(String.format("%02x", b));
206 + }
207 + return result.toString();
208 + } catch (IOException | NoSuchAlgorithmException e) {
209 + throw new RuntimeException(e);
210 + }
211 + }
212 +
213 + private void error(String format, String... args) {
214 + if (!format.endsWith("\n")) {
215 + format += '\n';
216 + }
217 + System.err.printf(format, args);
218 + System.exit(1);
219 + }
220 +}
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.libgen;
17 +
18 +import org.eclipse.aether.artifact.Artifact;
19 +
20 +import java.util.HashSet;
21 +import java.util.List;
22 +import java.util.Set;
23 +
24 +/**
25 + * Representation of a java library for Buck.
26 + */
27 +public class BuckLibrary {
28 +
29 + private final String name;
30 + private final List<String> targets;
31 +
32 + private final Set<Artifact> provided = new HashSet<>();
33 + private final Set<Artifact> runtime = new HashSet<>();
34 +
35 + public static BuckLibrary getLibrary(String libraryName, List<String> libraryTargets) {
36 + return new BuckLibrary(libraryName, libraryTargets);
37 + }
38 +
39 + private BuckLibrary(String name, List<String> targets) {
40 + this.name = name;
41 + this.targets = targets;
42 + }
43 +
44 + public String name() {
45 + return name;
46 + }
47 +
48 + public String getBuckFragment() {
49 + StringBuilder output = new StringBuilder()
50 + .append("osgi_feature_group(\n")
51 + .append(String.format(" name = '%s',\n", name))
52 + .append(" visibility = ['PUBLIC'],\n")
53 + .append(" exported_deps = [");
54 +
55 + targets.forEach(target -> output.append(String.format("\n '%s',", target)));
56 + output.append("\n ],\n)\n\n");
57 +
58 + return output.toString();
59 + }
60 +}
...\ No newline at end of file ...\ No newline at end of file
1 +#!/bin/bash
2 +
3 +cd $(buck root 2>/dev/null)
4 +
5 +java -jar $(buck build //tools/build/libgen:libgen --show-output 2>/dev/null | tail -1 | cut -d' ' -f2) lib/deps.json lib/BUCK
...@@ -100,10 +100,11 @@ staged_apps = ['$(location %s)' % a for a in APPS] ...@@ -100,10 +100,11 @@ staged_apps = ['$(location %s)' % a for a in APPS]
100 sources = [ '$(location :onos-features)', ] 100 sources = [ '$(location :onos-features)', ]
101 sources += staged_repos + staged_apps 101 sources += staged_repos + staged_apps
102 102
103 +import time
103 genrule( 104 genrule(
104 name = 'onos-package', 105 name = 'onos-package',
105 out = 'onos.tar.gz', 106 out = 'onos.tar.gz',
106 - bash = '$(exe //buck-tools:onos-stage) $OUT $(location :onos-karaf) ' + ' '.join(sources), 107 + bash = 'echo %s >/dev/null; $(exe //buck-tools:onos-stage) $OUT $(location :onos-karaf) ' % time.time() + ' '.join(sources),
107 visibility = [ 'PUBLIC' ], 108 visibility = [ 'PUBLIC' ],
108 ) 109 )
109 110
......