Giter Site home page Giter Site logo

rife2 / bld Goto Github PK

View Code? Open in Web Editor NEW
159.0 6.0 9.0 746 KB

Pure java build tool for developers who don't like dealing with build tools

Home Page: https://rife2.com/bld

License: Apache License 2.0

Shell 0.11% Batchfile 0.02% Java 99.84% HTML 0.03%
build build-tool compile java run test buildtool bld

bld's Introduction

License Java bld Release Maven Central Nexus Snapshot gradle-ci Tests


Welcome

RIFE2 is a full-stack, no-declaration, framework to quickly and effortlessly create web applications with modern Java.

RIFE2 is built on the foundations of the original RIFE framework that was popular from 2002-2010. Since then, the world and Java have changed and many of the original RIFE APIs could finally be replaced with pure Java, no-XML, no-YAML, leaving only type-safe expressive code.

RIFE2 preserves most of the original features and adds new ones, for a fraction of the footprint and with even greater developer productivity than before. RIFE2 is created by Geert Bevin, one of the first Java Champions and speaker at many Java conferences.

TIP: If you use IntelliJ IDEA as your IDE, consider installing the RIFE2 IDEA Plug-in.
It will greatly enhance your coding experience.

This is a quick tutorial, the full documentation contains a lot more information.

The RIFE2 Javadocs complement the documentation with many more details.

Watch the video

Why RIFE2?

A frequently asked question is: "Why choose RIFE2 over other popular frameworks"?

The short answer is that RIFE2 is different, it's designed to create web applications quickly with small teams. It has challenged and will always challenge the status-quo. It's not meant to replace enterprise-level frameworks like Spring or JEE, though I've used it for enterprise applications. RIFE2 leverages the power of the Java platform for web applications that you'd usually write with scripting languages. Productivity and maintainability is key, and you'll find that you get 90% of the work done for 10% of the effort, and can still integrate with other Java libraries and frameworks where you need it.

RIFE2 has features that after 20 years still can't be found elsewhere:
web continuations, bidirectional template engine, bean-centric metadata system, full-stack without dependencies, metadata-driven SQL builders, content management framework, full localization support, resource abstraction, persisted cron-like scheduler, continuations-based workflow engine.

Most of these features have stood the test of time and after 20 years still prove to be great choices for web application development. RIFE2 has learned from decades of experience and improves on these original features in many ways.

RIFE2 also has features that have been adopted by others, but that usually lack the convenience of the tight integration throughout a full-stack.

For instance: out-of-container tests can analyze the structure of the resulting templates without having to parse HTML, the authentication system is built from all the other pieces of the full-stack and seamlessly integrates into your web application, URLs are generated from the configuration you created without the risk of becoming stale, the logic-less templates are really purely content driven and can generate any text-based format (JSON, XML, HTML, SVG, SQL), ... and much more.

RIFE2 is the red pill, ready to show you how deep the rabbit hole can go, if you're up for it!

Quickstart

Hello World Example

This is how you get started with a Hello World site.

public class HelloWorld extends Site {
    public void setup() {
        get("/hello", c -> c.print("Hello World"));
    }

    public static void main(String[] args) {
        new Server().start(new HelloWorld());
    }
}

The main method spins up the integrated embedded Jetty server, so that you can immediately start coding. The same HelloWorld class can be added as a parameter value to your web.xml, requiring absolute no changes to your code between development and production.

Out-of-container testing is a first-class citizen in RIFE2, directly interacting with your Site class to simulate full request-response interactions, without having to spin up a servlet container.

This is how you could test the example above with JUnit 5:

class HelloTest {
    @Test void verifyHelloWorld() {
        var m = new MockConversation(new HelloWorld());
        assertEquals("Hello World", m.doRequest("/hello").getText());
    }
}

Type-safe Links and URLs

One of the most brittle aspects of web application development is typing links and URLs as text literals, without anything guaranteeing they remain correct when your routes change or when you deploy your application in different web application contexts. RIFE2's routing API allows all your application links to be generated correctly without any effort on your behalf.

Let's add a new route that contains an HTML link towards the previous Hello World route.

You can see that routes don't have to be created inside the setup() method, but can also be created as part of your Site's construction, allowing the routes to be stored in fields.

