Git Bash: Shell prompt customization

What is it?

Git Bash for Windows is not just bash compiled for Windows. It is a package that contains bash, which is a command-line shell, and a collection of other, separate *nix utilities which you can run using the shell, compiled for Windows, and a new command-line interface terminal window called mintty.

You can download it from here.

Shell prompt customization

If we want to customize the shell prompt according to our preferences, we just need to edit the file “git-prompt.sh”. In a Windows x64 system, we can find it in:

C:\Program Files\Git\etc\profile.d\git-prompt.sh

Now we just need to play a little bit with the different options available.

As an example, the version I am using right now looks like that:

TITLEPREFIX='Bash Prompt (Git for Windows) =>'

PS1='\[\033]0;$TITLEPREFIX:${PWD//[^[:ascii:]]/?}\007\]' # set window title
PS1="$PS1"'\[\033[32m\]'       # change to green
PS1="$PS1"'\w'                 # current working directory
if test -z "$WINELOADERNOEXEC"
then
    GIT_EXEC_PATH="$(git --exec-path 2>/dev/null)"
    COMPLETION_PATH="${GIT_EXEC_PATH%/libexec/git-core}"
    COMPLETION_PATH="${COMPLETION_PATH%/lib/git-core}"
    COMPLETION_PATH="$COMPLETION_PATH/share/git/completion"
    if test -f "$COMPLETION_PATH/git-prompt.sh"
    then
        . "$COMPLETION_PATH/git-completion.bash"
        . "$COMPLETION_PATH/git-prompt.sh"
        PS1="$PS1"'\[\033[36m\]'  # change color to cyan
        PS1="$PS1"'`__git_ps1`'   # bash function
    fi
fi
PS1="$PS1"'\[\033[0m\]'        # change color
PS1="$PS1"'$ '                 # prompt: always $
MSYS2_PS1="$PS1"               # for detection by MSYS2 SDK's bash.basrc
Git Bash: Shell prompt customization

Error Prone

We, as a developers, sometimes, make mistakes or add bugs to our code without realizing. For this reason static analyzers are a handy tool to apply during our builds or during our code verification processes.

One of these tools is Error Prone.

Error Prone is Google’s Java bug detection and static analysis tool. It is integrated into the Java compiler and catches bugs at compile time. It supports plugin checks for project-specific enforcement.

Basically, it is a tool created by Google for code analysis and error detection for the Java language. It is integrated inside the compiler and tries to detect bugs in compilation time.

But, let’s see and example. Imagine we have a program with the next line of code:

String.format("Param A: {}, param B: {}, param C: {}", paramA, paramB, paramC);

Obviously, it is not correct and the error comes from, maybe, a transformation between a previous log message to a different kind of message. The compiler is not going to complain because it is a string message and it is not a syntax error. But, the truth is there is an error.

When we try to compile the program with Error Prone, we are going to receive a compilation error message like this:

error: [FormatString] extra format arguments: used 0, provided 3
String.format("Param A: {}, param B: {}, param C: {}", paramA, paramB, paramC);
             ^
