Skip to content

Commit

Permalink
Merge pull request #63 from cmpsc-481-s22-m1/release/v1.0.0
Browse files Browse the repository at this point in the history
Release/v1.0.0
  • Loading branch information
ColemanKobe authored Feb 5, 2022
2 parents 4369217 + b145790 commit 54077b1
Show file tree
Hide file tree
Showing 20 changed files with 522 additions and 542 deletions.
6 changes: 5 additions & 1 deletion .github/cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@
"pwsh",
"fastfail",
"gatorconfig",
"gatorgrader"
"gatorgrader",
"Ullrich",
"ullrichd",
"Downey",
"favourojo"



Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
poetry config virtualenvs.in-project true
poetry env info
- name: Install dependencies
run: poetry install --no-interaction --no-ansi
run: poetry install --no-interaction --no-ansi -E gui
- name: Lint code
run: poetry run task lint
- name: Lint markdown
Expand Down Expand Up @@ -70,10 +70,11 @@ jobs:
poetry config virtualenvs.in-project true
poetry env info
- name: Install dependencies
run: poetry install --no-interaction --no-ansi
run: poetry install --no-interaction --no-ansi -E gui
- name: setup ${{ matrix.os }}
run: |
sudo apt install libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0
sudo apt install python3-pip mesa-utils libegl1-mesa xvfb
/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -screen 0 1920x1200x24 -ac +extension GLX
- name: Execute tests
run: poetry run task test
27 changes: 27 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Publish

on:
release:
types: [created]

jobs:
publish:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Set up Python 3.9
uses: actions/setup-python@v2
with:
python-version: '3.9'
- name: Install Poetry
uses: abatilo/[email protected]
with:
poetry-version: 1.1.12
- name: Publish
run: |
poetry version ${GITHUB_REF##*/v}
poetry publish --build
env:
POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_TOKEN }}
7 changes: 0 additions & 7 deletions .pylintrc

This file was deleted.

21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2022 GatorConfig Contributors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
91 changes: 64 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
# GatorConfig

