diff --git a/.gitignore b/.gitignore index 69e9bcf..f633df6 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ __pycache__ /.eggs /dist -/.python-version \ No newline at end of file +/.python-version +/.venv diff --git a/README.md b/README.md new file mode 100644 index 0000000..0e8c603 --- /dev/null +++ b/README.md @@ -0,0 +1,138 @@ +# git-remote-codecommit + +This package provides a simple method for pushing and pulling from [AWS CodeCommit](https://aws.amazon.com/codecommit/). This package extends [git](https://git-scm.com/) to support repository URLs prefixed with **codecommit://**. For example, if using IAM... + +```sh +% cat ~/.aws/config +[profile demo-profile] +region = us-east-2 +output = json + +% cat ~/.aws/credentials +[demo-profile] +aws_access_key_id = AKIAIOSFODNN7EXAMPLE +aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY + +... you can clone repositories as simply as... + +% git clone codecommit://demo-profile@MyRepositoryName +``` + +The *git-remote-codecommit* package works on Python versions: + +* 3.10.x +* 3.11.x +* 3.12.x +* 3.13.x +* 3.14.x + +## Prerequisites + +Before you can use *git-remote-codecommit*, you must: + +* Complete initial configuration for AWS CodeCommit, including: + + * Creating an AWS account + * Configuring an IAM user or role + * [Attaching a policy to that user/role that allows access to AWS CodeCommit repositories](https://docs.aws.amazon.com/codecommit/latest/userguide/auth-and-access-control-iam-identity-based-access-control.html#managed-policies) + +* Create an AWS CodeCommit repository (or have one already) in your AWS account. +* Install Python and its package manager, pip, if they are not already installed. To download and install the latest version of Python, visit the [Python website](https://www.python.org/). +* Install Git on your Linux, macOS, Windows, or Unix computer. +* Install the latest version of the AWS CLI on your Linux, macOS, Windows, or Unix computer. You can find instructions [here](https://docs.aws.amazon.com/cli/latest/userguide/installing.html). + +Note: Installation of the AWS CLI on some operating systems requires pip version 9.0.3 or later. To check your version of pip, open a terminal and type the following command: + +```sh +% pip --version +``` + +If the version is not 9.0.3 or later, run the following commands to update your version of pip: + +```sh +% curl -O https://bootstrap.pypa.io/get-pip.py +% python3 get-pip.py --user +``` + +## Set Up + +These instructions show how to set up *git-remote-codecommit* with an IAM user. If you plan to use a role with AWS Single Sign-On (SSO), see the AWS CLI SSO documentation to help configure your named credential profiles. Once your profile is set up correctly, usage of the remote helper will be the same as if you were using an IAM user (skip to step 3). + +### Step 1: Look Up Your AWS Account ID and IAM User Access Key + +* Look up and write down the account ID for your AWS account. You will need this information for step 2. If you don't know how to find your AWS Account ID, learn how [here](https://docs.aws.amazon.com/IAM/latest/UserGuide/console_account-alias.html). + +* Look up and write down the access key for your IAM user, if you do not already have that information stored locally. Learn more [here](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html). + +### Step 2: Configure an AWS credential profile on your local computer + +On your local computer, run the `aws configure --profile` command to create an AWS CLI profile to use with *git-remote-codecommit*. When prompted, provide your AWS access key, your secret access key, the AWS Region where you created your AWS CodeCommit repository, and the default output format you prefer. For example: + +```sh +% aws configure --profile demo-profile +AWS Access Key ID [None]: *************** +AWS Secret Access Key [None]: *************** +Default region name [None]: us-east-2 +Default output format [None]: json + +# Set up your AWS_PROFILE environment variable +export AWS_PROFILE=demo-profile +``` + +### Step 3: Install git-remote-codecommit + +* On your Linux, macOS, Windows, or Unix computer, install *git-remote-codecommit* using the [pip](https://pip.pypa.io/en/latest/) command. For example: + +```sh +% pip install git-remote-codecommit +``` + +* If you already have *git-remote-codecommit* installed you can upgrade to the latest version with the `--upgrade` parameter: + +```sh +% pip install --upgrade git-remote-codecommit +``` + +### Step 4: Clone your repository + +At the terminal, run the **git clone codecommit** command, using the name of your profile and the name of your repository. For example: + +```sh +% git clone codecommit://demo-profile@MyRepositoryName +Cloning into 'MyRepositoryName'... +remote: Counting objects: 1753, done. +Receiving objects: 100% (1753/1753), 351.77 KiB | 1.91 MiB/s, done. +Resolving deltas: 100% (986/986), done. +``` + +## Usage + +*git-remote-codecommit* supports several different URL formats and variants with optional parameters. + +RepositoryName is a required parameter. If you only supply this parameter, then *git-remote-codecommit* will attempt to use your default profile in the AWS Region configured in that profile. For example, to clone a repository named MyRepositoryName using the default profile: + +```sh +% git clone codecommit://MyRepositoryName +``` + +To specify a specific profile to use, use the profile name. For example, to clone a repository named *MyRepositoryName* using a profile named *demo-profile*: + +```sh +% git clone codecommit://demo-profile@MyRepositoryName +``` + +To specify an AWS Region different than the one in your profile, use the region parameter. For example, to clone a repository named *MyRepositoryName* in the *us-east-1* region using a profile named *demo-profile*: + +```sh +% git clone codecommit::us-east-1://demo-profile@MyRepositoryName +``` + +## Getting Help + +We use GitHub issues for tracking bugs and feature requests and have limited bandwidth to address them. We recommend using the following community resources for getting help: + +* View the official setup steps for [HTTPS Connections to AWS CodeCommit with git-remote-codecommit](https://docs.aws.amazon.com/codecommit/latest/userguide/setting-up-git-remote-codecommit.html). +* Check our existing troubleshooting [documentation](https://docs.aws.amazon.com/codecommit/latest/userguide/troubleshooting-grc.html) to see if your issue has been addressed there. +* Open a support ticket with [AWS Support](https://console.aws.amazon.com/support/home#/). +* Check for an existing thread or start a new one on the [AWS CodeCommit forum](https://forums.aws.amazon.com/forum.jspa?forumID=189). +* If you believe that you have found a bug, please [open an issue](https://github.com/aws/git-remote-codecommit/issues). diff --git a/README.rst b/README.rst deleted file mode 100644 index 9dd110b..0000000 --- a/README.rst +++ /dev/null @@ -1,146 +0,0 @@ -git-remote-codecommit -===================== - -This package provides a simple method for pushing and pulling from `AWS -CodeCommit `__. This package extends `git -`__ to support repository URLs prefixed with -**codecommit://**. For example, if using IAM... - -:: - - % cat ~/.aws/config - [profile demo-profile] - region = us-east-2 - output = json - - % cat ~/.aws/credentials - [demo-profile] - aws_access_key_id = AKIAIOSFODNN7EXAMPLE - aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY - -... you can clone repositories as simply as... - -:: - - % git clone codecommit://demo-profile@MyRepositoryName - -The *git-remote-codecommit* package works on Python versions: - -* 3.8.x -* 3.9.x -* 3.10.x -* 3.11.x - -Prerequisites -============= - -Before you can use *git-remote-codecommit*, you must: - -* Complete initial configuration for AWS CodeCommit, including: - - * Creating an AWS account - * Configuring an IAM user or role - * `Attaching a policy to that user/role that allows access to AWS CodeCommit repositories `__ - -* Create an AWS CodeCommit repository (or have one already) in your AWS account. -* Install Python and its package manager, pip, if they are not already installed. To download and install the latest version of Python, `visit the Python website `__. -* Install Git on your Linux, macOS, Windows, or Unix computer. -* Install the latest version of the AWS CLI on your Linux, macOS, Windows, or Unix computer. You can find instructions `here `__. - -Note: Installation of the AWS CLI on some operating systems requires pip version 9.0.3 or later. To check your version of pip, open a terminal and type the following command: - -:: - - % pip --version - -If the version is not 9.0.3 or later, run the following commands to update your version of pip: - -:: - - % curl -O https://bootstrap.pypa.io/get-pip.py - % python3 get-pip.py --user - -Set Up -=============== - -These instructions show how to set up *git-remote-codecommit* with an IAM user. If you plan to use a role with AWS Single Sign-On (SSO), see `this documentation `__ to help configure your named credential profiles. Once your profile is set up correctly, usage of the remote helper will be the same as if you were using an IAM user (skip to step 3). - -Step 1: Look Up Your AWS Account ID and IAM User Access Key ------------------------------------------------------------ - -* Look up and write down the account ID for your AWS account. You will need this information for step 2. If you don't know how to find your AWS Account ID, learn how `here `__. - -* Look up and write down the access key for your IAM user, if you do not already have that information stored locally. Learn more `here `__. - -Step 2: `Configure an AWS credential profile `__ on your local computer --------------------------------------------------------------------------------------------------------------------------------------------------- - -* On your local computer, run the **aws configure --profile** command to create an AWS CLI profile to use with *git-remote-codecommit*. When prompted, provide your AWS access key, your secret access key, the AWS Region where you created your AWS CodeCommit repository, and the default output format you prefer. For example: - -:: - - % aws configure --profile demo-profile - AWS Access Key ID [None]: *************** - AWS Secret Access Key [None]: *************** - Default region name [None]: us-east-2 - Default output format [None]: json - -Step 3: Install git-remote-codecommit -------------------------------------- - -* On your Linux, macOS, Windows, or Unix computer, install *git-remote-codecommit* using the `pip `__ command. For example: - -:: - - % pip install git-remote-codecommit - -* If you already have *git-remote-codecommit* installed you can upgrade to the latest version with the **--upgrade** parameter: - -:: - - % pip install --upgrade git-remote-codecommit - -Step 4: Clone your repository ------------------------------ - -* At the terminal, run the **git clone codecommit** command, using the name of your profile and the name of your repository. For example: - -:: - - % git clone codecommit://demo-profile@MyRepositoryName - Cloning into 'MyRepositoryName'... - remote: Counting objects: 1753, done. - Receiving objects: 100% (1753/1753), 351.77 KiB | 1.91 MiB/s, done. - Resolving deltas: 100% (986/986), done. - -Usage -===== -*git-remote-codecommit* supports several different URL formats and variants with optional parameters. - -RepositoryName is a required parameter. If you only supply this parameter, then *git-remote-codecommit* will attempt to use your default profile in the AWS Region configured in that profile. For example, to clone a repository named MyRepositoryName using the default profile: - -:: - - % git clone codecommit://MyRepositoryName - -To specify a specific profile to use, use the profile name. For example, to clone a repository named *MyRepositoryName* using a profile named *demo-profile*: - -:: - - % git clone codecommit://demo-profile@MyRepositoryName - -To specify an AWS Region different than the one in your profile, use the region parameter. For example, to clone a repository named *MyRepositoryName* in the *us-east-1* region using a profile named *demo-profile*: - -:: - - % git clone codecommit::us-east-1://demo-profile@MyRepositoryName - -Getting Help -============ -We use GitHub issues for tracking bugs and feature requests and have limited bandwidth to address them. We recommend using the following community resources for getting help: - -* View the official setup steps for `HTTPS Connections to AWS CodeCommit with git-remote-codecommit `__. -* Check our existing troubleshooting `documentation `__ to see if your issue has been addressed there. -* Open a support ticket with `AWS Support `__. -* Check for an existing thread or start a new one on the `AWS CodeCommit forum `__. -* If you believe that you have found a bug, please `open an issue `__. \ No newline at end of file diff --git a/git_remote_codecommit/__init__.py b/git_remote_codecommit/__init__.py index 1f800b8..a8b58b0 100644 --- a/git_remote_codecommit/__init__.py +++ b/git_remote_codecommit/__init__.py @@ -11,223 +11,286 @@ # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. -import collections +import argparse import datetime import os +import re import subprocess import sys -import re - -from botocore.credentials import JSONFileCache +from dataclasses import dataclass +from typing import Set +from urllib.parse import urlparse, quote import botocore.auth import botocore.awsrequest -import botocore.compat import botocore.hooks import botocore.session +from botocore.credentials import JSONFileCache + -try: - from urlparse import urlparse # python 2.x -except ImportError: - from urllib.parse import urlparse # python 3.x +# ========================= +# Constants +# ========================= + +CODECOMMIT_SERVICE = "codecommit" +PROTOCOL_VERSION = "v1" +REGION_PATTERN = re.compile(r"^[a-z]{2}-[a-z0-9-]+-\d+$") +__version__ = "2.0.0" + + +# ========================= +# Exceptions +# ========================= class FormatError(Exception): - pass + pass class ProfileNotFound(Exception): - pass + pass class RegionNotFound(Exception): - pass + pass class RegionNotAvailable(Exception): - pass + pass class CredentialsNotFound(Exception): - pass + pass + + +# ========================= +# Context +# ========================= + + +@dataclass(frozen=True) +class Context: + session: botocore.session.Session + repository: str + version: str + region: str + credentials: botocore.credentials.Credentials + + @staticmethod + def from_url(remote_url: str) -> "Context": + url = urlparse(remote_url) + + if not url.scheme or not url.netloc: + raise FormatError( + f"Malformed URL: {remote_url}. " + "Expected: codecommit://@ " + "or codecommit::://@" + ) + + profile = os.getenv("AWS_PROFILE", "default") + repository = url.netloc + + event_handler = botocore.hooks.HierarchicalEmitter() + + if "@" in url.netloc: + profile, repository = url.netloc.split("@", 1) + session = botocore.session.Session( + profile=profile, + event_hooks=event_handler, + ) + + if profile not in session.available_profiles: + raise ProfileNotFound( + f"Profile '{profile}' not found. " + f"Available profiles: {', '.join(session.available_profiles)}" + ) + else: + session = botocore.session.Session(event_hooks=event_handler) + + # Enable assume-role cache + session.get_component("credential_provider").get_provider( + "assume-role" + ).cache = JSONFileCache() + + available_regions: Set[str] = { + region + for partition in session.get_available_partitions() + for region in session.get_available_regions( + CODECOMMIT_SERVICE, + partition, + ) + } + + # Resolve region + if url.scheme == CODECOMMIT_SERVICE: + region = session.get_config_variable("region") + if not region: + raise RegionNotFound( + f"Profile '{profile}' does not have a region configured" + ) + + elif REGION_PATTERN.match(url.scheme): + region = url.scheme + else: + raise FormatError(f"Invalid scheme in URL: {remote_url}") + + if region not in available_regions: + raise RegionNotAvailable( + f"Region '{region}' is not available for AWS CodeCommit" + ) + + credentials = session.get_credentials() + if not credentials: + raise CredentialsNotFound( + f"No credentials configured for profile '{profile}'" + ) + + return Context( + session=session, + repository=repository, + version=PROTOCOL_VERSION, + region=region, + credentials=credentials, + ) + + +# ========================= +# Git URL & Signing +# ========================= + + +def website_domain_mapping(region: str) -> str: + return "amazonaws.com.cn" if region.startswith("cn-") else "amazonaws.com" + + +def git_url( + repository: str, + version: str, + region: str, + credentials, +) -> str: + hostname = os.getenv( + "CODE_COMMIT_ENDPOINT", + f"git-codecommit.{region}.{website_domain_mapping(region)}", + ) + + path = f"/{version}/repos/{repository}" + + token = f"%{credentials.token}" if credentials.token else "" + username = quote(credentials.access_key + token, safe="") + + signature = sign(hostname, path, region, credentials) + + return f"https://{username}:{signature}@{hostname}{path}" + + +def sign( + hostname: str, + path: str, + region: str, + credentials, +) -> str: + request = botocore.awsrequest.AWSRequest( + method="GIT", + url=f"https://{hostname}{path}", + ) + + timestamp = datetime.datetime.now(datetime.timezone.utc).strftime("%Y%m%dT%H%M%S") + + request.context["timestamp"] = timestamp + signer = botocore.auth.SigV4Auth( + credentials, + CODECOMMIT_SERVICE, + region, + ) -class Context(collections.namedtuple('Context', ['session', 'repository', 'version', 'region', 'credentials'])): - """ - Repository information the hook concerns, derived from git's remote url and - the user's AWS profile. + canonical_request = f"GIT\n{path}\n\n" f"host:{hostname}\n\n" "host\n" - :var botocore.session.Session session: aws session context - :var str repository: repository name - :var str version: protocol version for this hook - :var str region: region the repository resides within - :var botocore.credentials credentials: session credentials - """ + string_to_sign = signer.string_to_sign( + request, + canonical_request, + ) - @staticmethod - def from_url(remote_url): - """ - Parses repository information from a git url, filling in additional - attributes we need from our AWS profile. + signature = signer.signature(string_to_sign, request) - Our remote helper accepts two distinct types of urls... + return f"{timestamp}Z{signature}" - * codecommit://@ - * codecommit::://@ - If provided the former we get the whole url, but if the later git will - truncate the proceeding 'codecommit::' prefix for us. +# ========================= +# CLI +# ========================= - The '@' url is optional, using the aws sessions present profile - if not provided. - :param str remote_url: git remote url to parse +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser( + prog="git-remote-codecommit", + description="Git remote helper for AWS CodeCommit", + add_help=False + ) - :returns: **Context** with our CodeCommit repository information + parser.add_argument( + "--version", + action="version", + version=f"%(prog)s {__version__}", + ) - :raises: - * **FormatError** if the url is malformed - * **ProfileNotFound** if the url references a profile that doesn't exist - * **RegionNotFound** if the url references a region that doesn't exist - * **RegionNotAvailable** if the url references a region that is not available - """ + parser.add_argument( + "git_command", + help="Git command (e.g. pull,fetch, push)", + ) - url = urlparse(remote_url) - event_handler = botocore.hooks.HierarchicalEmitter() - profile = 'default' - repository = url.netloc - if not url.scheme or not url.netloc: - raise FormatError('The following URL is malformed: {}. A URL must be in one of the two following formats: codecommit://@ or codecommit::://@'.format(remote_url)) + parser.add_argument( + "remote_url", + help="CodeCommit remote URL", + ) - if '@' in url.netloc: - profile, repository = url.netloc.split('@', 1) - session = botocore.session.Session(profile = profile, event_hooks = event_handler) + return parser.parse_args() - if profile not in session.available_profiles: - raise ProfileNotFound('The following profile was not found: {}. Available profiles are: {}. Either use one of the available profiles, or create an AWS CLI profile to use and then try again. For more information, see Configure an AWS CLI Profile in the AWS CLI User Guide.'.format(profile, ', '.join(session.available_profiles))) - else: - session = botocore.session.Session(event_hooks = event_handler) - - session.get_component('credential_provider').get_provider('assume-role').cache = JSONFileCache() +def main() -> None: try: - # when the aws cli is available support plugin authentication - - import awscli.plugin - - awscli.plugin.load_plugins( - session.full_config.get('plugins', {}), - event_hooks = event_handler, - include_builtins = False, - ) - - session.emit_first_non_none_response('session-initialized', session = session) - except ImportError: - pass - - available_regions = [region for partition in session.get_available_partitions() for region in session.get_available_regions('codecommit', partition)] - - if url.scheme == 'codecommit': - region = session.get_config_variable('region') - - if not region: - raise RegionNotFound('The following profile does not have an AWS Region: {}. You must set an AWS Region for this profile. For more information, see Configure An AWS CLI Profile in the AWS CLI User Guide.'.format(profile)) - - if region not in available_regions: - raise RegionNotAvailable('The following AWS Region is not available for use with AWS CodeCommit: {}. For more information about CodeCommit\'s availability in AWS Regions, see the AWS CodeCommit User Guide. If an AWS Region is listed as supported but you receive this error, try updating your version of the AWS CLI or the AWS SDKs.'.format(region)) - - elif re.match(r"^[a-z]{2}-\w*.*-\d{1}", url.scheme): - if url.scheme in available_regions: - region = url.scheme - - else: - raise RegionNotAvailable('The following AWS Region is not available for use with AWS CodeCommit: {}. For more information about CodeCommit\'s availability in AWS Regions, see the AWS CodeCommit User Guide. If an AWS Region is listed as supported but you receive this error, try updating your version of the AWS CLI or the AWS SDKs.'.format(url.scheme)) - - else: - raise FormatError('The following URL is malformed: {}. A URL must be in one of the two following formats: codecommit://@ or codecommit::://@'.format(remote_url)) - credentials = session.get_credentials() - - if not credentials: - raise CredentialsNotFound('The following profile does not have credentials configured: {}. You must configure the access key and secret key for the profile. For more information, see Configure an AWS CLI Profile in the AWS CLI User Guide.'.format(profile)) - - return Context(session, repository, 'v1', region, credentials) - - -def error(msg): - sys.stderr.write('%s\n' % msg) - sys.exit(1) - - -def main(): - """ - Hook that can be invoked by git, providing simplified push/pull access for a - CodeCommit repository. - """ - - if len(sys.argv) < 3: - error('Too few arguments. This hook requires the git command and remote.') - - elif len(sys.argv) > 3: - error("Too many arguments. Hook only accepts the git command and remote, but argv was: '%s'" % "', '".join(sys.argv)) - - git_cmd, remote_url = sys.argv[1:3] - - try: - context = Context.from_url(remote_url) - authenticated_url = git_url(context.repository, context.version, context.region, context.credentials) - sys.exit(subprocess.call(['git', 'remote-http', git_cmd, authenticated_url])) - - except (FormatError, ProfileNotFound, RegionNotFound, CredentialsNotFound, RegionNotAvailable) as exc: - error(str(exc)) - -def website_domain_mapping(region): - if region in ['cn-north-1', 'cn-northwest-1']: - return 'amazonaws.com.cn' - return 'amazonaws.com' - -def git_url(repository, version, region, credentials): - """ - Provides the signed url we can use for pushing and pulling from CodeCommit... - - :: - - https://(username):(password)@git-codecommit.(region).(website_domain)/v1/repos/(repository) - - :param str repository: repository name - :param str version: protocol version for this hook - :param str region: region the repository resides within - :param botocore.credentials credentials: session credentials - - :return: url we can push/pull from - """ - - hostname = os.environ.get('CODE_COMMIT_ENDPOINT', 'git-codecommit.{}.{}'.format(region, website_domain_mapping(region))) - path = '/{}/repos/{}'.format(version, repository) - - token = '%' + credentials.token if credentials.token else '' - username = botocore.compat.quote(credentials.access_key + token, safe='') - signature = sign(hostname, path, region, credentials) - - return 'https://{}:{}@{}{}'.format(username, signature, hostname, path) - - -def sign(hostname, path, region, credentials): - """ - Provides a SigV4 signature for a CodeCommit url. - - :param str hostname: aws hostname request is for - :param str path: resource the request is for - :param str region: region the repository resides within - :param botocore.credentials credentials: session credentials - - :return: signature for the url - """ - - request = botocore.awsrequest.AWSRequest(method = 'GIT', url = 'https://{}{}'.format(hostname, path)) - request.context['timestamp'] = datetime.datetime.utcnow().strftime('%Y%m%dT%H%M%S') - - signer = botocore.auth.SigV4Auth(credentials, 'codecommit', region) - canonical_request = 'GIT\n{}\n\nhost:{}\n\nhost\n'.format(path, hostname) - string_to_sign = signer.string_to_sign(request, canonical_request) - signature = signer.signature(string_to_sign, request) - return "{}Z{}".format(request.context['timestamp'], signature) + args = parse_args() + + if args.git_command == "version": + print(__version__) + return + + if not args.git_command or not args.remote_url: + sys.exit( + "Usage: git-remote-codecommit " + ) + + context = Context.from_url(args.remote_url) + authenticated_url = git_url( + context.repository, + context.version, + context.region, + context.credentials, + ) + env = os.environ.copy() + env["GIT_CONFIG_COUNT"] = "1" + env["GIT_CONFIG_KEY_0"] = "credential.helper" + env["GIT_CONFIG_VALUE_0"] = "" + result = subprocess.run( + ["git", "remote-http", args.git_command, authenticated_url], + stdout=sys.stdout, + stderr=sys.stderr, + check=False, + env=env + ) + + sys.exit(result.returncode) + + except ( + FormatError, + ProfileNotFound, + RegionNotFound, + RegionNotAvailable, + CredentialsNotFound, + ) as exc: + sys.exit(str(exc)) + + +if __name__ == "__main__": + main() diff --git a/setup.cfg b/setup.cfg index 1f69afd..bc53f50 100644 --- a/setup.cfg +++ b/setup.cfg @@ -9,3 +9,5 @@ ignore = E251, # allow line break before operator as per https://lintlyci.github.io/Flake8Rules/rules/W503.html W503 +[metadata] +version = attr: git_remote_codecommit.__version__ diff --git a/setup.py b/setup.py index 55edeb4..177e0a9 100644 --- a/setup.py +++ b/setup.py @@ -3,32 +3,28 @@ import os import setuptools -__version__ = '1.17' - - def read(fname): - return open(os.path.join(os.path.dirname(__file__), fname)).read() + return open(os.path.join(os.path.dirname(__file__), fname)).read() setuptools.setup( - name = 'git-remote-codecommit', - packages = ['git_remote_codecommit'], - version = __version__, - description = 'Git remote prefix to simplify pushing to and pulling from CodeCommit.', - long_description = read('README.rst'), - author = 'Amazon Web Services', - url = 'https://github.com/awslabs/git-remote-codecommit', - license = 'Apache License 2.0', - install_requires = ['botocore >= 1.17.0'], - entry_points = { - 'console_scripts': [ - 'git-remote-codecommit = git_remote_codecommit:main', + name="git-remote-codecommit", + packages=["git_remote_codecommit"], + description="Git remote prefix to simplify pushing to and pulling from CodeCommit.", + long_description=read("README.md"), + author="Amazon Web Services", + url="https://github.com/aws/git-remote-codecommit", + license="Apache License 2.0", + install_requires=["botocore >= 1.34"], + entry_points={ + "console_scripts": [ + "git-remote-codecommit = git_remote_codecommit:main", ], }, - classifiers = [ - 'Development Status :: 5 - Production/Stable', - 'Intended Audience :: Developers', - 'Topic :: Utilities', - 'License :: OSI Approved :: Apache Software License', + classifiers=[ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Topic :: Utilities", + "License :: OSI Approved :: Apache Software License", ], )