Saturday, 5 August 2023

Variety build up in a long lived project

My current project has 319 Maven POMs. These have been worked upon by at least five 'generations' of coders, that is under five different software engineering leads. Maven enables different actions depending upon different profiles. This seems like a good idea: you want a new behavior, the work you are doing is new to you and maybe to the project. Name your profile and get the thing you want done. Lets see how that work out over ten years.
find * -name pom.xml | grep -v git |grep -v target \
    |xargs grep -h -a1 "<profile>" \
    |grep "<id>" |tr -d '[ \t]'| \
    sed  's/<[\/]*id>//g'| \
    sort |uniq -c

      2 code-quality
      5 component-test
     64 full
      1 Full
      5 im-elasticsearch
      1 it-test
      1 it-tests
      1 local-it-tests
     28 nightly
      1 owasp
      8 unit

2 code-quality
seems like you want to separate out your Sonar run, maybe combine it with another profile, say security checking, and want the luxury to only run one at a time.
Use full
5 component-test
wat? Is this an integration test or a unit test?
Use full
64 full
short and to the point
Winner!
1 Full
Typo
Use full
5 im-elasticsearch
Might have been a candidate, if inheritted and there was a need for mix-ins, but neither holds. Requires component-test
Use full
1 it-test
Should be plural.
Use full
1 it-tests
IT stands for Integration Test so it-tests is Integration Test Tests.
Use full
1 local-it-tests
Integration tests which are not run on the Continuous Integration server? Wrong.
Use full
28 nightly
These presumably still need to be run on any change. Control periodicity in the Continuous Integration server configuration.
Use full
1 owasp
What are these? Why are they special snowflakes? OWASP tests need to be run on any change.
Use full
8 unit
Unit tests are the default profile.
Delete

Using multiple profiles is a bad idea.

Unit tests should be run in any scenario, and should be run as part of development.

A reasonable distinction between tests is those which require external fixtures off the developers machine and those which do not, or those that take a long time to run, disabling the developer's machine. Some tests attempt to drain resources from the machine they are running on, not great on the developer's machine. There is no inherent advantage to calling out these motivations in the profile name.

What we want is to be able to reason about the whole class, to be able to say true things about all our builds. This is a much greater advantage than an attempt to communiate with other developers through naming.

Use full

Now we know that we have three types of build:

no tests
-Dmaven.test.skip=true
(preferred over -skipTests)
unit tests
Default profile, nothing for you to do.
all tests
-Pfull

We can happily say that the only thing to do when writing code to build our code is to use the profile full.

Variety is sand in the gears of our development machine, however much it may mean to you it wears away at your precious attention.

Monday, 17 July 2023

Press Release Driven Development

I realised, as I stumbled forwards with a presentation on my current project, that the presentation can be seen as a Press Release and remembered that I have explicitly followed the Amazon Working Backwards practice twice before.

Write the PR at the start of the project

This informs the team what the point of the activity is, which is not always self-evident.

Internal Press Release: Important System Upgrade Completed

Anticipated release date see: Upgrade Epic Ticket

Today we can announce that we have upgraded the whole of Important System.

In the process we have achieved the following:

  • Extended and upgraded our ability to act upon and monitor all repositories
  • Archived XX repositories
  • Reduced the number of ignored tests from XX to XX
  • Removed all Sonar Bugs and Vulnerabilities
  • Updated all libraries
  • Installed Dependabot to ensure we do not fall behind again

This enables us to take on the strategic work of removing Bad Thing from our estate.

The numeric gaps in the Press Release make it explicit what needs to be measured before and after the project.

Trying to use AI to create an image for work

The idea I want to convey, in a slide deck at work, is that the codebase we are working on has not had enough attention for five years. It has been run by a small number of people who managed to keep the system working, 'kept the lights on' but the team were not the original authors, and was not big enough, and not empowered enough, to make updates, let alone the structural changes required.

I hit upon the idea of The Marie Celeste and her skeleton crew. The original authors had left, the system was still running, but those running it were too few.

HotPot.ai

HotPot.ai is really good. It has a nice freemium on-ramp, generates images fast, and nearly had me spend money with them. I certainly used up my free goes.

I had to choose styles and engines.


Where is the crew?


Where is the crew?


Where is the crew?


