#!/bin/bash

OWNER=$1

GH=$(which gh)

if [ -z "$GH" ]
then
    echo "Github CLI is required for this script. Please go to https://cli.github.com/ to install a supported version for your platform"
    exit 1
fi

if [ -z "$OWNER" ]
then
    echo "Usage ./sync_fork.sh OWNER [branch_name]. OWNER is required"
    exit 1
fi

if [ -z "$2" ]
then
    $GH repo sync $OWNER/akd -b main
else
    echo "Overriding the branch to $2"
    $GH repo sync $OWNER/$2 -b main
fi


#!/bin/bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

# ManyLinux build
# Mount top-level Ax directory as Ax-main.
docker container run --mount type=bind,source="$(pwd)/../",target=/Ax-main -it quay.io/pypa/manylinux2010_x86_64

# MANUAL STEP FOR NOW
# Now, in Docker container, cd Ax-main and MANUALLY RUN ./docker_install.sh

# LOCAL BUILD
# Requires Python 3.7 installed locally, and on path
cd ..
pip3.7 install numpy
python3.7 setup.py bdist_wheel

# Final PyPI Upload
twine upload dist/*


#!/bin/bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

VERSION=$1

# Build Linux Python3.7
# Execute from Ax root directory.
cd ../ || exit
/opt/python/cp37-cp37m/bin/pip3.7 install numpy
/opt/python/cp37-cp37m/bin/python3.7 setup.py bdist_wheel

# Convert to manylinux
cd dist || exit
auditwheel repair ax_platform-"$VERSION"-cp37-cp37m-linux_x86_64.whl
rm ./*
mv wheelhouse/* .
rm -rf wheelhouse


#!/bin/bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

# Exit if any error occurs
set -e

usage() {
  echo "Usage: $0 [-b] [-o] [-r] [-t] [-k kernel_name]"
  echo ""
  echo "Build Ax documentation. Must be executed from root of Ax repository."
  echo ""
  echo "  -b   Build static version of documentation (otherwise start server)."
  echo "  -o   Only Docusaurus (skip Sphinx, tutorials). Useful when just make change to Docusaurus settings."
  echo "  -t   Execute tutorials (instead of just converting)."
  echo "  -r   Convert backtick-quoted class or function names in .md files into links to API documentation."
  echo "  -k   Kernel name to use for executing tutorials. Use Jupyter default if not set."
  echo ""
  exit 1
}

BUILD_STATIC=false
ONLY_DOCUSAURUS=false
BUILD_TUTORIALS=false
KERNEL_NAME=false
INSERT_API_REFS=false

while getopts 'hbotrk:' flag; do
  case "${flag}" in
    h)
      usage
      ;;
    b)
      BUILD_STATIC=true
      ;;
    o)
      ONLY_DOCUSAURUS=true
      ;;
    t)
      BUILD_TUTORIALS=true
      ;;
    r)
      INSERT_API_REFS=true
      ;;
    k)
      KERNEL_NAME=${OPTARG}
      ;;
    *)
      usage
      ;;
  esac
done

if [[ $ONLY_DOCUSAURUS == false ]]; then
  # generate Sphinx documentation
  echo "-----------------------------------"
  echo "Generating API reference via Sphinx"
  echo "-----------------------------------"
  cd sphinx || exit
  make html
  cd .. || exit
fi

# init Docusaurus deps
echo "-----------------------------------"
echo "Getting Docusaurus deps"
echo "-----------------------------------"
cd website || exit
yarn

if [[ $ONLY_DOCUSAURUS == false ]]; then
  # run script to parse html generated by sphinx
  echo "--------------------------------------------"
  echo "Parsing Sphinx docs and moving to Docusaurus"
  echo "--------------------------------------------"
  cd ..
  mkdir -p "website/pages/api/"

  cwd=$(pwd)
  python3 scripts/parse_sphinx.py -i "${cwd}/sphinx/build/html/" -o "${cwd}/website/pages/api/"

  SPHINX_JS_DIR='sphinx/build/html/_static/'
  DOCUSAURUS_JS_DIR='website/static/js/'

  mkdir -p $DOCUSAURUS_JS_DIR

  # move JS files from /sphinx/build/html/_static/*:
  cp "${SPHINX_JS_DIR}documentation_options.js" "${DOCUSAURUS_JS_DIR}documentation_options.js"
  cp "${SPHINX_JS_DIR}jquery.js" "${DOCUSAURUS_JS_DIR}jquery.js"
  cp "${SPHINX_JS_DIR}underscore.js" "${DOCUSAURUS_JS_DIR}underscore.js"
  cp "${SPHINX_JS_DIR}doctools.js" "${DOCUSAURUS_JS_DIR}doctools.js"
  cp "${SPHINX_JS_DIR}language_data.js" "${DOCUSAURUS_JS_DIR}language_data.js"
  cp "${SPHINX_JS_DIR}searchtools.js" "${DOCUSAURUS_JS_DIR}searchtools.js"

  # searchindex.js is not static util
  cp "sphinx/build/html/searchindex.js" "${DOCUSAURUS_JS_DIR}searchindex.js"

  # copy module sources
  cp -r "sphinx/build/html/_sources/" "website/static/_sphinx-sources/"

  echo "-----------------------------------"
  echo "Generating tutorials"
  echo "-----------------------------------"
  # mkdir -p "website/_tutorials"
  # mkdir -p "website/static/files"
  if [[ $BUILD_TUTORIALS == true ]]; then
    if [[ $KERNEL_NAME == false ]]; then
      python3 scripts/make_tutorials.py -w "${cwd}" -e
    else
      python3 scripts/make_tutorials.py -w "${cwd}" -e -k "${KERNEL_NAME}"
    fi
  else
    python3 scripts/make_tutorials.py -w "${cwd}"
  fi

cd website || exit
fi  # end of not only Docusaurus block

if [[ $INSERT_API_REFS == true ]]; then
  echo "-----------------------------------"
  echo "Inserting API reference links in Markdown files"
  echo "-----------------------------------"
  cd ..
  cwd=$(pwd)
  python3 scripts/insert_api_refs.py --source_path "${cwd}/ax" --docs_path "${cwd}/docs"
  cd - || exit
fi

if [[ $BUILD_STATIC == true ]]; then
  echo "-----------------------------------"
  echo "Building static Docusaurus site"
  echo "-----------------------------------"
  yarn build
else
  echo "-----------------------------------"
  echo "Starting local server"
  echo "-----------------------------------"
  yarn start
fi


#!/bin/bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

# Exit if any error occurs
set -e
set -x

usage() {
  echo "Usage: $0 [-d] [-k KERNEL_NAME] [-v VERSION]"
  echo ""
  echo "Build and push updated Ax site. Will either update latest or bump stable version."
  echo ""
  echo "  -d                Use Docusaurus bot GitHub credentials. If not specified, will use default GitHub credentials."
  echo "  -k=KERNEL_NAME    Kernel name to use for executing tutorials. Use Jupyter default if not set."
  echo "  -v=VERSION        Build site for new library version. If not specified, will update latest."
  echo ""
  exit 1
}

VERSION=false
DOCUSAURUS_BOT=false
KERNEL_NAME=false

while getopts 'dhk:v:' option; do
  case "${option}" in
    d)
      DOCUSAURUS_BOT=true
      ;;
    h)
      usage
      ;;
    k)
      KERNEL_NAME=${OPTARG}
      ;;
    v)
      VERSION=${OPTARG}
      ;;
    *)
      usage
      ;;
  esac
done

# Function to get absolute filename
fullpath() {
  echo "$(cd "$(dirname "$1")" || exit; pwd -P)/$(basename "$1")"
}

# Current directory (needed for cleanup later)
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

# Make temporary directory
WORK_DIR=$(mktemp -d)
cd "${WORK_DIR}" || exit

if [[ $DOCUSAURUS_BOT == true ]]; then
  # Setup git credentials
  git config --global user.name "Ax Website Deployment Script"
  git config --global user.email "docusaurus-bot@users.noreply.github.com"
  echo "machine github.com login docusaurus-bot password ${DOCUSAURUS_PUBLISH_TOKEN}" > ~/.netrc

  # Clone both main & gh-pages branches
  git clone https://docusaurus-bot@github.com/facebook/Ax.git Ax-main
  git clone --branch gh-pages https://docusaurus-bot@github.com/facebook/Ax.git Ax-gh-pages
else
  git clone git@github.com:facebook/Ax.git Ax-main
  git clone --branch gh-pages git@github.com:facebook/Ax.git Ax-gh-pages
fi

# A few notes about the script below:
# * Docusaurus versioning was designed to *only* version the markdown
#   files in the docs/ subdirectory. We are repurposing parts of Docusaurus
#   versioning, but snapshotting the entire site. Versions of the site are
#   stored in the versions/ subdirectory on gh-pages:
#
#   --gh-pages/
#     |-- api/
#     |-- css/
#     |-- docs/
#     |   ...
#     |-- versions/
#     |   |-- 1.0.1/
#     |   |-- 1.0.2/
#     |   |   ...
#     |   |-- latest/
#     |   ..
#     |-- versions.html
#
# * The stable version is in the top-level directory. It is also
#   placed into the versions/ subdirectory so that it does not need to
#   be built again when the version is augmented.
# * We want to support serving / building the Docusaurus site locally
#   without any versions. This means that we have to keep versions.js
#   outside of the website/ subdirectory.
# * We do not want to have a tracked file that contains all versions of
#   the site or the latest version. Instead, we determine this at runtime.
#   We use what's on gh-pages in the versions subdirectory as the
#   source of truth for available versions and use the latest tag on
#   the main branch as the source of truth for the latest version.

if [[ $VERSION == false ]]; then
  echo "-----------------------------------------"
  echo "Updating latest (main) version of site "
  echo "-----------------------------------------"

  # Populate _versions.json from existing versions; this is used
  # by versions.js & needed to build the site (note that we don't actually
  # use versions.js for latest build, but we do need versions.js
  # in website/pages in order to use docusaurus-versions)
  CMD="import os, json; "
  CMD+="vs = [v for v in os.listdir('Ax-gh-pages/versions') if v != 'latest' and not v.startswith('.')]; "
  CMD+="print(json.dumps(vs))"
  python3 -c "$CMD" > Ax-main/website/_versions.json

  # Move versions.js to website subdirectory.
  # This is the page you see when click on version in navbar.
  cp Ax-main/scripts/versions.js Ax-main/website/pages/en/versions.js
  cd Ax-main/website || exit

  # Replace baseUrl (set to /versions/latest/) & disable Algolia
  CONFIG_FILE=$(fullpath "siteConfig.js")
  python3 ../scripts/patch_site_config.py -f "${CONFIG_FILE}" -b "/versions/latest/" --disable_algolia

  # Tag site with "latest" version
  yarn
  yarn run version latest

  # Build site
  cd .. || exit
  ./scripts/make_docs.sh -b -t -k "${KERNEL_NAME}"
  rm -rf ../website/build/Ax/docs/next  # don't need this

  # Move built site to gh-pages (but keep old versions.js)
  cd "${WORK_DIR}" || exit
  cp Ax-gh-pages/versions/latest/versions.html versions.html
  rm -rf Ax-gh-pages/versions/latest
  mv Ax-main/website/build/Ax Ax-gh-pages/versions/latest
  # versions.html goes both in top-level and under en/ (default language)
  cp versions.html Ax-gh-pages/versions/latest/versions.html
  cp versions.html Ax-gh-pages/versions/latest/en/versions.html

  # erase git history then force push to overwrite
  cd Ax-gh-pages || exit
  rm -rf .git
  git init -b main
  git add --all
  git commit -m 'Update latest version of site'
  git push --force "git@github.com:facebook/Ax" main:gh-pages

else
  echo "-----------------------------------------"
  echo "Building new version ($VERSION) of site "
  echo "-----------------------------------------"

  # Checkout main branch with specified tag
  cd Ax-main || exit
  git fetch --tags
  git checkout "${VERSION}"

  # Populate _versions.json from existing versions; this contains a list
  # of versions present in gh-pages (excluding latest). This is then used
  # to populate versions.js (which forms the page that people see when they
  # click on version number in navbar).
  # Note that this script doesn't allow building a version of the site that
  # is already on gh-pages.
  CMD="import os, json; "
  CMD+="vs = [v for v in os.listdir('../Ax-gh-pages/versions') if v != 'latest' and not v.startswith('.')]; "
  CMD+="assert '${VERSION}' not in vs, '${VERSION} is already on gh-pages.'; "
  CMD+="vs.append('${VERSION}'); "
  CMD+="print(json.dumps(vs))"
  python3 -c "$CMD" > website/_versions.json

  cp scripts/versions.js website/pages/en/versions.js

  # Set Docusaurus version as 'stable'
  cd website || exit
  yarn
  yarn run version stable

  # Build new version of site (this will be stable, default version)
  # Execute tutorials
  cd .. || exit
  ./scripts/make_docs.sh -b -t -k "${KERNEL_NAME}"

  # Move built site to new folder (new-site) & carry over old versions
  # from existing gh-pages
  cd "${WORK_DIR}" || exit
  rm -rf Ax-main/website/build/Ax/docs/next  # don't need this
  mv Ax-main/website/build/Ax new-site
  mv Ax-gh-pages/versions new-site/versions

  # Build new version of site (to be placed in versions/$VERSION/)
  # the only thing that changes here is the baseUrl (for nav purposes)
  # we build this now so that in the future, we can just bump version and not move
  # previous stable to versions
  cd Ax-main/website || exit

  # Replace baseUrl & disable Algolia
  CONFIG_FILE=$(fullpath "siteConfig.js")
  python3 ../scripts/patch_site_config.py -f "${CONFIG_FILE}" -b "/versions/${VERSION}/" --disable_algolia

  # Set Docusaurus version with exact version & build
  yarn run version "${VERSION}"
  cd .. || exit
  # Only run Docusaurus (skip tutorial build & Sphinx)
  ./scripts/make_docs.sh -b -o
  rm -rf website/build/Ax/docs/next  # don't need this
  rm -rf website/build/Ax/docs/stable  # or this
  mv website/build/Ax "../new-site/versions/${VERSION}"

  # Need to run script to update versions.js for previous versions in
  # new-site/versions with the newly built versions.js. Otherwise,
  # the versions.js for older versions in versions subdirectory
  # won't be up-to-date and will not have a way to navigate back to
  # newer versions. This is the only part of the old versions that
  # needs to be updated when a new version is built.
  cd "${WORK_DIR}" || exit
  python3 Ax-main/scripts/update_versions_html.py -p "${WORK_DIR}"

  # Init as Git repo and push to gh-pages
  cd new-site || exit
  git init -b main
  git add --all
  git commit -m "Publish version ${VERSION} of site"
  git push --force "git@github.com:facebook/Ax" main:gh-pages

fi

# Clean up
cd "${SCRIPT_DIR}" || exit
rm -rf "${WORK_DIR}"


#!/bin/bash
# Copyright (c) Facebook, Inc. and its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -e

start_soyweb() {
  echo "Starting soyweb-prod.sh" >&2
  docs/soyweb-prod.sh >&2 &
  local soyweb_pid=$!
  sleep 2
  if ! kill -0 "$soyweb_pid" >/dev/null 2>&1; then
    echo "Soyweb not running after 2 seconds. kill 0 on pid ${soyweb_pid} failed" >&2
    exit 1
  fi
  echo "Started soyweb-prod.sh as pid ${soyweb_pid}" >&2
  echo "$soyweb_pid"
}

show_help() {
  cat <<-EOF
Usage: publish.sh [--start-soyweb] [--keep-files]
  --start-soyweb Start soyweb and shut it down when the script is finished
  --keep-files   Keep temporary files after attempting to publish
EOF
  exit 1
}

GIT_USER="buck-bot"
CNAME="buck.build"
START_SOYWEB=0
KEEP_FILES=0
SOYWEB_PID=0
for arg do
  shift
  case $arg in
    --start-soyweb) START_SOYWEB=1 ;;
    --keep-files) KEEP_FILES=1 ;;
    --help) show_help ;;
    *) set -- "$@" "$arg" ;;
  esac
done

STATIC_FILES_DIR=$(mktemp -d)

buck run //docs:generate_buckconfig_aliases
if ! git diff --quiet; then
  echo "Git repository is not clean; refusing to publish"
  exit 1
fi

# Always run this script from the root of the Buck project directory.
cd $(git rev-parse --show-toplevel)

if [ $START_SOYWEB -eq 1 ]; then
  SOYWEB_PID=$(($(start_soyweb) + 0))
fi

# Make sure we cleanup
trap_command=""
if [ $SOYWEB_PID -gt 0 ]; then
  trap_command="echo 'Stopping soyweb (pid ${SOYWEB_PID})'; kill -9 ${SOYWEB_PID};"
fi
if [ $KEEP_FILES -eq 0 ] && [ -n "$STATIC_FILES_DIR" ]; then
  trap_command="${trap_command}echo 'Removing temp dir at ${STATIC_FILES_DIR}'; rm -rf ${STATIC_FILES_DIR};"
fi
if [ -n "$trap_command" ]; then
  trap "$trap_command" EXIT
fi

echo "Documentation working directory is ${STATIC_FILES_DIR}"

# Create a clean checkout of the gh-pages branch with no data:
if [ -z "$1" ]
then
  git clone https://${GIT_USER}:${GITHUB_TOKEN}@github.com/facebook/buck.git $STATIC_FILES_DIR
else
  cp -r "$1" $STATIC_FILES_DIR
fi
cd $STATIC_FILES_DIR

# May need to do this if you are creating gh-pages for the first time.
git checkout main

git checkout --orphan gh-pages
git rm -rf .
cd -

# Generate the docs in the repo:
./docs/soy2html.sh $STATIC_FILES_DIR

# Commit the new version of the docs:
cd $STATIC_FILES_DIR
echo "${CNAME}" > CNAME
git config --global user.name "${GIT_USER}"
git add .
git commit -m "Updated HTML documentation."

# Push the new version of the docs to GitHub:
set +e
git push origin gh-pages --force
EXIT_CODE=$?
set -e

# Unfortunately, this script is not bulletproof,
# so inform the user of the failure.
if [ $EXIT_CODE -ne 0 ]; then
  echo "WARNING: 'git push origin gh-pages failed'. "
  echo "Try going to https://github.com/facebook/buck/branches"
  echo "and re-running this script."
fi


#!/bin/bash
# Copyright (c) Facebook, Inc. and its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -e

# Always run this script from the root of the Buck project directory.
cd "$(git rev-parse --show-toplevel)"

# The output directory should be the one and only argument.
OUTPUT_DIR="$1"

# Run soy2html.py, taking care to unset proxy env variables as the script will
# use curl internally.
(
  cd docs
  HTTP_PROXY="" HTTPS_PROXY="" http_proxy="" https_proxy="" python soy2html.py "$OUTPUT_DIR"
)

# Generate javadoc and include it in the output directory.
ant javadoc-with-android
mkdir -p "${OUTPUT_DIR}"/javadoc/
cp -r ant-out/javadoc-with-android/* "${OUTPUT_DIR}"/javadoc/


#!/bin/bash
# Copyright (c) Facebook, Inc. and its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Always run this script from the root of the Buck project directory.
cd "$(git rev-parse --show-toplevel)/docs" || exit
buck run //docs:generate_buckconfig_aliases
exec java -jar plovr-81ed862.jar soyweb --dir . --globals globals.json $@


#!/bin/bash
# Copyright (c) Facebook, Inc. and its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Always run this script from the root of the Buck project directory.

#
# Remove any residual files that could derail build and publication.
#
cd "$(git rev-parse --show-toplevel)" || exit
ant clean

cd "$(git rev-parse --show-toplevel)/docs" || exit
buck run //docs:generate_buckconfig_aliases
exec java -jar plovr-81ed862.jar soyweb --port 9814 --dir . --globals globals.json


#!/bin/sh
# Copyright (c) Facebook, Inc. and its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -eu

export PYTHONPATH="`dirname "$0"`"

python3 -m artificialproject "$@"


#!/bin/bash
# Copyright (c) Facebook, Inc. and its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -x

# $1: OS
export OS="linux"
if [ "$1" == "macos" ]; then
  export OS="darwin"
fi

export NDK_VERSION_STRING="android-ndk-r10e"
export NDK_FILENAME="$NDK_VERSION_STRING-${OS}-x86_64.bin"

export CACHED_PATH="${HOME}/ndk_cache/$NDK_FILENAME"

if [ ! -f "$CACHED_PATH" ]; then
  echo "Downloading NDK."
  curl -O "https://dl.google.com/android/ndk/$NDK_FILENAME"
else
  echo "Using cached NDK."
  mv "$CACHED_PATH" .
fi

# Uncpack the ndk.
chmod a+x "$NDK_FILENAME"
# Suppress the output to not spam the logs.
"./$NDK_FILENAME" > /dev/null
rm "$NDK_FILENAME";

# Move ndk into the proper place.
rm -rf ${NDK_HOME}
mv android-ndk-r10e ${NDK_HOME}


#!/bin/bash
# Copyright (c) Facebook, Inc. and its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -x
set -e

if [ -z "$1" ]; then
  echo "Must specify Android NDK version"
  exit 1
fi

# $1: NDK_VERSION_STRING
# $2: OS
export NDK_VERSION_STRING="$1"
export OS="linux"
if [ "$2" == "macos" ]; then
  export OS="darwin"
fi
export NDK_FILENAME="$NDK_VERSION_STRING-${OS}-x86_64.zip"

export CACHED_PATH="${HOME}/ndk_cache/$NDK_FILENAME"

if [ ! -f "$CACHED_PATH" ]; then
  echo "Downloading NDK."
  curl -O "https://dl.google.com/android/repository/$NDK_FILENAME"
else
  echo "Using cached NDK."
  mv "$CACHED_PATH" .
fi

unzip -o "./$NDK_FILENAME" > /dev/null
rm "$NDK_FILENAME"

# Move ndk into the proper place.
rm -rf "${NDK_HOME}"
mv "${NDK_VERSION_STRING}" "${NDK_HOME}"


#!/bin/bash -e
# Copyright (c) Facebook, Inc. and its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
BUCKRELEASE_FILE="$DIR"/../.buckrelease
DEFAULT_TAG=`date +v%Y.%m.%d.01`

shopt -s nocasematch

read -e -p "Enter tag name to create [hit enter for $DEFAULT_TAG]: " tag

if [[ -z $tag ]]; then
    tag="$DEFAULT_TAG"
fi

echo -n "Creating and committing .buckrelease file for $tag... "

echo "$tag" > "$BUCKRELEASE_FILE"
git add "$BUCKRELEASE_FILE"
git commit --allow-empty -q -m "Prepare release $tag."
echo "done."

git tag -f "$tag"

read -e -p "Run 'git push origin $tag'? [Y/n] " ok
if [[ $ok =~ ^(yes|y)$ ]]; then
    git push origin "$tag"
fi


#!/bin/bash
# Copyright (c) Facebook, Inc. and its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Wrapper script that runs the exopackage installer test on all connected
# devices
set -x
set -e
set -o pipefail

cd `dirname $0`
cd `git rev-parse --show-cdup`

RESULT=""
EXIT_CODE="0"

DEVICES=`adb devices | sed -Ene '2,$s/^([^[:space:]]+).*/\1/p'`
for DEV in $DEVICES ; do
  export ANDROID_SERIAL=$DEV
  ANDROID_VERSION=`adb shell getprop ro.build.version.release | tr -d '\r\n'`
  RESULT="$RESULT$DEV $ANDROID_VERSION"
  if ./scripts/exopackage_test_single.sh; then
    RESULT="$RESULT SUCCESS^"
  else
    RESULT="$RESULT FAILURE^"
    EXIT_CODE=1
  fi
