Kyle Boon
Domain-specific language (noun): a computer programming language of limited expressiveness focused on a particular domain.
String generateOversizePackLabelCommand(PackLabel packLabel) {
print()
.text("T-${packLabel.store}", 60, 40, EXTRA_LARGE)
.text(packLabel.itemType.code, 500, 40, EXTRA_LARGE)
.comment('Aisle List')
.text(LOCATION_IN_STORE, 60, 180, TextSize.SMALL)
.grid(packLabel.sortGroups.sort(), 60, 240)
.comment('Shelf location')
.rectangle(450, 250, 300, 100)
.text(packLabel.packLocation.shelf.position, 470, 270, EXTRA_LARGE, true)
.shelfShape(packLabel.packLocation.shelf, 560, 410)
.build()
}
^XA
^LH0,0
^FWN
^POI
^FO60,40^A0,80,80^FDT-3229^FS
^FO500,40^A0,80,80^FDNON-F^FS
^FXAisle List^FS
^FO60,180^A0,30,35^FDLocation in Store:^FS
^FO60,240^A0,45,40^FDA1^FS
^FO60,320^A0,45,40^FDA2^FS
^FO60,400^A0,45,40^FDA3^FS
^FO60,480^A0,45,40^FDA4^FS
^FO210,240^A0,45,40^FDA5^FS
^FO210,320^A0,45,40^FDA6^FS
^FO210,400^A0,45,40^FDA7^FS
^FO210,480^A0,45,40^FDA8^FS
^FXShelf location^FS
^FO450,250^GB300,100,100^FS
^FO470,270^A0,80,80^FR^FDBottom^FS
^FO560,410^GC80,80,B^FS
^XZ
root(BIN_AUDIT, request.rootId)
.requiresRole(Role.ADVANCED)
.locationId(request.locationId)
.entryPoint(request.binBarcode)
.title(AuditMessages.BIN_AUDIT_TITLE)
.sendsEvent(resultsBuilder)
.subTask(
scanTask()
.description(SCAN_BIN)
.successMessage(SCAN_BIN_SUCCESS)
.validates(BarcodeHasValue, request.binBarcode))
.subTask(
repeats()
.untilBarcodeScanned(
scanTask()
.successMessage(SCAN_BIN_SUCCESS)
.validates(BarcodeHasValue, request.binBarcode))
.subTask(
scanTask()
.description(SCAN_UPC_OR_BIN)
.successMessage(SCAN_UPC_SUCCESS)
.validates(MatchesRegex, /\d{7,17}/)
.populatesEventField(resultsBuilder.scannedUpcs)))
.subTask(
scanTask()
.validates(BarcodeHasValue, request.binBarcode)
.description(CONFIRM_CLOSE)
.successMessage(SCAN_BIN_SUCCESS))
@Unroll
void "#steps.index Scanning #steps.name (#steps.barcode) expects next screen '#steps.description'"() {
when:
process(steps)
then:
assertResult(steps)
where:
steps << [
successScan('binBarcode', binBarcode, REPEATS_UNTIL, BIN_AUDIT_TITLE, SCAN_UPC_OR_BIN, [], SCAN_BIN_SUCCESS, []),
successScan('first upc', upc1, REPEATS_UNTIL, BIN_AUDIT_TITLE, SCAN_UPC_OR_BIN, [], SCAN_UPC_SUCCESS, []),
successScan('second upc', upc2, REPEATS_UNTIL, BIN_AUDIT_TITLE, SCAN_UPC_OR_BIN, [], SCAN_UPC_SUCCESS, []),
successScan('other bin', BAD_BIN, REPEATS_UNTIL, BIN_AUDIT_TITLE, SCAN_UPC_OR_BIN, [], INVALID_BARCODE, [BAD_BIN]),
successScan('non upc', 'BAD_BAD_BAD_BAD_BAD_BARCODE', REPEATS_UNTIL, BIN_AUDIT_TITLE, SCAN_UPC_OR_BIN, [], INVALID_BARCODE, ['BAD_BAD_BAD_BAD_BAD_BARCODE']),
successScan('upc', 'BAD_UPC', REPEATS_UNTIL, BIN_AUDIT_TITLE, SCAN_UPC_OR_BIN, [], INVALID_BARCODE, ['BAD_UPC']),
successScan('third upc', upc1, REPEATS_UNTIL, BIN_AUDIT_TITLE, SCAN_UPC_OR_BIN, [], SCAN_UPC_SUCCESS, []),
successScan('binBarcode', binBarcode, BIN_AUDIT, BIN_AUDIT_TITLE, CONFIRM_CLOSE, [], SCAN_BIN_SUCCESS, []),
completionScan('binBarcode', binBarcode, BIN_AUDIT, BIN_AUDIT_TITLE, null, [], SCAN_BIN_SUCCESS, [])
.event(new BinAuditResults(upcsScanned: ['UPC1': 2, 'UPC2': 1], binBarcode: binBarcode, auditType: BIN_AUDIT, locationId: '3844', auditedByLanId: nextTask.completedBy))
]
}
---
deployment:
port: 5053
cpuMilliCores: 4000
memoryMi: 3072
image:
name: task-manager
ole_shared_configmaps:
- common.endpoints.yml
- common.kafka-ole.yml
ole_shared_secrets:
- kafka.secret.yml
Builders Support in Groovy
import groovy.transform.builder.Builder
@Builder
class User {
String username
String password
List<Role> roles
static enum Role {
NORMAL, ADMIN
}
}
User.builder()
.username("kyle")
.password("password1")
.build()
import groovy.transform.builder.Builder
@Builder(prefix = 'assign', buildMethodName = 'create', excludes = ['password'])
class User {
String username
String password
List<Role> roles
static enum Role {
NORMAL, ADMIN
}
}
User.builder()
.assignUsername("kyle")
.assignRoles([User.Role.ADMIN])
.create()
import groovy.transform.builder.Builder
@Builder()
class User {
String username
String password
List<Role> roles = [Role.ADMIN]
static enum Role {
NORMAL, ADMIN
}
}
assert User.builder().build().roles
import groovy.transform.builder.Builder
import groovy.transform.builder.ExternalStrategy
class User {
String username
String password
List<Role> roles
static enum Role {
NORMAL, ADMIN
}
}
@Builder(builderStrategy = ExternalStrategy, forClass = User)
class UserBuilder {
UserBuilder() {
roles = [User.Role.ADMIN]
}
}
new UserBuilder().build().roles
import groovy.transform.builder.Builder
import groovy.transform.builder.ExternalStrategy
class User {
String username
String password
List<Role> roles
static enum Role {
NORMAL, ADMIN
}
}
@Builder(builderStrategy = ExternalStrategy, forClass = User)
class UserBuilder {
UserBuilder admin() {
roles = [User.Role.ADMIN]
return this
}
}
new UserBuilder().admin().build().roles == [User.Role.ADMIN]
import groovy.transform.builder.Builder
import groovy.transform.builder.ExternalStrategy
import java.time.Duration
import java.time.LocalDateTime
@Builder
class User {
String username
String password
List<Role> roles
LocalDateTime passwordExpires
static enum Role {
NORMAL, ADMIN
}
}
// still need to add the descriptors file
class MonthsExtension {
static LocalDateTime monthsFromNow(Integer self) {
LocalDateTime.now().plusMonths(self)
}
}
User.builder().passwordExpires(3.monthsFromNow())
import groovy.transform.builder.Builder
import groovy.transform.builder.ExternalStrategy
class User {
String username
String password
List<Role> roles
static enum Role {
NORMAL, ADMIN
}
}
@Builder(builderStrategy = ExternalStrategy, forClass = User)
class UserBuilder {
UserBuilder() {
roles = []
}
UserBuilder leftShift(final User.Role role) {
roles << role
this
}
}
UserBuilder builder = new UserBuilder()
builder << User.Role.ADMIN
assert builder.build().roles == [User.Role.ADMIN]
RatpackServer.start({ def s -> s
.serverConfig(c -> c.baseDir(BaseDir.find()))
.registry(Guice.registry({ def b -> b.module(MyModule)) })
.handlers({ def chain -> chain
.path("foo", { def ctx -> ctx.render("from the foo handler") })
.path("bar", { def ctx -> ctx.render("from the bar handler") })
.prefix("nested", { def nested ->
nested.path("more", { def ctx ->
ctx.render("from the nested/more handler")
})
})
.prefix("static", { nested -> nested.fileSystem("public", Chain::files) })
})
})
ratpack {
serverConfig {
baseDir(BaseDir.find()
}
bindings {
module MyModule
}
handlers {
path "foo" { render "from the foo handler" }
path "bar" { render "from the bar handler" }
prefix "nested" {
path "more" {
render "from the nested/more handler"
}
}
fileSystem "public", { f -> f.files() }
}
}
These are functionally equivalent in groovy.
a(b).c(d)
a b c d
import groovy.transform.builder.Builder
import groovy.transform.builder.ExternalStrategy
import java.util.function.Supplier
@Builder
class User {
String username
String password
}
def build(Supplier supplier) {
supplier.get().build()
}
def user(String username) {
User.builder().username(username)
}
build { user "kyle" password "password1" }
import groovy.transform.builder.Builder
import groovy.transform.builder.ExternalStrategy
class User {
String username
String password
}
@Builder(builderStrategy = ExternalStrategy, forClass = User)
class UserBuilder { }
def build(@DelegatesTo(strategy=Closure.DELEGATE_ONLY, value=UserBuilder) Closure cl) {
def user = new UserBuilder()
def code = cl.rehydrate(user, this, this)
code.resolveStrategy = Closure.DELEGATE_ONLY
code().build()
}
build { username "kyle" password "password1" }