Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
57f32bb
Initial plan
Copilot Oct 14, 2025
79e03fc
Replace pkg_resources with importlib.metadata
Copilot Oct 14, 2025
8222fd5
Add importlib-metadata backport for Python 3.6-3.7 compatibility
Copilot Oct 14, 2025
0eed3ec
Merge pull request #18 from cvraut/copilot/remove-pkg-resources-depen…
cvraut Oct 14, 2025
e20cd1e
updated testing suite to remove windows 2019 and included py36 and py…
cvraut Oct 14, 2025
5624ee5
removed tox lines at the end of the yml file
cvraut Oct 14, 2025
59ca57e
mapped python version to supported runners in gha
cvraut Oct 14, 2025
5c4c60b
switched depreciated windows-2019 to windows-2022 for python 3.6 testing
cvraut Oct 14, 2025
df521e8
actually added the correct file for the commit
cvraut Oct 14, 2025
9ea668e
added isolated build option to tox.ini file to hopefully get automate…
cvraut Oct 14, 2025
c5cf3ba
fixed the version dependent import for python 3.6 compatibility
cvraut Oct 14, 2025
e4379c3
actually fixed the metadata import
cvraut Oct 14, 2025
f10a39d
added utf-8 restriction to tox.ini
cvraut Oct 14, 2025
811e974
added option to force skip missing runners in tox
cvraut Oct 14, 2025
210d6d1
simplified tox.ini to not use explicit python defs, also commented ou…
cvraut Oct 14, 2025
f12bb10
added back full test suite
cvraut Oct 14, 2025
5dfd55b
try to switch to latest ubuntu to test python 3.6
cvraut Oct 15, 2025
db5ec7b
try to switch to ubuntu-20.04 for python 3.6 test
cvraut Oct 15, 2025
2657016
decide to consolidate python 3.6 testing to only windows runners on g…
cvraut Oct 15, 2025
af10f2b
added new discord webhook format url to test cases
cvraut Mar 3, 2026
71bba88
should fix #21
cvraut Mar 3, 2026
291af6c
added the new URL secret to the workflows.yml file so that the runner…
cvraut Mar 3, 2026
b589582
added some debug code to see what fuckery is happening with github ac…
cvraut Mar 3, 2026
221d4f9
gha debugging
cvraut Mar 3, 2026
52ba25b
added -s flag to tox.ini to make sure pytest prints all stdout and st…
cvraut Mar 3, 2026
014ae52
added the discord url to the tox.ini file as well to make sure it is …
cvraut Mar 3, 2026
43e3d02
removed the -s flag from the tox.ini file
cvraut Mar 3, 2026
a210ec1
removed the PR testing run. Seems redundant and the PR actions run us…
cvraut Mar 3, 2026
e97eb0d
Update pyproject.toml
cvraut Mar 4, 2026
271de31
Update whecho/README.md
cvraut Mar 4, 2026
9339ab9
added null checks for message and url. Also added unit tests for null…
cvraut Mar 4, 2026
d4dafd8
removed non-sensical tests from whecho_simple
cvraut Mar 5, 2026
7c3e787
added conditional for emoji in help function, causes issues in non ut…
cvraut Mar 5, 2026
737d6c3
created seperate test file to test nulls for post_message
cvraut Mar 5, 2026
4be62e3
removed unsed platform import
cvraut Mar 5, 2026
9dc3f03
Apply suggestions from code review
cvraut Mar 5, 2026
e0e623a
removed redundant test in post message
cvraut Mar 5, 2026
1387d49
switched terminal encoding logic to handle None values from sys.stdout
cvraut Mar 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 21 additions & 8 deletions .github/workflows/pytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,48 @@ on:
branches:
- main
- dev
Comment thread
cvraut marked this conversation as resolved.
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

4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -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 = [
Expand Down Expand Up @@ -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"]
Expand Down
1 change: 0 additions & 1 deletion tests/test_auto_machine.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
28 changes: 28 additions & 0 deletions tests/test_post_message.py
Original file line number Diff line number Diff line change
@@ -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"
Comment thread
cvraut marked this conversation as resolved.

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()
14 changes: 14 additions & 0 deletions tests/test_whecho_simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Comment thread
cvraut marked this conversation as resolved.

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()
7 changes: 6 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -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
Expand Down
3 changes: 3 additions & 0 deletions whecho/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
7 changes: 5 additions & 2 deletions whecho/_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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",}
Expand Down
7 changes: 5 additions & 2 deletions whecho/_send_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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}
Expand Down
9 changes: 5 additions & 4 deletions whecho/_utilities.py
Original file line number Diff line number Diff line change
@@ -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():
Expand Down
9 changes: 8 additions & 1 deletion whecho/whecho.py
Original file line number Diff line number Diff line change
Expand Up @@ -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!'
Comment thread
cvraut marked this conversation as resolved.
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.')
Expand Down