(see http://errorprone.info/bugpattern/FormatString)

We can see clearly and without any doubts there is an error. Even, a link to the error description is provided.

The proper code should be:

String.format("Param A: %s, param B: %s, param C: %s", paramA, paramB, paramC);

The easiest way to start using the tool, it is to add the maven plugin to our pom.xml file:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.3</version>
    <configuration>
        <compilerId>javac-with-errorprone</compilerId>
        <forceJavacCompilerUse>true</forceJavacCompilerUse>
        <source>8</source>
        <target>8</target>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>org.codehaus.plexus</groupId>
            <artifactId>plexus-compiler-javac-errorprone</artifactId>
            <version>2.8.1</version>
        </dependency>
        <dependency>
            <groupId>com.google.errorprone</groupId>
            <artifactId>error_prone_core</artifactId>
            <version>2.0.19</version>
        </dependency>
    </dependencies>
</plugin>

For more options, just go to the installation instructions page.

The project is open source and you can see all the code in the official repository: error-prone.

I am not saying that it is going to solve all your problems but, at least, it is another tool to increase our code quality and avoid silly mistakes.

Error Prone

Publishing to GitHub

GitHub is a web-based Git or version control repository and Internet hosting service. As a developers, I am quite sure that all of you know the platform.

Every-time we start a new project, even if it is just something for us, it is a good idea to use a version control system. Here is where Git and GitHub can help us.

There are two easy ways to create and upload our project to a repository.

The first way, it is to create the repository in GitHub, and after that clone in our machine the created repository and start writing our code. This is the simplest way. Doing it in this way, our local repository is already connected to the remote repository and we just need to start committing things. The clone command, assuming the account name is “fjavierm” and the repository name is “myproject”,  is:

git clone https://github.com/fjavierm/myproject.git

Te second way, it is when we already have a project in our local machine and we want to add the project to a repository. In this case, we need to perform a few more steps.

1. We need to create the repository under our GitHub account. In this case, my account is “fjavierm” and my repository is going to be “myproject”.

2. In our local machine, in our local project folder, we need to initiate the git repository. This will add a folder “.git”:

git init

3. We can check the status of the available files:

git status

This instruction will show us the files that we can add to the repository to commit. In this step, it deserves to pay special attention to the files that we do not want to add and, maybe, it is a good idea to create the files “.gitignore” and “README.md”

4. Add the files to the repository:

git add .

5. Commit the added files adding a descriptive message. Usually, issue number and description, or something meaningful.:

git commit -m "Starting the project."

6. Connect our local repository with our remote repository:

git remote add origin https://github.com/fjavierm/myproject.git

7. Check we have perform the previous step properly:

git remote -v

8. Push our changes to the remote repository:

git push -u origin master

With these few instructions we should have available all our code in the GitHub repository.

Publishing to GitHub

Learn and Practice Linux online

Everyone working with technology knows or should know that Linux is one of the biggest platforms out-there. Maybe not in desktop environment where Windows in the king but, when we are talking about servers, I would say that Linux or Unix are the king of kings. In addition, it has a very good relation with developers and system administrators.

One of the most powerful tools we can find in Linux is the terminal. You can do multiple things with it. There are commands that can save our lives in punctual moments, commands that perform useful actions and, in general, commands that help us in our daily tasks, making our lives easier.

But the truth is, at the beginning, it can be scary. A lot of people tend to learn just the top 10 commands or to have just a cheat-sheet with the commands they use every day or people in their teams use. Sometimes, we do not know what the terminal is able to do it.

To solve this problem or, at least, help us to improve our knowledge around the terminal capabilities and the available commands, one of the options is to use Webminal. Webminal offer us an online terminal we can use to play and learn. In addition, it offers us some instructions about how to use the commands. When you are using the platform, it splits the screen in two parts. In the left side we can see a fully functional terminal and, in the right side we can see detailed instructions about how to use the different commands.

Just another tools to help us with our daily learning.

Learn and Practice Linux online

Java REST API + cURL + python3

During the next lines, I am going to implement a very simple REST API using JavaEE 7 and Java SE 8 technologies, maven as build tool and GlassFish as application server. I am going to test this API with cURL and, I am going to consume this API using python3 using the Requests module.

Java EE 7 REST API

First, we need to create a maven project in our favorite IDE and add our dependencies to the pom.xml file

...
<properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <failOnMissingWebXml>false</failOnMissingWebXml>
</properties>

<dependencies>
    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>eclipselink</artifactId>
        <version>2.5.2</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>org.eclipse.persistence.jpa.modelgen.processor</artifactId>
        <version>2.5.2</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-api</artifactId>
        <version>7.0</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

<build>
    <finalName>apicrud</finalName>
</build>
...

Second, we are going to create a persistence.xml file. In this case, we are not interested in how to configure a DB, then, we are going to use the default datasource that GlassFish provides us as default “jdbc/__default“. With all of this in mind, the file should look like this:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
        http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="ApiCrudPU" transaction-type="JTA">
        <jta-data-source>jdbc/__default</jta-data-source>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <properties>
            <property name="javax.persistence.schema-generation.database.action" value="create"/>
        </properties>
    </persistence-unit>
</persistence>

Now, we need to create our Entity. In this case, I have chosen a simple one, User with three attributes:

  • id: Autogenerated id to identify the user.
  • name: User’s name.
  • email: User’s email.

The result should be something like:

package com.wordpress.binarycoders.apicrud;

import java.io.Serializable;
import java.util.Objects;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

@Entity
@Table (name = "users")
@NamedQueries ({
    @NamedQuery (name = User.FIND_ALL, query = "SELECT u FROM User u")
})
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class User implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    public static final String FIND_ALL = "User.findAll";
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    
    @Column(name = "name")
    private String name;
    
    @Column(name = "email")
    private String email;

    /* Getters, Setters, equals and hashCode methods */    
}

The next step, it is to implement the boundary or service layer. Being a simple example, we can skip this layer, but I like to implement everything for learning purposes. This layer is going to be very simple, only the necessary object to perform the operation in the DB and the basic operations to implement a CRUD. The result looks like:

package com.wordpress.binarycoders.apicrud;

import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.validation.constraints.NotNull;

@Stateless
public class UserService {
    
    @PersistenceContext
    private EntityManager em;
    
    public void create(@NotNull User user) {
        this.em.persist(user);
    }
    
    public User findById(@NotNull Long id) {
        return this.em.find(User.class, id);
    }
    
    public List<User> findAll() {
        TypedQuery<User> typedQuery = this.em.createNamedQuery(User.FIND_ALL, User.class);

        return typedQuery.getResultList();
    }
    
    public void update(@NotNull User user) {
        this.em.merge(user);
    }
    
    public void delete(@NotNull Long id) {
        this.em.remove(this.findById(id));
    }
}

To do all of this available to the world, we need to implement our REST API, and for this, we need to configure the REST capabilities in our system, piece of cake with the last version of Java EE. We just need to create a class to enable these capabilities:

