From d2c23ed0708d58cb007b7a4f5eb97a55f4011668 Mon Sep 17 00:00:00 2001 From: Jarek Potiuk Date: Sun, 28 Nov 2021 20:52:26 +0100 Subject: [PATCH] Initial commit for new Breeze project It includes: * proposal for initial ADRs (Architecture Decision records) where we will keep decision records about both - Breeze2 and CI * scaffolding for the new breeze command including command line, pre-commit checks, automated tests in CI and requirements --- .github/workflows/ci.yml | 20 ++ .pre-commit-config.yaml | 7 + BREEZE.rst | 16 +- Breeze2 | 55 ++++++ STATIC_CODE_CHECKS.rst | 2 + breeze-complete | 1 + .../adr/0001-record-architecture-decisions.md | 48 +++++ ...002-implement-standalone-python-command.md | 178 ++++++++++++++++++ dev/breeze/pyproject.toml | 20 ++ dev/breeze/setup.cfg | 84 +++++++++ dev/breeze/setup.py | 27 +++ dev/breeze/src/airflow_breeze/__init__.py | 16 ++ dev/breeze/src/airflow_breeze/breeze.py | 71 +++++++ dev/breeze/src/airflow_breeze/ci/__init__.py | 16 ++ .../src/airflow_breeze/visuals/__init__.py | 62 ++++++ dev/breeze/tests/test_commands.py | 22 +++ pyproject.toml | 2 +- setup.cfg | 2 +- 18 files changed, 639 insertions(+), 10 deletions(-) create mode 100755 Breeze2 create mode 100644 dev/breeze/doc/adr/0001-record-architecture-decisions.md create mode 100644 dev/breeze/doc/adr/0002-implement-standalone-python-command.md create mode 100644 dev/breeze/pyproject.toml create mode 100644 dev/breeze/setup.cfg create mode 100644 dev/breeze/setup.py create mode 100644 dev/breeze/src/airflow_breeze/__init__.py create mode 100755 dev/breeze/src/airflow_breeze/breeze.py create mode 100644 dev/breeze/src/airflow_breeze/ci/__init__.py create mode 100644 dev/breeze/src/airflow_breeze/visuals/__init__.py create mode 100644 dev/breeze/tests/test_commands.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aae64e23b675..9ae5ca4b07a6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -237,6 +237,26 @@ jobs: echo "::set-output name=runsOn::\"self-hosted\"" fi + run-new-breeze-tests: + timeout-minutes: 10 + name: Breeze2 tests + runs-on: ${{ fromJson(needs.build-info.outputs.runsOn) }} + needs: [build-info] + defaults: + run: + shell: bash + working-directory: ./dev/breeze + steps: + - uses: actions/checkout@v2 + with: + persist-credentials: false + - uses: actions/setup-python@v2 + with: + python-version: '3.7' + cache: 'pip' + - run: pip install . + - run: python3 -m pytest -n auto --color=yes + tests-ui: timeout-minutes: 10 name: React UI tests diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ca0cb3cbb9a8..e06cc4eaa737 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -404,6 +404,13 @@ repos: ^docs/apache-airflow-providers-apache-hive/commits\.rst$| git| ^CHANGELOG\.txt$ + - id: capitalized-breeze + language: pygrep + name: Only capitalized Breeze used in Breeze2. + description: Please use capitalized "Breeze" in the new Breeze docs + entry: "breeze" + pass_filenames: true + files: ^dev/breeze/doc - id: base-operator language: pygrep name: Check BaseOperator[Link] core imports diff --git a/BREEZE.rst b/BREEZE.rst index 5f2514cff01e..544ef53a5434 100644 --- a/BREEZE.rst +++ b/BREEZE.rst @@ -2195,14 +2195,14 @@ This is the current syntax for `./breeze <./breeze>`_: all airflow-config-yaml airflow-providers-available airflow-provider-yaml-files-ok base-operator bats-tests bats-in-container-tests black blacken-docs boring-cyborg - build build-providers-dependencies changelog-duplicates check-apache-license - check-builtin-literals check-executables-have-shebangs check-extras-order - check-hooks-apply check-integrations check-merge-conflict check-xml - daysago-import-check debug-statements detect-private-key doctoc dont-use-safe-filter - end-of-file-fixer fix-encoding-pragma flake8 flynt codespell forbid-tabs helm-lint - identity incorrect-use-of-LoggingMixin insert-license isort json-schema - language-matters lint-dockerfile lint-openapi markdownlint mermaid mixed-line-ending - mypy mypy-helm no-providers-in-core-examples no-relative-imports + build build-providers-dependencies capitalized-breeze changelog-duplicates + check-apache-license check-builtin-literals check-executables-have-shebangs + check-extras-order check-hooks-apply check-integrations check-merge-conflict + check-xml daysago-import-check debug-statements detect-private-key doctoc + dont-use-safe-filter end-of-file-fixer fix-encoding-pragma flake8 flynt codespell + forbid-tabs helm-lint identity incorrect-use-of-LoggingMixin insert-license isort + json-schema language-matters lint-dockerfile lint-openapi markdownlint mermaid + mixed-line-ending mypy mypy-helm no-providers-in-core-examples no-relative-imports pre-commit-descriptions pre-commit-hook-names pretty-format-json provide-create-sessions providers-changelogs providers-init-file providers-subpackages-init-file provider-yamls pydevd pydocstyle python-no-log-warn diff --git a/Breeze2 b/Breeze2 new file mode 100755 index 000000000000..60cf940468b3 --- /dev/null +++ b/Breeze2 @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +# isort: skip +import os +import sys + +# Python <3.4 does not have pathlib +if sys.version_info.major != 3 or sys.version_info.minor < 7: + print("ERROR! Make sure you use Python 3.7+ !!") + sys.exit(1) + +import subprocess +from os import execv +from pathlib import Path + +AIRFLOW_SOURCES_DIR = Path(__file__).parent.resolve() +BUILD_DIR = AIRFLOW_SOURCES_DIR / ".build" +BUILD_BREEZE_DIR = BUILD_DIR / "breeze2" +BUILD_BREEZE_CFG_SAVED = BUILD_BREEZE_DIR / "setup.cfg.saved" +BUILD_BREEZE_VENV_DIR = BUILD_BREEZE_DIR / "venv" +BUILD_BREEZE_VENV_BIN_DIR = BUILD_BREEZE_VENV_DIR / "bin" +BUILD_BREEZE_VENV_PIP = BUILD_BREEZE_VENV_BIN_DIR / "pip" +BUILD_BREEZE_VENV_BREEZE = BUILD_BREEZE_VENV_BIN_DIR / "Breeze2" + +BREEZE_SOURCE_PATH = AIRFLOW_SOURCES_DIR / "dev" / "breeze" +BREEZE_SETUP_CFG_PATH = BREEZE_SOURCE_PATH / "setup.cfg" + +BUILD_BREEZE_DIR.mkdir(parents=True, exist_ok=True) + + +def needs_installation() -> bool: + """Returns true if Breeze's virtualenv needs (re)installation""" + if not BUILD_BREEZE_VENV_DIR.exists() or not BUILD_BREEZE_CFG_SAVED.exists(): + return True + return BREEZE_SETUP_CFG_PATH.read_text() != BUILD_BREEZE_CFG_SAVED.read_text() + + +def save_config(): + """Saves cfg file to virtualenv to check if there is a need for reinstallation of the virtualenv""" + BUILD_BREEZE_CFG_SAVED.write_text(BREEZE_SETUP_CFG_PATH.read_text()) + + +if needs_installation(): + print(f"(Re)Installing Breeze's virtualenv in {BUILD_BREEZE_VENV_DIR}") + BUILD_BREEZE_VENV_DIR.mkdir(parents=True, exist_ok=True) + subprocess.run([sys.executable, "-m", "venv", f"{BUILD_BREEZE_VENV_DIR}"], check=True) + subprocess.run( + [f"{BUILD_BREEZE_VENV_PIP}", "install", "--upgrade", "-e", "."], cwd=BREEZE_SOURCE_PATH, check=True + ) + save_config() + +if os.name == 'nt': + # This is the best way of running it on Windows, though it leaves the original process hanging around + subprocess.run([f"{BUILD_BREEZE_VENV_BREEZE}.exe"] + sys.argv[1:], check=True) +else: + execv(f"{BUILD_BREEZE_VENV_BREEZE}", [f"{BUILD_BREEZE_VENV_BREEZE}"] + sys.argv[1:]) diff --git a/STATIC_CODE_CHECKS.rst b/STATIC_CODE_CHECKS.rst index ce5a4a3a6959..4d926717c348 100644 --- a/STATIC_CODE_CHECKS.rst +++ b/STATIC_CODE_CHECKS.rst @@ -148,6 +148,8 @@ require Breeze Docker images to be installed locally. ------------------------------------ ---------------------------------------------------------------- ------------ ``build-providers-dependencies`` Regenerates the JSON file with cross-provider dependencies ------------------------------------ ---------------------------------------------------------------- ------------ +``capitalized-breeze`` Breeze has to be Capitalized in Breeze2 +------------------------------------ ---------------------------------------------------------------- ------------ ``changelog-duplicates`` Checks for duplicate changelog entries ------------------------------------ ---------------------------------------------------------------- ------------ ``check-apache-license`` Checks compatibility with Apache License requirements diff --git a/breeze-complete b/breeze-complete index 799ac38ac12c..8606e6094c5f 100644 --- a/breeze-complete +++ b/breeze-complete @@ -85,6 +85,7 @@ blacken-docs boring-cyborg build build-providers-dependencies +capitalized-breeze changelog-duplicates check-apache-license check-builtin-literals diff --git a/dev/breeze/doc/adr/0001-record-architecture-decisions.md b/dev/breeze/doc/adr/0001-record-architecture-decisions.md new file mode 100644 index 000000000000..d2e25cf852f5 --- /dev/null +++ b/dev/breeze/doc/adr/0001-record-architecture-decisions.md @@ -0,0 +1,48 @@ + + + + +**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* + +- [1. Record architecture decisions](#1-record-architecture-decisions) + - [Status](#status) + - [Context](#context) + - [Decision](#decision) + - [Consequences](#consequences) + +# 1. Record architecture decisions + +Date: 2021-11-28 + +## Status + +Accepted + +## Context + +We need to record the architectural decisions made on this project. + +## Decision + +We will use Architecture Decision Records, as [described by Michael Nygard](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions). + +## Consequences + +See Michael Nygard's article, linked above. For a lightweight ADR toolset, see Nat Pryce's [adr-tools](https://github.com/npryce/adr-tools). diff --git a/dev/breeze/doc/adr/0002-implement-standalone-python-command.md b/dev/breeze/doc/adr/0002-implement-standalone-python-command.md new file mode 100644 index 000000000000..5f57781c51cb --- /dev/null +++ b/dev/breeze/doc/adr/0002-implement-standalone-python-command.md @@ -0,0 +1,178 @@ + + + + +**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* + +- [2. Implement standalone python command](#2-implement-standalone-python-command) + - [Status](#status) + - [Context](#context) + - [Decision](#decision) + - [Consequences](#consequences) + + + +# 2. Implement standalone python command + +Date: 2021-11-28 + +## Status + +Draft + +## Context + +The [Breeze](https://github.com/apache/airflow/blob/main/BREEZE.rst) is +a command line development environment for Apache Airflow that makes +it easy to setup Airflow development and test environment easily +(< 10 minutes is the goal) and enable contributors to run any subset +of tests that are executed in our CI environment easily. + +The environment has proven to be very useful (it has successfully onboarded +a number of new contributors, and it makes the development environment of +even seasoned contributors much easier as it provides a very easy +replication of the CI environment as well as very easy to setup test +environment that can be used to run: + +* Unit tests +* Integration tests +* Kubernetes/Helm tests +* System tests + +It also serves as a base for our CI execution environment. The same scripts and tools are used +in our CI (based on GitHub actions). A lot of common code and function between CI and Breeze are +shared between the CI and Breeze. All those tools are held in "ci" package. + +Unfortunately, Breeze is largely based on Bash code - for which very few people (except maybe the +Breeze creator - Jarek Potiuk, the author of this document) have any other feeling that uneasiness, +disgust and fear of it :). Since Airflow is largely based on Python, the common consensus is that +Breeze should be rewritten in Python. + +In November 2021, Outreachy sponsored two internship for two interns: @Bowrna and @edithturn were assigned to +the projects: + +* Convert Airflow Local Development environment `Breeze` - from Bash-based to Python-based +* Rewrite Github Action workflows to Python + +With @potiuk, @eladkal and @xurror as mentors. + +The long-standing issues about those two projects are (and we hope to close the projects during the +three months internship - December 2021 - March 2022): + +* https://github.com/apache/airflow/issues/12282 +* https://github.com/apache/airflow/issues/13182 + +There are a number of problems with Bash scripts: + +* They are difficult to understand, modify and debug as Bash "magic" is somewhat arcane +* They are difficult to implement complex logic with +* Navigating common code that is used from the scripts is cumbersome and lack IDE/tools support +* Default Bash on MacOS is very old (from 3.* line) and it will not be updated to a newer version + which impacts cross-platform Breeze applicability +* Bash only works well for Windows in WSL2 environment, which further undermines cross-platform + abilities of testing and running Airflow + +On the contrary Python - after dropping Python 2 end of life in January 2020, has become much more +appealing as a common scripting language that can be cross-platform and ubiquitous. + +This is the current state of lines of code in the project (generated by `sloccount`): + +``` +SLOC Directory SLOC-by-Language (Sorted) + +144905 tests python=144761,xml=132,sh=12 +130115 airflow python=127249,javascript=2827,sh=39 +12052 docs javascript=8977,python=2931,sh=144 +9073 scripts sh=7457,python=1616 +6314 chart python=6218,sh=96 +3665 top_dir sh=2896,python=769 +3102 dev python=2938,sh=164 +1723 kubernetes_tests python=1723 +280 docker_tests python=280 +140 metastore_browser python=140 +109 clients sh=109 +28 images sh=28 + +Totals grouped by language (dominant language first): +python: 288625 (92.65%) +javascript: 11804 (3.79%) +sh: 10945 (3.51%) +xml: 132 (0.04%) +``` + +We have now >10K lines of shell code now. We'd announce the success of the project if the shell number is less +than `300` lines of code or so, constituting less than `0.1%` of the code base. + +## Decision + +The main decision is: + +**Vast majority of both Breeze and our CI scripts should be Python-based** + +There are likely a number of scripts that will remain in Bash, but they should contain no sophisticated +logic, they should not haave common code in form of libraries and only used to execute simple tasks inside +Docker containers. No Bash should ever be used in the host environment. + +The "working" name of the new Breeze is "Breeze2". We might come up with a better name in the future. In +order to distinguish from the Bash version of Breeze we will always use capitalized form of Breeze as opposed +to lower-case often used for the Bash version. + +There are a few properties of Breeze/CI scripts that should be maintained though + +* It should be possible to start Breeze and run any of the CI scripts without having a specially prepared + virtualenv. If the virtualenv is needed - such environment should be prepared and maintained automatically + by the script being run. The idea is that new person starting their adventure with Airflow can simply + run a command and get everything done with the least number of prerequisites + +* The prerequisites for Breeze and CI are: + * Python 3.7+ (Python 3.6 end of life is December 2021) + * Docker (TBD which minimum version supported) + * Docker Compose (TBD which minimum version supported) + * No other tools and CLI commands should be needed + * The python requirements should be automatically installed when missing in a "Breeze" venv and updated + automatically when needed. The number of Python dependencies needed to run Breeze and CI scripts + should be minimal in order to make the virtualenv installation portable to Linux, MacOS and Windows + environment. + +* There are some basic assumptions that result from our common patterns across other components we use: + * we use `rich` library for colouring terminal output. Using wisely terminal colours + is an essential part of the developer experience. We will have to standardize color usage in + a follow-up adr + * we use `click` library to provide command line parsing and autocompletion (in the future). Click is + a comprehensive library with clean, decorator-based interface and provides rich customisation options + * we use `pytest` to run automated tests for our code + * until we are ready to share it with developers the new `Breeze` script resides in `dev/Breeze` folder, + without yet linking it from main directory of Airflow. Later we will link to it from the main directory + likely as `Breeze2` script (in some environments where filesystem is case-insensitive (MacOS) you cannot + really put two files differing only by case in the same folder. + * There is enough overlap between the CI and Breeze to reuse a lot of commands for building images and + other CI actions that they should be shared between Breeze and CI. Therefore `dev/Breeze` will + also become a home for all the CI scripts that will be used in GitHubActions in CI. + +## Consequences + +The consequences of the change should be largely invisible to the current users of Breeze. They should be +able to perform the same actions and operations as in the Bash version (with possible later decision of +deprecating or removing of some commands). The biggest consequence should be to the whole development +community of Airflow - for them, modifying and extending and fixing Breeze and CI environment should +become much more appealing. + +The old script should remain and be maintained until the most important functionality of the +original Breeze script has been rewritten enough. diff --git a/dev/breeze/pyproject.toml b/dev/breeze/pyproject.toml new file mode 100644 index 000000000000..111f7e3768f3 --- /dev/null +++ b/dev/breeze/pyproject.toml @@ -0,0 +1,20 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. +[tool.black] +line-length = 110 +target-version = ['py37', 'py37', 'py38', 'py39'] +skip-string-normalization = true diff --git a/dev/breeze/setup.cfg b/dev/breeze/setup.cfg new file mode 100644 index 000000000000..c36d65002381 --- /dev/null +++ b/dev/breeze/setup.cfg @@ -0,0 +1,84 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + +[metadata] +version = 0.0.1 +name = apache-airflow-breeze +summary = Apache Airflow Breeze development environment +author = Apache Software Foundation +author_email = dev@airflow.apache.org +url = https://airflow.apache.org/ +long_description = file: README.md +long_description_content_type = text/markdown +license = Apache License 2.0 +license_files = + LICENSE + NOTICE +classifiers = + Development Status :: 5 - Production/Stable + Environment :: Console + Intended Audience :: Developers + License :: OSI Approved :: Apache Software License + Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 + Programming Language :: Python :: 3.10 +project_urls = + Documentation=https://github.com/apache/airflow/BREEZE.rst + Bug Tracker=https://github.com/apache/airflow/issues + Source Code=https://github.com/apache/airflow + Slack Chat=https://s.apache.org/airflow-slack + Twitter=https://twitter.com/ApacheAirflow + YouTube=https://www.youtube.com/channel/UCSXwxpWZQ7XZ1WL3wqevChA/ + +[options] +zip_safe = False +include_package_data = True +python_requires = ~=3.7 +package_dir= + =src +packages = find: +install_requires = + click + pytest + pytest-xdist + rich + +[options.packages.find] +where=src + +[options.entry_points] +console_scripts= + Breeze2=airflow_breeze.breeze:main + +[bdist_wheel] +python-tag=py3 + +[mypy] +ignore_missing_imports = True +no_implicit_optional = True +warn_redundant_casts = True +warn_unused_ignores = False +pretty = True + +[isort] +line_length=110 +combine_as_imports = true +default_section = THIRDPARTY +known_first_party=airflow,airflow_breeze,tests +skip=build,.tox,venv +profile = black diff --git a/dev/breeze/setup.py b/dev/breeze/setup.py new file mode 100644 index 000000000000..133d77a1ce08 --- /dev/null +++ b/dev/breeze/setup.py @@ -0,0 +1,27 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + +from setuptools import setup + + +def do_setup(): + """Perform the package setup.""" + setup() + + +if __name__ == "__main__": + do_setup() diff --git a/dev/breeze/src/airflow_breeze/__init__.py b/dev/breeze/src/airflow_breeze/__init__.py new file mode 100644 index 000000000000..13a83393a912 --- /dev/null +++ b/dev/breeze/src/airflow_breeze/__init__.py @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. diff --git a/dev/breeze/src/airflow_breeze/breeze.py b/dev/breeze/src/airflow_breeze/breeze.py new file mode 100755 index 000000000000..9969de7ead35 --- /dev/null +++ b/dev/breeze/src/airflow_breeze/breeze.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + +import click +from click import ClickException +from rich.console import Console + +from airflow_breeze.visuals import ASCIIART, ASCIIART_STYLE + +NAME = "Breeze2" +VERSION = "0.0.1" + + +@click.group() +def main(): + pass + + +console = Console(force_terminal=True, color_system="standard", width=180) + + +option_verbose = click.option( + "--verbose", + is_flag=True, + help="Print verbose information about performed steps", +) + + +@main.command() +def version(): + """Prints version of breeze.py.""" + console.print(ASCIIART, style=ASCIIART_STYLE) + console.print(f"\n[green]{NAME} version: {VERSION}[/]\n") + + +@option_verbose +@main.command() +def shell(verbose: bool): + """Enters breeze.py environment. this is the default command use when no other is selected.""" + if verbose: + console.print("\n[green]Welcome to breeze.py[/]\n") + console.print(ASCIIART, style=ASCIIART_STYLE) + raise ClickException("\nPlease implement entering breeze.py\n") + + +@option_verbose +@main.command() +def build_ci_image(verbose: bool): + """Builds breeze.ci image for breeze.py.""" + if verbose: + console.print("\n[blue]Building image[/]\n") + raise ClickException("\nPlease implement building the CI image\n") + + +if __name__ == '__main__': + main() diff --git a/dev/breeze/src/airflow_breeze/ci/__init__.py b/dev/breeze/src/airflow_breeze/ci/__init__.py new file mode 100644 index 000000000000..13a83393a912 --- /dev/null +++ b/dev/breeze/src/airflow_breeze/ci/__init__.py @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. diff --git a/dev/breeze/src/airflow_breeze/visuals/__init__.py b/dev/breeze/src/airflow_breeze/visuals/__init__.py new file mode 100644 index 000000000000..2df79115700d --- /dev/null +++ b/dev/breeze/src/airflow_breeze/visuals/__init__.py @@ -0,0 +1,62 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + +ASCIIART = """ + + + + + @&&&&&&@ + @&&&&&&&&&&&@ + &&&&&&&&&&&&&&&& + &&&&&&&&&& + &&&&&&& + &&&&&&& + @@@@@@@@@@@@@@@@ &&&&&& + @&&&&&&&&&&&&&&&&&&&&&&&&&& + &&&&&&&&&&&&&&&&&&&&&&&&&&&& + &&&&&&&&&&&& + &&&&&&&&& + &&&&&&&&&&&& + @@&&&&&&&&&&&&&&&@ + @&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&&&& + &&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&&&& + &&&&&&&&&&&&&&&&&&&&&&&& &&&&&& + &&&&&& + &&&&&&& + @&&&&&&&& + @&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& + &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& + &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& + + + + @&&&@ && @&&&&&&&&&&& &&&&&&&&&&&& && &&&&&&&&&& &&& &&& &&& + &&& &&& && @&& &&& && && &&& &&&@ &&& &&&&& &&& + &&& &&& && @&&&&&&&&&&&& &&&&&&&&&&& && && &&& &&& &&& &&@ &&& + &&&&&&&&&&& && @&&&&&&&&& && && &&@ &&& &&@&& &&@&& + &&& &&& && @&& &&&@ && &&&&&&&&&&& &&&&&&&&&&&& &&&& &&&& + +&&&&&&&&&&&& &&&&&&&&&&&& &&&&&&&&&&&@ &&&&&&&&&&&& &&&&&&&&&&& &&&&&&&&&&& +&&& &&& && &&& && &&& &&&& && +&&&&&&&&&&&&@ &&&&&&&&&&&& &&&&&&&&&&& &&&&&&&&&&& &&&& &&&&&&&&&& +&&& && && &&&& && &&& &&&& && +&&&&&&&&&&&&& && &&&&@ &&&&&&&&&&&@ &&&&&&&&&&&& @&&&&&&&&&&& &&&&&&&&&&& + +""" + +ASCIIART_STYLE = "blue" diff --git a/dev/breeze/tests/test_commands.py b/dev/breeze/tests/test_commands.py new file mode 100644 index 000000000000..034923b1afe6 --- /dev/null +++ b/dev/breeze/tests/test_commands.py @@ -0,0 +1,22 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + +from airflow_breeze.visuals import ASCIIART + + +def test_visuals(): + assert 2051 == len(ASCIIART) diff --git a/pyproject.toml b/pyproject.toml index 3d582c33e77c..723a5cb66b02 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,5 +16,5 @@ # under the License. [tool.black] line-length = 110 -target-version = ['py36', 'py37', 'py38'] +target-version = ['py36', 'py37', 'py38', 'py39'] skip-string-normalization = true diff --git a/setup.cfg b/setup.cfg index 5f503d4586d0..0e7ed68ba726 100644 --- a/setup.cfg +++ b/setup.cfg @@ -206,7 +206,7 @@ ignore_errors = True line_length=110 combine_as_imports = true default_section = THIRDPARTY -known_first_party=airflow,tests +known_first_party=airflow,airflow_breeze,tests # Need to be consistent with the exclude config defined in pre-commit-config.yaml skip=build,.tox,venv profile = black