├── .circleci └── config.yml ├── .dockerignore ├── .gitignore ├── .scalafmt ├── Dockerfile ├── LICENSE ├── README.md ├── build.sbt ├── entrypoint.sh ├── project ├── build.properties └── plugins.sbt └── src ├── main ├── AndroidManifest.xml ├── libs │ └── android-support-v4.jar ├── res │ ├── drawable-hdpi │ │ └── icon_launcher.png │ ├── drawable-mdpi │ │ └── icon_launcher.png │ ├── drawable-xhdpi │ │ └── icon_launcher.png │ ├── drawable-xxhdpi │ │ └── icon_launcher.png │ ├── drawable-xxxhdpi │ │ └── icon_launcher.png │ ├── layout │ │ └── main.xml │ ├── values-v21 │ │ └── themes.xml │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── themes.xml └── scala │ └── com │ └── example │ └── Hello.scala └── test └── scala └── com └── example └── test └── Test.scala /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | jobs: 3 | build: 4 | working_directory: /app/ 5 | docker: 6 | - image: docker:17.11.0-ce-rc2-git 7 | steps: 8 | - checkout 9 | - setup_remote_docker 10 | - restore_cache: 11 | keys: 12 | - v1-{{ .Branch }} 13 | paths: 14 | - /caches/hello-scala.tar 15 | - run: 16 | name: Load Docker image layer cache 17 | command: | 18 | set +o pipefail 19 | docker load -i /caches/hello-scala.tar | true 20 | - run: 21 | name: Build docker images 22 | command: | 23 | docker build --cache-from=hello-scala -t hello-scala . 24 | - run: 25 | name: Save Docker image layer cache 26 | command: | 27 | mkdir -p /caches/ 28 | docker save -o /caches/hello-scala.tar hello-scala 29 | - save_cache: 30 | key: v1-{{ .Branch }}-{{ epoch }} 31 | paths: 32 | - /caches/hello-scala.tar 33 | - run: 34 | name: Run tests 35 | command: | 36 | docker create -v /app/ --name app alpine /bin/true 37 | docker cp /app/ app:/ 38 | docker run \ 39 | --volumes-from app \ 40 | --entrypoint="./entrypoint.sh" \ 41 | hello-scala -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .git/ 3 | target/ 4 | project/project/ 5 | project/target/ -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | proguard-sbt.txt 2 | target/ 3 | -------------------------------------------------------------------------------- /.scalafmt: -------------------------------------------------------------------------------- 1 | maxColumn = 80 -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jdk-alpine 2 | 3 | ENV ANDROID_BUILD_TOOLS 27.0.0 4 | ENV ANDROID_PLATFORM 27 5 | ENV ANDROID_SDK 3859397 6 | ENV GLIBC "2.25-r0" 7 | 8 | # Install wget and unzip; add SSL certs to wget 9 | RUN apk update 10 | RUN apk add --no-cache ca-certificates wget bash 11 | RUN update-ca-certificates 12 | 13 | # Install glibc for Android SDK 14 | RUN wget -q https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub -O /etc/apk/keys/sgerrand.rsa.pub 15 | RUN wget -q https://github.com/sgerrand/alpine-pkg-glibc/releases/download/$GLIBC/glibc-$GLIBC.apk -O /tmp/glibc.apk 16 | RUN wget -q https://github.com/sgerrand/alpine-pkg-glibc/releases/download/$GLIBC/glibc-bin-$GLIBC.apk -O /tmp/glibc-bin.apk 17 | RUN apk add --no-cache /tmp/glibc.apk /tmp/glibc-bin.apk 18 | RUN rm /tmp/glibc.apk /tmp/glibc-bin.apk /etc/apk/keys/sgerrand.rsa.pub 19 | 20 | # Install Sbt 21 | RUN wget -q https://raw.githubusercontent.com/paulp/sbt-extras/master/sbt -O /bin/sbt 22 | RUN chmod +x /bin/sbt 23 | 24 | # Install Android SDK 25 | RUN mkdir /android-sdk 26 | RUN wget -q -O /android-sdk/android-tools.zip https://dl.google.com/android/repository/sdk-tools-linux-$ANDROID_SDK.zip 27 | RUN cd /android-sdk && unzip -q ./android-tools.zip 28 | RUN rm /android-sdk/android-tools.zip 29 | ENV ANDROID_HOME /android-sdk/ 30 | ENV PATH $PATH:$ANDROID_HOME/tools/:$ANDROID_HOME/platform-tools/ 31 | 32 | # Install major Android SDK components (tools/bin/sdkmanager --list) 33 | RUN yes | /android-sdk/tools/bin/sdkmanager \ 34 | "platform-tools" \ 35 | "tools" \ 36 | "build-tools;$ANDROID_BUILD_TOOLS" \ 37 | "platforms;android-$ANDROID_PLATFORM" \ 38 | "extras;android;m2repository" \ 39 | "extras;google;m2repository" 40 | 41 | RUN mkdir -p /cache/project/ 42 | RUN mkdir -p /cache/src/main/ 43 | RUN mkdir -p /cache/src/test/scala/ 44 | ADD ./build.sbt /cache/ 45 | ADD ./project/build.properties ./project/plugins.sbt /cache/project/ 46 | RUN echo "class Test" > /cache/src/test/scala/Test.scala 47 | RUN echo "" > /cache/src/main/AndroidManifest.xml 48 | RUN cd /cache/ && sbt test 49 | RUN rm -rf ./cache/ 50 | 51 | WORKDIR /app/ 52 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Niklas Klein 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hello Scala! 2 | 3 | [![Circle CI](https://circleci.com/gh/Taig/hello-scala/tree/master.svg?style=shield)](https://circleci.com/gh/Taig/hello-scala/tree/master) 4 | 5 | *Scala on Android* starter template for http://scala-on-android.taig.io/ 6 | 7 | ## Usage 8 | 9 | Clone the repository and navigate your terminal to the project's root directory. Execute `sbt run` to compile and deploy the sample app on your device. 10 | 11 | ![App screenshot](http://taig.io/hello-scala/screenshot.png) -------------------------------------------------------------------------------- /build.sbt: -------------------------------------------------------------------------------- 1 | enablePlugins(AndroidApp) 2 | 3 | fork in Test := true 4 | 5 | // Enforce Java 7 compilation (in case you have the JDK 8 installed) 6 | javacOptions ++= 7 | "-source" :: "1.7" :: 8 | "-target" :: "1.7" :: 9 | Nil 10 | 11 | libraryDependencies ++= 12 | "io.taig" %% "communicator" % "3.3.0" :: 13 | "com.android.support" % "appcompat-v7" % "27.1.1" :: 14 | "com.android.support" % "cardview-v7" % "27.1.1" :: 15 | "com.android.support" % "design" % "27.1.1" :: 16 | "com.android.support" % "gridlayout-v7" % "27.1.1" :: 17 | "com.android.support" % "recyclerview-v7" % "27.1.1" :: 18 | "com.android.support" % "support-v4" % "27.1.1" :: 19 | "com.google.code.findbugs" % "jsr305" % "3.0.2" % "compile" :: 20 | "com.geteit" %% "robotest" % "0.12" % "test" :: 21 | "org.scalatest" %% "scalatest" % "3.0.5" % "test" :: 22 | Nil 23 | 24 | name := "hello-scala" 25 | 26 | // Predefined as IceCreamSandwich (4.0), nothing stops you from going below 27 | minSdkVersion := "14" 28 | 29 | // Prevent common com.android.builder.packaging.DuplicateFileException. 30 | // Add further file names if you experience the exception after adding new dependencies 31 | packagingOptions := PackagingOptions( 32 | excludes = 33 | "META-INF/LICENSE" :: 34 | "META-INF/LICENSE.txt" :: 35 | "META-INF/NOTICE" :: 36 | "META-INF/NOTICE.txt" :: 37 | Nil 38 | ) 39 | 40 | platformTarget := "android-27" 41 | 42 | proguardCache ++= 43 | "android.support" :: 44 | "cats" :: 45 | "io.circe" :: 46 | "monix" :: 47 | "okhttp3" :: 48 | "shapeless" :: 49 | Nil 50 | 51 | proguardOptions ++= 52 | "-keepattributes EnclosingMethod,InnerClasses,Signature" :: 53 | "-dontwarn org.w3c.dom.bootstrap.DOMImplementationRegistry" :: 54 | "-dontwarn javax.xml.bind.DatatypeConverter" :: 55 | "-dontnote org.joda.time.DateTimeZone" :: 56 | "-dontnote scala.concurrent.stm.impl.STMImpl$" :: 57 | "-dontnote okhttp3.internal.**" :: 58 | "-dontwarn io.circe.generic.util.macros.**" :: 59 | "-dontwarn monix.execution.internals.**" :: 60 | "-dontnote monix.execution.internals.**" :: 61 | "-dontwarn okio.**" :: 62 | "-dontwarn org.jctools.**" :: 63 | "-dontwarn org.slf4j.**" :: 64 | Nil 65 | 66 | resolvers += "Google Maven" at "https://maven.google.com" 67 | 68 | // Shortcut: allows you to execute "sbt run" instead of "sbt android:run" 69 | run := (run in Android).evaluated 70 | 71 | scalacOptions ++= 72 | // Print detailed deprecation warnings to the console 73 | "-deprecation" :: 74 | // Print detailed feature warnings to the console 75 | "-feature" :: 76 | Nil 77 | 78 | // Don't upgrade to 2.12.x as it requires Java 8 which does not work with Android 79 | scalaVersion := "2.11.12" 80 | 81 | targetSdkVersion := "27" 82 | 83 | versionCode := Some(0) 84 | 85 | versionName := Some("0.0.0") 86 | 87 | parallelExecution in Global := false 88 | -------------------------------------------------------------------------------- /entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | sbt ";scalafmt::test;test:scalafmt::test;sbt:scalafmt::test" 6 | sbt test -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=0.13.17 -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | addSbtPlugin( "com.lucidchart" % "sbt-scalafmt" % "1.15" ) 2 | 3 | addSbtPlugin( "org.scala-android" % "sbt-android" % "1.7.10" ) -------------------------------------------------------------------------------- /src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/main/libs/android-support-v4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taig/hello-scala/445984bf70fcb8e95ba135ee7e8dc39f490f3b01/src/main/libs/android-support-v4.jar -------------------------------------------------------------------------------- /src/main/res/drawable-hdpi/icon_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taig/hello-scala/445984bf70fcb8e95ba135ee7e8dc39f490f3b01/src/main/res/drawable-hdpi/icon_launcher.png -------------------------------------------------------------------------------- /src/main/res/drawable-mdpi/icon_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taig/hello-scala/445984bf70fcb8e95ba135ee7e8dc39f490f3b01/src/main/res/drawable-mdpi/icon_launcher.png -------------------------------------------------------------------------------- /src/main/res/drawable-xhdpi/icon_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taig/hello-scala/445984bf70fcb8e95ba135ee7e8dc39f490f3b01/src/main/res/drawable-xhdpi/icon_launcher.png -------------------------------------------------------------------------------- /src/main/res/drawable-xxhdpi/icon_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taig/hello-scala/445984bf70fcb8e95ba135ee7e8dc39f490f3b01/src/main/res/drawable-xxhdpi/icon_launcher.png -------------------------------------------------------------------------------- /src/main/res/drawable-xxxhdpi/icon_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taig/hello-scala/445984bf70fcb8e95ba135ee7e8dc39f490f3b01/src/main/res/drawable-xxxhdpi/icon_launcher.png -------------------------------------------------------------------------------- /src/main/res/layout/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 13 | 14 | 22 | 23 | 24 | 25 | 27 | 28 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/main/res/values-v21/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | 16 | -------------------------------------------------------------------------------- /src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | #DC322F 6 | #ffb8302e 7 | #505050 8 | #FFFFFF 9 | 10 | -------------------------------------------------------------------------------- /src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Hello Scala! 6 | 7 | -------------------------------------------------------------------------------- /src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 25 | 26 | -------------------------------------------------------------------------------- /src/main/scala/com/example/Hello.scala: -------------------------------------------------------------------------------- 1 | package com.example 2 | 3 | import android.os.Bundle 4 | import android.support.v7.app.AppCompatActivity 5 | import android.view.MenuItem 6 | 7 | class Hello extends AppCompatActivity { 8 | override def onCreate(savedInstanceState: Bundle): Unit = { 9 | super.onCreate(savedInstanceState) 10 | 11 | val view: TypedViewHolder.main = 12 | TypedViewHolder.setContentView(this, TR.layout.main) 13 | 14 | setSupportActionBar(view.toolbar) 15 | getSupportActionBar.setDisplayHomeAsUpEnabled(true) 16 | 17 | view.welcome.setText(R.string.name) 18 | } 19 | 20 | override def onOptionsItemSelected(item: MenuItem): Boolean = 21 | item.getItemId match { 22 | case android.R.id.home ⇒ 23 | finish() 24 | true 25 | case _ ⇒ super.onOptionsItemSelected(item) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/test/scala/com/example/test/Test.scala: -------------------------------------------------------------------------------- 1 | package com.example.test 2 | 3 | import android.os.Build.VERSION_CODES.LOLLIPOP 4 | import com.example.R 5 | import org.robolectric.RuntimeEnvironment 6 | import org.robolectric.annotation.Config 7 | import org.scalatest.{FlatSpec, Matchers, RobolectricSuite} 8 | 9 | @Config(sdk = Array(LOLLIPOP)) 10 | class Test extends FlatSpec with Matchers with RobolectricSuite { 11 | "Resources" should "be accessible via R" in { 12 | RuntimeEnvironment.application.getString(R.string.name) shouldBe "Hello Scala!" 13 | } 14 | } 15 | --------------------------------------------------------------------------------