package com.wordpress.binarycoders.apicrud;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("/rs")
public class ApplicationConfig extends Application {
    
}

And, finally, we need to implement our REST layer with the four actions that are going to allow us to perform the CRUD operations:

package com.wordpress.binarycoders.apicrud;

import java.net.URI;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

@Path("/users")
@Produces ({ MediaType.APPLICATION_JSON })
@Consumes ({ MediaType.APPLICATION_JSON })
@Stateless
public class UserEndPoint {
    
    @EJB
    private UserService service;
    
    @Context
    private UriInfo uriInfo;
    
    @GET
    public Response findAll() {
        List<User> users = this.service.findAll();
        
        GenericEntity<List<User>> list = new GenericEntity<List<User>>(users) {};
        
        return Response.ok(list).build();
    }
    
    @GET
    @Path("/{id}")
    public Response findById(@PathParam("id") Long id) {
        User user = this.service.findById(id);
        
        if (user == null) {
            throw new NotFoundException();
        }
        
        return Response.ok(user).build();
    }
    
    @POST
    public Response create(User user) {
        this.service.create(user);
        
        URI uri = uriInfo.getAbsolutePathBuilder().path(String.valueOf(user.getId())).build();
        
        return Response.created(uri).build();
    }
    
    @PUT
    public Response update(User user) {
        this.service.update(user);
        
        return Response.ok().build();
    }
    
    @DELETE
    @Path("/{id}")
    public Response delete(@PathParam("id") Long id) {
        this.service.delete(id);
        
        return Response.noContent().build();
    }
}

I think that in this point, assuming that everyone reading this, it is a developer and this is not an entry level post, all of you should be capable to understand everything has been written in the above lines. If there are things that you do not know or you do not understand due to a lack of information or your knowledge is not enough (all of us have been there), look at the note at the end of this post.

cURL test

Now, obviously, we need to test if our REST API is working properly. For this, we can implement some solution based on test frameworks or manual code but, due to the simplicity of the object User, it is enough with the cURL tool. To test our API we are going to perform these operations:

  • Select all the users
  • Create a user
  • Select the created user
  • Update the user
  • Delete the user

These operations can be performed with the next commands:

curl -i -H "Content-Type: application/json" http://localhost:8080/ApiCRUD/rs/users
curl -i -H "Content-Type: application/json" -X POST -d '{"name":"john","email":"john@example.org"}' http://localhost:8080/ApiCRUD/rs/users
curl -i -H "Content-Type: application/json" http://localhost:8080/ApiCRUD/rs/users/1
curl -i -H "Content-Type: application/json" -X PUT -d '{"id”:1,”name":"John Doe","email":"john.doe@example.org"}' http://localhost:8080/ApiCRUD/rs/users
curl -i -H "Content-Type: application/json" -X DELETE http://localhost:8080/ApiCRUD/rs/users/1

Everything should look well, and the appropriate HTTP codes should be received.

Python3 client

The last step today, it is to implement a very very simple python3 client to consume our API. This is going to be a basic script to invoke the CRUD operations available in the API.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import requests
import json

URL = 'http://localhost:8080/ApiCRUD/rs/users'

def getUsers():
	print('Get users...\n')

	response = requests.get(URL)

	assert response.status_code == 200

	users = response.json()
	print(json.dumps(users, indent = 4, separators = (',', ':')))

def getUser(location):
	print('Get single user ...\n')

	response = requests.get(location)

	assert response.status_code == 200

	users = response.json()
	print(json.dumps(users, indent = 4, separators = (',', ':')))

def createUser():
	print('Creating user...\n')

	headers = {'content-type': 'application/json'}
	user = {"name": "John Doe", "email": "john.doe@example.org"}
	response = requests.post(URL, data = json.dumps(user), headers = headers)

	assert response.status_code == 201

	print('Location: ' + response.headers['location'])

	return response.headers['location']

def updateUser(location):
	print('Updating user...')

	loc = location.split('/')

	headers = {'content-type': 'application/json'}
	user = {"id": loc[-1], "name": "Jane Doe", "email": "jane.doe@example.org"}
	response = requests.put(URL, data = json.dumps(user), headers = headers)

	assert response.status_code == 200

def deleteUser(location):
	print('Deleting user...')

	response = requests.delete(location)

	assert response.status_code == 204

	print('Checking delete operation')
	response = requests.get(location)

	assert response.status_code == 404

def main():
	getUsers()
	location = createUser()
	getUser(location)
	updateUser(location)
	getUser(location)
	deleteUser(location)

if __name__ == "__main__":
	main()

And that’s all. Now, we have a little REST AP, a python3 client and a basic knowledge about how to use cURL to test it.

See you.

You can find the code for the REST API available here.

Note: All the content in this post will be splitter and explained in future post, one for each one of the three big point explained in here: Java EE 7 REST API creation, cURL test and python3 REST client.

Java REST API + cURL + python3