Skip to content

Commit

Permalink
Added contributing instructions.
Browse files Browse the repository at this point in the history
  • Loading branch information
afourney committed Oct 17, 2024
1 parent d6326ba commit 0a0f921
Show file tree
Hide file tree
Showing 9 changed files with 253 additions and 13 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -162,4 +162,6 @@ cython_debug/
#.idea/

# project - specific
config.yml
tests/test_data/precompiled_registrations.json
tests/test_data/registrations.db
tests/test_data/aprstastic.yaml
32 changes: 32 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# CONTRIBUTING

Code contributions are welcome and appreciated. Just submit a PR!

The current build environment uses `pre-commit`, and `hatch`.

### Environment setup:

```console
pip install hatch
git clone [email protected]:afourney/aprstastic.git
cd aprstastic
pre-commit install

# Optionally run the pre-commit scripts at any time
pre-commit run --all-files
```

### Running and testing:

From the aprstastic directory:

```console
hatch shell

# Running
python -m aprstastic


# Testing
hatch test
```
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
> [!WARNING]
> Legal operation of this software requires an amateur radio license and a valid call sign.
> [!NOTE]
> Code contributions are welcomed and appreciated. See [CONTRIBUTING.md](https://github.com/afourney/aprstastic/blob/main/CONTRIBUTING.md) for details.
## New!

:fire: 2-minute [YouTube demo](https://www.youtube.com/watch?v=qUvpZUwl-cY)
Expand Down
2 changes: 1 addition & 1 deletion src/aprstastic/__about__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2024-present Adam Fourney <[email protected]>
#
# SPDX-License-Identifier: MIT
__version__ = "0.0.1a12"
__version__ = "0.0.1a14"
16 changes: 6 additions & 10 deletions src/aprstastic/_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,29 +61,25 @@ def init_config():

# Try to get the data directory
data_dir = config.get("data_dir")
if data_dir is None:
if data_dir is None or data_dir.strip() == "":
data_dir = os.path.join(
os.path.dirname(os.path.abspath(config_path)), DATA_SUBDIR
)
elif data_dir.strip() == "":
data_dir = os.path.join(os.getcwd(), DATA_SUBDIR)
else:
data_dir = os.path.expanduser(data_dir)
elif not os.path.isabs(data_dir):
data_dir = os.path.join(os.path.dirname(os.path.abspath(config_path)), data_dir)

logger.debug(f"data directory: {data_dir}")
os.makedirs(data_dir, exist_ok=True)
config["data_dir"] = data_dir

# Try to get the logging directory
logs_dir = config.get("logs_dir")
if logs_dir is None:
if logs_dir is None or logs_dir.strip() == "":
logs_dir = os.path.join(
os.path.dirname(os.path.abspath(config_path)), LOGS_SUBDIR
)
elif logs_dir.strip() == "":
logs_dir = os.path.join(os.getcwd(), LOGS_SUBDIR)
else:
logs_dir = os.path.expanduser(logs_dir)
elif not os.path.isabs(logs_dir):
logs_dir = os.path.join(os.path.dirname(os.path.abspath(config_path)), logs_dir)

logger.debug(f"logs directory: {logs_dir}")
os.makedirs(logs_dir, exist_ok=True)
Expand Down
2 changes: 1 addition & 1 deletion src/aprstastic/_config_const.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
# Where should logs be stored?
# If null, (or commented out), store logs in the `logs` dir, sibling to this file.
#log_dir: null
#logs_dir: null
# Where should data be stored?
Expand Down
152 changes: 152 additions & 0 deletions tests/test_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# SPDX-FileCopyrightText: 2024-present Adam Fourney <[email protected]>
#
# SPDX-License-Identifier: MIT
import os
import json
import time
import shutil

from aprstastic._config import (
ConfigError,
init_config,
CONFIG_FILE_NAME,
LOGS_SUBDIR,
DATA_SUBDIR,
DEFAULT_CALL_SIGN,
)


TEST_CONFIG_FILE_NAME_1 = "test_aprstastic_1.yaml"
TEST_CONFIG_FILE_NAME_2 = "test_aprstastic_2.yaml"
config_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "test_data")

# Monkey patch the default directory
import aprstastic._config

aprstastic._config.DEFAULT_DATA_DIR = config_dir

logs_dir = os.path.join(config_dir, LOGS_SUBDIR)
data_dir = os.path.join(config_dir, DATA_SUBDIR)


def test_initialize_config():
config_file = os.path.join(config_dir, CONFIG_FILE_NAME)

# Start fresh
if os.path.isfile(config_file):
os.unlink(config_file)

assert not os.path.isfile(config_file)

cwd = os.path.abspath(os.getcwd())
error_msg = None
try:
os.chdir(config_dir)

# Initialize the config
config = init_config()

except ConfigError as e:
error_msg = str(e)
finally:
os.chdir(cwd)

# Make sure the sample config exists now
assert os.path.isfile(config_file)
# assert os.path.isdir(logs_dir)
# assert os.path.isdir(data_dir)

# Make sure the correct error was thrown
assert "A sample configuration was written" in error_msg

# Try loading it again, and check that the correct error was thrown the second time
try:
os.chdir(config_dir)
config = init_config()
except ConfigError as e:
error_msg = str(e)
finally:
os.chdir(cwd)
assert "appears to be the sample config" in error_msg


def test_load_config():
config_file = os.path.join(config_dir, CONFIG_FILE_NAME)
test_config_file_1 = os.path.join(config_dir, TEST_CONFIG_FILE_NAME_1)
test_config_file_2 = os.path.join(config_dir, TEST_CONFIG_FILE_NAME_2)

mylogs_dir = os.path.join(config_dir, "mylogs")
mydata_dir = os.path.join(config_dir, "mydata")

# Install our test config #1
shutil.copyfile(test_config_file_1, config_file)

# Load the config
cwd = os.path.abspath(os.getcwd())
error_msg = None
try:
os.chdir(config_dir)
config = init_config()
finally:
os.chdir(cwd)

# Check that it looks right
assert config == json.loads(
"""
{
"gateway": {
"call_sign": "N0CALL-1",
"aprsis_passcode": 12345,
"meshtastic_interface": {
"type": "serial"
},
"beacon_registrations": true,
"data_dir": "%s",
"logs_dir": "%s"
},
"licensed_operators": {}
}
"""
% (data_dir, logs_dir)
)

# Install our test config #2
shutil.copyfile(test_config_file_2, config_file)

# Load the config
cwd = os.path.abspath(os.getcwd())
error_msg = None
try:
os.chdir(config_dir)
config = init_config()
finally:
os.chdir(cwd)

# Check that it looks right
assert config == json.loads(
"""
{
"gateway": {
"call_sign": "N0CALL-2",
"aprsis_passcode": 12345,
"meshtastic_interface": {
"type": "serial"
},
"beacon_registrations": false,
"data_dir": "%s",
"logs_dir": "%s"
},
"licensed_operators": {}
}
"""
% (mydata_dir, mylogs_dir)
)


##########################
if __name__ == "__main__":
import logging

logging.basicConfig(level=logging.DEBUG)
test_initialize_config()
test_load_config()
27 changes: 27 additions & 0 deletions tests/test_data/test_aprstastic_1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#
# APRSTASTIC CONFIGURATION FILE (version: 1)
# Be sure to at least modify 'call_sign' and 'aprsis_passcode'.
#

# Radio call sign of the gateway itself (analogy, iGate's call sign)
call_sign: N0CALL-1

# APRS-IS passcode. Search Google for how to get this
aprsis_passcode: 12345

# Only serial devices are supported right now.
# If 'device' is null (or commented out), an attempt will be made to
# detected it automatically.
meshtastic_interface:
type: serial
# device: /dev/ttyACM0

# Beacon new registrations to APRS-IS to facilitate discovery
beacon_registrations: true
# Where should logs be stored?
# If null, (or commented out), store logs in the `logs` dir, sibling to this file.
#logs_dir: null

# Where should data be stored?
# If null, (or commented out), store data in the `data` dir, sibling to this file.
#data_dir: null
28 changes: 28 additions & 0 deletions tests/test_data/test_aprstastic_2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#
# APRSTASTIC CONFIGURATION FILE (version: 1)
# Be sure to at least modify 'call_sign' and 'aprsis_passcode'.
#

# Radio call sign of the gateway itself (analogy, iGate's call sign)
call_sign: N0CALL-2

# APRS-IS passcode. Search Google for how to get this
aprsis_passcode: 12345

# Only serial devices are supported right now.
# If 'device' is null (or commented out), an attempt will be made to
# detected it automatically.
meshtastic_interface:
type: serial
# device: /dev/ttyACM0

# Beacon new registrations to APRS-IS to facilitate discovery
beacon_registrations: false

# Where should logs be stored?
# If null, (or commented out), store logs in the `logs` dir, sibling to this file.
logs_dir: mylogs

# Where should data be stored?
# If null, (or commented out), store data in the `data` dir, sibling to this file.
data_dir: mydata

0 comments on commit 0a0f921

Please sign in to comment.