Where is the crew? Appears to be a futuristic gun on prow.


Maybe some crew, the one I went with.


Where is the crew?


Too marvel


Too stylised


Too sexualised


I changed the prompt to Crew the ghost ship Marie Celeste or similar, Dalle encorporates the prompt into the filename.


I changed the prompt back to The ghost ship Marie Celeste or similar, I have lost track of the prompts by this stage.


Back to the crew.


Too much emphasis on the word skeleton


I guess it is picking up on 'girls name' + skeleton


'girls name' + skeleton in a different style


Too much skeleton


Back to just the ship


Just the ship in a different style


Skeleton and ship, but I have run out of free goes and the will to live.

creator.nightcafe.studio


creator.nightcafe.studio is a similar, polished service. I liked this creation, though it is more Flying Dutchman than Marie Celest and has no crew, enough to tweet it.


I added the word 'Indian'


Lost the ship


Added 'on the sea'


Too much sea.


Lost the plot now


Back to ghost ship


'Indian skeleton crew on a ghost ship' in a different style


'Indian ghost ship' in a different style


'Ghost ship on the sea'


'Indian ghost ship on the sea' in a different style


'Indian ghost ship on the sea'

Out of credits

Dall-e


The big user benefit of Dall-e is that the prompt is in the file name, so not relying upon my poor memory. Dall-e does not seem to offer a download all option, which the others do.


The Marie Celeste and her Skeleton crew in a fantasy style


The Marie Celeste and her Skeleton crew in a fantasy style


The Marie Celeste and her Skeleton crew in a fantasy style


The Marie Celeste and her Skeleton crew in a fantasy style

Conclusion

I never got the image I wanted, maybe the two ideas are too explicit, but I have an image which I can use. This process was not quick, but it is better than choosing a stock image from the Powerpoint selection.

Sunday, 27 November 2022

House Marks in Ossun-ez-Angles, Haute Pyrenees

Last summer, in Ossun-ez-Angles, Haute Pyrenees, I came across a House Mark above a barn door.

Wednesday, 5 October 2022

The Tims by Eleanor Farjeon

From The Little Bookroom by Eleanor Farjeon via Eldrbarry

There were five Tims all told, Old Tim, Big Tim, Little Tim, Young Tim and Baby Tim, and they were all born wise. So whenever something was the matter in the village, or anything went wrong, or people for some cause were vexed or sorry for themselves, it became their habit to say "Let's go to the Tims about it, they'll know, they were born wise."

For instance, when Farmer John found out that the gypsies had slept without leave in his barn one night, his first thought was not, as you might suppose, "I'll fetch the constable and have the law on them!" but, "I'll see Old Tim about it, so I will!"

Then off he went to Old Tim, who was eighty years old, and he found him sitting on a gate, smoking his clay pipe.

"Morning, Old Tim," said Farmer John. "Morning, Farmer John," said Old Tim taking his clay pipe from his mouth. "I've had gypsies in my barn again, Old Tim," said Farmer John "Ah, have you now!"said Old Tim. "Ay, that I have," said Farmer John. "Ah, to be sure!," said Old Tim. "You were born wise, Old Tim," said Farmer John. "What would you do if you was me?"

Old Tim put his clay pipe in his mouth again and said, "If I was you, I'd ask Big Tim about it, for he was born wise too and is but sixty years old. So I be twenty years further off wisdom than he be."

Then off he went to Big Tim, who was Old Tim's son, and he found him sitting on a gate, smoking his briar.

"Morning, Big Tim," said Farmer John. "Morning, Farmer John," said Big Tim taking his briar from his mouth. "I've had gypsies in my barn again, Big Tim, and Old Tim sent me to ask what you would do if you was me, for you were born wise" said Farmer John. Big Tim put his briar in his mouth again and said, "If I was you, I'd ask Little Tim about it, for he was born wise too and is but forty years old which is twenty year nigher to wisdom than me."

Then off he went to Little Tim, who was Big Tim's son, and he found him lying in a haystack chewing a straw.

"Morning, Little Tim," said Farmer John. "Morning, Farmer John," said Little Tim taking the straw from his mouth. Then Farmer John put his case again, saying, "Big Tim told me to come to you about it, for you were born wise". Big Tim put the straw back in his mouth again and said, "Young Tim was born wise too and he's but twenty years old. You'll get wisdom fresher from him than from me."

