Skip to content

Commit

Permalink
Initial development
Browse files Browse the repository at this point in the history
  • Loading branch information
anevis committed Apr 6, 2024
1 parent 5132a9f commit c8f0b76
Show file tree
Hide file tree
Showing 17 changed files with 847 additions and 3 deletions.
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @anevis
19 changes: 19 additions & 0 deletions .github/workflows/ci-cd.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: CI/CD Pipeline
run-name: CI/CD 🚀
on: [push]
jobs:
CI:
runs-on: ubuntu-latest
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"
- run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
- name: Check out repository code
uses: actions/checkout@v4
- run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner."
- run: echo "🖥️ The workflow is now ready to test your code on the runner."
- name: Installing Devbox ⚙️
run: curl -fsSL https://get.jetpack.io/devbox | bash
- name: 🧹 Linting & Formatting
run: devbox run lint && devbox run format
- run: echo "🍏 This job's status is ${{ job.status }}."
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,5 @@ cython_debug/
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
.idea/
*.iml
54 changes: 52 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,52 @@
# json-to-markdown
A utility to take a JSON / YAML file or a python dict / list and create a Markdown file.
# JSON to Markdown Converter

A Python utility to take a JSON / YAML file or a python dict / list and create a Markdown file.

## Usage

### In Python Code example:

#### Convert a Pyton dictionary to Markdown:
```python
from json_to_markdown.md_converter import MDConverter

data = {
"name": "John Doe",
"age": 30,
"city": "Sydney",
"hobbies": ["reading", "swimming"],
}
converter = MDConverter()
with open("output.md", "w") as f:
converter.convert(data, f)
```
Content of `output.md` file will be:
```markdown
## Name
John Doe
## Age
30
## City
Sydney
## Hobbies
* reading
* swimming
```

### From the Command Line

You can also use the command line interface to convert a JSON or YAML file to Markdown. Here's an example:

#### Convert a JSON file to Markdown:
```bash
python json_to_markdown/convert.py --output-file output.md --json-file test.json
```

#### Convert a YAML file to Markdown:
```bash
python json_to_markdown/convert.py --output-file output.md --yaml-file test.yaml
```

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
32 changes: 32 additions & 0 deletions devbox.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"$schema": "https://raw.githubusercontent.com/jetpack-io/devbox/0.10.3/.schema/devbox.schema.json",
"packages": ["[email protected]"],
"shell": {
"env": {
"VENV_DIR": "$HOME/MyFiles/programming/OpenSource/json-to-markdown/.devbox/virtenv/python/.venv"
},
"init_hook": [
". $VENV_DIR/bin/activate"
],
"scripts": {
"install": [
"pip install -r requirements.txt"
],
"install-dev": [
"pip install -r requirements.txt -r requirements-dev.txt"
],
"test": [
"pytest src/"
],
"lint": [
"flake8 src/"
],
"format-check": [
"black --check src/"
],
"format": [
"black src/"
]
}
}
}
62 changes: 62 additions & 0 deletions devbox.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"lockfile_version": "1",
"packages": {
"[email protected]": {
"last_modified": "2024-03-22T11:26:23Z",
"plugin_version": "0.0.3",
"resolved": "github:NixOS/nixpkgs/a3ed7406349a9335cb4c2a71369b697cecd9d351#python312",
"source": "devbox-search",
"version": "3.12.2",
"systems": {
"aarch64-darwin": {
"outputs": [
{
"name": "out",
"path": "/nix/store/jc5jlynlx561ibqxd6sy12hcqc8p39c9-python3-3.12.2",
"default": true
}
],
"store_path": "/nix/store/jc5jlynlx561ibqxd6sy12hcqc8p39c9-python3-3.12.2"
},
"aarch64-linux": {
"outputs": [
{
"name": "out",
"path": "/nix/store/n5yvl08kxz5llrdiwwxfxyy6wiq2g6lc-python3-3.12.2",
"default": true
},
{
"name": "debug",
"path": "/nix/store/bihg62nz0vqqski18cpyppwgqz62blrq-python3-3.12.2-debug"
}
],
"store_path": "/nix/store/n5yvl08kxz5llrdiwwxfxyy6wiq2g6lc-python3-3.12.2"
},
"x86_64-darwin": {
"outputs": [
{
"name": "out",
"path": "/nix/store/41yqb3sxsx22drhza74icn4x1gfh3h8m-python3-3.12.2",
"default": true
}
],
"store_path": "/nix/store/41yqb3sxsx22drhza74icn4x1gfh3h8m-python3-3.12.2"
},
"x86_64-linux": {
"outputs": [
{
"name": "out",
"path": "/nix/store/7yh2ax34jd7fgf17mjfd3c6niw1h2hsj-python3-3.12.2",
"default": true
},
{
"name": "debug",
"path": "/nix/store/mq8jh0sl1lcpk592whzw96n52grhq8wl-python3-3.12.2-debug"
}
],
"store_path": "/nix/store/7yh2ax34jd7fgf17mjfd3c6niw1h2hsj-python3-3.12.2"
}
}
}
}
}
99 changes: 99 additions & 0 deletions docs/DEVELOPER.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Developer Documentation

