Working with GitHub and pull requests a lot, I end up accumulating stale branches that are no longer needed. In this post, we will look at how to clean the stale local branches.
There are mainly two strategies:
Pick a “master” branch, and delete what’s merged to it
Assuming branches are deleted first on GitHub, delete local branches that no longer exists on remote “origin”
I’ve been thinking about rich console applications, the kind of apps that can display things graphically, not just appending lines at the end. Here are some info, enough parts to be able to write Tetris.
ANSI X3.64 control sequences
To display some text at an arbitrary location on a termial screen, we first need to understand what a terminal actually is. In the middle of 1960s, companies started selling minicomputers such as PDP-8, and later PDP-11 and VAX-11. These were of a size of a refrigerator, purchased by “computer labs”, and ran operating systems like RT-11 and the original UNIX system that supported up many simultaneous users (12 ~ hundreds?). The users connected to a minicomputer using a physical terminal that looks like a monochrome screen and a keyboard. The classic terminal is VT100 that was introduced in 1978 by DEC.
Whether you want to try using OpenJDK 11-ea, GraalVM, Eclipse OpenJ9, or you are stuck needing to build using OpenJDK 6, jabba has got it all. jabba is a cross-platform Java version manager written by Stanley Shyiko (@shyiko).
AdoptOpenJDK 8 and 11
Here’s how we can use jabba on Travis CI to cross build using AdoptOpenJDK 8 and 11:
Power assert (or power assertion) is a variant of assert(...) function that that prints out detailed error message automatically. It was originally implemented by Peter Niederwieser (@pniederw) for Spock, and in 2009 it was merged into Groovy 1.7. Power assert has spread to Ruby, JavaScript, Rust, etc.
traditional assert statements
Let’s say you have something like a * b. Using a traditional assert, we would write:
dist: trustylanguage: scalamatrix:
include:
## build using JDK 8, test using JDK 8 - script:
- sbt universal:packageBin - cd citest && ./test.shjdk: oraclejdk8## build using JDK 8, test using JDK 8, on macOS - script:
- sbt universal:packageBin - cd citest && ./test.sh## https://github.com/travis-ci/travis-ci/issues/2316language: javaos: osxosx_image: xcode9.2## build using JDK 8, test using JDK 9 - script:
- sbt universal:packageBin - jdk_switcher use oraclejdk9 - cd citest && ./test.shjdk: oraclejdk8## build using JDK 8, test using JDK 10 - script:
- sbt universal:packageBin - citest/install-jdk10.sh - cd citest && ./test.shjdk: oraclejdk8scala:
- 2.10.7before_install:
# https://github.com/travis-ci/travis-ci/issues/8408 - unset _JAVA_OPTIONS - if [[ "$TRAVIS_OS_NAME" = "osx" ]]; thenbrew update;brew install sbt;ficache:
directories:
- $HOME/.ivy2/cache - $HOME/.sbt/bootbefore_cache:
- find $HOME/.ivy2 -name "ivydata-*.properties" -delete - find $HOME/.sbt -name "*.lock" -delete
Normally you’d write jdk: oraclejdk8 at the top level, but since the macOS image does not have the jdk_switcher script travis/travis#2317, we need to add to all entries in the matrix except for the osx one.
Oracle is moving to ship non-LTS JDK every 6 months, and LTS JDK every 3 years. Also it’s converging to OpenJDK. In this scheme, JDK 9 will be EOL in March 2018; JDK 10 will come out in March 2018, and EOL in September 2018; and LTS JDK 11 that replaces JDK 8 in September 2018 will stay with us until 2021.
As we will see quick succession of JDKs in the upcoming months, here’s a how-to on testing your app on JDK 8, JDK 9, and JDK 10 Early Access using Travis CI.
During the SIP-27 trailing commas discussion, one of the thoughts that came to my mind was unifiying some of the commas with semicolons, and take advantage of the semicolon inference.
This holiday break, I somehow got into binge watching Coursera’s Stanford Machine Learning course taught by Andrew Ng. I remember machine learning to be really math heavy, but I found this one more accessible.
Here are some notes for my own use. (I am removing all the fun examples, and making it dry, so if you’re interested in machine learning, you should check out the course or its official notes.)
Intro
Machine learning splits into supervised learning and unsupervised learning.
Future readers might also want to search for “file URI scheme RFC”, and find the latest version. If you’re a programmer, read the RFC. This post is to raise the awareness of the some of the issues around file to URI encoding, but it’s not a substitution.
On Tech Hub blog I demonstrated how to use sbt server from VS Code to display compiler errors from a running sbt session. In this post, I’ll show how to do that for Sublime Text 3 in this post.
cd ~/Library/Application\ Support/Sublime\ Text\ 3/Packages
git clone https://github.com/tomv564/LSP.git
Run ‘Preferences > Package Control > Satisfy Dependencies’
Next, download sbt-server-stdio.js and save it to ~/bin/ or somewhere you keep scripts. sbt server by default uses Unix domain sockets on POSIX systems and named pipe on Windows, but editors seem to expect stdio. The script is a Node script that’s included as our VS Code extension that discovers the socket, and fronts it with stdio.
It’s been a month since sbt 1.0 shipped, and I can finally sit back and think about sbt server again. Using my weekends time, I started hacking on an implementation of Scala language server on top of sbt server.
what is a language server?
A language server is a program that can provide language service to editors like Visual Studio Code, Eclipse Che, and Sublime Text 3 via Language Server Protocol. A typical operation might be textDocument/didOpen, which tells the server that a source file was opened in the editor.
In this post, I’d like to introduce a version scheme that I call Persistent Versioning. Most of the ideas presented in this post are not new or my own. Let me know if there’s already a name for it.
GitHub Pages is a convenient place to host OSS project docs.
This post explains how to use Travis CI to deploy your docs automatically on a pull request merge.
1. Generate a fresh RSA key in some directory
Make a directory outside of your project first.
Pick a key name deploy_yourproject_rsa, so you can distinguish it from other keys.
$ mkdir keys
$ cd keys
$ ssh-keygen -t rsa -b 4096 -C "yours@example.com"Generating public/private rsa key pair.
Enter file in which to save the key (/Users/xxx/.ssh/id_rsa): deploy_website_rsa
Enter passphrase (empty for no passphrase):
In the last post that I wrote about Atreus build, I noted that there’s an issue of keyboard positioning:
Even if I can overcome the layout and memorize the various symbol locations, there’s the issue of the placement. If I place the keyboard in between me and the laptop the screen becomes too far.
I solved this issue by making a tray for Atreus that I can position it on top of the MacBook Pro keyboard.
I’ve been asked by a few people on downloading JARs, and then running them from an sbt plugin.
Most recently, Shane Delmore (@shanedelmore) asked me about this at nescala in Brooklyn.
During an unconference session I hacked together a demo, and I continued some more after I came home.
sbt-sidedish
sbt-sidedish is a toolkit for plugin authors to download and run an app on the side from a plugin.
It on its own does not define any plugins.
Here are a few questions I’ve been thinking about:
How should I express data or API?
How should the data be represented in Java or Scala?
How do I convert the data into wire formats such as JSON?
How do I evolve the data without breaking binary compatibility?
limitation of case class
The sealed trait and case class is the idiomatic way to represent datatypes in Scala, but it’s impossible to add fields in binary compatible way. Take for example a simple case class Greeting, and see how it would expand into a class and a companion object:
Gigahorse 0.2.0 is now released. The new change is that it abstracts over two backends. @alexdupre contributed migration from AHC 1.9 to AHC 2.0, which is based on Netty 4 in #12.
In addition, there’s now an experimental Akka HTTP support that I added. #15
Gigahorse 0.1.0 is now released. It is an HTTP client for Scala with Async Http Client underneath. Please see Gigahorse docs for the details. Here’s an example snippet to get the feel of the library.
scala>import gigahorse._
scala>import scala.concurrent._, duration._scala>Gigahorse.withHttp(Gigahorse.config){ http =>val r =Gigahorse.url("http://api.duckduckgo.com").get. addQueryString("q"->"1 + 1","format"->"json")val f = http.run(r,Gigahorse.asString andThen {_.take(60)})Await.result(f,120.seconds)}
There’s a “pattern” that I’ve been thinking about, which arises in some situation while persisting/serializing objects.
To motivate this, consider the following case class:
scala>caseclassUser(name:String, parents:List[User])defined classUserscala>val alice =User("Alice",Nil)alice:User=User(Alice,List())scala>val bob =User("Bob", alice ::Nil)bob:User=User(Bob,List(User(Alice,List())))scala>val charles =User("Charles", bob ::Nil)charles:User=User(Charles,List(User(Bob,List(User(Alice,List())))))scala>val users =List(alice, bob, charles)users:List[User]=List(User(Alice,List()),User(Bob,List(User(Alice,List()))),User(Charles,List(User(Bob,List(User(Alice,List()))))))
The important part is that it contains parents field, which contains a list of other users.
Now let’s say you want to turn users list of users into JSON.