Skip to content

Commit

Permalink
Merge branch '__rultor'
Browse files Browse the repository at this point in the history
  • Loading branch information
rultor committed Jan 11, 2024
2 parents a831f3c + 26c02e1 commit 63cb73c
Show file tree
Hide file tree
Showing 7 changed files with 335 additions and 273 deletions.
193 changes: 11 additions & 182 deletions eo-maven-plugin/src/main/java/org/eolang/maven/BinarizeMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,34 +24,23 @@
package org.eolang.maven;

import com.jcabi.log.Logger;
import com.yegor256.Jaxec;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.SystemUtils;
import java.util.Collection;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.cactoos.experimental.Threads;
import org.cactoos.iterable.Filtered;
import org.cactoos.iterable.Mapped;
import org.cactoos.number.SumOf;
import org.cactoos.text.TextOf;
import org.cactoos.text.UncheckedText;
import org.eolang.maven.rust.BuildFailureException;
import org.eolang.maven.rust.Buildable;
import org.eolang.maven.rust.Names;

/**
* Compile binaries.
*
* @checkstyle ClassDataAbstractionCouplingCheck (500 lines)
* @since 0.1
* @todo #2118:90min Make it more generic. Perhaps by compilation of
* RustNode instead of going and building throw directories. Maybe it
* is better to get from BinarizeParseMojo.
*/
@Mojo(
name = "binarize",
Expand All @@ -62,11 +51,6 @@
@SuppressWarnings("PMD.LongVariable")
public final class BinarizeMojo extends SafeMojo {

/**
* Name of executable file which is result of cargo building.
*/
public static final String LIB = BinarizeMojo.common();

/**
* The directory where to binarize to.
*/
Expand Down Expand Up @@ -108,170 +92,15 @@ public final class BinarizeMojo extends SafeMojo {
private File eoPortalDir;

@Override
public void exec() {
new Moja<>(BinarizeParseMojo.class).with(
"names", new Names(this.namesDir.toPath())
).copy(this).execute();
final int total = new SumOf(
new Threads<>(
Runtime.getRuntime().availableProcessors(),
new Mapped<>(
project -> () -> {
this.build(project);
return 1;
},
new Filtered<>(
BinarizeMojo::valid,
targetDir.toPath().resolve("Lib").toFile().listFiles()
)
)
)
).intValue();
Logger.info(this, "Built in total %d cargo projects", total);
}

/**
* Calculates name for Rust shared library depending on OS.
* @return Name.
*/
private static String common() {
final String result;
if (SystemUtils.IS_OS_WINDOWS) {
result = "common.dll";
} else if (SystemUtils.IS_OS_LINUX) {
result = "libcommon.so";
} else if (SystemUtils.IS_OS_MAC) {
result = "libcommon.dylib";
} else {
throw new IllegalArgumentException(
String.format(
"Rust inserts are not supported in %s os. Only windows, linux and macos are allowed.",
System.getProperty("os.name")
)
);
}
return result;
}

/**
* Is the project valid?
* @param project File to check.
* @return True if valid. Otherwise, false.
*/
private static boolean valid(final File project) {
return project.isDirectory()
&& project.toPath().resolve("Cargo.toml").toFile().exists();
}

/**
* Builds cargo project.
* @param project Path to the project.
* @throws IOException If any issues with IO.
*/
private void build(final File project) throws IOException {
final File cached = this.cache
.resolve("Lib")
.resolve(project.getName())
.resolve("target").toFile();
if (BinarizeMojo.sameProject(
project.toPath(),
this.cache
.resolve("Lib")
.resolve(project.getName())
)) {
Logger.info(
this,
"content of %s was not changed since the last launch",
project.getName()
);
final File executable = cached.toPath()
.resolve("debug")
.resolve(BinarizeMojo.LIB)
.toFile();
if (executable.exists()) {
FileUtils.copyFile(
executable,
project.toPath()
.resolve("target")
.resolve("debug")
.resolve(BinarizeMojo.LIB)
.toFile()
);
}
} else {
final File target = project.toPath().resolve("target").toFile();
if (cached.exists()) {
Logger.info(this, "Copying %s to %s", cached, target);
FileUtils.copyDirectory(cached, target);
}
Logger.info(this, "Building %s rust project..", project.getName());
try {
new Jaxec("cargo", "build").withHome(project).execUnsafe();
} catch (final IOException | IllegalArgumentException ex) {
throw new BuildFailureException(
String.format(
"Failed to build cargo project with dest = %s",
project
),
ex
);
}
Logger.info(
this,
"Cargo building succeeded, update cached %s with %s",
cached,
target
);
FileUtils.copyDirectory(target.getParentFile(), cached.getParentFile());
}
public void exec() throws IOException {
final Collection<Buildable> ffis = new BinarizeParse(
this.generatedDir,
this.eoPortalDir,
new Names(this.namesDir.toPath()),
this.targetDir
).exec(this.scopedTojos().withOptimized());
ffis.stream().parallel().forEach(ffi -> ffi.build(this.cache));
Logger.info(this, "Built in total %d cargo projects", ffis.size());
}

/**
* Check if the project was not changed.
* @param src Directory in current target.
* @param cached Directory in cache.
* @return True if the project is the same.
*/
private static boolean sameProject(final Path src, final Path cached) {
return BinarizeMojo.sameFile(
src.resolve("src/foo.rs"), cached.resolve("src/foo.rs")
) && BinarizeMojo.sameFile(
src.resolve("src/lib.rs"), cached.resolve("src/lib.rs")
) && BinarizeMojo.sameFile(
src.resolve("Cargo.toml"), cached.resolve("Cargo.toml")
);
}

/**
* Check if the source file is the same as in cache.
* @param src Source file.
* @param cached Cache file.
* @return True if the same.
*/
private static boolean sameFile(final Path src, final Path cached) {
return cached.toFile().exists() && BinarizeMojo.uncomment(
new UncheckedText(
new TextOf(src)
).asString()
).equals(
BinarizeMojo.uncomment(
new UncheckedText(
new TextOf(cached)
).asString()
)
);
}

/**
* Removed the first line from the string.
* We need it because generated files are disclaimed.
* @param content Content.
* @return String without the first line.
* @checkstyle StringLiteralsConcatenationCheck (8 lines)
*/
private static String uncomment(final String content) {
return content.substring(
1 + content.indexOf(System.getProperty("line.separator"))
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,8 @@
import java.util.Collection;
import java.util.Map;
import java.util.function.BiFunction;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.cactoos.map.MapOf;
import org.eolang.maven.rust.Buildable;
import org.eolang.maven.rust.FFINode;
import org.eolang.maven.rust.Names;
import org.eolang.maven.rust.RustNode;
Expand All @@ -56,15 +53,8 @@
* @checkstyle ClassDataAbstractionCouplingCheck (500 lines)
* @since 0.1
*/
@Mojo(
name = "binarize_parse",
defaultPhase = LifecyclePhase.PROCESS_SOURCES,
threadSafe = true,
requiresDependencyResolution = ResolutionScope.COMPILE
)

@SuppressWarnings("PMD.LongVariable")
public final class BinarizeParseMojo extends SafeMojo {
public final class BinarizeParse {

/**
* The directory where to binarize to.
Expand All @@ -90,7 +80,7 @@ public final class BinarizeParseMojo extends SafeMojo {
* Map that matches ffi insert xpath to building of FFINode.
*/
private static final
Map<String, BiFunction<XML, BinarizeParseMojo, FFINode>> FACTORY = new MapOf<>(
Map<String, BiFunction<XML, BinarizeParse, FFINode>> FACTORY = new MapOf<>(
"/program/rusts/rust",
(node, mojo) -> new RustNode(
node,
Expand All @@ -105,39 +95,65 @@ public final class BinarizeParseMojo extends SafeMojo {
* Target directory.
* @checkstyle MemberNameCheck (7 lines)
*/
@Parameter(
required = true,
defaultValue = "${project.build.directory}/eo-binaries"
)
@SuppressWarnings("PMD.UnusedPrivateField")
private File generatedDir;
private final File generatedDir;

/**
* The directory with portal project.
* @checkstyle MemberNameCheck (8 lines)
*/
@Parameter(
property = "eo.portal",
required = true,
defaultValue = "${project.basedir}/src/main/rust/eo"
)
@SuppressWarnings("PMD.UnusedPrivateField")
private File eoPortalDir;
private final File eoPortalDir;

/**
* To uniquely name different ffi inerts.
*/
private Names names;
private final Names names;

@Override
public void exec() throws IOException {
/**
* To uniquely name different ffi inerts.
* @checkstyle MemberNameCheck (7 lines)
*/
private final File targetDir;

/**
* Ctor.
* @param generated Generated directory.
* @param portal Directory to portal dependency.
* @param names Names.
* @param target Target directory.
* @checkstyle ParameterNumberCheck (10 lines)
*/
public BinarizeParse(
final File generated,
final File portal,
final Names names,
final File target
) {
this.generatedDir = generated;
this.eoPortalDir = portal;
this.names = names;
this.targetDir = target;
}

/**
* Parse ffi nodes in tojos.
* @param tojos Tojos where to parse ffi node,
* @return Collection of {@link FFINode}s that will be then also compiled.
* @throws IOException if any issue with IO.
*/
public Collection<Buildable> exec(final Collection<ForeignTojo> tojos) throws IOException {
final Collection<Buildable> res = new ArrayList<>(0);
new File(this.targetDir.toPath().resolve("Lib/").toString()).mkdirs();
for (final ForeignTojo tojo : this.scopedTojos().withOptimized()) {
for (final ForeignTojo tojo : tojos) {
final Path file = tojo.verified();
this.getFFIs(new XMLDocument(file))
.forEach(FFINode::generateUnchecked);
for (final FFINode ffi: this.getFFIs(new XMLDocument(file))) {
ffi.generateUnchecked();
if (ffi instanceof Buildable) {
res.add((Buildable) ffi);
}
}
}
this.names.save();
return res;
}

/**
Expand All @@ -152,7 +168,7 @@ private XML addFFIs(
final String name = input.xpath("/program/@name").get(0);
final Place place = new Place(name);
final Train<Shift> trn = new SpyTrain(
BinarizeParseMojo.TRAIN,
BinarizeParse.TRAIN,
place.make(this.targetDir.toPath().resolve(BinarizeMojo.DIR), "")
);
return new Xsline(trn).pass(input);
Expand All @@ -167,7 +183,7 @@ private XML addFFIs(
private Collection<FFINode> getFFIs(final XML input) {
final Collection<FFINode> ret = new ArrayList<>(0);
final XML injected = this.addFFIs(input);
BinarizeParseMojo.FACTORY.forEach(
BinarizeParse.FACTORY.forEach(
(xpath, ctor) -> injected
.nodes(xpath)
.forEach(node -> ret.add(ctor.apply(node, this)))
Expand Down
Loading

0 comments on commit 63cb73c

Please sign in to comment.