Git Product home page Git Product logo

blaze's Introduction

Blaze by Fizzed

Maven Central

Java 8 Java 11 Java 17 Java 21

Linux MacOS Windows

Overview

A speedy, flexible, general purpose scripting and application launching stack for the JVM. Can replace shell scripts and plays nicely with other tools. Only requires a Java 8 runtime and adding blaze.jar to your project directory. Start writing portable and cross-platform scripts.

Blaze pulls together stable, mature libraries from the Java ecosystem into a light-weight package that lets you focus on getting things done. When you invoke blaze, it does the following:

  • Sets up console logging
  • Loads your optional configuration file(s)
  • Downloads runtime dependencies (e.g. jars from Maven central)
  • Loads and compiles your script(s)
  • Executes "tasks" (methods your script defines)

Includes the following features:

  • Write your applications (scripts) in whatever JVM language you prefer. Out-of-the-box support for
    • Java (.java) (8, 11, 17, 21, etc.)
    • Groovy (.groovy) (v4.0.15)
    • Kotlin (.kt) (v1.9.10)
    • JavaScript (.js) (via nashorn on Java 11+)
    • Or write your own (examples here, here, and here)
  • Zero-install required. Just drop blaze.jar into your project directory and you or others can run it with java -jar blaze.jar.
  • IDE support
  • Small size so you can commit blaze.jar to your repository
  • Excellent framework support for executing processes, modifying the filesystem, user interaction, http, and ssh.
  • Easily use any Java library as a dependency to accomplish whatever the framework doesn't provide.

Sponsorship & Support

Project by Fizzed, Inc. (Follow on Twitter: @fizzed_inc)

Developing and maintaining opensource projects requires significant time. If you find this project useful or need commercial support, we'd love to chat. Drop us an email at [email protected]

Project sponsors may include the following benefits:

  • Priority support (outside of Github)
  • Feature development & roadmap
  • Priority bug fixes
  • Privately hosted continuous integration tests for their unique edge or use cases

What is a blaze script?

A Blaze script is a 100% valid JVM class with public methods that typically uses an empty (root) package declaration. Each public method becomes the externally accessible task that can be called from the command-line. Since most JVM languages support this kind of structure, Blaze can easily support a wide variety of JVM languages.

More documentation

Try It

To give this project a quick try on your own machine, just run some of the examples:

git clone https://github.com/fizzed/blaze.git
cd blaze
java -jar blaze.jar examples/hello.java
java -jar blaze.jar examples/natives.java
java -jar blaze.jar examples/find_javas.java

Install to your project

Download blaze.jar to your project directory. If you have wget available

wget -O blaze.jar 'https://repo1.maven.org/maven2/com/fizzed/blaze-lite/1.5.2/blaze-lite-1.5.2.jar'

If you have curl available

curl -o blaze.jar 'https://repo1.maven.org/maven2/com/fizzed/blaze-lite/1.5.2/blaze-lite-1.5.2.jar'

Or simply download the file in your web browser and save it to your project directory with a name of blaze.jar

Write hello world blaze script in .java

Create blaze.java file

public class blaze {
    
    public void main() {
        System.out.println("Hello World!");
    }
    
}

Run blaze script

Since you named your file blaze.java, Blaze will find it automatically. You can run it like so

java -jar blaze.jar

If no task is supplied on the command line, Blaze will attempt to run the main task by default.

Write script that executes a process

Let's do a more useful example of how we use Blaze in many cases. Let's say you had a Maven project and wanted to execute a class with a main method. The syntax to do that in Maven becomes difficult to remember and communicate to other developers. Blaze lets you simplify the entry points to your project by exposing everything as named tasks.

import static com.fizzed.blaze.Systems.exec;

public class blaze {

    public void demo1() {
        exec(
           "mvn", "compile", "exec:java", "-Dexec.classpathScope=runtime",
           "-Dexec.mainClass=com.example.Demo1").run();
    }