## Getting Started

### Prerequisites

- devbox
- Python (3.12.2)
- pip

#### Setting up the Development Environment
Install the devbox CLI tool if you haven't already. You can install it using the following command:

```bash
curl -fsSL https://get.jetpack.io/devbox | bash
````

[![Built with Devbox](https://jetpack.io/img/devbox/shield_galaxy.svg)](https://jetpack.io/devbox/docs/contributor-quickstart/)
### Setting up Development Environment

#### Clone the repository:

```bash
git clone [email protected]:anevis/json-to-markdown.git
cd json-to-markdown-converter
```
#### Start the development environment:

```bash
devbox shell
```

#### Install the required packages:

From within devbox shell
```bash
pip install -r requirements.txt -r requirements-dev.txt
```

From outside devbox shell
```bash
devbox run install-dev
```

## Code Structure

The functionality can be used in the command line or in Python code.

To use the functionality in Python code, you can import the `MDConverter` class from the `json_to_markdown.md_converter` module.
The `md_converter.py` file contains the `MDConverter` class, which is used by the `convert` function to perform the conversion.

To use the functionality from the command line, you can run the `convert.py` script in the `json_to_markdown` directory.
This file contains the `convert` function, which takes a JSON or YAML file and converts it to Markdown.

## Testing
Tests for the project are located in the `*_test.py` files.
These tests use the Pytest and Mock libraries to test the functionality of the `convert` function and the `MDConverter` class.

### Running the Tests

You can run the tests with the following command:

From within devbox shell
```bash
pytest src/
```

From outside devbox shell
```bash
devbox run test
```

## Linting & Formatting

The project uses the Black and Flake8 libraries for code formatting and linting.
You can run the following commands to format and lint the code:

From within devbox shell
```bash
black src/
flake8 src/
```

From outside devbox shell
```bash
devbox run format
devbox run lint
```

You can use `devbox run format-check` to check if the code is formatted correctly without making any changes.

## Contributing

We welcome contributions to this project. Please feel free to submit a pull request or open an issue on GitHub.

## License

This project is licensed under the MIT License - see the [LICENSE](../LICENSE) file for details.
23 changes: 23 additions & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Dev dependencies
coverage==7.4.4
mock==5.1.0
pytest==8.1.1
pytest-cov==5.0.0

bandit==1.7.8
black==24.3.0
flake8==7.0.0
flake8-bandit==4.1.1
flake8-black==0.3.6
flake8-bugbear==24.2.6
flake8-functions==0.0.8
isort==5.13.2
mypy==1.9.0
pep8-naming==0.13.3
safety

# Typing
types-mock==5.1.0.20240311
types-orjson==3.6.2
types-PyYAML==6.0.12.20240311
types-jsonschema==4.21.0.20240331
3 changes: 3 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
click==8.1.7
jsonschema[format]==4.21.1
pyyaml==6.0.1
4 changes: 4 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[flake8]
max-line-length = 120
per-file-ignores = *_test.py:S101
max-returns-amount = 4
Empty file.
54 changes: 54 additions & 0 deletions src/json_to_markdown/convert.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import io
import json
from typing import Dict, Any, Optional

import click
import yaml

from json_to_markdown.md_converter import MDConverter


def _get_json_data(json_file: str) -> Dict[str, Any]:
with io.open(json_file, "r", encoding="utf-8") as j_file:
return json.load(j_file)


def _get_yaml_data(yaml_file: str) -> Dict[str, Any]:
with io.open(yaml_file, "r", encoding="utf-8") as y_file:
return yaml.safe_load(y_file)


@click.command()
@click.option("-o", "--output-file", "output_file", type=str)
@click.option("-y", "--yaml-file", "yaml_file", type=str, default=None)
@click.option("-j", "--json-file", "json_file", type=str, default=None)
def main(output_file: str, yaml_file: Optional[str], json_file: Optional[str]) -> None:
convert(output_file=output_file, yaml_file=yaml_file, json_file=json_file)


def convert(
output_file: str, yaml_file: Optional[str] = None, json_file: Optional[str] = None
) -> None:
if yaml_file is None and json_file is None:
raise RuntimeError("One of yaml_file or json_file is required.")

data = _get_json_data(json_file) if json_file else _get_yaml_data(yaml_file)
with io.open(output_file, "w", encoding="utf-8") as md_file:
converter = MDConverter()
converter.set_selected_sections(
sections=[
"assessment-date",
"assessors",
"description",
"diagram",
"external-dependencies",
"roles",
"entry-points",
"threats",
]
)
converter.convert(data=data, output_writer=md_file)


if __name__ == "__main__":
main()
Loading

0 comments on commit c8f0b76

Please sign in to comment.