How to merge git repositories preserving git history
Struggling with merging multiple repositories together into one (mono) repository? You wanna preserve your valuable git history?
This blogpost will show you how to do this step-by-step.
Struggling with merging multiple repositories together into one (mono) repository? You wanna preserve your valuable git history?
This blogpost will show you how to do this step-by-step.
If we have an Optional
instance we can consume the value if it is present using the ifPresent
method. Since Java 9 the method ifPresentOrElse
has been added to the Optional
class. The first argument is of type Consumer
and is invoked when there is an optional value. The second argument is of type Runnable
and is executed when the the optional is empty. The method in the Consumer
and Runnable
implementations does not return a type but returns void
. Therefore we should use ifPresentOrElse
when we need a conditional side effect for an Optional
instance.
In the following example we have a method handleName
that will update a list if an optional value is present or increases a counter when the optional value is empty:
In the clojure.set
namespace we can find the function map-invert
. This function returns a new map where the values are keys with the appropriates keys of the original map assigned as value. If the original map has duplicate values than the latest key for the duplicate value will be the value of the new key.
In the following example code we see the result of using map-invert
:
A Spring Boot application typically consists of several components handling the business functionality and probably some configuration to configure all these components. This configuration consists of defining some properties, setting up some beans with the right conditions and dependencies and wrapping it all together into a class structure. Nevertheless, the configuration of our Spring Boot application is also code. Let’s threat is as code.
In this blog we will se how we can improve our Spring Boot Configuration by splitting up the configuration from the properties and how this effects the design principles.
Outside the Java community, Java is often regarded as an old and verbose language. Though I love writing Java code, I kind of have to agree with this. New features are implemented slowly and looked upon by the language designers with thorough suspicion. For example, support for multi-line strings has been tried multiple times before Java got official support[1]. If we are talking about verbosity, the Java language needs quite some characters to write a simple function. As I am specializing in functional programming in Java this year, I struggled a lot with this. Read along how I tackled this a little.
If we want to get two types of information from a Stream
of objects we can consume the Stream
twice and collect the results. But that is not very efficient, especially when the stream has a lot of objects. Since Java 12 we can use the teeing
method of the java.util.stream.Collectors
class to get multiple results while consuming the stream of objects only once. The teeing
method takes two collectors as argument each returning a separate result for the stream items. As third argument we must pass a function that will merge the results of the two collectors into a new object.
In the following code we have two example use cases that use the teeing
method to get multiple results while consuming a Stream
of objects only one time:
Our team has a (not so) slight tendency to not immediately follow through with our deployments to production. We’ll create and review our changes, merge and deploy to staging, and dilligently test the changes there. And then… nothing happens.
It could be that something else needs our immediate attention, or someone else wants to confirm an issue is fixed; Or we might want to deploy at a different point in time as to not disrupt an ongoing process by a service restart. Any which way the result is the same: changes accumulate in staging, and with that the risk involved with the next production deployment.
To nudge ourselves to deploy to production more often we created a Slack App that gives us a daily report of such pending deployments. In this post I’ll showcase the code we use, and how to set up something similar yourself.
Working with Java classes from Clojure code is easy. If we want to invoke methods or access fields on instances of Java classes we must first create an instance by invoking the constructor. In Clojure we can do that using the special form new
or using a dot (.
) notation. The new
special form has the class name of the Java class we want to create an instance of as argument followed by arguments for the Java class constructor. With the dot notation we place a .
after the class name followed by arguments for the class constructor to create a new instance.
In the following example we see several ways to create an instance of a Java class.
When you look at how a given organization develops software over time, it’s not uncommon to spot evolutionary patterns that mimic what we see in nature. Particularly where micro services are involved, you might well be able to deduce which services came first, and which were developed later in time, by looking at various subtle variations in project structure, tools, dependencies, build pipelines and deployment descriptors. Later services copy elements from the initial template services, apply variations to fit their needs, and successful variations are again used in future services, or even applied in the original template services.
Variations from service to service are essential to maintaining a vibrant engineering culture, with room for experimentation within appropriate boundaries. Over time however, all the subtle variations can make it harder to reason across services, particularly when you want to apply broader changes.
In this blogpost I’ll outline, and provide various samples of, how I harmonize such diverse micro service landscapes, and the scripts I use to reduce the accidental complexity in maintaining the various variations.
If we need to create a Java properties file in our build we could create a custom task and use the Properties
class to store a file with properties. Instead of writing our custom task we can use the task WriteProperties
that is already part of Gradle. Using this task Gradle will not add a timestamp in the comment to the properties file. Also the properties are sorted by name, so we know the properties are always in the same order in the output file. Finally, a fixed line separator is used, which is \n
by default, but can be set via the task property lineSeparator
.
To define the properties that need to be in the output file we can use the property
method for a single property, or we can use properties
method with a Map
argument to set multiple properties.
As explained in part two of this series, OBS is a tool that makes it possible to create your ‘virtual camera’. We can use this camera in conferencing tools like Zoom, Slack, Microsoft Teams, Google meet, Signal, and so on. OBS is available for Windows, Mac and Linux, so it will probably work on your system as well. In this part I’m going to explain how to get and install OBS, then we’re going to use it together with the chromakey screen. I’ll focus on the virtual camera support, but the OBS suite can do a lot more. It is free and open source software for video recording and live streaming. It allows you to apply filters, supports NFI (via a plug-in) and much more.
OBS can be found on the OBS project website. Here you’ll find a support forum as well, there is an active community helping you out on problems you might face. For now let’s download the software. Select your operating system en press ‘Download Installer’. When you’re using Linux, it’s a bit harder. If your distribution does not offer OBS Studio as a package, you’ll have to build it yourself. Luckily the build instructions are not that hard to follow. On the Mac or on Windows, the process is straight-forward. After downloading the installer, just run it, and follow the given steps. As it gives you the question for what it should be optimised for, I did choose 'streaming'. You are able to change this later on in the 'Profile menu', when you select 'New'.
The Maven Release plugin allows you to easily craft releases of your own libraries, to share code between projects.
When combined with Semantic Versioning you can communicate clearly to your library users which changes are minor, or potentially breaking.
The plugin will trim off the -SNAPSHOT
suffix of your artifact version, run through all the stages to create your build artifacts, and push those artifacts to a remote registry such as Artifactory.
It will also push a Git tag to your code repository, as well as increment your artifact version to prepare for further development.
This blogpost will run you through the steps to authenticate with both GitLab and Artifactory when running a Maven Release from GitLab CI.