    public void demo2() {
        exec(
           "mvn", "compile", "exec:java", "-Dexec.classpathScope=runtime",
           "-Dexec.mainClass=com.example.Demo2").run();
    }
}

You can now just run these with java -jar blaze.jar demo1 or java -jar blaze.jar demo2

But I can still do your previous example in a shell script?

Yeah, I suppose so. But you'd probably use two shell scripts to define the separate tasks and if you cared about platform portability, you'd be nice to also include .bat scripts for Windows users. However, when you want to do anything else that's remotely advanced, you'll start to appreciate having a more advanced environment.

An example of finding a specific JDK on your local system to execute a Maven test with it.

find_java.conf

blaze.dependencies = [
  "com.fizzed:jne:4.1.1"
]

find_java.java

public class blaze {

   private final Logger log = Contexts.logger();
   private final Config config = Contexts.config();
   private final Path projectDir = withBaseDir("..").toAbsolutePath();
    
   @Task
   public void test() throws Exception {
      // optional command-line arguments to control which jdk version or hardware architecture
      final Integer jdkVersion = this.config.value("jdk.version", Integer.class).orNull();
      final HardwareArchitecture jdkArch = ofNullable(this.config.value("jdk.arch").orNull())
              .map(HardwareArchitecture::resolve)
              .orElse(null);

      final long start = System.currentTimeMillis();
      final JavaHome jdkHome = new JavaHomeFinder()
              .jdk()
              .version(jdkVersion)
              .hardwareArchitecture(jdkArch)
              .preferredDistributions()
              .sorted(jdkVersion != null || jdkArch != null)  // sort if any criteria provided
              .find();

      log.info("");
      log.info("Detected {} (in {} ms)", jdkHome, (System.currentTimeMillis()-start));
      log.info("");

      exec("mvn", "clean", "test")
              .workingDir(projectDir)
              .env("JAVA_HOME", jdkHome.getDirectory().toString())
              .verbose()
              .run();
   }
    
}

Another example where we query git for the latest tag and use it to update a README file with it. We use this as a way to maintain a README file with the latest version pushed to Maven central

import com.fizzed.blaze.Contexts;
import static com.fizzed.blaze.Contexts.withBaseDir;
import static com.fizzed.blaze.Contexts.fail;
import static com.fizzed.blaze.Systems.exec;
import com.fizzed.blaze.core.Actions;
import com.fizzed.blaze.core.Blaze;
import com.fizzed.blaze.util.Streamables;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.slf4j.Logger;

public class blaze {
    static private final Logger log = Contexts.logger();
    
    private String latest_tag() {
        // get latest tag from git
        return exec("git", "describe", "--abbrev=0", "--tags")
            .runCaptureOutput()
            .toString()
            .trim();
    }
    
    public void update_readme() throws IOException {
        Path readmeFile = withBaseDir("../README.md");
        Path newReadmeFile = withBaseDir("../README.md.new");
        
        // find latest version via git tag, trim off leading 'v'
        String taggedVersion = latest_tag().substring(1);
        
        log.info("Tagged version: {}", taggedVersion);
        
        // find current version in readme using a regex to match
        // then apply a mapping function to return the first group of each match
        // then we only need to get the first matched group
        String versionRegex = ".*lite-(\\d+\\.\\d+\\.\\d+)\\.jar.*";
        String readmeVersion
            = Streamables.matchedLines(input(readmeFile), versionRegex, (m) -> m.group(1))
                .findFirst()
                .get();
        
        log.info("Readme version: {}", readmeVersion);
        
        if (readmeVersion.equals(taggedVersion)) {
            log.info("Versions match (no need to update README)");
            return;
        }
        
        // replace version in file and write a new version
        final Pattern replacePattern = Pattern.compile(readmeVersion);
        try (BufferedWriter writer = Files.newBufferedWriter(newReadmeFile)) {
            Files.lines(readmeFile)
                .forEach((l) -> {
                    Matcher matcher = replacePattern.matcher(l);
                    String newLine = matcher.replaceAll(taggedVersion);
                    try {
                        writer.append(newLine);
                        writer.append("\n");
                    } catch (IOException e) {
                        throw new UncheckedIOException(e);
                    }
                });
            writer.flush();
        }
        
        // replace readme with updated version
        Files.move(newReadmeFile, readmeFile, StandardCopyOption.REPLACE_EXISTING);
    }
}

