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

This commit is contained in:
Pedro Pombeiro 2019-06-04 18:50:29 +02:00
parent 0ed6ef59ba
commit a7fd659d84
No known key found for this signature in database
GPG Key ID: C4A24185B2AA48A1
77 changed files with 37958 additions and 463 deletions

1
.gitignore vendored
View File

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

103
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 '^$@$$'

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

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

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()

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

8
android/gradlew vendored
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 "$@"

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' }
}
}

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']
)
}

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' }
}
}

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') }
}
}
} }

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') }
}
}
} }

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
'''
}
}
}

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') }
}
}
} }

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']
)
}

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

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']
)
}

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(

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('/')
}

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;
}

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);
}

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)

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
'';
}

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"];

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" \

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
nix/derivation.nix Normal file
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)}
'';
};
}

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;

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;
};
};

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 ]));
}

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 { };

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!

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

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

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

File diff suppressed because it is too large Load Diff

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
'';
}

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;
}

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;
};
}

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";
};
}

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('
'';
# The ELF types are incompatible with the host platform, so let's not even try
# TODO: Use Android NDK to strip binaries manually
dontPatchELF = true;
dontStripHost = true;
# Take whole sources into consideration when calculating sha
outputHashMode = "recursive";
outputHashAlgo = "sha256";
};
in {
deriv = deps;
shellHook = ''
${createMobileFilesSymlinks "$STATUS_REACT_HOME"}
export STATUSREACT_NIX_MAVEN_REPO="${deps}/.m2/repository"
'';
}

View File

@ -0,0 +1,10 @@
# Maven dependencies Nix wrapper
## Overview
This folder contains the Nix expression (`maven-sources.nix`) that downloads all Maven dependencies required for Gradle, as well as the scripts used to generate that file, namely:
- `generate-nix.sh`: This is the main entry point script, which will use Gradle to determine the dependencies (into `maven-inputs.txt`), and `nix/tools/maven/maven-inputs2nix.sh` to generate `default.nix` from those dependencies.
- `fetch-maven-deps.sh`: This script does the heavy work of determining Gradle dependencies and outputting a `maven-inputs.txt` file listing the external URLs.
- `reactnative-android-native-deps.nix`: Contains the Nix attribute set used to download the React Native dependencies used in `gradle react-native-android:installArchives`.
- `maven-inputs.txt`: A list of Maven dependenciy URLs that can be used by `nix/tools/maven/maven-inputs2nix.sh` to generate `maven-sources.nix`.

View File

@ -0,0 +1,43 @@
{ stdenv,
localMavenRepoBuilder, zip, unzip }:
let
mavenLocalRepo = (localMavenRepoBuilder "status-react-maven-deps" mavenSourceFiles).overrideDerivation (oldAttrs: {
# Add the zip and unzip tools that we'll use in the postCopy step
nativeBuildInputs = oldAttrs.nativeBuildInputs ++ (stdenv.lib.optionals stdenv.isLinux [ zip unzip ]);
});
mavenSourceFiles =
let
srcs = import ./maven-sources.nix { };
system = if stdenv.isDarwin then "osx" else "linux";
aapt2NativePkg = "https://dl.google.com/dl/android/maven2/com/android/tools/build/aapt2/3.4.1-5326820/aapt2-3.4.1-5326820-${system}";
in srcs // (if !stdenv.isLinux then { } else {
# On Linux, we need to patch the interpreter in Java packages that contain native executables to use Nix's interpreter instead
"${aapt2NativePkg}" = srcs."${aapt2NativePkg}" // {
postCopy = ''
[ -n "$NIX_CC" ] || exit 1 # We need an stdenv with a compiler
prevSet=$-
set -e
# Patch executables from maven dependency to use Nix's interpreter
tmpDir=$(mktemp -d)
unzip $depPath.jar -d $tmpDir
for exe in `find $tmpDir/ -type f -executable`; do
patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" $exe
done
# Rebuild the .jar file with patched binaries
pushd $tmpDir > /dev/null
chmod u+w $depPath.jar
zip -fr $depPath.jar
chmod $depPath.jar --reference=$depPath.jar.sha1
popd > /dev/null
rm -rf $tmpDir
set $prevSet
'';
};
});
in mavenLocalRepo

View File

@ -0,0 +1,194 @@
#!/usr/bin/env bash
set -Eeu
# This script takes care of generating/updating the maven-inputs.txt file.
# For this, we:
# 1. query the projects in the main gradle project
# 2. loop through each of the projects, querying its dependencies
# 3. add each one to maven-inputs.txt
GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)
current_dir=$(cd "${BASH_SOURCE%/*}" && pwd)
gradle_opts="--console plain"
tmp_pom_filename=$(mktemp --tmpdir fetch-maven-deps-XXXX.pom)
deps_file_path=$(mktemp --tmpdir fetch-maven-deps-XXXX-deps.txt)
function join_by { local IFS="$1"; shift; echo "$*"; }
mavenSources=(
https://dl.google.com/dl/android/maven2 \
https://jcenter.bintray.com \
https://repo.maven.apache.org/maven2 \
https://maven.fabric.io/public \
https://jitpack.io \
https://plugins.gradle.org/m2
)
mavenSourcesSedFilter=$(join_by '|' ${mavenSources[@]})
# Converts a URL to a Maven package ID (e.g. https://dl.google.com/dl/android/maven2/android/arch/core/common/1.0.0/common-1.0.0 -> android.arch.core:common:1.0.0)
function getPackageIdFromURL() {
local url="$1"
local path=$(echo $url | sed -E "s;($mavenSourcesSedFilter)/(.+);\2;")
IFS='/' read -ra tokens <<< "$path"
local groupLength=$(( ${#tokens[@]} - 3 ))
local groupId=''
for ((i=0;i<$groupLength;i++)); do
if [ $i -eq 0 ]; then
groupId=${tokens[i]}
else
groupId="${groupId}.${tokens[i]}"
fi
done
artifactId=${tokens[-3]}
version="${tokens[-2]}"
echo "$groupId:$artifactId:$version"
}
# Formats the components of a Maven package ID as a URL path component (e.g. android/arch/core/common/1.0.0/common-1.0.0)
function getPath() {
local tokens=("$@")
local groupId=${tokens[0]}
local artifactId=${tokens[1]}
local version=${tokens[2]}
groupId=$(echo $groupId | tr '.' '/')
echo "$groupId/$artifactId/$version/$artifactId-$version"
}
# Tries to download a POM to $tmp_pom_filename given a base URL (also checks for empty files)
function tryGetPOMFromURL() {
local url="$1"
rm -f $tmp_pom_filename
curl --output $tmp_pom_filename --silent --fail "$url.pom" && test -s $tmp_pom_filename
}
# Given the components of a package ID, will loop through known repositories to figure out a source for the package
function determineArtifactUrl() {
local tokens=("$@")
local groupId=${tokens[0]}
local artifactId=${tokens[1]}
local version=${tokens[2]}
local path=$(getPath "${tokens[@]}")
for mavenSourceUrl in ${mavenSources[@]}; do
if tryGetPOMFromURL "$mavenSourceUrl/$path"; then
if [ "$path" = "com/google/firebase/firebase-analytics/16.0.3/firebase-analytics-16.0.3" ]; then
# For some reason maven doesn't detect the correct version of firebase-analytics so we have to hardcode it
# TODO: See if we can get rid of this by upgrading to latest firebase
echo "$mavenSourceUrl/com/google/firebase/firebase-analytics/15.0.2/firebase-analytics-15.0.2"
fi
echo "$mavenSourceUrl/$path"
return
fi
done
}
# Executes a gradle dependencies command and returns the output package IDs
function runGradleDepsCommand() {
echo "Computing maven dependencies with \`gradle $1 $gradle_opts\`..." > /dev/stderr
# Add a comment header with the command we're running (useful for debugging)
echo "# $1"
# Run the gradle command and:
# - remove lines that end with (*) or (n)
# - keep only lines that start with \--- or +---
# - remove lines that refer to a project
# - extract the package name and version, ignoring version range indications, such as in `com.google.android.gms:play-services-ads:[15.0.1,16.0.0) -> 15.0.1`
gradle $1 $gradle_opts \
| grep --invert-match -E ".+ \([\*n]\)$" \
| grep -e "[\\\+]---" \
| grep --invert-match -e "--- project :" \
| sed -E "s;.*[\\\+]--- ([^ ]+:)(.+ -> )?([^ ]+).*$;\1\3;"
}
function retrieveAdditionalDependencies() {
# It is not enough to output the dependencies in deps, we must also ask maven to report
# the dependencies for each individual POM file. Instead of parsing the dependency tree itself though,
# we look at what packages maven downloads from the internet into the local repo,
# which avoids us having to do a deep search, and does not report duplicates
# tryGetPOMFromURL downloads the POM file into $tmp_pom_filename
local additional_deps=( $(mvn dependency:tree -B -Dmaven.repo.local=$mvn_tmp_repo -f "$1" 2>&1 \
| grep -E 'Downloaded from [^:]+: [^ ]+\.(pom|jar|aar)' \
| sed -E "s;^\[INFO\] Downloaded from [^:]+: ([^ ]+)\.(pom|jar|aar) .*$;\1;") )
for additional_dep_url in ${additional_deps[@]}; do
local additional_dep_id=$(getPackageIdFromURL $additional_dep_url)
# See if we already have this dependency in $deps
local alreadyExists=0
for _dep in ${deps[@]}; do
if [ "$additional_dep_id" = "$_dep" ]; then
alreadyExists=1
break
fi
done
[ $alreadyExists -eq 0 ] && echo "$additional_dep_url" || continue
done
}
mvn_tmp_repo=$(mktemp -d)
trap "rm -rf $mvn_tmp_repo $tmp_pom_filename $deps_file_path" ERR EXIT HUP INT
pushd $GIT_ROOT/android > /dev/null
projects=$(gradle projects $gradle_opts 2>&1 \
| grep "Project ':" \
| sed -E "s;^.--- Project '(\:[a-zA-Z0-9\-]+)';\1;")
echo -n > $deps_file_path
# TODO: try to limit unnecessary dependencies brought in by passing e.g. `--configuration releaseCompileClasspath` to the `gradle *:dependencies` command
runGradleDepsCommand 'buildEnvironment' >> $deps_file_path
for project in ${projects[@]}; do
runGradleDepsCommand "${project}:buildEnvironment" >> $deps_file_path
runGradleDepsCommand "${project}:dependencies" >> $deps_file_path
done
popd > /dev/null
# Read the deps file into memory, sorting and getting rid of comments, project names and duplicates
IFS=$'\n' deps=( $(cat $deps_file_path \
| grep --invert-match -E '^#.*$' \
| grep --invert-match -E '^[a-z]+$' \
| grep --invert-match -E '^:?[^:]+$' \
| sort -uV) )
unset IFS
rm -f $deps_file_path
lineCount=${#deps[@]}
currentLine=0
pstr="[=======================================================================]"
echo "Determining URLs for ${#deps[@]} packages..." > /dev/stderr
for dep in ${deps[@]}; do
currentLine=$(( $currentLine + 1 ))
pd=$(( $currentLine * 73 / $lineCount ))
printf "\r%3d.%1d%% %.${pd}s" $(( $currentLine * 100 / $lineCount )) $(( ($currentLine * 1000 / $lineCount) % 10 )) $pstr > /dev/stderr
[ -z "$dep" ] && continue
# Ignore own dependencies (e.g. status-im:status-go:v0.30.0-beta.0)
if [[ "$dep" == "status-im:"* ]]; then
echo "Ignoring $dep" > /dev/stderr
continue
fi
# Parse dependency ID into components (group ID, artifact ID, version)
IFS=':' read -ra tokens <<< "$dep"
groupId=${tokens[0]}
[ -z "$groupId" ] && continue
artifactId=${tokens[1]}
version=$(echo "${tokens[2]}" | cut -d'@' -f1)
artifactUrl=$(determineArtifactUrl $groupId $artifactId $version)
if [ -z "$artifactUrl" ]; then
# Some dependencies don't contain a normal format, so we ignore them (e.g. `com.squareup.okhttp:okhttp:{strictly`)
echo "Failed to determine source of $dep, ignoring..." > /dev/stderr
continue
fi
echo "$artifactUrl"
retrieveAdditionalDependencies $tmp_pom_filename
done

View File

@ -0,0 +1,26 @@
#!/usr/bin/env bash
#
# This script takes care of generating/updating the maven-sources.nix file
# representing the offline Maven repo containing the dependencies
# required to build the project
#
set -Eeu
. ~/.nix-profile/etc/profile.d/nix.sh
GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)
current_dir=$(cd "${BASH_SOURCE%/*}" && pwd)
inputs_file_path="${current_dir}/maven-inputs.txt"
output_nix_file_path="${current_dir}/maven-sources.nix"
inputs2nix=$(realpath --relative-to="${current_dir}" "${GIT_ROOT}/nix/tools/maven/maven-inputs2nix.sh")
echo "Regenerating Nix files, this process should take about 90 minutes"
nix-shell --run "set -Eeuo pipefail; LC_ALL=C ${current_dir}/fetch-maven-deps.sh | sort -u -o ${inputs_file_path}" \
--pure -A targets.mobile.android.generate-maven-and-npm-deps-shell --show-trace "${GIT_ROOT}/default.nix"
pushd ${current_dir}
${inputs2nix} ${inputs_file_path} > ${output_nix_file_path}
echo "Done"
popd

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,52 @@
{ stdenvNoCC, fetchurl, jsc-filename }:
let
# These versions should match node_modules/react-native/ReactAndroid/gradle.properties
react-native-deps-sources = [
rec {
name = "boost";
version = "1.63.0";
url = "https://github.com/react-native-community/boost-for-react-native/releases/download/v${version}-0/${name}_${builtins.replaceStrings ["."] ["_"] version}.tar.gz";
sha256 = "1hq5h6wzcr3sk1kccfk769d59swwxy1kvfhqd6p7786a1zsavdr6";
}
rec {
name = "double-conversion";
version = "1.1.6";
url = "https://github.com/google/${name}/archive/v${version}.tar.gz";
sha256 = "0ynnckpyyhpwisb976knk9gr8jklfwr9flic8xj5flc8iv6hm1bb";
}
rec {
name = "folly";
version = "2018.10.22.00";
url = "https://github.com/facebook/${name}/archive/v${version}.tar.gz";
sha256 = "08cxc8hw34vnyyq45d04spy4dilrgqrv374lwxhg3sx60ww640y4";
}
rec {
name = "glog";
url = "https://github.com/google/${name}/archive/v0.3.5.tar.gz";
sha256 = "1q6ihk2asbx95a56kmyqwysq1x3grrw9jwqllafaidf0l84f903m";
}
];
in stdenvNoCC.mkDerivation {
name = "reactnative-android-native-deps";
srcs = builtins.map (d: (fetchurl { inherit (d) url sha256; })) react-native-deps-sources;
jsc = fetchurl {
url = "https://registry.npmjs.org/jsc-android/-/${jsc-filename}.tgz";
sha256 = "1s1fzmvpvdblzca7p2ifcysvd9na4jrsikaccqmfpgvkqjalfccp";
};
phases = [ "unpackPhase" ];
unpackPhase = ''
# Unpack all source archives.
mkdir -p $out/deps
cd $out/deps
for i in $srcs; do
unpackFile "$i"
done
cp $jsc $out/deps/${jsc-filename}.tar.gz # do the work of downloadJSC
cd ..
export sourceRoot=$out/deps
echo $sourceRoot
'';
}

View File

@ -0,0 +1,20 @@
{ mkShell, curl, git, gradle, maven,
projectNodePackage, androidEnvShellHook, status-go }:
mkShell {
buildInputs = [
curl
git
gradle
maven
projectNodePackage
];
shellHook =
androidEnvShellHook +
status-go.shellHook + ''
rm -rf ./node_modules
cp -a ${projectNodePackage}/node_modules/. ./node_modules/
chmod -R u+w ./node_modules/
'';
}

View File

@ -0,0 +1,122 @@
{ stdenv, stdenvNoCC, lib, target-os, callPackage,
mkFilter, bash, file, gnumake, watchman, gradle, androidEnvShellHook, mavenAndNpmDeps, nodejs, openjdk, prod-build, status-go, zlib }:
{ build-number ? "9999",
build-type ? "nightly", # Build type (e.g. nightly, release, e2e). Default is to use .env.nightly file
gradle-opts ? "",
keystore-file ? "", # Path to the .keystore file used to sign the package
secrets-file ? "", # Path to the file containing secret environment variables
env ? {} # Attribute set contaning environment variables to expose to the build script
}:
let
name = "release-${target-os}";
gradleHome = "$NIX_BUILD_TOP/.gradle";
localMavenRepo = "${mavenAndNpmDeps.deriv}/.m2/repository";
sourceProjectDir = "${mavenAndNpmDeps.deriv}/project";
envFileName =
if (build-type == "release" || build-type == "nightly" || build-type == "e2e") then ".env.${build-type}" else
if build-type != "" then ".env.jenkins" else ".env";
buildType' = if (build-type == "release" || build-type == "nightly") then "release" else "pr";
generatedApkPath = "android/app/build/outputs/apk/${buildType'}/app-${buildType'}.apk";
outApkName = "app.apk";
in stdenv.mkDerivation {
inherit name;
src =
let path = ./../../../..;
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-${name}-source";
filter =
# Keep this filter as restrictive as possible in order to avoid unnecessary rebuilds and limit closure size
mkFilter {
dirRootsToInclude = [
"mobile_files"
"modules/react-native-status"
"packager"
"resources"
];
dirsToExclude = [ ".git" ".svn" "CVS" ".hg" ".gradle" "build" "intermediates" "libs" "obj" ];
filesToInclude = [ envFileName "STATUS_GO_VERSION" "VERSION" ];
root = path;
};
};
nativeBuildInputs = [ bash gradle ] ++ lib.optionals stdenv.isDarwin [ file gnumake watchman ];
buildInputs = [ nodejs openjdk ];
phases = [ "unpackPhase" "patchPhase" "buildPhase" "installPhase" ];
postUnpack = ''
mkdir -p ${gradleHome}
${if keystore-file != "" then "cp -a --no-preserve=ownership ${keystore-file} ${gradleHome}/; export STATUS_RELEASE_STORE_FILE=${gradleHome}/$(basename ${keystore-file})" else ""}
# Ensure we have the right .env file
cp -f $sourceRoot/${envFileName} $sourceRoot/.env
# Copy index.*.js input file
cp -a --no-preserve=ownership ${prod-build}/index*.js $sourceRoot/
# Copy android/ directory
cp -a --no-preserve=ownership ${sourceProjectDir}/android/ $sourceRoot/
chmod u+w $sourceRoot/android
chmod u+w $sourceRoot/android/app
chmod -R u+w $sourceRoot/android/.gradle
mkdir $sourceRoot/android/build && chmod -R u+w $sourceRoot/android/build
# Copy node_modules/ directory
cp -a --no-preserve=ownership ${sourceProjectDir}/node_modules/ $sourceRoot/
# Make android/build directories writable under node_modules
chmod -R u+w $sourceRoot/node_modules/react-native/
for d in `ls $sourceRoot/node_modules/react-native-*/android/build -d1`; do
chmod -R u+w $d
done
for d in `ls $sourceRoot/node_modules/react-native-*/android -d1`; do
chmod u+w $d
done
chmod u+w $sourceRoot/node_modules/realm/android
'';
patchPhase = ''
prevSet=$-
set -e
substituteInPlace android/gradlew \
--replace 'exec gradle' "exec gradle -S -Dmaven.repo.local='${localMavenRepo}' --offline ${gradle-opts}"
substituteInPlace android/gradle.properties \
--replace 'versionCode=9999' 'versionCode=${build-number}'
# OPTIONAL: There's no need to forward debug ports for a release build, just disable it
substituteInPlace node_modules/realm/android/build.gradle \
--replace 'compileTask.dependsOn forwardDebugPort' 'compileTask'
set $prevSet
'';
buildPhase =
let
inherit (lib) catAttrs concatStrings concatStringsSep mapAttrsToList makeLibraryPath optionalString substring toUpper;
# Take the env attribute set and build a couple of scripts
# (one to export the environment variables, and another to unset them)
exportEnvVars = concatStringsSep ";" (mapAttrsToList (name: value: "export ${name}='${value}'") env);
unsetEnvVars = concatStringsSep ";" (mapAttrsToList (name: value: "unset ${name}") env);
adhocEnvVars = optionalString stdenv.isLinux "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${makeLibraryPath [ zlib ]}";
capitalizedBuildType = toUpper (substring 0 1 buildType') + substring 1 (-1) buildType';
in ''
export STATUS_REACT_HOME=$PWD
export HOME=$NIX_BUILD_TOP
${exportEnvVars}
${if secrets-file != "" then "source ${secrets-file}" else ""}
${androidEnvShellHook}
${concatStrings (catAttrs "shellHook" [ mavenAndNpmDeps status-go ])}
pushd android
${adhocEnvVars} gradle assemble${capitalizedBuildType} -S -Dmaven.repo.local='${localMavenRepo}' --offline ${gradle-opts} || exit
popd > /dev/null
${unsetEnvVars}
'';
installPhase = ''
mkdir -p $out
cp ${generatedApkPath} $out/${outApkName}
'';
}

View File

@ -1,27 +1,38 @@
{ config, stdenv, pkgs, callPackage, target-os,
gradle, status-go, composeXcodeWrapper, nodejs }:
with stdenv;
{ config, stdenv, pkgs, callPackage, mkShell, fetchurl, fetchFromGitHub, target-os,
mkFilter, localMavenRepoBuilder, maven, status-go, composeXcodeWrapper, nodejs, yarn, prod-build-fn }:
let
inherit (stdenv.lib) catAttrs concatStrings optional unique;
platform = callPackage ../platform.nix { inherit target-os; };
xcodewrapperArgs = {
version = "10.2.1";
};
xcodeWrapper = composeXcodeWrapper xcodewrapperArgs;
androidPlatform = callPackage ./android.nix { inherit config gradle; };
selectedSources =
[ status-go ] ++
lib.optional platform.targetAndroid androidPlatform;
androidPlatform = callPackage ./android { inherit config target-os mkShell mkFilter nodejs maven localMavenRepoBuilder projectNodePackage prod-build-fn; status-go = status-go.android; };
iosPlatform = callPackage ./ios { inherit config mkFilter mkShell xcodeWrapper projectNodePackage; status-go = status-go.ios; };
fastlane = callPackage ./fastlane { inherit stdenv target-os mkShell; };
selectedSources = [
fastlane
status-go.android
status-go.ios
] ++
optional platform.targetAndroid androidPlatform ++
optional platform.targetIOS iosPlatform;
in
{
inherit (androidPlatform) androidComposition;
inherit xcodewrapperArgs;
projectNodePackage = callPackage ./node-package.nix { inherit pkgs nodejs yarn; };
buildInputs =
status-go.buildInputs ++
lib.catAttrs "buildInputs" selectedSources ++
lib.optional (platform.targetIOS && isDarwin) xcodeWrapper;
shellHook = lib.concatStrings (lib.catAttrs "shellHook" selectedSources);
}
# TARGETS
prod-build = prod-build-fn { inherit projectNodePackage; };
in {
buildInputs = unique (catAttrs "buildInputs" selectedSources);
shellHook = concatStrings (catAttrs "shellHook" selectedSources);
# CHILD DERIVATIONS
android = androidPlatform;
ios = iosPlatform;
# TARGETS
inherit prod-build fastlane;
}

View File

@ -0,0 +1,26 @@
{ stdenv, target-os, callPackage, mkShell, makeWrapper,
bundlerEnv, bundler, ruby, curl }:
let
platform = callPackage ../../platform.nix { inherit target-os; };
useFastlanePkg = platform.targetAndroid && !stdenv.isDarwin;
fastlane = callPackage ../../../fastlane {
bundlerEnv = _: bundlerEnv {
name = "fastlane-gems";
gemdir = ../../../fastlane;
};
};
buildInputs = if useFastlanePkg then [ fastlane curl ] else stdenv.lib.optionals platform.targetMobile [ bundler ruby ]; # bundler/ruby used for fastlane on macOS
shellHook = stdenv.lib.optionalString useFastlanePkg fastlane.shellHook;
# TARGETS
shell = mkShell {
inherit buildInputs shellHook;
};
in {
inherit buildInputs shellHook;
# TARGETS
inherit shell;
}

View File

@ -0,0 +1,53 @@
{ config, stdenv, stdenvNoCC, callPackage, mkShell,
xcodeWrapper, mkFilter, fetchurl, nodejs, bash, zlib, procps,
status-go, projectNodePackage }:
let
inherit (stdenv.lib) catAttrs concatStrings unique;
createMobileFilesSymlinks = root: ''
# Set up symlinks to mobile enviroment in project 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
'';
src =
let path = ./../../..;
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-npm-deps-source";
filter =
# Keep this filter as restrictive as possible in order to avoid unnecessary rebuilds and limit closure size
mkFilter {
dirRootsToInclude = [ "mobile_files" ];
dirsToExclude = [ ".git" ".svn" "CVS" ".hg" ];
filesToInclude = [ ".babelrc" ];
root = path;
};
};
selectedSources = [ status-go ];
# TARGETS
shell = mkShell {
buildInputs = [ xcodeWrapper ];
};
in {
inherit xcodeWrapper;
buildInputs = unique ([ xcodeWrapper procps ] ++ catAttrs "buildInputs" selectedSources);
shellHook = ''
${status-go.shellHook}
${createMobileFilesSymlinks "$STATUS_REACT_HOME"}
$STATUS_REACT_HOME/nix/mobile/reset-node_modules.sh "${projectNodePackage}" && \
$STATUS_REACT_HOME/nix/mobile/ios/install-pods-and-status-go.sh || \
exit
'';
# TARGETS
inherit shell;
}

View File

@ -0,0 +1,30 @@
#!/usr/bin/env bash
set -e
if [ -z "$RCTSTATUS_FILEPATH" ]; then
echo "RCTSTATUS_FILEPATH is not defined! Aborting."
exit 1
fi
RCTSTATUS_DIR="$STATUS_REACT_HOME/modules/react-native-status/ios/RCTStatus"
targetBasename='Statusgo.framework'
# Compare target folder with source to see if copying is required
if [ -d "$RCTSTATUS_DIR/$targetBasename" ] && \
diff -q --no-dereference --recursive $RCTSTATUS_DIR/$targetBasename/ $RCTSTATUS_FILEPATH/ > /dev/null; then
echo "$RCTSTATUS_DIR/$targetBasename already in place"
else
sourceBasename="$(basename $RCTSTATUS_FILEPATH)"
echo "Copying $sourceBasename from Nix store to $RCTSTATUS_DIR"
rm -rf "$RCTSTATUS_DIR/$targetBasename/"
cp -a $RCTSTATUS_FILEPATH $RCTSTATUS_DIR && chmod -R 755 "$RCTSTATUS_DIR/$targetBasename"
if [ "$sourceBasename" != "$targetBasename" ]; then
mv "$RCTSTATUS_DIR/$sourceBasename" "$RCTSTATUS_DIR/$targetBasename"
fi
if [ "$(uname)" == 'Darwin' ]; then
# CocoaPods are trash and can't handle other pod instances running at the same time
$STATUS_REACT_HOME/scripts/wait-for.sh pod 240
pushd $STATUS_REACT_HOME/ios && pod install; popd
fi
fi

View File

@ -1,21 +0,0 @@
{ config, stdenv, androidComposition }:
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"
'';
}

View File

@ -0,0 +1,44 @@
{ fetchFromGitHub, pkgs, nodejs, yarn }:
let
yarn2nix = import (fetchFromGitHub {
name = "yarn2nix-source";
owner = "moretea";
repo = "yarn2nix";
rev = "3cc020e384ce2a439813adb7a0cc772a034d90bb";
sha256 = "0h2kzdfiw43rbiiffpqq9lkhvdv8mgzz2w29pzrxgv8d39x67vr9";
}) { inherit pkgs nodejs yarn; };
# Create a yarn package for our project that contains all the dependecies, so that we have a
# known good node_modules folder that we can use later on
projectNodePackage = yarn2nix.mkYarnModules rec {
name = "${pname}-${version}";
pname = "StatusIm";
version = "0.0.1";
packageJSON = ../../mobile_files/package.json.orig;
yarnLock = ../../mobile_files/yarn.lock;
# Replace symlink to deps with copy of real dependencies
postBuild = ''
# Fixup symlinks in folder we'll be moving.
# Basically transform a symlink pointing to ../../../../../../a into ../../../../a
symlinks=( $(find $out/deps/${pname}/node_modules/ -lname '../../../../../..*') )
for sl in ''${symlinks[@]}; do
newTarget=$(readlink "$sl" | sed -E "s|(\.\./){2}(.*)|\2|")
ln -snf "$newTarget" "$sl"
done
unset sl
unset symlinks
# Merge deps with node_modules
cp -R --no-clobber $out/deps/${pname}/node_modules/. $out/node_modules/
# Get rid of deps
rm -rf $out/deps/
# Get rid of symlink to deps
rm $out/node_modules/${pname}
# Ensure the we copied expected dependencies from $out/deps
[ -d $out/node_modules/react-native-fs ] || exit 1
'';
};
in projectNodePackage

View File

@ -0,0 +1,71 @@
#!/usr/bin/env bash
#
# Check if we need to copy node_modules (e.g. in case it has been modified after last copy)
#
# The reasoning for a (mostly) read-only node_modules folder:
# ideally wed symlink the folder directly to the Nix store
# so that were guaranteed to have a reproducible source.
# Unfortunately react-native wants to build some stuff after the fact
# and this is incompatible with the concept of a pure Nix package.
# Therefore we copy the whole source to the repo directory,
# allow writing only on the folders where it is absolutely required,
# and therefore we still keep some peace of mind that the rest
# of node_modules is unchanged the rest of the time.
#
set -Eeuo pipefail
deps="$1"
[ -d $deps ] || exit 1
nodeModulesDir="$STATUS_REACT_HOME/node_modules"
needCopyModules=1
# Check if node_modules exists and is valid
if [ -d "$nodeModulesDir" ]; then
if [ -f "$nodeModulesDir/.copied~" ]; then
echo "Checking for modifications in node_modules..."
modifiedFiles=( $(find $nodeModulesDir -writable -type f -newer $nodeModulesDir/.copied~ -not \( -path "$nodeModulesDir/react-native/third-party/*" -prune -o -path './resources/icons/*' -prune \) -print) )
if [ ${#modifiedFiles[@]} -eq 0 ]; then
needCopyModules=0
echo "No modifications detected."
else
echo "Modifications detected in ${#modifiedFiles[@]} files:\n${modifiedFiles[@]}"
fi
fi
if [ $needCopyModules -eq 1 ]; then
chmod u+w -R $nodeModulesDir
rm -rf $nodeModulesDir
fi
fi
# Replace node_modules if necessary
if [ ! -d "$nodeModulesDir" ]; then
if [ -n "${IN_CI_ENVIRONMENT:-''}" ]; then
# CI jobs might run multiple tasks in parallel, so it is possible that another process is setting up node_modules. In that case, let's wait up to 10 seconds for the .tmp dir goes away
for i in {1..10}; do
if [ -d "$nodeModulesDir.tmp" ]; then
echo "$nodeModulesDir.tmp exists, another process is probably setting up node_modules, waiting for 1 second..."
sleep 1
else
break
fi
done
fi
if [ -d "$nodeModulesDir.tmp" ]; then
echo "$nodeModulesDir.tmp already exists, another shell session is probably currently setting up node_modules. Please try again in a few moments."
ls -al $STATUS_REACT_HOME
exit 1
elif [ ! -d "$nodeModulesDir" ]; then
echo "Copying node_modules from Nix store (${deps}/node_modules)..."
trap "[ -d \"$nodeModulesDir.tmp\" ] && chmod -R u+w \"$nodeModulesDir.tmp\" && rm -rf \"$nodeModulesDir.tmp\"" ERR INT HUP
time cp -HRf --preserve=all ${deps}/node_modules/. "$nodeModulesDir.tmp"
chmod -R u+w "$nodeModulesDir.tmp"
mv -f "$nodeModulesDir.tmp" $nodeModulesDir
touch $nodeModulesDir/.copied~
trap - ERR INT HUP
echo "Done"
fi
fi

View File

@ -1,10 +1,10 @@
{ target-os, stdenv }:
with stdenv;
assert lib.assertOneOf "target-os" target-os [ "linux" "android" "windows" "macos" "darwin" "ios" "all" ];
assert stdenv.lib.assertOneOf "target-os" target-os [ "linux" "android" "windows" "macos" "darwin" "ios" "all" ];
let
inherit (stdenv) isDarwin isLinux;
# based on the value passed in through target-os, check if we're targetting a desktop platform
targetDesktop = {
"linux" = true;

View File

@ -2,6 +2,12 @@
#
# This script is used by the Makefile to have an implicit nix-shell.
# The following environment variables modify the script behavior:
# - TARGET_OS: This attribute is passed as `target-os` to Nix, limiting the scope
# of the Nix expressions.
# - _NIX_ATTR: This attribute can be used to specify an attribute set
# from inside the expression in `default.nix`, allowing drilling down into a specific attribute.
# - _NIX_KEEP: This variable allows specifying which env vars to keep for Nix pure shell.
#
GREEN='\033[0;32m'
@ -23,13 +29,23 @@ fi
if command -v "nix" >/dev/null 2>&1; then
platform=${TARGET_OS:=all}
if [ "$platform" != 'all' ]; then
if [ "$platform" != 'all' ] && [ "$platform" != 'android' ] && [ "$platform" != 'ios' ]; then
# This is a dirty workaround to the fact that 'yarn install' is an impure operation, so we need to call it from an impure shell. Hopefull we'll be able to fix this later on with something like yarn2nix
nix-shell --show-trace --argstr target-os ${TARGET_OS} --run "scripts/prepare-for-platform.sh $platform" || exit
nix-shell --show-trace --argstr target-os ${TARGET_OS} --run "scripts/prepare-for-desktop-platform.sh" || exit
fi
entry_point='shell.nix'
attrset_option=''
if [ -n "${_NIX_ATTR}" ]; then
entry_point='default.nix'
attrset_option="-A ${_NIX_ATTR}"
fi
attrStr="${_NIX_ATTR}"
[ -n "$attrStr" ] && attrStr="$attrStr "
if [[ $@ == "ENTER_NIX_SHELL" ]]; then
echo -e "${GREEN}Configuring Nix shell for target '${TARGET_OS}'...${NC}"
exec nix-shell --show-trace --argstr target-os ${TARGET_OS}
echo -e "${GREEN}Configuring ${attrStr}Nix shell for target '${TARGET_OS}'...${NC}"
exec nix-shell --show-trace --argstr target-os ${TARGET_OS} ${attrset_option} ${entry_point}
else
is_pure=''
if [[ "${TARGET_OS}" != 'all' ]] && [[ "${TARGET_OS}" != 'ios' ]] && [[ "${TARGET_OS}" != 'windows' ]]; then
@ -39,10 +55,10 @@ if command -v "nix" >/dev/null 2>&1; then
# This variable allows specifying which env vars to keep for Nix pure shell
# The separator is a semicolon
keep_opts=''
if [[ -n "${NIX_KEEP}" ]]; then
keep_opts="--keep ${NIX_KEEP//;/ --keep }"
if [[ -n "${_NIX_KEEP}" ]]; then
keep_opts="--keep ${_NIX_KEEP//;/ --keep }"
fi
echo -e "${GREEN}Configuring ${pure_desc}Nix shell for target '${TARGET_OS}'...${NC}"
exec nix-shell ${is_pure} ${keep_opts} --show-trace --argstr target-os ${TARGET_OS} --run "$@"
echo -e "${GREEN}Configuring ${pure_desc}${attrStr}Nix shell for target '${TARGET_OS}'...${NC}"
exec nix-shell ${is_pure} ${keep_opts} --show-trace --argstr target-os ${TARGET_OS} ${attrset_option} --run "$@" ${entry_point}
fi
fi

View File

@ -9,8 +9,6 @@
outputFileName,
hostSystem } @ args':
with stdenv;
let
buildStatusGo = callPackage ./build-status-go.nix { inherit buildGoPackage go xcodeWrapper utils; };
@ -35,7 +33,7 @@ let
outputs = [ "out" ];
meta = {
platforms = with lib.platforms; linux ++ darwin;
platforms = with stdenv.lib.platforms; linux ++ darwin;
};
});

View File

@ -8,15 +8,15 @@
goBuildFlags, goBuildLdFlags,
config } @ args':
with stdenv;
let
inherit (stdenv.lib) concatStringsSep makeBinPath optional;
targetConfig = config;
buildStatusGo = callPackage ./build-status-go.nix { inherit buildGoPackage go xcodeWrapper utils; };
args = removeAttrs args' [ "config" "goBuildFlags" "goBuildLdFlags" ]; # Remove mobile-only arguments from args
buildStatusGoMobileLib = buildStatusGo (args // {
nativeBuildInputs = [ gomobile ] ++ lib.optional (targetConfig.name == "android") openjdk;
nativeBuildInputs = [ gomobile ] ++ optional (targetConfig.name == "android") openjdk;
buildMessage = "Building mobile library for ${targetConfig.name}";
# Build mobile libraries
@ -24,10 +24,10 @@ let
mkdir $NIX_BUILD_TOP/go-build
GOPATH=${gomobile.dev}:$GOPATH \
PATH=${lib.makeBinPath [ gomobile.bin ]}:$PATH \
${lib.concatStringsSep " " targetConfig.envVars} \
PATH=${makeBinPath [ gomobile.bin ]}:$PATH \
${concatStringsSep " " targetConfig.envVars} \
NIX_GOWORKDIR=$NIX_BUILD_TOP/go-build \
gomobile bind ${goBuildFlags} -target=${targetConfig.name} ${lib.concatStringsSep " " targetConfig.gomobileExtraFlags} \
gomobile bind ${goBuildFlags} -target=${targetConfig.name} ${concatStringsSep " " targetConfig.gomobileExtraFlags} \
-o ${targetConfig.outputFileName} \
${goBuildLdFlags} \
${goPackagePath}/mobile
@ -43,7 +43,7 @@ let
outputs = [ "out" ];
meta = {
platforms = with lib.platforms; linux ++ darwin;
platforms = with stdenv.lib.platforms; linux ++ darwin;
};
});

View File

@ -1,17 +1,16 @@
{ target-os, stdenv, callPackage,
buildGoPackage, go, fetchFromGitHub, openjdk,
androidPkgs, composeXcodeWrapper, xcodewrapperArgs ? {} }:
with stdenv;
androidPkgs, xcodeWrapper }:
let
inherit (stdenv.lib) catAttrs concatStrings fileContents last makeBinPath optional optionalString splitString;
platform = callPackage ../platform.nix { inherit target-os; };
utils = callPackage ../utils.nix { inherit xcodeWrapper; };
gomobile = callPackage ./gomobile { inherit (androidPkgs) platform-tools; inherit target-os composeXcodeWrapper xcodewrapperArgs utils buildGoPackage; };
gomobile = callPackage ./gomobile { inherit (androidPkgs) platform-tools; inherit target-os xcodeWrapper utils buildGoPackage; };
buildStatusGoDesktopLib = callPackage ./build-desktop-status-go.nix { inherit buildGoPackage go xcodeWrapper utils; };
buildStatusGoMobileLib = callPackage ./build-mobile-status-go.nix { inherit buildGoPackage go gomobile xcodeWrapper utils; };
extractStatusGoConfig = f: lib.last (lib.splitString "\n" (lib.fileContents f));
owner = lib.fileContents ../../STATUS_GO_OWNER;
extractStatusGoConfig = f: last (splitString "\n" (fileContents f));
owner = fileContents ../../STATUS_GO_OWNER;
version = extractStatusGoConfig ../../STATUS_GO_VERSION; # TODO: Simplify this path search with lib.locateDominatingFile
sha256 = extractStatusGoConfig ../../STATUS_GO_SHA256;
repo = "status-go";
@ -26,7 +25,7 @@ let
envVars = [
"ANDROID_HOME=${androidPkgs.androidsdk}/libexec/android-sdk"
"ANDROID_NDK_HOME=${androidPkgs.ndk-bundle}/libexec/android-sdk/ndk-bundle"
"PATH=${lib.makeBinPath [ openjdk ]}:$PATH"
"PATH=${makeBinPath [ openjdk ]}:$PATH"
];
gomobileExtraFlags = [];
};
@ -47,19 +46,17 @@ let
allTargets = [ status-go-packages.desktop status-go-packages.android ];
};
};
currentHostConfig = if isDarwin then hostConfigs.darwin else hostConfigs.linux;
currentHostConfig = if stdenv.isDarwin then hostConfigs.darwin else hostConfigs.linux;
goBuildFlags = "-v";
# TODO: Manage to pass "-s -w" to -ldflags. Seems to only accept a single flag
goBuildLdFlags = "-ldflags=-s";
xcodeWrapper = composeXcodeWrapper xcodewrapperArgs;
statusGoArgs = { inherit owner repo rev version goPackagePath src goBuildFlags goBuildLdFlags; };
status-go-packages = {
desktop = buildStatusGoDesktopLib (statusGoArgs // {
outputFileName = "libstatus.a";
hostSystem = hostPlatform.system;
hostSystem = stdenv.hostPlatform.system;
host = currentHostConfig.name;
});
@ -74,27 +71,42 @@ let
});
};
buildInputs = if target-os == "android" then [ status-go-packages.android ] else
if target-os == "ios" then [ status-go-packages.ios ] else
buildInputs = if target-os == "android" then android.buildInputs else
if target-os == "ios" then ios.buildInputs else
if target-os == "all" then currentHostConfig.allTargets else
if platform.targetDesktop then [ status-go-packages.desktop ] else
if platform.targetDesktop then desktop.buildInputs else
throw "Unexpected target platform ${target-os}";
android = {
buildInputs = optional platform.targetAndroid [ status-go-packages.android ];
shellHook =
optionalString platform.targetAndroid ''
# These variables are used by the Status Android Gradle build script in android/build.gradle
export STATUS_GO_ANDROID_LIBDIR=${status-go-packages.android}/lib
'';
};
ios = {
buildInputs = optional platform.targetIOS [ status-go-packages.ios ];
shellHook =
optionalString platform.targetIOS ''
# These variables are used by the iOS build preparation section in nix/mobile/ios/default.nix
export RCTSTATUS_FILEPATH=${status-go-packages.ios}/lib/Statusgo.framework
'';
};
desktop = {
buildInputs = optional platform.targetDesktop [ status-go-packages.desktop ];
shellHook =
optionalString platform.targetDesktop ''
# These variables are used by the Status Desktop CMake build script in modules/react-native-status/desktop/CMakeLists.txt
export STATUS_GO_DESKTOP_INCLUDEDIR=${status-go-packages.desktop}/include
export STATUS_GO_DESKTOP_LIBDIR=${status-go-packages.desktop}/lib
'';
};
platforms = [ android ios desktop ];
in {
inherit buildInputs;
shellHook = concatStrings (catAttrs "shellHook" platforms);
shellHook =
lib.optionalString platform.targetIOS ''
# These variables are used by the iOS build preparation section in scripts/prepare-for-platform.sh
export RCTSTATUS_FILEPATH=${status-go-packages.ios}/lib/Statusgo.framework
'' +
lib.optionalString platform.targetAndroid ''
# These variables are used by the Status Android Gradle build script in android/build.gradle
export STATUS_GO_ANDROID_LIBDIR=${status-go-packages.android}/lib
'' +
lib.optionalString platform.targetDesktop ''
# These variables are used by the Status Desktop CMake build script in modules/react-native-status/desktop/CMakeLists.txt
export STATUS_GO_DESKTOP_INCLUDEDIR=${status-go-packages.desktop}/include
export STATUS_GO_DESKTOP_LIBDIR=${status-go-packages.desktop}/lib
'';
# CHILD DERIVATIONS
inherit android ios desktop;
}

View File

@ -1,17 +1,17 @@
{ stdenv, target-os, callPackage, utils, fetchgit,
buildGoPackage, glibc, ncurses5, zlib, makeWrapper, patchelf,
platform-tools, composeXcodeWrapper, xcodewrapperArgs ? {}
platform-tools, xcodeWrapper
}:
with stdenv;
let
xcodeWrapper = composeXcodeWrapper xcodewrapperArgs;
inherit (stdenv) isDarwin;
inherit (stdenv.lib) optional optionalString strings;
platform = callPackage ../../platform.nix { inherit target-os; };
in buildGoPackage rec {
name = "gomobile-${version}";
version = "20190319-${lib.strings.substring 0 7 rev}";
version = "20190319-${strings.substring 0 7 rev}";
rev = "167ebed0ec6dd457a6b24a4f61db913f0af11f70";
sha256 = "0lspdhikhnhbwv8v0q6fs3a0pd9sjnhkpg8z03m2dc5h6f84m38w";
@ -19,16 +19,16 @@ in buildGoPackage rec {
subPackages = [ "bind" "cmd/gobind" "cmd/gomobile" ];
buildInputs = [ makeWrapper ]
++ lib.optional isDarwin xcodeWrapper;
++ optional isDarwin xcodeWrapper;
# Ensure XCode and the iPhone SDK are present, instead of failing at the end of the build
preConfigure = lib.optionalString isDarwin utils.enforceiPhoneSDKAvailable;
preConfigure = optionalString isDarwin utils.enforceiPhoneSDKAvailable;
patches = [ ./ndk-search-path.patch ./resolve-nix-android-sdk.patch ]
++ lib.optional isDarwin ./ignore-nullability-error-on-ios.patch;
++ optional isDarwin ./ignore-nullability-error-on-ios.patch;
postPatch =
lib.optionalString platform.targetAndroid ''
optionalString platform.targetAndroid ''
substituteInPlace cmd/gomobile/install.go --replace "\`adb\`" "\`${platform-tools}/bin/adb\`"
'' + ''
WORK=$NIX_BUILD_TOP/gomobile-work
@ -52,17 +52,20 @@ in buildGoPackage rec {
rm -rf $WORK
'';
postInstall = ''
postInstall =
let
inherit (stdenv.lib) makeBinPath makeLibraryPath;
in ''
mkdir -p $out $bin/lib
ln -s ${ncurses5}/lib/libncursesw.so.5 $bin/lib/libtinfo.so.5
'' + (if isDarwin then ''
wrapProgram $bin/bin/gomobile \
--prefix "PATH" : "${lib.makeBinPath [ xcodeWrapper ]}" \
--prefix "LD_LIBRARY_PATH" : "${lib.makeLibraryPath [ ncurses5 zlib ]}:$bin/lib"
--prefix "PATH" : "${makeBinPath [ xcodeWrapper ]}" \
--prefix "LD_LIBRARY_PATH" : "${makeLibraryPath [ ncurses5 zlib ]}:$bin/lib"
'' else ''
wrapProgram $bin/bin/gomobile \
--prefix "LD_LIBRARY_PATH" : "${lib.makeLibraryPath [ ncurses5 zlib ]}:$bin/lib"
--prefix "LD_LIBRARY_PATH" : "${makeLibraryPath [ ncurses5 zlib ]}:$bin/lib"
'') + ''
$bin/bin/gomobile init
'';
@ -74,12 +77,12 @@ in buildGoPackage rec {
outputs = [ "bin" "dev" "out" ];
meta = {
meta = with stdenv.lib; {
description = "A tool for building and running mobile apps written in Go.";
longDescription = "Gomobile is a tool for building and running mobile apps written in Go.";
homepage = https://go.googlesource.com/mobile;
license = lib.licenses.bsdOriginal;
maintainers = with lib.maintainers; [ sheenobu pombeirp ];
platforms = with lib.platforms; linux ++ darwin;
license = licenses.bsdOriginal;
maintainers = with maintainers; [ sheenobu pombeirp ];
platforms = with platforms; linux ++ darwin;
};
}

View File

@ -0,0 +1,66 @@
#
# This Nix expression builds an index.*.js file for the current repository given a node modules Nix expression
#
{ stdenv, stdenvNoCC, lib, target-os, callPackage, pkgs,
mkFilter, clojure, leiningen, maven, nodejs, localMavenRepoBuilder }:
# The Nix expression takes a second argument to specify the node dependencies
{ projectNodePackage }:
let
lein-command = if target-os == "all" then "lein prod-build" else "lein prod-build-${target-os}";
lein-project-deps = import ../lein/lein-project-deps.nix { };
leinProjectDepsLocalRepo = localMavenRepoBuilder "lein-project-deps" lein-project-deps;
in stdenv.mkDerivation {
name = "prod-build-${target-os}";
src =
let path = ./../..;
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-prod-build-source";
filter =
# Keep this filter as restrictive as possible in order to avoid unnecessary rebuilds and limit closure size
mkFilter {
dirRootsToInclude = [
"components/src" "react-native/src/cljsjs" "react-native/src/mobile" "src" "env/prod" "prod" # Taken from project.clj :profiles :prod :cljsbuild :builds :android :source-paths
"resources" "status-modules/cljs" "status-modules/resources"
];
dirsToExclude = [ ".git" ".svn" "CVS" ".hg" ".gradle" "build" "intermediates" "libs" "obj" ];
filesToInclude = [ "build.clj" "externs.js" "project.clj" "prepare-modules.js" ];
root = path;
};
};
buildInputs = [ clojure leiningen nodejs ];
LEIN_OFFLINE = "y";
phases = [ "unpackPhase" "patchPhase" "buildPhase" "installPhase" ];
patchPhase =
let anchor = '':url "https://github.com/status-im/status-react/"'';
in ''
substituteInPlace project.clj \
--replace '${anchor}' \
'${anchor}
:local-repo "${leinProjectDepsLocalRepo}"' \
--replace '[rasom/lein-githooks "' ';; [rasom/lein-githooks "' \
--replace ':githooks' ';; :githooks' \
--replace ':pre-commit' ';; :pre-commit'
'';
buildPhase = ''
ln -s ${projectNodePackage}/node_modules
# On macOS, lein tries to create $HOME/.lein, which fails with java.lang.Exception: Couldn't create directories: /homeless-shelter/.lein, so we just make it use a temp dir
tmp=$(mktemp -d)
HOME=$tmp ${lein-command}
rm -rf $tmp
unset tmp
node prepare-modules.js
'';
installPhase = ''
mkdir -p $out
cp index.*.js $out/
'';
}

View File

@ -0,0 +1,32 @@
#!/usr/bin/env bash
set -Eeu
# This script computes the required Maven dependencies required by cljsbuild for this project
# and outputs them as a text file, where each line represents a URL to a Maven dependency
# (minus the extension).
# For this, we start with a clean cache (in a temporary directory) and call cljsbuild
# to cause it to download all the artifacts.
GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)
_current_dir=$(cd "${BASH_SOURCE%/*}" && pwd)
_project_file_name='project.clj'
_lein_cmd='lein with-profile prod cljsbuild once'
_repo_path=$(mktemp -d)
function filter() {
sed -E "s;Retrieving ([^ ]+)\.(pom|jar) from $1.*;$2\1;"
}
echo "Computing maven dependencies with \`$_lein_cmd\`..." > /dev/stderr
trap "rm -rf ${_repo_path}; [ -f ${_project_file_name}.bak ] && mv -f ${_project_file_name}.bak ${_project_file_name}" HUP ERR EXIT INT
cd $GIT_ROOT
# Add a :local-repo entry to project.clj so that we always start with a clean repo
sed -i'.bak' -E "s|(:license \{)|:local-repo \"$_repo_path\" \1|" ${_project_file_name}
rm -rf ./${_repo_path}
$_lein_cmd 2>&1 \
| grep Retrieving \
| filter clojars https://repo.clojars.org/ \
| filter central https://repo1.maven.org/maven2/ # NOTE: We could use `lein pom` to figure out the repository names and URLs so they're not hardcoded

28
nix/tools/lein/generate-nix.sh Executable file
View File

@ -0,0 +1,28 @@
#!/usr/bin/env bash
# This script takes care of generating/updating the nix files in the directory passed as a single argument.
# For this, we start with a clean cache (in ./.m2~/repository/) and call cljsbuild
# to cause it to download all the artifacts. At the same time, we note them
# in $1/lein-project-deps-maven-inputs.txt so that we can use that as an input
# to ../maven/maven-inputs2nix.sh
set -Eeuo pipefail
. ~/.nix-profile/etc/profile.d/nix.sh
output_dir=$1
mkdir -p $output_dir
_current_dir=$(cd "${BASH_SOURCE%/*}" && pwd)
_inputs_file_path="$output_dir/lein-project-deps-maven-inputs.txt"
_deps_nix_file_path="$output_dir/lein-project-deps.nix"
_nix_shell_opts="-I nixpkgs=https://github.com/status-im/nixpkgs/archive/db492b61572251c2866f6b5e6e94e9d70e7d3021.tar.gz"
echo "Regenerating Nix files, this process should take 5-10 minutes"
nix-shell ${_nix_shell_opts} --run "set -Eeuo pipefail; $_current_dir/fetch-maven-deps.sh | sort -u > $_inputs_file_path" \
--pure --packages leiningen git
echo "Generating $(basename $_deps_nix_file_path) from $(basename $_inputs_file_path)..."
nix-shell ${_nix_shell_opts} \
--run "$_current_dir/../maven/maven-inputs2nix.sh $_inputs_file_path > $_deps_nix_file_path" \
--packages maven
echo "Done"

View File

@ -0,0 +1,153 @@
#!/usr/bin/env bash
#
# This script takes a maven-inputs.txt file and builds a Nix expression that can be used by maven-repo-builder.nix to produce a path to a local Maven repository
#
function getSHA() {
nix-prefetch-url --type sha256 "$1" 2> /dev/null
}
_tmp=$(mktemp)
sort $1 | uniq > $_tmp
trap "rm $_tmp" EXIT INT
apacheUrl='https://repo.maven.apache.org/maven2'
clojarsUrl='https://repo.clojars.org'
fabricUrl='https://maven.fabric.io/public'
googleUrl='https://dl.google.com/dl/android/maven2'
gradleUrl='http://repo.gradle.org/gradle/libs-releases-local'
gradlePluginsUrl='https://plugins.gradle.org/m2'
javaUrl='https://maven.java.net/content/repositories/releases'
jcenterUrl='https://jcenter.bintray.com'
jitpackUrl='https://jitpack.io'
mavenUrl='https://repo1.maven.org/maven2'
sonatypeSnapshotsUrl='https://oss.sonatype.org/content/repositories/snapshots'
sonatypePublicGridUrl='https://repository.sonatype.org/content/groups/sonatype-public-grid'
# Writes Nix attribute set describing a package (represented by its URL)
function writeEntry() {
local depurl=$1
if [[ "$depurl" = "$apacheUrl"* ]]; then
host='apache'
prefix=$apacheUrl
elif [[ "$depurl" = "$clojarsUrl"* ]]; then
host='clojars'
prefix=$clojarsUrl
elif [[ "$depurl" = "$fabricUrl"* ]]; then
host='fabric-io'
prefix=$fabricUrl
elif [[ "$depurl" = "$googleUrl"* ]]; then
host='google'
prefix=$googleUrl
elif [[ "$depurl" = "$gradleUrl"* ]]; then
host='gradle'
prefix=$gradleUrl
elif [[ "$depurl" = "$gradlePluginsUrl"* ]]; then
host='gradlePlugins'
prefix=$gradlePluginsUrl
elif [[ "$depurl" = "$jcenterUrl"* ]]; then
host='jcenter'
prefix=$jcenterUrl
elif [[ "$depurl" = "$jitpackUrl"* ]]; then
host='jitpack'
prefix=$jitpackUrl
elif [[ "$depurl" = "$javaUrl"* ]]; then
host='java'
prefix=$javaUrl
elif [[ "$depurl" = "$mavenUrl"* ]]; then
host='maven'
prefix=$mavenUrl
elif [[ "$depurl" = "$sonatypeSnapshotsUrl"* ]]; then
host='sonatypeSnapshots'
prefix=$sonatypeSnapshotsUrl
elif [[ "$depurl" = "$sonatypePublicGridUrl"* ]]; then
host='sonatypePublicGrid'
prefix=$sonatypePublicGridUrl
else
echo "Unknown host in $depurl, exiting."
exit 1
fi
deppath="${depurl/$prefix\//}"
pom_sha256=$(getSHA "$depurl.pom")
[ -n "$pom_sha256" ] && pom_sha1=$(curl -s "$depurl.pom.sha1") || unset pom_sha1
jar_sha256=$(getSHA "$depurl.jar")
type='jar'
if [ -z "$jar_sha256" ]; then
jar_sha256=$(getSHA "$depurl.aar")
[ -n "$jar_sha256" ] && type='aar'
fi
[ -n "$jar_sha256" ] && jar_sha1=$(curl -s "$depurl.${type}.sha1") || unset jar_sha1
if [ -z "$pom_sha256" ] && [ -z "$jar_sha256" ] && [ -z "$aar_sha256" ]; then
echo "Warning: failed to download $depurl" > /dev/stderr
echo "Exiting." > /dev/stderr
exit 1
fi
echo -n " \"$depurl\" = {
host = repositories.$host;
path = \"$deppath\";
type = \"$type\";"
if [ -n "$pom_sha256" ]; then
echo -n "
pom = {
sha1 = \"$pom_sha1\";
sha256 = \"$pom_sha256\";
};"
fi
if [ -n "$jar_sha256" ]; then
echo -n "
jar = {
sha1 = \"$jar_sha1\";
sha256 = \"$jar_sha256\";
};"
fi
echo "
};"
}
lineCount=$(wc -l $1 | cut -f 1 -d ' ')
currentLine=0
pstr="[=======================================================================]"
echo "# Auto-generated by $(realpath --relative-to="$(dirname $1)" ${BASH_SOURCE})
{}:
let
repositories = {
apache = \"$mavenUrl\";
clojars = \"$clojarsUrl\";
fabric-io = \"$fabricUrl\";
google = \"$googleUrl\";
gradle = \"$gradleUrl\";
gradlePlugins = \"$gradlePluginsUrl\";
java = \"$javaUrl\";
jcenter = \"$jcenterUrl\";
jitpack = \"$jitpackUrl\";
maven = \"$mavenUrl\";
sonatypeSnapshots = \"$sonatypeSnapshotsUrl\";
sonatypePublicGrid = \"$sonatypePublicGridUrl\";
};
in {"
echo "Generating Nix file from $1..." > /dev/stderr
while read depurl
do
currentLine=$(( $currentLine + 1 ))
pd=$(( $currentLine * 73 / $lineCount ))
printf "\r%3d.%1d%% %.${pd}s" $(( $currentLine * 100 / $lineCount )) $(( ($currentLine * 1000 / $lineCount) % 10 )) $pstr > /dev/stderr
if [ -z "$depurl" ]; then
continue
fi
writeEntry $depurl
# com.android.tools.build:aapt2 package also includes a platform-specific package, so we should add that too
if [[ "$depurl" = *'com/android/tools/build/aapt2/'* ]]; then
writeEntry "$depurl-linux"
writeEntry "$depurl-osx"
fi
done < $_tmp
echo "}"

View File

@ -0,0 +1,57 @@
{ stdenv, lib, writeShellScriptBin, fetchurl }:
# Put the downloaded files in a fake Maven repository
name: source:
let
script = writeShellScriptBin "create-local-maven-repo" (''
mkdir -p $out
cd $out
'' +
(lib.concatMapStrings (dep':
let
dep = { postCopy = ""; } // dep';
url = "${dep.host}/${dep.path}";
pom = {
sha1 = lib.attrByPath [ "pom" "sha1" ] "" dep;
sha256 = lib.attrByPath [ "pom" "sha256" ] "" dep;
};
pom-download = lib.optionalString (pom.sha256 != "") (fetchurl { url = "${url}.pom"; inherit (pom) sha256; });
jar = {
sha1 = lib.attrByPath [ "jar" "sha1" ] "" dep;
sha256 = lib.attrByPath [ "jar" "sha256" ] "" dep;
};
jar-download = lib.optionalString (jar.sha256 != "") (fetchurl { url = "${url}.${dep.type}"; inherit (jar) sha256; });
fileName = lib.last (lib.splitString "/" dep.path);
directory = lib.removeSuffix fileName dep.path;
in
''
mkdir -p ${directory}
${lib.optionalString (pom-download != "") ''
cp -f "${pom-download}" "${dep.path}.pom"
''}
${lib.optionalString (pom.sha1 != "") ''
echo "${pom.sha1}" > "${dep.path}.pom.sha1"
''}
${lib.optionalString (jar-download != "") ''
cp -f "${jar-download}" "${dep.path}.${dep.type}"
''}
${lib.optionalString (jar.sha1 != "") ''
echo "${jar.sha1}" > "${dep.path}.${dep.type}.sha1"
''}
${if dep.postCopy != "" then ''
depPath="$PWD/${dep.path}"
${dep.postCopy}
unset depPath
'' else ""
}
'')
(lib.attrValues source)));
in lib.makeOverridable stdenv.mkDerivation {
inherit name;
phases = [ "buildPhase" ];
buildPhase = "${script}/bin/create-local-maven-repo";
}

40
nix/tools/mkFilter.nix Normal file
View File

@ -0,0 +1,40 @@
{ lib }:
# This Nix expression allows filtering a local directory by specifying dirRootsToInclude, dirsToExclude and filesToInclude.
# It also filters out symlinks to result folders created by nix-build, as well as backup/swap/generated files
let
inherit (lib) any compare compareLists elem elemAt hasPrefix length min splitString take;
isPathAllowed =
allowedPath:
path:
let
count = min (length allowedPathElements) (length pathElements);
pathElements = splitString "/" path;
allowedPathElements = splitString "/" allowedPath;
pathElementsSubset = take count pathElements;
allowedPathElementsSubset = take count allowedPathElements;
in (compareLists compare allowedPathElementsSubset pathElementsSubset) == 0;
mkFilter = {
dirRootsToInclude, # Relative paths of directories to include
dirsToExclude ? [], # Base names of directories to exclude
filesToInclude ? [], # Relative path of files to include
filesToExclude ? [], # Relative path of files to exclude
root
}: path: type:
let
baseName = baseNameOf (toString path);
subpath = elemAt (splitString "${toString root}/" path) 1;
spdir = elemAt (splitString "/" subpath) 0;
in lib.cleanSourceFilter path type && (
(type != "directory" && (elem spdir filesToInclude) && !(elem spdir filesToExclude)) ||
# check if any part of the directory path is described in dirRootsToInclude
((any (dirRootToInclude: isPathAllowed dirRootToInclude subpath) dirRootsToInclude) && ! (
# Filter out version control software files/directories
(type == "directory" && (elem baseName dirsToExclude))
)));
in mkFilter

View File

@ -0,0 +1,50 @@
# This file is an example of the syntax required to call a Nix function
# and serves to test mkFilter.nix.
#
# nix-instantiate --strict --json --eval ./mkFilter_test.nix
# [
# {
# "expected": true,
# "path": "/home/pedro/src/github.com/status-im/status-react/android/1",
# "result": true
# },
# {
# "expected": true,
# "path": "/home/pedro/src/github.com/status-im/status-react/ios",
# "result": false
# }
# ]
{ pkgs ? import <nixpkgs> { },
lib ? pkgs.stdenv.lib }:
let
mkFilter = pkgs.callPackage ./mkFilter.nix { inherit lib; };
absPath = "/ABS/PROJECT/PATH";
filter = mkFilter {
dirRootsToInclude = [ "android" ];
# dirsToExclude ? [], # Base names of directories to exclude
# filesToInclude ? [], # Relative path of files to include
# filesToExclude ? [], # Relative path of files to exclude
root = absPath;
};
tests = [
{
a = { path = "${absPath}/android/1"; type = "directory"; };
e = true;
}
{
a = { path = "${absPath}/ios"; type = "directory"; };
e = false;
}
];
boolToString = b: if b then "true" else "false";
in builtins.map (
t: let
rval = (filter t.a.path t.a.type);
in {
path = t.a.path;
pass = t.e == rval;
}
) tests

View File

@ -22,10 +22,10 @@
[status-im/pluto "iteration-4-9"]
[mvxcvi/alphabase "1.0.0"]
[rasom/cljs-react-navigation "0.1.4"]]
:plugins [[lein-cljsbuild "1.1.7"]
:plugins [[rasom/lein-githooks "0.1.5"]
[lein-cljsbuild "1.1.7"]
[lein-re-frisk "0.5.8"]
[lein-cljfmt "0.5.7"]
[rasom/lein-githooks "0.1.5"]]
[lein-cljfmt "0.5.7"]]
:githooks {:auto-install true
:pre-commit ["lein cljfmt check src/status_im/core.cljs $(git diff --diff-filter=d --cached --name-only src test/cljs)"]}
:cljfmt {:indents {letsubs [[:inner 0]]}}
@ -162,6 +162,7 @@
:fn-invoke-direct true
:optimize-constants true
:optimizations :advanced
:stable-names true
:pseudo-names false
:pretty-print false
:closure-defines {"goog.DEBUG" false}

View File

@ -1,10 +1,14 @@
#!/usr/bin/env bash
set -Eeu
. ~/.nix-profile/etc/profile.d/nix.sh
GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)
rm -rf .nix-gcroots
mkdir .nix-gcroots
drv=$(nix-instantiate shell.nix)
drv=$(nix-instantiate ${GIT_ROOT}/shell.nix)
refs=$(nix-store --query --references $drv)
nix-store -r $refs --indirect --add-root $GIT_ROOT/.nix-gcroots/shell.dep

23
scripts/copy-translations.sh Executable file
View File

@ -0,0 +1,23 @@
#!/usr/bin/env bash
set -e
use_chmod="$1"
GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)
if [ ! -d "${GIT_ROOT}/node_modules" ]; then
echo "node_modules directory is missing, aborting!"
exit 1
fi
# 1. copy translations to node_modules
# 2. touch node_modules/.copied~ to avoid copying node_modules again during build
cp -R "${GIT_ROOT}/translations" "${GIT_ROOT}/status-modules/"
[ "$use_chmod" == 'chmod' ] && chmod u+w "${GIT_ROOT}/node_modules"
cp -R "${GIT_ROOT}/status-modules" "${GIT_ROOT}/node_modules/"
[ -f "${GIT_ROOT}/node_modules/.copied~" ] && touch "${GIT_ROOT}/node_modules/.copied~"
[ "$use_chmod" == 'chmod' ] && chmod u-w "${GIT_ROOT}/node_modules"
set +e

View File

@ -0,0 +1,36 @@
#!/usr/bin/env bash
###################################################################################################
#
# Impure setup (any setup here should be minimized and instead be moved to Nix for a pure setup)
#
###################################################################################################
set -e
GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
PLATFORM_FOLDER="desktop_files"
$GIT_ROOT/scripts/run-environment-check.sh desktop
if [ ! -f package.json ] || [ $(readlink package.json) != "${PLATFORM_FOLDER}/package.json.orig" ]; then
rm -rf node_modules
echo "Creating link: package.json -> ${PLATFORM_FOLDER}/package.json.orig"
ln -sf ${PLATFORM_FOLDER}/package.json.orig package.json
echo "Creating link: yarn.lock -> ${PLATFORM_FOLDER}/yarn.lock"
ln -sf ${PLATFORM_FOLDER}/yarn.lock yarn.lock
echo "Creating link: metro.config.js -> ${PLATFORM_FOLDER}/metro.config.js"
ln -sf ${PLATFORM_FOLDER}/metro.config.js metro.config.js
fi
yarn install --frozen-lockfile
echo -e "${GREEN}Finished!${NC}"

View File

@ -1,90 +0,0 @@
#!/usr/bin/env bash
###################################################################################################
#
# Impure setup (any setup here should be minimized and instead be moved to Nix for a pure setup)
#
###################################################################################################
set -e
GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
PLATFORM=""
PLATFORM_FOLDER=""
RCTSTATUS_DIR="$GIT_ROOT/modules/react-native-status/ios/RCTStatus"
#if no arguments passed, inform user about possible ones
if [ $# -eq 0 ]; then
echo -e "${GREEN}This script should be invoked with platform argument: 'android', 'ios', 'desktop', 'windows', 'linux', 'macos' or 'darwin'${NC}"
echo "If invoked with 'android' argument it will link: "
echo "mobile_files/package.json.orig -> package.json"
echo "etc.."
exit 1
else
case $1 in
android | ios)
PLATFORM='mobile'
;;
windows | linux | macos | darwin)
PLATFORM='desktop'
;;
*)
PLATFORM=$1
;;
esac
PLATFORM_FOLDER="${PLATFORM}_files"
fi
$GIT_ROOT/scripts/run-environment-check.sh $1
if [ ! -f package.json ] || [ $(readlink package.json) != "${PLATFORM_FOLDER}/package.json.orig" ]; then
echo "Creating link: package.json -> ${PLATFORM_FOLDER}/package.json.orig"
ln -sf ${PLATFORM_FOLDER}/package.json.orig package.json
echo "Creating link: yarn.lock -> ${PLATFORM_FOLDER}/yarn.lock"
ln -sf ${PLATFORM_FOLDER}/yarn.lock yarn.lock
echo "Creating link: metro.config.js -> ${PLATFORM_FOLDER}/metro.config.js"
ln -sf ${PLATFORM_FOLDER}/metro.config.js metro.config.js
fi
yarn install --frozen-lockfile
case $1 in
android)
set -e
if [ ! -d $GIT_ROOT/node_modules/react-native/android/com/facebook/react/react-native/ ]; then
cd $GIT_ROOT/android && ./gradlew react-native-android:installArchives
fi
;;
ios)
targetBasename='Statusgo.framework'
# Compare target folder with source to see if copying is required
if [ -d "$RCTSTATUS_DIR/$targetBasename" ] && \
diff -q --no-dereference --recursive $RCTSTATUS_DIR/$targetBasename/ $RCTSTATUS_FILEPATH/ > /dev/null; then
echo "$RCTSTATUS_DIR/$targetBasename already in place"
else
sourceBasename="$(basename $RCTSTATUS_FILEPATH)"
echo "Copying $sourceBasename from Nix store to $RCTSTATUS_DIR"
rm -rf "$RCTSTATUS_DIR/$targetBasename/"
cp -a $RCTSTATUS_FILEPATH $RCTSTATUS_DIR && chmod -R 755 "$RCTSTATUS_DIR/$targetBasename"
if [ "$sourceBasename" != "$targetBasename" ]; then
mv "$RCTSTATUS_DIR/$sourceBasename" "$RCTSTATUS_DIR/$targetBasename"
fi
if [ "$(uname)" == 'Darwin' ]; then
# CocoaPods are trash and can't handle other pod instances running at the same time
$GIT_ROOT/scripts/wait-for.sh pod 240
pushd $GIT_ROOT/ios && pod install; popd
fi
fi
;;
esac
echo -e "${GREEN}Finished!${NC}"

67
scripts/release-android.sh Executable file
View File

@ -0,0 +1,67 @@
#!/usr/bin/env bash
set -Eeo pipefail
GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)
CURRENT_DIR="$( cd "$( dirname "$0" )" && pwd )"
. "$CURRENT_DIR/lib/setup/path-support.sh"
source_lib "properties.sh"
source_lib "platform.sh"
STORE_FILE=$(property_gradle 'STATUS_RELEASE_STORE_FILE')
STORE_FILE="${STORE_FILE/#\~/$HOME}"
function cleanup() {
trap - EXIT ERR INT QUIT
if [ -n "$nixResultPath" ]; then
echo "Deleting derivations from Nix store..."
. ~/.nix-profile/etc/profile.d/nix.sh
releaseDrv=$(nix-instantiate --quiet $nixOpts)
if [ -n "$releaseDrv" ]; then
local releaseSrcPath=$(nix-store -q --binding src $releaseDrv)
local releaseOutPath=$(nix-store -q --outputs $releaseDrv)
local releaseRefs=( $(nix-store -q --references $releaseDrv) )
local prodBuildDrv=$(printf -- '%s\n' "${releaseRefs[@]}" | grep -e "prod-build-android.drv")
local prodBuildSrcPath=$(nix-store -q --binding src $prodBuildDrv)
local prodBuildOutPath=$(nix-store -q --outputs $prodBuildDrv)
nix-store --delete $prodBuildDrv $prodBuildSrcPath $prodBuildOutPath $releaseDrv $releaseSrcPath $releaseOutPath 2> /dev/null
fi
fi
}
trap "cleanup" EXIT ERR INT QUIT
[ -z "$BUILD_TYPE" ] && BUILD_TYPE='nightly'
exportedEnv=()
if [ -n "$NDK_ABI_FILTERS" ]; then
exportedEnv+=( "NDK_ABI_FILTERS=''${NDK_ABI_FILTERS}'';" ) # NOTE: Do not include spaces in the Nix attribute set, otherwise it'll create issues with automatic bash quoting
fi
exportedEnvFlag=''
if [ ${#exportedEnv[@]} -ne 0 ]; then
exportedEnvFlag="--arg env {${exportedEnv[@]}}"
fi
nixOpts="--option extra-sandbox-paths ${STORE_FILE} \
--argstr target-os ${TARGET_OS} \
--argstr build-type ${BUILD_TYPE} \
--argstr keystore-file ${STORE_FILE} \
--show-trace \
$exportedEnvFlag \
-A targets.mobile.${TARGET_OS}.release"
# Run the build
outType='release'
if [ "$BUILD_TYPE" != "release" ] && [ "$BUILD_TYPE" != "nightly" ]; then
outType="pr"
fi
nixResultPath=$(. ~/.nix-profile/etc/profile.d/nix.sh && nix-build --pure --fallback --no-out-link $nixOpts)
if [ -n "$${nixResultPath}" ]; then
targetPath="android/app/build/outputs/apk/${outType}/app-${outType}.apk"
cpFlags='-v'
is_linux && cpFlags='-fv --no-preserve=mode'
mkdir -p android/app/build/outputs/apk/${outType} && \
cp ${cpFlags} "${nixResultPath}/app.apk" "${targetPath}" && \
chmod u+w ${targetPath}
fi

View File

@ -3,18 +3,11 @@
target-os ? "all" }:
let
projectDeps = import ./default.nix { inherit target-os pkgs nixpkgs-bootstrap; inherit (nixpkgs-bootstrap) config; };
project = import ./default.nix { inherit target-os pkgs nixpkgs-bootstrap; inherit (nixpkgs-bootstrap) config; };
mkShell = pkgs.callPackage ./nix/bootstrapped-shell.nix { inherit stdenv; inherit (pkgs) mkShell; };
platform = pkgs.callPackage ./nix/platform.nix { inherit target-os; };
useFastlanePkg = (platform.targetAndroid && !stdenv.isDarwin);
# 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;
mkShell = pkgs.mkShell.override { inherit stdenv; };
fastlane = pkgs.callPackage ./fastlane {
bundlerEnv = _: pkgs.bundlerEnv {
name = "fastlane-gems";
gemdir = ./fastlane;
};
};
in mkShell {
buildInputs = with pkgs; [
@ -30,23 +23,13 @@ in mkShell {
ps # used in scripts/start-react-native.sh
unzip
wget
] ++
(if useFastlanePkg then [ fastlane ] else with pkgs; lib.optionals platform.targetMobile [ bundler ruby ]); # bundler/ruby used for fastlane on macOS
inputsFrom = [ projectDeps ];
clojure
leiningen
maven
watchman
];
inputsFrom = [ project.shell ];
TARGET_OS = target-os;
shellHook = ''
set -e
export STATUS_REACT_HOME=$(git rev-parse --show-toplevel)
export PATH=$STATUS_REACT_HOME/node_modules/.bin:$PATH
${projectDeps.shellHook}
${stdenv.lib.optionalString useFastlanePkg fastlane.shellHook}
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
'';
shellHook = project.shell.shellHook;
}