-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5f9f169
commit 2cd2d2e
Showing
6 changed files
with
264 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
format-gml.zip |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
{ | ||
"indent_size": 4, | ||
"indent_char": " ", | ||
"indent_with_tabs": true, | ||
"editorconfig": false, | ||
"eol": "\n", | ||
"end_with_newline": true, | ||
"indent_level": 0, | ||
"preserve_newlines": true, | ||
"max_preserve_newlines": 2, | ||
"space_in_paren": false, | ||
"space_in_empty_paren": false, | ||
"jslint_happy": false, | ||
"space_after_anon_function": true, | ||
"space_after_named_function": false, | ||
"brace_style": "expand,preserve-inline", | ||
"unindent_chained_methods": false, | ||
"break_chained_methods": false, | ||
"keep_array_indentation": false, | ||
"unescape_strings": false, | ||
"wrap_line_length": 120, | ||
"e4x": true, | ||
"comma_first": false, | ||
"operator_position": "after-newline", | ||
"indent_empty_lines": false, | ||
"templating": [ | ||
"auto" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,94 @@ | ||
# format-gml | ||
Tiny tool and a Git hook for automatic formatting of GML code | ||
|
||
> Tiny tool and a Git hook for automatic formatting of GML code | ||
[![License](https://img.shields.io/github/license/blueburncz/format-gml)](LICENSE) | ||
[![Discord](https://img.shields.io/discord/298884075585011713?label=Discord)](https://discord.gg/ep2BGPm) | ||
|
||
## Table of Contents | ||
|
||
* [About](#about) | ||
* [How to set up](#how-to-set-up) | ||
* [As a repo owner](#as-a-repo-owner) | ||
* [As a contributor](#as-a-contributor) | ||
* [Common issues](#common-issues) | ||
|
||
## About | ||
|
||
format-gml is a simple Python script that uses [js-beautify](https://github.com/beautifier/js-beautify) to format GML files, designed primarily to ensure that all contributors to an open-source GameMaker project use the same code formatting style. This is achieved with a pre-commit Git hook, which checks whether all staged GML files follow the style defined in a file `.jsbeautifyrc` placed in the root of the repo. If a staged GML file doesn't follow the formatting style, it's not allowed to be committed before it's fixed. This can be done simply by running the tool. | ||
|
||
## How to set up | ||
|
||
### As a repo owner | ||
First, you need to download a release of format-gml and extract it into the root of your repo. Don't forget to commit all the extracted files! 🙂 | ||
|
||
Next, install [Python 3](https://www.python.org/downloads/) and the required packages by running the following command: | ||
|
||
```sh | ||
pip3 install -r requirements.txt | ||
``` | ||
|
||
You may want to customize the `.jsbeautifyrc` file to match your preferred code formatting style. Our default setup follows the [Allman style](https://en.wikipedia.org/wiki/Indentation_style#Allman_style), with tabs for indentation (size 4) and a maximum line length of 120 characters. You can have a look here for all available options: <https://github.com/beautifier/js-beautify?tab=readme-ov-file#options>. | ||
|
||
To format all GML files present in your repo with the configure style, run the following command and commit the changes. | ||
|
||
```sh | ||
python3 format-gml.py --all | ||
``` | ||
|
||
Afterwards, set up the hook by running: | ||
|
||
```gml | ||
git config core.hooksPath hooks | ||
``` | ||
|
||
And that's it! From now on, when you try to commit changes to GML files within the repo, the hook won't allow you to do so if they're not properly formatted. To fix their formatting, simply run `format-gml.py` with out any arguments like so: | ||
|
||
```sh | ||
python3 format-gml.py | ||
``` | ||
|
||
### As a contributor | ||
|
||
1. Install [Python 3](https://www.python.org/downloads/) and the required packages by running the following command from the root of the repo: | ||
|
||
```sh | ||
pip3 install -r requirements.txt | ||
``` | ||
|
||
2. Set up the hook by running: | ||
|
||
```gml | ||
git config core.hooksPath hooks | ||
``` | ||
|
||
3. When you're not allowed to commit a file because of its formatting, run the following command and stage the changes: | ||
|
||
```sh | ||
python3 format-gml.py | ||
``` | ||
|
||
## Common issues | ||
|
||
Since js-beautify is a JavaScript formatter, it doesn't work properly on GameMaker in all cases. | ||
|
||
1. `$"these strings"` | ||
|
||
Handled automatically inside of `format-gml.py` by removing all whitespace between character `$` and `"`. | ||
|
||
2. `#macro`s | ||
|
||
Currently the only fix for those is to surround them with `/* beautify ignore:start */` and `/* beautify ignore:end */` like so: | ||
|
||
```gml | ||
/* beautify ignore:start */ | ||
#macro MY_FANCY_MACRO \ | ||
do | ||
{ \ | ||
some_stuff_here(); \ | ||
} \ | ||
until (1) | ||
/* beautify ignore:end */ | ||
``` | ||
If you find more, please let us know via an issue or contact us on our Discord server (link at the top). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
#!/usr/bin/env python3 | ||
# -*- coding: utf-8 -*- | ||
import jsbeautifier | ||
import json | ||
import os | ||
import re | ||
import subprocess | ||
import sys | ||
|
||
VERSION_MAJOR = 1 | ||
VERSION_MINOR = 0 | ||
VERSION_PATCH = 0 | ||
VERSION_STRING = f"{VERSION_MAJOR}.{VERSION_MINOR}.{VERSION_PATCH}" | ||
|
||
HELP_MESSAGE = """ | ||
Usage: format-gml [-h, -v, --validate, --staged, --all, --file FILE] | ||
Arguments: | ||
-h - Show this help message and exit. | ||
-v - Show version and exit. | ||
--validate - Check whether all staged GML files are properly formatted and exit with status 0 on success or 1 on fail. | ||
--staged - Format all staged GML files. This is the default option. | ||
--all - Format all GML files in the repo. | ||
--file - Format only given file. | ||
"""[ | ||
1: | ||
] | ||
|
||
OPTIONS_PATH = "./.jsbeautifyrc" | ||
|
||
if os.path.exists(OPTIONS_PATH): | ||
with open(OPTIONS_PATH, "r") as f: | ||
OPTIONS = json.load(f) | ||
else: | ||
OPTIONS = None | ||
|
||
|
||
def beautify_file(filepath): | ||
res = jsbeautifier.beautify_file(filepath, OPTIONS) | ||
res = re.sub(r"\$[\s\n]+\"", '$"', res) | ||
return res | ||
|
||
|
||
def get_staged_files(): | ||
# Run the git command | ||
result = subprocess.run( | ||
["git", "diff", "--name-only", "--cached"], | ||
stdout=subprocess.PIPE, # Capture output | ||
stderr=subprocess.PIPE, # Capture errors | ||
text=True, | ||
) # Return output as string | ||
|
||
# Check if there was an error | ||
if result.returncode != 0: | ||
print(f"Error: {result.stderr}") | ||
return [] | ||
|
||
# Get the output (list of file paths) | ||
staged_files = result.stdout.strip().split("\n") | ||
|
||
# Remove any empty strings (in case no files are staged) | ||
return [file for file in staged_files if file] | ||
|
||
|
||
def get_staged_file_contents(file_path): | ||
try: | ||
# Run the git show command to get the staged contents | ||
result = subprocess.run( | ||
["git", "show", f":{file_path}"], capture_output=True, text=True, check=True | ||
) | ||
return result.stdout # Return the staged file contents | ||
except subprocess.CalledProcessError as e: | ||
print(f"ERROR: {e}") | ||
exit(1) | ||
|
||
|
||
if __name__ == "__main__": | ||
target = "--staged" | ||
filepath = None | ||
|
||
if len(sys.argv) > 1: | ||
target = sys.argv[1] | ||
|
||
if target == "--file": | ||
if len(sys.argv) > 2: | ||
filepath = sys.argv[2] | ||
else: | ||
print("Argument FILE not defined!") | ||
print(1) | ||
|
||
if target == "-h": | ||
print(HELP_MESSAGE) | ||
elif target == "-v": | ||
print(VERSION_STRING) | ||
elif target == "--validate": | ||
for filepath in get_staged_files(): | ||
if filepath.endswith(".gml"): | ||
orig = get_staged_file_contents(filepath) | ||
res = beautify_file(filepath) | ||
if orig != res: | ||
print( | ||
f'ERROR: File "{filepath}" is not properly formatted!\n\nPlease run ./format-gml.py to fix formatting of all staged GML files and stage the changes before running commit again.' | ||
) | ||
exit(1) | ||
elif target == "--staged": | ||
for filepath in get_staged_files(): | ||
if filepath.endswith(".gml"): | ||
res = beautify_file(filepath) | ||
with open(filepath, "w") as f: | ||
f.write(res) | ||
elif target == "--all": | ||
for dirpath, _, filenames in os.walk("."): | ||
for filename in filenames: | ||
if filename.endswith(".gml"): | ||
filepath = os.path.join(dirpath, filename) | ||
res = beautify_file(filepath) | ||
with open(filepath, "w") as f: | ||
f.write(res) | ||
elif target == "--file": | ||
res = beautify_file(filepath) | ||
with open(filepath, "w") as f: | ||
f.write(res) | ||
else: | ||
print(f"Invalid target {target}! Run format-gml -h to display usage.") | ||
exit(1) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#!/bin/sh | ||
if hash python3 2>/dev/null; | ||
then | ||
python3 format-gml.py --validate | ||
else | ||
python format-gml.py --validate | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
cachetools==5.0.0 | ||
EditorConfig==0.12.4 | ||
future==0.18.2 | ||
Jinja2==3.1.1 | ||
jsbeautifier==1.15.1 | ||
MarkupSafe==2.1.1 | ||
mistune==2.0.2 | ||
pefile==2021.9.3 | ||
six==1.16.0 |