Optionally install blaze on your PATH

While you can invoke blaze.jar as an executable jar by running

java -jar blaze.jar

Sometimes it's more convenient to have a system-wide executable installed on your PATH to make that even shorter. Blaze has a built-in method to copy a wrapper script to a directory. On Linux or Mac OSX, you can run the following

sudo java -jar blaze.jar -i /usr/local/bin

On Windows, open up a shell as an administrator (Start Menu -> Command Prompt > right mouse click Run as administrator), then run the following

java -jar blaze.jar -i C:\Windows\System32

Depending on your operating system, this will install either a blaze shell script or a blaze.bat batch script. Assuming /usr/local/bin or C:\Windows\System32 is already on your PATH (which normally it is), then you can now just run the following in your shell

blaze

IDE support

Writing your blaze scripts in an IDE is significantly more productive than trying to write them in a text editor. We initially tried writing our own IDE plugins to automatically recognize blaze was present, but that proved too difficult to maintain over IDE versions. As of Blaze v1.5.2+, there is a new simple method to enable IDE support across any IDE that supports Maven projects.

java -jar blaze.jar --generate-maven-project

This command will leverage the location of the script currently being executed, calculate the dependencies it needs to run, and then create a minimal pom.xml in the same directory. You can then open that pom.xml in any IDE, and you'll get all the full blown features of your IDE to efficiently write and maintain your blaze scripts.

The --generate-maven-project command will set the target source version to Java 8 by default. If you need to override this to something else, you can add a [blaze-script].conf file that is associated with your blaze script, and add the following configuration values:

java.source.version = 11

You can also pass this is on the command line:

blaze --generate-maven-project -Djava.source.version=17

Where to save your script(s)

Blaze is designed to play nicely with other popular JVM build tools such as Maven, Gradle, Ant, SBT, etc. Blaze is also designed to play nicely with your favorite IDE. If you are planning on a blaze-only project, then create a blaze.[ext] file in your project directory (at the same level as your blaze.jar). Your project directory would be

<project directory>/
    blaze.jar
    blaze.[ext]

The [ext] would be whatever JVM language you'd like to write your script in. So java would be .java, groovy would be .groovy, etc.

However, if you are using another build tool such as Maven, we'd suggest creating a sub-directory called .blaze or blaze and placing your blaze.[ext] script in there. Most Java IDEs compute classpaths for auto completion based on directory paths and placing your script in the root directory doesn't work very well with IDEs like Netbeans. So a maven project + blaze would be

<project directory>/
    .blaze/
        blaze.[ext]
    blaze.jar
    pom.xml

In either setup, you'd run your script identically. That's because blaze will first search the current directory for blaze.[ext] then .blaze/blaze.[ext] then blaze/blaze.[ext]

If you'd like to have more than one script, you can supply it on the command-line like so

java -jar blaze.jar path/to/script.[ext]

blaze's People

Contributors

dependabot[bot] avatar jjlauer avatar mikegager avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

blaze's Issues

Pipeline confusion?

I'm trying to emulate this...

echo "Hello World" | mail -r [email protected] -s "Testing email" [email protected]

And here is what I've tried so far...

        pipeline()
                .pipeInput(Streamables.input(new ByteArrayInputStream("Hello World".getBytes(StandardCharsets.UTF_8))))
                .add(exec("mail").args("-r", "[email protected]").args("-s", "Testing email").arg("[email protected]"))
                .pipeOutput(Streamables.standardOutput())
                .run();