public class HelloLink extends Site {
    Route hello = get("/hello", c -> c.print("Hello World"));
    Route link = get("/link", c-> c.print("<a href='" + c.urlFor(hello) + "'>Hello</a>"));

    public static void main(String[] args) {
        new Server().start(new HelloLink());
    }
}

We can now test this as such:

class HelloTest {
    @Test void verifyHelloLink() {
        var m = new MockConversation(new HelloLink());
        assertEquals("Hello World", m.doRequest("/link")
            .getParsedHtml().getLinkWithText("Hello")
            .follow().getText());
    }
}

Bidirectional Logic-Less Templates

The main impetus that had me create RIFE2, was RIFE's unique template engine.

RIFE2's templates contain two main concepts:

  • values - that can be filled in with content and data
  • blocks - that will be stripped away and that provide content snippets

Your Java code will compose the final layout by assigning and appending blocks, and by putting data into values. Let's rewrite the HelloLink example above with a template.

In this example, no template manipulation is done in Java yet.

Instead, it introduces the {{v route:hello/}} value tag, which will automatically be replaced with the URL of the route that is available with that field name in your active Site.

public class HelloTemplate extends Site {
    Route hello = get("/hello", c -> c.print("Hello World"));
    Route link = get("/link", c-> c.print(c.template("HelloTemplate")));

    public static void main(String[] args) {
        new Server().start(new HelloTemplate());
    }
}

With HelloTemplate.html being:

<!DOCTYPE html>
<html lang="en">
<body>
<a href="{{v route:hello/}}">Hello</a>
</body>
</html>

Note that RIFE2 internally transforms your templates into Java classes by generating optimized bytecode.

This happens on-the-fly during development. For production, templates can be pre-compiled, making them incredibly fast.

Template Manipulation

Let's change the example some more and create a single route that can respond to both get and post requests.

  • the get request will display a form with a single button to click.
  • the post request will receive the form's submission and display Hello World.
public class HelloForm extends Site {
    Route hello = route("/hello", c -> {
        var t = c.template("HelloForm");
        switch (c.method()) {
            case GET -> t.setBlock("content", "form");
            case POST -> t.setBlock("content", "text");
        }
        c.print(t);
    });

    public static void main(String[] args) {
        new Server().start(new HelloForm());
    }
}

With HelloForm.html being:

<!DOCTYPE html>
<html lang="en">
<body>
<!--v content/-->
<!--b form-->
<form action="{{v route:action:hello/}}" method="post" name="hello">
  <!--v route:inputs:hello/-->
  <input type="submit" name="Submit">
</form>
<!--/b-->
<!--b text--><p id="greeting">Hello World</p><!--/b-->
</body>
</html>

NOTE: that the route: value tag from the above has been split into route:action: and route:inputs:, generating hidden HTML form inputs for parameters instead of query string parameters.

You can see that the template contains all the pieces to create both pages:

  • the value named content
  • the block named form
  • the block named text

In Java, we simply assign either block to the value, depending on what we want to display.

Another benefit is that RIFE2's template tags can be HTML comments, making them completely invisible. This allows you to work on your HTML design as usual and preview the template file with a regular browser.

Finally, let's include a test for this functionality:

class HelloTest {
    @Test void verifyHelloForm() {
        var m = new MockConversation(new HelloForm());
        var r = m.doRequest("/hello").getParsedHtml()
            .getFormWithName("hello").submit();
        assertEquals("Hello World", r.getParsedHtml()
            .getDocument().body()
            .getElementById("greeting").text());
    }
}

Just the top of the rabbit hole

Thanks for reading until the end!

This was merely a quick introduction to whet your appetite, RIFE2 comes with a comprehensive and easy to read manual with many examples and pragmatic explanations.

If you have any questions, suggestions, ideas or just want to chat, feel free to post on the forums or to join us on Discord.

Read more in the full documentation and RIFE2 Javadocs.

bld's People

Contributors

ethauvin avatar gbevin avatar sombriks 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

bld's Issues

bld does not build

❱ java -version
openjdk version "20.0.1" 2023-04-18
OpenJDK Runtime Environment Temurin-20.0.1+9 (build 20.0.1+9)
OpenJDK 64-Bit Server VM Temurin-20.0.1+9 (build 20.0.1+9, mixed mode, sharing)

