#!/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.

printf "'package' module resolves to file:\n"
assert_errors "$FLOW" status
echo

printf "duplicate provider:\n"
mv fixtures/package package
# changing a package will restart the server, so update saved_state_file_changes
if [ -f .flow.saved_state_file_changes ]; then
  printf "package/package.json\npackage/index.js\n" > .flow.saved_state_file_changes
fi
assert_ok "$FLOW" force-recheck package/package.json package/index.js
assert_errors "$FLOW" status
echo

printf "'package' module resolves to package:\n"
mv package.js fixtures/package.js
assert_ok "$FLOW" force-recheck package.js
assert_errors "$FLOW" status
echo

printf "duplicate provider:\n"
mv fixtures/package.js package.js
assert_ok "$FLOW" force-recheck package.js
assert_errors "$FLOW" status
echo

printf "'package' module resolves to file again:\n"
mv package fixtures/package
# changing a package will restart the server, so update saved_state_file_changes
if [ -f .flow.saved_state_file_changes ]; then
  echo "" > .flow.saved_state_file_changes
fi
assert_ok "$FLOW" force-recheck package/package.json package/index.js
assert_errors "$FLOW" status


#!/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.

# The server starts in lazy mode. First trigger a slow recheck.
# This will check slow_dependent and dependency.
printf "\nTrigger a slow recheck: "
assert_ok "$FLOW" force-recheck --focus slow_dependent.js
printf "DONE\n"

# Sleep for a bit to give the recheck a chance to actually start
# rechecking the file (vs calculating deps, etc).
printf "\nSleep: "
sleep 1
printf "DONE\n"

start_time=$(date +"%s.%N")

# While that's running, try to get-def on fast_dependent, which
# also needs dependency. It should cancel the slow recheck and
# answer quickly.
printf "\nGet-def with unchecked dependency:\n"
assert_ok "$FLOW" get-def fast_dependent.js 5 2 --strip-root --json

printf "\nDid it finish in less than 2 seconds? "
end_time=$(date +"%s.%N")
echo "$start_time $end_time" | awk '{ s=$1; e=$2; print ((e - s) < 2) ? "YES" : "NO"; }'

# Then the slow recheck should restart and eventually finish.
printf "\nOriginal recheck finished:\n"
assert_errors "$FLOW" status --no-auto-start


#!/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.

# shellcheck disable=SC2094

printf "==== No errors at start====\\n"
assert_ok "$FLOW" status --no-auto-start

# simulate a file watcher race condition by changing dependency.js without
# a force-recheck.
printf "\\n\\nexport const y = 123;\\n" >> dependency.js

# checking file.js needs dependency.js, and we notice it's changed. we have
# to re-merge it, but check-contents doesn't wait for dependent.js to be checked.
printf "\\n==== Checking file.js finds errors ====\\n"
assert_errors "$FLOW" check-contents --strip-root file.js < file.js
# 1 file should be merged (dependency) and nothing should be checked
show_skipping_stats "$FLOW_LOG_FILE"

# here's the late file watcher update
assert_ok "$FLOW" force-recheck dependency.js

# even though we've already noticed the update, now is when we actually
# recheck dependency.js and its dependents, and find the error in
# dependent.js
printf "\\n==== force-recheck checks dependent ====\\n"
assert_errors "$FLOW" status --no-auto-start
# 3 files (dependency.js and its dependents, dependent.js and file.js) should
# be both merged and checked
show_skipping_stats "$FLOW_LOG_FILE"


#!/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.

printf "Without --include-suppressed\n"
assert_errors "$FLOW" check --all --strip-root

printf "\n\nWith --include-suppressed\n"
assert_errors "$FLOW" check --all --strip-root --include-suppressed

printf "\n\nJSON without --include-suppressed\n"
assert_errors \
  "$FLOW" check --all --strip-root --json --pretty \
  | grep -v '^ *"flowVersion":.*'

printf "\n\nJSON with --include-suppressed\n"
assert_errors \
  "$FLOW" check --all --strip-root --include-suppressed --json --pretty \
  | grep -v '^ *"flowVersion":.*'

printf "\n\nServer without --include-suppressed\n"
"$FLOW" start --wait --all
assert_errors "$FLOW" status --no-auto-start
"$FLOW" stop

printf "\n\nServer with --include-suppressed\n"
"$FLOW" start --wait --all --include-suppressed
assert_errors "$FLOW" status --no-auto-start
"$FLOW" stop

printf "\n"


#!/bin/sh
# 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.

printf "Without --include-warnings\n"
assert_errors "$FLOW" check --all --strip-root

printf "\n\nWith --include-warnings\n"
assert_errors "$FLOW" check --all --strip-root --include-warnings

printf "\n\nJSON without --include-warnings\n"
assert_errors "$FLOW" check --all --strip-root --pretty \
  | grep -v '^ *"flowVersion":.*'

printf "\n\nJSON with --include-warnings\n"
assert_errors "$FLOW" check --all --strip-root --include-warnings --pretty \
  | grep -v '^ *"flowVersion":.*'

printf "\n"


#!/bin/sh
# 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.

printf "EMPTY FLOWCONFIG\n"
assert_ok "$FLOW" stop
cp empty_flowconfig .flowconfig
start_flow .

printf "\n\nCheck Without --include-warnings\n"
assert_errors "$FLOW" check --strip-root

printf "\n\nCheck With --include-warnings\n"
assert_errors "$FLOW" check --strip-root --include-warnings

printf "\n\nCheck-contents Without --include-warnings\n"
assert_errors "$FLOW" check-contents test.js --strip-root < test.js

printf "\n\nCheck-contents With --include-warnings\n"
assert_errors "$FLOW" check-contents test.js --strip-root --include-warnings < test.js

printf "\n\nStatus Without --include-warnings\n"
assert_errors "$FLOW" status --strip-root

printf "\n\nStatus With --include-warnings\n"
assert_errors "$FLOW" status --strip-root --include-warnings

printf "\n\n\n\nINCLUDE_WARNINGS FLOWCONFIG\n"
assert_ok "$FLOW" stop
cp include_warnings_flowconfig .flowconfig
start_flow .

printf "\n\nCheck Without --include-warnings\n"
assert_errors "$FLOW" check --strip-root

printf "\n\nCheck With --include-warnings\n"
assert_errors "$FLOW" check --strip-root --include-warnings

printf "\n\nCheck-contents Without --include-warnings\n"
assert_errors "$FLOW" check-contents test.js --strip-root < test.js

printf "\n\nCheck-contents With --include-warnings\n"
assert_errors "$FLOW" check-contents test.js --strip-root --include-warnings < test.js

printf "\n\nStatus Without --include-warnings\n"
assert_errors "$FLOW" status --strip-root

printf "\n\nStatus With --include-warnings\n"
assert_errors "$FLOW" status --strip-root --include-warnings


#!/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.

