Skip to content

Commit b886e1d

Browse files
authored
feat: implement a simple docker file to run cli commands (#14111)
This PR implements a minimalistic Dockerfile which runs the required CLI commands for Librarian. Testing steps: ``` docker build . -t <image-name> ``` Command: ``` docker run --rm <image-name> ``` Output: ``` 'generate' command executed. ``` Fixes: googleapis/librarian#899
1 parent 62da15d commit b886e1d

File tree

4 files changed

+179
-0
lines changed

4 files changed

+179
-0
lines changed

.generator/Dockerfile

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
FROM marketplace.gcr.io/google/ubuntu2404 AS builder
16+
17+
# TODO(https://github.com/googleapis/librarian/issues/901): Install the necssary dependencies and build tools.
18+
RUN apt-get update && \
19+
apt-get install -y --no-install-recommends \
20+
# Essential for compiling C code
21+
build-essential \
22+
# For downloading secure files
23+
wget \
24+
ca-certificates \
25+
# --- Critical libraries for a complete Python build ---
26+
libssl-dev \
27+
zlib1g-dev \
28+
libbz2-dev \
29+
libffi-dev \
30+
libsqlite3-dev \
31+
libreadline-dev \
32+
# ------------------------------------------------------
33+
&& apt-get clean && \
34+
rm -rf /var/lib/apt/lists/*
35+
36+
# Set up environment variables for tool versions to make updates easier.
37+
# TODO(): Downgrade to Python `3.11` if `3.13.5` is incompatible with googleapis.
38+
ENV PYTHON_VERSION=3.13.5
39+
40+
# Create a symbolic link for `python3` to point to our specific version.
41+
ENV PATH /usr/local/bin/python3.13:$PATH
42+
43+
# Install Python from source
44+
RUN wget https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tgz && \
45+
tar -xvf Python-${PYTHON_VERSION}.tgz && \
46+
cd Python-${PYTHON_VERSION} && \
47+
./configure --enable-optimizations && \
48+
make altinstall && \
49+
cd / && \
50+
rm -rf Python-${PYTHON_VERSION}*
51+
52+
# TODO(https://github.com/googleapis/librarian/issues/904): Install protoc for gencode.
53+
54+
# TODO(https://github.com/googleapis/librarian/issues/903): Install Bazelisk for building a client library.
55+
56+
# TODO(https://github.com/googleapis/librarian/issues/902): Create a dedicate non-root user and
57+
# switch to the non-root user to run subsequent commands.
58+
59+
# Set the working directory in the container.
60+
WORKDIR /app
61+
62+
# TODO(https://github.com/googleapis/librarian/issues/907): Install Python dependencies from requirements.in.
63+
# TODO(https://github.com/googleapis/librarian/issues/905): Install Synthtool by cloning its repo.
64+
# TODO(https://github.com/googleapis/librarian/issues/906): Clone googleapis and run bazelisk build.
65+
66+
# Copy the CLI script into the container and set ownership.
67+
# No other files or dependencies are needed for this simple script.
68+
COPY cli.py .
69+
70+
# Set the entrypoint for the container to run the script.
71+
ENTRYPOINT ["python3.13", "./cli.py"]

.generator/cli.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import argparse
16+
import sys
17+
18+
def handle_configure(dry_run=False):
19+
# TODO(https://github.com/googleapis/librarian/issues/466): Implement configure command.
20+
print("'configure' command executed.")
21+
22+
def handle_generate(dry_run=False):
23+
# TODO(https://github.com/googleapis/librarian/issues/448): Implement generate command.
24+
print("'generate' command executed.")
25+
26+
def handle_build(dry_run=False):
27+
# TODO(https://github.com/googleapis/librarian/issues/450): Implement build command.
28+
print("'build' command executed.")
29+
30+
31+
if __name__ == "__main__":
32+
parser = argparse.ArgumentParser(description="A simple CLI tool.")
33+
subparsers = parser.add_subparsers(dest="command", required=True, help="Available commands")
34+
35+
# Define commands
36+
for command_name, help_text in [
37+
("configure", "Onboard a new library or an api path to Librarian workflow."),
38+
("generate", "generate a python client for an API."),
39+
("build", "Run unit tests via nox for the generated library.")
40+
]:
41+
handler_map = {"configure": handle_configure, "generate": handle_generate, "build": handle_build}
42+
parser_cmd = subparsers.add_parser(command_name, help=help_text)
43+
parser_cmd.set_defaults(func=handler_map[command_name])
44+
45+
if len(sys.argv) == 1:
46+
parser.print_help(sys.stderr)
47+
sys.exit(1)
48+
49+
args = parser.parse_args()
50+
args.func(args)

.generator/test_cli.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from cli import handle_generate, handle_build, handle_configure
16+
17+
18+
def test_handle_configure_dry_run():
19+
# This is a simple test to ensure that the dry run command succeeds.
20+
handle_configure(dry_run=True)
21+
22+
def test_handle_generate_dry_run():
23+
# This is a simple test to ensure that the dry run command succeeds.
24+
handle_generate(dry_run=True)
25+
26+
def test_handle_build_dry_run():
27+
# This is a simple test to ensure that the dry run command succeeds.
28+
handle_build(dry_run=True)

.github/workflows/generator.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
on:
2+
pull_request:
3+
branches:
4+
- main
5+
name: generator
6+
7+
permissions:
8+
contents: read
9+
10+
jobs:
11+
test_generator_cli:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Checkout
15+
uses: actions/checkout@v4
16+
# Use a fetch-depth of 2
17+
# See https://github.com/googleapis/google-cloud-python/issues/12013
18+
# and https://github.com/actions/checkout#checkout-head.
19+
with:
20+
fetch-depth: 2
21+
- name: Setup Python
22+
uses: actions/setup-python@v5
23+
with:
24+
python-version: "3.10"
25+
- name: Install pytest
26+
run: |
27+
python -m pip install pytest
28+
- name: Run generator_cli tests
29+
run: |
30+
pytest .generator/test_cli.py

0 commit comments

Comments
 (0)