done

set +x
echo
echo $RESULT | tr ^ '\n'
exit $EXIT_CODE


#!/bin/bash
# Copyright (c) Facebook, Inc. and its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Integration test for the exopackage installer.
# This just tests the happy path, so it's more a test of device compatibility.

set -x
set -e
set -o pipefail

# Just check that we can communicate with a device/emulator.
adb get-state

function sedInPlace() {
  case "$(uname -s)" in
    Darwin)
      sed -i '' -e "$1" "$2"
      ;;
    Linux)
      sed "$1" -i "$2"
      ;;
    *)
      echo "Unsupported OS name '$(uname -s)' for running sed."
      exit 1
  esac
}

cd `dirname $0`
cd `git rev-parse --show-cdup`

if [ "$1" == "--debug" ]; then
  shift
  TMP_DIR='/tmp/exopackage-test'
  rm -rf $TMP_DIR/*
  mkdir -p $TMP_DIR
else
  TMP_DIR=`mktemp -d /tmp/exopackage-test.XXXXXX`
  trap "rm -rf $TMP_DIR" EXIT HUP INT TERM
fi

# Copy the test project into a temp dir, then cd into it and make it a buck project.
cp -r test/com/facebook/buck/android/testdata/exopackage-device/* $TMP_DIR
# Copy the testrunner script
cp test/com/facebook/buck/testutil/endtoend/testdata/mobile/simple_test_runner.py $TMP_DIR/
# Copy the test libraries
mkdir $TMP_DIR/test_libs
cp -r test/com/facebook/buck/testutil/endtoend/testdata/mobile/android/libs/*.jar $TMP_DIR/test_libs/

buck build --out $TMP_DIR/buck.pex buck
buck build --out $TMP_DIR/buck-android-support.jar buck-android-support

cd $TMP_DIR
for BUCKFILE in `find . -name BUCK.fixture` ; do
  mv $BUCKFILE ${BUCKFILE%%.fixture}
done
cat >.buckconfig <<EOF
[java]
  source_level = 7
  target_level = 7
[ndk]
  cxx_runtime = system
  cpu_abis = armv7, x86
EOF
cat >.bucklogging.properties <<EOF
com.facebook.buck.android.exopackage.level=FINER
EOF
export NO_BUCKD=1

# Clear out the phone.
(
set +e
adb uninstall com.facebook.buck.android.agent
adb uninstall buck.exotest
adb uninstall buck.exotest.meta
adb shell 'rm -r /data/local/tmp/exopackage/buck.exotest || rm -f -r /data/local/tmp/exopackage/buck.exotest'
)

EXP_APP_NAME='Exo Test App'

OUT_COUNT=0
function installAndLaunch() {
  ./buck.pex install ${1:-//:exotest} | cat
  adb logcat -c
  adb shell am start -n buck.exotest/exotest.LogActivity
  adb shell am start -n buck.exotest.meta/.ExoMetaLogActivity
  SECONDARY_DEX_INSTALLED=$(cat buck-out/log/build.trace | \
    jq -r '[ .[] | select(.name == "install_secondary_dex") | select(.ph == "B") ] | length')
  NATIVE_LIBS_INSTALLED=$(cat buck-out/log/build.trace | \
    jq -r '[ .[] | select(.name == "install_native_library") | select(.ph == "B") ] | length')
  RESOURCE_APKS_INSTALLED=$(cat buck-out/log/build.trace | \
    jq -r '[ .[] | select(.name == "install_resources") | select(.ph == "B") ] | length')
  MODULAR_DEX_INSTALLED=$(cat buck-out/log/build.trace | \
      jq -r '[ .[] | select(.name == "install_modular_dex") | select(.ph == "B") ] | length')
  sleep 1
  adb logcat -d '*:S' EXOPACKAGE_TEST:V EXOPACKAGE_TEST_META:V > out.txt
  cp out.txt out$((++OUT_COUNT)).txt

  # Check for values in the logs.
  grep -q "VALUE=$EXP_JAVA" out.txt || (cat out.txt && false)
  grep -q "NATIVE_ONE=$EXP_CPP1" out.txt || (cat out.txt && false)
  grep -q "NATIVE_TWO=$EXP_CPP2" out.txt || (cat out.txt && false)
  grep -q "RESOURCE=$EXP_RESOURCE" out.txt || (cat out.txt && false)
  grep -q "IMAGE=$EXP_IMAGE" out.txt || (cat out.txt && false)
  grep -q "ASSET=$EXP_ASSET" out.txt || (cat out.txt && false)
  grep -q "ASSET_TWO=$EXP_ASSET2" out.txt || (cat out.txt && false)
  grep -q "MODULE_ONE=$EXP_MODULE" out.txt || (cat out.txt && false)

  grep -q "META_ICON=.*_.*" out.txt || (cat out.txt && false)
  grep -q "META_NAME=$EXP_APP_NAME" out.txt || (cat out.txt && false)
  grep -q "META_DATA=<item0,item1,item2>" out.txt || (cat out.txt && false)
}

function runInstrumentationTestWithExternalRunner() {
  ./buck.pex test //:instrumentation_test --config test.external_runner=./simple_test_runner.py
}

function runInstrumentationTest() {
  ./buck.pex test //:instrumentation_test
}

function create_image() {
  mkdir -p res/drawable-nodpi
  convert -size ${1}x${1} xc:none res/drawable-nodpi/image.png
  EXP_IMAGE=png_${1}_${1}
}

function edit_asset() {
  echo "asset_$1" > assets/asset.txt
  EXP_ASSET=asset_$1
}

function edit_asset2() {
  echo "asset2_$1" > assets2/asset2.txt
  EXP_ASSET2=asset2_$1
}

function edit_resource() {
  sedInPlace "s/\(string name=\"hello\">\)[^<]*/\1res_$1/" res/values/strings.xml
  EXP_RESOURCE=res_$1
}