And

    exec("mail")
        .args("-r", "[email protected]")
        .args("-s", "Testing email")
        .arg("[email protected]")
        .pipeInput(Streamables.input(new ByteArrayInputStream("Hello World".getBytes(StandardCharsets.UTF_8)))
        .pipeOutput(Streamables.standardOutput())
        .run()

And both hang. If I hit CTRL+C, I get (Interrupt -- one more to kill letter). And this is what mail outputs when there is nothing coming in on stdin. So how do I pipe text to a process?

License infringement

Your repository "blaze-kotlin" project is violating my rights as a developer to use the AGPL license.
At least one class of it - if not the whole - has been (at least initially) taken from my repository (https://github.com/xafero/dynkt) and then it has been illegally sublicensed under the terms of the ASL2!

Compiler path error

I used wget to download the blaze jar file on Windows:

wget -O blaze.jar 'http://repo1.maven.org/maven2/com/fizzed/blaze-lite/0.14.0/blaze-lite-0.14.0.jar'

And made the example "hello world" Java file in the same directory. I set JAVA_HOME to point to the Java 8 u102 JDK folder. I get compile errors when I attempt to run hello world:

    public class blaze {

        public void main() {
            System.out.println("Hello World!");
        }

    }

When I fire the Jar file I see this error ...

  • [ERROR] Unable to get or create path to compile classes

Command line session

    d:> DIR
     Volume in drive D is win

    22-Sep-2016  09:25         1,806,644 blaze.jar
    22-Sep-2016  09:26               113 blaze.java

    d:> echo %JAVA_HOME%
    b:\lang\java\jdk\v1.8\u102\x64

    d:> java -jar blaze.jar
    [INFO] Resolving dependencies...
    [INFO] Resolved dependencies in 14 ms
    [INFO] Compiling script...
    [ERROR] Unable to get or create path to compile classes
    com.fizzed.blaze.core.BlazeException: Unable to get or create path to compile classes
            at com.fizzed.blaze.jdk.BlazeJdkEngine.compile(BlazeJdkEngine.java:88)
            at com.fizzed.blaze.jdk.BlazeJdkEngine.compile(BlazeJdkEngine.java:43)
            at com.fizzed.blaze.core.Blaze$Builder.compileScript(Blaze.java:314)
            at com.fizzed.blaze.core.Blaze$Builder.build(Blaze.java:322)
            at com.fizzed.blaze.cli.Bootstrap.buildBlaze(Bootstrap.java:203)
            at com.fizzed.blaze.cli.Bootstrap.run(Bootstrap.java:132)
            at com.fizzed.blaze.cli.Bootstrap.run(Bootstrap.java:54)
            at com.fizzed.blaze.cli.Bootstrap.main(Bootstrap.java:42)
    Caused by: java.nio.file.NoSuchFileException: \Users\wmason\.blaze
            at sun.nio.fs.WindowsException.translateToIOException(Unknown Source)
            at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)
            at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)
            at sun.nio.fs.WindowsFileSystemProvider.createDirectory(Unknown Source)
            at java.nio.file.Files.createDirectory(Unknown Source)
            at com.fizzed.blaze.internal.ConfigHelper.userBlazeDir(ConfigHelper.java:138)
            at com.fizzed.blaze.internal.ConfigHelper.userBlazeEngineDir(ConfigHelper.java:155)
            at com.fizzed.blaze.internal.ConfigHelper.userBlazeEngineScriptClassesDir(ConfigHelper.java:182)
            at com.fizzed.blaze.jdk.BlazeJdkEngine.compile(BlazeJdkEngine.java:76)
            ... 7 more

Evidently I need to set-up some further config or specify something more to get things running.

Also I've added the blaze plugin for Netbeans, but I can't see anything in the Netbeans Options to do any set-up for the plugin.

This issue seems like a documentation thing, it would be nice though if it worked like the readme says.

Blaze doesn't run on Java 9

When I run balze on Windows with a installed Java 9 it crashes on start:

[INFO] Resolving dependencies... [INFO] Resolved dependencies in 561 ms [ERROR] Only classloaders of type URLClassLoader supported java.lang.IllegalArgumentException: Only classloaders of type URLClassLoader supported at com.fizzed.blaze.internal.ClassLoaderHelper.requireURLClassLoader(ClassLoaderHelper.java:46) at com.fizzed.blaze.internal.ClassLoaderHelper.addClassPath(ClassLoaderHelper.java:61) at com.fizzed.blaze.internal.ClassLoaderHelper.addClassPath(ClassLoaderHelper.java:53) at com.fizzed.blaze.core.Blaze$Builder.lambda$loadDependencies$0(Blaze.java:285) at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(Unknown Source) at java.base/java.util.stream.ReferencePipeline$Head.forEach(Unknown Source) at com.fizzed.blaze.core.Blaze$Builder.loadDependencies(Blaze.java:284) at com.fizzed.blaze.core.Blaze$Builder.build(Blaze.java:324) at com.fizzed.blaze.cli.Bootstrap.buildBlaze(Bootstrap.java:211) at com.fizzed.blaze.cli.Bootstrap.run(Bootstrap.java:140) at com.fizzed.blaze.cli.Bootstrap.run(Bootstrap.java:54) at com.fizzed.blaze.cli.Bootstrap.main(Bootstrap.java:42)

The URLClassLoader isn't supported anymore in Java 9.

More info for Java 9 migration and classloader and Casting To URL Class Loader

Avoid use of ivy cache if possible

Build internal dependency resolver caching system to avoid using Ivy as much as possible. Even in the best of circumstances Ivy takes about half a second to resolve fully cached dependencies.

Cannot access external images on template

Is there any problem to open images on the template? I tried to refer some images (located at same folder of template) using tags without luck.

Is there any impediment for this, or anyone can provide me a snippet that have this ?

Thanks in advance.

If no task supplied on command-line skip printing error

Blaze lists the tasks by default if the task entered on command-line doesn't exist. In the case where the user enters no tasks and the default task is not found it'd be a little more user-friendly to skip printing that error out.

Found a possible security concern

Hey there!

I belong to an open source security research community, and a member (@srikanthprathi) has found an issue, but doesn’t know the best way to disclose it.

If not a hassle, might you kindly add a SECURITY.md file with an email, or another contact method? GitHub recommends this best practice to ensure security issues are responsibly disclosed, and it would serve as a simple instruction for security researchers in the future.

Thank you for your consideration, and I look forward to hearing from you!

(cc @huntr-helper)

Is it possible to provide arguments (args) to a script?

Can I provide arguments which blaze passes to the script? So it would be possible to write:

fun main(args: Array<String>) {
    print(args)
}

and call java -jar blaze.jar -args mySuperArgument ?

I saw the blaze.conf property option. But in this way I have to add a blaze dependency / import to my script, which I want to avoid. And it's not flexible enough like arguments.

Or is the java -Dname=value the only possibility to pass an argument to a script? Which is not typical if i run the script without blaze, or want to test it with JUnit.

Make blaze native-image compatible

Corresponding issue in graalvm tracker: oracle/graal#772
Main point: currently blaze uses nashorn as js engine, potentially using graal.js instead will make blaze native-image build-able.
If it will be possible to build blaze with native-image then we'll get almost imstant startup time, which is must have for scripting.

Discussion about testable documents.

Hi @tristram found your youtube video introducing blaze.

We actually have a GUI demo that can achieve testable documentations. I found youtube kept blocking my comments so I have to reach you here. Feel free to delete this issue if it feels intrusive.

And we are kinda yearning for feedback right now. Would love to have a discussion on the potential of such tools with you!
https://www.reddit.com/r/SideProject/comments/1666ond/hello_hackers_advice_for_this_product/

Bash completion support

Support for bash completion of known tasks for a script would be incredibly useful and user-friendly. May require deeper integration with a terminal.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.