mkdir tmp
cp ./*.js tmp/
assert_errors "$FLOW" status .
cp tmp1/*.js ./
assert_ok "$FLOW" force-recheck ./*.js # overapproximation
assert_errors "$FLOW" status .
cp tmp2/*.js ./
assert_ok "$FLOW" force-recheck ./*.js # overapproximation
assert_errors "$FLOW" status .
cp tmp3/*.js ./
assert_ok "$FLOW" force-recheck ./*.js # overapproximation
assert_errors "$FLOW" status .
mv tmp/*.js ./
rmdir tmp


#!/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.

mkdir tmp

printf "\nInitial status:\n"
assert_ok "$FLOW" status --no-auto-start .
cp A.js tmp/

printf "\nClear A.js:\n"
cp tmp1/A.js A.js
assert_ok "$FLOW" force-recheck --no-auto-start A.js
assert_errors "$FLOW" status --no-auto-start .

printf "\nRestore A.js:\n"
mv tmp/A.js A.js
assert_ok "$FLOW" force-recheck --no-auto-start A.js
assert_ok "$FLOW" status --no-auto-start .

rmdir tmp
printf "\nDone!\n"


#!/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.

mkdir tmp
cp foo.js tmp/

printf "\nInitial status...with type errors:\n"
assert_errors "$FLOW" status --no-auto-start .

printf "\nDelete foo.js (cannot resolve module!):\n"
rm foo.js
assert_ok "$FLOW" force-recheck --no-auto-start foo.js
assert_errors "$FLOW" status --no-auto-start .

printf "\nRestore foo.js (same as initial status):\n"
cp tmp/foo.js .
assert_ok "$FLOW" force-recheck --no-auto-start foo.js
assert_errors "$FLOW" status --no-auto-start .

printf "\nRemove @flow in foo.js:\n"
cp tmp1/foo.js .
assert_ok "$FLOW" force-recheck --no-auto-start foo.js
assert_errors "$FLOW" status --no-auto-start .

printf "\nRestore foo.js (same as initial status):\n"
cp tmp/foo.js .
assert_ok "$FLOW" force-recheck --no-auto-start foo.js
assert_errors "$FLOW" status --no-auto-start .

printf "\nIntroduce parse error in foo.js (unexpected identifier!):\n"
cp tmp2/foo.js .
assert_ok "$FLOW" force-recheck --no-auto-start foo.js
assert_errors "$FLOW" status --no-auto-start .

printf "\nRestore foo.js (same as initial status):\n"
cp tmp/foo.js .
assert_ok "$FLOW" force-recheck --no-auto-start foo.js
assert_errors "$FLOW" status --no-auto-start .

rm tmp/foo.js
rmdir tmp
printf "\nDone!\n"


#!/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.

mkdir tmp

printf "\nInitial status:\n"
assert_errors "$FLOW" status --no-auto-start .

printf "\nDelete c.js:\n"
mv c.js tmp
assert_ok "$FLOW" force-recheck --no-auto-start c.js
assert_errors "$FLOW" status --no-auto-start .

printf "\nDelete b.js:\n"
mv b.js tmp
assert_ok "$FLOW" force-recheck --no-auto-start b.js
assert_errors "$FLOW" status --no-auto-start .

printf "\nRestore b.js:\n"
mv tmp/b.js .
assert_ok "$FLOW" force-recheck --no-auto-start b.js
assert_errors "$FLOW" status --no-auto-start .

printf "\nRestore c.js:\n"
mv tmp/c.js .
assert_ok "$FLOW" force-recheck --no-auto-start c.js
assert_errors "$FLOW" status --no-auto-start .

printf "\nDelete d.json:\n"
mv d.json tmp
assert_ok "$FLOW" force-recheck --no-auto-start d.json
assert_errors "$FLOW" status --no-auto-start .

mv tmp/d.json .

printf "\nDelete unchecked.js:\n"
mv unchecked.js tmp
assert_ok "$FLOW" force-recheck --no-auto-start unchecked.js
assert_errors "$FLOW" status --no-auto-start .

printf "\nRestore unchecked.js:\n"
mv tmp/unchecked.js .
assert_ok "$FLOW" force-recheck --no-auto-start unchecked.js
assert_errors "$FLOW" status --no-auto-start .

printf "\nDelete dupe2.js:\n"
mv dupe2.js tmp
assert_ok "$FLOW" force-recheck --no-auto-start dupe2.js
assert_errors "$FLOW" status --no-auto-start .

printf "\nRestore dupe2.js:\n"
mv tmp/dupe2.js .
assert_ok "$FLOW" force-recheck --no-auto-start dupe2.js
assert_errors "$FLOW" status --no-auto-start .

rmdir tmp
printf "\nDone!\n"


#!/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.

rm foo.js
rm bar.js
mv baz.js.tmp baz.js

assert_ok "$FLOW" force-recheck --no-auto-start foo.js bar.js baz.js
assert_errors "$FLOW" status --no-auto-start

rm baz.js

assert_ok "$FLOW" force-recheck --no-auto-start baz.js
assert_ok "$FLOW" status --no-auto-start


#!/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.

# server is auto-started

rm b.js

assert_ok "$FLOW" force-recheck --focus b.js

assert_errors "$FLOW" status --strip-root --no-auto-start


#!/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.

printf "\nInitial status:\n"
assert_ok "$FLOW" status --no-auto-start --strip-root .

printf "\nCopy A.js to B.js:\n"
cp A.js B.js
assert_ok "$FLOW" force-recheck --no-auto-start B.js
assert_errors "$FLOW" status --no-auto-start --strip-root .

printf "\nDelete A.js:\n"
rm A.js
assert_ok "$FLOW" force-recheck --no-auto-start A.js
assert_ok "$FLOW" status --no-auto-start --strip-root .

printf "\nMove B.js to A.js:\n"
mv B.js A.js
assert_ok "$FLOW" force-recheck --no-auto-start A.js B.js
assert_ok "$FLOW" status --no-auto-start --strip-root .

printf "\nDone!\n"


#! /bin/sh
# 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.

assert_ok "$FLOW" status

cp a.js.after a.js

assert_ok "$FLOW" force-recheck --no-auto-start a.js b.js

assert_errors "$FLOW" status


#! /bin/sh
# 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.

assert_errors "$FLOW" status

cp a.js.after a.js

assert_ok "$FLOW" force-recheck --no-auto-start a.js b.js

assert_ok "$FLOW" status


#!/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.

mkdir tmp
cp ./*.js tmp/

printf "Initial status:\n"
assert_errors $FLOW status --no-auto-start --strip-root .

printf "\nChange .js file:\n"
cp tmp1/*.js ./
assert_ok "$FLOW" force-recheck ./*.js # overapproximation
assert_errors $FLOW status --no-auto-start --strip-root .

mv tmp/*.js ./
rmdir tmp


#!/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.

printf "\nInitial status:\n"
assert_ok $FLOW status --no-auto-start --strip-root .

printf "\nMove A.js to B.js (excluded):\n"
mv A.js B.js
sed -i -e "s/require('A')/require('B')/g" index.js
assert_ok $FLOW force-recheck --no-auto-start A.js B.js index.js
assert_errors $FLOW status --no-auto-start --strip-root .

printf "\nMove B.js to A.js:\n"
mv B.js A.js
sed -i -e "s/require('B')/require('A')/g" index.js
assert_ok $FLOW force-recheck --no-auto-start A.js B.js index.js
assert_ok $FLOW status --no-auto-start --strip-root .

printf "\nDone!\n"


#!/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.

printf "\nInitial status:\n"
assert_ok "$FLOW" status --no-auto-start --strip-root .

printf "\nCopy A.js to B.js:\n"
cp A.js B.js
assert_ok "$FLOW" force-recheck --no-auto-start A.js B.js
assert_errors "$FLOW" status --no-auto-start --strip-root .

printf "\nMove B.js to A.js:\n"
mv B.js A.js
assert_ok "$FLOW" force-recheck --no-auto-start A.js B.js
assert_ok "$FLOW" status --no-auto-start --strip-root .

printf "\nDone!\n"


#!/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.

printf "\nInitial status:\n"
assert_errors "$FLOW" status --no-auto-start .

printf "\nIntroduce haste module \"foo\"\n"
cp tmp/foo.js foo.js
assert_ok "$FLOW" force-recheck --no-auto-start foo.js
assert_errors "$FLOW" status --no-auto-start .

printf "\nRemove haste module \"foo\"\n"
rm foo.js
assert_ok "$FLOW" force-recheck --no-auto-start foo.js
assert_errors "$FLOW" status --no-auto-start .

printf "\nDone!\n"


#!/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.

assert_errors "$FLOW" status

# We change baz's re-export from ./foo to an identical ./bar, which causes qux's
# re-export to change, which affects the error printed in thud, since it now
# needs to point to bar.js instead of foo.js
mv baz.js.after baz.js
assert_ok "$FLOW" force-recheck baz.js

assert_errors "$FLOW" status


#!/bin/bash -e
# 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.

assert_ok "$FLOW" force-recheck --no-auto-start a.js
assert_ok "$FLOW" status --no-auto-start .

cp tmp/b.js ./
trap 'rm b.js' EXIT

assert_ok "$FLOW" force-recheck --no-auto-start b.js
assert_errors "$FLOW" status --no-auto-start .


#!/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.

mkdir tmp
cp root.js tmp/

assert_errors "$FLOW" status .
cp tmp1/root.js ./
assert_ok "$FLOW" force-recheck root.js
assert_errors "$FLOW" status .

mv tmp/root.js ./
rmdir tmp


#!/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.

mkdir tmp

printf "\nInitial status:\n"
assert_ok "$FLOW" status --no-auto-start .

printf "\nDelete non-@flow file foo.js:\n"
mv foo.js tmp
assert_ok "$FLOW" force-recheck --no-auto-start foo.js
assert_errors "$FLOW" status --no-auto-start .

printf "\nRestore non-@flow file foo.js:\n"
mv tmp/foo.js .
assert_ok "$FLOW" force-recheck --no-auto-start foo.js
assert_ok "$FLOW" status --no-auto-start .

rmdir tmp
printf "\nDone!\n"


#!/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.

. ../fs.sh
mkdir -p tmp/node_modules
printf "\nShould resolve to dir/node_modules/b.js which is number\n"
assert_errors "$FLOW" status .
printf "\nShould resolve to node_modules/b.js which is a string\n"
move dir/node_modules/b.js tmp/node_modules/b.js
assert_errors "$FLOW" status .
printf "\nShould resolve to dir/node_modules/b.js which is number\n"
move tmp/node_modules/b.js dir/node_modules/b.js
assert_errors "$FLOW" status .
rm -r tmp


#!/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.

assert_errors "$FLOW" status

# We move a.js, which provides HasteName, to a different path, which causes b.js
# to be rechecked, but we also need to recheck c.js because the error found in c
# now needs to point to bar/a.js instead of foo/a.js
mv foo/a.js bar/a.js
assert_ok "$FLOW" force-recheck foo/a.js bar/a.js

assert_errors "$FLOW" status


#!/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.

rm .flowconfig
assert_ok "$FLOW" init

printf "Default .flowconfig should typecheck:\n"
assert_ok "$FLOW" check

printf "\nDefault .flowconfig looks like this:\n"
cat .flowconfig


#!/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.

mv bar.js _bar.js
assert_ok $FLOW force-recheck --root . bar.js _bar.js
assert_errors $FLOW status .
mv _bar.js bar.js


#!/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.

assert_ok "$FLOW" stop

assert_errors "$FLOW" check --no-flowlib .

echo "{" > package.json
echo
echo "============================================"
echo "Parse error in package.json will be reported"
echo "============================================"
assert_errors "$FLOW" check --no-flowlib .


#!/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.

echo "flow check --json-version=2"
assert_errors "$FLOW" check . --strip-root --json-version=2
echo ""
echo ""

echo "flow check --json-version=2 --json"
assert_errors "$FLOW" check . --strip-root --json-version=2 --json
echo ""
echo ""

echo "flow check --json-version=2 --pretty"
assert_errors "$FLOW" check . --strip-root --json-version=2 --pretty
echo ""
echo ""

echo "flow focus-check test.js --json-version=2"
assert_errors "$FLOW" focus-check test.js --strip-root --json-version=2
echo ""
echo ""

echo "flow focus-check test.js --json-version=2 --json"
assert_errors "$FLOW" focus-check test.js --strip-root --json-version=2 --json
echo ""
echo ""

echo "flow focus-check test.js --json-version=2 --pretty"
assert_errors "$FLOW" focus-check test.js --strip-root --json-version=2 --pretty
echo ""
echo ""

echo "flow check-contents --json-version=2 < test.js"
assert_ok "$FLOW" check-contents --json-version=2 < test.js
echo ""
echo ""

echo "flow check-contents --json-version=2 --json < test.js"
assert_ok "$FLOW" check-contents --json-version=2 --json < test.js
echo ""
echo ""

echo "flow check-contents --json-version=2 --pretty < test.js"
assert_ok "$FLOW" check-contents --json-version=2 --pretty < test.js
echo ""
echo ""

echo "flow status --json-version=2"
assert_errors "$FLOW" status . --strip-root --json-version=2
echo ""
echo ""

echo "flow status --json-version=2 --json"
assert_errors "$FLOW" status . --strip-root --json-version=2 --json
echo ""
echo ""

echo "flow status --json-version=2 --pretty"
assert_errors "$FLOW" status . --strip-root --json-version=2 --pretty
echo ""


#!/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.

assert_exit "$EXIT_COULD_NOT_FIND_FLOWCONFIG" \
  "$FLOW" check --json pants

assert_exit "$EXIT_COULD_NOT_FIND_FLOWCONFIG" \
  "$FLOW" check --pretty pants

assert_exit "$EXIT_USAGE" \
  "$FLOW" check --json --pants

assert_exit "$EXIT_USAGE" \
  "$FLOW" check --pretty --pants


#!/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.

printf "\\nA full check should ignore the lazy mode in the .flowconfig\\n"
assert_errors "$FLOW" check --strip-root

printf "\\nServer should start in fs lazy mode\\n"
start_flow .
assert_ok "$FLOW" status --strip-root

printf "\\nEditing a file should cause fs lazy mode to focus on the file\\n"
echo " " >> foo.js
assert_ok "$FLOW" force-recheck foo.js
assert_errors "$FLOW" status --strip-root
assert_ok "$FLOW" stop

printf "\\nServer should start in non-lazy mode due to --lazy-mode none\\n"
start_flow . --lazy-mode none
assert_errors "$FLOW" status --strip-root
assert_ok "$FLOW" stop


#!/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.

printf "\\nServer should start in fs lazy mode\\n"
start_flow . --lazy-mode fs

assert_ok "$FLOW" status --strip-root

printf "\\nFocus a file\\n"
assert_ok "$FLOW" force-recheck --focus foo.js
assert_errors "$FLOW" status --strip-root

printf "\\nEdit a dependency\\n"
cp tmp1/node_modules_bar_index.js node_modules/bar/index.js
assert_ok "$FLOW" force-recheck node_modules/bar/index.js
assert_ok "$FLOW" status --strip-root

printf "\\nRevert edit\\n"
cp tmp2/node_modules_bar_index.js node_modules/bar/index.js
assert_ok "$FLOW" force-recheck node_modules/bar/index.js
assert_errors "$FLOW" status --strip-root

assert_ok "$FLOW" stop


#!/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.

printf "\\nServer should start in fs lazy mode\\n"
start_flow . --lazy-mode fs

assert_ok "$FLOW" status --strip-root

echo

assert_ok "$FLOW" get-def --strip-root bar.js 5 2

assert_ok "$FLOW" stop


#!/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.

printf "\\nServer should start in fs lazy mode\\n"
start_flow . --lazy-mode fs

assert_ok "$FLOW" status --strip-root

printf "\\nFocus a file\\n"
assert_ok "$FLOW" force-recheck --focus focused.js
assert_errors "$FLOW" status --strip-root

printf "\\nEdit a dependency\\n"
cp tmp1/dependency.js dependency.js
assert_ok "$FLOW" force-recheck dependency.js
assert_ok "$FLOW" status --strip-root

printf "\\nRevert edit\\n"
cp tmp2/dependency.js dependency.js
assert_ok "$FLOW" force-recheck dependency.js
assert_errors "$FLOW" status --strip-root

assert_ok "$FLOW" stop


#!/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.

echo "============================================"
echo "No warnings:"
echo "============================================"
assert_errors "$FLOW" check --no-flowlib

echo ""
echo "============================================"
echo "With warnings:"
echo "============================================"
assert_errors "$FLOW" check --no-flowlib --include-warnings


#!/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.

assert_errors "$FLOW" check . --all --lints "all=error"


#!/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.

assert_errors "$FLOW" check . --all --lints "sketchy-null=error"


#!/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.

assert_errors "$FLOW" check . --all --lints ""


#!/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.

assert_ok "$FLOW" check . --all --lints ""


#!/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.

assert_ok "$FLOW" check . --all --lints "all=off"


#!/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.

assert_ok "$FLOW" check . --all --lints "sketchy-null=off"


#!/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.

printf "After start:\n"
assert_ok "$FLOW" status .

cp test1.js.fixture test.js
printf "\nAfter introducing a lint error:\n"
assert_ok "$FLOW" force-recheck test.js
assert_errors "$FLOW" status .

cp test2.js.fixture test.js
printf "\nAfter suppressing the lint error:\n"
assert_ok "$FLOW" force-recheck test.js
assert_ok "$FLOW" status .

cp test3.js.fixture test.js
printf "\nAfter fixing the lint error, leaving the suppression:\n"
assert_ok "$FLOW" force-recheck test.js
assert_ok "$FLOW" status . # 0 errors & 1 warning

cp test4.js.fixture test.js
printf "\nAfter removing the unused suppression:\n"
assert_ok "$FLOW" force-recheck test.js
assert_ok "$FLOW" status .


#!/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.

assert_exit "$EXIT_USAGE" \
  "$FLOW" check . --all --lints "sketchy-null=error,all=off"


#!/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.

assert_exit "$EXIT_USAGE" \
  "$FLOW" check . --all --lints "sketchy-null=error,sketchy-null-bool=error"


#!/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.

assert_exit "$EXIT_USAGE" \
  "$FLOW" check . --all --lints "sketchy-null-bool=error,sketchy-null=off"


#!/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.

assert_errors "$FLOW" check . --all --include-warnings --color always


#!/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.

assert_errors "$FLOW" check . --all --include-warnings --pretty --strip-root \
  | grep -v '^ *"flowVersion":.*'


#!/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.

assert_errors "$FLOW" status --include-warnings --strip-root --from vim


#!/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.

printf "Without --include-suppressed:\n"
assert_ok "$FLOW" check
printf "With --include-suppressed:\n"
assert_errors "$FLOW" check --include-suppressed --strip-root


#!/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.

# This script is just a simple wrapper around the
# build/fbcode_builder/getdeps.py script.
#
# Feel free to invoke getdeps.py directly to have more control over the build.

SCRIPT_DIR=$(dirname "${BASH_SOURCE[0]}")
GETDEPS_PATHS=(
    "$SCRIPT_DIR/build/fbcode_builder/getdeps.py"
    "$SCRIPT_DIR/../../opensource/fbcode_builder/getdeps.py"
)
for getdeps in "${GETDEPS_PATHS[@]}"; do
    if [[ -x "$getdeps" ]]; then
        exec "$getdeps" build folly "$@"
    fi
done
echo "Could not find getdeps.py" >&2
exit 1


#!/bin/bash -x
# 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.

# The only prerequisite should be homebrew. If something doesn't work out of
# the box with just homebrew, let's fix it.

# fail fast
set -e

BUILD_DIR=${BUILD_DIR:-_build}

# brew install alias
brew_install() {
    brew install "$@" || brew upgrade "$@"
}

# install deps
install_deps() {
    # folly deps
    dependencies=(
        boost
        cmake
        double-conversion
        gflags
        glog
        jemalloc
        libevent
        lz4
        openssl
        pkg-config
        snappy
        xz
        fmt
    )

    # fetch deps
    for dependency in "${dependencies[@]}"; do
        brew_install "${dependency}"
    done
}

install_deps

# Allows this script to be invoked from anywhere in the source tree but the
# BUILD_DIR we create will always be in the top level folly directory
TOP_LEVEL_DIR="$(cd "$(dirname -- "$0")"/../.. ; pwd)"  # folly
cd "$TOP_LEVEL_DIR"
mkdir -p "${BUILD_DIR}"
cd "${BUILD_DIR}"

OPENSSL_INCLUDES=$(brew --prefix openssl)/include
cmake \
    -DOPENSSL_INCLUDE_DIR="${OPENSSL_INCLUDES}" \
    -DFOLLY_HAVE_WEAK_SYMBOLS=ON \
    "$@" \
    ..

# fetch googletest, if doesn't exist
GTEST_VER=1.10.0
GTEST_DIR=gtest-${GTEST_VER}
if [ ! -d ${GTEST_DIR} ]; then
    mkdir ${GTEST_DIR}
    curl -SL \
        https://github.com/google/googletest/archive/release-${GTEST_VER}.tar.gz | \
        tar -xvzf - --strip-components=1 -C ${GTEST_DIR}
fi

# make, test, install
make
make install


#!/bin/sh -x
# 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: this script was written on Ubuntu 18.04 and will need work in order to
# work on additional platforms. This is left as an exercise for the reader.

set -e

BUILD_DIR=${BUILD_DIR:-_build}
BOOST_VERSION=${BOOST_VERSION:-1.65.1}
LIBEVENT_VERSION=${LIBEVENT_VERSION:-2.0-5}
SSL_VERSION=${SSL_VERSION:-1.0.0}

VERSION_FILE_PATH=folly/VERSION
VERSION=${VERSION:-"$(sed 's/:/./' ${VERSION_FILE_PATH})"}
ITERATION=${ITERATION:-1}

DESTDIR=${DESTDIR:-$(mktemp -d)}
DEBUGDIR=${DEBUGDIR:-$DESTDIR/usr/lib/debug}
PKGDIR=${PKGDIR:-/tmp}

DESC="Folly is an open-source C++ library developed and used at Facebook
  as a foundation for our infrastructure."
URL=https://github.com/facebook/folly
LICENSE="Apache License v2.0"
MAINTAINER="Folly Eng"

command -v fpm || (echo "Please install fpm from https://github.com/jordansissel/fpm" && exit 1)
[ -d "$DESTDIR" ]

command -v cmake || (echo "Please install cmake." && exit 1)

# Make
rm -rf "${BUILD_DIR}"
mkdir "${BUILD_DIR}"
cd "${BUILD_DIR}"
cmake ..
make
make install DESTDIR="$DESTDIR"

# Move symbols to debug file
[ -d "$DEBUGDIR/usr/lib" ] || mkdir -p "$DEBUGDIR/usr/lib"
find "$DESTDIR/usr/lib" -maxdepth 1 -iname "lib*.so.*" -type f \
  -execdir objcopy --only-keep-debug {} "$DEBUGDIR/usr/lib/{}.debug" \; \
  -execdir strip --strip-debug --strip-unneeded {} \; \
  -execdir objcopy --add-gnu-debuglink "$DEBUGDIR/usr/lib/{}.debug" {} \;

# Build debs
fpm \
  -s dir -t deb \
  -n "libfolly$VERSION" \
  -v "$VERSION" --iteration "$ITERATION" \
  -p "$PKGDIR/NAME_VERSION-ITERATION_ARCH.deb" \
  -C "$DESTDIR" \
  --description "$DESC" \
  --vendor Facebook \
  --url "$URL" \
  --license "$LICENSE" \
  --maintainer "$MAINTAINER" \
  --category libs \
  --provides libfolly \
  --depends libc6 \
  --depends libstdc++6 \
  --depends libboost-context"$BOOST_VERSION" \
  --depends libboost-filesystem"$BOOST_VERSION" \
  --depends libboost-program-options"$BOOST_VERSION" \
  --depends libboost-regex"$BOOST_VERSION" \
  --depends libboost-system"$BOOST_VERSION" \
  --depends libboost-thread"$BOOST_VERSION" \
  --depends libdouble-conversion1 \
  --depends libevent-"$LIBEVENT_VERSION" \
  --depends libgflags2 \
  --depends libgoogle-glog0 \
  --depends libicu52 \
  --depends libjemalloc1 \
  --depends liblz4-1 \
  --depends liblzma5 \
  --depends libsnappy1 \
  --depends libssl"$SSL_VERSION" \
  --depends zlib1g \
  --exclude usr/lib/debug \
  --exclude usr/lib/*.a \
  --exclude usr/lib/*.la \
  usr/lib

fpm \
  -s dir -t deb \
  -n libfolly-dev \
  -v "$VERSION" --iteration "$ITERATION" \
  -p "$PKGDIR/NAME_VERSION-ITERATION_ARCH.deb" \
  -C "$DESTDIR" \
  --description "$DESC" \
  --vendor Facebook \
  --url "$URL" \
  --license "$LICENSE" \
  --maintainer "$MAINTAINER" \
  --category devel \
  --depends "libfolly$VERSION" \
  --exclude usr/lib/*.so* \
  usr/include \
  usr/lib/debug

echo "${DESTDIR}"


#!/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.

FOLLY_ADDR2LINE="$1"
LLVM_ADDR2LINE="$2"
BINARY_TO_SYMBOLIZE="$3"

N=100
ADDRS=("$@")
ADDRS=("${ADDRS[@]:3}")

if [[ ${#ADDRS[@]} == 0 ]]; then
    SYMBOLS=$(readelf -s "$BINARY_TO_SYMBOLIZE")
    # An address may be part of multiple functions.
    # folly-addr2line and llvm-addr2line may choose either version leading to a comparison failure.
    # Only compare symbolization output if a single function matches the address.
    FUNCTION_ADDR_RANGES=$(echo "$SYMBOLS" | grep -E 'FUNC +GLOBAL +DEFAULT +[0-9]+' | awk '{print $2 " " $3}' | sort)
    UNIQUE_ADDR_RANGES=$(echo "$SYMBOLS" | awk '{print $2 " " $3}' | sort | uniq -u)
    FUNCTION_UNIQUE_ADDR_RANGES=$(comm -12 <(echo "$FUNCTION_ADDR_RANGES") <(echo "$UNIQUE_ADDR_RANGES") | shuf -n "$N")
    if [[ -z "$FUNCTION_UNIQUE_ADDR_RANGES" ]]; then
        exit 0
    fi
    readarray -t ADDRS < <(
        echo "$FUNCTION_UNIQUE_ADDR_RANGES" | shuf -n "$N" | while read -r start_hex size; do
            start="$((16#$start_hex))"
            end="$((start + size))"
            printf '0x%x\n' "$(seq "$start" "$end" | shuf -n 1)"
        done
    )
fi

echo ADDRS: "${ADDRS[@]}"

set -x
set -o pipefail

if command -v wdiff &> /dev/null
then
    DIFF=wdiff
else
    DIFF="diff -U 10"
fi

if command -v colordiff &> /dev/null
then
    COLORDIFF="colordiff"
else
    COLORDIFF="cat"
fi

$DIFF <("$FOLLY_ADDR2LINE" -e "$BINARY_TO_SYMBOLIZE" -i -f -a "${ADDRS[@]}") <("$LLVM_ADDR2LINE" -e "$BINARY_TO_SYMBOLIZE" -i -f -a "${ADDRS[@]}" | sed -E 's| \(discriminator [0-9]+\)||g') | "$COLORDIFF"


#!/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.

crash="$1"

uuid=$(cat /proc/sys/kernel/random/uuid)
for sig in 1 2 3 13 15; do eval "trap 'exit $((sig + 128))' $sig"; done
trap 'rm -f "$crash.debuginfo.$uuid" "$crash.strip.$uuid"' 0

objcopy --only-keep-debug "$crash" "$crash.debuginfo.$uuid"
objcopy --strip-debug --add-gnu-debuglink="$crash.debuginfo.$uuid" "$crash" "$crash.strip.$uuid"

echo '{"op":"start","test":"gnu_debuglink_test"}';
start=$(date +%s)
if "$crash.strip.$uuid" 2>&1 | grep -q 'Crash.cpp:[0-9]*$'; then
    result='"status":"passed"';
else
    result='"status":"failed"';
fi
end=$(date +%s)
echo '{"op":"test_done","test":"gnu_debuglink_test",'"$result"'}'
echo '{"op":"all_done","results":[{"name":"gnu_debuglink_test",'"$result"',"start_time":'"$start"',"end_time":'"$end"',"details":"nothing"}]}'


#!/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.

BINARY="$1"
DWP="$2"

NEW_BINARY=$(dirname "$DWP")
# Keep the binary file with the dwp file in the same directory.
cp "$BINARY" "$NEW_BINARY"
NEW_BINARY+="/$(basename "$BINARY")"

echo "$NEW_BINARY" "$DWP"

OUTPUT=$(tr -d '[:space:]' <<<$($NEW_BINARY))
echo "Unit test output is " "$OUTPUT"
[[ $OUTPUT =~ "[PASSED]16tests" ]] && exit 0 || exit 5


#!/bin/bash -ue
# 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.

CERT_LIFETIME_DAYS=${CERT_LIFETIME_DAYS:-36500}

extensions() {
  cat << EOF
[ca]
basicConstraints        = critical, CA:TRUE
subjectKeyIdentifier    = hash
authorityKeyIdentifier  = keyid:always, issuer:always
keyUsage                = critical, cRLSign, digitalSignature, keyCertSign

[client]
basicConstraints        = critical, CA:FALSE
subjectKeyIdentifier    = hash
authorityKeyIdentifier  = keyid:always
keyUsage                = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage        = critical, clientAuth

[server]
basicConstraints        = critical, CA:FALSE
subjectKeyIdentifier    = hash
authorityKeyIdentifier  = keyid:always
keyUsage                = critical, nonRepudiation, digitalSignature, keyEncipherment, keyAgreement
extendedKeyUsage        = critical, serverAuth
subjectAltName          = IP:127.0.0.1,IP:::1

[client_and_server]
basicConstraints        = critical, CA:FALSE
subjectKeyIdentifier    = hash
authorityKeyIdentifier  = keyid:always
keyUsage                = critical, nonRepudiation, digitalSignature, keyEncipherment, keyAgreement
extendedKeyUsage        = critical, serverAuth, clientAuth
subjectAltName          = IP:127.0.0.1,IP:::1
EOF
}

die() {
  echo "$@" >&2
  exit 1
}

generate_key() {
  keytype="$1"
  modulus_bits="$2"
  outfile="$3"

  [ "$keytype" != "rsa" ] && die "unsupported key type"

  openssl genrsa -out "$outfile" "$modulus_bits" 2>/dev/null
}

mkcsr() {
  local key="$1"
  local name="$2"
  local output="$3"

  openssl req -new \
    -sha256 \
    -key "$key" \
    -keyform PEM \
    -subj "/CN=$name/" \
    -outform PEM \
    -out "$output" \

}

selfsign() {
  local incsr="$1"
  local inkey="$2"
  local outfile="$3"

  openssl x509 \
    -req \
    -set_serial 1 \
    -signkey "$inkey" \
    -inform PEM \
    -in "$incsr" \
    -outform PEM \
    -out "$outfile" \
    -days "$CERT_LIFETIME_DAYS" \
    -extfile <(extensions) \
    -extensions "ca" \

}

sign() {
  csr="$1"
  cacert="$2"
  cakey="$3"
  serial="$4"
  extensions="$5"
  outfile="$6"

  openssl x509 \
    -req \
    -set_serial "$serial" \
    -CA "$cacert" \
    -CAkey "$cakey" \
    -inform PEM \
    -in "$csr" \
    -outform PEM \
    -out "$outfile" \
    -days "$CERT_LIFETIME_DAYS" \
    -extfile <(extensions) \
    -extensions "$extensions" \

}

# Client CA
generate_key rsa 2048 client_ca_key.pem
mkcsr client_ca_key.pem "Asox Certification Authority" client_ca.csr.pem
selfsign client_ca.csr.pem client_ca_key.pem client_ca_cert.pem

# Client Intermediate CA
generate_key rsa 2048 client_intermediate_ca_key.pem
mkcsr client_intermediate_ca_key.pem "Intermediate CA" client_intermediate_ca.csr.pem
sign client_intermediate_ca.csr.pem client_ca_cert.pem client_ca_key.pem 2 ca client_intermediate_ca.pem

# Directly signed client cert (client_key.pem)
generate_key rsa 2048 client_key.pem
mkcsr client_key.pem "testuser1" client.csr.pem
sign client.csr.pem client_ca_cert.pem client_ca_key.pem 100 client client_cert.pem

# Client signed by an intermediate
generate_key rsa 2048 clienti_key.pem
mkcsr clienti_key.pem "Leaf Certificate" clienti.csr.pem
sign clienti.csr.pem client_intermediate_ca.pem client_intermediate_ca_key.pem 200 client clienti_cert.pem
cat clienti_cert.pem client_intermediate_ca.pem > client_chain.pem

# Server CA "Thrift Certificate Authority"
generate_key rsa 2048 ca-key.pem
mkcsr ca-key.pem "Thrift Certificate Authority" ca.csr.pem
selfsign ca.csr.pem ca-key.pem ca-cert.pem

# Server cert "Asox Company"
generate_key rsa 2048 tests-key.pem
mkcsr tests-key.pem "Asox Company" tests.csr.pem
sign tests.csr.pem ca-cert.pem ca-key.pem 300 client_and_server tests-cert.pem

# Remove all of the CSRs but leave the keys in case you need to regenerate a
# different cert with the same key.
rm ./*.csr.pem


#!/usr/bin/env bash

# Copyright 2013-present Facebook
#
# 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
set -o verbose
bundle exec chef-zero &
ZERO=$!
trap "kill -9 $ZERO" EXIT
SOURCE=/tmp/source
sleep 5

rm -rf /tmp/master_path
rm -rf $SOURCE
GIT="git -c user.email='foo@bar.com' -c user.name='foobar'"

function gd {
  bundle exec ./bin/grocery-delivery -c test/gd-git.rb -vv
}

(
  mkdir $SOURCE
  $GIT init $SOURCE
  cd $SOURCE && touch test && $GIT add . -A && $GIT commit -m "Dummy commit"
)
gd
(
  cd $SOURCE
  mkdir chef/cookbooks/cookbook1/recipes -p
  touch chef/cookbooks/cookbook1/recipes/default.rb
  echo "name 'cookbook1'" > chef/cookbooks/cookbook1/metadata.rb
  $GIT add . -A
  $GIT commit -m "Add cookbook1"
)
gd
(
  cd $SOURCE
  touch chef/cookbooks/cookbook1/recipes/recipe2.rb
  $GIT add . -A
  $GIT commit -m "Modify cookbook1"
)
gd
(
  cd $SOURCE
  rm -rf chef/cookbooks/cookbook1
  $GIT add . -A
  $GIT commit -m "Remove cookbook1"
)
gd


#!/usr/bin/env bash

# Copyright 2013-present Facebook
#
# 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
set -o verbose
bundle exec chef-zero &
ZERO=$!
trap "kill -9 $ZERO" EXIT
SOURCE=/tmp/source
sleep 5

rm -rf /tmp/master_path
rm -rf $SOURCE
rm -rf $SOURCE-import
rm -rf $SOURCE-checkout

function gd {
  bundle exec ./bin/grocery-delivery -c test/gd-svn.rb -vv
}

(
  mkdir $SOURCE
  svnadmin create $SOURCE
  mkdir $SOURCE-import && cd $SOURCE-import && touch test && svn import . file://$SOURCE -m"Dummy commit"
)
gd
(
  svn checkout file://$SOURCE $SOURCE-checkout
  cd $SOURCE-checkout
  mkdir chef/cookbooks/cookbook1/recipes -p
  touch chef/cookbooks/cookbook1/recipes/default.rb
  echo "name 'cookbook1'" > chef/cookbooks/cookbook1/metadata.rb
  svn add chef
  svn commit chef -m"Add cookbook1"
)
gd
(
  cd $SOURCE-checkout
  touch chef/cookbooks/cookbook1/recipes/recipe2.rb
  svn add chef/cookbooks/cookbook1/recipes/recipe2.rb
  svn commit chef -m"Modify cookbook1"
)
gd
(
  cd $SOURCE-checkout
  svn delete chef/cookbooks/cookbook1/metadata.rb
  svn delete chef/cookbooks/cookbook1/recipes/default.rb
  svn delete chef/cookbooks/cookbook1/recipes/recipe2.rb
  svn status
  svn commit -m"Remove cookbook1"
)
gd


#!/usr/bin/env bash

# Copyright 2013-present Facebook
#
# 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 verbose
set -e
./test/run-svn.sh
./test/run-git.sh


#!/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.

cmake ~/fbsource/xplat/hermes \
    -DHERMES_FACEBOOK_BUILD=OFF \
    -DCMAKE_BUILD_TYPE=MinSizeRel \
    -DCMAKE_TOOLCHAIN_FILE=/opt/android_ndk/android-ndk-r15c/build/cmake/android.toolchain.cmake \
    -DICU_ROOT=/Users/tmikov/3rd/swift-libiconv-libicu-android.git/armeabi-v7a -G Ninja $*


#!/bin/sh
# 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.

# RUN: sh %s %hermesc %S/input1.js.txt %t-input1 %S/input1-p.js.txt
# RUN: sh %s %hermesc %S/richards.js.txt %t-richards

set -e

HERMESC=$1
INP=$2
TMPN=$3
PRETTY=$4

"$HERMESC" -dump-ast -Xinclude-raw-ast-prop=0 "$INP" > "${TMPN}.json"

"$HERMESC" -dump-js -pretty "$INP" > "${TMPN}-p.js"
if [ -n "$PRETTY" ]; then
    cmp "$PRETTY" "${TMPN}-p.js"
fi
"$HERMESC" -dump-ast -Xinclude-raw-ast-prop=0 "${TMPN}-p.js" > "${TMPN}-p.json"
cmp "${TMPN}.json" "${TMPN}-p.json"

"$HERMESC" -dump-js -pretty=0 "$INP" > "${TMPN}-m.js"
"$HERMESC" -dump-ast -Xinclude-raw-ast-prop=0 "${TMPN}-m.js" > "${TMPN}-m.json"
cmp "${TMPN}.json" "${TMPN}-m.json"


#!/bin/bash -xe
# 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.

# Parse command-line arguments
hermes_npm_package=

while (( "$#" )); do
  case $1 in
    --hermes-npm-package)
      shift || (
        echo "Missing NPM package argument"
        exit 1
      )
      hermes_npm_package="$1"
      ;;
    *)
      echo "Unsupported argument: $1"
      exit 1
      ;;
   esac
   shift
done

# Clone a fresh copy of RN main
git clone --depth=1 https://github.com/facebook/react-native

cd react-native
npm install
# Install new Hermes NPM.
npm install "$hermes_npm_package"

# Modify RN Tester app to print a log message at start-up
echo "console.log('Using Hermes: ' + (global.HermesInternal != null));" >> packages/rn-tester/js/RNTesterApp.android.js

# Wait for emulator to boot
adb wait-for-device

# Build and install release app
./gradlew :packages:rn-tester:android:app:installHermesRelease

cd ..

# Start screen recording for debug
adb shell screenrecord /sdcard/screencap.mp4 &
adb_screen_record_pid=$!
function stashScreenCapture() {
  local exit_code=$?
  adb shell killall -s INT screenrecord
  wait $adb_screen_record_pid || true
  adb pull /sdcard/screencap.mp4 /tmp/hermes/output/screencap.mp4
  exit "$exit_code"
}
trap stashScreenCapture EXIT

# Start app + wait to see relevant log message
adb logcat -c || true  # This sometimes fails to clear the "main" log. This is benign.
adb shell am start com.facebook.react.uiapp/.RNTesterActivity
SECONDS=0
until grep 'Using Hermes: true' <(adb logcat -d -s ReactNativeJS:I) ; do
  if ((SECONDS > 30 )) ; then
    echo "Did not see correct log message within 30s"
    adb logcat -d > /tmp/hermes/output/adblog.txt
    tar cfz /tmp/hermes/output/project.tar.gz react-native
    exit 1
  fi
  sleep 2
done

echo "Test passed: Hermes in use in RNTester App"
exit 0


# 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.

# RUN: bash %s %S %T %hbc-deltaprep %hermes
# shellcheck shell=bash

# Exit on any failure.
set -e
set -o pipefail

SRCDIR=$1
TMPDIR=$2
DELTAPREP=$3
HERMES=$4

# Compile the source and delta-prep it, then compare the original.
${HERMES} -emit-binary -out "${TMPDIR}/file1.hbc" "${SRCDIR}/file1.js"
${DELTAPREP} "${TMPDIR}/file1.hbc" -form=delta -out "${TMPDIR}/file1-delta.hbc"
! diff -q "${TMPDIR}/file1.hbc" "${TMPDIR}/file1-delta.hbc"

# Convert back and verify it matches the original.
${DELTAPREP} "${TMPDIR}/file1-delta.hbc" -form=execution -out "${TMPDIR}/file1-roundtrip.hbc"
! diff -q "${TMPDIR}/file1-delta.hbc" "${TMPDIR}/file1-roundtrip.hbc"
diff -q "${TMPDIR}/file1.hbc" "${TMPDIR}/file1-roundtrip.hbc"


# 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.

# RUN: sh %s %S %t %hermes
# RUN: sh %s %S %t %hermesc

# shellcheck disable=SC2148

SRCDIR=$1
TMPFILE=$2
HERMES=$3

# Return values from hermes and hermesc.
Success=0
InvalidFlags=1
ParsingFailed=2
# shellcheck disable=SC2034
VerificationFailed=3
LoadGlobalsFailed=4
InputFileError=5
OutputFileError=6
# shellcheck disable=SC2034
OptimizationFailed=7

set -x

expect() {
  EXPECTED=$1
  shift
  eval "$@" 2>"$TMPFILE"
  if [[ $? != "$EXPECTED" ]]; then
    echo "Command '$CMD' produced wrong exit status" >&2
    exit 1
  fi
  true
}

cd "${SRCDIR}" || exit 1
expect "${Success}" "${HERMES}" test.js.in -target=HBC -emit-binary > "$TMPFILE"
expect "${InvalidFlags}" "${HERMES}" -lazy -commonjs test.js.in
expect "${InvalidFlags}" "${HERMES}" -nonsenseflag test.js.in
expect "${ParsingFailed}" "${HERMES}" bogus.js.in -target=HBC -emit-binary > "$TMPFILE"
expect "${LoadGlobalsFailed}" "${HERMES}" test.js.in -include-globals bogus.js.in -emit-binary -target=HBC > "$TMPFILE"
expect "${InputFileError}" "${HERMES}" ./not/a/valid/path.js -target=HBC -emit-binary > "$TMPFILE"
expect "${OutputFileError}" "${HERMES}" test.js.in -target=HBC -emit-binary -out ./not/a/valid/path.hbc


# 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.

# RUN: bash %s %S %T %hermes
# shellcheck shell=bash disable=SC2086

# This test is an end-to-end source-map symbolication test. First it runs a
# file thrower.js which throws an exception, and records the backtrace (which
# has line and column numbers through its debug info). It then compiles the
# same file to bytecode with a source map (thus omitting the debug info from
# the binary), runs the bytecode file, and records that backtrace as the "raw"
# trace. It then symbolicates the raw trace using the source-map project from
# Mozilla, and compares the original and symbolicated trace. This tests that
# a source-map symbolicated backtrace is identical to the one output when
# debug info is present.

SRCDIR=$1
TMPDIR=$2
HERMES=$3

# Perform a symbolication test.
# Argument 1: a name for the test
# Argument 2: parameters to pass to hermes driver.
run_1_test() {
  NAME=$1;
  ARGS=$2;
  HBC_FILE=$3;
  SRC_FILES=("${@:4}");

  ORIG_TRACE="$TMPDIR/${NAME}_original_trace.txt"
  RAW_TRACE="$TMPDIR/${NAME}_raw_trace.txt"
  SYM_TRACE="$TMPDIR/${NAME}_symbolicated_trace.txt"

  # Run the JS directly, record the backtrace.
  "$HERMES" $ARGS "${SRC_FILES[@]}" > "$ORIG_TRACE"

  # Compile the JS to bytecode and have it emit a source map.
  # Run the bytecode and store its trace (which will contain addresses).
  "$HERMES" $ARGS -output-source-map -emit-binary -out "$HBC_FILE" "${SRC_FILES[@]}"
  "$HERMES" "$HBC_FILE" > "$RAW_TRACE"

  # Ensure that the two backtraces are different so the symbolicator has
  # real work to do.
  if diff -q "$ORIG_TRACE" "$RAW_TRACE" > /dev/null ; then
    echo "Raw and original backtraces should not be the same"
    echo "Raw trace: $RAW_TRACE"
    echo "Original trace: $ORIG_TRACE"
    echo "Artifacts in $TMPDIR"
    exit 1
  fi

  # Stringize the sourcemap and raw stack trace, concatenate them along with
  # the symbolicator source, and then execute that. The output will be a
  # symbolicated stacktrace. This is to enable the test to run via Hermes alone
  # (i.e. without introducing a node dependency).
  ( python3 $SRCDIR/stringize.py SOURCEMAP < "$HBC_FILE.map" ;
    python3 $SRCDIR/stringize.py STACKTRACE < "$RAW_TRACE" ;
    cat $SRCDIR/symbolicator.js.in
  ) | "$HERMES" - -target=HBC -gc-sanitize-handles=0 > "$SYM_TRACE"

  # Ensure that the original and symbolicated stack trace are the same!
  if ! diff "$ORIG_TRACE" "$SYM_TRACE" ; then
    echo "Symbolicated stack trace differed from debug-info version.";
    echo "Symbolicated trace: $SYM_TRACE"
    echo "Original trace: $ORIG_TRACE"
    echo "Artifacts in $TMPDIR";
    exit 1
  fi
}

(cat "$SRCDIR/stack-formatter.js.in" "$SRCDIR/thrower.js") > "$TMPDIR/thrower-with-formatter.js"

# -gc-sanitize-handles=0 because ASAN build is far too slow without it.
run_1_test "default"   "-gc-sanitize-handles=0 -target=HBC" "$TMPDIR/thrower.hbc" "$SRCDIR/thrower.js"
run_1_test "optimized" "-O -gc-sanitize-handles=0 -target=HBC" "$TMPDIR/thrower.hbc" "$SRCDIR/thrower.js"
run_1_test "default_cjs" "-commonjs -gc-sanitize-handles=0 -target=HBC" "$TMPDIR/cjs-1.hbc" "$SRCDIR/cjs-1.js" "$SRCDIR/cjs-2.js"
run_1_test "optimized_cjs" "-O -commonjs -gc-sanitize-handles=0 -target=HBC" "$TMPDIR/cjs-1.hbc" "$SRCDIR/cjs-1.js" "$SRCDIR/cjs-2.js"
run_1_test "formatter_optimized" "-w -O -gc-sanitize-handles=0 -target=HBC" "$TMPDIR/thrower-with-formatter.hbc" "$TMPDIR/thrower-with-formatter.js"


# 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.

# RUN: bash %s %S %T %hermes | %FileCheck %s
# shellcheck shell=bash disable=SC2086

SRCDIR=$1
TMPDIR=$2
HERMES=$3

HBC_FILE="$TMPDIR/out.hbc"
RAW_TRACE="$TMPDIR/raw_trace.txt"
SYM_TRACE="$TMPDIR/symbolicated_trace.txt"

"$HERMES" -gc-sanitize-handles=0 -commonjs -output-source-map \
  -emit-binary -out "$HBC_FILE" \
  "$SRCDIR"

"$HERMES" "$HBC_FILE" > "$RAW_TRACE"

# Stringize the sourcemap and raw stack trace, concatenate them along with
# the symbolicator source, and then execute that. The output will be a
# symbolicated stacktrace. This is to enable the test to run via Hermes alone
# (i.e. without introducing a node dependency).
( python3 "$SRCDIR/../stringize.py" SOURCEMAP < "$HBC_FILE.map" ;
  python3 "$SRCDIR/../stringize.py" STACKTRACE < "$RAW_TRACE" ;
  cat "$SRCDIR/../symbolicator.js.in"
) | "$HERMES" - -gc-sanitize-handles=0 > "$SYM_TRACE"

cat "$SYM_TRACE"
# CHECK: Error: ERROR_FOR_TESTING
# CHECK-NEXT:     at mod2Inner ({{.*}}cjs-subdir-2.js:11:17)
# CHECK-NEXT:     at unmappedFunction (null:null:null)
# CHECK-NEXT:     at mappedFunction (/fake/source/of/mappedFunction.js:1:1)
# CHECK-NEXT:     at anonymous ({{.*}}cjs-subdir-2.js:10:47)
# CHECK-NEXT:     at immediatelyInvoke ({{.*}}cjs-subdir-shared.js:9:3)
# CHECK-NEXT:     at mod2fun ({{.*}}cjs-subdir-2.js:9:39)
# CHECK-NEXT:     at run ({{.*}}cjs-subdir-unminified.js:11:20)
# CHECK-NEXT:     at mainInner ({{.*}}cjs-subdir-main.js:12:11)
# CHECK-NEXT:     at immediatelyInvoke ({{.*}}cjs-subdir-shared.js:9:3)
# CHECK-NEXT:     at cjs_module ({{.*}}cjs-subdir-main.js:8:37)


# 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.

# RUN: bash %s %S %T %hermes
# REQUIRES: !fbcode_coverage
# shellcheck shell=bash disable=SC2086

# This test is an end-to-end merge input source-map with hermes debuginfo symbolication test.
# First it runs original non-transformed file throw.js which throws an exception, and records the backtrace.
# It then runs the uglifyjs generated throw.min.js with input source map and records that backtrace
# as the "symbolicated trace".
# Finally it diffs both traces(ignoring full path/column number) to ensure they are the same.
# This tests that generated js code backtrace merged with input source map is identical
# to the original source file backtrace.

SRCDIR=$1
TMPDIR=$2
HERMES=$3

# Perform a symbolication test.
# Argument 1: a name for the test
# Argument 2: parameters to pass to hermes driver.
# Argument 3: input js file to evaluate.
# Argument 4: generated minified file correspoinding to input js file.
# Argument 5: source map for input js file.
run_1_test() {
  NAME=$1;
  ARGS=$2;
  ORIGINAL_JS_FILE=$3;
  GENERATED_JS_FILE=$4;
  JS_FILE_SOURCE_MAP=$5;

  ORIG_TRACE="$TMPDIR/${NAME}_original_trace.txt"
  SYM_TRACE="$TMPDIR/${NAME}_symbolicated_trace.txt"

  # Run the original JS, record the backtrace.
  "$HERMES" $ARGS "$ORIGINAL_JS_FILE" &> "$ORIG_TRACE"

  # Run the generated JS with input source file, record the backtrace symbolicated with merged debuginfo.
  "$HERMES" $ARGS "$GENERATED_JS_FILE" -source-map "$JS_FILE_SOURCE_MAP" &> "$SYM_TRACE"

  # Check if original and symbolicated traces using input source map match using stacktrace_diff.py.
  # stacktrace_diff.py matches stack frames ignoring file full path and column number. This is necessary because:
  # 1. Ignore full path: Original trace's file full path depends on the running matchine while file path
  #   in source map is hard-coded with full path stripped.
  # 2. Ignore column number: Uglifyjs generated source map does not have full fidelity range mapping
  #   for every single tokens so if a generated line/column is in the middle of a mapping range the symbolicated
  #   trace will report the beginning of the range in original source most likely diff in column numbers.
  python3 "$SRCDIR/stacktrace_diff.py" "$ORIG_TRACE" "$SYM_TRACE"
}

# -gc-sanitize-handles=0 because ASAN build is far too slow without it.
run_1_test "default"   "-gc-sanitize-handles=0 -target=HBC" "$SRCDIR/throw.js" "$SRCDIR/throw.min.js" "$SRCDIR/throw.min.js.map"
run_1_test "optimized"   "-O -gc-sanitize-handles=0 -target=HBC" "$SRCDIR/throw.js" "$SRCDIR/throw.min.js" "$SRCDIR/throw.min.js.map"


#!/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.

set -e -o pipefail

hbcattribute() {
  "$HBC_ATTRIBUTE"  "$@"
}

symbolicate() {
  "$SYMBOLICATE" "$@"
}

accumulate() {
  "$ACCUMULATE"
}

# Buck passes in a series of variables like 'HBC_ATTRIBUTE_RUN=somevalue'
while [[ $# != 0 && $1 != -- ]]
do
  declare "$1"
  shift
done
shift

case $# in
  1) hbcattribute "$1" | accumulate ;;
  2) hbcattribute "$1" | symbolicate "$2" --attribution | accumulate ;;
  *)
    echo "Usage: $(basename "$0") bundle.hbc [sourcemap.map]" >&2
    exit 1
esac


#! /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 on any failure
set -e
set -o pipefail

# Check that the supplied binaries exist
[ -x "$HERMES" ] || exit 3
[ -x "$HBCDUMP" ] || exit 4
[ -x "$HBC_READ_TRACE" ] || exit 5

# Create a workspace and make sure it is cleaned up when we exit.
TMP=$(mktemp -d)
trap 'rm -rf $TMP' exit

# The JS file we will compile.
cat <<EOF > "$TMP/test.js"
print("Hello, world!")
EOF

"$HERMES" -O -emit-binary -target=HBC -out="$TMP/test.hbc" "$TMP/test.js"

# The test trace of page accesses (states that we saw one access, of the 0'th
# page and it took 42 microseconds).
# The output test.log is a tsv file, and therefore there are tabs in the string
# below, thus
# @lint-ignore-every TXT2
cat <<EOF > "$TMP/test.log"
Page	Time (us)
0	42
EOF

# The sections we expect hbc-read-trace to output
cat <<EOF > "$TMP/expected"
<unknown>
function-table
string-kinds
identifier-hashes
string-table
overflow-string-table
string-storage
array-buffer
object-key-buffer
object-value-buffer
bigint-storage
regular-expression-table
regular-expression-storage
commonjs-module-table
function-body
function-info
debug-info
EOF

# Run hbc-read-trace and compare it with the above list.
"$HBC_READ_TRACE" -v -D "$HBCDUMP" -B "$TMP/test.hbc" < "$TMP/test.log" \
  | head -n 1 \
  | perl -pe 's/\//\n/g' \
  | diff -u - "$TMP/expected"


#!/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.

set -xe -o pipefail

THIS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

PACKAGES=(
  hermes-estree
  hermes-parser
  hermes-eslint
  hermes-transform
  flow-api-translator
  prettier-plugin-hermes-parser
  babel-plugin-syntax-hermes-parser
)

# Yarn install all packages
yarn install

# Use internal FB build or pass path to WASM parser as first command line argument
FB_BUILD_WASM_PARSER="$THIS_DIR/facebook/buildWasmParser.sh"
if [[ -f "$1" ]]; then
  WASM_PARSER="$1"
elif [[ -f "$FB_BUILD_WASM_PARSER" ]]; then
  WASM_PARSER=$("$FB_BUILD_WASM_PARSER")
else
  echo "Failed to get WASM parser" 1>&2
  exit 1
fi

# Use internal FB build or pass path to include path as second command line argument
FB_GET_INCLUDE_PATH="$THIS_DIR/facebook/getIncludePath.sh"
if [[ -d "$2" ]]; then
  INCLUDE_PATH="$2"
elif [[ -f "$FB_GET_INCLUDE_PATH" ]]; then
  INCLUDE_PATH=$("$FB_GET_INCLUDE_PATH")
else
  echo "Failed to get include path" 1>&2
  exit 1
fi

# Generate the JSON blob used to drive the rest of the JS codegen
yarn babel-node "$THIS_DIR/genESTreeJSON.js" "$INCLUDE_PATH"

# Generate source code, written into package src directories
yarn babel-node "$THIS_DIR/genNodeDeserializers.js" "$INCLUDE_PATH"
yarn babel-node "$THIS_DIR/genParserVisitorKeys.js"
yarn babel-node "$THIS_DIR/genESTreeVisitorKeys.js"
yarn babel-node "$THIS_DIR/genPredicateFunctions.js"
yarn babel-node "$THIS_DIR/genTransformNodeTypes.js"

# Create fresh dist directory for each package, and copy source files in
for package in "${PACKAGES[@]}"; do
  PACKAGE_DIR="$THIS_DIR/../$package"
  rm -rf "$PACKAGE_DIR/dist"

  cp -r "$PACKAGE_DIR/src" "$PACKAGE_DIR/dist"

  # There is no system for flow to emit flow declarations for files
  # So we rename all the JS files to .js.flow so they are treated like flow declarations
  find "$PACKAGE_DIR/dist" -type f -name "*.js" -exec grep -q " @flow" {} \; -exec rename --no-overwrite ".js" ".js.flow" {} \;

  # Copy just the JS files again
  (cd "$PACKAGE_DIR/src" && find . -type f -name '*.js' -exec cp --parents -t ../dist {} +)
done

# Generate source code that only applies to dist directory
yarn babel-node "$THIS_DIR/genWasmParser.js" "$WASM_PARSER"
# TODO: Move these to `src` directory, currently causes Flow errors.
yarn babel-node "$THIS_DIR/genSelectorTypes.js"
yarn babel-node "$THIS_DIR/genTransformCloneTypes.js"
yarn babel-node "$THIS_DIR/genTransformModifyTypes.js"
yarn babel-node "$THIS_DIR/genTransformReplaceNodeTypes.js"

for package in "${PACKAGES[@]}"; do
  PACKAGE_DIST_DIR="$THIS_DIR/../$package/dist"
  yarn babel --config-file="$THIS_DIR/../babel.config.js" "$PACKAGE_DIST_DIR" --out-dir="$PACKAGE_DIST_DIR"
done

# Validate that the generated flow files are sane
# We don't bother validating the raw-js files as they are validated by babel first
yarn eslint "*/dist/**/*.js.flow" --no-ignore


