Browse Source

nix: Wrap gradle, npm packages, `lein prod-build` and `gradle assembleRelease` in Nix expressions to improve reproducible builds with constant build paths

pull/8549/head
Pedro Pombeiro 2 months ago
parent
commit
a7fd659d84
No account linked to committer's email address
77 changed files with 37958 additions and 463 deletions
  1. 1
    0
      .gitignore
  2. 68
    35
      Makefile
  3. 4
    0
      android/app/build.gradle
  4. 1
    0
      android/app/jni/Application.mk
  5. 8
    1
      android/build.gradle
  6. 2
    0
      android/gradle.properties
  7. 7
    1
      android/gradlew
  8. 14
    10
      ci/Jenkinsfile.android
  9. 4
    1
      ci/Jenkinsfile.fastlane.clean
  10. 4
    5
      ci/Jenkinsfile.ios
  11. 2
    2
      ci/Jenkinsfile.linux
  12. 2
    2
      ci/Jenkinsfile.macos
  13. 37
    8
      ci/Jenkinsfile.nix-cache
  14. 2
    3
      ci/Jenkinsfile.windows
  15. 23
    8
      ci/android.groovy
  16. 15
    6
      ci/common.groovy
  17. 5
    5
      ci/ios.groovy
  18. 100
    9
      ci/nix.groovy
  19. 9
    1
      ci/utils.groovy
  20. 9
    8
      default.nix
  21. 0
    42
      derivation.nix
  22. 5
    5
      fastlane/Gemfile.lock
  23. 4
    2
      fastlane/default.nix
  24. 10
    10
      fastlane/gemset.nix
  25. 2
    1
      fastlane/update
  26. 31
    0
      nix/bootstrapped-shell.nix
  27. 73
    0
      nix/derivation.nix
  28. 1
    3
      nix/desktop/cmake/qtkeychain/default.nix
  29. 9
    8
      nix/desktop/cmake/snorenotify/default.nix
  30. 9
    9
      nix/desktop/default.nix
  31. 1
    2
      nix/desktop/macos/default.nix
  32. 1
    1
      nix/desktop/realm-node/default.nix
  33. 8
    1
      nix/desktop/realm-node/generate-nix.sh
  34. 2
    4
      nix/desktop/windows/default.nix
  35. 291
    0
      nix/lein/lein-project-deps-maven-inputs.txt
  36. 3555
    0
      nix/lein/lein-project-deps.nix
  37. 0
    44
      nix/mobile/android.nix
  38. 61
    0
      nix/mobile/android/android-env.nix
  39. 43
    0
      nix/mobile/android/default.nix
  40. 15
    0
      nix/mobile/android/gradle.nix
  41. 209
    0
      nix/mobile/android/maven-and-npm-deps/default.nix
  42. 10
    0
      nix/mobile/android/maven-and-npm-deps/maven/README.md
  43. 43
    0
      nix/mobile/android/maven-and-npm-deps/maven/default.nix
  44. 194
    0
      nix/mobile/android/maven-and-npm-deps/maven/fetch-maven-deps.sh
  45. 26
    0
      nix/mobile/android/maven-and-npm-deps/maven/generate-nix.sh
  46. 2445
    0
      nix/mobile/android/maven-and-npm-deps/maven/maven-inputs.txt
  47. 29480
    0
      nix/mobile/android/maven-and-npm-deps/maven/maven-sources.nix
  48. 52
    0
      nix/mobile/android/maven-and-npm-deps/maven/reactnative-android-native-deps.nix
  49. 20
    0
      nix/mobile/android/maven-and-npm-deps/maven/shell.nix
  50. 122
    0
      nix/mobile/android/targets/release-android.nix
  51. 29
    18
      nix/mobile/default.nix
  52. 26
    0
      nix/mobile/fastlane/default.nix
  53. 53
    0
      nix/mobile/ios/default.nix
  54. 30
    0
      nix/mobile/ios/install-pods-and-status-go.sh
  55. 0
    21
      nix/mobile/licensed-android-sdk.nix
  56. 44
    0
      nix/mobile/node-package.nix
  57. 71
    0
      nix/mobile/reset-node_modules.sh
  58. 3
    3
      nix/platform.nix
  59. 24
    8
      nix/shell.sh
  60. 1
    3
      nix/status-go/build-desktop-status-go.nix
  61. 7
    7
      nix/status-go/build-mobile-status-go.nix
  62. 40
    28
      nix/status-go/default.nix
  63. 20
    17
      nix/status-go/gomobile/default.nix
  64. 66
    0
      nix/targets/prod-build.nix
  65. 32
    0
      nix/tools/lein/fetch-maven-deps.sh
  66. 28
    0
      nix/tools/lein/generate-nix.sh
  67. 153
    0
      nix/tools/maven/maven-inputs2nix.sh
  68. 57
    0
      nix/tools/maven/maven-repo-builder.nix
  69. 40
    0
      nix/tools/mkFilter.nix
  70. 50
    0
      nix/tools/mkFilter_test.nix
  71. 4
    3
      project.clj
  72. 5
    1
      scripts/add-gcroots.sh
  73. 23
    0
      scripts/copy-translations.sh
  74. 36
    0
      scripts/prepare-for-desktop-platform.sh
  75. 0
    90
      scripts/prepare-for-platform.sh
  76. 67
    0
      scripts/release-android.sh
  77. 10
    27
      shell.nix

+ 1
- 0
.gitignore View File

@@ -41,6 +41,7 @@ project.xcworkspace
# node.js
#
node_modules/
node_modules.tmp/
npm-debug.log
yarn-error.log
default.realm/

+ 68
- 35
Makefile View File

@@ -1,4 +1,4 @@
.PHONY: add-gcroots clean clean-nix react-native-android react-native-ios react-native-desktop test release _list
.PHONY: add-gcroots clean clean-nix disable-githooks react-native-android react-native-ios react-native-desktop test release _list _fix-perms

help: ##@other Show this help
@perl -e '$(HELP_FUN)' $(MAKEFILE_LIST)
@@ -27,7 +27,7 @@ HELP_FUN = \
HOST_OS := $(shell uname | tr '[:upper:]' '[:lower:]')

# Defines which variables will be kept for Nix pure shell, use semicolon as divider
export NIX_KEEP ?= BUILD_ENV
export _NIX_KEEP ?= BUILD_ENV
export NIX_CONF_DIR = $(PWD)/nix

export REACT_SERVER_PORT ?= 5001 # any value different from default 5000 will work; this has to be specified for both the Node.JS server process and the Qt process
@@ -41,21 +41,18 @@ endif

# Main targets

_fix-perms: SHELL := /bin/sh
_fix-perms: ##@prepare Fix permissions so that directory can be cleaned
$(shell test -d node_modules && chmod -R 744 node_modules)
$(shell test -d node_modules.tmp && chmod -R 744 node_modules.tmp)

clean: SHELL := /bin/sh
clean: ##@prepare Remove all output folders
@test -d node_modules && chmod -R 744 node_modules; \
test -d node_modules.tmp && chmod -R 744 node_modules.tmp; \
clean: _fix-perms ##@prepare Remove all output folders
git clean -dxf -f

clean-nix: SHELL := /bin/sh
clean-nix: ##@prepare Remove complete nix setup
sudo rm -rf /nix ~/.nix-profile ~/.nix-defexpr ~/.nix-channels ~/.cache/nix ~/.status .nix-gcroots

watchman-clean: export _NIX_ATTR := targets.watchman.shell
watchman-clean:
watchman watch-del $(PWD)

add-gcroots: ##@prepare Add Nix GC roots to avoid status-react expressions being garbage collected
scripts/add-gcroots.sh
watchman watch-del $${STATUS_REACT_HOME}

shell: ##@prepare Enter into a pre-configured shell
ifndef IN_NIX_SHELL
@@ -64,58 +61,82 @@ else
@echo "Nix shell is already active"
endif

add-gcroots: SHELL := /bin/sh
add-gcroots: ##@nix Add Nix GC roots to avoid status-react expressions being garbage collected
scripts/add-gcroots.sh

clean-nix: SHELL := /bin/sh
clean-nix: ##@nix Remove complete nix setup
sudo rm -rf /nix ~/.nix-profile ~/.nix-defexpr ~/.nix-channels ~/.cache/nix ~/.status .nix-gcroots

update-npm-nix: SHELL := /bin/sh
update-npm-nix: ##@nix Update node2nix expressions based on current package.json
nix/desktop/realm-node/generate-nix.sh

update-gradle-nix: SHELL := /bin/sh
update-gradle-nix: ##@nix Update maven nix expressions based on current gradle setup
nix/mobile/android/maven-and-npm-deps/maven/generate-nix.sh

update-lein-nix: SHELL := /bin/sh
update-lein-nix: ##@nix Update maven nix expressions based on current lein setup
nix/tools/lein/generate-nix.sh nix/lein

disable-githooks: SHELL := /bin/sh
disable-githooks:
@rm -f ${env.WORKSPACE}/.git/hooks/pre-commit && \
sed -i'~' -e 's|\[rasom/lein-githooks|;; [rasom/lein-githooks|' \
-e 's|:githooks|;; :githooks|' \
-e 's|:pre-commit|;; :pre-commit|' project.clj; \
rm project.clj~

#----------------
# Release builds
#----------------
release: release-android release-ios ##@build build release for Android and iOS

release-android: SHELL := /bin/sh
release-android: export TARGET_OS ?= android
release-android: export BUILD_ENV ?= prod
release-android: ##@build build release for Android
@$(MAKE) prod-build-android && \
cp -R translations status-modules/translations && \
cp -R status-modules node_modules/status-modules && \
react-native run-android --variant=release
scripts/release-$(TARGET_OS).sh

release-ios: export TARGET_OS ?= ios
release-ios: export BUILD_ENV ?= prod
release-ios: ##@build build release for iOS release
release-ios: watchman-clean ##@build build release for iOS release
# Open XCode inside the Nix context
@$(MAKE) prod-build-ios && \
@git clean -dxf -f target/ios && \
$(MAKE) prod-build-ios && \
echo "Build in XCode, see https://status.im/build_status/ for instructions" && \
cp -R translations status-modules/translations && \
cp -R status-modules node_modules/status-modules && \
scripts/copy-translations.sh && \
open ios/StatusIm.xcworkspace

release-desktop: export TARGET_OS ?= $(HOST_OS)
release-desktop: ##@build build release for desktop release
@$(MAKE) prod-build-desktop && \
cp -R translations status-modules/translations && \
cp -R status-modules node_modules/status-modules && \
scripts/build-desktop.sh
scripts/copy-translations.sh && \
scripts/build-desktop.sh; \
$(MAKE) watchman-clean

release-windows-desktop: export TARGET_OS ?= windows
release-windows-desktop: ##@build build release for desktop release
@$(MAKE) prod-build-desktop && \
cp -R translations status-modules/translations && \
cp -R status-modules node_modules/status-modules && \
scripts/build-desktop.sh

prod-build: export TARGET_OS ?= all
prod-build:
scripts/prepare-for-platform.sh android && \
scripts/prepare-for-platform.sh ios && \
lein prod-build
scripts/copy-translations.sh && \
scripts/build-desktop.sh; \
$(MAKE) watchman-clean

