Codecov Troubleshooting

No such file or directory If you, for instance, download the alpine version of Codecov within a non-alpine linux container such as node:14.20.0-bullseye, then you’ll get bash: ./codecov: No such file or directory Double check you are using the correct flavour. Can’t find project If you are using a container that does not have git installed, then the default Codecov will not be able to detect the project. You’ll need to use ...

April 26, 2023 · Nigel Sim

Migrating from ModelMapper to Map Struct

TL;DR I’ve built many applications that have used ModelMapper for projecting from one object structure to another, and it has been very good for getting up and running quickly. However, it costs in terms of type safety, and startup performance. So, I’ve switched to a type safe, compile time alternative MapStruct. This article mainly covers the pros and cons of each framework, not how to use them in real projects, or best practises. There are plenty of other articles on the web covering these topics. ...

December 1, 2020 · Nigel Sim

Spring Boot Web Services Client with Jib

When it comes to building a SOAP web services client using Spring, the guide suggests using an Ant based gradle build task to generate the required classes. However, if you are using Jib to produce a Docker container, you may find that the generated classes are not in the container, and there are few guides as to how to get them in there. It looks something like this: ... task genJaxb { ext.sourcesDir = "${buildDir}/generated-sources/jaxb" ext.classesDir = "${buildDir}/classes/jaxb" ext.schema = "http://localhost:8080/ws/countries.wsdl" outputs.dir classesDir doLast() { project.ant { taskdef name: "xjc", classname: "com.sun.tools.xjc.XJCTask", classpath: configurations.jaxb.asPath mkdir(dir: sourcesDir) mkdir(dir: classesDir) xjc(destdir: sourcesDir, schema: schema, package: "com.example.consumingwebservice.wsdl") { arg(value: "-wsdl") produces(dir: sourcesDir, includes: "**/*.java") } javac(destdir: classesDir, source: 1.8, target: 1.8, debug: true, debugLevel: "lines,vars,source", classpath: configurations.jaxb.asPath) { src(path: sourcesDir) include(name: "**/*.java") include(name: "*.java") } copy(todir: classesDir) { fileset(dir: sourcesDir, erroronmissingdir: false) { exclude(name: "**/*.java") } } } } } ... The crux of the issue is getting the generated classes onto the main source set so that Jib will package them up. I’m not a Gradle expert, so while there may be a way to make this happen with this setup, the neater solution appeared to be to us the XJC Gradle Plugin which takes care of a lot of this automatically. ...

October 18, 2020 · Nigel Sim

Calculating the resulting colour

This is a simple Python application that calculate the resulting hex colour from a foreground colour, background colour, and opacity. This has been useful when writing templates using Flying Saucer which doesn’t support opacity, so we need to calculate final values manually. e.g.: $ python rgba.py a9b421 99e0b2 0.5 #a1ca69 Now, if only this was a handy webpage…

December 18, 2019 · Nigel Sim

Can't resolve all parameters - Angular 8

What follows is an explanation of how to resolve an issue that you may hit with Angular if you are using services from modules. In my application I use the pattern of having a service that can be used to display modals, so that other components can show a modal using a method call, and not have to worry about the specifics of the modal implementation. As a mock example, suppose you have a feature module, that has a component, a modal, and a modal service: ...

November 27, 2019 · Nigel Sim

Debugging Storybook Angular Customisation

Out of the box the support for Angular under Storybook is great. However, depending on how customised your setup is, you’ll probably need to harmonise your Angular setup with your Storybook setup. Typescript Paths Because we have customised tsconfig.json roots in order to clean up our import paths, we first need to make sure that Storybook’s Webpack uses the the TsconfigPathsPlugin. const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin'); module.exports = async ({ config, mode }) => { config.resolve.plugins = [new TsconfigPathsPlugin({})]; return config }; MapBox and Node core libraries Because we use MapBox we get the following error ...

October 26, 2019 · Nigel Sim

Supplying resources directly to Flying Saucer

In the Java world, one of the options you have for generating PDFs is Flying Saucer. It is quite a nice solution that renders HTML to, amongst other things, PDF. In its simplest form a report, receipt, etc, could just be a chunk of text. But, more realistic situations would require images to be embedded in the output, be these logos, charts, images, etc. A commonly found suggestion for achieving this is to link to the assets via the file-system. This actually occurs by default if you set the base URL of the document to null: ...

July 28, 2019 · Nigel Sim

Create a void return type function in TypeScript

A benefit of a strong type system is the ability to have good guard rails that tell you when you’ve writing an invalid program, without having to run it. However, to be truly useful it needs to be possible and ideally easy to define interfaces and method signatures once, and simply transform these for their various applications. In react/redux applications you define actions, and these are dispatched to mutate state or trigger side effects. I’m just using this as a way of introducing the TypeScript example, rather than suggesting what follows is a good way of solving this problem (e.g., libraries like Typesafe Actions exists to solve this problem specifically). ...

June 8, 2019 · Nigel Sim

rxjs of synchronised by default

As mentioned here if you use of from rxjs to implement mock services you can get some unexpected results. In my case, my code always cleans up its subscriptions. But, by default, of executes synchronously, so the following code will fail because sub isn’t set when the closure is called. import { of } from 'rxjs'; const mockService = { get() { return of([]); } } const sub = mockService.get() .subscribe(result => { this.list = result; sub.unsubscribe(); }); In order to get this code to behave like a the real service we need to use a scheduler. ...

May 27, 2019 · Nigel Sim

Migrating AngularJS UI Bootstrap Modals to Angular 7

I’ve recently been involved in upgrading a AngularJS + UI-Bootstrap + UI Router project to Angular 7 + ngx-bootstrap + UI Router. The reason for the upgrade was that the support for a lot of the other components was fading, and the availability of new components was far better for Angular 7 than AngularJS. Having said that, AngularJS is still going strong for better or worse. The approach was to use the Angular Upgrade module which allowed a component-by-component upgrade, and basically seamless interop between the two versions. This was helped a lot by the use of UI Router which navigates to both AngularJS and Angular 7 container components. ...

April 21, 2019 · Nigel Sim