How to make open-source projects, which people want to use

2017-04-01 Conferences, DSP2017, Open source No comments

Today at Kariera IT conference in Katowice, Poland, I presented talk explaining how to make open-source projects, which people want to use from my perspective.

Below, you can find slides from my presentation. Thank you all for the attendance, interesting questions and organizers for inviting me. I hope you learned something new.
Of course, any constructive feedback for this talk will be appreciated :).

Links

Handling different Android versions with strategy pattern

2017-03-26 Android, DSP2017, Software Design Patterns No comments

When we’re developing Android apps, we have to remember that different users have different versions of the Android OS. Unfortunately, not all of them has the newest version of the system and some of them have older devices with older systems. Some of these devices may be even unsupported because e.g. Google supports their devices like Nexus and Pixel for only 2 years. When we want to reach as many users as possible and make the app available for almost everyone, we have to handle different Android versions. One of the solutions for that problem is strategy design pattern (it’s also called Policy in Domain-Driven Design).

I’m developing an Android open-source library called ReactiveNetwork, which is used for monitoring connectivity with the network in the system. Network monitoring strategies vary between different versions of Android and I wanted to choose an appropriate strategy for appropriate Android version. To do so, I’ve created NetworkObservingStrategy interface:

This interface can have many implementations like LollipopNetworkObservingStrategy, PreLollipopNetworkObservingStrategy and MarshmallowNetworkObservingStrategy. Morever, more implementations can be added in the future.

After that, we can choose valid strategy for concrete version of the system:

That’s it. Now, we have the separate code working for Android M, L and all devices with system version lower than L.
This approach can also be applied to other areas.

Review your changes in the code before the commit

2017-03-26 DSP2017, Git 2 comments

Most of the people use git as follows.

  1. they create a feature branch
  2. they make some changes
  3. they add all the changes: git add -A
  4. they commit changes: git commit -m "I've done changes"
  5. they push it: git push

There’s a problem with such approach. When we created a lot of changes, it may happen that we forgot to delete something and we pushed some garbage to the remote repository.

It’s better to review our own changes before the commit.

When we’ve done some changes, instead of typing git add -A, we can type git add -p. It will allow us to review our own changes and approve or disapprove them with typing y (yes) or n (no).

After that process, all changes approved by us are “staged”. Changes, which are not approved are not staged. We can discard unstaged (and also unapproved) changes by typing git checkout -- .. After that, our repository is clean – unwanted changes are discarded & changes, which we approved are staged. Next, we can simply commit & push our changes to the remote repository.

This approach is, in my opinion, very useful and helps to avoid pushing unwanted code to the remote repository, what will hopefully make your co-workers happy.

Android design inspirations

2017-03-19 Android, Design, DSP2017 No comments

When we are planning to create our next Android app, besides the codebase, it’s also good to plan its design, UI, and UX. Before doing that, we can take a look at some inspirations and work of other people to gather a few UI design patterns, inspirations, and ideas.
Good resource of such inspirations is Android Niceties website. As the authors write, this website is
a collection of screenshots encompassing some of the most beautiful looking Android apps.

You can also take a look at https://pl.pinterest.com/explore/android-ui/.

Do you know any other similar resources? Share them in comments :-).

Unit test coverage report with Travis CI for Robolectric on Android

2017-03-19 Android, Continuous Integration, DSP2017, Gradle, Unit Tests No comments

Introduction

Some time ago, I’ve written an article about Test coverage report for Android application. It got some interest (many comments below article and many visits according to Google Analytics), so I decided to refresh this topic. Previously, I’ve written instrumentation unit tests, which needed to be executed on a real device or an emulator. It’s a good approach when you want to test functionalities strongly connected with the device. E.g. when you want to test operations on a real SQLite database or something like that. Nevertheless, this approach has huge disadvantages. It’s hard to run tests on the Continous Integration server because we need to have the emulator or device up & connected all the time and also tests need to interact properly with the device to get passed what is not so easy. In most cases, mocking part of the application’s behavior is enough. In that case, we can easily run tests on a CI server and have deterministic test results. In order to do that, we can use Robolectric.

Gradle configuration

First, we have to add appropriate dependency to jacoco-android plugin in our top-level build.gradle file:

buildscript {
  repositories {
    jcenter()
  }
  dependencies {
    classpath 'com.android.tools.build:gradle:2.3.0'
    classpath 'com.dicedmelon.gradle:jacoco-android:0.1.1'
  }
}

Next, we need to add appropriate test dependencies in another build.gradle file for our app or library.

