sapling/build/fbcode_builder/shell_builder.py
Martin Thomas Fleischer a8b76ca8e3 Fix shell builders (#50)
Summary:
In 0ae204a978c11ddefafd81bd319a078239a44c1c the 'projects_dir' option
became a required constructor argument since it is called within the
constructor. However, it has not been adjusted in the subclasses that
used to set the option after instantiation. This commit fixes the
'shell_builder' and the 'debian_system_builder'.
Pull Request resolved: https://github.com/facebook/openr/pull/50

Test Plan:
1. Go to build directory: `cd build`
2. Run the `shell_builder` & `debian_system_builder`:
    - `python fbcode_builder/shell_builder.py`
    - `python debian_system_builder/debian_system_builder.py`

`shell_builder` output before:
```
Traceback (most recent call last):
  File "fbcode_builder/shell_builder.py", line 102, in <module>
    builder = ShellFBCodeBuilder()
  File "/home/butjar/tu/ma/openr/build/fbcode_builder/fbcode_builder.py", line 93, in __init__
    self._github_dir = self.option('projects_dir')
  File "/home/butjar/tu/ma/openr/build/fbcode_builder/fbcode_builder.py", line 108, in option
    raise RuntimeError('Option {0} is required'.format(name))
RuntimeError: Option projects_dir is required
```

`shell_builder` output after:
```
set -exo pipefail
export CCACHE_DIR='/home/butjar/.fbcode_builder-sZshomesZsbutjarsZstusZsmasZsopenr/.ccache' CC="ccache ${CC:-gcc}" CXX="ccache ${CXX:-g++}"
### Diagnostics ###

# Builder ShellFBCodeBuilder(google/googletest:cmake_defines={u'BUILD_GTEST': u'ON', u'BUILD_SHARED_LIBS': u'OFF'}, google/googletest:git_hash=u'release-1.8.1', facebook/openr:local_repo_dir='/home/butjar/tu/ma/openr', facebook/zstd:git_hash=ShellQuoted(u'$(git describe --abbrev=0 --tags origin/master)'), openr/build:cmake_defines={u'ADD_ROOT_TESTS': u'OFF'}, thom311/libnl:git_hash=u'libnl3_2_25', projects_dir=u'/home/butjar/.fbcode_builder-sZshomesZsbutjarsZstusZsmasZsopenr', fmtlib/fmt:git_hash=u'5.3.0', wangle/wangle/build:cmake_defines={u'BUILD_TESTS': u'OFF'}, prefix=u'/home/butjar/.fbcode_builder-sZshomesZsbutjarsZstusZsmasZsopenr/installed', fizz/fizz/build:cmake_defines={u'BUILD_TESTS': u'ON'}, ccache_dir=u'/home/butjar/.fbcode_builder-sZshomesZsbutjarsZstusZsmasZsopenr/.ccache', zeromq/libzmq:git_hash=u'v4.2.2', make_parallelism=4, jedisct1/libsodium:git_hash=u'stable')
hostname
cat /etc/issue || echo no /etc/issue
g++ --version || echo g++ not installed
cmake --version || echo cmake not installed

### Check out fmtlib/fmt, workdir build ###

mkdir -p '/home/butjar/.fbcode_builder-sZshomesZsbutjarsZstusZsmasZsopenr' && cd '/home/butjar/.fbcode_builder-sZshomesZsbutjarsZstusZsmasZsopenr'
git clone  https://github.com/'fmtlib/fmt'
mkdir -p '/home/butjar/.fbcode_builder-sZshomesZsbutjarsZstusZsmasZsopenr'/'fmt'/'build' && cd '/home/butjar/.fbcode_builder-sZshomesZsbutjarsZstusZsmasZsopenr'/'fmt'/'build'
git checkout '5.3.0'

### Build and install fmtlib/fmt ###

...
```

Reviewed By: steven1327

Differential Revision: D21865881

Pulled By: saifhhasan

fbshipit-source-id: dfd78127d3b2c78721f84a3ecafe0b7198c38f06
2020-06-03 14:19:29 -07:00

115 lines
3.6 KiB
Python

#!/usr/bin/env python
# Copyright (c) Facebook, Inc. and its affiliates.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
'''
shell_builder.py allows running the fbcode_builder logic
on the host rather than in a container.
It emits a bash script with set -exo pipefail configured such that
any failing step will cause the script to exit with failure.
== How to run it? ==
cd build
python fbcode_builder/shell_builder.py > ~/run.sh
bash ~/run.sh
'''
import os
import distutils.spawn
from fbcode_builder import FBCodeBuilder
from shell_quoting import (
raw_shell, shell_comment, shell_join, ShellQuoted
)
from utils import recursively_flatten_list
class ShellFBCodeBuilder(FBCodeBuilder):
def _render_impl(self, steps):
return raw_shell(shell_join('\n', recursively_flatten_list(steps)))
def set_env(self, key, value):
return ShellQuoted("export {key}={val}").format(key=key, val=value)
def workdir(self, dir):
return [
ShellQuoted('mkdir -p {d} && cd {d}').format(
d=dir
),
]
def run(self, shell_cmd):
return ShellQuoted('{cmd}').format(cmd=shell_cmd)
def step(self, name, actions):
assert '\n' not in name, 'Name {0} would span > 1 line'.format(name)
b = ShellQuoted('')
return [ShellQuoted('### {0} ###'.format(name)), b] + actions + [b]
def setup(self):
steps = [
ShellQuoted('set -exo pipefail'),
] + self.create_python_venv() + self.python_venv()
if self.has_option('ccache_dir'):
ccache_dir = self.option('ccache_dir')
steps += [
ShellQuoted(
# Set CCACHE_DIR before the `ccache` invocations below.
'export CCACHE_DIR={ccache_dir} '
'CC="ccache ${{CC:-gcc}}" CXX="ccache ${{CXX:-g++}}"'
).format(ccache_dir=ccache_dir)
]
return steps
def comment(self, comment):
return shell_comment(comment)
def copy_local_repo(self, dir, dest_name):
return [
ShellQuoted('cp -r {dir} {dest_name}').format(
dir=dir,
dest_name=dest_name
),
]
def find_project_root():
here = os.path.dirname(os.path.realpath(__file__))
maybe_root = os.path.dirname(os.path.dirname(here))
if os.path.isdir(os.path.join(maybe_root, '.git')):
return maybe_root
raise RuntimeError(
"I expected shell_builder.py to be in the "
"build/fbcode_builder subdir of a git repo")
def persistent_temp_dir(repo_root):
escaped = repo_root.replace('/', 'sZs').replace('\\', 'sZs').replace(':', '')
return os.path.join(os.path.expandvars("$HOME"), '.fbcode_builder-' + escaped)
if __name__ == '__main__':
from utils import read_fbcode_builder_config, build_fbcode_builder_config
repo_root = find_project_root()
temp = persistent_temp_dir(repo_root)
config = read_fbcode_builder_config('fbcode_builder_config.py')
builder = ShellFBCodeBuilder(projects_dir=temp)
if distutils.spawn.find_executable('ccache'):
builder.add_option('ccache_dir',
os.environ.get('CCACHE_DIR', os.path.join(temp, '.ccache')))
builder.add_option('prefix', os.path.join(temp, 'installed'))
builder.add_option('make_parallelism', 4)
builder.add_option(
'{project}:local_repo_dir'.format(project=config['github_project']),
repo_root)
make_steps = build_fbcode_builder_config(config)
steps = make_steps(builder)
print(builder.render(steps))