#!/bin/sh

# Copyright (c) 2013, Ben Noordhuis <info@bnoordhuis.nl>
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

cd `dirname "$0"`

if [ "$LIBTOOLIZE" = "" ] && [ "`uname`" = "Darwin" ]; then
  LIBTOOLIZE=glibtoolize
fi

ACLOCAL=${ACLOCAL:-aclocal}
AUTOCONF=${AUTOCONF:-autoconf}
AUTOMAKE=${AUTOMAKE:-automake}
LIBTOOLIZE=${LIBTOOLIZE:-libtoolize}

automake_version=`"$AUTOMAKE" --version | head -n 1 | sed 's/[^.0-9]//g'`
automake_version_major=`echo "$automake_version" | cut -d. -f1`
automake_version_minor=`echo "$automake_version" | cut -d. -f2`

UV_EXTRA_AUTOMAKE_FLAGS=
if test "$automake_version_major" -gt 1 || \
   test "$automake_version_major" -eq 1 && \
   test "$automake_version_minor" -gt 11; then
  # serial-tests is available in v1.12 and newer.
  UV_EXTRA_AUTOMAKE_FLAGS="$UV_EXTRA_AUTOMAKE_FLAGS serial-tests"
fi
echo "m4_define([UV_EXTRA_AUTOMAKE_FLAGS], [$UV_EXTRA_AUTOMAKE_FLAGS])" \
    > m4/libuv-extra-automake-flags.m4