dependencies {
  testCompile 'junit:junit:4.12'
  testCompile 'com.google.truth:truth:0.32'
  testCompile 'org.robolectric:robolectric:3.1.2'
  testCompile 'org.mockito:mockito-core:2.7.17'
}

I’ve added also dependencies to JUnit, Truth and Mockito library, which are used in my tests.

We also need to add appropriate plugins:

apply plugin: 'jacoco'
apply plugin: 'jacoco-android'

To avoid ignoring our tests by the coverage report, we need to configure the following settings:

android {
  testOptions {
    unitTests.all {
      jacoco {
        includeNoLocationClasses = true
      }
    }
  }
}

Next, we need to configure report output:

jacocoAndroidUnitTestReport {
  csv.enabled false
  html.enabled true
  xml.enabled true
}

Travis CI configuration

We are done with Gradle configuration. I’m assuming we have Travis CI build configured. If you don’t know, how to do this, visit travis-ci.org and enable builds for your project. It’ pretty easy. Now, we should visit codecov.io website, register there (e.g. with GitHub account) and add our project. After that, we need to add the following items to our .travis.yml file:

after_success:
  - bash <(curl -s https://codecov.io/bash)

script:
  - ./gradlew clean build test jacocoTestReport check

Here we are performing clean, build an application, running unit tests, generating test coverage report with Jacoco and performing check (Lint, FindBugs, PMD & CheckStyle).

Writing unit tests with Robolectric

Next we can place our tests in src/test/ directory.
Sample unit test can look as follows:

In my case, I also needed to create src/test/resources/robolectric.properties file with the following content:

sdk=23

because Robolectric didn’t work with the Android SDK newer than 23. Moreover, I also needed to use Robolectric v. 3.1.2, because I had problems with running tests and generating coverage report with the latest version of the Robolectric.

Summary

When we have everything configured, we can push our tests to the GitHub repository, Travis CI build will be triggered and we can beautiful test coverage report, which can help to improve our tests.

We can also click on the main package and see detailed coverage information for the several packages.

Moreover, we can analyze coverage change in time.

I’ve applied approach described in this article in ReactiveNetwork open-source library. If want to see the complete solution, take a look at the source code of this project or see its coverage report on-line.

My approach to Git aliases

2017-03-12 DSP2017, Git No comments

While we are working with Version Control Systems like Git, it’s good to adapt them to our needs to perform daily work in a more productive way. People often create so-called Git aliases, which are shortcuts for longer commands. E.g. you can edit your .gitconfig file, which is usually located in your home directory and place a few aliases in the [alias] section. For example:

[alias]
  ls = log --pretty=format:"%C(yellow)%h%Cred%d\\ %Creset%s%Cblue\\ [%cn]" --decorate

Then you can type: git ls in your Git repository to see pretty Git log.

Sometimes people go further and create many more aliases like:

cp = cherry-pick
st = status
cl = clone
ci = commit
co = checkout
br = branch

and so on. I’ve seen configurations containing about 20 aliases or more consisting of shortcuts, which have 2 or 3 letters. Usually, we don’t use 20 commands every day. I can remember e.g. 5 shortcuts, but I don’t want to remember more.

Instead of alias:

lcm = log -1 --pretty=%B

I prefer:

last-commit-msg = log -1 --pretty=%B

When I’m using terminal on Linux or macOS, I have type hinting, so I can type: git la, hit Tab and terminal will autocomplete my command to git last-commit-. Then I can hit Tab again and I can choose one of my aliases and select one by hitting Enter.

git alias hints in unix terminal

Now, I don’t have to remember all of my aliases. I treat my .gitconfig file as a documentation. Whenever I want to browse aliases, I can type git list-aliases (it’s also an alias to !git config -l | grep alias | cut -c 7- | sort) and if I want to find aliases related to diffs, I can type git list-aliases | grep diff. I also have more descriptive aliases like:

undo-last-commit = reset --hard HEAD^

so I know what this command actually does.

Morover, divided my aliases into separate sections and marked these sections with comments. The sections are as follows:

  • showing metadata
  • showing urls
  • showing commits, logs & branches
  • ignoring files
  • adding & reviewing changes
  • resetting and reverting changes
  • merging changes
  • branching
  • showing diffs
  • searching files

It allows me to keep my aliases in more organized way. It’s useful when our .gitconfig file “lives” and we update it during the work day if we need to.

Maybe this approach won’t be the best way of using Git for everyone, but it works for me and allows me to solve my daily tasks easier and faster.

You can find complete source of my .gitconfig file in my dotfiles repository at https://github.com/pwittchen/dotfiles/blob/master/.gitconfig.

Further reading

Happy coding!

Working with different Git configs

2017-03-10 DSP2017, Git, Linux, macOS No comments

Short introduction

Sometimes people need to specify multiple values for single .gitconfig file or they want to share just part of the configuration between two machines. There are different approaches for that. I can show you mine.

Different configs for different Operating Systems

On my private computer, I use Linux. I use Git for my private projects and I use my private e-mail address there. At the same time, I use Git at work on macOS with exactly the same Git configuration, but with a different e-mail address. How to deal with that?

In my .gitconfig file, I set my private e-mail address, which is used by default. In my .zshrc file, I created two aliases:

alias setupGitPersonal="git config --global user.email \"piotr@wittchen.biz.pl\""
alias setupGitForWork="git config --global user.email \"piotr.wittchen@sap.com\""

Hint: If you want to configure more stuff than just an e-mail, you can do it in the appropriate alias or you can create separate shell scripts for that and place them in /usr/local/bin/ directory.

Then, on Linux, I don’t have to do anything and my private e-mail address is used out-of-the-box.
On macOS, I do the following trick in .zshrc file:

if [ `uname` = "Darwin" ]; then
  setupGitForWork

  # rest of the macOS config goes here...
fi

After that, every time I start terminal on macOS, it automatically sets up my e-mail address to the one I use at work and keeps my .gitconfig file updated.

Hint: If you don’t use zsh, instead of .zshrc file, edit .bashrc file.

Different configs for the same OS on two machines

If you’re using different configs on the different machines with the same OS, you can try another trick. Create configuration file – e.g. .machine_name in your home directory. Setup one name on one machine and another name on a different machine. Next, include this file in your .zshrc or .bashrc file, perform appropriate check and load different settings basing on variable name.

. ~/.machine_name

if [ $machineName = "workMachine" ]; then
  setupGitForWork
else
  setupGitPersonal
fi

Contents of the .machine_name file are simple:

machineName="workMachine"

Different configs on the single machine with one OS

In such case, we are supposed to perform the manual switch. We can use aliases provided above. When we want to have personal settings, we can open terminal and type setupGitPersonal. When we want to apply work settings, then we can type setupGitForWork.

Summary

As we can see, keeping different configs for different machines or operating systems and changing them depending on our needs is not so hard. I hope these ideas will help you to manage your configs.

SJUG updates – March 2017

2017-03-05 DSP2017, Java, Meetups No comments

SJUG aka Silesia Java Users Group meetups were reactivated one year ago and it’s still alive! I think it’s a great success of the community of Java developers who are located there. It’s not an easy thing to gather people from different cities in the region in one place every month, but it’s possible! During the year we gathered a few sponsors and partners, discounts for software tools and tickets for the conferences. Moreover, we had guests outside the Silesian region. There were really interesting presentations and discussions. Recently, I updated the website of the SJUG, so it automatically downloads information about the latest meetup. Now, we don’t have to do it manually every time.
Next meetup is planned for this Friday (10.03.2017) and if you’re interested in it, feel free to join.

More details about the group:

Control Spotify on Linux like a hacker

2017-03-05 DSP2017, Linux, Open source, Python No comments

Recently, I created a tiny script called spotify-cli, which allows you to control Spotify on Linux from terminal. It’s inspired by shpotify, which is a shell script doing similar things, but on macOS. My script is written in Python and uses dbus under the hood, which allows to communicate with bus daemon to pass messages between applications. I used pactl for controlling the system sound.

You can install spotify-cli as follows via wget:

sh -c "$(wget https://raw.githubusercontent.com/pwittchen/spotify-cli-linux/master/install.sh -O -)"

or via curl:

sh -c "$(curl -fsSL https://raw.githubusercontent.com/pwittchen/spotify-cli-linux/master/install.sh)"

After that, you can just type spotify-cli in your terminal.
You can use spotify-cli with the following parameters:

--help, -h          shows help
--status            shows status (currently played song name and artist)
--play              plays the song
--pause             pauses the song
--playpause         plays or pauses the song (toggles a state)
--next              plays the next song
--previous, --prev  plays the previous song
--volumeup          increases sound volume
--volumedown        decreases sound volume

That’s it! Happy listening!

Source code of the project can be found at https://github.com/pwittchen/spotify-cli-linux.

KrkDataLink Meetup – Functional Programming & Data Science

2017-02-09 Meetups No comments

Recently, a lot of new interesting meetups connected with IT were started in Poland. Yet another meetup is starting in Kraków in the middle of February. It’s called KrkDataLink and is related to functional programming and data science. These topics became hot recently, so it’s worth to be up to date with them. You can find more details about this event on the meetup website.

Visit website of the event!