❱ cd ; mkdir tmp ; cd tmp ; git clone [email protected]:rife2/bld.git ; cd bld
[...]

❱ ./bld
Updating bld extensions...
Downloading: https://repo1.maven.org/maven2/com/uwyn/rife2/bld-antlr4/1.2.0/bld-antlr4-1.2.0.jar ... not found
Downloading: https://repo.rife2.com/releases/com/uwyn/rife2/bld-antlr4/1.2.0/bld-antlr4-1.2.0.jar ... done
[...more downloading...]

/home/myuser/tmp/bld/src/bld/java/rife/BldBuild.java:26: error: cannot find symbol
public class BldBuild extends AbstractRife2Build {
                              ^
  symbol: class AbstractRife2Build
/home/myuser/tmp/bld/src/bld/java/rife/BldBuild.java:29: error: cannot find symbol
        name = "bld";
        ^
  symbol:   variable name
  location: class rife.BldBuild

[...40 more similar erorrs...]

❱ ./bld 2>| grep 'error: cannot find symbol' | wc -l
42

Unreliable evaluation of variable $USER_HOME$ for IntelliJ IDEA when using Windows Subsystem for Linux

The generated configuration file bld.xml for IntelliJ IDEA uses the variable $USER_HOME$ to declare the path to bld (<root url="jar://$USER_HOME$/.bld/dist/bld-1.7.0.jar!/" />) which does not evaluate to correct path when bld is installed via Windows Subsystem for Linux and IntelliJ IDEA is installed under Windows.

Given the user bob and bld is installed under WSL.

Path to bld: \\wsl$\Ubuntu\home\bob\.bld\dist\bld-1.7.0.jar

IntelliJ IDEA will however evaluate $USER_HOME$/.bld/dist/bld-1.7.0.jar to C:\Users\bob\.bld\dist\bld-1.7.0.jar and thus won't find the path to rife.bld.Project.

It "only" seems to impact the IntelliJ IDEA editor when browsing the build class, the run configuration for IDEA still works fine.

[1.9.1] Issue with extensions dependencies.

Maybe I missed something in the docs, but here is something strange. I expected below extensions config to download 2 jars in lib/bld for my build code to use:

bld.downloadExtensionJavadoc=false
bld.downloadExtensionSources=true
bld.extensions=peruncs:peruncs-platform:0.0.1, com.uwyn.rife2:bld:1.9.1
bld.repositories=MAVEN_LOCAL,MAVEN_CENTRAL
bld.downloadLocation=
bld.sourceDirectories=
bld.version=1.9.1

but I only get peruncs-platform-0.0.1.jar , the other one did not download?

Build Maven Central artifacts

Can I build somehow artifacts for maven central?

Sorry for spamming issues... I just saw your repo to day and I love it.

[1.9.1] better exception message

I had a pice of Builder code like this:

public class Build extends BaseProject {
    ...
    public Build() {
        r//epositories = List.of(MAVEN_LOCAL, MAVEN_CENTRAL);
        ..
    }

It turns out that I had to explicitly configure the repositories, despite that I had this in my bld-wrpapper.properties:

bld.repositories=MAVEN_LOCAL,MAVEN_CENTRAL

Is this my mistake, assuming that the config repos will flow in my Build object? What happens when I do not set the repositories properly, is shown below. However, it would have been much better if the error also spelled out the repos it was given - I would have notice immediately that the repositories config was empty.

So, please improve the eror message to include the repositories list.

hristo:~$./bld -s helidon-download
rife.bld.dependencies.exceptions.ArtifactNotFoundException: Couldn't find artifact for dependency 'io.helidon.http:helidon-http:4.0.8' at 
        at rife.bld.dependencies.DependencyResolver.getMavenPom(DependencyResolver.java:417)
        at rife.bld.dependencies.DependencyResolver.getAllDependencies(DependencyResolver.java:126)
        at rife.bld.dependencies.DependencyScopes.resolveScopedDependencies(DependencyScopes.java:147)
        at rife.bld.dependencies.DependencyScopes.resolveCompileDependencies(DependencyScopes.java:75)
        at rife.bld.operations.DownloadOperation.executeDownloadCompileDependencies(DownloadOperation.java:60)
        at rife.bld.operations.DownloadOperation.execute(DownloadOperation.java:44)
        at rife.bld.operations.AbstractOperation.executeOnce(AbstractOperation.java:75)
        at rife.bld.BaseProject.download(BaseProject.java:499)
        at peruncs.shared.Build.downloadHelidon(Build.java:81)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at rife.bld.CommandAnnotated.execute(CommandAnnotated.java:27)
        at rife.bld.BuildExecutor.executeCommand(BuildExecutor.java:454)
        at rife.bld.BuildExecutor.execute(BuildExecutor.java:230)
        at rife.bld.BaseProject.execute(BaseProject.java:1679)
        at rife.bld.BuildExecutor.start(BuildExecutor.java:274)
        at peruncs.shared.Build.main(Build.java:19)

Clarity around 'create'

The following commands are supported.

