Around 21:00, not sure if there exists `getValue` for threadlocal, but there should be! Would make your life easier with the `get` calls
@kyay102 сағат бұрын
Around 17:00, `Timed` should be a sealed interface!
@PairingWithDuncan11 минут бұрын
Yes I suppose it should be! Do you think that it will survive though? The whole thing is a bit of a mess: Timed is a concern of the Mermaid rendering that is leaking into the capture; TestEvents and TestStats are kind of the same and kind of different …
@eatthepi13 сағат бұрын
The Result type is apparently Http4k's Result4k. I assume Duncan made this clear in an earlier video that I haven't gotten to yet.
@TimSchraepen2 күн бұрын
Hoarse Duncan sounds like regular Richard Ayoade. 😅 Get well soon!
@PairingWithDuncanКүн бұрын
Ooh, bit of a nasal whine? I can hear it now you’ve pointed it out. I seem to have reached the age when every cold goes to my chest. Thank you for your concern.
@mytubektКүн бұрын
@@PairingWithDuncan get well soon!
@sandrodelacruz81252 күн бұрын
Vitamin C
@PairingWithDuncanКүн бұрын
Maybe I need to take supplements more seriously 🍊
@k0zakini06 күн бұрын
2:34 😆
@PairingWithDuncan6 күн бұрын
😅
@TimSchraepen7 күн бұрын
Happy end of year celebrations!
@PairingWithDuncan7 күн бұрын
And to you! My wife bought me some bottle of La Chouffe, so I can have Ardennes flashbacks!
@edgeeffect8 күн бұрын
I came to Gradle and Kotlin at the same time.... so YOU WOULD THINK I don't need to care about migrating from Groovy at all.... right?!... right??? Well, I'm still learning and I need to check out the docs a lot.... and when I'm lucky enough to find docs that actually have examples, yeah, there's still A LOT of Groovy for me to read.... so I'm finding myself needing to migrate other people's Groovy quite a lot.
@PairingWithDuncan7 күн бұрын
At least the AI seems to be good at that job! And no-one cares about code-quality when it comes to the build, so any old solution will do ;-)
@edgeeffect6 күн бұрын
@@PairingWithDuncan Speaking as a "code quality fascist" I hate having to modify spaghetti-build files as much as I hate modifying spaghetti run-time code. :)
@pavlosoia8 күн бұрын
amazing
@PairingWithDuncan8 күн бұрын
Thank you. It was a while ago, but I had a lot of fun making this one.
@IPad-gf8mv9 күн бұрын
Maybe it‘s worth to measure before/after methods in Addition? Could be that test prepartion consumes a lot of time?
@PairingWithDuncan9 күн бұрын
Wait for it, wait for it! Actually that’s surprisingly hard to add to the diagram- watch this space.
@PairingWithDuncan8 күн бұрын
I should also say that I believe that the times here are including everything it takes to run a test, so including the setup and teardown.
@devopsthinh9 күн бұрын
❤ thanks, from Vietnam 😊
@PairingWithDuncan9 күн бұрын
I’m pleased to get positive feedback. Thank you.
@erikvanvelzen304515 күн бұрын
Maybe Intellij is reporting CPU time instead of clock time. I/O would report less CPU time than clocktime, for multithreaded calculations it would be the opposite.
@PairingWithDuncan14 күн бұрын
🤔 That would explain some things. Do you know any way to measure that for a function in Java?
@oharaandrew31416 күн бұрын
I know that running tests with IntelliJ tends to be faster, but putting IntelliJ in charge just rubs me the wrong way for some reason. For me, it tends to be the "Instatiating Tests" step that takes most of the time.
@PairingWithDuncan15 күн бұрын
I think that is the pre-build with Gradle. I wonder if we can invoke a different build target when we know that we either just need to compile or not, so that Gradle would be quicker.
@Onlinepmcourses16 күн бұрын
That's great! My developer lies to me, and my developers tools lie to them.
@PairingWithDuncan16 күн бұрын
Looking up the definition, a lie is a knowing untruth. I do wonder if the tool is deliberately or accidentally deceiving
@Onlinepmcourses16 күн бұрын
@@PairingWithDuncan Maybe. Does that suggest that it can't read the computer's clock, or that the developer who created the tool doesn't know how to tell it how to read the clock. Maybe my developer's code's developer was incompetent...
@jynxxnerd16 күн бұрын
'Enter' to complete the current word.
@PairingWithDuncan16 күн бұрын
Ooh, that would be simple, thank you. I’ll try to remember that when I’m next in the situation
@IPad-gf8mv16 күн бұрын
Like your investigation on test execution duration! Since most of developers don‘t care 😊
@PairingWithDuncan16 күн бұрын
I think that’s true, but it’s a shame, because the tight inner loop can feel really nice and productive.
@eatthepi21 күн бұрын
One trick I try in situations like this is creating a new project from the IDE; the IDE can make a really simple project to compare against.
@PairingWithDuncan21 күн бұрын
Thank you, that’s a good tip. It fails a bit when Gradle changes the model for more complicated setups, but I have been reduced to this trick myself
@dom-22 күн бұрын
I really care about shorter feedback loops. It would be great to have all those tests run below 1s, even if it's just a psychological barrier.
@PairingWithDuncan22 күн бұрын
Absolutely. Once you’ve experienced TDD with really fast feedback you don’t want to go back.
@DmitryKandalov23 күн бұрын
Thank you so much for digging into the test runners' measurements! I'm sure the built-in IntelliJ test runner for Java was way faster. I might dig out an old version of IntelliJ to have proper evidence of software degradation (although sadly it doesn't feel like anyone would really care).
@PairingWithDuncan23 күн бұрын
I couldn’t have done it without your help - a great collaboration. I don’t think most people care as much as I do, but it takes me 10 minutes a week just to remove the pauses while nothing happens in my videos!
@eatthepi23 күн бұрын
Great stuff! Never heard of the `project.messageBus` before -- I think I would have assumed that timing thing you did was impossible. 😜
@PairingWithDuncan23 күн бұрын
Thank you, but credit where it’s due - knowing Dmitry I knew he would find a way!
@kacpermachnik286624 күн бұрын
33:39 I was coding along with you and noticed something interesting - I didn't get the same warnings as you did in your code, about nullability. I'm wondering if you may know why. I've checked my inspections settings in intellij but with no success
@PairingWithDuncan24 күн бұрын
Ooh, interesting! The Kotlin compiler is getting cleverer at what it can infer about nullability, so I suspect that the version of the compiler is significant here.
@kobac820729 күн бұрын
by the way, how do you make the IDE make the sound when finished with the tests? I tried a bunch of plugins but couldn't find anything useful.
@PairingWithDuncan29 күн бұрын
I think that I used Notification settings - Test finished to play a sound. More recently videos have a plugin to put up a big progress bar - kzbin.info/www/bejne/qqemhI2dg5aaldksi=vrlQvTW7xVQPM8Tu&t=1080 - the notes on that video have a link
@kobac820729 күн бұрын
Nice! One way also to redirect tests to lower level (from handler to render in this case) is to use The Saff Squeeze technique.
@PairingWithDuncan25 күн бұрын
I haven’t heard of that, please tell me more
@TimSchraepenАй бұрын
Going to try out those junit properties in our codebase. Thanks for sharing them again!
@PairingWithDuncan29 күн бұрын
They take a bit of tuning, and can reveal nasty test coupling, but I think that the those given are the best starting point. Next week, Supercharge Specifications….
@FedericoDanielAnastasi-b9wАй бұрын
I still have to watch the whole video but does duncan migrations run for each test? I have a weird combination that i want a clean db but with the migrations already ran, yet i don't know if it is related with Kotest or my testcontainer config
@PairingWithDuncanАй бұрын
Unless you’re using kotest magic, you are in control of when containers are started, and when migrations are run. I guess a few println’s might clarify the lifecycle
@DavidA-fi9jyАй бұрын
You don't really need to initialize the container yourself... the tc driver will do it for you, in the docs it shows what connection string you can use that postgres will be started for you. The only thing is that there are less configuration options in that case.
@PairingWithDuncanАй бұрын
Ah interesting - do you have a link please?
@kubazalasАй бұрын
Another way to start the container once before all test cases is to let testcontainers control the lifecycle by using the Container annotation, but define the container in a companion object. It’s unlikely to Chang a much for you though. Example: ``` @Testcontainers(disabledWithoutDocker = true) class EventStoreDbExamples : EventStoreContract(EventStoreDbEventStore(eventStoreDb.connectionString)) { companion object { @Container private val eventStoreDb: EventStoreDbContainer<*> = EventStoreDbContainer() } } ```
@PairingWithDuncanАй бұрын
Thank you. I realise that I haven’t really looked at the container lifecycle properly - watch this space next week
@jonathankolberg2706Ай бұрын
Just change your image for the testcontainer creation to match the image in the docker compose file, that fixes your problems with timezones. I guess in the alpine image there is no timezone information installed to keep it as slim as possible.
@PairingWithDuncanАй бұрын
Strangely I didn’t even think that I had a working container downloaded that I could use!
@IgorRumihaАй бұрын
Instead of a Postgres image based on Alpine Linux, you might want to try an image based on a more complete Linux variant, such as Debian. That might solve your supported timezones issue.
@PairingWithDuncanАй бұрын
Thank you. I recorded this one without rehearsal, so was genuinely surprised when this issue came up
@user-yf1ml8jt3iАй бұрын
But turns out the program is irrelevant, so we can just delete the whole program. It's now much easier to maintain, and takes much less time to compile.
@PairingWithDuncanАй бұрын
Luckily Alison has re-upped our contract, so we know she wants the functionality we have delivered.
@TimSchraepenАй бұрын
That failing test about “remember to close DbItems” was nothing short of wonderful. What a delightfully empathic thing of Past Duncan to have done, in order to help out Future Duncan. ❤
@PairingWithDuncanАй бұрын
Thank you. As I hadn’t rehearsed this session, my surprise at the failing test was genuine. To be honest though, I doubt whether the time spent writing that test was actually worthwhile. The consequences of leaving a class open are hardly severe, and it’s telling that the name of the test got out of sync because it was an identifier that wasn’t updated in a refactoring. So maybe the takeaway should be - you can use tests to maintain code structure invariants, and you can set up tests to let you know when an event has occurred.
@mytubektАй бұрын
This is the best refactoring video I have ever seen! Thanks for sharing ❤
@PairingWithDuncanАй бұрын
Thank you. I think some of my later work is better, or at least better (video) edited, so please look around.
@eatthepiАй бұрын
If `flywayMigrate` defines the task outputs, can you set the `generateJooq` inputs to be the `flywayMigrate` outputs? If you map them in the special gradle way, gradle knows about the task dependency without explicitly stating it. By explicitly depending on `flywayMigrate` and also setting the inputs to the path that `flywayMigrate` writes to, I think you're accomplishing the same thing -- but in a less flexible way. I'm not familiar with either plugin, so it seems quite likely that you can't use this approach.
@PairingWithDuncanАй бұрын
I think this is the same question as @dom asked? This would be a better solution, marred only by my not knowing how to make it work! At this point having something that does the job allows me to get on with actual programming, but, as you say, with a bit of an unsatisfactory feeling.
@dom-Ай бұрын
@@eatthepi if the flywayMigrate task output returns if new migrations have been applied, yes you could. But if we are looking at two tasks that need to always run together the declarative approach stops making sense and it's better/easier to just use "doLast{}" on flywayMigrate.
@oharaandrew314Ай бұрын
Took me forever to get around to watching this. I had hoped for some examples on how to make HTMX apps that work more like React or Flutter and less like jQuery. I don't know why I had hoped for that, but I see it was way out of scope! Question: what plugin do you have that gives you the button to approve the actual files?
@PairingWithDuncanАй бұрын
That’s it, hold my feet to the fire! I have plans to look at click to edit, but one thing at a time. The fabulous Ivan wrote plugins.jetbrains.com/plugin/9424-okey-doke-support
@dom-Ай бұрын
Wouldn't make more sense to put input.files("src/main/resources/db/migration") into the flywayMigrate task? (If it's not by default like that)
@PairingWithDuncanАй бұрын
Good question, thank you. I did wonder while I was filming. We would still have to make the jooq task depend on migrate in order to have the migrate happen, but jooq would run, with its delays, whether or not the migrate actually did anything. I suppose it is possible to run one task only if another actually ran? But this works, and seems the least complicated, if not the best expression of the actual task dependencies.
@dom-Ай бұрын
@@PairingWithDuncan Yes, apparently this can be achieved using outputs.upToDateWhen { false } on the flywayMigrate task (I haven't personally tested it).
@upbeatsarcastic8217Ай бұрын
The fact that Gradle even exists (I claim) is a symptom of a pretty sick attitude towards complexity and, ultimately, quality. It is a tool born of laziness and arrogance (and, to be fair, Java weirdness).
@PairingWithDuncanАй бұрын
I think I know what you mean by the attitude towards complexity, but like democracy, Gradle is the worst solution except for all the others
@upbeatsarcastic8217Ай бұрын
@@PairingWithDuncan This is true, sadly. Here's hoping Amper can rescue us from the madness. I'm in the middle of some KMP fun and games myself, and I find I spend more time fiddling with Gradle than I do actually developing features.
@BlacklandsАй бұрын
There's also Declarative Gradle that's being worked on, which might make the builds for most projects (that don't need extra logic) more simple to understand, eventually?
@kyay10Ай бұрын
Unstoppable force (Duncan) meets immovable object (comprehending Gradle)
@PairingWithDuncanАй бұрын
:-) I figure that at least I’m aiming at a relatively stationary part of Gradle, so stand a chance of hitting.
@IPad-gf8mvАй бұрын
I recommend using „-rerun-tasks“ over clean.
@PairingWithDuncanАй бұрын
Oh wow, I’ve been using Gradle for, what, 10 years now, and no one has ever told me about that. Must investigate thank you.
@JentaroYusongАй бұрын
We've set up a "Renovate" bot at our workplace taking care of dependency updates by opening pull requests. That helped us keeping on track with dependency updates immensely. Its highly customizable in regards of what to update, when to to run and even supports merging automatically once CI tests were successful. It supports both dependency declarations in the build.gradle.kts as well as the .toml file. And it can even update the Gradle wrapper itself. However, it's not written or configurable using Kotlin, so it's most likely not a fit for a video on this channel. Just wanted to let others know who might be struggling with dependency updates as well.
@zeusalmighty6740Ай бұрын
Not sure which version this was added but at least in Android Studio, IDE shows a warning if update is available in toml
@PairingWithDuncanАй бұрын
I had heard that there was editor support, but haven’t seen it in IntelliJ. There is a warning (at least in the build.gradle) if there is a CVE against a library, but I didn’t see support for other version updates.
@nixoncodeАй бұрын
I got into Kotlin sometimes back, it's horrible having to upgrade every 3 months. no wonder Java won. I pity my team for putting them through this
@PairingWithDuncanАй бұрын
Do you need to talk about it ;-? I do feel that Kotlin is going through a bit of a lull at the moment. We have to put up with constant tooling change for not perceived progress on the language front. The changes, Gradle aside, are rarely breaking though, so I tolerate them. Java is also evolving, but I don’t think we can say either won, and I still prefer Kotlin to Java or Scala for team productivity and fun.
@Alivezombie16Ай бұрын
Do either of dependency tasks you used allow you to specify via flags or config to ignore alpha/beta/RC and/or only show patch, minor or major updates?
@PairingWithDuncanАй бұрын
Good question thank you. They do! Gradle-versions-plugin has something complicated, but I’m told that refreshVersions can be configured with refreshVersions { enableBuildSrcLibs() rejectVersionIf { candidate.stabilityLevel.isLessStableThan(current.stabilityLevel) } }
@TimSchraepenАй бұрын
Hilarious intro 😂
@PairingWithDuncanАй бұрын
@TimSchraepen thank you. It’s the only bit I script, so it’s good to know my efforts aren’t wasted
@oharaandrew3142 ай бұрын
I don't know if the Kotlin DLS is any "better" than the original Groovy DSL. They say you're supposed to take advantage of the autocomplete to inspect available properties, but as you've seen, the script doesn't even get syntax highlighting until it's fully correct, so I rarely actually get to use it. This doesn't make the Kotlin DLS any worse though; I think both are about the same amount of pain to work with. But for consistency, I might as well use the Kotlin DSL in my Kotlin project. And since I don't even know Groovy, at least I know what my copy-pasta is doing.
@PairingWithDuncan2 ай бұрын
I think this sums up my view. Neither is good enough, Kotlin is a bit better.
@xozzy78092 ай бұрын
In my opinion is a lot better, the problem with groovy gradle files is that people at some point tend to write scripts that works by accident, they dont declare plugins but declare extensions for them and the plugin is applied in different file etc. This leads to IDE being completly useless, hovewer in kotlin due to type safety it forces you to write better code, and IDE is actually helpful.
@edgeeffect6 күн бұрын
Coming to the world of Gradle late, like I have. It's nicer to only have to learn one new language (Kotlin) rather than having 2 to contend with at once.
@righteouscoder2 ай бұрын
Version Catalog should probably be your next hurdle, it really does make updating dependencies MUCH easier (and less error prone) one large multi-module project and I like that the catalog is reusable between projects, a little fiddley to get strings and such, but honestly makes everything so much nicer once done.
@PairingWithDuncan2 ай бұрын
At the risk of flogging a dead elephant, this is on my list for next week!
@oharaandrew3142 ай бұрын
Welcome to the party! Perhaps just in time for the new declarative DSL to drop!
@PairingWithDuncan2 ай бұрын
All the more content to thrill you with
@vlogan792 ай бұрын
You jest, but Jetbrains are working on a new build system...
@oharaandrew3142 ай бұрын
No, not even. Gradle is working on a new declarative DSL. As for Amper, so far, there's been conflicting information on whether it's a layer on top of gradle or not. If it is, then I fear it will add too many new failure points to be worthwhile.
@PairingWithDuncan2 ай бұрын
@oharaandrew314 Isn’t Amper both? The problem is that we want a JFDI build, where we can also customise everything when we have specialist requirements
@sandrodelacruz81252 ай бұрын
Who cares about removing the apply? If it works I would leave it.
@PairingWithDuncan2 ай бұрын
I suppose my thought was that if I had other builds to convert, the extension would save a bunch of manual work.
@sandrodelacruz81252 ай бұрын
Why didn't you use the AI to help fix the issues?
@PairingWithDuncan2 ай бұрын
To be honest, because when I tried that in a run-through (I prefer the term to rehearsal ;-) it just dug me in to a deeper hole.
@gekylafas2 ай бұрын
The latest release of kotlinx.html is visible at 5:37 at the right column of the github page.
@PairingWithDuncan28 күн бұрын
Sorry, missed this comment as well as the version! It must be age.
@eatthepi2 ай бұрын
The AI assistant is impressive. We're not allowed to use this feature at work, so I appreciate seeing it in action.
@PairingWithDuncan2 ай бұрын
Thanks for the feedback. I’m slowly learning where I expect it to be faster than doing things by hand. At the moment these bulk transformations seem to be a good bet.
@eatthepi2 ай бұрын
The versions gradle plugin you used can be configured with "RejectVersionsIf and componentSelection" to filter out those beta version update suggestions. It would be nice if it worked a bit better out of the box, but for my projects where I do a bit of configuration, the plugin would have suggested the Kotlin 2.0.0 -> 2.0.21 update. Gradle version catalogs extract all the dependency versions into a "libs.versions.toml"-file. In that file, the IDE does give me quick actions to update dependency version strings, although it doesn't work 100% of the time.
@PairingWithDuncan2 ай бұрын
Thank you for the info. I’ve been thinking of introducing a version catalog, although yet another file format!