saker.build icon indicating copy to clipboard operation
saker.build copied to clipboard

Context based build task invocation

Open Sipkab opened this issue 5 years ago • 1 comments

Feature description

The build tasks in the script could be declared based on the enclosing task context. It should reduce the boilerplate that surrounds a task invocation. E.g.:

some.task(
    Configuration: .config(data),
    # note the two dots
    Parameter: ..foo.bar(baz),
)

The above would be equivalent to:

some.task(
    Configuration: some.task.config(data),
    Parameter: some.foo.bar(baz),
)

Starting a task declaration with a dot can mean that the following task identifier is to be interpreted against the enclosing task.

Workarounds Use fully qualified task names.

Use-case For long task names this can reduce the boilerplate surrounding it. This is mostly prevalent when tasks are called in a way that they can be configured with other tasks that bear the same name.

Non-goals

The solution should not take multiple levels of task declarations into account. The solution should only be a syntactic enhancement, and the behaviour of actual task invocation and name resolution should not change.

Other aspects

We should also examine how this feature integrates with task names. Whether or not we should allow multiple dots at the start of task identifiers, and what may be the limit of it. In other aspects, we may not want to use too many preceeding dots, as that would limit readability.

Sipkab avatar Jan 09 '20 20:01 Sipkab

Two-dot examples

Some examples that justify allowing multiple preceeding dots:

saker.java.compile(
    ClassPath: ..classpath.bundle(bundle.name-v1.2.3),
    AnnotationProcessors: [
        ..processor(lib/myprocessor.jar)
    ]
)
nest.dependency.resolve(
    some.bundle,
    Filters: [
        ..filter.kind(classpath),
        ..filter.compile(CompileTransitive: false)
    ]
)

Often the related tasks are not a direct continuation of the enclosing task, as the above example showcases.

We should also note that if we allow multiple preceeding dots, we need to allow more than two. Restricting it to a maximum number would be only an opinionated restriction for readability and has no technical reasons at all.

We should let the developers use as many dots as they want, but strongly recommend them to keep them at minimum.

The above example without the feature would look like:

saker.java.compile(
    ClassPath: saker.java.classpath.bundle(bundle.name-v1.2.3),
    AnnotationProcessors: [
        saker.java.processor(lib/myprocessor.jar)
    ]
)
nest.dependency.resolve(
    some.bundle,
    Fiilters: [
        nest.dependency.filter.kind(classpath),
        nest.dependency.filter.compile(CompileTransitive: false)
    ]
)

Another example is when dealing with Maven tasks:

saker.maven.deploy(
	RemoteRepository: {
		Authentication: ..auth.account(
			Username: foo,
			Password: bar,
		)
	},
)

We can also realize that by using context based task declaration, the copiableness of the code parts are reduced. You cannot simply copy script parts that contain context based tasks and paste them to other locations as that may have different meanings.

The upcoming process related build tasks can also take advantage of this:

proc.run([
    java,
    -cp,
    ..arg.in.file(### ... ###),
    ..arg.out.file(### ... ###)
])

Based on the above, it would be great if there was a solution that allowed us to omit the ..arg part of the inner tasks. Something like this:

proc.run([
    java,
    -cp,
    .in.file(### ... ###),
    .out.file(### ... ###)
])

Maybe some way where it is included in the parameter name? e.g:

proc.run(Command..arg: [
    java,
    -cp,
    .in.file(### ... ###),
    .out.file(### ... ###)
])

Where the ..arg part specifies that the enclosed context based declarations start with ..arg. In its current form it is not straightforward and I wouldn't consider it to be readable, so this is only for brainstorming.

Sipkab avatar Jan 09 '20 20:01 Sipkab