# team4-GatorConfig
![logo](https://user-images.githubusercontent.com/42869122/152203388-39f5f0ef-e4c7-4f80-b667-07a4ed739b4d.png)

A simple Python project utilizing a CLI approach to automate generating
configuration files for GatorGrader. The GitHub Actions workflow executes
[pytest](https://pytest.org/) (with
[coverage](https://pypi.org/project/pytest-cov/)) and
[pylint](https://pylint.org/) using the Poetry configuration, and checks
markdown with [markdownlint](https://github.com/DavidAnson/markdownlint) and
spelling with [cspell](https://cspell.org/).
A simple Python tool utilizing both a CLI and GUI approach
to automate the generation of configuration files for
[GatorGrader](https://github.com/GatorEducator/gatorgrader).
This tool is designed to assist educators in grading
GitHub-based assignments for their computer science courses.

## Requirements

Expand All @@ -17,14 +16,64 @@ spelling with [cspell](https://cspell.org/).

## Usage

### Install with pip or pipx

To install the tool and its dependencies using pip, run the following command:

```bash
pip install gatorconfig
```

Alternatively, you can install using pipx by running:

```bash
pipx install gatorconfig
```

### Running GatorConfig

GatorConfig is a tool that can utilize the command line interface, which
was built to accommodate the users. To run the GatorConfig program
in CLI, type the command:

`gatorconfig`

Once you run this command, the program will output:

`Wrote file to: C:\Users\<YOUR PATH>\config\gatorgrader.yml`

This command will auto-generate a default configuration file for GatorGradle
named `gatorgrader.yml` located in the `config` folder.

Additionally, you can run the `gatorconfig --help` for more
information about the configuration. This command will list the variables
in the file as well as the defaults it outputs.

## Contributing

### Technical details

The GitHub Actions
workflow executes [pytest](https://pytest.org/) (with
[coverage](https://pypi.org/project/pytest-cov/)) and
[pylint](https://pylint.org/) using the Poetry configuration, and checks
markdown with [markdownlint](https://github.com/DavidAnson/markdownlint) and
spelling with [cspell](https://cspell.org/).

### Installing Python dependencies

After cloning this project, you will likely want to instruct Poetry to create a
virtual environment and install the Python packages (like pytest and pylint)
virtual environment and install the Python packages (such as pytest and pylint)
listed in `pyproject.toml`.

To install Python dependencies:

```bash
poetry install -E gui
```

To install without the extra GUI feature, install with:

```bash
poetry install
```
Expand All @@ -38,22 +87,10 @@ are executed under the `[tool.taskipy.tasks]` header in `pyproject.toml`.
- **Test** your code with `poetry run task test`
- **Lint** your code with `poetry run task lint`

### Running GatorConfig

GatorConfig is a tool that will utilize the command line interface, which
was built to accommodate the users. To run the GatorConfig program
in CLI, type the command:

`poetry run gatorconfig`
## Authors

Once you run this command, the program will output

`Wrote file to: C:\Users\<YOUR PATH>\GatorConfig\gatorgrader.yml`

This command will auto-generate a default configuration file for GatorGradle
named `gatorgrader.yml` which will contain a default input for
the variables, such as the name, break, fastfail, etc.,

Additionally, you can run the `poetry run gatorconfig --help` for more
information about the configuration. This command will list out the variables
in the file as well as the defaults it outputs.
- Wesley Long, @WesleyL30 - *Lead CLI developer*
- Danny Ullrich, @ullrichd21 - *Lead GUI developer*
- Kobe Coleman, @ColemanKobe
- Paige Downey, @PaigeCD
- Favour Ojo, @favourojo
125 changes: 78 additions & 47 deletions gatorconfig/gator_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,68 +2,97 @@
from typing import Dict
from typing import List
from pathlib import Path
import os
import typer
from gatorconfig import gator_yaml
import gatoryaml
from gatorconfig.gui_main import Gui
from gatorconfig import actions_configuration

cli = typer.Typer()



def default_name():
"""Generate default name based on current directory."""
return os.path.basename(Path.cwd())


#pylint: disable=too-many-arguments
#pylint: disable=too-many-locals
@cli.command()
def cli_input(
name: str = typer.Option("Project"),
brk: bool = typer.Option(False, "--break"),
fastfail: bool = typer.Option(False),
gen_readme: bool = typer.Option(False),
file: List[str] = typer.Option([]),
#language: str = typer.Option(None),
output_path: Path = typer.Option(Path.cwd()),
indent: int = typer.Option(4),
commit_count: int = typer.Option(5)
name: str = typer.Option(default_name(), help="The name of the project"),
no_break: bool = typer.Option(False, "--no-break", help="""Configure GatorGradle to not fail the
grading run when a GatorGrader check fails"""),
overwrite: bool = typer.Option(False, help="Allows GatorConfig to overwrite existing files"),
fastfail: bool = typer.Option(False, help="""Configure GatorGradle to fail the grading run
immediately when a single GatorGrader check fails"""),
gen_readme: bool = typer.Option(False, help="Generates a README file"),
file: List[str] = typer.Option([], help="""Enter singular file path, can be done
multiple times"""),
output_path: Path = typer.Option(Path.cwd(), help="Enter preferred output path"),
indent: int = typer.Option(4, help="""Enter the number of spaces for an indentation
level in the GatorGrader configuration file"""),
actions: bool = typer.Option(True, help="Toggles whether or not github actions are created"),
gui: bool = typer.Option(False, help="Open GatorConfig in GUI mode"),
):
"""Gather input from the command line.
"""Gather input from the command line."""
config_dir = output_path / "config"
config_path = config_dir / "gatorgrader.yml"
config_dir.mkdir(exist_ok=True)
if overwrite or not config_path.exists():
if gui:
gui_obj = Gui()
header, body = gui_obj.get_data()
else:
# Creation of the output variable
body = get_checks(file)
# Creation of the output variable
header = {
"name": name,
"break": not no_break,
"fastfail": fastfail,
"indent": indent,
}
file_yaml = gatoryaml.dump(header, body, indent=indent)
output_file(file_yaml, config_path)
elif config_path.exists():
print(f"'gatorgrader.yml' already exists within {config_dir}")
print("\nUse '--overwrite' to rewrite this file.")
if actions:
actions_configuration.create_configuration_file('.github/workflows/grade.yml')
if gen_readme:
readme_gen(output_path)

Args:
name (str, optional): [description]. Defaults to typer.Option("Project").
brk (bool, optional): [description]. Defaults to typer.Option(False, "--break").
fastfail (bool, optional): [description]. Defaults to typer.Option(False).
file (List[str], optional): [description]. Defaults to typer.Option([]).
indent (int, optional): [description]. Defaults to typer.Option(4).
commit_count (int, optional): [description]. Defaults to typer.Option(5).
"""
files = get_checks(file)

yaml_out = gator_yaml.GatorYaml()
#print(files)
# Creation of the output variable
output = {
"name": name,
"break": brk,
"fastfail": fastfail,
"readme": gen_readme,
"indent": indent,
"commits": commit_count,
"files": files
}
file_yaml = yaml_out.dump(output, paths=output["files"])
output_file(file_yaml, output_path)
actions_configuration.create_configuration_file('../.github/workflows/grade.yml')


def output_file(yaml_string: str, output_path: Path):

def readme_gen(output_path: Path):
"""Generate basic README in current directory."""
if output_path.exists():
with open(Path(output_path / "README.md"), "x", encoding="utf8") as file:
file.write(
"# " + default_name() + "\n" + "\n" +
"This is the repository containing the " + default_name() + " assignment."
+ "\n" + "\n" + "## Using GatorGradle" + "\n" + "\n" +
"This assignment utilizes " +
"[GatorGrader](https://github.com/GatorEducator/gatorgrader)"
" in order to perform automated grading checks." +
" To grade your assignment, run the following command in your " +
"Docker container or environment containing Gradle:"
+ "\n" + "\n" + "```" + "\n" + "gradle grade" + "\n" + "```" + "\n"
)


def output_file(yaml_string: str, config_path: Path):
"""Create and write to file if it doesn't exist, writes to file otherwise.
Args:
yaml_string (str): [description]
output_path (Path): [description]
"""
fle = Path(output_path / "gatorgrader.yml")
fle.touch(exist_ok=True)
with open(fle, "w", encoding="utf8") as yml:
yml.write(yaml_string)
print(f"Wrote file to: {fle}")
config_path.parent.mkdir(exist_ok=True)
config_path.open('w').write(yaml_string)
print(f"Wrote file to: {config_path}")


def get_checks(file: List[Path]) -> Dict:
"""Read in checks per file.
Expand All @@ -77,10 +106,12 @@ def get_checks(file: List[Path]) -> Dict:
files = {}
for item in file:
running = True
print("")
check_list = []
check_list = ['--description "Confirm the file exists" ConfirmFileExists',
'--description "Make sure there are no TODOs in the file"'
' MatchFileFragment --fragment "TODO" --count 0']
print(f"These checks are added by default:\n {check_list} \n")
while running:
check = input(f"Enter a check for {item} (Press \"Enter\" to move on): ")
check = input(f"Enter a check for {item} (Press 'Enter' to move on to the next file): ")
if check.lower() == "":
running = False
else:
Expand Down
Loading

0 comments on commit 54077b1

Please sign in to comment.