set -ex
"$LIBTOOLIZE" --copy
"$ACLOCAL" -I m4
"$AUTOCONF"
"$AUTOMAKE" --add-missing --copy


#!/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.

if [ "$#" -ne 1 ]; then
  echo "Usage: gen_cpp.sh SOURCE"
  exit 1
fi

FNRUNTIME_DIR=$(dirname ${0})/runtime
BIN_DIR=$(dirname ${0})/../../target/debug

name="${1%.js}"
name="${name##*/}"
"$BIN_DIR/fnc" "${1}" | clang-format > "${name}.cpp"


#!/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.

if [ "$#" -ne 3 ]; then
  echo "Usage: run_fnc.sh FNC SOURCE OUTPUT"
  exit 1
fi

FNRUNTIME_DIR=$(dirname ${0})/runtime

"${1}" -g "${2}" | c++ -x c++ -I "${FNRUNTIME_DIR}" "${FNRUNTIME_DIR}/FNRuntime.cpp" - -O3 -std=c++17 -o "${3}"


#!/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.

THIS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

[ ! -d "$HERMES_BUILD" ] && echo "HERMES_BUILD must be valid" && exit 1

rustgen=$HERMES_BUILD/bin/rustgen

$rustgen ffi > "$THIS_DIR/../../juno/crates/hermes/src/parser/generated_ffi.rs"
$rustgen cvt > "$THIS_DIR/../../juno/crates/juno/src/hparser/generated_cvt.rs"