prod-build-android: SHELL := /bin/sh
prod-build-android: export TARGET_OS ?= android
prod-build-android: export BUILD_ENV ?= prod
prod-build-android:
lein prod-build-android && \
node prepare-modules.js
# Call nix-build to build the 'targets.mobile.prod-build' attribute and copy the index.android.js file to the project root
@git clean -dxf -f ./index.$(TARGET_OS).js && \
_NIX_RESULT_PATH=$(shell . ~/.nix-profile/etc/profile.d/nix.sh && nix-build --argstr target-os $(TARGET_OS) --pure --no-out-link --show-trace -A targets.mobile.prod-build) && \
[ -n "$${_NIX_RESULT_PATH}" ] && cp -av $${_NIX_RESULT_PATH}/* .

prod-build-ios: export TARGET_OS ?= ios
prod-build-ios: export BUILD_ENV ?= prod
prod-build-ios:
@git clean -dxf -f ./index.$(TARGET_OS).js && \
lein prod-build-ios && \
node prepare-modules.js

@@ -165,6 +186,7 @@ _run-%:
$(eval SYSTEM := $(word 2, $(subst -, , $@)))
npx react-native run-$(SYSTEM)

# TODO: Migrate this to a Nix recipe, much the same way as nix/mobile/android/targets/release-android.nix
run-android: export TARGET_OS ?= android
run-android: ##@run Run Android build
npx react-native run-android --appIdSuffix debug
@@ -185,9 +207,11 @@ endif
# Tests
#--------------

test: export _NIX_ATTR := targets.leiningen.shell
test: ##@test Run tests once in NodeJS
lein with-profile test doo node test once

test-auto: export _NIX_ATTR := targets.leiningen.shell
test-auto: ##@test Run tests in interactive (auto) mode in NodeJS
lein with-profile test doo node test

@@ -209,11 +233,13 @@ react-native-ios: export TARGET_OS ?= ios
react-native-ios: ##@other Start react native packager for Android client
@scripts/start-react-native.sh

geth-connect: export _NIX_ATTR := targets.mobile.android.adb.shell
geth-connect: export TARGET_OS ?= android
geth-connect: ##@other Connect to Geth on the device
adb forward tcp:8545 tcp:8545 && \
build/bin/geth attach http://localhost:8545

android-ports: export _NIX_ATTR := targets.mobile.android.adb.shell
android-ports: export TARGET_OS ?= android
android-ports: ##@other Add proxies to Android Device/Simulator
adb reverse tcp:8081 tcp:8081 && \
@@ -221,10 +247,17 @@ android-ports: ##@other Add proxies to Android Device/Simulator
adb reverse tcp:4567 tcp:4567 && \
adb forward tcp:5561 tcp:5561

android-logcat: export _NIX_ATTR := targets.mobile.android.adb.shell
android-logcat: export TARGET_OS ?= android
android-logcat:
adb logcat | grep -e StatusModule -e ReactNativeJS -e StatusNativeLogs

android-install: export _NIX_ATTR := targets.mobile.android.adb.shell
android-install: export TARGET_OS ?= android
android-install: export BUILD_TYPE ?= release
android-install:
adb install android/app/build/outputs/apk/$(BUILD_TYPE)/app-$(BUILD_TYPE).apk

_list: SHELL := /bin/sh
_list:
@$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$'

+ 4
- 0
android/app/build.gradle View File

@@ -107,6 +107,10 @@ def enableProguardInReleaseBuilds = false

def getVersionCode = { ->
new ByteArrayOutputStream().withStream { stdOut ->
if (project.hasProperty("versionCode")) {
return project.versionCode.toString().toInteger()
}

exec {
commandLine "bash", "../../scripts/build_no.sh"
standardOutput = stdOut

+ 1
- 0
android/app/jni/Application.mk View File

@@ -1,4 +1,5 @@
APP_ABI := armeabi-v7a arm64-v8a x86 x86_64
APP_LDFLAGS := -Wl,--build-id=none
APP_PLATFORM := android-18
APP_STL := c++_static
NDK_TOOLCHAIN_VERSION=clang

+ 8
- 1
android/build.gradle View File

@@ -7,6 +7,7 @@ buildscript {
compileSdkVersion = 28
targetSdkVersion = 28
supportLibVersion = "28.0.0"
gradleBuildTools = 'com.android.tools.build:gradle:3.4.1'
}
repositories {
flatDir { dirs "libs", "${rootDir}/app/libs" }
@@ -14,7 +15,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.2'
classpath 'com.android.tools.build:gradle:3.4.1'
// google-services downgraded from 4.1.0 because of
// https://github.com/invertase/react-native-firebase/issues/766#issuecomment-365116012
classpath 'com.google.gms:google-services:4.0.1'
@@ -41,6 +42,12 @@ subprojects {
}

allprojects {
beforeEvaluate {
if (System.env.STATUS_GO_ANDROID_LIBDIR == null || System.env.STATUS_GO_ANDROID_LIBDIR == "") {
throw new GradleException('STATUS_GO_ANDROID_LIBDIR environment variable is not valid!')
}
}

repositories {
mavenLocal()
google()

+ 2
- 0
android/gradle.properties View File

@@ -28,3 +28,5 @@ STATUS_RELEASE_KEY_PASSWORD=password
NDK_ABI_FILTERS=armeabi-v7a;arm64-v8a;x86

org.gradle.jvmargs=-Xmx8704M

versionCode=9999

+ 7
- 1
android/gradlew View File

@@ -16,4 +16,10 @@ if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi

exec gradle "$@"
# Map mavenLocal() to the Nix maven repo we set up in nix/mobile/android/maven-and-npm-deps/default.nix
if [ -n "$STATUSREACT_NIX_MAVEN_REPO" ]; then
repoOpts="-Dmaven.repo.local=${STATUSREACT_NIX_MAVEN_REPO}"
else
repoOpts=''
fi
exec gradle $repoOpts "$@"

+ 14
- 10
ci/Jenkinsfile.android View File

@@ -32,9 +32,7 @@ pipeline {
/* since we are mounting it we need to specify location */
STATUS_RELEASE_STORE_FILE = '/home/jenkins/status-im.keystore'
/* We use EXECUTOR_NUMBER to avoid multiple instances clashing */
LEIN_HOME = "/var/tmp/lein-${EXECUTOR_NUMBER}"
YARN_CACHE_FOLDER = "/var/tmp/yarn-${EXECUTOR_NUMBER}"
GRADLE_USER_HOME = "/var/tmp/gradle-${EXECUTOR_NUMBER}"
LEIN_HOME = "/var/tmp/lein-${EXECUTOR_NUMBER}"
/* coverage report identification */
COVERALLS_SERVICE_NAME = "jenkins"
COVERALLS_SERVICE_JOB_ID = "${JOB_NAME}#${BUILD_NUMBER}"
@@ -55,17 +53,25 @@ pipeline {
}
}
}
stage('Implicit dependencies') {
steps {
/* Build implicit dependencies if needed (we run `lein deps :tree` but it's not really required, for this purpose)
Implicit dependencies include building a patched node_modules, fetching maven dependencies, and anything else required.
We do this before the parallel steps so we have a known starting situation. */
script { cmn.nix.shell('lein deps :tree', attr: 'targets.leiningen.shell') }
}
}
stage('Parallel') {
parallel {
stage('Checks') { stages {
stage('Lint') {
steps {
script { cmn.nix.shell('lein cljfmt check') }
script { cmn.nix.shell('lein cljfmt check', attr: 'targets.leiningen.shell') }
}
}
stage('Tests') {
steps {
script { cmn.nix.shell('lein test-cljs') }
script { cmn.nix.shell('lein test-cljs', attr: 'targets.leiningen.shell') }
}
}
stage('Coverage') {
@@ -77,7 +83,7 @@ pipeline {
stage('Build') { stages {
stage('Clojure') {
steps {
script { cmn.nix.shell('make prod-build-android')}
script { cmn.nix.build(attr: "targets.mobile.prod-build") }
}
}
stage('Bundle') {
@@ -110,14 +116,12 @@ pipeline {
}
}
stage('Cleanup') {
steps {
sh 'make watchman-clean'
sh 'make clean'
}
steps { sh 'make clean' }
}
}
post {
success { script { load('ci/github.groovy').notifyPR(true) } }
failure { script { load('ci/github.groovy').notifyPR(false) } }
always { sh 'make _fix-perms' }
}
}

+ 4
- 1
ci/Jenkinsfile.fastlane.clean View File

@@ -23,7 +23,9 @@ pipeline {
stage('Prep') {
steps { script {
nix = load('ci/nix.groovy')
nix.shell('bundle install --gemfile=fastlane/Gemfile')
nix.shell(
'bundle install --gemfile=fastlane/Gemfile',
attr: 'targets.mobile.fastlane.shell')
} }
}
stage('Clean Users'){
@@ -37,6 +39,7 @@ pipeline {
]) {
nix.shell(
'bundle exec --gemfile=fastlane/Gemfile fastlane ios clean',
attr: 'targets.mobile.fastlane.shell',
keep: ['FASTLANE_APPLE_ID', 'FASTLANE_PASSWORD']
)
}

+ 4
- 5
ci/Jenkinsfile.ios View File

@@ -31,9 +31,7 @@ pipeline {
REALM_DISABLE_ANALYTICS = 1
BUNDLE_PATH = "${HOME}/.bundle"
/* We use EXECUTOR_NUMBER to avoid multiple instances clashing */
LEIN_HOME = "/var/tmp/lein-${EXECUTOR_NUMBER}"
YARN_CACHE_FOLDER = "/var/tmp/yarn-${EXECUTOR_NUMBER}"
GRADLE_USER_HOME = "/var/tmp/gradle-${EXECUTOR_NUMBER}"
LEIN_HOME = "/var/tmp/lein-${EXECUTOR_NUMBER}"
}

stages {
@@ -56,12 +54,12 @@ pipeline {
stage('Checks') { stages {
stage('Lint') {
steps {
script { cmn.nix.shell('lein cljfmt check') }
script { cmn.nix.shell('lein cljfmt check', attr: 'targets.leiningen.shell') }
}
}
stage('Tests') {
steps {
script { cmn.nix.shell('lein test-cljs') }
script { cmn.nix.shell('lein test-cljs', attr: 'targets.leiningen.shell') }
}
}
} }
@@ -107,5 +105,6 @@ pipeline {
post {
success { script { load('ci/github.groovy').notifyPR(true) } }
failure { script { load('ci/github.groovy').notifyPR(false) } }
always { sh 'make _fix-perms' }
}
}

+ 2
- 2
ci/Jenkinsfile.linux View File

@@ -58,12 +58,12 @@ pipeline {
stage('Checks') { stages {
stage('Lint') {
steps {
script { cmn.nix.shell('lein cljfmt check') }
script { cmn.nix.shell('lein cljfmt check', attr: 'targets.leiningen.shell') }
}
}
stage('Tests') {
steps {
script { cmn.nix.shell('lein test-cljs') }
script { cmn.nix.shell('lein test-cljs', attr: 'targets.leiningen.shell') }
}
}
} }

+ 2
- 2
ci/Jenkinsfile.macos View File

@@ -54,12 +54,12 @@ pipeline {
stage('Checks') { stages {
stage('Lint') {
steps {
script { cmn.nix.shell('lein cljfmt check') }
script { cmn.nix.shell('lein cljfmt check', attr: 'targets.leiningen.shell') }
}
}
stage('Tests') {
steps {
script { cmn.nix.shell('lein test-cljs') }
script { cmn.nix.shell('lein test-cljs', attr: 'targets.leiningen.shell') }
}
}
} }

+ 37
- 8
ci/Jenkinsfile.nix-cache View File

@@ -26,19 +26,35 @@ pipeline {
stage('Setup') {
steps {
sh 'scripts/setup'
sh """
sh '''
. ~/.nix-profile/etc/profile.d/nix.sh && \
nix-env -i openssh
"""
'''
}
}
stage('Build') {
stage('Build prod-build-android') {
steps {
sh """
// Run a Nix build to build/fetch everything that is necessary to produce a prod-build for TARGET_OS=android (e.g. maven and node repos)
sh '''
args="--argstr target-os android --show-trace -A targets.mobile.prod-build"

. ~/.nix-profile/etc/profile.d/nix.sh && \
nix build -v --no-link && \
nix-shell --pure --run echo
"""
nix-build --pure --no-out-link $args

prodBuildDrv=$(nix-instantiate --quiet $args) && \
prodBuildSrcPath=$(nix-store -q --binding src $prodBuildDrv) && \
prodBuildOutPath=$(nix-store -q --outputs $prodBuildDrv) && \
nix-store --delete $prodBuildDrv $prodBuildSrcPath $prodBuildOutPath
'''
}
}
stage('Build nix shell deps') {
steps {
// Run a Nix build to build/fetch everything that is necessary to instantiate shell.nix for TARGET_OS=all
sh '''
. ~/.nix-profile/etc/profile.d/nix.sh && \
nix-build --pure --no-out-link --show-trace -A shell default.nix
'''
}
}
stage('Upload') {
@@ -46,11 +62,24 @@ pipeline {
sshagent(credentials: ['nix-cache-ssh']) {
sh """
. ~/.nix-profile/etc/profile.d/nix.sh && \
find /nix/store/ -mindepth 1 -maxdepth 1 -not -name '.links' -and -not -name '*.lock' | \
find /nix/store/ -mindepth 1 -maxdepth 1 \
-not -name '.links' -and -not -name '*.lock' \
-and -not -name '*-status-react-prod-build-source' \
-and -not -name '*-status-react-release-android-source' \
-and -not -name '*-prod-build-*' \
-and -not -name '*-release-android' | \
xargs nix-copy-closure -v --to ${NIX_CACHE_USER}@${NIX_CACHE_HOST}
"""
}
}
}
}
post {
always {
sh '''
. ~/.nix-profile/etc/profile.d/nix.sh && \
nix-store --optimize
'''
}
}
}

+ 2
- 3
ci/Jenkinsfile.windows View File

@@ -39,7 +39,6 @@ pipeline {
/* We use EXECUTOR_NUMBER to avoid multiple instances clashing */
LEIN_HOME = "/var/tmp/lein-${EXECUTOR_NUMBER}"
YARN_CACHE_FOLDER = "/var/tmp/yarn-${EXECUTOR_NUMBER}"
GRADLE_USER_HOME = "/var/tmp/gradle-${EXECUTOR_NUMBER}"
}

stages {
@@ -62,12 +61,12 @@ pipeline {
stage('Checks') { stages {
stage('Lint') {
steps {
script { cmn.nix.shell('lein cljfmt check') }
script { cmn.nix.shell('lein cljfmt check', attr: 'targets.leiningen.shell') }
}
}
stage('Tests') {
steps {
script { cmn.nix.shell('lein test-cljs') }
script { cmn.nix.shell('lein test-cljs', attr: 'targets.leiningen.shell') }
}
}
} }

+ 23
- 8
ci/android.groovy View File

@@ -4,7 +4,7 @@ utils = load 'ci/utils.groovy'
def bundle() {
def btype = utils.getBuildType()
/* Disable Gradle Daemon https://stackoverflow.com/questions/38710327/jenkins-builds-fail-using-the-gradle-daemon */
def gradleOpt = "-PbuildUrl='${currentBuild.absoluteUrl}' -Dorg.gradle.daemon=false "
def gradleOpt = "-PbuildUrl='${currentBuild.absoluteUrl}' --console plain "
def target = "release"
/* we don't need x86 for any builds except e2e */
env.NDK_ABI_FILTERS="armeabi-v7a;arm64-v8a"
@@ -19,6 +19,7 @@ def bundle() {
gradleOpt += "-PreleaseVersion='${utils.getVersion()}'"
}

// The Nix script cannot access the user home directory, so best to copy the file to the Nix store and pass that to the Nix script
dir('android') {
withCredentials([
string(
@@ -31,18 +32,29 @@ def bundle() {
passwordVariable: 'STATUS_RELEASE_KEY_PASSWORD'
)
]) {
nix.shell(
"./gradlew assemble${target.capitalize()} ${gradleOpt}",
nix.build(
args: [
'gradle-opts': gradleOpt,
'build-number': utils.readBuildNumber(),
'build-type': btype
],
safeEnv: [
'STATUS_RELEASE_KEY_ALIAS',
'STATUS_RELEASE_STORE_PASSWORD',
'STATUS_RELEASE_KEY_PASSWORD'
],
keep: [
'REALM_DISABLE_ANALYTICS', 'NDK_ABI_FILTERS',
'STATUS_RELEASE_STORE_FILE', 'STATUS_RELEASE_STORE_PASSWORD',
'STATUS_RELEASE_KEY_ALIAS', 'STATUS_RELEASE_KEY_PASSWORD'
]
'STATUS_RELEASE_STORE_FILE'
],
sbox: [
env.STATUS_RELEASE_STORE_FILE
],
attr: "targets.mobile.android.release"
)
}
}
sh 'find android/app/build/outputs/apk'
def outApk = "android/app/build/outputs/apk/${target}/app-${target}.apk"
def outApk = "android/result/app.apk"
def pkg = utils.pkgFilename(btype, 'apk')
/* rename for upload */
sh "cp ${outApk} ${pkg}"
@@ -57,6 +69,7 @@ def uploadToPlayStore(type = 'nightly') {
]) {
nix.shell(
"fastlane android ${type}",
attr: 'targets.mobile.fastlane.shell',
keep: ['FASTLANE_DISABLE_COLORS', 'GOOGLE_PLAY_JSON_KEY']
)
}
@@ -79,6 +92,7 @@ def uploadToSauceLabs() {
]) {
nix.shell(
'fastlane android saucelabs',
attr: 'targets.mobile.fastlane.shell',
keep: [
'FASTLANE_DISABLE_COLORS', 'APK_PATH',
'SAUCE_ACCESS_KEY', 'SAUCE_USERNAME', 'SAUCE_LABS_NAME'
@@ -94,6 +108,7 @@ def uploadToDiawi() {
]) {
nix.shell(
'fastlane android upload_diawi',
attr: 'targets.mobile.fastlane.shell',
keep: ['FASTLANE_DISABLE_COLORS', 'APK_PATH', 'DIAWI_TOKEN']
)
}

+ 15
- 6
ci/common.groovy View File

@@ -36,6 +36,10 @@ def prep(type = 'nightly') {
utils.doGitRebase()
/* ensure that we start from a known state */
sh 'make clean'
/* Disable git hooks in CI, it's not useful, takes time and creates weird errors at times
(e.g. bin/sh: 2: /etc/ssl/certs/ca-certificates.crt: Permission denied) */
sh 'make disable-githooks'

/* pick right .env and update from params */
utils.updateEnv(type)

@@ -44,18 +48,23 @@ def prep(type = 'nightly') {
utils.genBuildNumber()
}

nix.shell('watchman watch-del-all', attr: 'targets.watchman.shell')

if (env.TARGET_OS == 'ios') {
/* install ruby dependencies */
nix.shell 'bundle install --gemfile=fastlane/Gemfile --quiet'
nix.shell(
'bundle install --gemfile=fastlane/Gemfile --quiet',
attr: 'targets.mobile.fastlane.shell')
}

def prepareTarget=env.TARGET_OS
if (env.TARGET_OS == 'macos' || env.TARGET_OS == 'linux' || env.TARGET_OS == 'windows') {
prepareTarget='desktop'
/* node deps, pods, and status-go download */
utils.nix.shell('scripts/prepare-for-desktop-platform.sh', pure: false)
sh('scripts/copy-translations.sh')
} else if (env.TARGET_OS != 'android') {
// run script in the nix shell so that node_modules gets instantiated before attempting the copies
utils.nix.shell('scripts/copy-translations.sh chmod')
}
/* node deps, pods, and status-go download */
utils.nix.shell("scripts/prepare-for-platform.sh ${prepareTarget}", pure: false)
sh("cp -R translations status-modules/translations && cp -R status-modules node_modules/status-modules")
}

return this

+ 5
- 5
ci/ios.groovy View File

@@ -17,11 +17,9 @@ def bundle() {
default: target = 'nightly';
}
/* configure build metadata */
nix.shell(
plutil('CFBundleShortVersionString', utils.getVersion()) +
plutil('CFBundleVersion', utils.genBuildNumber()) +
plutil('CFBundleBuildUrl', currentBuild.absoluteUrl)
)
nix.shell(plutil('CFBundleShortVersionString', utils.getVersion()), attr: 'targets.mobile.ios.shell')
nix.shell(plutil('CFBundleVersion', utils.genBuildNumber()), attr: 'targets.mobile.ios.shell')
nix.shell(plutil('CFBundleBuildUrl', currentBuild.absoluteUrl), attr: 'targets.mobile.ios.shell')
/* the dir might not exist */
sh 'mkdir -p status-e2e'
/* build the actual app */
@@ -66,6 +64,7 @@ def uploadToDiawi() {
]) {
nix.shell(
'bundle exec --gemfile=fastlane/Gemfile fastlane ios upload_diawi',
attr: 'targets.mobile.fastlane.shell',
keep: ['FASTLANE_DISABLE_COLORS', 'DIAWI_TOKEN']
)
}
@@ -89,6 +88,7 @@ def uploadToSauceLabs() {
]) {
nix.shell(
'bundle exec --gemfile=fastlane/Gemfile fastlane ios saucelabs',
attr: 'targets.mobile.fastlane.shell',
keep: ['FASTLANE_DISABLE_COLORS', 'SAUCE_ACCESS_KEY', 'SAUCE_USERNAME']
)
}

+ 100
- 9
ci/nix.groovy View File

@@ -15,23 +15,114 @@ def shell(Map opts = [:], String cmd) {
/* Previous merge overwrites the array */
opts.keep = (opts.keep + defaults.keep).unique()

def isPure = opts.pure && env.TARGET_OS != 'windows' && env.TARGET_OS != 'ios'
def keepFlags = opts.keep.collect { var -> "--keep ${var} " }
def argsFlags = opts.args.collect { key,val -> "--argstr ${key} \'${val}\'" }
if (env.TARGET_OS in ['windows', 'ios']) {
opts.pure = false
}
sh """
set +x
. ~/.nix-profile/etc/profile.d/nix.sh
set -x
IN_CI_ENVIRONMENT=1 \\
nix-shell \\
${isPure ? "--pure" : ""} \\
${keepFlags.join(" ")} \\
${argsFlags.join(" ")} \\
--run \'${cmd}\' \\
\'${env.WORKSPACE}/shell.nix\'
nix-shell --run \'${cmd}\' ${_getNixCommandArgs(opts, true)}
"""
}

/**
* Arguments:
* - pure - Use --pure mode with Nix for more deterministic behaviour
* - keep - List of env variables to pass through to Nix build
* - args - Map of arguments to provide to --argstr
* - attr - Name of attribute to use with --attr flag
* - safeEnv - Name of env variables to pass securely through to Nix build (they won't get captured in Nix derivation file)
* - sbox - List of host file paths to pass to the Nix expression
**/
def build(Map opts = [:]) {
env.IN_CI_ENVIRONMENT = '1'

def defaults = [
pure: true,
args: ['target-os': env.TARGET_OS],
keep: ['IN_CI_ENVIRONMENT'],
safeEnv: [],
attr: null,
sbox: []
]
/* merge defaults with received opts */
opts = defaults + opts
/* Previous merge overwrites the array */
opts.args = defaults.args + opts.args
opts.keep = (opts.keep + defaults.keep).unique()

return sh(
returnStdout: true,
script: """
set +x
. ~/.nix-profile/etc/profile.d/nix.sh
set -x
nix-build ${_getNixCommandArgs(opts, false)}
"""
).trim()
}

private makeNixBuildEnvFile(Map opts = [:]) {
File envFile = File.createTempFile("nix-env", ".tmp")
if (!opts.safeEnv.isEmpty()) {
// Export the environment variables we want to keep into a temporary script we can pass to Nix and source it from the build script
def exportCommandList = opts.safeEnv.collect { envVarName -> """
echo \"export ${envVarName}=\\\"\$(printenv ${envVarName})\\\"\" >> ${envFile.absolutePath}
""" }
def exportCommands = exportCommandList.join("")
sh """
${exportCommands}
chmod u+x ${envFile.absolutePath}
"""

opts.args = opts.args + [ 'secrets-file': envFile.absolutePath ]
opts.sbox = opts.sbox + envFile.absolutePath
}

return envFile
}

private def _getNixCommandArgs(Map opts = [:], boolean isShell) {
def keepFlags = []
def entryPoint = "\'${env.WORKSPACE}/shell.nix\'"
if (!isShell || opts.attr != null) {
entryPoint = "\'${env.WORKSPACE}/default.nix\'"
}
def extraSandboxPathsFlag = ''

if (isShell) {
keepFlags = opts.keep.collect { var -> "--keep ${var} " }
} else {
def envVarsList = opts.keep.collect { var -> "${var}=\"${env[var]}\";" }
keepFlags = ["--arg env \'{${envVarsList.join("")}}\'"]

/* Export the environment variables we want to keep into
* a Nix attribute set we can pass to Nix and source it from the build script */
def envFile = makeNixBuildEnvFile(opts)
envFile.deleteOnExit()
}

def argsFlags = opts.args.collect { key,val -> "--argstr ${key} \'${val}\'" }
def attrFlag = ''
if (opts.attr != null) {
attrFlag = "--attr '${opts.attr}'"
}
if (opts.sbox != null && !opts.sbox.isEmpty()) {
extraSandboxPathsFlag = "--option extra-sandbox-paths \"${opts.sbox.join(' ')}\""
}

return [
opts.pure ? "--pure" : "",
keepFlags.join(" "),
argsFlags.join(" "),
extraSandboxPathsFlag,
attrFlag,
entryPoint,
].join(" ")
}

def prepEnv() {
if (env.TARGET_OS in ['linux', 'windows', 'android']) {
def glibcLocales = sh(

+ 9
- 1
ci/utils.groovy View File

@@ -57,12 +57,20 @@ def doGitRebase() {
def genBuildNumber() {
def number = sh(
returnStdout: true,
script: "./scripts/gen_build_no.sh"
script: "${env.WORKSPACE}/scripts/gen_build_no.sh"
).trim()
println "Build Number: ${number}"
return number
}

def readBuildNumber() {
def number = sh(
returnStdout: true,
script: "${env.WORKSPACE}/scripts/build_no.sh"
).trim().toInteger()
return number
}

def getDirPath(path) {
return path.tokenize('/')[0..-2].join('/')
}

+ 9
- 8
default.nix View File

@@ -5,11 +5,12 @@
stdenv ? pkgs.stdenv,
target-os ? "all" }:

(pkgs.callPackage ./derivation.nix { inherit pkgs target-os; inherit (nixpkgs-bootstrap) config; }).overrideAttrs(_: {
src = null;
# TODO: Figure out if there's a better way to do this
# NOTE: There's a weird difference in behavior between Linux and macOS: in Linux the packages will only be fetched by `nix build` if unpackPhase exists. In macOS it's the other way around :-/
phases = with stdenv; lib.optional isLinux [ "unpackPhase" ] ++ [ "noPhase" ];
unpackPhase = "true";
noPhase = "mkdir -p $out";
})
let deriv = pkgs.callPackage ./nix/derivation.nix { inherit pkgs target-os; inherit (nixpkgs-bootstrap) config; };

in {
targets = {
inherit (deriv) mobile leiningen watchman;
};

inherit (deriv) shell;
}

+ 0
- 42
derivation.nix View File

@@ -1,42 +0,0 @@
{ system ? builtins.currentSystem
, config ? { android_sdk.accept_license = true; }, overlays ? []
, pkgs ? (import <nixpkgs> { inherit system config overlays; })
, target-os }:

let
platform = pkgs.callPackage ./nix/platform.nix { inherit target-os; };
# TODO: Try to use stdenv for iOS. The problem is with building iOS as the build is trying to pass parameters to Apple's ld that are meant for GNU's ld (e.g. -dynamiclib)
stdenv = pkgs.stdenvNoCC;
gradle = pkgs.gradle_4_10;
baseGo = pkgs.go_1_11;
go = pkgs.callPackage ./nix/patched-go { inherit baseGo; };
buildGoPackage = pkgs.buildGoPackage.override { inherit go; };
statusDesktop = pkgs.callPackage ./nix/desktop { inherit target-os stdenv status-go pkgs nodejs; inherit (pkgs) darwin; go = baseGo; };
statusMobile = pkgs.callPackage ./nix/mobile { inherit target-os config stdenv pkgs nodejs status-go gradle; inherit (pkgs.xcodeenv) composeXcodeWrapper; };
status-go = pkgs.callPackage ./nix/status-go { inherit target-os go buildGoPackage; inherit (pkgs.xcodeenv) composeXcodeWrapper; inherit (statusMobile) xcodewrapperArgs; androidPkgs = statusMobile.androidComposition; };
nodejs = pkgs.nodejs-10_x;
yarn = pkgs.yarn.override { inherit nodejs; };
nodePkgBuildInputs = [
nodejs
pkgs.python27 # for e.g. gyp
yarn
];
selectedSources =
stdenv.lib.optional platform.targetDesktop statusDesktop ++
stdenv.lib.optional platform.targetMobile statusMobile;

in with stdenv; mkDerivation rec {
name = "status-react-build-env";

buildInputs = with pkgs; [
clojure
leiningen
maven
watchman
] ++ nodePkgBuildInputs
++ lib.optional isDarwin cocoapods
++ lib.optional (isDarwin && !platform.targetIOS) clang
++ lib.optional (!isDarwin) gcc8
++ lib.catAttrs "buildInputs" selectedSources;
shellHook = lib.concatStrings (lib.catAttrs "shellHook" selectedSources);
}

+ 5
- 5
fastlane/Gemfile.lock View File

@@ -14,9 +14,9 @@ GEM
declarative (0.0.10)
declarative-option (0.1.0)
digest-crc (0.4.1)
domain_name (0.5.20180417)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
dotenv (2.7.2)
dotenv (2.7.4)
emoji_regex (1.0.1)
excon (0.64.0)
faraday (0.15.4)
@@ -27,7 +27,7 @@ GEM
faraday_middleware (0.13.1)
faraday (>= 0.7.4, < 1.0)
fastimage (2.1.5)
fastlane (2.125.2)
fastlane (2.127.1)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.3, < 3.0.0)
babosa (>= 1.0.2, < 2.0.0)
@@ -78,7 +78,7 @@ GEM
signet (~> 0.9)
google-cloud-core (1.3.0)
google-cloud-env (~> 1.0)
google-cloud-env (1.1.0)
google-cloud-env (1.2.0)
faraday (~> 0.11)
google-cloud-storage (1.16.0)
digest-crc (~> 0.4)
@@ -146,7 +146,7 @@ GEM
unf_ext (0.0.7.6)
unicode-display_width (1.6.0)
word_wrap (1.0.0)
xcodeproj (1.10.0)
xcodeproj (1.11.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)

+ 4
- 2
fastlane/default.nix View File

@@ -19,7 +19,7 @@ let
installPhase = ''
mkdir -p $out/bin
makeWrapper ${env}/bin/fastlane $out/bin/fastlane \
--set FASTLANE_SKIP_UPDATE_CHECK 1
--set FASTLANE_SKIP_UPDATE_CHECK 1
'';

meta = with stdenv.lib; {
@@ -35,7 +35,9 @@ let

in fastlane // {
shellHook = ''
export FASTLANE_PLUGINFILE_PATH=$PWD/fastlane/Pluginfile
[ -z "$STATUS_REACT_HOME" ] && echo "STATUS_REACT_HOME is empty!" && exit 1

export FASTLANE_PLUGINFILE_PATH=$STATUS_REACT_HOME/fastlane/Pluginfile
'';
}


+ 10
- 10
fastlane/gemset.nix View File

@@ -117,20 +117,20 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0abdlwb64ns7ssmiqhdwgl27ly40x2l27l8hs8hn0z4kb3zd2x3v";
sha256 = "0lcqjsmixjp52bnlgzh4lg9ppsk52x9hpwdjd53k8jnbah2602h0";
type = "gem";
};
version = "0.5.20180417";
version = "0.5.20190701";
};
dotenv = {
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "13cis6bf06hmz744xrsl163p6gb78xcm8g8q4pcabsy5ywyv6kag";
sha256 = "1375dyawvcp81d94jkjwjjkj3j23gsp06cfwh15g695l4g3ssswc";
type = "gem";
};
version = "2.7.2";
version = "2.7.4";
};
emoji_regex = {
groups = ["default"];
@@ -201,10 +201,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1k828cyp287asy9ahii51aifcxnia049v2cs60650ngym9x5fr0w";
sha256 = "1dw06kbsnfg6mqzxvkmb4bswgzng0kc1nbfpvv0r7sq99wsscrz9";
type = "gem";
};
version = "2.125.2";
version = "2.127.1";
};
fastlane-plugin-clean_testflight_testers = {
groups = ["default"];
@@ -265,10 +265,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "09g0dwzhz4f74x5dq6dp1fm7sc7d0g0ry4533yih360isjrl4mcy";
sha256 = "0j25sy2qhybqfwsyh8j4m10z2x7dn2jmf1gwr1w2b90cmya4yrbd";
type = "gem";
};
version = "1.1.0";
version = "1.2.0";
};
google-cloud-storage = {
dependencies = ["digest-crc" "google-api-client" "google-cloud-core" "googleauth"];
@@ -677,10 +677,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1x2ypkxyfsr6k8qy75iy64p6af6b024fqnlmw8qvzzzixmwrr8q7";
sha256 = "1h73ilwyjwyyhj761an3pmicllw50514gxb6b1r4z4klc9rzxw4j";
type = "gem";
};
version = "1.10.0";
version = "1.11.0";
};
xcpretty = {
dependencies = ["rouge"];

+ 2
- 1
fastlane/update View File

@@ -3,13 +3,14 @@
set -x
set -e

SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)

rm -f "${GIT_ROOT}/fastlane/Gemfile.lock"

bundler install \
--gemfile="${GIT_ROOT}/fastlane/Gemfile" \
--path "${GIT_ROOT}/.bundle/vendor"
--path "${GIT_ROOT}/fastlane/.bundle/vendor"
bundix \
--gemfile="${GIT_ROOT}/fastlane/Gemfile" \
--lockfile="${GIT_ROOT}/fastlane/Gemfile.lock" \

+ 31
- 0
nix/bootstrapped-shell.nix View File

@@ -0,0 +1,31 @@
#
# This Nix expression appends/modifies an existing attribute set in order to run scripts/setup if needed,
# as well as define STATUS_REACT_HOME
#

{ stdenv, mkShell, git }:

let
shell' = shellAttr:
shellAttr // {
nativeBuildInputs = (shellAttr.nativeBuildInputs or []) ++ [ git ];
shellHook = ''
set -e

export STATUS_REACT_HOME=$(git rev-parse --show-toplevel)

${shellAttr.shellHook or ""}

if [ "$IN_NIX_SHELL" != 'pure' ] && [ ! -f $STATUS_REACT_HOME/.ran-setup ]; then
$STATUS_REACT_HOME/scripts/setup
touch $STATUS_REACT_HOME/.ran-setup
fi

set +e
'';
};
# Declare a specialized mkShell function which adds some bootstrapping
# so that e.g. STATUS_REACT_HOME is automatically available in the shell
mkShell' = shellAttr: (mkShell.override { inherit stdenv; }) (shell' shellAttr);

in mkShell'

+ 73
- 0
nix/derivation.nix View File

@@ -0,0 +1,73 @@
{ system ? builtins.currentSystem
, config ? { android_sdk.accept_license = true; }, overlays ? []
, pkgs ? (import <nixpkgs> { inherit system config overlays; })
, target-os }:

let
inherit (stdenv) isDarwin;
inherit (stdenv.lib) catAttrs concatStrings optional unique;

platform = pkgs.callPackage ./platform.nix { inherit target-os; };
# Declare a specialized mkShell function which adds some bootstrapping
# so that e.g. STATUS_REACT_HOME is automatically available in the shell
mkShell = (import ./bootstrapped-shell.nix { inherit stdenv; inherit (pkgs) mkShell git; });
# TODO: Try to use stdenv for iOS. The problem is with building iOS as the build is trying to pass parameters to Apple's ld that are meant for GNU's ld (e.g. -dynamiclib)
stdenv = pkgs.stdenvNoCC;
maven = pkgs.maven;
baseGo = pkgs.go_1_11;
go = pkgs.callPackage ./patched-go { inherit baseGo; };
buildGoPackage = pkgs.buildGoPackage.override { inherit go; };
desktop = pkgs.callPackage ./desktop { inherit target-os stdenv status-go pkgs nodejs; inherit (pkgs) darwin; go = baseGo; };
mobile = pkgs.callPackage ./mobile { inherit target-os config stdenv pkgs mkShell nodejs yarn status-go maven localMavenRepoBuilder mkFilter prod-build-fn; inherit (pkgs.xcodeenv) composeXcodeWrapper; };
status-go = pkgs.callPackage ./status-go { inherit target-os go buildGoPackage; inherit (mobile.ios) xcodeWrapper; androidPkgs = mobile.android.androidComposition; };
# mkFilter is a function that allows filtering a directory structure (used for filtering source files being captured in a closure)
mkFilter = import ./tools/mkFilter.nix { inherit (stdenv) lib; };
localMavenRepoBuilder = pkgs.callPackage ./tools/maven/maven-repo-builder.nix { inherit (pkgs) stdenv; };
# Import a function that can build a prod-build target with specified node dependencies Nix expression
prod-build-fn = pkgs.callPackage ./targets/prod-build.nix { inherit stdenv pkgs target-os nodejs localMavenRepoBuilder mkFilter; };
nodejs = pkgs.nodejs-10_x;
yarn = pkgs.yarn.override { inherit nodejs; };
selectedSources =
optional platform.targetDesktop desktop ++
optional platform.targetMobile mobile;

# TARGETS
leiningen-shell = mkShell {
buildInputs = with pkgs; [ clojure leiningen maven nodejs ];
shellHook =
if target-os == "android" then mobile.android.shellHook else
if target-os == "ios" then mobile.ios.shellHook else "";
};
watchman-shell = mkShell {
buildInputs = with pkgs; [ watchman ];
};

in {
# CHILD DERIVATIONS
inherit mobile;

# TARGETS
leiningen = {
shell = leiningen-shell;
};
watchman = {
shell = watchman-shell;
};

shell = {
buildInputs = unique ([
nodejs
pkgs.python27 # for e.g. gyp
yarn
]
++ optional isDarwin pkgs.cocoapods
++ optional (isDarwin && !platform.targetIOS) pkgs.clang
++ optional (!isDarwin) pkgs.gcc8
++ catAttrs "buildInputs" selectedSources);
shellHook = ''
export PATH="$STATUS_REACT_HOME/node_modules/.bin:$PATH"

${concatStrings (catAttrs "shellHook" selectedSources)}
'';
};
}

+ 1
- 3
nix/desktop/cmake/qtkeychain/default.nix View File

@@ -1,14 +1,12 @@
{ pkgs, stdenv, fetchFromGitHub }:

with pkgs;

let
version = "0.8.90";
rev = "d3c606c55adf8c2c2747556055652b3469f6c4c2"; # This revision will get used in https://github.com/status-im/react-native-keychain/blob/master/desktop/CMakeLists.txt#L45
sha256 = "1gqw3g0j46aswncm8fgy419lp1fp2y2nild82hs18xra5albvf3i";
package = stdenv.mkDerivation {
name = "qtkeychain-patched-source";
version = "${version}-${lib.strings.substring 0 7 rev}";
version = "${version}-${stdenv.lib.strings.substring 0 7 rev}";

src = fetchFromGitHub {
inherit rev sha256;

+ 9
- 8
nix/desktop/cmake/snorenotify/default.nix View File

@@ -1,14 +1,12 @@
{ pkgs, stdenv, fetchFromGitHub }:

with pkgs;

let
version = "0.7.1";
rev = "9d54904e4896ab6c3c3a52f97381e5948b455970"; # This revision will get used in modules/react-native-desktop-notification/desktop/CMakeLists.txt#L71
sha256 = "0ix1qgx877nw9mlbbqsgkis4phkkf4ax2ambziy2w48hg6ai0x4d";
package = stdenv.mkDerivation {
name = "snorenotify-patched-source";
version = "${version}-${lib.strings.substring 0 7 rev}";
version = "${version}-${stdenv.lib.strings.substring 0 7 rev}";

src = fetchFromGitHub {
inherit rev sha256;
@@ -18,16 +16,19 @@ let
};

phases = [ "unpackPhase" ];
unpackPhase = ''
unpackPhase =
let
inherit (stdenv.lib) versions;
in ''
mkdir -p $out/src
cp -r $src/* $out/src/
substituteInPlace $out/src/CMakeLists.txt \
--replace "cmake_minimum_required( VERSION 2.8.12 )" "" \
--replace "project( SnoreNotify )" "cmake_minimum_required( VERSION 3.12.1 )
project( SnoreNotify VERSION ${version} )" \
--replace "set(SNORE_VERSION_MAJOR 0)" "set(SNORE_VERSION_MAJOR ${lib.versions.major version} )" \
--replace "set(SNORE_VERSION_MINOR 7)" "set(SNORE_VERSION_MINOR ${lib.versions.minor version} )" \
--replace "set(SNORE_VERSION_PATCH 1)" "set(SNORE_VERSION_PATCH ${lib.versions.patch version} )"
--replace "set(SNORE_VERSION_MAJOR 0)" "set(SNORE_VERSION_MAJOR ${versions.major version} )" \
--replace "set(SNORE_VERSION_MINOR 7)" "set(SNORE_VERSION_MINOR ${versions.minor version} )" \
--replace "set(SNORE_VERSION_PATCH 1)" "set(SNORE_VERSION_PATCH ${versions.patch version} )"
substituteInPlace $out/src/src/libsnore/CMakeLists.txt \
--replace "{SNORE_VERSION_MAJOR}" "SNORE_VERSION_MAJOR" \
--replace "{SNORE_VERSION_MINOR}" "SNORE_VERSION_MINOR" \
@@ -39,7 +40,7 @@ project( SnoreNotify VERSION ${version} )" \
description = "Patched sources for Snorenotify, a multi platform Qt notification framework. Using a plugin system it is possible to create notifications with many different notification systems on Windows, Mac OS and Unix and mobile Devices";
homepage = https://github.com/status-im/snorenotify;
license = stdenv.lib.licenses.lgpl3;
maintainers = [ stdenv.lib.maintainers.pombeirp ];
maintainers = with stdenv.lib.maintainers; [ pombeirp ];
platforms = with stdenv.lib.platforms; darwin ++ linux;
};
};

+ 9
- 9
nix/desktop/default.nix View File

@@ -2,9 +2,9 @@
cmake, extra-cmake-modules, file, status-go, go,
darwin, nodejs }:

with stdenv;

let
inherit (stdenv.lib) catAttrs concatStrings optional unique;

platform = callPackage ../platform.nix { inherit target-os; };
linuxPlatform = callPackage ./linux { inherit status-go; };
darwinPlatform = callPackage ./macos { inherit status-go darwin; };
@@ -12,23 +12,23 @@ let
snoreNotifySources = callPackage ./cmake/snorenotify { };
qtkeychainSources = callPackage ./cmake/qtkeychain { };
selectedSources =
lib.optional platform.targetLinux linuxPlatform ++
lib.optional platform.targetDarwin darwinPlatform ++
lib.optional platform.targetWindows windowsPlatform;
optional platform.targetLinux linuxPlatform ++
optional platform.targetDarwin darwinPlatform ++
optional platform.targetWindows windowsPlatform;
nodeInputs = import ./realm-node {
# The remaining dependencies come from Nixpkgs
inherit pkgs nodejs;
};

in {
buildInputs = [
buildInputs = unique ([
cmake
extra-cmake-modules
file
snoreNotifySources
qtkeychainSources
] ++ lib.catAttrs "buildInputs" selectedSources
++ (builtins.attrValues nodeInputs);
] ++ catAttrs "buildInputs" selectedSources
++ (builtins.attrValues nodeInputs));

shellHook = lib.concatStrings (lib.catAttrs "shellHook" (selectedSources ++ [ snoreNotifySources qtkeychainSources ]));
shellHook = concatStrings (catAttrs "shellHook" (selectedSources ++ [ snoreNotifySources qtkeychainSources ]));
}

+ 1
- 2
nix/desktop/macos/default.nix View File

@@ -1,10 +1,9 @@
{ stdenv, callPackage,
darwin, qt5, status-go }:

with stdenv;
with darwin.apple_sdk.frameworks;

assert isDarwin;
assert stdenv.isDarwin;

let
baseImage = callPackage ./base-image { };

+ 1
- 1
nix/desktop/realm-node/default.nix View File

@@ -21,7 +21,7 @@ let nodePackages = import ./output { inherit pkgs nodejs; };
"$out/lib/node_modules/realm/compiled/node-v64_darwin_x64/realm.node" else
"$out/lib/node_modules/realm/compiled/node-v64_linux_x64/realm.node";
in nodePackages // {
${realm-patched-name} = nodePackages.${realm-patched-name}.override(oldAttrs: {
"${realm-patched-name}" = nodePackages."${realm-patched-name}".override(oldAttrs: {
reconstructLock = true;
preRebuild = ''
# Do not attempt to do any http calls!

+ 8
- 1
nix/desktop/realm-node/generate-nix.sh View File

@@ -17,7 +17,14 @@ rm -rf $output_dir && mkdir -p $output_dir
# Specify the package.json file containing the dependencies to install
cat << EOF > $input
[
{ "realm": "https://github.com/status-im/realm-js/archive/v2.20.1.tar.gz" }
{ "realm": "https://github.com/status-im/realm-js/archive/v2.20.1.tar.gz" }
]
EOF

# Specify the package.json file containing the build dependencies to install
cat << EOF > $supplement_input
[
"node-pre-gyp"
]
EOF


+ 2
- 4
nix/desktop/windows/default.nix View File

@@ -1,16 +1,14 @@
{ stdenv, callPackage,
conan, nsis, go }:

with stdenv;

assert isLinux;
assert stdenv.isLinux;

let
baseImage = callPackage ./base-image { };

in
{
buildInputs = lib.optionals isLinux [
buildInputs = stdenv.lib.optionals stdenv.isLinux [
conan
nsis
baseImage

+ 291
- 0
nix/lein/lein-project-deps-maven-inputs.txt View File

@@ -0,0 +1,291 @@
https://repo.clojars.org/binaryage/devtools/0.9.10/devtools-0.9.10
https://repo.clojars.org/binaryage/env-config/0.2.2/env-config-0.2.2
https://repo.clojars.org/clj-stacktrace/clj-stacktrace/0.2.5/clj-stacktrace-0.2.5
https://repo.clojars.org/clj-time/clj-time/0.11.0/clj-time-0.11.0
https://repo.clojars.org/clj-time/clj-time/0.6.0/clj-time-0.6.0
https://repo.clojars.org/clj-time/clj-time/0.9.0/clj-time-0.9.0
https://repo.clojars.org/cljfmt/cljfmt/0.5.7/cljfmt-0.5.7
https://repo.clojars.org/cljsbuild/cljsbuild/1.1.7/cljsbuild-1.1.7
https://repo.clojars.org/cljsjs/create-react-class/15.5.3-0/create-react-class-15.5.3-0
https://repo.clojars.org/cljsjs/create-react-class/15.6.3-0/create-react-class-15.6.3-0
https://repo.clojars.org/cljsjs/highlight/9.6.0-0/highlight-9.6.0-0
https://repo.clojars.org/cljsjs/prop-types/15.6.0-0/prop-types-15.6.0-0
https://repo.clojars.org/cljsjs/react-dom-server/15.2.1-0/react-dom-server-15.2.1-0
https://repo.clojars.org/cljsjs/react-dom-server/15.5.4-0/react-dom-server-15.5.4-0
https://repo.clojars.org/cljsjs/react-dom-server/16.3.2-0/react-dom-server-16.3.2-0
https://repo.clojars.org/cljsjs/react-dom/15.2.1-0/react-dom-15.2.1-0
https://repo.clojars.org/cljsjs/react-dom/15.5.4-0/react-dom-15.5.4-0
https://repo.clojars.org/cljsjs/react-dom/16.3.2-0/react-dom-16.3.2-0
https://repo.clojars.org/cljsjs/react-flip-move/2.9.17-0/react-flip-move-2.9.17-0
https://repo.clojars.org/cljsjs/react-highlight/1.0.7-1/react-highlight-1.0.7-1
https://repo.clojars.org/cljsjs/react/15.2.1-0/react-15.2.1-0
https://repo.clojars.org/cljsjs/react/15.5.4-0/react-15.5.4-0
https://repo.clojars.org/cljsjs/react/15.6.1-2/react-15.6.1-2
https://repo.clojars.org/cljsjs/react/16.3.2-0/react-16.3.2-0
https://repo.clojars.org/clout/clout/2.1.2/clout-2.1.2
https://repo.clojars.org/com/andrewmcveigh/cljs-time/0.4.0/cljs-time-0.4.0
https://repo.clojars.org/com/andrewmcveigh/cljs-time/0.5.2/cljs-time-0.5.2
https://repo.clojars.org/com/taoensso/encore/2.79.1/encore-2.79.1
https://repo.clojars.org/com/taoensso/encore/2.84.2/encore-2.84.2
https://repo.clojars.org/com/taoensso/encore/2.91.0/encore-2.91.0
https://repo.clojars.org/com/taoensso/encore/2.94.0/encore-2.94.0
https://repo.clojars.org/com/taoensso/sente/1.11.0/sente-1.11.0
https://repo.clojars.org/com/taoensso/timbre/4.7.4/timbre-4.7.4
https://repo.clojars.org/com/taoensso/truss/1.3.5/truss-1.3.5
https://repo.clojars.org/com/taoensso/truss/1.3.6/truss-1.3.6
https://repo.clojars.org/com/taoensso/truss/1.5.0/truss-1.5.0
https://repo.clojars.org/compojure/compojure/1.5.2/compojure-1.5.2
https://repo.clojars.org/crypto-equality/crypto-equality/1.0.0/crypto-equality-1.0.0
https://repo.clojars.org/crypto-random/crypto-random/1.2.0/crypto-random-1.2.0
https://repo.clojars.org/day8/re-frame/re-frame-10x/0.3.2/re-frame-10x-0.3.2
https://repo.clojars.org/fs/fs/1.1.2/fs-1.1.2
https://repo.clojars.org/hiccup/hiccup/1.0.5/hiccup-1.0.5
https://repo.clojars.org/hickory/hickory/0.7.1/hickory-0.7.1
https://repo.clojars.org/http-kit/http-kit/2.2.0/http-kit-2.2.0
https://repo.clojars.org/instaparse/instaparse/1.4.0/instaparse-1.4.0
https://repo.clojars.org/io/aviso/pretty/0.1.30/pretty-0.1.30
https://repo.clojars.org/io/aviso/pretty/0.1.33/pretty-0.1.33
https://repo.clojars.org/lein-cljfmt/lein-cljfmt/0.5.7/lein-cljfmt-0.5.7
https://repo.clojars.org/lein-cljsbuild/lein-cljsbuild/1.1.7/lein-cljsbuild-1.1.7
https://repo.clojars.org/lein-re-frisk/lein-re-frisk/0.5.8/lein-re-frisk-0.5.8
https://repo.clojars.org/medley/medley/0.8.2/medley-0.8.2
https://repo.clojars.org/meta-merge/meta-merge/1.0.0/meta-merge-1.0.0
https://repo.clojars.org/mvxcvi/alphabase/1.0.0/alphabase-1.0.0
https://repo.clojars.org/net/cgrand/macrovich/0.2.0/macrovich-0.2.0
https://repo.clojars.org/quoin/quoin/0.1.2/quoin-0.1.2
https://repo.clojars.org/rasom/cljs-react-navigation/0.1.4/cljs-react-navigation-0.1.4
https://repo.clojars.org/rasom/lein-githooks/0.1.5/lein-githooks-0.1.5
https://repo.clojars.org/re-com/re-com/2.1.0/re-com-2.1.0
https://repo.clojars.org/re-frame/re-frame/0.10.1/re-frame-0.10.1
https://repo.clojars.org/re-frame/re-frame/0.10.4/re-frame-0.10.4
https://repo.clojars.org/re-frame/re-frame/0.10.6/re-frame-0.10.6
https://repo.clojars.org/re-frisk-shell/re-frisk-shell/0.5.2/re-frisk-shell-0.5.2
https://repo.clojars.org/re-frisk-sidecar/re-frisk-sidecar/0.5.7/re-frisk-sidecar-0.5.7
https://repo.clojars.org/re-frisk/re-frisk/0.5.4/re-frisk-0.5.4
https://repo.clojars.org/reagent/reagent/0.6.0/reagent-0.6.0
https://repo.clojars.org/reagent/reagent/0.7.0/reagent-0.7.0
https://repo.clojars.org/reagent/reagent/0.8.1/reagent-0.8.1
https://repo.clojars.org/rewrite-clj/rewrite-clj/0.5.2/rewrite-clj-0.5.2
https://repo.clojars.org/rewrite-clj/rewrite-clj/0.6.0/rewrite-clj-0.6.0
https://repo.clojars.org/rewrite-cljs/rewrite-cljs/0.4.3/rewrite-cljs-0.4.3
https://repo.clojars.org/rewrite-cljs/rewrite-cljs/0.4.4/rewrite-cljs-0.4.4
https://repo.clojars.org/ring-cors/ring-cors/0.1.8/ring-cors-0.1.8
https://repo.clojars.org/ring/ring-anti-forgery/1.0.0/ring-anti-forgery-1.0.0
https://repo.clojars.org/ring/ring-codec/1.0.0/ring-codec-1.0.0
https://repo.clojars.org/ring/ring-codec/1.0.1/ring-codec-1.0.1
https://repo.clojars.org/ring/ring-core/1.3.0-RC1/ring-core-1.3.0-RC1
https://repo.clojars.org/ring/ring-core/1.3.2/ring-core-1.3.2
https://repo.clojars.org/ring/ring-core/1.4.0/ring-core-1.4.0
https://repo.clojars.org/ring/ring-core/1.5.1/ring-core-1.5.1
https://repo.clojars.org/ring/ring-defaults/0.1.5/ring-defaults-0.1.5
https://repo.clojars.org/ring/ring-headers/0.1.3/ring-headers-0.1.3
https://repo.clojars.org/ring/ring-ssl/0.2.1/ring-ssl-0.2.1
https://repo.clojars.org/status-im/pluto/iteration-4-9/pluto-iteration-4-9
https://repo.clojars.org/status-im/re-frame/0.10.5/re-frame-0.10.5
https://repo.clojars.org/status-im/timbre/4.10.0-2-status/timbre-4.10.0-2-status
https://repo.clojars.org/viebel/codox-klipse-theme/0.0.1/codox-klipse-theme-0.0.1
https://repo.clojars.org/zprint/zprint/0.4.7/zprint-0.4.7
https://repo1.maven.org/maven2/args4j/args4j-site/2.0.26/args4j-site-2.0.26
https://repo1.maven.org/maven2/args4j/args4j-site/2.33/args4j-site-2.33
https://repo1.maven.org/maven2/args4j/args4j/2.0.26/args4j-2.0.26
https://repo1.maven.org/maven2/args4j/args4j/2.33/args4j-2.33
https://repo1.maven.org/maven2/com/cognitect/transit-clj/0.8.290/transit-clj-0.8.290
https://repo1.maven.org/maven2/com/cognitect/transit-clj/0.8.309/transit-clj-0.8.309
https://repo1.maven.org/maven2/com/cognitect/transit-cljs/0.8.239/transit-cljs-0.8.239
https://repo1.maven.org/maven2/com/cognitect/transit-cljs/0.8.243/transit-cljs-0.8.243
https://repo1.maven.org/maven2/com/cognitect/transit-cljs/0.8.248/transit-cljs-0.8.248
https://repo1.maven.org/maven2/com/cognitect/transit-java/0.8.316/transit-java-0.8.316
https://repo1.maven.org/maven2/com/cognitect/transit-java/0.8.332/transit-java-0.8.332
https://repo1.maven.org/maven2/com/cognitect/transit-js/0.8.846/transit-js-0.8.846
https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-core/2.3.2/jackson-core-2.3.2
https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-core/2.8.7/jackson-core-2.8.7
https://repo1.maven.org/maven2/com/fasterxml/jackson/jackson-parent/2.8/jackson-parent-2.8
https://repo1.maven.org/maven2/com/fasterxml/oss-parent/12/oss-parent-12
https://repo1.maven.org/maven2/com/fasterxml/oss-parent/27/oss-parent-27
https://repo1.maven.org/maven2/com/google/code/findbugs/jsr305/1.3.9/jsr305-1.3.9
https://repo1.maven.org/maven2/com/google/code/findbugs/jsr305/3.0.1/jsr305-3.0.1
https://repo1.maven.org/maven2/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2
https://repo1.maven.org/maven2/com/google/code/gson/gson-parent/2.7/gson-parent-2.7
https://repo1.maven.org/maven2/com/google/code/gson/gson/2.2.4/gson-2.2.4
https://repo1.maven.org/maven2/com/google/code/gson/gson/2.7/gson-2.7
https://repo1.maven.org/maven2/com/google/errorprone/error_prone_annotations/2.0.18/error_prone_annotations-2.0.18
https://repo1.maven.org/maven2/com/google/errorprone/error_prone_annotations/2.1.3/error_prone_annotations-2.1.3
https://repo1.maven.org/maven2/com/google/errorprone/error_prone_annotations/2.3.1/error_prone_annotations-2.3.1
https://repo1.maven.org/maven2/com/google/errorprone/error_prone_parent/2.0.18/error_prone_parent-2.0.18
https://repo1.maven.org/maven2/com/google/errorprone/error_prone_parent/2.1.3/error_prone_parent-2.1.3
https://repo1.maven.org/maven2/com/google/errorprone/error_prone_parent/2.3.1/error_prone_parent-2.3.1
https://repo1.maven.org/maven2/com/google/google/1/google-1
https://repo1.maven.org/maven2/com/google/guava/guava-parent/17.0/guava-parent-17.0
https://repo1.maven.org/maven2/com/google/guava/guava-parent/18.0/guava-parent-18.0
https://repo1.maven.org/maven2/com/google/guava/guava-parent/19.0/guava-parent-19.0
https://repo1.maven.org/maven2/com/google/guava/guava-parent/20.0/guava-parent-20.0
https://repo1.maven.org/maven2/com/google/guava/guava-parent/25.1-jre/guava-parent-25.1-jre
https://repo1.maven.org/maven2/com/google/guava/guava/17.0/guava-17.0
https://repo1.maven.org/maven2/com/google/guava/guava/18.0/guava-18.0
https://repo1.maven.org/maven2/com/google/guava/guava/19.0/guava-19.0
https://repo1.maven.org/maven2/com/google/guava/guava/20.0/guava-20.0
https://repo1.maven.org/maven2/com/google/guava/guava/25.1-jre/guava-25.1-jre
https://repo1.maven.org/maven2/com/google/j2objc/j2objc-annotations/1.1/j2objc-annotations-1.1
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-externs/v20150126/closure-compiler-externs-v20150126
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-externs/v20160315/closure-compiler-externs-v20160315
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-externs/v20160911/closure-compiler-externs-v20160911
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-externs/v20161201/closure-compiler-externs-v20161201
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-externs/v20170521/closure-compiler-externs-v20170521
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-externs/v20170806/closure-compiler-externs-v20170806
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-externs/v20170910/closure-compiler-externs-v20170910
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-externs/v20180805/closure-compiler-externs-v20180805
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-externs/v20190325/closure-compiler-externs-v20190325
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-main/v20160315/closure-compiler-main-v20160315
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-main/v20160911/closure-compiler-main-v20160911
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-main/v20161201/closure-compiler-main-v20161201
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-main/v20170521/closure-compiler-main-v20170521
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-main/v20170806/closure-compiler-main-v20170806
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-main/v20170910/closure-compiler-main-v20170910
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-main/v20180805/closure-compiler-main-v20180805
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-main/v20190325/closure-compiler-main-v20190325
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-parent/v20150126/closure-compiler-parent-v20150126
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-parent/v20151216/closure-compiler-parent-v20151216
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-parent/v20160315/closure-compiler-parent-v20160315
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-parent/v20160911/closure-compiler-parent-v20160911
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-parent/v20161201/closure-compiler-parent-v20161201
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-parent/v20170521/closure-compiler-parent-v20170521
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-parent/v20170806/closure-compiler-parent-v20170806
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-parent/v20170910/closure-compiler-parent-v20170910
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-parent/v20180805/closure-compiler-parent-v20180805
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-parent/v20190325/closure-compiler-parent-v20190325
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-unshaded/v20160315/closure-compiler-unshaded-v20160315
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-unshaded/v20160911/closure-compiler-unshaded-v20160911
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-unshaded/v20161201/closure-compiler-unshaded-v20161201
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-unshaded/v20170521/closure-compiler-unshaded-v20170521
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-unshaded/v20170806/closure-compiler-unshaded-v20170806
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-unshaded/v20170910/closure-compiler-unshaded-v20170910
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-unshaded/v20180805/closure-compiler-unshaded-v20180805
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler-unshaded/v20190325/closure-compiler-unshaded-v20190325
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler/v20150126/closure-compiler-v20150126
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler/v20151216/closure-compiler-v20151216
https://repo1.maven.org/maven2/com/google/javascript/closure-compiler/v20160315/closure-compiler-v20160315
https://repo1.maven.org/maven2/com/google/jsinterop/jsinterop-annotations/1.0.0/jsinterop-annotations-1.0.0
https://repo1.maven.org/maven2/com/google/jsinterop/jsinterop/1.0.0/jsinterop-1.0.0
https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/2.5.0/protobuf-java-2.5.0
https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.0.2/protobuf-java-3.0.2
https://repo1.maven.org/maven2/com/google/protobuf/protobuf-parent/3.0.2/protobuf-parent-3.0.2
https://repo1.maven.org/maven2/com/google/truth/truth-parent/0.24/truth-parent-0.24
https://repo1.maven.org/maven2/com/google/truth/truth/0.24/truth-0.24
https://repo1.maven.org/maven2/com/googlecode/java-diff-utils/diffutils/1.2.1/diffutils-1.2.1
https://repo1.maven.org/maven2/com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1
https://repo1.maven.org/maven2/com/yahoo/platform/yui/yuicompressor/2.4.8/yuicompressor-2.4.8
https://repo1.maven.org/maven2/commons-codec/commons-codec/1.10/commons-codec-1.10
https://repo1.maven.org/maven2/commons-codec/commons-codec/1.6/commons-codec-1.6
https://repo1.maven.org/maven2/commons-fileupload/commons-fileupload/1.3.1/commons-fileupload-1.3.1
https://repo1.maven.org/maven2/commons-fileupload/commons-fileupload/1.3/commons-fileupload-1.3
https://repo1.maven.org/maven2/commons-io/commons-io/2.2/commons-io-2.2
https://repo1.maven.org/maven2/commons-io/commons-io/2.4/commons-io-2.4
https://repo1.maven.org/maven2/commons-io/commons-io/2.5/commons-io-2.5
https://repo1.maven.org/maven2/javax/servlet/servlet-api/2.5/servlet-api-2.5
https://repo1.maven.org/maven2/joda-time/joda-time/2.2/joda-time-2.2
https://repo1.maven.org/maven2/joda-time/joda-time/2.6/joda-time-2.6
https://repo1.maven.org/maven2/joda-time/joda-time/2.8.2/joda-time-2.8.2
https://repo1.maven.org/maven2/junit/junit/4.10/junit-4.10
https://repo1.maven.org/maven2/org/apache/apache/13/apache-13
https://repo1.maven.org/maven2/org/apache/apache/15/apache-15
https://repo1.maven.org/maven2/org/apache/apache/16/apache-16
https://repo1.maven.org/maven2/org/apache/apache/9/apache-9
https://repo1.maven.org/maven2/org/apache/commons/commons-compress/1.3/commons-compress-1.3
https://repo1.maven.org/maven2/org/apache/commons/commons-parent/22/commons-parent-22
https://repo1.maven.org/maven2/org/apache/commons/commons-parent/24/commons-parent-24
https://repo1.maven.org/maven2/org/apache/commons/commons-parent/25/commons-parent-25
https://repo1.maven.org/maven2/org/apache/commons/commons-parent/28/commons-parent-28
https://repo1.maven.org/maven2/org/apache/commons/commons-parent/32/commons-parent-32
https://repo1.maven.org/maven2/org/apache/commons/commons-parent/35/commons-parent-35
https://repo1.maven.org/maven2/org/apache/commons/commons-parent/39/commons-parent-39
https://repo1.maven.org/maven2/org/checkerframework/checker-qual/2.0.0/checker-qual-2.0.0
https://repo1.maven.org/maven2/org/clojure/clojure/1.10.0/clojure-1.10.0
https://repo1.maven.org/maven2/org/clojure/clojure/1.2.1/clojure-1.2.1
https://repo1.maven.org/maven2/org/clojure/clojure/1.3.0/clojure-1.3.0
https://repo1.maven.org/maven2/org/clojure/clojure/1.4.0/clojure-1.4.0
https://repo1.maven.org/maven2/org/clojure/clojure/1.5.0/clojure-1.5.0
https://repo1.maven.org/maven2/org/clojure/clojure/1.5.1/clojure-1.5.1
https://repo1.maven.org/maven2/org/clojure/clojure/1.6.0/clojure-1.6.0
https://repo1.maven.org/maven2/org/clojure/clojure/1.7.0-beta1/clojure-1.7.0-beta1
https://repo1.maven.org/maven2/org/clojure/clojure/1.7.0/clojure-1.7.0
https://repo1.maven.org/maven2/org/clojure/clojure/1.8.0/clojure-1.8.0
https://repo1.maven.org/maven2/org/clojure/clojure/1.9.0-RC1/clojure-1.9.0-RC1
https://repo1.maven.org/maven2/org/clojure/clojure/1.9.0/clojure-1.9.0
https://repo1.maven.org/maven2/org/clojure/clojurescript/0.0-3211/clojurescript-0.0-3211
https://repo1.maven.org/maven2/org/clojure/clojurescript/1.10.516/clojurescript-1.10.516
https://repo1.maven.org/maven2/org/clojure/clojurescript/1.10.520/clojurescript-1.10.520
https://repo1.maven.org/maven2/org/clojure/clojurescript/1.7.228/clojurescript-1.7.228
https://repo1.maven.org/maven2/org/clojure/clojurescript/1.8.51/clojurescript-1.8.51
https://repo1.maven.org/maven2/org/clojure/clojurescript/1.9.227/clojurescript-1.9.227
https://repo1.maven.org/maven2/org/clojure/clojurescript/1.9.293/clojurescript-1.9.293
https://repo1.maven.org/maven2/org/clojure/clojurescript/1.9.456/clojurescript-1.9.456
https://repo1.maven.org/maven2/org/clojure/clojurescript/1.9.655/clojurescript-1.9.655
https://repo1.maven.org/maven2/org/clojure/clojurescript/1.9.671/clojurescript-1.9.671
https://repo1.maven.org/maven2/org/clojure/clojurescript/1.9.908/clojurescript-1.9.908
https://repo1.maven.org/maven2/org/clojure/clojurescript/1.9.946/clojurescript-1.9.946
https://repo1.maven.org/maven2/org/clojure/core.async/0.2.395/core.async-0.2.395
https://repo1.maven.org/maven2/org/clojure/core.async/0.4.474/core.async-0.4.474
https://repo1.maven.org/maven2/org/clojure/core.cache/0.6.5/core.cache-0.6.5
https://repo1.maven.org/maven2/org/clojure/core.memoize/0.5.9/core.memoize-0.5.9
https://repo1.maven.org/maven2/org/clojure/core.specs.alpha/0.1.24/core.specs.alpha-0.1.24
https://repo1.maven.org/maven2/org/clojure/core.specs.alpha/0.2.44/core.specs.alpha-0.2.44
https://repo1.maven.org/maven2/org/clojure/data.json/0.2.6/data.json-0.2.6
https://repo1.maven.org/maven2/org/clojure/data.priority-map/0.0.7/data.priority-map-0.0.7
https://repo1.maven.org/maven2/org/clojure/google-closure-library-third-party/0.0-20140718-946a7d39/google-closure-library-third-party-0.0-20140718-946a7d39
https://repo1.maven.org/maven2/org/clojure/google-closure-library-third-party/0.0-20151016-61277aea/google-closure-library-third-party-0.0-20151016-61277aea
https://repo1.maven.org/maven2/org/clojure/google-closure-library-third-party/0.0-20160609-f42b4a24/google-closure-library-third-party-0.0-20160609-f42b4a24
https://repo1.maven.org/maven2/org/clojure/google-closure-library-third-party/0.0-20170519-fa0499ef/google-closure-library-third-party-0.0-20170519-fa0499ef
https://repo1.maven.org/maven2/org/clojure/google-closure-library-third-party/0.0-20170809-b9c14c6b/google-closure-library-third-party-0.0-20170809-b9c14c6b
https://repo1.maven.org/maven2/org/clojure/google-closure-library-third-party/0.0-20190213-2033d5d9/google-closure-library-third-party-0.0-20190213-2033d5d9
https://repo1.maven.org/maven2/org/clojure/google-closure-library/0.0-20140718-946a7d39/google-closure-library-0.0-20140718-946a7d39
https://repo1.maven.org/maven2/org/clojure/google-closure-library/0.0-20151016-61277aea/google-closure-library-0.0-20151016-61277aea
https://repo1.maven.org/maven2/org/clojure/google-closure-library/0.0-20160609-f42b4a24/google-closure-library-0.0-20160609-f42b4a24
https://repo1.maven.org/maven2/org/clojure/google-closure-library/0.0-20170519-fa0499ef/google-closure-library-0.0-20170519-fa0499ef
https://repo1.maven.org/maven2/org/clojure/google-closure-library/0.0-20170809-b9c14c6b/google-closure-library-0.0-20170809-b9c14c6b
https://repo1.maven.org/maven2/org/clojure/google-closure-library/0.0-20190213-2033d5d9/google-closure-library-0.0-20190213-2033d5d9
https://repo1.maven.org/maven2/org/clojure/pom.contrib/0.1.2/pom.contrib-0.1.2
https://repo1.maven.org/maven2/org/clojure/pom.contrib/0.2.0/pom.contrib-0.2.0
https://repo1.maven.org/maven2/org/clojure/pom.contrib/0.2.2/pom.contrib-0.2.2
https://repo1.maven.org/maven2/org/clojure/spec.alpha/0.1.143/spec.alpha-0.1.143
https://repo1.maven.org/maven2/org/clojure/spec.alpha/0.2.176/spec.alpha-0.2.176
https://repo1.maven.org/maven2/org/clojure/tools.analyzer.jvm/0.6.10/tools.analyzer.jvm-0.6.10
https://repo1.maven.org/maven2/org/clojure/tools.analyzer.jvm/0.7.0/tools.analyzer.jvm-0.7.0
https://repo1.maven.org/maven2/org/clojure/tools.analyzer/0.6.9/tools.analyzer-0.6.9
https://repo1.maven.org/maven2/org/clojure/tools.logging/0.3.1/tools.logging-0.3.1
https://repo1.maven.org/maven2/org/clojure/tools.macro/0.1.5/tools.macro-0.1.5
https://repo1.maven.org/maven2/org/clojure/tools.namespace/0.2.11/tools.namespace-0.2.11
https://repo1.maven.org/maven2/org/clojure/tools.reader/0.10.0/tools.reader-0.10.0
https://repo1.maven.org/maven2/org/clojure/tools.reader/0.8.1/tools.reader-0.8.1
https://repo1.maven.org/maven2/org/clojure/tools.reader/0.9.1/tools.reader-0.9.1
https://repo1.maven.org/maven2/org/clojure/tools.reader/1.0.0-alpha1/tools.reader-1.0.0-alpha1
https://repo1.maven.org/maven2/org/clojure/tools.reader/1.0.0-alpha3/tools.reader-1.0.0-alpha3
https://repo1.maven.org/maven2/org/clojure/tools.reader/1.0.0-alpha4/tools.reader-1.0.0-alpha4
https://repo1.maven.org/maven2/org/clojure/tools.reader/1.0.0-beta1/tools.reader-1.0.0-beta1
https://repo1.maven.org/maven2/org/clojure/tools.reader/1.0.0-beta2/tools.reader-1.0.0-beta2
https://repo1.maven.org/maven2/org/clojure/tools.reader/1.0.0-beta3/tools.reader-1.0.0-beta3
https://repo1.maven.org/maven2/org/clojure/tools.reader/1.0.0-beta4/tools.reader-1.0.0-beta4
https://repo1.maven.org/maven2/org/clojure/tools.reader/1.0.0/tools.reader-1.0.0
https://repo1.maven.org/maven2/org/clojure/tools.reader/1.0.5/tools.reader-1.0.5
https://repo1.maven.org/maven2/org/clojure/tools.reader/1.1.0/tools.reader-1.1.0
https://repo1.maven.org/maven2/org/clojure/tools.reader/1.2.1/tools.reader-1.2.1
https://repo1.maven.org/maven2/org/clojure/tools.reader/1.3.0/tools.reader-1.3.0
https://repo1.maven.org/maven2/org/clojure/tools.reader/1.3.2/tools.reader-1.3.2
https://repo1.maven.org/maven2/org/codehaus/codehaus-parent/4/codehaus-parent-4
https://repo1.maven.org/maven2/org/codehaus/mojo/animal-sniffer-annotations/1.14/animal-sniffer-annotations-1.14
https://repo1.maven.org/maven2/org/codehaus/mojo/animal-sniffer-parent/1.14/animal-sniffer-parent-1.14
https://repo1.maven.org/maven2/org/codehaus/mojo/mojo-parent/34/mojo-parent-34
https://repo1.maven.org/maven2/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1
https://repo1.maven.org/maven2/org/hamcrest/hamcrest-parent/1.1/hamcrest-parent-1.1
https://repo1.maven.org/maven2/org/javassist/javassist/3.18.1-GA/javassist-3.18.1-GA
https://repo1.maven.org/maven2/org/jsoup/jsoup/1.9.2/jsoup-1.9.2
https://repo1.maven.org/maven2/org/kohsuke/pom/14/pom-14
https://repo1.maven.org/maven2/org/kohsuke/pom/6/pom-6
https://repo1.maven.org/maven2/org/mozilla/rhino/1.7R5/rhino-1.7R5
https://repo1.maven.org/maven2/org/msgpack/msgpack/0.6.12/msgpack-0.6.12
https://repo1.maven.org/maven2/org/ow2/asm/asm-all/4.2/asm-all-4.2
https://repo1.maven.org/maven2/org/ow2/asm/asm-parent/4.2/asm-parent-4.2
https://repo1.maven.org/maven2/org/ow2/ow2/1.3/ow2-1.3
https://repo1.maven.org/maven2/org/sonatype/oss/oss-parent/4/oss-parent-4
https://repo1.maven.org/maven2/org/sonatype/oss/oss-parent/5/oss-parent-5
https://repo1.maven.org/maven2/org/sonatype/oss/oss-parent/7/oss-parent-7
https://repo1.maven.org/maven2/org/sonatype/oss/oss-parent/9/oss-parent-9

+ 3555
- 0
nix/lein/lein-project-deps.nix
File diff suppressed because it is too large
View File


+ 0
- 44
nix/mobile/android.nix View File

@@ -1,44 +0,0 @@
{ config, stdenv, callPackage,
androidenv, openjdk, gradle }:

with stdenv;

let
androidComposition = androidenv.composeAndroidPackages {
toolsVersion = "26.1.1";
platformToolsVersion = "28.0.2";
buildToolsVersions = [ "28.0.3" ];
includeEmulator = false;
platformVersions = [ "28" ];
includeSources = false;
includeDocs = false;
includeSystemImages = false;
systemImageTypes = [ "default" ];
abiVersions = [ "armeabi-v7a" ];
lldbVersions = [ "2.0.2558144" ];
cmakeVersions = [ "3.6.4111459" ];
includeNDK = true;
ndkVersion = "19.2.5345600";
useGoogleAPIs = false;
useGoogleTVAddOns = false;
includeExtras = [ "extras;android;m2repository" "extras;google;m2repository" ];
};
licensedAndroidEnv = callPackage ./licensed-android-sdk.nix { inherit androidComposition; };

in
{
inherit androidComposition;

buildInputs = [ openjdk gradle ];
shellHook = ''
export JAVA_HOME="${openjdk}"
export ANDROID_HOME="${licensedAndroidEnv}"
export ANDROID_SDK_ROOT="$ANDROID_HOME"
export ANDROID_NDK_ROOT="${androidComposition.androidsdk}/libexec/android-sdk/ndk-bundle"
export ANDROID_NDK_HOME="$ANDROID_NDK_ROOT"
export ANDROID_NDK="$ANDROID_NDK_ROOT"
export PATH="$ANDROID_HOME/bin:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools:$ANDROID_HOME/build-tools:$PATH"

$STATUS_REACT_HOME/scripts/generate-keystore.sh
'';
}

+ 61
- 0
nix/mobile/android/android-env.nix View File

@@ -0,0 +1,61 @@
#
# This Nix expression centralizes the configuration for the Android development environment
#

{ stdenv, config, target-os, callPackage,
androidenv, openjdk }:

let
platform = callPackage ../../platform.nix { inherit target-os; };

androidComposition = androidenv.composeAndroidPackages {
toolsVersion = "26.1.1";
platformToolsVersion = "28.0.2";
buildToolsVersions = [ "28.0.3" ];
includeEmulator = false;
platformVersions = [ "28" ];
includeSources = false;
includeDocs = false;
includeSystemImages = false;
systemImageTypes = [ "default" ];
abiVersions = [ "armeabi-v7a" ];
lldbVersions = [ "2.0.2558144" ];
cmakeVersions = [ "3.6.4111459" ];
includeNDK = true;
ndkVersion = "19.2.5345600";
useGoogleAPIs = false;
useGoogleTVAddOns = false;
includeExtras = [ "extras;android;m2repository" "extras;google;m2repository" ];
};
licensedAndroidEnv = stdenv.mkDerivation rec {
name = "licensed-android-sdk";
version = "licensed";
phases = [ "installPhase" ];
installPhase = ''
mkdir -p $out/libexec/android-sdk
ln -s "${androidComposition.androidsdk}/bin" $out/bin
for d in ${androidComposition.androidsdk}/libexec/android-sdk/*; do
ln -s $d $out/$(basename $d)
done
'' + stdenv.lib.optionalString config.android_sdk.accept_license ''
mkdir -p $out/licenses
echo -e "\n601085b94cd77f0b54ff86406957099ebe79c4d6" > "$out/licenses/android-googletv-license"
echo -e "\n24333f8a63b6825ea9c5514f83c2829b004d1fee" > "$out/licenses/android-sdk-license"
echo -e "\n84831b9409646a918e30573bab4c9c91346d8abd" > "$out/licenses/android-sdk-preview-license"
echo -e "\nd975f751698a77b662f1254ddbeed3901e976f5a" > "$out/licenses/intel-android-extra-license"
echo -e "\n33b6a2b64607f11b759f320ef9dff4ae5c47d97a" > "$out/licenses/google-gdk-license"
'';
};
shellHook = assert platform.targetAndroid; ''
export JAVA_HOME="${openjdk}"
export ANDROID_HOME="${licensedAndroidEnv}"
export ANDROID_SDK_ROOT="$ANDROID_HOME"
export ANDROID_NDK_ROOT="${androidComposition.androidsdk}/libexec/android-sdk/ndk-bundle"
export ANDROID_NDK_HOME="$ANDROID_NDK_ROOT"
export ANDROID_NDK="$ANDROID_NDK_ROOT"
export PATH="$ANDROID_HOME/bin:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools:$ANDROID_HOME/build-tools:$PATH"
'';

in {
inherit androidComposition licensedAndroidEnv shellHook;
}

+ 43
- 0
nix/mobile/android/default.nix View File

@@ -0,0 +1,43 @@
{ config, stdenv, stdenvNoCC, target-os, callPackage, mkShell,
mkFilter, androidenv, fetchurl, openjdk, nodejs, bash, maven, zlib,
status-go, localMavenRepoBuilder, projectNodePackage, prod-build-fn }:

let
platform = callPackage ../../platform.nix { inherit target-os; };

androidEnv = callPackage ./android-env.nix { inherit target-os openjdk; };
gradle = callPackage ./gradle.nix { };

# Import a local patched version of node_modules, together with a local version of the Maven repo
mavenAndNpmDeps = callPackage ./maven-and-npm-deps { inherit stdenv stdenvNoCC gradle bash nodejs zlib localMavenRepoBuilder mkFilter projectNodePackage status-go; androidEnvShellHook = androidEnv.shellHook; };

# TARGETS
prod-build = (prod-build-fn { inherit projectNodePackage; });
release = callPackage ./targets/release-android.nix { inherit target-os gradle mavenAndNpmDeps mkFilter nodejs prod-build status-go zlib; androidEnvShellHook = androidEnv.shellHook; };
generate-maven-and-npm-deps-shell = callPackage ./maven-and-npm-deps/maven/shell.nix { inherit gradle maven projectNodePackage status-go; androidEnvShellHook = androidEnv.shellHook; };
adb-shell = mkShell {
buildInputs = [ androidEnv.licensedAndroidEnv ];
inherit (androidEnv) shellHook;
};

in {
inherit (androidEnv) androidComposition;

buildInputs = assert platform.targetAndroid; [ mavenAndNpmDeps.deriv openjdk gradle ];
shellHook =
let
inherit (stdenv.lib) catAttrs concatStrings;
in ''
${concatStrings (catAttrs "shellHook" [ mavenAndNpmDeps androidEnv ])}
$STATUS_REACT_HOME/scripts/generate-keystore.sh

$STATUS_REACT_HOME/nix/mobile/reset-node_modules.sh "${mavenAndNpmDeps.deriv}/project" || exit
'';

# TARGETS
inherit release generate-maven-and-npm-deps-shell;
adb = {
shell = adb-shell;
};
}

+ 15
- 0
nix/mobile/android/gradle.nix View File

@@ -0,0 +1,15 @@
#
# This Nix expression returns our sanctioned version of Gradle
#

{ gradleGen, fetchurl }:

gradleGen.gradleGen rec {
name = "gradle-5.1.1";
nativeVersion = "0.14";

src = fetchurl {
url = "http://services.gradle.org/distributions/${name}-bin.zip";
sha256 = "16671jp5wdr3q6p91h6szkgcxg3mw9wpgp6hjygbimy50lv34ls9";
};
}

+ 209
- 0
nix/mobile/android/maven-and-npm-deps/default.nix View File

@@ -0,0 +1,209 @@
#
# This script prepares a finalized version of node_modules
# (required because for Android we need to run `gradle react-native-android:installArchives`, which builds some additional native libraries
# under node_modules/react-native), as well as a local version of the Maven repository required by Gradle scripts
#

{ stdenv, stdenvNoCC, lib, callPackage,
gradle, bash, file, nodejs, status-go, zlib,
projectNodePackage, androidEnvShellHook, localMavenRepoBuilder, mkFilter }:

let
mavenLocalRepo = callPackage ./maven { inherit localMavenRepoBuilder; stdenv = if stdenv.isLinux then stdenv else stdenvNoCC; };

# Import the native dependencies for React Native Android builds
jsc-filename = "jsc-android-236355.1.1";
react-native-deps = callPackage ./maven/reactnative-android-native-deps.nix { inherit stdenvNoCC jsc-filename; };

createMobileFilesSymlinks = root: ''
ln -sf ${root}/mobile_files/package.json.orig ${root}/package.json
ln -sf ${root}/mobile_files/metro.config.js ${root}/metro.config.js
ln -sf ${root}/mobile_files/yarn.lock ${root}/yarn.lock
'';

# fake build to pre-download deps into fixed-output derivation
deps =
let
# Place build target directories in NIX_BUILD_TOP (normally represents /build)
projectDir = "$NIX_BUILD_TOP/project";
mavenRepoDir = "$NIX_BUILD_TOP/.m2/repository";
reactNativeMavenPackageDir = "${mavenRepoDir}/com/facebook/react/react-native"; # This is directory where the react-native Maven package will be generated in
reactNativeDepsDir = "$NIX_BUILD_TOP/deps"; # Use local writable deps, otherwise (probably due to some interaction between Nix sandboxing and Java) gradle will fail copying directly from the nix store
in
stdenv.mkDerivation {
name = "gradle-install-android-archives-and-patched-npm-modules";
src =
let path = ./../../../..; # Import the root /android and /mobile_files folders clean of any build artifacts
in builtins.path { # We use builtins.path so that we can name the resulting derivation, otherwise the name would be taken from the checkout directory, which is outside of our control
inherit path;
name = "status-react-gradle-install-source";
filter =
# Keep this filter as restrictive as possible in order to avoid unnecessary rebuilds and limit closure size
mkFilter {
dirRootsToInclude = [
"android" "mobile_files" "packager" "resources"
"translations" "status-modules"
];
dirsToExclude = [ ".git" ".svn" "CVS" ".hg" ".gradle" "build" "intermediates" "libs" "obj" ];
filesToInclude = [ ".babelrc" ];
filesToExclude = [ "android/gradlew" ];
root = path;
};
};
nativeBuildInputs = [ projectNodePackage ];
buildInputs = [ gradle bash file zlib mavenLocalRepo ];
propagatedBuildInputs = [ react-native-deps ] ++ status-go.buildInputs;
unpackPhase = ''
runHook preUnpack

# Copy project directory
mkdir -p ${projectDir}
cp -a $src/. ${projectDir}
chmod u+w ${projectDir}
cd ${projectDir}

# Copy RN maven dependencies and make them writable, otherwise Gradle copy fails (since the top-level directory is read-only, Java isn't smart enough to copy the child files/folders into that target directory)
mkdir -p ${mavenRepoDir}
cp -a ${mavenLocalRepo}/. ${mavenRepoDir}
mkdir -p ${reactNativeMavenPackageDir}
chmod u+w ${reactNativeMavenPackageDir}/
cp -a ${react-native-deps}/deps ${reactNativeDepsDir}
for d in `find ${reactNativeDepsDir} -mindepth 1 -maxdepth 1 -type d`; do
chmod -R u+w $d
done

# Copy node_modules from Nix store
rm -rf ${projectDir}/node_modules
mkdir -p ${projectDir}/node_modules
cp -a ${projectNodePackage}/node_modules/. ${projectDir}/node_modules/

# Adjust permissions
chmod -R u+w ${projectDir}

cp -R ${projectDir}/status-modules/ ${projectDir}/node_modules/status-modules/
cp -R ${projectDir}/translations/ ${projectDir}/node_modules/status-modules/translations/

# Set up symlinks to mobile enviroment in project root
${createMobileFilesSymlinks projectDir}

# Create a dummy VERSION, since we don't want this expression to be invalidated just because the version changed
echo '0.0.1' > ${projectDir}/VERSION

runHook postUnpack
'';
patchPhase = ''
runHook prePatch

prevSet=$-
set -e

patchShebangs ${projectDir}

function patchMavenSource() {
set +e

local targetGradleFile="$1"
local source="$2"
local deriv="$3"
grep "$source" $targetGradleFile > /dev/null && \
substituteInPlace $targetGradleFile --replace "$source" "$deriv"
}

function patchMavenSources() {
set +e

local targetGradleFile="$1"
local deriv="$2"
patchMavenSource $targetGradleFile 'mavenCentral()' 'mavenLocal()'
patchMavenSource $targetGradleFile 'google()' 'mavenLocal()'
patchMavenSource $targetGradleFile 'jcenter()' 'mavenLocal()'
grep 'https://maven.google.com' $targetGradleFile > /dev/null && \
substituteInPlace $targetGradleFile --replace 'https://maven.google.com' "$deriv"
grep 'https://jitpack.io' $targetGradleFile > /dev/null && \
substituteInPlace $targetGradleFile --replace 'https://jitpack.io' "$deriv"
}

# Patch maven and google central repositories with our own local directories. This prevents the builder from downloading Maven artifacts
patchMavenSources 'android/build.gradle' '${mavenLocalRepo}'
for f in `find ${projectDir}/node_modules/ -name build.gradle`; do
patchMavenSources $f '${mavenLocalRepo}'
done

# Patch prepareJSC so that it doesn't try to download from registry
substituteInPlace ${projectDir}/node_modules/react-native/ReactAndroid/build.gradle \
--replace 'prepareJSC(dependsOn: downloadJSC)' 'prepareJSC(dependsOn: createNativeDepsDirectories)' \
--replace 'def jscTar = tarTree(downloadJSC.dest)' "def jscTar = tarTree(new File(\"${react-native-deps}/deps/${jsc-filename}.tar.gz\"))"

# Do not add a BuildId to the generated libraries, for reproducibility
substituteInPlace ${projectDir}/node_modules/react-native/ReactAndroid/src/main/jni/Application.mk \
--replace '-Wl,--build-id' '-Wl,--build-id=none'

# Disable Gradle daemon and caching, since that causes rebuilds (and subsequently errors) anyway due to cache being considered stale
substituteInPlace ${projectDir}/android/gradle.properties \
--replace 'org.gradle.jvmargs=-Xmx8704M' 'org.gradle.jvmargs=-Xmx8704M
org.gradle.daemon=false
org.gradle.caching=false'

# Patch the path to nodejs in project.ext.react
substituteInPlace ${projectDir}/android/app/build.gradle \
--replace 'nodeExecutableAndArgs: ["node"' 'nodeExecutableAndArgs: ["${nodejs}/bin/node"'

set $prevSet

runHook postPatch
'';
buildPhase =
androidEnvShellHook +
status-go.shellHook + ''
export HOME=$NIX_BUILD_TOP
export REACT_NATIVE_DEPENDENCIES="${reactNativeDepsDir}"
export STATUS_REACT_HOME="${projectDir}"

pushd ${projectDir}/android
# NOTE: This generates the react-native-android binaries under node_modules/react-native/android
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${lib.makeLibraryPath [ zlib ]} \
gradle -Dmaven.repo.local=${mavenRepoDir} --offline -S react-native-android:installArchives || exit
popd > /dev/null
'';
doCheck = true;
checkPhase = ''
runHook preCheck
test -d ${projectDir}/node_modules/react-native/ReactAndroid/build/intermediates/javac/release/compileReleaseJavaWithJavac/classes/com/facebook || \
exit 1
test -d ${projectDir}/node_modules/react-native/ReactAndroid/build/react-ndk/exported || \
exit 2
runHook postCheck
'';
installPhase = ''
rm -rf $out
mkdir -p $out/project $out/.m2/repository

# TODO: maybe node_modules/react-native/ReactAndroid/build/{tmp,generated} can be discarded?
cp -R ${mavenRepoDir} $out/.m2/
cp -R ${projectDir}/android/ ${projectDir}/node_modules/ $out/project
'';
fixupPhase = ''
# Patch prepareJSC so that it doesn't subsequently try to build NDK libs
substituteInPlace $out/project/node_modules/react-native/ReactAndroid/build.gradle \
--replace 'packageReactNdkLibs(dependsOn: buildReactNdkLib, ' 'packageReactNdkLibs('
'';