diff --git a/WORKSPACE b/WORKSPACE index 14014796d34c..02304ff5cc20 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -14,6 +14,13 @@ http_archive( url = "https://github.com/bazelbuild/rules_foreign_cc/archive/master.zip", ) +# Add Bazel's python rules. +http_archive( + name = "rules_python", + url = "https://github.com/bazelbuild/rules_python/releases/download/0.1.0/rules_python-0.1.0.tar.gz", + sha256 = "b6d46438523a3ec0f3cead544190ee13223a52f6a6765a29eae7b7cc24cc83a0", +) + # Set up necessary dependencies for working with the foreign C++ rules. load("@rules_foreign_cc//:workspace_definitions.bzl", "rules_foreign_cc_dependencies") diff --git a/github_tools/BUILD b/github_tools/BUILD new file mode 100644 index 000000000000..e50fca9950f7 --- /dev/null +++ b/github_tools/BUILD @@ -0,0 +1,43 @@ +# Part of the Carbon Language project, under the Apache License v2.0 with LLVM +# Exceptions. See /LICENSE for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +load("@rules_python//python:defs.bzl", "py_binary", "py_library", "py_test") + +py_library( + name = "github_helpers", + srcs = ["github_helpers.py"], +) + +py_test( + name = "github_helpers_test", + srcs = ["github_helpers_test.py"], + deps = [":github_helpers"], +) + +py_binary( + name = "pr_comments", + srcs = ["pr_comments.py"], + deps = ["github_helpers"], +) + +py_test( + name = "pr_comments_test", + srcs = ["pr_comments_test.py"], + deps = [":pr_comments"], +) + +py_binary( + name = "update_label_access", + srcs = ["update_label_access.py"], + deps = ["github_helpers"], +) + +py_test( + name = "update_label_access_test", + srcs = ["update_label_access_test.py"], + deps = [ + ":pr_comments", + ":update_label_access", + ], +) diff --git a/github_tools/README.md b/github_tools/README.md index 063f5e835320..54cff8b827cf 100644 --- a/github_tools/README.md +++ b/github_tools/README.md @@ -9,9 +9,3 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception Scripts for use with GitHub. See individual scripts for more details. - -Please use `pytest` for testing: - -``` -$ pip install pytest -``` diff --git a/github_tools/github_helpers_test.py b/github_tools/github_helpers_test.py index 8a3c5dda4e03..1d36637ce053 100644 --- a/github_tools/github_helpers_test.py +++ b/github_tools/github_helpers_test.py @@ -9,7 +9,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception import unittest from unittest import mock -from github_tools import github_helpers +from carbon.github_tools import github_helpers _TEST_QUERY = """ diff --git a/github_tools/pr_comments.py b/github_tools/pr_comments.py index 0d136fbba96f..b6417a7b29ed 100755 --- a/github_tools/pr_comments.py +++ b/github_tools/pr_comments.py @@ -12,15 +12,21 @@ import argparse import datetime import hashlib import os -import sys +import importlib.util import textwrap -# To support direct runs, ensure the pythonpath has the repo root. -_PYTHONPATH = os.path.realpath(os.path.join(os.path.dirname(__file__), "..")) -if _PYTHONPATH not in sys.path: - sys.path.insert(0, _PYTHONPATH) -from github_tools import github_helpers +# Do some extra work to support direct runs. +try: + from carbon.github_tools import github_helpers +except ImportError: + github_helpers_spec = importlib.util.spec_from_file_location( + "github_helpers", + os.path.join(os.path.dirname(__file__), "github_helpers.py"), + ) + github_helpers = importlib.util.module_from_spec(github_helpers_spec) + github_helpers_spec.loader.exec_module(github_helpers) + # The main query, into which other queries are composed. _QUERY = """ diff --git a/github_tools/pr_comments_test.py b/github_tools/pr_comments_test.py index 6c90ffa9b09b..8949e6582c82 100644 --- a/github_tools/pr_comments_test.py +++ b/github_tools/pr_comments_test.py @@ -10,10 +10,15 @@ import os import unittest from unittest import mock -from github_tools import pr_comments +from carbon.github_tools import github_helpers +from carbon.github_tools import pr_comments class TestPRComments(unittest.TestCase): + def setUp(self): + # Stub out the access token. + os.environ[github_helpers._ENV_TOKEN] = "unused" + def test_format_comment_short(self): created_at = "2001-02-03T04:05:06Z" self.assertEqual( diff --git a/github_tools/update_label_access.py b/github_tools/update_label_access.py old mode 100755 new mode 100644 index 000a54f1738b..16c9505acf41 --- a/github_tools/update_label_access.py +++ b/github_tools/update_label_access.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - """Updates the contributors-with-label-access team. This team exists because we need a team to manage triage access to repos; @@ -14,25 +12,18 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception """ import argparse -import os -import sys # https://github.com/PyGithub/PyGithub # GraphQL is preferred, but falling back to pygithub for unsupported mutations. import github -# To support direct runs, ensure the pythonpath has the repo root. -_PYTHONPATH = os.path.realpath(os.path.join(os.path.dirname(__file__), "..")) -if _PYTHONPATH not in sys.path: - sys.path.insert(0, _PYTHONPATH) - -from github_tools import github_helpers +from carbon.github_tools import github_helpers # The organization to mirror members from. _ORG = "carbon-language" # The team to mirror to. -_TEAM = "contributors-with-label-access" +_TEAM = "contributors" # Accounts in the org to skip mirroring. _IGNORE_ACCOUNTS = ("CarbonLangInfra", "google-admin", "googlebot") diff --git a/github_tools/update_label_access_test.py b/github_tools/update_label_access_test.py index 713c90a0f6ca..01a1dff9d667 100644 --- a/github_tools/update_label_access_test.py +++ b/github_tools/update_label_access_test.py @@ -6,16 +6,21 @@ Exceptions. See /LICENSE for license information. SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception """ -import github +import os import unittest from unittest import mock -from github_tools import github_helpers -from github_tools import update_label_access +import github + +from carbon.github_tools import github_helpers +from carbon.github_tools import update_label_access class TestUpdateLabelAccess(unittest.TestCase): def setUp(self): + # Stub out the access token. + os.environ[github_helpers._ENV_TOKEN] = "unused" + self.client = mock.create_autospec(github_helpers.Client, instance=True) self.gh = mock.create_autospec(github.Github, instance=True) self.gh_org = mock.create_autospec(github.Organization, instance=True) diff --git a/proposals/BUILD b/proposals/BUILD new file mode 100644 index 000000000000..0e3f9f9c8dcc --- /dev/null +++ b/proposals/BUILD @@ -0,0 +1,5 @@ +# Part of the Carbon Language project, under the Apache License v2.0 with LLVM +# Exceptions. See /LICENSE for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +exports_files(["template.md"]) diff --git a/proposals/scripts/BUILD b/proposals/scripts/BUILD new file mode 100644 index 000000000000..5618d5d1dc0f --- /dev/null +++ b/proposals/scripts/BUILD @@ -0,0 +1,35 @@ +# Part of the Carbon Language project, under the Apache License v2.0 with LLVM +# Exceptions. See /LICENSE for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +load("@rules_python//python:defs.bzl", "py_binary", "py_library", "py_test") + +py_library( + name = "proposals", + srcs = ["proposals.py"], +) + +py_test( + name = "proposals_test", + srcs = ["proposals_test.py"], + deps = [":proposals"], +) + +py_binary( + name = "new_proposal", + srcs = ["new_proposal.py"], +) + +py_test( + name = "new_proposal_test", + srcs = ["new_proposal_test.py"], + data = ["//proposals:template.md"], + deps = [":new_proposal"], +) + +# This is a directly runnable script, but should not be run via bazel. +py_library( + name = "update_proposal_list", + srcs = ["update_proposal_list.py"], + deps = [":proposals"], +) diff --git a/proposals/scripts/README.md b/proposals/scripts/README.md index 27f035b96c8b..074459f0d048 100644 --- a/proposals/scripts/README.md +++ b/proposals/scripts/README.md @@ -9,9 +9,3 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception Scripts for use with proposals. See individual scripts for more details. - -Please use `pytest` for testing: - -``` -$ pip install pytest -``` diff --git a/proposals/scripts/new_proposal_test.py b/proposals/scripts/new_proposal_test.py index 0b823541d790..ec4d4e7d052a 100644 --- a/proposals/scripts/new_proposal_test.py +++ b/proposals/scripts/new_proposal_test.py @@ -12,7 +12,7 @@ import os import unittest from unittest import mock -from proposals.scripts import new_proposal +from carbon.proposals.scripts import new_proposal class FakeExitError(Exception): @@ -61,7 +61,8 @@ class TestNewProposal(unittest.TestCase): def test_run_failure(self): with mock.patch( - "proposals.scripts.new_proposal._exit", side_effect=_fake_exit + "carbon.proposals.scripts.new_proposal._exit", + side_effect=_fake_exit, ): self.assertRaises(FakeExitError, new_proposal._run, ["false"]) diff --git a/proposals/scripts/proposals_test.py b/proposals/scripts/proposals_test.py index 0b4e575d3255..853289f0e770 100644 --- a/proposals/scripts/proposals_test.py +++ b/proposals/scripts/proposals_test.py @@ -8,7 +8,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception import unittest -from proposals.scripts import proposals +from carbon.proposals.scripts import proposals class TestProposal(unittest.TestCase): diff --git a/proposals/scripts/update_proposal_list.py b/proposals/scripts/update_proposal_list.py index 54b990614694..3bfed2f4fbce 100755 --- a/proposals/scripts/update_proposal_list.py +++ b/proposals/scripts/update_proposal_list.py @@ -10,15 +10,19 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception import io import os +import importlib.util import re import sys -# To support direct runs, ensure the pythonpath has the repo root. -_PYTHONPATH = os.path.realpath(os.path.join(os.path.dirname(__file__), "../..")) -if _PYTHONPATH not in sys.path: - sys.path.insert(0, _PYTHONPATH) - -from proposals.scripts import proposals +# Do some extra work to support direct runs. +try: + from carbon.proposals.scripts import proposals +except ImportError: + proposals_spec = importlib.util.spec_from_file_location( + "proposals", os.path.join(os.path.dirname(__file__), "proposals.py") + ) + proposals = importlib.util.module_from_spec(proposals_spec) + proposals_spec.loader.exec_module(proposals) if __name__ == "__main__": proposals_path = proposals.get_path()