#!/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.

if [ "$DEBUG" = true ]; then
  BUILD_TYPE="Debug"
else
  BUILD_TYPE="Release"
fi

function command_exists {
  command -v "${1}" > /dev/null 2>&1
}

if command_exists "cmake"; then
  if command_exists "ninja"; then
    BUILD_SYSTEM="Ninja"
  else
    BUILD_SYSTEM="Unix Makefiles"
  fi
else
  echo >&2 'CMake is required to install Hermes, install it with: brew install cmake'
  exit 1
fi

function get_release_version {
  ruby -rcocoapods-core -rjson -e "puts Pod::Specification.from_file('hermes-engine.podspec').version"
}

function get_ios_deployment_target {
  ruby -rcocoapods-core -rjson -e "puts Pod::Specification.from_file('hermes-engine.podspec').deployment_target('ios')"
}

function get_mac_deployment_target {
  ruby -rcocoapods-core -rjson -e "puts Pod::Specification.from_file('hermes-engine.podspec').deployment_target('osx')"
}

# Build host hermes compiler for internal bytecode
function build_host_hermesc {
  cmake -S . -B build_host_hermesc
  cmake --build ./build_host_hermesc --target hermesc
}

# Utility function to configure an Apple framework
function configure_apple_framework {
  local build_cli_tools enable_bitcode

  if [[ $1 == iphoneos || $1 == catalyst ]]; then
    enable_bitcode="true"
  else
    enable_bitcode="false"
  fi
  if [[ $1 == macosx ]]; then
    build_cli_tools="true"
  else
    build_cli_tools="false"
  fi

  cmake -S . -B "build_$1" -G "$BUILD_SYSTEM" \
    -DHERMES_APPLE_TARGET_PLATFORM:STRING="$1" \
    -DCMAKE_OSX_ARCHITECTURES:STRING="$2" \
    -DCMAKE_OSX_DEPLOYMENT_TARGET:STRING="$3" \
    -DHERMES_ENABLE_DEBUGGER:BOOLEAN=true \
    -DHERMES_ENABLE_INTL:BOOLEAN=true \
    -DHERMES_ENABLE_LIBFUZZER:BOOLEAN=false \
    -DHERMES_ENABLE_FUZZILLI:BOOLEAN=false \
    -DHERMES_ENABLE_TEST_SUITE:BOOLEAN=false \
    -DHERMES_ENABLE_BITCODE:BOOLEAN="$enable_bitcode" \
    -DHERMES_BUILD_APPLE_FRAMEWORK:BOOLEAN=true \
    -DHERMES_BUILD_APPLE_DSYM:BOOLEAN=true \
    -DHERMES_ENABLE_TOOLS:BOOLEAN="$build_cli_tools" \
    -DIMPORT_HERMESC:PATH="$PWD/build_host_hermesc/ImportHermesc.cmake" \
    -DCMAKE_INSTALL_PREFIX:PATH=../destroot \
    -DCMAKE_BUILD_TYPE="$BUILD_TYPE"
}