Then off went Farmer John to find Young Tim, who was Little Tim's son, and he found him staring into the mill pond, munching an apple.

"Morning, Young Tim," said Farmer John. "Morning, Farmer John," said Young Tim taking the apple from his mouth. Then Farmer John told his tale for the fourth time, and ended by saying, "Little Tim thinks you'll know what I'd best do, for you were born wise". Young Tim took a new bite of his apple and said, "My son who was born last month was born wise too, and from him you'll get wisdom at the fountain-head, so to say."

Off went Farmer John to find Baby Tim, who was Young Tim's son, and he found him in his cradle with his thumb in his mouth.

"Morning, Baby Tim," said Farmer John. Baby Tim took his thumb out of his mouth and said nothing. "I've had gypsies in my barn again, Baby Tim," said Farmer John, "and Young Tim advised me to ask your advice upon it, for you was born wise. What would you do if you was me? I'll do whatever you say." Baby Tim put his thumb back in his mouth and said nothing. So Farmer John went home and did it.

And the gypsies went on to the next village and slept in the barn of Farmer George, and Farmer George called in the constable and had the law on them; and a week later his barn and his ricks were burned down, and his speckled hen was stolen away.

But the happy village went on being happy and doing nothing, neither when the Miller's wife forgot herself one day and boxed the Miller's ears, nor when Molly Garden got a bad sixpence from the pedlar, nor when the parson once came home singing by moonlight. After consulting the Tims, the village did no more than trees do in a wood or crops in a field and so all these accidents got better before they got worse.

Until the day when Baby Tim died an unmarried man at one hundred years of age. After that the happy village became as other villages and did something.

Wednesday, 23 March 2022

Letter to Anneliese Dodds on the invasion of Ukraine by Russia

Dear Anneliese Dodds,

I learn from the BBC (https://www.bbc.co.uk/news/58888451) that "The UK is to phase out Russian oil by the end of the year" and "Russian imports account for 8% of total UK oil demand".

8% is a small amount and the end of the year is a long time in the future. We need immediate action to change Russia's course. Please use all your influence to this end.

Some suggestions, as a minimum:

  • Stop all petrochemical purchases from Russia, and requiring this of multinationals
  • Expulsion of all remaining Russian banks from SWIFT
  • Make it unlawful to insure a Russian enterprise
  • Seizure and forfeiture of all Russian assets within the UK and its dominions
  • Motion to remove Russia from the UN Security Council

There are many more things which could and should be done, by January 2023 there will be no Ukraine to defend.

Yours sincerely,
Tim Pizey

Sunday, 14 November 2021

An Exception wrapper suitable for a RESTful API

User Story

As a third line support engineer

I want to be able to go to the server class that throws an exception reported by a client

So that I do not need to look for the stack trace in the server logs

Example

Client code

if (responseCode != 200) {
    throw new TaskException(
        "Error occurred while processing the scan response: " + 
        "response code: " + responseCode + 
        " response body: " + responseContent.getResponseBody());
} 

Server code

  if (null != header && header.startsWith(BEARER)) {
        String token = header.substring(BEARER.length()).trim();
        try {
            final Jws jws = Jwts.parser().setSigningKeyResolver(jwtPublicKeyResolver)
                    .setAllowedClockSkewSeconds(3)
                    .parseClaimsJws(token);
        } catch (JwtException ex) {
            String errorMessage = "Invalid JWT token. ";
            setError(httpServletResponse, errorMessage + ex.getMessage());
            return;
        }
    }

This results in the following being reported by the second level support agent monitoring the client logs:

[Error occurred while processing the scan response : response code: 401 response body: Invalid JWT token. Error accessing publickey Api]:

What we, as Third Line Support, want is to know which server class throws the exception, ideally without grepping the code base or opening the server logs.

A better Exception message would be:

[Problem with scan response: status code: 401, body: com.corp.server.validation.JwtValidator.validate() line 72: JWT token Exception: Error accessing Public Key API]

This is the motivation for the StackAwareException, a wrapper exception which adds the class, method and line number of the first element of the wrapped exception's stack trace.

See https://github.com/timp/StackAwareException