diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 5cc5fcf..f58e131 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -5,35 +5,48 @@ on: branches: - main - dev - pull_request: - branches: - - main - - dev env: TEST_URL: ${{secrets.TEST_URL}} TEST_SLACK_URL: ${{secrets.TEST_SLACK_URL}} TEST_WEBEX_URL: ${{secrets.TEST_WEBEX_URL}} + TEST_DISCORD_URL: ${{secrets.TEST_DISCORD_URL}} jobs: test: runs-on: ${{ matrix.os }} strategy: matrix: - os: [windows-2019, windows-2022, windows-latest, ubuntu-latest] + include: + # Python 3.9 is the primary dev version + - os: windows-2022 + python-version: '3.9' + - os: windows-latest + python-version: '3.9' + - os: ubuntu-latest + python-version: '3.9' + # Python 3.6 is the minimum supported version + - os: windows-2022 + python-version: '3.6' + # github actions does not support any other runners with python 3.6 + # Python 3.14 is the latest (Oct 14th 2025) version + - os: windows-latest + python-version: '3.14' + - os: ubuntu-latest + python-version: '3.14' environment: test steps: - name: Checkout code uses: actions/checkout@v4 - - name: Set up Python + - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: - python-version: 3.9 + python-version: ${{ matrix.python-version }} - name: Install Tox run: pip install tox - name: Run tests run: tox - + diff --git a/pyproject.toml b/pyproject.toml index 8eff242..2d0c686 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "whecho" -version = "0.0.5" +version = "0.0.6" description = "Linux echo with webhooks! ⚓" readme = "README.md" authors = [ @@ -28,8 +28,8 @@ classifiers = [ [tool.poetry.dependencies] python = ">=3.6" requests = ">=2.25.1" -setuptools = ">=40.6.3" toml = ">=0.6.0" +importlib-metadata = {version = ">=1.0", python = "<3.8"} [build-system] requires = ["poetry-core>=1.0.0"] diff --git a/tests/test_auto_machine.py b/tests/test_auto_machine.py index ba18bb1..5ae32e1 100644 --- a/tests/test_auto_machine.py +++ b/tests/test_auto_machine.py @@ -4,7 +4,6 @@ import subprocess import re import socket -import platform from whecho import _config as config import toml from test_whecho_simple import simple_post diff --git a/tests/test_post_message.py b/tests/test_post_message.py new file mode 100644 index 0000000..d6392f9 --- /dev/null +++ b/tests/test_post_message.py @@ -0,0 +1,28 @@ +import os + +from whecho._send_message import post_simple + +def test_no_url_in_config(): + # test that an error is raised when no URL is passed and no URL in config + try: + post_simple("This should fail", None, conf={'default_url': None}) + except ValueError as e: + assert str(e) == 'No URL passed. Did you run whecho --init?' + else: + assert False, "Expected Error message was not delivered" + +def test_no_message(): + # test that an error is raised when no message is passed + url = os.environ.get("TEST_URL", None) + if not url: + raise ValueError(f'No test URL passed. Did you set the TEST_URL environment variable?') + try: + post_simple("", url) + except ValueError as e: + assert str(e) == 'No message passed. Try whecho --help for more info.' + else: + assert False, "Expected Error message was not delivered" + +if __name__ == "__main__": + test_no_url_in_config() + test_no_message() \ No newline at end of file diff --git a/tests/test_whecho_simple.py b/tests/test_whecho_simple.py index 10246e5..f66dbe4 100644 --- a/tests/test_whecho_simple.py +++ b/tests/test_whecho_simple.py @@ -44,9 +44,23 @@ def test_simple_slack(): def test_simple_webex(): # test webex url with python function simple_post('TEST_WEBEX_URL', False) + +def test_simple_discord(): + # test discord url with python function + simple_post('TEST_DISCORD_URL', False) +def test_empty_url(): + # test that an error is raised when no URL is passed + try: + whecho_simple("This should fail", None) + except ValueError as e: + assert str(e) == 'No URL passed. Did you run whecho --init?' + else: + assert False, "Expected Error message was not delivered" if __name__ == "__main__": simple_post() # only test discord with main function (duplicated in test_auto_machine.py) test_simple_slack() test_simple_webex() + test_simple_discord() + test_empty_url() \ No newline at end of file diff --git a/tox.ini b/tox.ini index 9f0560e..a616d3b 100644 --- a/tox.ini +++ b/tox.ini @@ -1,11 +1,16 @@ [tox] -envlist = py39 +envlist = py +isolated_build = true [testenv] +skip_missing_interpreters = true +setenv = + PYTHONIOENCODING = utf-8 passenv = TEST_URL TEST_SLACK_URL TEST_WEBEX_URL + TEST_DISCORD_URL deps = pytest toml diff --git a/whecho/README.md b/whecho/README.md index 813f681..671a24d 100644 --- a/whecho/README.md +++ b/whecho/README.md @@ -4,6 +4,8 @@ Thank you for your interest in whecho's source code. New features and contributi Raise an issue or submit a pull request if you have any new ideas! +**Do not open PRs to `main`**, GitHub Actions stores the webhook URLs in repository secrets. If it is your first time contributing please create a new branch and **create the PR to `dev`**. The core maintainers will then evaluate the contribution and run it in GitHub Actions to verify no regression in functionality. + ## building the project - clone the repo & go to the directory of the `pyproject.toml` file - clone the environment using the supplied environment.yml file @@ -20,4 +22,5 @@ Raise an issue or submit a pull request if you have any new ideas! - `TEST_URL` pointing to a discord webhook - `TEST_SLACK_URL` pointing to a slack webhook - `TEST_WEBEX_URL` pointing to a webex webhook + - `TEST_DISCORD_URL` pointing to a discord webhook (ideally using the discordapp.com endpoint instead) - tox makes use of these environment variables during the automated testing \ No newline at end of file diff --git a/whecho/_config.py b/whecho/_config.py index 52a3bde..7d4ff4b 100644 --- a/whecho/_config.py +++ b/whecho/_config.py @@ -2,7 +2,10 @@ import os import getpass -import pkg_resources +try: # python >= 3.8 + import importlib.metadata as metadata +except ImportError: # python < 3.8 + import importlib_metadata as metadata import toml import socket import platform @@ -13,7 +16,7 @@ except Exception: config_username = "user" DEFAULT_CONFIG = {'default_url': None, - 'version': pkg_resources.get_distribution('whecho').version, + 'version': metadata.version('whecho'), 'user': config_username, 'os': platform.system(), 'machine': "auto",} diff --git a/whecho/_send_message.py b/whecho/_send_message.py index b60a0f9..a04009c 100644 --- a/whecho/_send_message.py +++ b/whecho/_send_message.py @@ -9,11 +9,13 @@ def post_simple(message, url, conf=None, debug=False): conf = config.get_config() if not url: url = conf['default_url'] + if not url: + raise ValueError('No URL passed. Did you run whecho --init?') + if not message: + raise ValueError('No message passed. Try whecho --help for more info.') data = get_data(conf,message,url,debug) if debug: print(f"Data: {data}") - if not url: - raise ValueError('No URL passed. Did you run whecho --init?') try: r = requests.post(url, json=data) if debug: @@ -27,6 +29,7 @@ def post_simple(message, url, conf=None, debug=False): def get_data(conf,message,url,debug=False): """General get data function for all supported webhooks.""" url_keyword_map = {"discord.com": get_discord_data, + "discordapp.com": get_discord_data, "slack.com": get_slack_data, "webhook.office.com": get_teams_data, "webexapis.com": get_webex_data} diff --git a/whecho/_utilities.py b/whecho/_utilities.py index 20a4b3d..ebf026e 100644 --- a/whecho/_utilities.py +++ b/whecho/_utilities.py @@ -1,14 +1,15 @@ # Contains utility functions for the whecho project. -import pkg_resources -import os +try: # python >= 3.8 + import importlib.metadata as metadata +except ImportError: # python < 3.8 + import importlib_metadata as metadata from whecho import _config as config -import toml from whecho import _send_message as send_message def get_version(): """Prints the version of whecho and exits.""" - print(pkg_resources.get_distribution('whecho').version) + print(metadata.version('whecho')) exit(0) def init(): diff --git a/whecho/whecho.py b/whecho/whecho.py index 5fdcbd3..0bd56e9 100755 --- a/whecho/whecho.py +++ b/whecho/whecho.py @@ -3,10 +3,17 @@ from whecho._send_message import post_simple import requests from typing import Optional +import sys + def main(): # deal with arguments - parser = argparse.ArgumentParser(prog='whecho', description='Linux echo with webhooks! ⚓') + desc = 'Linux echo with webhooks! ⚓' + # if terminal does not support utf-8, remove the anchor emoji from the description + encoding = getattr(sys.stdout, 'encoding', 'utf-8') or 'utf-8' + if encoding.lower() != 'utf-8': + desc = 'Linux echo with webhooks!' + parser = argparse.ArgumentParser(prog='whecho', description=desc) parser.add_argument('--version', action='store_true', help='Prints the version of whecho and exits.') parser.add_argument('-m', '--msg', help='The message to echo (same as 1st positional argument).') parser.add_argument('message', metavar="MSG" ,nargs='*', help='The message to echo.')