# Utility function to build an Apple framework
function build_apple_framework {
  echo "Building framework for $1 with architectures: $2"

  build_host_hermesc
  [ ! -f "$PWD/build_host_hermesc/ImportHermesc.cmake" ] &&
  echo "Host hermesc is required to build apple frameworks!"

  configure_apple_framework "$1" "$2" "$3"

  if [[ "$BUILD_SYSTEM" == "Ninja" ]]; then
    (cd "./build_$1" && ninja install/strip)
  else
    (cd "./build_$1" && make install/strip)
  fi
}

# Accepts an array of frameworks and will place all of
# the architectures into an universal folder and then remove
# the merged frameworks from destroot
function create_universal_framework {
  cd ./destroot/Library/Frameworks || exit 1

  local platforms=("$@")
  local args=""

  echo "Creating universal framework for platforms: ${platforms[*]}"

  for i in "${!platforms[@]}"; do
    args+="-framework ${platforms[$i]}/hermes.framework "
  done

  mkdir universal
  xcodebuild -create-xcframework $args -output "universal/hermes.xcframework"

  for platform in $@; do
    rm -r "$platform"
  done

  cd - || exit 1
}


#!/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.

. ./utils/build-apple-framework.sh

if [ ! -d destroot/Library/Frameworks/universal/hermes.xcframework ]; then
    ios_deployment_target=$(get_ios_deployment_target)

    build_apple_framework "iphoneos" "arm64" "$ios_deployment_target"
    build_apple_framework "iphonesimulator" "x86_64;arm64" "$ios_deployment_target"
    build_apple_framework "catalyst" "x86_64;arm64" "$ios_deployment_target"

    create_universal_framework "iphoneos" "iphonesimulator" "catalyst"
else
    echo "Skipping; Clean \"destroot\" to rebuild".
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.

. ./utils/build-apple-framework.sh
if [ ! -d destroot/Library/Frameworks/macosx/hermes.framework ]; then
    mac_deployment_target=$(get_mac_deployment_target)

    build_apple_framework "macosx" "x86_64;arm64" "$mac_deployment_target"
else
    echo "Skipping; Clean \"destroot\" to rebuild".
fi


#!/usr/bin/env 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.

if ! (return 0 2>/dev/null); then
  echo "commons.sh must be sourced"
  exit 1
fi

# Run a command repeatedly until it success (exit code is 0), up to X times.
# For example, "retry 3 make -j2" will run "make -j2" repeatedly until
# it fails 3 times or succeeds.
function retry() {
  RETRY=$1
  ATTEMPTS=0
  while (( ATTEMPTS <= RETRY )); do
    "${@:2}" && return 0
    ATTEMPTS=$((ATTEMPTS+1))
    echo "Retry: $ATTEMPTS failures so far"
  done
  echo "Retry depleted for command: ${*:2}"
  return 1
}

