From d84c8bc150ff9d1e5e0800dadfa79774e7c0a7ee Mon Sep 17 00:00:00 2001 From: neodix Date: Mon, 3 Jun 2024 18:02:04 +0200 Subject: [PATCH] detect FIFTPATH automatically. --- .../ton/java/smartcontract/FuncCompiler.java | 98 +++++++++++++++++-- .../unittests/TestFuncCompiler.java | 15 +-- 2 files changed, 98 insertions(+), 15 deletions(-) diff --git a/smartcontract/src/main/java/org/ton/java/smartcontract/FuncCompiler.java b/smartcontract/src/main/java/org/ton/java/smartcontract/FuncCompiler.java index dfbe47f5..f7568760 100644 --- a/smartcontract/src/main/java/org/ton/java/smartcontract/FuncCompiler.java +++ b/smartcontract/src/main/java/org/ton/java/smartcontract/FuncCompiler.java @@ -1,5 +1,6 @@ package org.ton.java.smartcontract; +import jdk.nashorn.internal.ir.annotations.Ignore; import lombok.Builder; import lombok.Getter; import lombok.extern.java.Log; @@ -13,10 +14,7 @@ import java.io.File; import java.io.IOException; import java.nio.charset.Charset; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; +import java.util.concurrent.*; import static java.util.Objects.nonNull; @@ -34,6 +32,12 @@ public class FuncCompiler { String fiftAsmLibraryPath; String fiftSmartcontLibraryPath; + @Ignore + private String funcExecutable; + @Ignore + private String fiftExecutable; + + public static class FuncCompilerBuilder { } @@ -42,9 +46,69 @@ public static FuncCompilerBuilder builder() { } private static class CustomFuncCompilerBuilder extends FuncCompilerBuilder { + private String errorMsg = "Make sure you have fift and func installed. See https://github.com/ton-blockchain/packages for instructions."; + private String funcAbsolutePath; + private String fiftAbsolutePath; + @Override public FuncCompiler build() { + if (StringUtils.isEmpty(super.funcExecutablePath)) { + System.out.println("checking if func is installed..."); + + try { + ProcessBuilder pb = new ProcessBuilder("func", "-h").redirectErrorStream(true); + Process p = pb.start(); + p.waitFor(5, TimeUnit.SECONDS); + if (p.exitValue() != 2) { + throw new Error("Cannot execute simple func command.\n" + errorMsg); + } + funcAbsolutePath = detectAbsolutePath("func"); + + System.out.println("func found at " + funcAbsolutePath); + super.funcExecutable = "func"; + + } catch (Exception e) { + e.printStackTrace(); + throw new Error("Cannot execute simple func command.\n" + errorMsg); + } + } else { + System.out.println("using " + super.funcExecutablePath); + super.funcExecutable = super.funcExecutablePath; + } + + if (StringUtils.isEmpty(super.fiftExecutablePath)) { + System.out.println("checking if fift is installed..."); + try { + ProcessBuilder pb = new ProcessBuilder("fift", "-h").redirectErrorStream(true); + Process p = pb.start(); + p.waitFor(5, TimeUnit.SECONDS); + if (p.exitValue() != 2) { + throw new Error("Cannot execute simple fift command.\n" + errorMsg); + } + fiftAbsolutePath = detectAbsolutePath("fift"); + System.out.println("fift found at " + fiftAbsolutePath); + super.fiftExecutable = "fift"; + } catch (Exception e) { + throw new Error("Cannot execute simple fift command.\n" + errorMsg); + } + } else { + System.out.println("using " + super.fiftExecutablePath); + super.fiftExecutable = super.fiftExecutablePath; + } + + if (StringUtils.isEmpty(super.fiftAsmLibraryPath)) { + super.fiftAsmLibraryPath = new File(fiftAbsolutePath).getParent() + File.separator + ".." + File.separator + + "lib" + File.separator + "ton" + File.separator + "bin" + File.separator + "lib"; + } + + if (StringUtils.isEmpty(super.fiftSmartcontLibraryPath)) { + super.fiftSmartcontLibraryPath = new File(fiftAbsolutePath).getParent() + File.separator + ".." + File.separator + + "lib" + File.separator + "ton" + File.separator + "bin" + File.separator + "smartcont"; + } + + System.out.println("using FIFTPATH: " + super.fiftAsmLibraryPath + ":" + super.fiftSmartcontLibraryPath); + return super.build(); } } @@ -66,16 +130,16 @@ public String compile() throws IOException, ExecutionException, InterruptedExcep return Utils.bytesToHex(bocContent); } - public String executeFunc(String... params) throws ExecutionException, InterruptedException { - Pair> result = execute("func", params); + private String executeFunc(String... params) throws ExecutionException, InterruptedException { + Pair> result = execute(funcExecutable, params); return result.getRight().get(); } - public String executeFift(String... params) { + private String executeFift(String... params) { String[] withInclude = new String[]{"-I", fiftAsmLibraryPath + ":" + fiftSmartcontLibraryPath}; String[] all = ArrayUtils.addAll(withInclude, params); - Pair> result = execute("fift", all); + Pair> result = execute(fiftExecutable, all); if (nonNull(result)) { try { return result.getRight().get(); @@ -88,7 +152,7 @@ public String executeFift(String... params) { } } - public Pair> execute(String pathToBinary, String... command) { + private Pair> execute(String pathToBinary, String... command) { String[] withBinaryCommand = new String[]{pathToBinary}; @@ -131,4 +195,20 @@ public Pair> execute(String pathToBinary, String... comm return null; } } + + private static String detectAbsolutePath(String executable) { + try { + ProcessBuilder pb; + if (Utils.getOS() == Utils.OS.WINDOWS) { + pb = new ProcessBuilder("where", executable).redirectErrorStream(true); + } else { + pb = new ProcessBuilder("which", executable).redirectErrorStream(true); + } + Process p = pb.start(); + p.waitFor(5, TimeUnit.SECONDS); + return IOUtils.toString(p.getInputStream(), Charset.defaultCharset()); + } catch (Exception e) { + throw new Error("Cannot detect absolute path to executable " + executable); + } + } } \ No newline at end of file diff --git a/smartcontract/src/test/java/org/ton/java/smartcontract/unittests/TestFuncCompiler.java b/smartcontract/src/test/java/org/ton/java/smartcontract/unittests/TestFuncCompiler.java index 268e34e2..d786f2cf 100644 --- a/smartcontract/src/test/java/org/ton/java/smartcontract/unittests/TestFuncCompiler.java +++ b/smartcontract/src/test/java/org/ton/java/smartcontract/unittests/TestFuncCompiler.java @@ -25,7 +25,7 @@ @RunWith(JUnit4.class) public class TestFuncCompiler { /** - * Make sure you have fift and func installed. See packages for instructions. + * Make sure you have fift and func installed in your system. See packages for instructions. * Example is based on new-wallet-v4r2.fc smart contract. You can specify path to any smart contract. */ @Test @@ -36,8 +36,10 @@ public void testFuncCompiler() throws URISyntaxException, InterruptedException, FuncCompiler smcFunc = FuncCompiler.builder() // .contractPath("C:/stablecoin/contracts/jetton-minter.fc") .contractPath(contractAbsolutePath) - .fiftAsmLibraryPath("C:/ProgramData/chocolatey/lib/ton/bin/lib") // todo detect automatically - .fiftSmartcontLibraryPath("C:/ProgramData/chocolatey/lib/ton/bin/smartcont") +// .fiftExecutablePath("C:/ProgramData/chocolatey/bin/fift") +// .funcExecutablePath("C:/ProgramData/chocolatey/bin/func") +// .fiftAsmLibraryPath("C:/ProgramData/chocolatey/lib/ton/bin/lib") +// .fiftSmartcontLibraryPath("C:/ProgramData/chocolatey/lib/ton/bin/smartcont") .build(); String codeCellHex = smcFunc.compile(); @@ -49,7 +51,8 @@ public void testFuncCompiler() throws URISyntaxException, InterruptedException, .storeUint(42, 32) // wallet id .storeBytes(keyPair.getPublicKey()) .storeUint(0, 1) //plugins dict empty - .endCell().toHex(); + .endCell() + .toHex(); log.info("codeCellHex {}", codeCellHex); log.info("dataCellHex {}", dataCellHex); @@ -81,8 +84,8 @@ public void testFuncCompiler() throws URISyntaxException, InterruptedException, Cell deployMessageBody = CellBuilder.beginCell() .storeUint(42, 32) // wallet-id - .storeInt(-1, 32) // valid-until - .storeUint(0, 32) //seqno + .storeInt(-1, 32) // valid-until + .storeUint(0, 32) //seqno .endCell(); smc.deploy(deployMessageBody);