  create        Creates a new project
  create-base   Creates a new baseline Java project with minimal commands
  create-blank  Creates a new blank Java project with standard commands
  create-lib    Creates a new Java library with minimal commands
  create-rife2  Creates a new RIFE2 project

The "create " line would be even better if it suggested there would be an interactive prompt for base, blank, lib, etc.

Base and blank and lib might be better if they suggested roughly how many files that would be under git control at the end of the invocation. I say that cos I can't as a novice, guess which of base and blank would make fewer source files.

Maybe also a --dry-run option for create, so that could be made clear?

libs in provided scope should not be included in war

Looks like jars included in the provided scope are included in the WEB-INF/lib directory when creating a war.

Maybe I'm not understanding the intent behind the provided scope, but the documentation states it is used to specify libraries that are provided by a container. It that is the case, these libraries should not be included in web archives.

I couldn't really figure out a way to exclude a library from the WarOperation, as a workaround.

Dependency with unusual version number cannot be specified

For example javax-help with this maven dependency (notice "05" in version number) cannot be specified in BLD; the version type assumes integers. When providing a string "2.0.05" it will be converted to 2.0.5 and the dependency will not be resolved.

<dependency>
    <groupId>javax.help</groupId>
    <artifactId>javahelp</artifactId>
    <version>2.0.05</version>
</dependency>

This will not work:

dependency("javax.help", "javahelp", "2.0.05")
dependency("javax.help", "javahelp", version(2, 0, 05))

You will get

Couldn't find artifact for dependency 'javax.help:javahelp:2.0.5' at https://repo1.maven.org/maven2/javax/help/javahelp/2.0.5/javahelp-2.0.5.pom

create command should also create .gitignore file

That said, it could be there's nothing to be auto added to a .gitignore file.

I would think that not all of bld, compile, provided, runtime, standalone, test, from iib/ need to be checked into source control. Some of them can be hot re-aquired by the person cloning and running their first bld build

`

JEP458 opportunity?

This JEP458 delivered in java 22 may allow for running the BLD project files without needing to compile them, avoiding the "chickedn-and-egg" problem mentioned in the docs. Just fyi, since it is Java 22...

Is there a way to run in BLD in "online mode", watching the file system and launching builds as needed?, maybe caching things in the process?

installation guide could also show curl-to-invoke way

E.g.

## To create a project interactively with no prior installation of bld ...
curl -L https://github.com/rife2/bld/releases/download/1.8.0/bld-1.8.0.jar -o ./deleteme.jar && java -jar ./deleteme.jar create && rm ./deleteme.jar

Maybe that spits out: run './bld updates' to update bld itself in case you bootstrapped an older version by accident

Stop treating version like numbers

Hello!

Just got a bug that prevents installation of a library I'm willing to try. Here is snippet causing a problem:

public class FooBuild extends BaseProject {
    final static Repository REPORTMILL = new Repository("https://reportmill.com/maven");

    public FooBuild() {
        pkg = "foo";
        name = "bar";
        mainClass = "bar.foo.Main";
        version = version(0, 0, 1);

        repositories = List.of(MAVEN_CENTRAL, REPORTMILL);

        scope(compile).include(
            dependency("com.reportmill", "snapkit", version("2024.02"))  // <-- HERE
        );
    }
}

Whenever I'm trying to ./bld download, I got the error:

Couldn't find artifact for dependency 'com.reportmill:snapkit:2024.2' at https://reportmill.com/maven/com/reportmill/snapkit/2024.2/snapkit-2024.2.pom, https://repo1.maven.org/maven2/com/reportmill/snapkit/2024.2/snapkit-2024.2.pom

Here is some valid URL for that repo: https://reportmill.com/maven/com/reportmill/snapkit/2024.02/

Notice the difference:

-2024.02
+2024.2

That's not how it is supposed to be...

This is because of that:

// rife.bld.dependencies.VersionNumber
    public static VersionNumber parse(String version) {
        <...>
        var major_integer = (major != null ? Integer.parseInt(major) : null);
        var minor_integer = (minor != null ? Integer.parseInt(minor) : null);
        var revision_integer = (revision != null ? Integer.parseInt(revision) : null);
        <...>
    }

This is wrong. You shouldn't do that. Sometimes people are getting very creative about versioning. But even when there is some kind of "standard" in place, like "semantic versioning" - versions are still not numbers.

Some ideas for BLD

@gbevin @ethauvin

Here are some ideas after I tried to oragniza 3 re-usable java libraries and an app that uses them with BLD. I think I got what I wanted, but the experience was not straightforward and I did not feel productive, maybe also because I think I was pushing BLD to do thing no one had tried.

There are 2 problems worth mentioning:

  • mult-module setup would require BLD code that is pretty much boilerplate that no one need to write manually for the most part.
  • generating multi-module IntelliJ/VSCode is just as important and could be a an even bigger time waster.

To help with that, I propose the initial code generating wizard to be expanded beyond what it currently does: 1 bld + java source root (lib, app or base). However, if the wizard starts asking too much questions for multi-module setup, it could also become a bottleneck, as developers may need to re-generate their initial setup many times over, until they get it right. Therefore, a better approach is to make the wizard read a very tight and concise spec file, from which to generate all the boilerplate BLD java code + IDE configuration files. Here is what such specs file might look like (using YAML, for example):

# Platform definition
inventory:
   repository:
       - maven_central:
             libraries: 
                - liba: some.org:libA:1.2.3
                - libb: another.com:libB:1.3.4
        - rife2:
             ....     
project:
    modules:
      - module
          name: myapp
          type: app
          module_name: com.example.        # java modules should be optional?
          main_class: Main.  #Optional, default to Main
          package: com.example
      - module
         name: mylib1
         type: lib
         module_name: com.mylib
         package: com.mylib
      - module
        ....
dependencies:
    mylib:
       - compile: libb, mylib2
    myapp: 
        - compile: liba, mylib1
ide: intellij

The main idea is the boostrap wizard reads in specs file and generate all the boilerplate . The code quality of the boilerplate needs to be high quality, well annotated with comments and folowing "best BLD practices". It needs to scale to X libs, Y app and Z external modules. The generated codebase need to have just 1 bld folder and as many java module as specified, plus all IDE setup files.

This idea can be extended even further - build a website where the specs are requested with some sort of web forms, then the user gets to donload a ZIP (with the wrapper included!) file with all the boilerplate as if s/he ran the wizard command line. This is what Spring and Quarkus do on their web sites!

Once the code is generated, users can jump right into it. The BLD api is awesome already, so a capable Java developer can immediately start extending it. Alternatively, the user can re-generate the boilerplate cheaply and repeatedly as many time as needed, until s/he is satisfied.

Now, the good news is that even now BLD has all the necessary functionality already baked in - I know because I already wrote manually something like the above, and it works, and is possible. I only wish I did not have to re-invent the hot water and the wheel, but just get "recommended" boilerpalte code for my modules quickly, so I can immediately load up in IntelliJ and see all my X modules.

BLD can still claim to be "imperative - doing only what you tell it to", but giving it this "declarative" compact specs file/web form boost only to get started with, will make it that much more competitive to Maven and Gradle!





Alternate Groovy syntax for projects that would use bld

I write about a particular Groovy language feature a lot - https://paulhammant.com/2024/02/14/that-groovy-language-feature/. The best GPT4 can do to describe it is "Groovy in builder-style DSL syntax that leverages closures". It needs a shorter name, which is the request of that blog entry. Anyway, I know Gradle exists, but I wonder what Bld itself would look like in an alternative Groovy syntax.

Code below is GPT4-made and for a initial subset of Bld features.

A sample Grooby bld script:

// This is how you would use the above classes to interpret your DSL
def buildConfig = new BuildConfig()
buildConfig.build {
    project(name: 'MyApp', version: '1.0.0') {
        sourceSets {
            main {
                java { srcDir 'src/main/java' }
                resources { srcDir 'src/main/resources' }
            }
            test {
                java { srcDir 'src/test/java' }
                resources { srcDir 'src/test/resources' }
            }
        }
        dependencies {
            compile 'org.springframework:spring-core:5.2.3.RELEASE'
            testCompile 'junit:junit:4.13'
        }
        tasks {
            compileJava {
                source = sourceSets.main.javaSrcDir
                destination = 'build/classes'
            }
            test {
                source = sourceSets.test.javaSrcDir
                classpath = ['build/classes'] + dependencies.testCompileDependencies
            }
        }
    }
}

The classes that would minimally implement that:

// Define the BuildConfig class to handle the 'build' closure
class BuildConfig {
    Project project

    def project(Map attributes, Closure config) {
        project = new Project(attributes.name, attributes.version)
        config.delegate = project
        config()
    }
}

// Define the Project class to handle the 'project' closure
class Project {
    String name
    String version
    SourceSets sourceSets = new SourceSets()
    Dependencies dependencies = new Dependencies()
    Tasks tasks = new Tasks()

    Project(String name, String version) {
        this.name = name
        this.version = version
    }

    def sourceSets(Closure config) {
        config.delegate = sourceSets
        config()
    }

    def dependencies(Closure config) {
        config.delegate = dependencies
        config()
    }

    def tasks(Closure config) {
        config.delegate = tasks
        config()
    }
}

// Define the SourceSets class to handle the 'sourceSets' closure
class SourceSets {
    SourceSet main = new SourceSet()
    SourceSet test = new SourceSet()

    // Define inner class for each source set
    class SourceSet {
        String javaSrcDir
        String resourcesSrcDir

        def java(Closure config) {
            javaSrcDir = config.srcDir
        }

        def resources(Closure config) {
            resourcesSrcDir = config.srcDir
        }
    }
}

// Define the Dependencies class to handle the 'dependencies' closure
class Dependencies {
    List<String> compileDependencies = []
    List<String> testCompileDependencies = []

    def compile(String dependency) {
        compileDependencies.add(dependency)
    }

    def testCompile(String dependency) {
        testCompileDependencies.add(dependency)
    }
}

// Define the Tasks class to handle the 'tasks' closure
class Tasks {
    Task compileJava = new Task()
    Task test = new Task()

    // Define inner class for tasks
    class Task {
        String source
        String destination
        List<String> classpath

        def source(String source) {
            this.source = source
        }

        def destination(String destination) {
            this.destination = destination
        }

        def classpath(List<String> classpath) {
            this.classpath = classpath
        }
    }
}

For the uniitiatated the Closure config is how the magic is passed around. Ruby has the same language feature.

Groovy also has a "Grapes" way of declaring deps at the top of the groovy source file. Plucking bld jars from MavenCentral, this could also be a way of doing bld without ./lib/bld/ bits and pieces.

The tech could easily be a separate build technology that secretly delegates to bld, but it might as well be part of bld seeing as it would have 1:1 concept/method mapping. It could simultaneously allow bld-using projects to mix Groovy and Java sources in one solution. Well, maybe it could

GraalVM Native Image build support

I am currently also go back to the root of java instead of tools and frameworks.
I like to build native executables with graalvm.
Would be really nice to be able to build native executables with bld.

Maybe bld could be also build with graalvm so you don't need even java to execute it but no idea if this makes sense

Unexpected error downloading SNAPSHOT dependency

I have two repositories configured, one is jitpack.io and the other is the OSSRH snapshot repository.

repositories = List.of(
        new Repository("https://jitpack.io"),
        new Repository("https://s01.oss.sonatype.org/content/repositories/snapshots/")
);

scope(compile)
        .include(dependency("io.github.jwharm.javagi:gtk:0.7-SNAPSHOT"));

The dependency should download a bunch of other dependencies, from both declared repositories.
Running bld download results in an error:

Unexpected error while retrieving artifact for dependency 'io.github.jwharm.javagi:gtk:0.7-SNAPSHOT' from 'https://jitpack.io/io/github/jwharm/javagi/gtk/0.7-SNAPSHOT/maven-metadata.xml'
> Error while reading URL 'https://jitpack.io/io/github/jwharm/javagi/gtk/0.7-SNAPSHOT/maven-metadata.xml.
> Server returned HTTP response code: 401 for URL: https://jitpack.io/io/github/jwharm/javagi/gtk/0.7-SNAPSHOT/maven-metadata.xml

I think the error is thrown here:
https://github.com/rife2/bld/blob/main/src/main/java/rife/bld/dependencies/DependencyResolver.java#L363

Because the snapshot artifact is not found in the first repository (jitpack.io), the HTTP GET throws an IOException: Server returned HTTP response code: 401 for URL: ... that is not handled, so it throws an ArtifactRetrievalErrorException which stops the build process.

Invalid dependency resolution

Looking at the following dependency tree:

compile:
├─ com.uwyn.rife2:rife2:1.7.1
├─ com.uwyn.rife2:rife2-renderers:1.1.2
├─ jakarta.servlet:jakarta.servlet-api:6.0.0
├─ net.thauvin.erik:readingtime:0.9.1
│  └─ org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.10
│     ├─ org.jetbrains.kotlin:kotlin-stdlib:1.7.10
│     │  ├─ org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10
│     │  └─ org.jetbrains:annotations:13.0
│     └─ org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10
├─ net.thauvin.erik:shortener:0.4.0
└─ net.thauvin.erik:social:2.0.30
   ├─ com.github.jtidy:jtidy:1.0.5
   ├─ com.github.scribejava:scribejava-apis:8.3.3
   │  ├─ com.fasterxml.jackson.core:jackson-databind:2.14.0
   │  │  ├─ com.fasterxml.jackson.core:jackson-annotations:2.14.0
   │  │  └─ com.fasterxml.jackson.core:jackson-core:2.14.0
   │  └─ com.github.scribejava:scribejava-core:8.3.3
   │     └─ com.github.scribejava:scribejava-java8:8.3.3
   ├─ com.restfb:restfb:2023.12.0
   ├─ com.squareup.okhttp3:okhttp:4.11.0
   │  └─ com.squareup.okio:okio:3.2.0
   │     └─ com.squareup.okio:okio-jvm:3.2.0
   ├─ commons-codec:commons-codec:1.16.0
   ├─ net.thauvin.erik:bitly-shorten:1.0.0
   ├─ net.thauvin.erik:pinboard-poster:1.1.0
   ├─ net.thauvin.erik:utils:0.9.0
   ├─ org.json:json:20230618
   └─ org.jsoup:jsoup:1.16.1

bld is using version 1.7.10 of the Kotlin standard libs, which are needed by readingtime.

Yet, for example, the bitly-shorten dependency is needing version 1.9.10 of the same Kotlin libraries.

The workaround is to include bitly-shorten as a direct dependency.

create-base missing MAVEN_CENTRAL import

❯ bld create-base
Please enter a package name (for instance: com.example):
com.example
Please enter a project name (for instance: myapp):
BaseExample
Downloading finished successfully.
The project was successfully created at '/home/erik/dev/tmp/BaseExample'.
❯ cd BaseExample
❯ ./bld co
/home/erik/dev/tmp/BaseExample/src/bld/java/com/example/BaseExampleBuild.java:15: error: cannot find symbol
        repositories = List.of(MAVEN_CENTRAL);
                               ^
  symbol:   variable MAVEN_CENTRAL
  location: class com.example.BaseExampleBuild

process reporting success after incorrect parameter

i put an incorrect parameter for ci but instead of fail it just printed the help and exited with success.

in a ci env the process should return something other than zero so i could see clearly the build failure

image

Incorrect version number parsing with Maven metadata generated by Gradle 8.4

The latest version of Gradle is now generating maven-metadata files with the artifact version tag defined as the last tag.

maven-metadata-local.xml

This causes bld to incorrectly set the artifact version number, as it is currently expecting the version tag to be defined first. Moving the tag back to the top will fix the problem.

maven-metadata-local-xml

The problematic code is here.

The above metadata files are taken from my local repository, but the problem is identical with published artifacts, for example:

net.thauvin.erik:bitly-shorten:1.0.1-SNAPSHOT in SONATYPE_SNAPSHOTS_LEGACY

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.