# Determine platform so that things like NT
# don't need to be littered everywhere.
case "$(uname)" in
  "Linux")
    PLATFORM="linux" ;;
  "Darwin")
    PLATFORM="macosx" ;;
  *"_NT-"*)
    PLATFORM="windows" ;;
  *)
    PLATFORM="unknown" ;;
esac

# Setup Windows specific path conversion
if [[ "$PLATFORM" == "windows" ]]; then
  platform_path() {
    # Cygwin, MSYS, and MSYS2 all provides cygpath
    cygpath -m -- "$@"
  }
  # Disable MSYS and MSYS2 automatic path conversion. This script needs to run
  # in both Cygwin and MSYS*. Allowing the automatic path conversion,
  # which isn't available in Cygwin, allows bugs to hide.
  export MSYS2_ARG_CONV_EXCL="*"
  export MSYS_NO_PATHCONV=1
else
  platform_path() {
    echo "$@"
  }
fi


#!/usr/bin/env 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.

IFS=$'\n'
set -f

all=0
force=0
if [ "$1" == "-a" ]; then
  shift
  all=1
elif [ "$1" == "-f" ]; then
  shift
  force=1
fi

[ -n "$1" ] && {
  echo "$0: Too many arguments" >&2
  exit 1
}

# Look for clang-format at a fixed path relative to the script.
script_path="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
clang_format_path="${script_path}/../../../tools/third-party/clang-format"
if [ "$(uname)" == Linux ]; then
  clang_format="${clang_format_path}/linux/x86_64/clang-format"
else
  clang_format="${clang_format_path}/macos/clang-format"
fi

# Fall back to one in $PATH if not found.
[ -x "${clang_format}" ] || clang_format="$(which clang-format)"

if [ ! -x "$clang_format" ]; then
  echo "ERROR: Must have clang-format in PATH"
  exit 1
fi
clang_format_version="$("$clang_format" --version)"
if echo "$clang_format_version" | grep -q -v '12.0.*'
then
   printf "ERROR: clang-format's version must match 12.0.*\n  clang-format path: %s\n  clang-format --version: %s" "$clang_format" "$clang_format_version"
   exit 1
fi

THIS_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
cd "$THIS_DIR"/../ || exit 1

have_changes=0       # We have uncommitted changes
authored_previous=0  # We authored the most recent commit on this branch

if [[ $(hg status -mard 2>/dev/null) ]]; then
  have_changes=1
fi

if hg log -l 1 --template="{author}" | grep -q -e "<$USER@" -e "^$USER$"
then
  authored_previous=1
fi

files=()

if (( all )); then
  echo "Formatting all files..."
  files=(
    $(find lib include tools unittests \
        -name \*.h -print -o -name \*.cpp -print)
  )
elif (( have_changes )); then
  echo "Formatting only modified files..."
  files=( $(hg st . -man --include "**.{h,cpp,inc,def,mm,m}") )

elif (( authored_previous )) || (( force )); then
  last_commit_files=( $(hg st . -man --change . | grep -E '\.(h|cpp|inc|def|mm|m)$') )
  echo "There are no modified files, but you authored the last commit:"
  printf '  %s\n' "${last_commit_files[@]}"
  if (( !force )); then
    read -r -p "Format files in that commit? [y/N]" reply
    if [[ $reply != [Yy] ]]; then
      echo "Not doing anything."
      exit 0
    fi
  fi
  files=( "${last_commit_files[@]}" )
else
  echo "You have no modified files and you didn't recently commit on this branch."
  echo "To format all files: $0 -a"
  exit 1
fi

for f in "${files[@]}"; do
  before=$(date -r "$f")
  "$clang_format" --verbose -i -style=file "$f" 2>&1 | tr -d "\n"
  echo -n '...'
  after=$(date -r "$f")
  test "$before" = "$after" && echo "ok" || echo "reformatted"
done
echo
echo "Done"


#!/usr/bin/env sh
# 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.

# This script generated the `lib/InternalBytecode/Promise.js` by performing the
# below steps:
#
# 0. It copies the `util/promise/` to a tmp dir to run `yarn` and `rollup`. The
#   tmp dir is always wiped away on Bash's trap exit so we can keep our source
#   tree clean regardless of whether the script was success or not.
#
# 1. The Rollup is configured to build the `util/promise/index.js`, which
#   imports the `promise` polyfill that we installed with `yarn`, exposes it to
#   Hermes's globalThis, and then setup Hermes promise rejection tracking.
#
# 2. It adds `@nolint` to the start of the file and append a snippet to make
#   the initialization of Promise conditionalized against
#   `HermesInternal.hasPromise()` to ensure there is no runtime overhead when
#   Hermes' Promise flag is disabled.
#
# 3. Finally, it moved the resulted file to the `InternalBytecode`.

SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

BC_DIR="${SCRIPT}/../lib/InternalBytecode"
TMP_DIR=$(mktemp -d)
PROMISE_DIR="${SCRIPT}/promise"
TMP_PROMISE_DIR="${TMP_DIR}/promise"

TMP_PROMISE_JS="${TMP_PROMISE_DIR}/Promise.js"
BC_PROMISE_JS="${BC_DIR}/01-Promise.js"

NOLINT="/* @nolint */"
PATCH1="  var useEngineQueue = HermesInternal.useEngineQueue()\;"
PATCH2='(useEngineQueue ? HermesInternal.enqueueJob : setImmediate)'

gen() {
  # It's tricky to ensure `sed -i` work on both GNU and macOS consistently.
  # https://stackoverflow.com/questions/5694228/sed-in-place-flag-that-works-both-on-mac-bsd-and-linux
  sed -i.bak "1s;^;${NOLINT};" $TMP_PROMISE_JS && \
  sed -i.bak "3s;^;${PATCH1};" $TMP_PROMISE_JS && \
  sed -i.bak "s/setImmediate/${PATCH2}/g" $TMP_PROMISE_JS && \
  sed -i.bak '$ d' $TMP_PROMISE_JS && \
  cat <<EOT >> $TMP_PROMISE_JS
});
if (HermesInternal?.hasPromise?.()) {
  initPromise();
}
EOT
}

cleanup() {
  rm -rf $TMP_DIR
}

trap cleanup EXIT
cp -r $PROMISE_DIR $TMP_DIR
cd $TMP_PROMISE_DIR
yarn && yarn start && gen && mv $TMP_PROMISE_JS $BC_PROMISE_JS


#!/usr/bin/env 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.

if [ $(which clang-tidy) ]; then
  FILES=`find lib include tools unittests -name \*.h -print -o -name \*.cpp -print`

  FARRAY=( $FILES ) # count the number of files to process
  echo  Inspecting ${#FARRAY[@]} files

  for F in $FILES; do
    clang-tidy $F -p ../build/ $1
    echo -n .
  done
  echo
  echo "Done"
  exit
fi

echo "ERROR: can't find clang-tidy in your path."


#!/bin/sh
# 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.

# README:
# To update the fbcode copy of Hermes, follow these steps:
# 1) cd to fbsource/xplat/hermes/utils
# 2) Run the current script: ./update-fbcode-hermes.sh
#    This should leave you with files copied over, and new files as hg adds.
# 3) Until we update the xplat hermes to the newer LLVM used in fbcode,
#    if any of the files we had to modify for the LLVM version (only
#    4, I believe) changed, we have to re-apply those changes.
#    Those changes are in D10353003.  So attempt to build, in fbsource/fbcode:
#      buick build xplat/hermes/...
#    For any errors, check whether the file is one of those modified
#    in the given diff, and reapply the changes.
#    You may also get errors if BUCK files changed; if so, you need to
#    make equivalent changes in the corresponding TARGETS file.
#
# Not completely automatic, but not too bad.

case $(pwd) in
    *fbsource/xplat/hermes/utils) ;;
    *) echo Must run from fbsource/xplat/hermes/utils; exit 1;;
esac

# Move to fbsource
cd ../../.. || exit

# copy hermes to fbcode
echo Copying hermes.
/bin/cp -r xplat/hermes fbcode/xplat
# Now remove some directories with large files we don't need in fbcode.
echo Removing unnecessary hermes subdirs.
/bin/rm -rf fbcode/xplat/hermes/facebook/js_bundles
/bin/rm -rf fbcode/xplat/hermes/facebook/sandcastle

# copy jsi to fbcode
echo Copying jsi.
/bin/cp -r xplat/jsi fbcode/xplat

# Now do hg adds for any new files:

echo Doing hg adds.
hg status > /tmp/hg-status.out
grep "^\\? " /tmp/hg-status.out > /tmp/hg-status2.out
sed -e "s/^\\?/hg add/" /tmp/hg-status2.out > /tmp/hg-status3.out
# This executes the shell commands in /tmp/hg-status3.out.  Like "source".
. /tmp/hg-status3.out

/bin/rm /tmp/hg-status.out /tmp/hg-status2.out /tmp/hg-status3.out


#!/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.

# This script creates a build subdirectory called "build_wasm" and builds Hermes
# inside it. The result (hermes.js, hermes.wasm) will be under "build_wasm/bin".
# It requires three parameters:
# - the path to Emscripten, so that it can find
#   "emscripten/cmake/Modules/Platform/Emscripten.cmake" relative to it
# - the path to the Hermes source tree
# - the path to a host hermesc, so that it can find "ImportHermesc.cmake"
#   relative to it. See <https://hermesengine.dev/docs/emscripten>
#
# An example of usage:
#   ./build-hermes.sh ~/github/emsdk/upstream/ ~/github/hermes ~/hermes-host-hermesc

SCRIPT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
BUILD_DIR="${SCRIPT}/build_wasm"
REL_DIR="${SCRIPT}/static"

set -e

[ -z "$1" ] && echo "Emscripten path required" && exit 1
EMS_PATH="$1"
shift

[ -z "$1" ] && echo "Hermes path required" && exit 1
HERMES_PATH="$1"
shift

[ -z "$1" ] && echo "Host Hermesc path required" && exit 1
HOST_HERMESC_PATH="$1"
shift

FLAGS=""
FLAGS="$FLAGS -s WASM=1"
FLAGS="$FLAGS -s ALLOW_MEMORY_GROWTH=0"
FLAGS="$FLAGS -s TOTAL_MEMORY=33554432"
FLAGS="$FLAGS -s MODULARIZE=1 -s EXPORT_NAME=createHermes"
FLAGS="$FLAGS -s INVOKE_RUN=0"
FLAGS="$FLAGS -s EXIT_RUNTIME=1"
FLAGS="$FLAGS -s NODERAWFS=0"
FLAGS="$FLAGS -s EXTRA_EXPORTED_RUNTIME_METHODS=[callMain,FS]"

cleanup() {
  rm -rf "$BUILD_DIR"
}

configure() {
  mkdir "$BUILD_DIR" && cd "$BUILD_DIR"
  cmake "$HERMES_PATH" \
    -DCMAKE_TOOLCHAIN_FILE="$EMS_PATH/emscripten/cmake/Modules/Platform/Emscripten.cmake" \
    -DCMAKE_BUILD_TYPE=MinSizeRel \
    -DIMPORT_HERMESC:PATH="$HOST_HERMESC_PATH/ImportHermesc.cmake" \
    -DCMAKE_EXE_LINKER_FLAGS="$FLAGS"
}

build () {
  make -j hermes
}

# copy the build artifacts to release dir
copy () {
  cp "$BUILD_DIR/bin/hermes.js" "$REL_DIR/hermes.js"
  cp "$BUILD_DIR/bin/hermes.wasm" "$REL_DIR/hermes.wasm"
}

cleanup && configure && build && copy


#!/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.

set -e
set -o pipefail

if hash xcpretty 2>/dev/null; then
  HAS_XCPRETTY=true
fi

BUILD_DIRECTORY=build

function invoke_xcodebuild() {
  local arguments=$@
  if [[ -n $HAS_XCPRETTY ]]; then
    NSUnbufferedIO=YES xcodebuild $arguments | xcpretty -c
  else
    xcodebuild $arguments
  fi
}

function framework_build() {
  local name=$1
  local output_directory=$2

  invoke_xcodebuild \
    -project FBSimulatorControl.xcodeproj \
    -scheme $name \
    -sdk macosx \
    -derivedDataPath $BUILD_DIRECTORY \
    build

  if [[ -n $output_directory ]]; then
    framework_install $name $output_directory
  fi
}