function edit_java() {
  echo "$1" > value.txt
  EXP_JAVA=$1
}

function edit_module() {
  echo "$1" > module_value.txt
  EXP_MODULE=$1
}

function edit_cpp1() {
  sedInPlace "s/one_../one_$1/" jni/one/one.c
  EXP_CPP1=one_$1
}

function edit_cpp2() {
  sedInPlace "s/two_../two_$1/" jni/two/two.c
  EXP_CPP2=two_$1
}

function change_label() {
  sedInPlace "s/$EXP_APP_NAME/$1/" res/values/strings.xml
  sedInPlace "s/$EXP_APP_NAME/$1/" res-real-name/values/strings.xml
  EXP_APP_NAME=$1
}

./buck.pex install //app-meta-tool:exometa

# Build and do a clean install of the app.  Launch it and capture logs.
create_image 1
edit_java '1a'
edit_module '1a'

installAndLaunch

# Check for full install.
test "$SECONDARY_DEX_INSTALLED" = 1
test "$NATIVE_LIBS_INSTALLED" = 2
# 1: exo-resources 2: exo-assets 3: exo-java-resources
test "$RESOURCE_APKS_INSTALLED" = 3
test "$MODULAR_DEX_INSTALLED" = 1

change_label 'Exo App New Label'
installAndLaunch
test "$SECONDARY_DEX_INSTALLED" = 0
test "$NATIVE_LIBS_INSTALLED" = 0
test "$RESOURCE_APKS_INSTALLED" = 1
test "$MODULAR_DEX_INSTALLED" = 0

# Change java code and do an incremental install of the app.  Launch it and capture logs.
edit_java '2b'
installAndLaunch

# Check for incremental java install.
test "$SECONDARY_DEX_INSTALLED" = 1
test "$NATIVE_LIBS_INSTALLED" = 0
test "$RESOURCE_APKS_INSTALLED" = 0
test "$MODULAR_DEX_INSTALLED" = 0
# Check for the new values in the logs.

# Change modular code and do an incremental install of the app.  Launch it and capture logs.
edit_module '2bpart2'
installAndLaunch

# Check for incremental module install.
test "$SECONDARY_DEX_INSTALLED" = 0
test "$NATIVE_LIBS_INSTALLED" = 0
test "$RESOURCE_APKS_INSTALLED" = 0
test "$MODULAR_DEX_INSTALLED" = 1
# Check for the new values in the logs.

# Change one of the native libraries, do an incremental install and capture logs.
edit_cpp1 3c
installAndLaunch

# Check for incremental native install.
test "$SECONDARY_DEX_INSTALLED" = 0
test "$NATIVE_LIBS_INSTALLED" = 1
test "$RESOURCE_APKS_INSTALLED" = 0
test "$MODULAR_DEX_INSTALLED" = 0

# Change both native and java code and do an incremental build.
edit_java '4d'
edit_cpp2 4d
installAndLaunch

# Check for incremental java and native install.
test "$SECONDARY_DEX_INSTALLED" = 1
test "$NATIVE_LIBS_INSTALLED" = 1
test "$RESOURCE_APKS_INSTALLED" = 0
test "$MODULAR_DEX_INSTALLED" = 0

# Change an image and do an incremental build.
create_image 5
installAndLaunch
test "$SECONDARY_DEX_INSTALLED" = 0
test "$NATIVE_LIBS_INSTALLED" = 0
test "$RESOURCE_APKS_INSTALLED" = 1
test "$MODULAR_DEX_INSTALLED" = 0

# Change an asset and do an incremental build.
edit_asset '6f'
installAndLaunch
test "$SECONDARY_DEX_INSTALLED" = 0
test "$NATIVE_LIBS_INSTALLED" = 0
test "$RESOURCE_APKS_INSTALLED" = 1
test "$MODULAR_DEX_INSTALLED" = 0

# Change a resource and do an incremental build.
edit_resource '7g'
installAndLaunch
test "$SECONDARY_DEX_INSTALLED" = 0
test "$NATIVE_LIBS_INSTALLED" = 0
test "$RESOURCE_APKS_INSTALLED" = 1
test "$MODULAR_DEX_INSTALLED" = 0

# Change all resources and do an incremental build.
create_image 8
edit_asset2 '8h'
edit_resource '8h'
installAndLaunch
test "$SECONDARY_DEX_INSTALLED" = 0
test "$NATIVE_LIBS_INSTALLED" = 0
test "$RESOURCE_APKS_INSTALLED" = 2
test "$MODULAR_DEX_INSTALLED" = 0

# Change everything and do a incremental build.
edit_java '9i'
edit_module '9i'
edit_cpp2 '9i'
create_image 9
edit_asset '9i'
edit_resource '9i'
installAndLaunch
test "$SECONDARY_DEX_INSTALLED" = 1
test "$NATIVE_LIBS_INSTALLED" = 1
test "$RESOURCE_APKS_INSTALLED" = 2
test "$MODULAR_DEX_INSTALLED" = 1

# Change everything and do a no-exopackage incremental build.
edit_java '10j'
edit_cpp2 '10j'
create_image 10
edit_resource '10j'
edit_asset '10j'
installAndLaunch //:exotest-noexo

# Check for no exo install.
test "$SECONDARY_DEX_INSTALLED" = 0
test "$NATIVE_LIBS_INSTALLED" = 0
test "$RESOURCE_APKS_INSTALLED" = 0
test "$MODULAR_DEX_INSTALLED" = 0

# Check for instrumentation test support
runInstrumentationTest
runInstrumentationTestWithExternalRunner

# Clean up after ourselves.
./buck.pex uninstall //:exotest-noexo
./buck.pex uninstall //app-meta-tool:exometa
./buck.pex uninstall //:instrumentation_test-apk
adb uninstall com.facebook.buck.android.agent

# Celebrate!  (And show that we succeeded, because grep doesn't print error messages.)
echo -e "\033[42;37m\033[1mGREAT_SUCCESS\033[0m"


#!/bin/bash
# Copyright (c) Facebook, Inc. and its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -x
set -euo pipefail

BUCK_ROOT=$(git rev-parse --show-toplevel)
BUCK_FBXCTEST_DIR=$BUCK_ROOT/test/com/facebook/buck/apple/testdata/fbxctest

rm -rf $BUCK_FBXCTEST_DIR/{Frameworks,bin,lib}
mkdir $BUCK_FBXCTEST_DIR/{Frameworks,bin,lib}

TMPDIR=`mktemp -d`
cd $TMPDIR

git clone https://github.com/facebook/xctool
pushd xctool
./xctool.sh || true
XCTOOL_LIB_DIR=$(ls -d build/*/*/Products/Release/lib)
cp -r $XCTOOL_LIB_DIR $BUCK_FBXCTEST_DIR
popd

git clone https://github.com/facebook/FBSimulatorControl
pushd FBSimulatorControl
./build.sh fbxctest build
cp build/Build/Products/Debug/fbxctest $BUCK_FBXCTEST_DIR/bin

./build.sh framework build
find build/Build/Products/Debug/ -type l -delete
find build/Build/Products/Debug/ -name Frameworks | xargs rm -rf
find build/Build/Products/Debug/ -name Headers | xargs rm -rf
find build/Build/Products/Debug/ -name Modules | xargs rm -rf
cp -r build/Build/Products/Debug/*.framework $BUCK_FBXCTEST_DIR/Frameworks
cp -r $BUCK_FBXCTEST_DIR/Frameworks/XCTestBootstrap.framework/Versions/A/Resources $BUCK_FBXCTEST_DIR/Frameworks/XCTestBootstrap.framework
popd


#!/bin/sh
# Copyright (c) Facebook, Inc. and its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -x
set -e
PATH=/opt/homebrew/bin:$PATH
./scripts/apple/build_script.py


#!/bin/bash
# Copyright (c) Facebook, Inc. and its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Run with -e so the script will fail if any of the steps fail.
set -e

(
function resolveList() {
  echo $1 | tr ':' '\n' | sed "s/^\([^/].*\)$/$(echo $PWD | sed 's/\//\\\//g')\/\1/" | tr '\n' ':'
}

function resolve() {
  echo $1 | sed "s/^\([^/].*\)$/$(echo $PWD | sed 's/\//\\\//g')\/\1/"
}

function getJavaPathForVersion() {
  local java_path
  java_path="java"
  echo "$java_path"
}

export BUCK_CLASSPATH=$(resolveList $BUCK_CLASSPATH)
export CLASSPATH=$(resolveList $CLASSPATH)
export BUCK_ISOLATED_ROOT=$PWD

export BUCK_PLUGIN_RESOURCES=$(resolve $BUCK_PLUGIN_RESOURCES)
export BUCK_PLUGIN_ROOT=$(resolve $BUCK_PLUGIN_ROOT)
# necessary for "isolated buck" invocations to work correctly
export BASE_BUCK_OUT_DIR=$BASE_BUCK_OUT_DIR
# this env variable is used in some rules to check if build is running using BUCK
export BUCK_BUILD_ID="RE_buck_build_id"

if [ "$BUCK_DEBUG_MODE" == "1" ]; then
  export BUCK_DEBUG_ARGS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8888"
fi

cd $1

JAVA_PATH=$(getJavaPathForVersion $BUCK_JAVA_VERSION)

$JAVA_PATH -cp $CLASSPATH \
  $BUCK_DEBUG_ARGS \
  -Xverify:none -XX:+TieredCompilation -XX:TieredStopAtLevel=1 \
  -Dpf4j.pluginsDir=$BUCK_PLUGIN_ROOT \
  -Dbuck.module.resources=$BUCK_PLUGIN_RESOURCES \
  -Dbuck.base_buck_out_dir=$BASE_BUCK_OUT_DIR \
  com.facebook.buck.cli.bootstrapper.ClassLoaderBootstrapper \
  com.facebook.buck.rules.modern.builders.OutOfProcessIsolatedBuilder \
  $BUCK_ISOLATED_ROOT "$@"
)


#!/bin/bash

OUT=$1
TMP=$2
MANIFEST=$3
PRIMARY=$4
DEP=$5

cp $MANIFEST $TMP
cp $PRIMARY $TMP/classes.jar
mkdir $TMP/libs
cp $DEP $TMP/libs
mkdir -p $TMP/res/values
echo '<?xml version="1.0" encoding="utf-8" ?>
<resources>
  <string name="app_name">Sample App</string>
  <string name="base_button">Hello world!</string>
</resources>' > $TMP/res/values/strings.xml
jar cf $OUT -C $TMP .


#!/bin/sh
exec < "$1" > "$2"
echo "package com.gen;"
echo "public class MergedLibraryMapping {"
sed 's/[.]/_/g;s/\(.*\) \(.*\)/public static final String \1 = "\2";/'
echo "}"


#!/usr/bin/env bash

echo "$1";
echo "$2";


#/bin/sh

cat <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>AppIDName</key>
  <string>Example</string>
  <key>ApplicationIdentifierPrefix</key>
  <array>
  <string>ABCDE12345</string>
  </array>
  <key>CreationDate</key>
  <date>2015-07-08T20:27:14Z</date>
  <key>Platform</key>
  <array>
    <string>iOS</string>
  </array>
  <key>DeveloperCertificates</key>
  <array>
    <data>
      MIIDSzCCAjOgAwIBAgIBATANBgkqhkiG9w0BAQsFADBTMSAwHgYDVQQDDBdCdWNrIFRlc3QgQ29kZXNp
      Z24gQ2VydDELMAkGA1UEBhMCVVMxIjAgBgkqhkiG9w0BCQEWE2V4YW1wbGVAZXhhbXBsZS5jb20wHhcN
      MTUxMDIzMjAwNzI1WhcNMzIwMzI3MjAwNzI1WjBTMSAwHgYDVQQDDBdCdWNrIFRlc3QgQ29kZXNpZ24g
      Q2VydDELMAkGA1UEBhMCVVMxIjAgBgkqhkiG9w0BCQEWE2V4YW1wbGVAZXhhbXBsZS5jb20wggEiMA0G
      CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrmmMdeV17d72ihmdbB0MTn5v3iu9LSGVYlbnJbI+FNmDJ
      1U/0PAR7aLIPux0puN3N1Rob5VMdSZCG+SvsjV5zUNyepiRYlhf1jMyYTGDuoF8EOtfE94w9kr1EH9gl
      aKRqir4770oXrFywbOaDO1iLPkpiVnfKVkkoU4dM0UD3YEtXoM70LIpYouGtVvNyc0Sx9/emvyiMH3iA
      yQz5erVdfJQ2O85eyXz+U6rrcsNQpE0AuyQNnBnm0irSvtvnoPxlCsf0EbLnmnkDlv8yTrgCxzj/jmys
      0zs+EZFAjYCX/I2ef63Ll+Wm7ilh7CjwNaRMIQmL0QpJIR9kUYnp3v33AgMBAAGjKjAoMA4GA1UdDwEB
      /wQEAwIHgDAWBgNVHSUBAf8EDDAKBggrBgEFBQcDAzANBgkqhkiG9w0BAQsFAAOCAQEATpWzY5IXhyb4
      PXiRS64Q6Sh2YXj6Dot2srWC+FJwWngGbF6J8aQfoymsRTkgTa+69WinMefmdRkEzysmXvAUfD1iWpBX
      jRREQXkUhmt2FwqKp8pWbYSlgOTaQMojQn3DdvDu8l5ZFIrU+8Z8X4g/aggvffoIOygHvhbwkcgrA6Lq
      TziJssmKd56+QKfVfx52vg6pv1Ok03pmVsQ8semHTJr53juc4QutADhtJBXe9inVs1evosO15At0N731
      Lz37Bzwedpu8DSEr4PIdwF5yBDRbQoyAF29zQaJgO/mU2G4i9wYTZJrj75BD/qr2ukjQOYOtz4IVNUuz
      kPu+rDPz4A==
    </data>
  </array>
  <key>Entitlements</key>
  <dict>
    <key>keychain-access-groups</key>
    <array>
      <string>ABCDE12345.*</string>
    </array>
    <key>get-task-allow</key>
    <false/>
    <key>application-identifier</key>
    <string>0000000000.com.example.override</string>
    <key>com.apple.security.application-groups</key>
    <array>
      <string>group.com.example</string>
    </array>
    <key>com.apple.developer.team-identifier</key>
    <string>12345ABCDE</string>
    <key>com.apple.developer.icloud-container-development-container-identifiers</key>
    <array>
      <string>iCloud.com.appleseedinc.MyProject</string>
      <string>iCloud.com.appleseedinc.container1</string>
    </array>
  </dict>
  <key>ExpirationDate</key>
  <date>9999-03-05T01:33:40Z</date>
  <key>Name</key>
  <string>Example</string>
  <key>ProvisionsAllDevices</key>
  <true/>
  <key>TeamIdentifier</key>
  <array>
    <string>12345ABCDE</string>
  </array>
  <key>TeamName</key>
  <string>Example</string>
  <key>TimeToLive</key>
  <integer>240</integer>
  <key>UUID</key>
  <string>00000000-0000-0000-0000-000000000000</string>
  <key>Version</key>
  <integer>1</integer>
</dict>
</plist>
EOF


#!/usr/bin/env bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under both the MIT license found in the
# LICENSE-MIT file in the root directory of this source tree and the Apache
# License, Version 2.0 found in the LICENSE-APACHE file in the root directory
# of this source tree.

# This script is used to generate rust-project.json when using internal rust-analyzer
# on internal VSCode on devserver/OD.
# If this is not working, make sure your VSCode's root workspace is open at fbsource.
# Check out the full wiki guide at https://www.internalfb.com/intern/wiki/Rust-at-meta/rust-project/

# Fail if we have any errors
set -e

# Change to this directory
cd -- "$(dirname -- "$0")"

arc rust-project develop fbcode//buck2:buck2 --out ../../rust-project.json


# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under both the MIT license found in the
# LICENSE-MIT file in the root directory of this source tree and the Apache
# License, Version 2.0 found in the LICENSE-APACHE file in the root directory
# of this source tree.

# The commands in this script are to be executed in the current shell
# and so invoke it via the builtin 'source' command e.g. `source
# setup.sh`. It assumes an opam installation. In addition to
# symlinking the 'prelude' directory it activates the 'default' opam
# switch and create symlinks in the 'third-party/opam' directory to
# support building the example OCaml targets.

if ! command -v opam &> /dev/null
then
    echo "opam is not installed, which is a dependency for building targets in ocaml."
    exit
fi

# Bring the OCaml toolchain into scope.
eval "$(opam env --switch=default --set-switch)"

# Link 'third-party/ocaml/standard_library'.
if [ ! -L third-party/ocaml/standard_library ]; then
  (cd third-party/ocaml && ln -s "$(ocamlopt.opt -config | grep standard_library: | awk '{ print $2 }' )" standard_library)
else
    echo "Link 'third-party/ocaml/standard_library' exists. To overwrite it, first remove it and run $0 again"
fi

# Link 'third-party/ocaml/opam'.
if [ ! -L third-party/ocaml/opam ]; then
  (cd third-party/ocaml && ln -s "$OPAM_SWITCH_PREFIX" opam)
else
    echo "Link 'third-party/ocaml/opam' exists. To overwrite it, first remove it and run $0 again"
fi


#!/bin/bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under both the MIT license found in the
# LICENSE-MIT file in the root directory of this source tree and the Apache
# License, Version 2.0 found in the LICENSE-APACHE file in the root directory
# of this source tree.

set -e

# - Apply a debug prefix map for the current directory
# to make debug info relocatable.
# - Use $TMPDIR for the module cache location. This
# will be set to a unique location for each RE action
# which will avoid sharing modules across RE actions.
# This is necessary as the inputs to the modules will
# be transient and can be removed at any point, causing
# module validation errors to fail builds.
if [ -n "$INSIDE_RE_WORKER" ]; then
    MODULE_CACHE_PATH="$TMPDIR/module-cache"
else
    # When building locally we can use a shared module
    # cache as the inputs should remain at a fixed
    # location.
    MODULE_CACHE_PATH="/tmp/buck-module-cache"
fi

module_cache_path_args=()
if [ -z "$EXPLICIT_MODULES_ENABLED" ]; then
    module_cache_path_args+=("-module-cache-path")
    module_cache_path_args+=("$MODULE_CACHE_PATH")
fi

"$@" -debug-prefix-map "$PWD"=. "${module_cache_path_args[@]}"

OUTPUT_PATHS=()
for ARG in "$@"
do
    if [ "${FOUND_OUTPUT_ARG}" = 1 ]; then
        OUTPUT_PATHS+=( "${ARG}" )
    fi
    FOUND_OUTPUT_ARG=0
    if [ "${ARG}" = "-o" ] || [ "${ARG}" = "-emit-module-path" ] || [ "${ARG}" = "-emit-objc-header-path" ]; then
        FOUND_OUTPUT_ARG=1
    fi
done

if [ ${#OUTPUT_PATHS[@]} -eq 0 ]; then
    >&2 echo "No output paths found, ensure output args are not passed in argfiles"
    exit 1
fi

for OUTPUT_PATH in "${OUTPUT_PATHS[@]}"
do
    # We've observed cases where the Swift compiler would return with a zero exit code but
    # would not have created the output file, correctly a non-zero exit code in such cases.
    if [ ! -f "${OUTPUT_PATH}" ]; then
        >&2 echo "Output file does not exist: '${OUTPUT_PATH}'"
        exit 1
    fi
done


#! /bin/bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under both the MIT license found in the
# LICENSE-MIT file in the root directory of this source tree and the Apache
# License, Version 2.0 found in the LICENSE-APACHE file in the root directory
# of this source tree.

set -eu

$1 "${@:2}" 1>&2


#!/bin/bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under both the MIT license found in the
# LICENSE-MIT file in the root directory of this source tree and the Apache
# License, Version 2.0 found in the LICENSE-APACHE file in the root directory
# of this source tree.

PYTHONPATH="$(dirname "$(dirname "$(dirname "$(realpath "$0")")")")"
export PYTHONPATH
exec python3 -m unittest sourcedb_merger.tests


#! /bin/bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

input_logfile=$1
if [[ $# -ne 1 ]] || [[ ! -s "$input_logfile" ]] || [[ ! -f "$input_logfile" ]]; then
    echo "USAGE: $0 LOGFILE"
    echo "produces a tsv containing nvm read/write latencies from LOGFILE"
    echo "if gnuplot is installed, will produce a plot of these latencies"
    echo "LOGFILE should be logging output of cachebench with --progress-stats_file"
    exit 1
fi

percentiles="p50us p90us p99us p999us p9999us p99999us p999999us p100us"
# grep for the lines, convert sequential lines into columns
#   NVM Read Latency p50     : 201.39 us
#   NVM Read Latency p90     : 449.96 us
#   NVM Read Latency p99     : 1054.32 us
#   NVM Read Latency p999    : 2426.05 us
#   NVM Read Latency p9999   : 4632.00 us
#   NVM Read Latency p99999  : 5533.74 us
#   NVM Read Latency p999999 : 5533.74 us
#   NVM Read Latency p100    : 9111.00 us
#
#   becomes
#   1 201.39   449.96   1054.32 .... 9111.00
extract_latency() {
    local in=$3
    local out=$2
    local search=$1

    {
        echo "time $percentiles"
        # get the latency and translate from one per line into 8 columns
        # use sequence number of line as time stamp
        grep -e "$search" "$in"             | \
            awk '{print $6}'                | \
            perl -pe 's/\n/ / if $. % 8'    | \
            awk '{print NR" "$0}'
    }  | column -t > "$out"

    # check if the file actually produced valid content
    [[ "$(wc -l < "$out")" -eq "1" ]] &&                        \
        echo "Incorrect log file. No latecny records found" ||  \
        echo "$search latency written to $out"
}

bandwidth="egress_gb_s ingress_gb_s"
# grep for the last line, convert egressBytesPerSec/ingressBytesPerSec into columns
# egressBytes : 4573.78 GB, ingressBytes: 771.18 GB, egressBytesPerSec :   9.53 GB/s, ingressBytesPerSec:   1.61 GB/s, ingressEgressratio:  83.14%
#
#   becomes
#   9.53   1.61
extract_bandwidth() {
    local in=$3
    local out=$2
    local search=$1

    {
        echo "$bandwidth"
        # get the bandwidth
        grep -e "$search" "$in"             | \
            tail -1                         | \
            awk '{print $10 " " $13}'
    }  | column -t > "$out"

    # check if the file actually produced valid content
    [[ "$(wc -l < "$out")" -eq "1" ]] &&                        \
        echo "Incorrect log file. No bandwidth records found" ||  \
        echo "Bandwidth written to $out"
}

extract_median() {
    local in="$1"
    local column="$2"
    local cnt
    cnt=$(wc -l "$in" | cut -f 1 -d " ")
    local median=$(("$cnt"/2))
    # get the median line's value
    awk -v col="$column" '{print $col}' "$in" | grep -E  '^[0-9]' | sort -n |\
        head -n "$median" | tail -n 1
}

print_median_percentile() {
    local tsv=$1
    local i=2
    local type="$2"
    echo -n "$type "
    for _ in $percentiles; do
        pct_val=$(extract_median "$tsv" $i)
        echo -n "$pct_val "
        i=$((i+1))
    done
    echo
}

out_dir=$(dirname "$input_logfile")
filename=$(basename "$input_logfile")

# location of the intermediate tsv
read_tsv="$out_dir/${filename%%.*}_read_latency.tsv"
write_tsv="$out_dir/${filename%%.*}_write_latency.tsv"
bandwidth_tsv="$out_dir/${filename%%.*}_bandwidth.tsv"

extract_latency "NVM Write Latency" "$write_tsv"  "$input_logfile"
extract_latency "NVM Read  Latency" "$read_tsv"  "$input_logfile"
extract_bandwidth "egressBytesPerSec" "$bandwidth_tsv"  "$input_logfile"

# location of the final latency charts
read_png="$out_dir/${filename%%.*}_read_latency.png"
write_png="$out_dir/${filename%%.*}_write_latency.png"
plot_file="$(dirname "$0")/gnuplot_latency.plt"

plot_png() {
    gnuplot                     \
        -e "tsv='$1'"           \
        -e "out_file='$2'"      \
        -e "chart_title='$3'"   \
        "$4"                &&  \
            echo "Plotted $3 in $2" || \
            echo "Failed to plot $3"
}

plot_png "$read_tsv" "$read_png" "Read Latency" "$plot_file"
plot_png "$write_tsv" "$write_png" "Write Latency" "$plot_file"

echo -e "\n\n======= Median Latency ======= "
{
    echo "OpType $percentiles"
    print_median_percentile "$read_tsv" "read"
    print_median_percentile "$write_tsv" "write"
} | column -t


#!/bin/sh
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

NAME=cachelib

die()
{
  base=$(basename "0")
  echo "$base: error: $*" >&2
  exit 1
}

dir=$(dirname "$0")
cd "$dir/.." || die "failed to change-dir into $dir/.."
test -d cachelib || die "failed to change-dir to expected root directory"

mkdir -p "build-$NAME" || die "failed to create build-$NAME directory"
cd "build-$NAME" || die "'cd' failed"

cmake ../cachelib/ || die "cmake failed"
make -j --keep-going || die "make failed"
#sudo make install || die "make install failed"

#echo "$NAME library is now installed"


#!/bin/sh
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

## Note about shellcheck SC2086
## "Double-quote arguments to prevent globbing and word-splitting"
## https://github.com/koalaman/shellcheck/wiki/SC2086
## In few cases the $XXX_PARAMS argument is NOT double-quoted
## on purpose: it might be empty, and it might have several
## distinct arguments to be passed to other scripts (e.g. "-i -t -D").
##
## As this is done purposfully, and the content of $XXX_PARAMS
## is closely controlled, an explicit 'shellcheck disable SC2086'
## was added to the relevant lines.

set -u

die()
{
  base=$(basename "$0")
  echo "$base: error: $*" >&2
  exit 1
}

show_help_and_exit()
{
  base=$(basename "$0")
  echo "CacheLib dependencies builder

usage: $base [-BdhijStv] NAME

options:
  -B    skip build step
        (default is to build with cmake & make)
  -d    build with DEBUG configuration
        (default is RELEASE with debug information)
  -h    This help screen
  -i    install after build using 'sudo make install'
        (default is to build but not install)
  -j    build using all available CPUs ('make -j')
        (default is to use single CPU)
  -S    skip git-clone/git-pull step
        (default is to get the latest source)
  -t    build tests
        (default is to skip tests if supported by the package)
  -v    verbose build

NAME: the dependency to build supported values are:
  zstd
  googlelog, googleflags, googletest,
  fmt, sparsemap,
  folly, fizz, wangle, fbthrift,
  cachelib

  "
  exit 0
}

###############################
## Parse Commandline arguments
###############################
install=
build=yes
source=yes
debug_build=
build_tests=
show_help=
many_jobs=
verbose=
PREFIX="$PWD/opt/cachelib/"

while getopts :BSdhijtvp: param
do
  case $param in
    i) install=yes ;;
    B) build= ;;
    S) source= ;;
    h) show_help=yes ;;
    d) debug_build=yes ;;
    v) verbose=yes ;;
    j) many_jobs=yes ;;
    t) build_tests=yes ;;
    p) PREFIX=$OPTARG ;;
    ?) die "unknown option. See -h for help."
  esac
done
test -n "$show_help" && show_help_and_exit;
shift $((OPTIND-1))

test "$#" -eq 0 \
    && die "missing dependancy name to build. See -h for help"

######################################
## Check which dependency was requested
######################################

external_git_clone=
external_git_branch=
# external_git_tag can also be used for commit hashes
external_git_tag=
update_submodules=
cmake_custom_params=

case "$1" in
  googlelog)
    NAME=glog
    REPO=https://github.com/google/glog
    REPODIR=cachelib/external/$NAME
    SRCDIR=$REPODIR
    external_git_clone=yes
    external_git_tag="v0.5.0"
    cmake_custom_params="-DBUILD_SHARED_LIBS=ON"
    ;;

  googleflags)
    NAME=gflags
    REPO=https://github.com/gflags/gflags
    REPODIR=cachelib/external/$NAME
    SRCDIR=$REPODIR
    external_git_clone=yes
    external_git_tag="v2.2.2"
    cmake_custom_params="-DGFLAGS_BUILD_SHARED_LIBS=YES"
    if test "$build_tests" = "yes" ; then
        cmake_custom_params="$cmake_custom_params -DGFLAGS_BUILD_TESTING=YES"
    else
        cmake_custom_params="$cmake_custom_params -DGFLAGS_BUILD_TESTING=NO"
    fi
    ;;

  googletest)
    NAME=googletest
    REPO=https://github.com/google/googletest.git
    REPODIR=cachelib/external/$NAME
    SRCDIR=$REPODIR
    # Work-around: build googletest with DEBUG information
    # results in CMake problems in detecting the library.
    # See https://gitlab.kitware.com/cmake/cmake/-/issues/17799
    # Disable debug build, even if requested.
    if test "$debug_build" ; then
        echo "Note: disabling DEBUG mode for googletest build"
        debug_build=
    fi
    cmake_custom_params="-DBUILD_SHARED_LIBS=ON"
    external_git_clone=yes
    ;;

  fmt)
    NAME=fmt
    REPO=https://github.com/fmtlib/fmt.git
    REPODIR=cachelib/external/$NAME
    SRCDIR=$REPODIR
    external_git_clone=yes
    external_git_tag="8.0.1"
    cmake_custom_params="-DBUILD_SHARED_LIBS=ON"
    if test "$build_tests" = "yes" ; then
        cmake_custom_params="$cmake_custom_params -DFMT_TEST=YES"
    else
        cmake_custom_params="$cmake_custom_params -DFMT_TEST=NO"
    fi
    ;;

  zstd)
    NAME=zstd
    REPO=https://github.com/facebook/zstd
    REPODIR=cachelib/external/$NAME
    SRCDIR=$REPODIR/build/cmake
    external_git_clone=yes
    # Previously, we pinned to release branch. v1.5.4 needed
    # CMake >= 3.18, later reverted. While waiting for v1.5.5,
    # pin to the fix: https://github.com/facebook/zstd/pull/3510
    external_git_tag=8420502e
    if test "$build_tests" = "yes" ; then
        cmake_custom_params="-DZSTD_BUILD_TESTS=ON"
    else
        cmake_custom_params="-DZSTD_BUILD_TESTS=OFF"
    fi
    ;;

  sparsemap)
    NAME=sparsemap
    REPO=https://github.com/Tessil/sparse-map.git
    REPODIR=cachelib/external/$NAME
    SRCDIR=$REPODIR
    external_git_clone=yes
    ;;

  folly)
    NAME=folly
    SRCDIR=cachelib/external/$NAME
    update_submodules=yes
    cmake_custom_params="-DBUILD_SHARED_LIBS=ON"
    if test "$build_tests" = "yes" ; then
        cmake_custom_params="$cmake_custom_params -DBUILD_TESTS=ON"
    else
        cmake_custom_params="$cmake_custom_params -DBUILD_TESTS=OFF"
    fi
    ;;

  fizz)
    NAME=fizz
    SRCDIR=cachelib/external/$NAME/$NAME
    update_submodules=yes
    cmake_custom_params="-DBUILD_SHARED_LIBS=ON"
    if test "$build_tests" = "yes" ; then
        cmake_custom_params="$cmake_custom_params -DBUILD_TESTS=ON"
    else
        cmake_custom_params="$cmake_custom_params -DBUILD_TESTS=OFF"
    fi
    ;;

  wangle)
    NAME=wangle
    SRCDIR=cachelib/external/$NAME/$NAME
    update_submodules=yes
    cmake_custom_params="-DBUILD_SHARED_LIBS=ON"
    if test "$build_tests" = "yes" ; then
        cmake_custom_params="$cmake_custom_params -DBUILD_TESTS=ON"
    else
        cmake_custom_params="$cmake_custom_params -DBUILD_TESTS=OFF"
    fi
    ;;

  fbthrift)
    NAME=fbthrift
    SRCDIR=cachelib/external/$NAME
    update_submodules=yes
    cmake_custom_params="-DBUILD_SHARED_LIBS=ON"
    ;;

  cachelib)
    NAME=cachelib
    SRCDIR=cachelib
    if test "$build_tests" = "yes" ; then
        cmake_custom_params="$cmake_custom_params -DBUILD_TESTS=ON"
    else
        cmake_custom_params="$cmake_custom_params -DBUILD_TESTS=OFF"
    fi
    ;;

  *) die "unknown dependency '$1'. See -h for help."
esac

####################################
## Calculate cmake/make parameters
####################################

CMAKE_PARAMS="$cmake_custom_params"
test "$debug_build" \
  && CMAKE_PARAMS="$CMAKE_PARAMS -DCMAKE_BUILD_TYPE=Debug" \
  || CMAKE_PARAMS="$CMAKE_PARAMS -DCMAKE_BUILD_TYPE=RelWithDebInfo"

MAKE_PARAMS=
test "$verbose" && MAKE_PARAMS="$MAKE_PARAMS VERBOSE=YES"

JOBS=$(nproc --ignore 1)
test "$many_jobs" && MAKE_PARAMS="$MAKE_PARAMS -j$JOBS"

####################################
# Real work starts here
####################################

dir=$(dirname "$0")
cd "$dir/.." || die "failed to change-dir into $dir/.."
test -d cachelib || die "expected 'cachelib' directory not found in $PWD"

# After ensuring we are in the correct directory, set the installation prefix"
CMAKE_PARAMS="$CMAKE_PARAMS -DCMAKE_INSTALL_PREFIX=$PREFIX"
CMAKE_PREFIX_PATH="$PREFIX/lib/cmake:$PREFIX/lib64/cmake:$PREFIX/lib:$PREFIX/lib64:$PREFIX:${CMAKE_PREFIX_PATH:-}"
export CMAKE_PREFIX_PATH
PKG_CONFIG_PATH="$PREFIX/lib/pkgconfig:$PREFIX/lib64/pkgconfig:${PKG_CONFIG_PATH:-}"
export PKG_CONFIG_PATH
LD_LIBRARY_PATH="$PREFIX/lib:$PREFIX/lib64:${LD_LIBRARY_PATH:-}"
export LD_LIBRARY_PATH
PATH="$PREFIX/bin:$PATH"
export PATH

##
## Update the latest source code
##

if test "$source" ; then

  if test "$external_git_clone" ; then

    # This is an external (non-facebook) project, clone/pull it.
    if test -d "$SRCDIR" ; then
      # cloned repository already exists, update it, unless we're on a specific tag
      ( cd "$SRCDIR" && git fetch --all ) \
        || die "failed to fetch git repository for '$NAME' in '$SRCDIR'"
    else
      # Clone new repository directory
      git clone "$REPO" "$REPODIR" \
        || die "failed to clone git repository $REPO to '$REPODIR'"
    fi

    # switch to specific branch/tag if needed
    if test "$external_git_branch" ; then
        ( cd "$REPODIR" \
           && git checkout --force "origin/$external_git_branch" ) \
           || die "failed to checkout branch $external_git_branch in $REPODIR"
    elif test "$external_git_tag" ; then
        ( cd "$REPODIR" \
           && git checkout --force "$external_git_tag" ) \
           || die "failed to checkout tag $external_git_tag in $REPODIR"
    fi

  fi

  if test "$update_submodules" ; then
    ./contrib/update-submodules.sh || die "failed to update git-submodules"
  fi
fi

## If we do not build or install (only download the source code),
## exit now.
if test -z "$build" && test -z "$install" ; then
  echo "Source for '$NAME' downloaded/updated"
  exit 0
fi

# The build directory is needed for both build and installation
mkdir -p "build-$NAME" || die "failed to create build-$NAME directory"
cd "build-$NAME" || die "'cd' failed"

##
## Build
##
if test "$build" ; then
  # shellcheck disable=SC2086
  cmake $CMAKE_PARAMS "../$SRCDIR" || die "cmake failed on $SRCDIR"
  # shellcheck disable=SC2086
  nice make $MAKE_PARAMS || die "make failed"
fi

## If no install requested, exit now
if test -z "install" ; then
  echo "'$NAME' is now built in build-$NAME (source in $REPODIR)"
  exit 0
fi

##
## Install
##

if test "$install" ; then
  # shellcheck disable=SC2086
  make $MAKE_PARAMS install || die "make install failed"
fi

echo "'$NAME' is now installed"


#!/bin/sh
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

## Note about shellcheck SC2086
## "Double-quote arguments to prevent globbing and word-splitting"
## https://github.com/koalaman/shellcheck/wiki/SC2086
## In few cases the $pass_params argument is NOT double-quoted
## on purpose: it might be empty, and it might have several
## distinct arguments to be passed to other scripts (e.g. "-i -t -D").
##
## As this is done purposfully, and the content of $pass_params
## is closely controlled, an explicit 'shellcheck disable SC2086'
## was added to the relevant lines.

set -u

die()
{
  base=$(basename "$0")
  echo "$base: error: $*" >&2
  exit 1
}

detect_os()
{
  ### Detect by /etc/os-release (if exists)
  if test -e /etc/os-release ; then
    DETECTED=$(sh -c '. /etc/os-release ; echo ${ID}${VERSION_ID} | tr A-Z a-z')
  fi

  if test -z "$DETECTED" ; then
    ### Detect by lsb_release (if exists)
    if command -v lsb_release >/dev/null 2>&1 ; then
      DETECTED=$(lsb_release -s -ir | tr -d '\n' | tr '[:upper:]' '[:lower:]')
    fi
  fi

  test -n "$DETECTED" || die "failed to detect operating system type"
}

build_debian_10()
{
  ./contrib//prerequisites-debian10.sh \
    || die "failed to install packages for Debian"
}

build_centos_8()
{
  ./contrib/prerequisites-centos8.sh \
    || die "failed to install packages for CentOS"
}

build_rocky_9()
{
  ./contrib/prerequisites-rocky9.sh \
    || die "failed to install packages for RockyLinux 9"
}

build_ubuntu_18()
{
  ./contrib//prerequisites-ubuntu18.sh \
    || die "failed to install packages for Ubuntu"
}

build_fedora_34()
{
  ./contrib//prerequisites-fedora34.sh \
    || die "failed to install packages for Fedora"
}

build_arch()
{
  ./contrib//prerequisites-arch.sh \
    || die "failed to install packages for ArchLinux"
}

build_dependencies()
{
  for pkg in zstd googleflags googlelog googletest sparsemap fmt folly fizz wangle fbthrift ;
  do
    # shellcheck disable=SC2086
    ./contrib/build-package.sh $pass_params "$pkg" \
      || die "failed to build dependency '$pkg'"
  done
}

show_help_and_exit()
{
  base=$(basename "$0")
  echo "CacheLib dependencies builder

usage: $base [-BdhijOStv]

options:
  -B    skip build - just download packages and git source
  -d    build with DEBUG configuration
        (default is RELEASE with debug information)
  -h    This help screen
  -j    build using all available CPUs ('make -j')
        (default is to use single CPU)
  -O    skip OS package installation (apt/yum/dnf)
  -S    skip git-clone/git-pull step
  -t    build tests
        (default is to skip tests if supported by the package)
  -T    build only CacheLib tests
  -v    verbose build

  "
  exit 0
}

###############################
## Parse Commandline arguments
###############################
pass_params=
skip_os_pkgs=
skip_build=
show_help=
build_cachelib_tests=
while getopts BdhjOStvTp: param
do
  case $param in
  h)  show_help=yes ;;
  O)  skip_os_pkgs=yes ;;
  B)  skip_build=yes ;;
  d|j|S|t|v) pass_params="$pass_params -$param" ;;
  T)  build_cachelib_tests=yes ;;
  p)  pass_params="$pass_params -$param $OPTARG" ;;
  ?)      die "unknown option. See -h for help."
  esac
done
test -n "$show_help" && show_help_and_exit;

test -n "$skip_build" \
  && pass_params="$pass_params -B" \
  || pass_params="$pass_params -i"

# Nothing detected so far
DETECTED=
detect_os

if test -z "$skip_os_pkgs" ; then
  case "$DETECTED" in
    debian10|debian11) build_debian_10 ;;
    ubuntu18.04|ubuntu20.04|ubuntu21.04|ubuntu22.04) build_ubuntu_18 ;;
    centos8|rocky8.?) build_centos_8 ;;
    rocky9.?) build_rocky_9 ;;
    fedora3[456]) build_fedora_34 ;;
    arch*|manjaro*) build_arch ;;
    *) die "No build recipe for detected operating system '$DETECTED'" ;;
  esac
fi

build_dependencies

test -n "$build_cachelib_tests" \
  && pass_params="$pass_params -t"

# shellcheck disable=SC2086
./contrib/build-package.sh $pass_params cachelib \
  || die "failed to build cachelib"


#!/usr/bin/env bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -o pipefail
export LC_ALL=C

# In case these directories were not included
export LD_LIBRARY_PATH=/usr/local/lib64:/usr/local/lib:$LD_LIBRARY_PATH

# Default installation path
BINARY=opt/cachelib/bin/cachebench

die()
{
  base=$(basename "$0")
  echo "$base: error: $*" >&2
  exit 1
}

dir=$(dirname "$0")
cd "$dir/.." || die "failed to change-dir into $dir/.."
test -d cachelib || die "failed to change-dir to expected root directory"

test -d build-cachelib || die "the 'build-cachelib' directory wasn't found (try ./contrib/build-cachelib.sh)"

test -e "$BINARY" || die "the executable '$BINARY' was not found"

# Ensure all libraries are found
if ldd "$BINARY" 2>&1 | grep -q "not found" ; then
  die "some shared-object/libraries not found for '$BINARY' - check \$LD_LIBRARY_PATH"
fi

d=$(date +%F-%H%M%S)

dst=dist-$d

# Find parent directory of the binary
BASE_DIR=$(dirname "$BINARY")
BASE_DIR=$(dirname "$BASE_DIR")
LIB_OS_DIR="$BASE_DIR/lib-os"

mkdir -p "$LIB_OS_DIR" \
  || die "failed to create directory '$LIB_OS_DIR'"

ldd "$BINARY" \
    | awk '/=>/ { print $3 }' \
    | sort -u \
    | xargs -I% realpath --no-symlinks --relative-base="$BASE_DIR" "%" \
    | grep "^/" \
    | grep -vE "lib(c|m|dl|rt|pthread)[-.]" \
    | sed -E 's/\.so\.[0-9.]*$/\.so*/' \
    | xargs echo cp --no-dereference -t "$LIB_OS_DIR" \
    | sh \
   || die "failed to extract and copy shared-object dependencies"

tar -C opt -czf "cachelib-rpath-binary-$d.tar.gz" cachelib \
  || die "failed to create tarball"

echo "
  Tarball in:
     cachelib-rpath-binary-$d.tar.gz
"


#!/bin/sh
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

sudo pacman -S --needed --noconfirm cmake \
  make \
  gcc \
  boost \
  double-conversion \
  libdwarf \
  numactl \
  libsodium


#!/bin/sh
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

sudo dnf install -y epel-release
sudo dnf groupinstall -y "Development Tools"
sudo dnf install -y \
  libtool bison flex cmake \
  double-conversion double-conversion-devel \
  boost-devel \
  libevent-devel \
  openssl-devel \
  libunwind-devel \
  zlib-devel \
  lz4-devel \
  xz-devel \
  bzip2-devel \
  jemalloc-devel \
  libsodium-devel \
  libaio-devel \
  binutils-devel

# Install and enable the "PowerTools" repository
sudo dnf -y install dnf-plugins-core
sudo dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm

# CentOS Repository name changed from "PowerTools" to "powertools" (and back?)
# Get the list of ALL repositories, try to detect the 'powertools' one.
# We could do:
#    dnf config-manager --set-enabled PowerTools
#    dnf config-manager --set-enabled powertools
# But we don't want to change the system's repository configuration.

# Show list of repos (for debugging)
sudo dnf repolist --all

POWERTOOLS_REPO=$(sudo dnf repolist --all | grep -i '^powertools' | awk '{print $1}')
echo "Detected CentOS Powertools repository: '$POWERTOOLS_REPO'"

sudo dnf --enablerepo="$POWERTOOLS_REPO" install -y \
  libdwarf-devel \
  snappy-devel \
  gmock-devel \
  gtest-devel \
  libsodium-static \
  libdwarf-static \
  boost-static \
  double-conversion-static \
  numactl-devel

#Do not install these from OS packages - they are typically outdated.
#gflags-devel \
#glog \
#fmt \


#!/bin/sh
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

sudo apt-get update
sudo apt-get install -y \
  build-essential \
  git \
  g++ \
  cmake \
  bison flex \
  libboost-all-dev \
  libevent-dev \
  libdouble-conversion-dev \
  libgoogle-glog-dev \
  libgflags-dev \
  libiberty-dev \
  liblz4-dev \
  liblzma-dev \
  libbz2-dev \
  libsnappy-dev \
  make \
  zlib1g-dev \
  binutils-dev \
  libjemalloc-dev \
  libssl-dev \
  pkg-config \
  libunwind-dev \
  libelf-dev \
  libdwarf-dev \
  libsodium-dev \
  libgmock-dev \
  libgtest-dev googletest \
  libnuma-dev


#!/bin/sh
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

sudo dnf -y update
sudo dnf groupinstall -y "Development Tools"
sudo dnf -y install bison flex patch bzip2 cmake \
  double-conversion double-conversion-devel \
  boost-devel libevent-devel openssl-devel libunwind-devel \
  zlib-devel lz4-devel xz-devel bzip2-devel \
  jemalloc-devel snappy-devel libsodium-devel libdwarf-devel libaio-devel \
  gmock-devel gflags-devel gtest gtest-devel \
  numactl-devel \
  fmt fmt-devel

# DO NOT INSTALL glog-devel - need to build from source for the glog-*.cmake files


#!/bin/sh
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

sudo dnf -y update
sudo dnf groupinstall -y "Development Tools"
sudo dnf -y install bison flex patch bzip2 cmake \
  double-conversion double-conversion-devel make g++ \
  boost-devel libevent-devel openssl-devel libunwind-devel \
  zlib-devel lz4-devel xz-devel bzip2-devel \
  jemalloc-devel snappy-devel libsodium-devel libdwarf-devel libaio-devel \
  numactl-devel


#!/bin/sh
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# RockyLinux 9 diverged from CentOS, instead of "Powertools" repo,
# use CRB (CodeBuild Ready).
# see: https://wiki.rockylinux.org/rocky/repo/

sudo dnf update -y
sudo dnf install dnf-plugins-core
sudo dnf install -y epel-release
sudo dnf config-manager --set-enabled crb

sudo dnf groupinstall -y "Development Tools"
sudo dnf install -y \
  libtool bison flex cmake \
  double-conversion double-conversion-devel \
  boost-devel \
  libevent-devel \
  openssl-devel \
  libunwind-devel \
  zlib-devel \
  lz4-devel \
  xz-devel \
  bzip2-devel \
  jemalloc-devel \
  libsodium-devel \
  libaio-devel \
  binutils-devel \
  numactl-devel

sudo dnf install -y \
  libdwarf-devel \
  snappy-devel \
  gmock-devel \
  gtest-devel \
  libsodium-static \
  libdwarf-static \
  boost-static \
  double-conversion-devel


#!/bin/sh
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

sudo apt-get update
sudo apt-get install -y \
  build-essential \
  git \
  g++ \
  cmake \
  bison flex \
  libboost-all-dev \
  libevent-dev \
  libdouble-conversion-dev \
  libgoogle-glog-dev \
  libgflags-dev \
  libiberty-dev \
  liblz4-dev \
  liblzma-dev \
  libbz2-dev \
  libsnappy-dev \
  make \
  zlib1g-dev \
  binutils-dev \
  libjemalloc-dev \
  libssl-dev \
  pkg-config \
  libunwind-dev \
  libelf-dev \
  libdwarf-dev \
  libsodium-dev \
  libnuma-dev

# NOTE:
# GoogleTest/GoogleMock libraries are available in Ubuntu as
# Standard packages, but the do not contain the required CMAKE
# files, and aren't detected when building CacheLib.
# So on Ubuntu-18 - build googletest from source.
### googletest libgtest-dev google-mock


#!/bin/sh
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

die()
{
  base=$(basename "$0")
  echo "$base: error: $*" >&2
  exit 1
}

dir=$(dirname "$0")
cd "$dir/.." || die "failed to change-dir into $dir/.."
test -d cachelib || die "failed to change-dir to expected root directory"

git submodule update --init --checkout --force
git submodule foreach git fetch

root=./cachelib/external

# Temporary hack:
# After updating, checkout the required version based on fbthrift's files.
file="$root/fbthrift/build/deps/github_hashes/facebook/wangle-rev.txt"
wangle_rev=$(awk '{print $3}' $file) \
  || die "failed to detect required wangle revision"

( cd "$root/wangle" ; git checkout --force "$wangle_rev" ) \
  || die "failed to checkout required wangle revision '$wangle_rev'"

# Based on Wangle, checkout fizz
file="$root/wangle/build/deps/github_hashes/facebookincubator/fizz-rev.txt"
fizz_rev=$(awk '{print $3}' $file) \
  || die "failed to detect required fizz revision"

( cd "$root/fizz" ; git checkout --force "$fizz_rev" ) \
  || die "failed to checkout required fizz revision '$fizz_rev'"


#!/bin/sh
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -e

# Root directory for the CacheLib project
CLBASE="$PWD/../.."

# Additional "FindXXX.cmake" files are here (e.g. FindSodium.cmake)
CLCMAKE="$CLBASE/cachelib/cmake"

# After ensuring we are in the correct directory, set the installation prefix"
PREFIX="$CLBASE/opt/cachelib/"

CMAKE_PARAMS="-DCMAKE_INSTALL_PREFIX='$PREFIX' -DCMAKE_MODULE_PATH='$CLCMAKE'"

CMAKE_PREFIX_PATH="$PREFIX/lib/cmake:$PREFIX/lib64/cmake:$PREFIX/lib:$PREFIX/lib64:$PREFIX:${CMAKE_PREFIX_PATH:-}"
export CMAKE_PREFIX_PATH
PKG_CONFIG_PATH="$PREFIX/lib/pkgconfig:$PREFIX/lib64/pkgconfig:${PKG_CONFIG_PATH:-}"
export PKG_CONFIG_PATH
LD_LIBRARY_PATH="$PREFIX/lib:$PREFIX/lib64:${LD_LIBRARY_PATH:-}"
export LD_LIBRARY_PATH

mkdir -p build
cd build
cmake $CMAKE_PARAMS ..
make


#!/bin/sh
# Copyright (c) 2022-present, Meta, Inc.
# All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Shell script so that this can be made non-dependent on
# chef-workstation in the future
exec /opt/chef-workstation/embedded/bin/ruby /usr/local/lib/bookworm/bookworm.rb "$@"


#!/bin/bash

# Copyright (c) 2018-present, Facebook, Inc.

if [ $# -lt 1 ] || [ "$1" == "-h" ] || [ "$1" == "--help" ]; then
  echo "Uses file locking to runs a single instance of a command "
  echo "on a host at a time. Intended to stop cron job stampedes"
  echo ""
  echo "Usage: exclusive_cron.sh <lockfile path> <command to run>"
  echo ""
  echo "NOTE: Uses flock, so lockfiles must be on local storage"
  exit 1;
fi

LOCKFILE="${1}"
shift 1
COMMAND="$*"

if [ -e "${LOCKFILE}" ] && [ ! -f "${LOCKFILE}" ]; then
  echo "Lockfile ${LOCKFILE} exists, but is not a file"
  exit 1;
fi

function on_exit() {
  rm -f "${LOCKFILE}";
}

# FD200 is completely arbitrary
(
  if ! flock -x -w 0.001 200; then
    echo "Command '${COMMAND}' with lockfile '${LOCKFILE}' is already running"
    exit 1
  fi
  trap 'on_exit' EXIT
  eval "${COMMAND}"
) 200>"${LOCKFILE}"


#!/bin/bash
#
# Copyright (c) 2018-present, Facebook, Inc.
#
# OS X doesn't support cron.d directories. It also doesn't have a stock
# /etc/crontab -- so we fake it here.

set -e

# OS X also doesn't have a "tempfile" command...
tempfile="/tmp/cron.d.$$"

cat /etc/cron.d/* > "$tempfile"

if ! diff "$tempfile" "/etc/crontab" > /dev/null 2> /dev/null
then
  echo "Installing new /etc/crontab"
  mv -f "$tempfile" /etc/crontab
else
  rm -f "$tempfile"
fi


#!/bin/sh

# vim: syntax=sh:expandtab:shiftwidth=2:softtabstop=2:tabstop=2

set -u

# This script is meant to be called in dbus.service by ExecStartPost. It will
# trigger a systemd reload, unless it's the first time it runs or when current
# systemd target is active, which means systemd finished boot up procedure.

flag='/run/dbus-was-started-once'

# current systemd target
target=$(systemctl get-default)

# status of systemd target
result=$(systemctl is-active "$target")

if [ -r "$flag" ]; then
  echo 'dbus-restart-hack: reloading systemd as the flag file exists'
  sleep 1
  /usr/bin/systemctl daemon-reload
elif [ "$result" = "active" ]; then
  echo "dbus-restart-hack: reloading systemd as current target $target is active"
  sleep 1
  /usr/bin/systemctl daemon-reload
else
  echo 'dbus-restart-hack: not reloading systemd as this is the first start'
fi

touch "$flag"

exit 0


#!/bin/bash
# shellcheck disable=SC2086,SC2018,SC2019,SC1090,SC2064,SC2124,SC2181,SC2002,SC2153,SC2046,SC2173,SC2230
#
# Copyright (c) 2016-present, Facebook, Inc.
# All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

# Simple script for chef to call to
# dump and reload custom chain rules

set -u

CONFIG='/etc/fb_iptables.conf'
TMPDIR=$(mktemp -d /tmp/fb_iptables.XXXXXXXXXXXX)
trap "rm -rf $TMPDIR &>/dev/null" exit INT TERM KILL

help_print() {
  echo "$0 [4|6] <action>"
  exit;
}

exit_error() {
  msg="$@"
  echo "ERROR: $msg"
  exit 1
}

# Walk dynamic changes for a table and dump them to temp files in, if they exist
dump_dynamic_chains() {
  local table="$1"
  local dynamic_chains="$2"
  local outfile
  local chain_regex
  echo -n "  - Stashing dynamic chains on $table: "
  for chain in $dynamic_chains; do
    echo -n "$chain  "
    "${IPTABLES_CMD}" -t "$table" -S | grep -q "\-N $chain"
    if [ $? -ne 0 ]; then
      echo '(no chain yet, nothing to stash) '
      continue
    fi
    outfile=$TMPDIR/${table}_${chain}_rules
    chain_regex="\-A $chain "
    out=$("${IPTABLES_CMD}" -t "$table" -S)
    if [ $? -ne 0 ]; then
      exit_error "Failed to stash $chain on $table"
    fi
    if [ -n "$out" ]; then
      echo "$out" | grep "$chain_regex" > "$outfile"
    fi
  done
  echo 'done.'
}

# Restore any registered chains we found and backed up
restore_dynamic_chains() {
  local table="$1"
  local dynamic_chains="$2"

  echo -n "  - Restoring dynamic chains on $table: "
  for chain in $dynamic_chains; do
    echo -n "$chain "
    local rules_file=$TMPDIR/${table}_${chain}_rules
    if [ ! -r $rules_file ]; then
      echo '(no chain to restore) '
      continue
    fi

    ${IPTABLES_CMD} -t $table -F $chain
    while read -r rule
    do
      ${IPTABLES_CMD} -t $table $rule
    done < "$rules_file"
  done
  echo 'done.'
}

reload_static_chains() {
  local table="$1"

  # NOTE: You cannot use '-t' here ... ip6tables-* choke on it... you must
  # specify --table=
  echo "  - Reloading $table"
  cat "${CONFIG_DIR}/${IPTABLES_RULES_FILE}" | ${IPTABLES_CMD}-restore --table=$table
}

reload() {
    for table in $TABLES; do
      # iptables-restore triggers loading modules, even with empty
      # rules.  Let's avoid that (t28313270).
      echo "Reloading $table..."
      cap_table=$(echo $table | tr 'a-z' 'A-Z')
      static_chains=$(eval echo \$STATIC_${cap_table}_CHAINS)
      if [ -z "$static_chains" ] && ! grep -q $table /proc/net/ip*_tables_names; then
        continue
      fi
      dynamic_chains=$(eval echo \$${cap_table}_CHAINS)
      dump_dynamic_chains $table "$dynamic_chains"
      reload_static_chains $table
      restore_dynamic_chains $table "$dynamic_chains"
  done
}

[ -r "$CONFIG" ] && . $CONFIG

# Poor mans help print
if [ "$1" == "help" ]; then
  help_print
fi

# v4 or v6
IPTABLES_CMD=ip6tables
IPTABLES_RULES_FILE="$RULES6_FILE"
if [ "$1" == "4" ]; then
  IPTABLES_CMD=iptables
  IPTABLES_RULES_FILE="$RULES_FILE"
fi
ACTION="$2"

if [ ! -x $(which "${IPTABLES_CMD}") ]; then
  echo "ERROR: No ${IPTABLES_CMD} in path bro ..."
  exit 1
fi

case "$ACTION" in
  reload)
    reload
    ;;
  *)
    help_print
    ;;
esac


#!/bin/bash
#
# To use this filter with less, define LESSOPEN:
# export LESSOPEN="|/usr/bin/lesspipe.sh %s"
#
# The script should return zero if the output was valid and non-zero
# otherwise, so less could detect even a valid empty output
# (for example while uncompressing gzipped empty file).
# For backward-compatibility, this is not required by default. To turn
# this functionality there should be another vertical bar (|) straight
# after the first one in the LESSOPEN environment variable:
# export LESSOPEN="||/usr/bin/lesspipe.sh %s"

if [ ! -e "$1" ] ; then
	exit 1
fi

if [ -d "$1" ] ; then
	ls -alF -- "$1"
	exit $?
fi

exec 2>/dev/null

# Allow for user defined filters
if [ -x ~/.lessfilter ]; then
	if ~/.lessfilter "$1"; then
		exit 0
	fi
fi

manfilter ()
{
	if test -x /usr/bin/man ; then
		# See rhbz#1241543 for more info.  Well, actually we firstly
		# used 'man -l', then we switched to groff, and then we again
		# switched back to 'man -l'.
		/usr/bin/man -P /usr/bin/cat -l "$1"
	elif test -x /usr/bin/groff; then
		# This is from pre-rhbz#1241543-time.
		groff -Tascii -mandoc "$1" | cat -s
	else
		echo "WARNING:"
		echo "WARNING: to better show manual pages, install 'man-db' package"
		echo "WARNING:"
		cat "$1"
	fi
}

export MAN_KEEP_FORMATTING=1

case "$1" in
*.[1-9n].bz2|*.[1-9]x.bz2|*.man.bz2|*.[1-9n].[gx]z|*.[1-9]x.[gx]z|*.man.[gx]z|*.[1-9n].lzma|*.[1-9]x.lzma|*.man.lzma|*.[1-9n].zst|*.[1-9]x.zst|*.man.zst)
	case "$1" in
	*.gz)		DECOMPRESSOR="gzip -dc" ;;
	*.bz2)		DECOMPRESSOR="bzip2 -dc" ;;
	*.xz|*.lzma)	DECOMPRESSOR="xz -dc" ;;
	*.zst)		DECOMPRESSOR="zstd -dcq" ;;
	esac
	if [ -n "$DECOMPRESSOR" ] && $DECOMPRESSOR -- "$1" | file - | grep -q troff; then
		$DECOMPRESSOR -- "$1" | manfilter -
		exit $?
	fi ;;&
*.[1-9n]|*.[1-9]x|*.man)
	if file "$1" | grep -q troff; then
		manfilter "$1"
		exit $?
	fi ;;&
*.tar) tar tvvf "$1"; exit $? ;;
*.tgz|*.tar.gz|*.tar.[zZ]) tar tzvvf "$1"; exit $? ;;
*.tar.xz) tar Jtvvf "$1"; exit $? ;;
*.tzst|*.tar.zst) tar -I zstd tvvf "$1"; exit $? ;;
*.xz|*.lzma) xz -dc -- "$1"; exit $? ;;
*.tar.bz2|*.tbz2) bzip2 -dc -- "$1" | tar tvvf -; exit $? ;;
*.[zZ]|*.gz) gzip -dc -- "$1"; exit $? ;;
*.bz2) bzip2 -dc -- "$1"; exit $? ;;
*.zst) zstd -dcq -- "$1"; exit $? ;;
*.zip|*.jar|*.nbm) zipinfo -- "$1"; exit $? ;;
# --nomanifest -> rhbz#1450277
*.rpm) rpm -qpivl --changelog --nomanifest -- "$1"; exit $? ;;
*.cpi|*.cpio) cpio -itv < "$1"; exit $? ;;
*.gpg)
	if [ -x /usr/bin/gpg2 ]; then
		gpg2 -d "$1"
		exit $?
	elif [ -x /usr/bin/gpg ]; then
		gpg -d "$1"
		exit $?
	else
		echo "No GnuPG available."
		echo "Install gnupg2 or gnupg to show encrypted files."
		exit 1
	fi ;;
*.gif|*.jpeg|*.jpg|*.pcd|*.png|*.tga|*.tiff|*.tif)
	if [ -x /usr/bin/identify ]; then
		identify "$1"
		exit $?
	elif [ -x /usr/bin/gm ]; then
		gm identify "$1"
		exit $?
	else
		echo "No identify available"
		echo "Install ImageMagick or GraphicsMagick to browse images"
		exit 1
	fi ;;
*)
	if [ -x /usr/bin/file ] && [ -x /usr/bin/iconv ] && [ -x /usr/bin/cut ]; then
    case $(file -b "$1") in
		*UTF-16*) conv='UTF-16' ;;
		*UTF-32*) conv='UTF-32' ;;
		esac
		if [ -n "$conv" ]; then
      env=$(echo "$LANG" | cut -d. -f2)
			if [ -n "$env" ] && [ "$conv" != "$env" ]; then
				iconv -f "$conv" -t "$env" "$1"
				exit $?
			fi
		fi
	fi
	exit 1
esac


# shellcheck shell=sh

# Set some useful LESS options.  If you prefer your own, set it in
# your shell startup script and it will be honored.
if [ -z "${LESS+set}" ]; then
    export LESS='-n -i'
fi
if [ -z "${LESSOPEN+set}" ]; then
	export LESSOPEN='||/usr/local/bin/lesspipe.sh %s'
fi


#!/bin/bash
#
# vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
#
# Copyright (c) 2022-present, Vicarious, Inc.
# All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# A script to help downstream users keep cookbooks in sync

set -u

# constants
CONF="$HOME/.config/sync_fb_cookbooks.conf"

# defaults
upstreamdir="$HOME/src/chef-cookbooks"
internaldir="$HOME/src/chef"

# methods
error() {
    echo "ERROR: $*"
}

warn() {
    echo "WARNING: $*"
}

die() {
    error "$@"
    exit 1
}

ourhelp() {
    cat <<EOF
Usage: $0 [<options>]

OPTIONS
    -c <cookbook>
        Compare just <cookbook>

    -d
        Diff mode.

    -h
        This.

    -i <dir>
        Where your clone of the INTERNAL repo is.
        Default: $internaldir

    -p
        Push changes internal -> upstream

    -s
        Sync changes upstream -> internal

    -u <dir>
        Where your clone of the UPSTREAM repo is.
        Default: $internaldir

CONFIG FILE
You can also tell this script where your repos are by creating $CONF
in shell format and defining 'upstreamdir' and 'internaldir', like so:

    upstreamdir="\$HOME/mycheckouts/chef-cookbooks"
    internaldir="\$HOME/mycheckouts/chef"

GENERAL USAGE
    # get a list of cookbooks that differ
    $ $0
    ...
    fb_sysfs does not match
    ...

    # Get a diff for a specific cookbook
    $ $0 -c fb_sysfs
    ...

    # Pull in upstream changes
    $ $0 -c fb_sysfs -s
    ...

    # OR.... push out internal changes
    $ $0 -c fb_sysfs -p

EOF
}

# people put repos in different places, don't make them pass in
# -u and -i every time.
if [ -e "$CONF" ]; then
    # shellcheck disable=SC1090
    source "$CONF" || die "Configuration file $CONF malformed"
fi

mode=''
cookbook=''
while getopts c:dhi:psu: opt; do
    case $opt in
        c)
            cookbook="$OPTARG"
            ;;
        d)
            mode='diff'
            ;;
        h)
            ourhelp
            exit
            ;;
        i)
            internaldir="$OPTARG"
            ;;
        p)
            mode='push'
            ;;
        s)
            mode='sync'
            ;;
        u)
            upstreamdir="$OPTARG"
            ;;
        ?)
            ourhelp
            exit 1
            ;;
    esac
done

if [ -z "$mode" ]; then
    if [ -n "$cookbook" ]; then
        mode='diff'
    else
        mode='status'
    fi
fi

cd "$internaldir/cookbooks" || die "where am I?"
[ -z "$cookbook" ] && cookbook="$(ls -d fb_*)"
for cb in $cookbook; do
    ours="$cb/"
    upstream="$upstreamdir/cookbooks/$cb/"
    if [ "$cb" = 'fb_init' ]; then
        upstream="$upstreamdir/cookbooks/fb_init_sample/"
    fi
    if [ "$mode" = 'status' ]; then
        diff -Nru "$ours" "$upstream" &>/dev/null || echo "$cb does not match"
    elif [ "$mode" = 'diff' ]; then
        diff -Nru "$ours" "$upstream"
    elif [ "$mode" = 'push' ]; then
        rsync -avz "$ours" "$upstream"
    elif [ "$mode" = 'sync' ]; then
        rsync -avz "$upstream" "$ours"
    else
        die "wut? wut mode is '$mode'"
    fi
done


#!/bin/sh

# Go to root directory of the script
pushd $(dirname $0)

if [ -z $1 ]; then
  echo "usage: build.sh <subcommand>"
  echo "available subcommands:"
  echo "  ci-componentkit-ios"
  echo "  ci-componentkit-tvos"
  echo "  ci-wildeguess-ios"
  echo "  docs"
  exit
fi

set -eu

MODE=$1

function project_version() {
  # get contents -> grep for project version line -> cut string with '=' delimeter, take 2nd value -> trim whitespaces.
  more ComponentKit/ComponentKit.xcconfig | grep "CURRENT_PROJECT_VERSION = [\.0-9]*" | cut -d = -f 2 | xargs echo -n
}

function ci() {
  # replace line contains s.version with a new line contains value of `project_version`.
  sed -i -e "s/s.version = \'[\.0-9]*\'/s.version = \'$(project_version)\'/g" ComponentKit.podspec

  xcodebuild \
    clean \
    -project $1 \
    -scheme $2 \
    -sdk $3 \
    -destination "$4" \
    -configuration $5 \
    $6 \
    -json \
    -UseModernBuildSystem=NO
}

function ios_ci() {
  ci $1 $2 iphonesimulator "platform=iOS Simulator,name=iPhone 8" Release $3
}

function tvos_ci() {
  ci $1 $2 appletvsimulator "platform=tvOS Simulator,name=Apple TV" Release $3
}

function carthage_bootstrap() {
  carthage bootstrap --platform iOS --no-use-binaries || true
}

carthage_bootstrap

if [ "$MODE" = "ci-componentkit-ios" ]; then
  ios_ci ComponentKit.xcodeproj ComponentKit test
fi

if [ "$MODE" = "ci-componentkit-tvos" ]; then
  tvos_ci ComponentKit.xcodeproj ComponentKitAppleTV test
fi

if [ "$MODE" = "ci-wildeguess-ios" ]; then
  ios_ci Examples/WildeGuess/WildeGuess.xcodeproj WildeGuess build
fi

if [ "$MODE" = "docs" ]; then
  HEADERS=`ls ComponentKit/**/*.h ComponentTextKit/**/*.h`
  rm -rf appledoc
  appledoc \
    --no-create-docset \
    --create-html \
    --exit-threshold 2 \
    --no-repeat-first-par \
    --no-merge-categories \
    --explicit-crossref \
    --warn-missing-output-path \
    --warn-missing-company-id \
    --warn-undocumented-object \
    --warn-undocumented-member \
    --warn-empty-description \
    --warn-unknown-directive \
    --warn-invalid-crossref \
    --warn-missing-arg \
    --project-name ComponentKit \
    --project-company Facebook \
    --company-id "org.componentkit" \
    --output appledoc \
    $HEADERS
fi

# Go back to the initial directory
popd