function framework_install() {
  local name=$1
  local output_directory=$2
  local artifact="$BUILD_DIRECTORY/Build/Products/Debug/$name.framework"
  local output_directory_framework="$output_directory/Frameworks"

  echo "Copying Build output of $artifact to $output_directory_framework"
  mkdir -p "$output_directory_framework"
  cp -R $artifact "$output_directory_framework/"
}

function framework_test() {
  local name=$1
  invoke_xcodebuild \
    -project FBSimulatorControl.xcodeproj \
    -scheme $name \
    -sdk macosx \
    -derivedDataPath $BUILD_DIRECTORY \
    test
}

function core_framework_build() {
  framework_build FBControlCore $1
}

function core_framework_test() {
  framework_test FBControlCore
}

function xctest_framework_build() {
  framework_build XCTestBootstrap $1
}

function xctest_framework_test() {
  framework_test XCTestBootstrap
}

function simulator_framework_build() {
  framework_build FBSimulatorControl $1
}

function simulator_framework_test() {
  framework_test FBSimulatorControl
}

function device_framework_build() {
  framework_build FBDeviceControl $1
}

function device_framework_test() {
  framework_test FBDeviceControl
}

function all_frameworks_build() {
  local output_directory=$1
  core_framework_build $output_directory
  xctest_framework_build $output_directory
  simulator_framework_build $output_directory
  device_framework_build $output_directory
}

function all_frameworks_test() {
  core_framework_test
  xctest_framework_test
  simulator_framework_test
  device_framework_test
}

function strip_framework() {
  local FRAMEWORK_PATH="$BUILD_DIRECTORY/Build/Products/Debug/$1"
  if [ -d "$FRAMEWORK_PATH" ]; then
    echo "Stripping Framework $FRAMEWORK_PATH"
    rm -r "$FRAMEWORK_PATH"
  fi
}

function cli_build() {
  local name=$1
  local output_directory=$2
  local script_directory=$1/Scripts

  invoke_xcodebuild \
    -workspace $name/$name.xcworkspace \
    -scheme $name \
    -sdk macosx \
    -derivedDataPath $BUILD_DIRECTORY \
    build

  strip_framework "FBSimulatorControlKit.framework/Versions/Current/Frameworks/FBSimulatorControl.framework"
  strip_framework "FBSimulatorControlKit.framework/Versions/Current/Frameworks/FBDeviceControl.framework"
  strip_framework "FBSimulatorControl.framework/Versions/Current/Frameworks/XCTestBootstrap.framework"
  strip_framework "FBSimulatorControl.framework/Versions/Current/Frameworks/FBControlCore.framework"
  strip_framework "FBDeviceControl.framework/Versions/Current/Frameworks/XCTestBootstrap.framework"
  strip_framework "FBDeviceControl.framework/Versions/Current/Frameworks/FBControlCore.framework"
  strip_framework "XCTestBootstrap.framework/Versions/Current/Frameworks/FBControlCore.framework"

  if [[ -n $output_directory ]]; then
    cli_install $output_directory $script_directory
  fi
}

function cli_install() {
  local output_directory=$1
  local script_directory=$2
  local cli_artifact="$BUILD_DIRECTORY/Build/Products/Debug/!(*.framework)"
  local framework_artifact="$BUILD_DIRECTORY/Build/Products/Debug/*.framework"
  local output_directory_cli="$output_directory/bin"
  local output_directory_framework="$output_directory/Frameworks"

  mkdir -p "$output_directory_cli"
  mkdir -p "$output_directory_framework"

  shopt -s extglob

  echo "Copying Build output from $cli_artifact to $output_directory_cli"
  cp -R $cli_artifact "$output_directory_cli"

  echo "Copying Build output from $framework_artifact to $output_directory_framework"
  cp -R $framework_artifact "$output_directory_framework"

  if [[ -d $script_directory ]]; then
    echo "Copying Scripts from $script_directory to $output_directory_cli"
    cp -R "$2"/* "$output_directory_cli"
  fi

  shopt -u extglob
}

function cli_framework_test() {
  NAME=$1
  invoke_xcodebuild \
    -workspace $NAME/$NAME.xcworkspace \
    -scheme $NAME \
    -sdk macosx \
    -derivedDataPath $BUILD_DIRECTORY \
    test
}

function cli_e2e_test() {
  NAME=$1
  pushd $NAME/cli-tests
  py=$(which python3.6 || which python3 || which python)
  $py ./tests.py
  popd
}

function print_usage() {
cat <<EOF
./build.sh usage:
  /build.sh <target> <command> [<arg>]*

Supported Commands:
  help
    Print usage.
  framework build <output-directory>
    Build the FBSimulatorControl.framework. Optionally copies the Framework to <output-directory>
  framework test
    Build then Test the FBSimulatorControl.framework.
  fbxctest test
    Builds the FBXCTestKit.framework and runs the tests.
EOF
}

if [[ -n $TARGET ]]; then
  echo "using target $TARGET"
elif [[ -n $1 ]]; then
  TARGET=$1
  echo "using target $TARGET"
else
  echo "No target argument or $TARGET provided"
  print_usage
  exit 1
fi

if [[ -n $COMMAND ]]; then
  echo "using command $COMMAND"
elif [[ -n $2 ]]; then
  COMMAND=$2
  echo "using command $COMMAND"
else
  echo "No command argument or $COMMAND provided"
  print_usage
  exit 1
fi

if [[ -n $OUTPUT_DIRECTORY ]]; then
  echo "using output directory $OUTPUT_DIRECTORY"
elif [[ -n $3 ]]; then
  echo "using output directory $3"
  OUTPUT_DIRECTORY=$3
else
  echo "No output directory specified"
fi

case $TARGET in
  help)
    print_usage;;
  framework)
    case $COMMAND in
      build)
        all_frameworks_build $OUTPUT_DIRECTORY;;
      test)
        all_frameworks_test;;
      *)
        echo "Unknown Command $2"
        exit 1;;
    esac;;
  fbxctest)
    case $COMMAND in
      build)
        cli_build fbxctest $OUTPUT_DIRECTORY;;
      test)
        cli_framework_test fbxctest;;
      *)
        echo "Unknown Command $COMMAND"
        exit 1;;
    esac;;
  *)
    echo "Unknown Command $TARGET"
    exit 1;;
esac

# vim: set tabstop=2 shiftwidth=2 filetype=sh:


#!/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.

set -e
set -o pipefail

if hash xcpretty 2>/dev/null; then
  HAS_XCPRETTY=true
fi

BUILD_DIRECTORY=build

function invoke_xcodebuild() {
  local arguments=$@
  if [[ -n $HAS_XCPRETTY ]]; then
    NSUnbufferedIO=YES xcodebuild $arguments | xcpretty -c
  else
    xcodebuild $arguments
  fi
}

function build_idb_deps() {
  if [ -n "$CUSTOM_idb_DEPS_SCRIPT" ]; then
    "$CUSTOM_idb_DEPS_SCRIPT"
  fi
}

function framework_build() {
  local name=$1
  local output_directory=$2

  invoke_xcodebuild \
    -project FBSimulatorControl.xcodeproj \
    -scheme $name \
    -sdk macosx \
    -derivedDataPath $BUILD_DIRECTORY \
    build

  if [[ -n $output_directory ]]; then
    framework_install $name $output_directory
  fi
}

function framework_install() {
  local name=$1
  local output_directory=$2
  local artifact="$BUILD_DIRECTORY/Build/Products/Debug/$name.framework"
  local output_directory_framework="$output_directory/Frameworks"

  echo "Copying Build output of $artifact to $output_directory_framework"
  mkdir -p "$output_directory_framework"
  cp -R $artifact "$output_directory_framework/"
}

function core_framework_build() {
  framework_build FBControlCore $1
}

function xctest_framework_build() {
  framework_build XCTestBootstrap $1
}

function simulator_framework_build() {
  framework_build FBSimulatorControl $1
}

function device_framework_build() {
  framework_build FBDeviceControl $1
}

function all_frameworks_build() {
  local output_directory=$1
  core_framework_build $output_directory
  xctest_framework_build $output_directory
  simulator_framework_build $output_directory
  device_framework_build $output_directory
}

function strip_framework() {
  local FRAMEWORK_PATH="$BUILD_DIRECTORY/Build/Products/Release/$1"
  if [ -d "$FRAMEWORK_PATH" ]; then
    echo "Stripping Framework $FRAMEWORK_PATH"
    rm -r "$FRAMEWORK_PATH"
  fi
}

function cli_build() {
  local name=$1
  local output_directory=$2
  local script_directory=$1/Scripts

  invoke_xcodebuild \
    ONLY_ACTIVE_ARCH=NO \
    -workspace $name.xcworkspace \
    -scheme $name \
    -sdk macosx \
    -derivedDataPath $BUILD_DIRECTORY \
    -configuration Release \
    build

  strip_framework "FBSimulatorControl.framework/Versions/Current/Frameworks/XCTestBootstrap.framework"
  strip_framework "FBSimulatorControl.framework/Versions/Current/Frameworks/FBControlCore.framework"
  strip_framework "FBDeviceControl.framework/Versions/Current/Frameworks/XCTestBootstrap.framework"
  strip_framework "FBDeviceControl.framework/Versions/Current/Frameworks/FBControlCore.framework"
  strip_framework "XCTestBootstrap.framework/Versions/Current/Frameworks/FBControlCore.framework"

  if [[ -n $output_directory ]]; then
    cli_install $output_directory $script_directory
  fi
}

function cli_install() {
  local output_directory=$1
  local script_directory=$2
  local cli_artifact="$BUILD_DIRECTORY/Build/Products/Release/idb_companion"
  local framework_artifact="$BUILD_DIRECTORY/Build/Products/Release/*.framework"
  local output_directory_cli="$output_directory/bin"
  local output_directory_framework="$output_directory/Frameworks"

  mkdir -p "$output_directory_cli"
  mkdir -p "$output_directory_framework"

  shopt -s extglob

  echo "Copying Build output from $cli_artifact to $output_directory_cli"
  cp -R $cli_artifact "$output_directory_cli"

  echo "Copying Build output from $framework_artifact to $output_directory_framework"
  cp -R $framework_artifact "$output_directory_framework"

  if [[ -d $script_directory ]]; then
    echo "Copying Scripts from $script_directory to $output_directory_cli"
    cp -R "$2"/* "$output_directory_cli"
  fi

  shopt -u extglob
}

function print_usage() {
cat <<EOF
./idb_build.sh usage:
  /idb_build.sh <target> <command> [<arg>]*

Supported Commands:
  help
    Print usage.
  framework build <output-directory>
    Build the frameworks. Optionally copies the Framework to <output-directory>
  idb_companion build <output-directory>
    Build the idb companion exectutable. Optionally copies the executable and its dependencies to <output-directory>
EOF
}

if [[ -n $TARGET ]]; then
  echo "using target $TARGET"
elif [[ -n $1 ]]; then
  TARGET=$1
  echo "using target $TARGET"
else
  echo "No target argument or $TARGET provided"
  print_usage
  exit 1
fi

if [[ -n $COMMAND ]]; then
  echo "using command $COMMAND"
elif [[ -n $2 ]]; then
  COMMAND=$2
  echo "using command $COMMAND"
else
  echo "No command argument or $COMMAND provided"
  print_usage
  exit 1
fi

if [[ -n $OUTPUT_DIRECTORY ]]; then
  echo "using output directory $OUTPUT_DIRECTORY"
elif [[ -n $3 ]]; then
  echo "using output directory $3"
  OUTPUT_DIRECTORY=$3
else
  echo "No output directory specified"
fi

case $TARGET in
  help)
    print_usage;;
  framework)
    case $COMMAND in
      build)
        all_frameworks_build $OUTPUT_DIRECTORY;;
      *)
        echo "Unknown Command $2"
        exit 1;;
    esac;;
  idb_companion)
    build_idb_deps
    case $COMMAND in
      build)
        cli_build idb_companion $OUTPUT_DIRECTORY;;
      *)
        echo "Unknown Command $COMMAND"
        exit 1;;
    esac;;
  *)
    echo "Unknown Command $TARGET"
    exit 1;;
esac

# vim: set tabstop=2 shiftwidth=2 filetype=sh: