Skip to content

Commit 5e412bf

Browse files
committedFeb 26, 2022
Initial commit
0 parents  commit 5e412bf

38 files changed

+2570
-0
lines changed
 

‎.github/workflows/codeql-analysis.yml

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# For most projects, this workflow file will not need changing; you simply need
2+
# to commit it to your repository.
3+
#
4+
# You may wish to alter this file to override the set of languages analyzed,
5+
# or to provide custom queries or build logic.
6+
#
7+
# ******** NOTE ********
8+
# We have attempted to detect the languages in your repository. Please check
9+
# the `language` matrix defined below to confirm you have the correct set of
10+
# supported CodeQL languages.
11+
#
12+
name: "CodeQL"
13+
14+
on:
15+
push:
16+
branches: [ main ]
17+
pull_request:
18+
# The branches below must be a subset of the branches above
19+
branches: [ main ]
20+
schedule:
21+
- cron: '24 12 * * 2'
22+
23+
jobs:
24+
analyze:
25+
name: Analyze
26+
runs-on: ubuntu-latest
27+
permissions:
28+
actions: read
29+
contents: read
30+
security-events: write
31+
32+
strategy:
33+
fail-fast: false
34+
matrix:
35+
language: [ 'python' ]
36+
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
37+
# Learn more about CodeQL language support at https://git.io/codeql-language-support
38+
39+
steps:
40+
- name: Checkout repository
41+
uses: actions/checkout@v2
42+
43+
# Initializes the CodeQL tools for scanning.
44+
- name: Initialize CodeQL
45+
uses: github/codeql-action/init@v1
46+
with:
47+
languages: ${{ matrix.language }}
48+
# If you wish to specify custom queries, you can do so here or in a config file.
49+
# By default, queries listed here will override any specified in a config file.
50+
# Prefix the list here with "+" to use these queries and those in the config file.
51+
# queries: ./path/to/local/query, your-org/your-repo/queries@main
52+
53+
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
54+
# If this step fails, then you should remove it and run the build manually (see below)
55+
- name: Autobuild
56+
uses: github/codeql-action/autobuild@v1
57+
58+
# ℹ️ Command-line programs to run using the OS shell.
59+
# 📚 https://git.io/JvXDl
60+
61+
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
62+
# and modify them (or add more) to build your code if your project
63+
# uses a compiled language
64+
65+
#- run: |
66+
# make bootstrap
67+
# make release
68+
69+
- name: Perform CodeQL Analysis
70+
uses: github/codeql-action/analyze@v1

‎.github/workflows/publish-docs.yml

+129
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
name: Publish Docs
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
8+
jobs:
9+
build:
10+
runs-on: ubuntu-latest
11+
strategy:
12+
matrix:
13+
python-version: ["3.10"]
14+
steps:
15+
- uses: actions/checkout@v1
16+
- name: Configure git
17+
run: |
18+
git config --global user.name 'travis-ci'
19+
git config --global user.email 'travis@nowhere.edu'
20+
21+
- name: Filter changed file paths to outputs
22+
uses: dorny/paths-filter@v2.7.0
23+
id: changes
24+
with:
25+
filters: |
26+
root_docs:
27+
- CHANGES
28+
- README.*
29+
docs:
30+
- 'docs/**/*.rst'
31+
- 'docs/**/*.md'
32+
- 'examples/**'
33+
python_files:
34+
- 'g.py'
35+
- 'g/**'
36+
37+
- name: Should publish
38+
if: steps.changes.outputs.docs == 'true' || steps.changes.outputs.root_docs == 'true' || steps.changes.outputs.python_files == 'true'
39+
run: echo "PUBLISH=$(echo true)" >> $GITHUB_ENV
40+
41+
- name: Set up Python ${{ matrix.python-version }}
42+
uses: actions/setup-python@v1
43+
with:
44+
python-version: ${{ matrix.python-version }}
45+
46+
- name: Get full Python version
47+
id: full-python-version
48+
shell: bash
49+
run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))")
50+
51+
- name: Install poetry
52+
run: |
53+
curl -O -sSL https://install.python-poetry.org/install-poetry.py
54+
python install-poetry.py -y --version 1.1.12
55+
echo "PATH=${HOME}/.poetry/bin:${PATH}" >> $GITHUB_ENV
56+
rm install-poetry.py
57+
58+
- name: Add ~/.local/bin to PATH
59+
run: echo "$HOME/.local/bin" >> $GITHUB_PATH
60+
61+
- name: Get poetry cache paths from config
62+
run: |
63+
echo "poetry_virtualenvs_path=$(poetry config --list | sed -n 's/.*virtualenvs.path = .* # //p' | sed -e 's/^\"//' -e 's/\"$//')" >> $GITHUB_ENV
64+
echo "poetry_virtualenvs_path=$(poetry config --list | sed -n 's/.*virtualenvs.path = .* # //p' | sed -e 's/^\"//' -e 's/\"$//')" >> $GITHUB_ENV
65+
66+
- name: Configure poetry
67+
shell: bash
68+
run: poetry config virtualenvs.in-project true
69+
70+
- name: Set up cache
71+
uses: actions/cache@v2
72+
id: cache
73+
with:
74+
path: |
75+
.venv
76+
{{ env.poetry_cache_dir }}
77+
{{ env.poetry_virtualenvs_path }}
78+
key: venv-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('**/poetry.lock') }}
79+
80+
- name: Ensure cache is healthy
81+
if: steps.cache.outputs.cache-hit == 'true'
82+
shell: bash
83+
run: poetry run pip --version >/dev/null 2>&1 || rm -rf .venv
84+
85+
- name: Upgrade pip
86+
shell: bash
87+
run: poetry run python -m pip install pip -U
88+
89+
- name: Install dependencies [w/ docs]
90+
run: poetry install --extras "docs lint"
91+
92+
- name: Build documentation
93+
run: |
94+
pushd docs; make SPHINXBUILD='poetry run sphinx-build' html; popd
95+
96+
- name: Push documentation to S3
97+
uses: jakejarvis/s3-sync-action@v0.5.1
98+
with:
99+
args: --acl public-read --follow-symlinks --delete
100+
env:
101+
AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }}
102+
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
103+
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
104+
AWS_REGION: "us-west-1" # optional: defaults to us-east-1
105+
SOURCE_DIR: "docs/_build/html" # optional: defaults to entire repository
106+
107+
- name: Generate list of changed files for CloudFront to invalidate
108+
run: |
109+
FILES=$(find docs/_build/html -exec realpath --relative-to docs/_build/html {} \; | awk '{print "/"$0}' | grep "html\|searchindex.js");
110+
for file in $FILES; do
111+
echo $file
112+
# add bare directory to list of updated paths when we see index.html
113+
[[ "$file" == *"/index.html" ]] && echo $file | sed -e 's/\/index.html$/\//'
114+
done | sort | uniq | tr '\n' ' ' > .updated_files
115+
116+
- name: Invalidate on CloudFront
117+
uses: chetan/invalidate-cloudfront-action@master
118+
env:
119+
DISTRIBUTION: ${{ secrets.AWS_CLOUDFRONT_DISTRIBUTION }}
120+
AWS_REGION: "us-east-1"
121+
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
122+
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
123+
PATHS_FROM: .updated_files
124+
125+
- name: Purge cache on Cloudflare
126+
uses: jakejarvis/cloudflare-purge-action@master
127+
env:
128+
CLOUDFLARE_TOKEN: ${{ secrets.CLOUDFLARE_TOKEN }}
129+
CLOUDFLARE_ZONE: ${{ secrets.CLOUDFLARE_ZONE }}

‎.github/workflows/tests.yml

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
name: tests
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
build:
7+
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
8+
9+
runs-on: ubuntu-latest
10+
strategy:
11+
matrix:
12+
python-version: ["3.7", "3.10"]
13+
steps:
14+
- uses: actions/checkout@v1
15+
- name: Configure git
16+
run: |
17+
git config --global user.name 'travis-ci'
18+
git config --global user.email 'travis@nowhere.edu'
19+
- name: Set up Python ${{ matrix.python-version }}
20+
uses: actions/setup-python@v1
21+
with:
22+
python-version: ${{ matrix.python-version }}
23+
24+
- name: Get full Python version
25+
id: full-python-version
26+
shell: bash
27+
run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))")
28+
29+
- name: Install poetry
30+
run: |
31+
curl -O -sSL https://install.python-poetry.org/install-poetry.py
32+
python install-poetry.py -y --version 1.1.12
33+
echo "PATH=${HOME}/.poetry/bin:${PATH}" >> $GITHUB_ENV
34+
rm install-poetry.py
35+
36+
- name: Add ~/.local/bin to PATH
37+
run: echo "$HOME/.local/bin" >> $GITHUB_PATH
38+
39+
- name: Get poetry cache paths from config
40+
run: |
41+
echo "poetry_virtualenvs_path=$(poetry config --list | sed -n 's/.*virtualenvs.path = .* # //p' | sed -e 's/^\"//' -e 's/\"$//')" >> $GITHUB_ENV
42+
echo "poetry_virtualenvs_path=$(poetry config --list | sed -n 's/.*virtualenvs.path = .* # //p' | sed -e 's/^\"//' -e 's/\"$//')" >> $GITHUB_ENV
43+
44+
- name: Configure poetry
45+
shell: bash
46+
run: poetry config virtualenvs.in-project true
47+
48+
- name: Set up cache
49+
uses: actions/cache@v2
50+
id: cache
51+
with:
52+
path: |
53+
.venv
54+
${{ env.poetry_cache_dir }}
55+
${{ env.poetry_virtualenvs_path }}
56+
key: venv-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('**/poetry.lock') }}
57+
58+
- name: Ensure cache is healthy
59+
if: steps.cache.outputs.cache-hit == 'true'
60+
shell: bash
61+
run: poetry run pip --version >/dev/null 2>&1 || rm -rf .venv
62+
63+
- name: Upgrade pip
64+
shell: bash
65+
run: poetry run python -m pip install pip -U
66+
67+
- name: Install dependencies
68+
run: poetry install -E "docs test coverage lint format"
69+
70+
- name: Lint with flake8
71+
run: poetry run flake8
72+
73+
- name: Test with pytest
74+
run: poetry run py.test --cov=./ --cov-report=xml
75+
76+
- uses: codecov/codecov-action@v1
77+
with:
78+
token: ${{ secrets.CODECOV_TOKEN }}

‎.gitignore

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# macOS
2+
.DS_Store
3+
4+
# Byte-compiled / optimized / DLL files
5+
__pycache__/
6+
*.py[cod]
7+
*$py.class
8+
9+
# C extensions
10+
*.so
11+
12+
# Distribution / packaging
13+
.Python
14+
*env*/
15+
build/
16+
develop-eggs/
17+
dist/
18+
downloads/
19+
eggs/
20+
.eggs/
21+
lib/
22+
lib64/
23+
parts/
24+
sdist/
25+
var/
26+
*.egg-info/
27+
.installed.cfg
28+
*.egg
29+
30+
# PyInstaller
31+
# Usually these files are written by a python script from a template
32+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
33+
*.manifest
34+
*.spec
35+
36+
# Installer logs
37+
pip-log.txt
38+
pip-delete-this-directory.txt
39+
40+
# Unit test / coverage reports
41+
htmlcov/
42+
.tox/
43+
.coverage
44+
.coverage.*
45+
.cache
46+
nosetests.xml
47+
coverage.xml
48+
*.cover
49+
.hypothesis/
50+
.pytest_cache/
51+
52+
# Translations
53+
*.mo
54+
*.pot
55+
56+
# Django stuff:
57+
*.log
58+
59+
# Sphinx documentation
60+
docs/_build/
61+
62+
# PyBuilder
63+
target/
64+
65+
# ipython Notebook
66+
.ipynb_checkpoints
67+
68+
# editors
69+
.idea
70+
.ropeproject
71+
*.swp
72+
.vim/
73+
74+
# docs
75+
doc/_build/
76+
77+
*.lprof
78+
79+
pip-wheel-metadata/

‎.pre-commit-config.yaml

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
repos:
2+
- repo: https://github.com/psf/black
3+
rev: 22.1.0
4+
hooks:
5+
- id: black
6+
language_version: python3.10
7+
- repo: https://github.com/pycqa/isort
8+
rev: 5.10.1
9+
hooks:
10+
- id: isort
11+
name: isort (python)
12+
- repo: https://github.com/PyCQA/flake8
13+
rev: 4.0.1
14+
hooks:
15+
- id: flake8

‎.prettierrc

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"printWidth": 100
3+
}

‎.python-version

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.10.1 3.9.9 3.8.11 3.7.12

‎.tmuxp.yaml

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
session_name: g
2+
start_directory: ./ # load session relative to config location (project root).
3+
before_script: ./.tmuxp-before-script.sh
4+
shell_command_before:
5+
- '[ -f .venv/bin/activate ] && source .venv/bin/activate && reset'
6+
windows:
7+
- window_name: g
8+
focus: True
9+
layout: main-horizontal
10+
options:
11+
main-pane-height: 35
12+
panes:
13+
- focus: true
14+
- pane
15+
- make watch_test
16+
- window_name: docs
17+
layout: main-horizontal
18+
options:
19+
main-pane-height: 35
20+
start_directory: docs/
21+
panes:
22+
- focus: true
23+
- pane
24+
- pane
25+
- make start

‎.tool-versions

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
poetry 1.1.12
2+
python 3.10.1 3.9.9 3.8.11 3.7.12

‎CHANGES

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Changelog
2+
3+
## current
4+
5+
- _Add your latest changes from PRs here_
6+
7+
## g 0.0.0 (2022-02-26)
8+
9+
### Compatibility
10+
11+
-
12+
13+
### Documentation
14+
15+
- sphinx, furo theme, sphinx-autobuild
16+
17+
### Development
18+
19+
- Setup CI, codecov, cloudfront, s3
20+
21+
.. vim: set filetype=markdown:

‎LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2022 python utilities for version control
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

‎Makefile

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
PY_FILES= find . -type f -not -path '*/\.*' | grep -i '.*[.]py$$' 2> /dev/null
2+
DOC_FILES= find . -type f -not -path '*/\.*' | grep -i '.*[.]rst\$\|.*[.]md\$\|.*[.]css\$\|.*[.]py\$\|mkdocs\.yml\|CHANGES\|TODO\|.*conf\.py' 2> /dev/null
3+
SHELL := /bin/bash
4+
5+
6+
entr_warn:
7+
@echo "----------------------------------------------------------"
8+
@echo " ! File watching functionality non-operational ! "
9+
@echo " "
10+
@echo "Install entr(1) to automatically run tasks on file change."
11+
@echo "See http://entrproject.org/ "
12+
@echo "----------------------------------------------------------"
13+
14+
isort:
15+
poetry run isort `${PY_FILES}`
16+
17+
black:
18+
poetry run black `${PY_FILES}`
19+
20+
test:
21+
poetry run py.test $(test)
22+
23+
start:
24+
poetry run ptw .
25+
26+
watch_test_entr:
27+
if command -v entr > /dev/null; then ${PY_FILES} | entr -c $(MAKE) test; else $(MAKE) test entr_warn; fi
28+
29+
build_docs:
30+
$(MAKE) -C docs html
31+
32+
start_docs:
33+
$(MAKE) -C docs start
34+
35+
flake8:
36+
flake8 g tests
37+
38+
watch_flake8:
39+
if command -v entr > /dev/null; then ${PY_FILES} | entr -c $(MAKE) flake8; else $(MAKE) flake8 entr_warn; fi
40+
41+
format_markdown:
42+
prettier --parser=markdown -w *.md docs/*.md docs/**/*.md CHANGES

‎README.md

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
`g` - passthrough to your current directories vcs (or reach with --cwd)
2+
3+
[![Python Package](https://img.shields.io/pypi/v/g.svg)](http://badge.fury.io/py/g)
4+
[![Docs](https://github.com/vcs-python/g/workflows/Publish%20Docs/badge.svg)](https://github.com/vcs-python/g/actions?query=workflow%3A%22Publish+Docs%22)
5+
[![Build Status](https://github.com/vcs-python/g/workflows/tests/badge.svg)](https://github.com/vcs-python/g/actions?query=workflow%3A%22tests%22)
6+
[![Code Coverage](https://codecov.io/gh/vcs-python/g/branch/master/graph/badge.svg)](https://codecov.io/gh/vcs-python/g)
7+
![License](https://img.shields.io/github/license/vcs-python/g.svg)
8+
9+
Shortcut / powertool for developers to access current repos' vcs, whether it's
10+
svn, hg, mercurial.
11+
12+
```sh
13+
$ pip install --user g
14+
```
15+
16+
```sh
17+
$ g
18+
```
19+
20+
# Credits
21+
22+
2021-12-05: Thanks to [John Shanahan](https://github.com/shanahanjrs) ([@_shanahanjrs](https://twitter.com/_shanahanjrs)) for giving g use [g](https://pypi.org/project/g/)
23+
24+
# Donations
25+
26+
Your donations fund development of new features, testing and support.
27+
Your money will go directly to maintenance and development of the
28+
project. If you are an individual, feel free to give whatever feels
29+
right for the value you get out of the project.
30+
31+
See donation options at <https://git-pull.com/support.html>.
32+
33+
# More information
34+
35+
- Python support: >= 3.7, pypy
36+
- VCS supported: git(1), svn(1), hg(1)
37+
- Source: <https://github.com/vcs-python/g>
38+
- Docs: <https://g.git-pull.com>
39+
- Changelog: <https://g.git-pull.com/history.html>
40+
- API: <https://g.git-pull.com/api.html>
41+
- Issues: <https://github.com/vcs-python/g/issues>
42+
- Test Coverage: <https://codecov.io/gh/vcs-python/g>
43+
- pypi: <https://pypi.python.org/pypi/g>
44+
- Open Hub: <https://www.openhub.net/p/g>
45+
- License: [MIT](https://opensource.org/licenses/MIT).

‎docs/Makefile

+180
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
# Makefile for Sphinx documentation
2+
#
3+
SHELL := /bin/bash
4+
HTTP_PORT = 8034
5+
WATCH_FILES= find .. -type f -not -path '*/\.*' | grep -i '.*[.]\(rst\|md\)\$\|.*[.]py\$\|CHANGES\|TODO\|.*conf\.py' 2> /dev/null
6+
7+
# You can set these variables from the command line.
8+
SPHINXOPTS =
9+
SPHINXBUILD = sphinx-build
10+
PAPER =
11+
BUILDDIR = _build
12+
13+
# Internal variables.
14+
PAPEROPT_a4 = -D latex_paper_size=a4
15+
PAPEROPT_letter = -D latex_paper_size=letter
16+
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
17+
# the i18n builder cannot share the environment and doctrees with the others
18+
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
19+
20+
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
21+
22+
help:
23+
@echo "Please use \`make <target>' where <target> is one of"
24+
@echo " html to make standalone HTML files"
25+
@echo " dirhtml to make HTML files named index.html in directories"
26+
@echo " singlehtml to make a single large HTML file"
27+
@echo " pickle to make pickle files"
28+
@echo " json to make JSON files"
29+
@echo " htmlhelp to make HTML files and a HTML help project"
30+
@echo " qthelp to make HTML files and a qthelp project"
31+
@echo " devhelp to make HTML files and a Devhelp project"
32+
@echo " epub to make an epub"
33+
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
34+
@echo " latexpdf to make LaTeX files and run them through pdflatex"
35+
@echo " text to make text files"
36+
@echo " man to make manual pages"
37+
@echo " texinfo to make Texinfo files"
38+
@echo " info to make Texinfo files and run them through makeinfo"
39+
@echo " gettext to make PO message catalogs"
40+
@echo " changes to make an overview of all changed/added/deprecated items"
41+
@echo " linkcheck to check all external links for integrity"
42+
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
43+
44+
clean:
45+
-rm -rf $(BUILDDIR)/*
46+
47+
html:
48+
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
49+
@echo
50+
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
51+
52+
dirhtml:
53+
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
54+
@echo
55+
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
56+
57+
singlehtml:
58+
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
59+
@echo
60+
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
61+
62+
pickle:
63+
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
64+
@echo
65+
@echo "Build finished; now you can process the pickle files."
66+
67+
json:
68+
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
69+
@echo
70+
@echo "Build finished; now you can process the JSON files."
71+
72+
htmlhelp:
73+
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
74+
@echo
75+
@echo "Build finished; now you can run HTML Help Workshop with the" \
76+
".hhp project file in $(BUILDDIR)/htmlhelp."
77+
78+
qthelp:
79+
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
80+
@echo
81+
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
82+
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
83+
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/g.qhcp"
84+
@echo "To view the help file:"
85+
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/g.qhc"
86+
87+
devhelp:
88+
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
89+
@echo
90+
@echo "Build finished."
91+
@echo "To view the help file:"
92+
@echo "# mkdir -p $$HOME/.local/share/devhelp/g"
93+
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/g"
94+
@echo "# devhelp"
95+
96+
epub:
97+
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
98+
@echo
99+
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
100+
101+
latex:
102+
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
103+
@echo
104+
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
105+
@echo "Run \`make' in that directory to run these through (pdf)latex" \
106+
"(use \`make latexpdf' here to do that automatically)."
107+
108+
latexpdf:
109+
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
110+
@echo "Running LaTeX files through pdflatex..."
111+
$(MAKE) -C $(BUILDDIR)/latex all-pdf
112+
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
113+
114+
text:
115+
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
116+
@echo
117+
@echo "Build finished. The text files are in $(BUILDDIR)/text."
118+
119+
man:
120+
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
121+
@echo
122+
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
123+
124+
texinfo:
125+
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
126+
@echo
127+
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
128+
@echo "Run \`make' in that directory to run these through makeinfo" \
129+
"(use \`make info' here to do that automatically)."
130+
131+
info:
132+
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
133+
@echo "Running Texinfo files through makeinfo..."
134+
make -C $(BUILDDIR)/texinfo info
135+
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
136+
137+
gettext:
138+
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
139+
@echo
140+
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
141+
142+
changes:
143+
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
144+
@echo
145+
@echo "The overview file is in $(BUILDDIR)/changes."
146+
147+
linkcheck:
148+
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
149+
@echo
150+
@echo "Link check complete; look for any errors in the above output " \
151+
"or in $(BUILDDIR)/linkcheck/output.txt."
152+
153+
doctest:
154+
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
155+
@echo "Testing of doctests in the sources finished, look at the " \
156+
"results in $(BUILDDIR)/doctest/output.txt."
157+
158+
checkbuild:
159+
rm -rf $(BUILDDIR)
160+
$(SPHINXBUILD) -n -q ./ $(BUILDDIR)
161+
162+
watch:
163+
if command -v entr > /dev/null; then ${WATCH_FILES} | entr -c $(MAKE) html; else $(MAKE) html; fi
164+
165+
serve:
166+
@echo '================================================='
167+
@echo
168+
@echo 'docs server running at http://localhost:${HTTP_PORT}/'
169+
@echo
170+
@echo '================================================='
171+
@$(MAKE) serve_py3
172+
173+
serve_py3:
174+
python -m http.server ${HTTP_PORT} --directory _build/html
175+
176+
dev:
177+
$(MAKE) -j watch serve
178+
179+
start:
180+
poetry run sphinx-autobuild "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) --port ${HTTP_PORT} $(O)

‎docs/_static/favicon.ico

18.2 KB
Binary file not shown.

‎docs/_static/img/g-dark.svg

+1
Loading

‎docs/_static/img/g.svg

+1
Loading
9.53 KB
Loading
10.9 KB
Loading
11.6 KB
Loading
15.2 KB
Loading
33.5 KB
Loading
56.4 KB
Loading

‎docs/_static/img/icons/icon-72x72.png

5.15 KB
Loading

‎docs/_static/img/icons/icon-96x96.png

6.96 KB
Loading

‎docs/_static/vcspull-screenshot.png

315 KB
Loading

‎docs/_templates/layout.html

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{% extends "!layout.html" %}
2+
{%- block extrahead %}
3+
{{ super() }}
4+
{%- if theme_show_meta_manifest_tag == true %}
5+
<link rel="manifest" href="/manifest.json">
6+
{% endif -%}
7+
{%- if theme_show_meta_og_tags == true %}
8+
<meta name="description" content="{{ theme_project_description }}">
9+
10+
<!-- Open Graph / Facebook -->
11+
<meta property="og:type" content="website">
12+
<meta property="og:url" content="{{ theme_project_url }}/">
13+
<meta property="og:title" content="{{ theme_project_title }}">
14+
<meta property="og:description" content="{{ theme_project_description }}">
15+
<meta property="og:image" itemprop="image" content="{{ theme_project_url }}/_static/img/icons/icon-192x192.png">
16+
17+
<!-- Twitter -->
18+
<meta property="twitter:card" content="summary_large_image">
19+
<meta property="twitter:url" content="{{ theme_project_url }} ">
20+
<meta property="twitter:title" content="{{ theme_project_title }}">
21+
<meta property="twitter:description" content="{{ theme_project_description }}">
22+
<meta property="twitter:image" content="{{ theme_project_url }}/_static/img/icons/icon-512x512.png">
23+
{% endif -%}
24+
{%- if theme_show_meta_app_icon_tags == true %}
25+
<meta name="theme-color" content="#ffffff">
26+
<meta name="application-name" content="{{ theme_project_name }}">
27+
28+
<link rel="shortcut icon" href="/_static/favicon.ico">
29+
<link rel="icon" type="image/png" sizes="512x512" href="/_static/img/icons/icon-512x512.png">
30+
<link rel="icon" type="image/png" sizes="192x192" href="/_static/img/icons/icon-192x192.png">
31+
<link rel="icon" type="image/png" sizes="32x32" href="/_static/img/icons/icon-32x32.png">
32+
<link rel="icon" type="image/png" sizes="96x96" href="/_static/img/icons/icon-96x96.png">
33+
<link rel="icon" type="image/png" sizes="16x16" href="/_static/img/icons/icon-16x16.png">
34+
35+
<!-- Apple -->
36+
<meta name="apple-mobile-web-app-title" content="{{ theme_project_name }}">
37+
38+
<link rel="apple-touch-icon" sizes="192x192" href="/_static/img/icons/icon-192x192.png">
39+
<link rel="mask-icon" href="/_static/img/g.svg" color="grey">
40+
41+
<!-- Microsoft -->
42+
<meta name="msapplication-TileColor" content="#ffffff">
43+
<meta name="msapplication-TileImage" content="/_static/img/icons/ms-icon-144x144.png">
44+
{% endif -%}
45+
{% endblock %}

‎docs/conf.py

+196
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
# flake8: noqa E501
2+
import os
3+
4+
# Get the project root dir, which is the parent dir of this
5+
cwd = os.getcwd()
6+
project_root = os.path.dirname(cwd)
7+
8+
# package data
9+
about = {}
10+
with open("../g/__about__.py") as fp:
11+
exec(fp.read(), about)
12+
13+
extensions = [
14+
"sphinx.ext.autodoc",
15+
"sphinx.ext.intersphinx",
16+
"sphinx_autodoc_typehints",
17+
"sphinx.ext.todo",
18+
"sphinx.ext.napoleon",
19+
"sphinx.ext.linkcode",
20+
"sphinx_issues",
21+
"myst_parser",
22+
]
23+
24+
# app setup hook
25+
def setup(app):
26+
pass
27+
28+
29+
myst_enable_extensions = ["substitution", "replacements"]
30+
31+
32+
issues_github_path = about["__github__"].replace("https://github.com/", "")
33+
templates_path = ["_templates"]
34+
35+
source_suffix = {".rst": "restructuredtext", ".md": "markdown"}
36+
37+
master_doc = "index"
38+
39+
project = about["__title__"]
40+
copyright = about["__copyright__"]
41+
42+
version = "%s" % (".".join(about["__version__"].split("."))[:2])
43+
release = "%s" % (about["__version__"])
44+
45+
exclude_patterns = ["_build"]
46+
47+
pygments_style = "monokai"
48+
pygments_dark_style = "monokai"
49+
50+
html_favicon = "_static/favicon.ico"
51+
html_theme_path = []
52+
html_theme = "furo"
53+
html_theme_options = {
54+
"light_logo": "img/g.svg",
55+
"dark_logo": "img/g-dark.svg",
56+
"footer_icons": [
57+
{
58+
"name": "GitHub",
59+
"url": "https://github.com/vcs-python/g",
60+
"html": """
61+
<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 16 16">
62+
<path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path>
63+
</svg>
64+
""",
65+
"class": "",
66+
},
67+
],
68+
}
69+
html_sidebars = {
70+
"**": [
71+
"sidebar/scroll-start.html",
72+
"sidebar/brand.html",
73+
"sidebar/search.html",
74+
"sidebar/navigation.html",
75+
"sidebar/scroll-end.html",
76+
]
77+
}
78+
79+
html_static_path = ["_static"]
80+
html_extra_path = ["manifest.json"]
81+
82+
htmlhelp_basename = "%sdoc" % about["__title__"]
83+
84+
latex_documents = [
85+
(
86+
"index",
87+
"{0}.tex".format(about["__package_name__"]),
88+
"{0} Documentation".format(about["__title__"]),
89+
about["__author__"],
90+
"manual",
91+
)
92+
]
93+
94+
man_pages = [
95+
(
96+
"index",
97+
about["__package_name__"],
98+
"{0} Documentation".format(about["__title__"]),
99+
about["__author__"],
100+
1,
101+
)
102+
]
103+
104+
texinfo_documents = [
105+
(
106+
"index",
107+
"{0}".format(about["__package_name__"]),
108+
"{0} Documentation".format(about["__title__"]),
109+
about["__author__"],
110+
about["__package_name__"],
111+
about["__description__"],
112+
"Miscellaneous",
113+
)
114+
]
115+
116+
intersphinx_mapping = {
117+
"py": ("https://docs.python.org/", None),
118+
"libvcs": ("http://libvcs.git-pull.com/", None),
119+
}
120+
121+
122+
def linkcode_resolve(domain, info): # NOQA: C901
123+
import inspect
124+
import sys
125+
from os.path import dirname, relpath
126+
127+
import g
128+
129+
"""
130+
Determine the URL corresponding to Python object
131+
132+
Notes
133+
-----
134+
From https://github.com/numpy/numpy/blob/v1.15.1/doc/source/conf.py, 7c49cfa
135+
on Jul 31. License BSD-3. https://github.com/numpy/numpy/blob/v1.15.1/LICENSE.txt
136+
"""
137+
if domain != "py":
138+
return None
139+
140+
modname = info["module"]
141+
fullname = info["fullname"]
142+
143+
submod = sys.modules.get(modname)
144+
if submod is None:
145+
return None
146+
147+
obj = submod
148+
for part in fullname.split("."):
149+
try:
150+
obj = getattr(obj, part)
151+
except Exception:
152+
return None
153+
154+
# strip decorators, which would resolve to the source of the decorator
155+
# possibly an upstream bug in getsourcefile, bpo-1764286
156+
try:
157+
unwrap = inspect.unwrap
158+
except AttributeError:
159+
pass
160+
else:
161+
obj = unwrap(obj)
162+
163+
try:
164+
fn = inspect.getsourcefile(obj)
165+
except Exception:
166+
fn = None
167+
if not fn:
168+
return None
169+
170+
try:
171+
source, lineno = inspect.getsourcelines(obj)
172+
except Exception:
173+
lineno = None
174+
175+
if lineno:
176+
linespec = "#L%d-L%d" % (lineno, lineno + len(source) - 1)
177+
else:
178+
linespec = ""
179+
180+
fn = relpath(fn, start=dirname(g.__file__))
181+
182+
if "dev" in about["__version__"]:
183+
return "%s/blob/master/%s/%s%s" % (
184+
about["__github__"],
185+
about["__package_name__"],
186+
fn,
187+
linespec,
188+
)
189+
else:
190+
return "%s/blob/v%s/%s/%s%s" % (
191+
about["__github__"],
192+
about["__version__"],
193+
about["__package_name__"],
194+
fn,
195+
linespec,
196+
)

‎docs/developing.md

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Development
2+
3+
[poetry] is a required package to develop.
4+
5+
`git clone https://github.com/vcs-python/g.git`
6+
7+
`cd g`
8+
9+
`poetry install -E "docs test coverage lint format"`
10+
11+
Makefile commands prefixed with `watch_` will watch files and rerun.
12+
13+
## Tests
14+
15+
`poetry run py.test`
16+
17+
Helpers: `make test`
18+
19+
## Automatically run tests on file save
20+
21+
1. `make start` (via [pytest-watcher])
22+
2. `make watch_test` (requires installing [entr(1)])
23+
24+
[pytest-watcher]: https://github.com/olzhasar/pytest-watcher
25+
26+
## Documentation
27+
28+
Default preview server: http://localhost:8034
29+
30+
[sphinx-autobuild] will automatically build the docs, watch for file changes and launch a server.
31+
32+
From home directory: `make start_docs`
33+
From inside `docs/`: `make start`
34+
35+
[sphinx-autobuild]: https://github.com/executablebooks/sphinx-autobuild
36+
37+
### Manual documentation (the hard way)
38+
39+
`cd docs/` and `make html` to build. `make serve` to start http server.
40+
41+
Helpers:
42+
`make build_docs`, `make serve_docs`
43+
44+
Rebuild docs on file change: `make watch_docs` (requires [entr(1)])
45+
46+
Rebuild docs and run server via one terminal: `make dev_docs` (requires above, and a
47+
`make(1)` with `-J` support, e.g. GNU Make)
48+
49+
## Formatting / Linting
50+
51+
The project uses [black] and [isort] (one after the other) and runs [flake8] via
52+
CI. See the configuration in `pyproject.toml` and `setup.cfg`:
53+
54+
`make black isort`: Run `black` first, then `isort` to handle import nuances
55+
`make flake8`, to watch (requires `entr(1)`): `make watch_flake8`
56+
57+
## Releasing
58+
59+
As of 0.10, [poetry] handles virtualenv creation, package requirements, versioning,
60+
building, and publishing. Therefore there is no setup.py or requirements files.
61+
62+
Update `__version__` in `__about__.py` and `pyproject.toml`::
63+
64+
git commit -m 'build(g): Tag v0.1.1'
65+
git tag v0.1.1
66+
git push
67+
git push --tags
68+
poetry build
69+
poetry publish
70+
71+
[poetry]: https://python-poetry.org/
72+
[entr(1)]: http://eradman.com/entrproject/
73+
[black]: https://github.com/psf/black
74+
[isort]: https://pypi.org/project/isort/
75+
[flake8]: https://flake8.pycqa.org/

‎docs/history.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
(history)=
2+
3+
```{include} ../CHANGES
4+
5+
```

‎docs/index.md

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
(index)=
2+
3+
# g - access the vcs of current directory (or reach for it)
4+
5+
```{include} ../README.md
6+
7+
```
8+
9+
```{toctree}
10+
:maxdepth: 2
11+
12+
developing
13+
history
14+
15+
```

‎docs/manifest.json

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
{
2+
"name": "g",
3+
"short_name": "g",
4+
"description": "CLI proxy command to route your current directory's VCS",
5+
"theme_color": "#2196f3",
6+
"background_color": "#fff",
7+
"display": "browser",
8+
"Scope": "https://g.git-pull.com/",
9+
"start_url": "https://g.git-pull.com/",
10+
"icons": [
11+
{
12+
"src": "_static/img/icons/icon-72x72.png",
13+
"sizes": "72x72",
14+
"type": "image/png"
15+
},
16+
{
17+
"src": "_static/img/icons/icon-96x96.png",
18+
"sizes": "96x96",
19+
"type": "image/png"
20+
},
21+
{
22+
"src": "_static/img/icons/icon-128x128.png",
23+
"sizes": "128x128",
24+
"type": "image/png"
25+
},
26+
{
27+
"src": "_static/img/icons/icon-144x144.png",
28+
"sizes": "144x144",
29+
"type": "image/png"
30+
},
31+
{
32+
"src": "_static/img/icons/icon-152x152.png",
33+
"sizes": "152x152",
34+
"type": "image/png"
35+
},
36+
{
37+
"src": "_static/img/icons/icon-192x192.png",
38+
"sizes": "192x192",
39+
"type": "image/png"
40+
},
41+
{
42+
"src": "_static/img/icons/icon-384x384.png",
43+
"sizes": "384x384",
44+
"type": "image/png"
45+
},
46+
{
47+
"src": "_static/img/icons/icon-512x512.png",
48+
"sizes": "512x512",
49+
"type": "image/png"
50+
}
51+
],
52+
"splash_pages": null
53+
}

‎g/__about__.py

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
__title__ = "g"
2+
__package_name__ = "g"
3+
__description__ = "cli shortcut for directory's vcs command: git, svn, hg"
4+
__version__ = "0.0.0a0"
5+
__author__ = "Tony Narlock"
6+
__github__ = "https://github.com/vcs-python/g"
7+
__docs__ = "https://g.git-pull.com"
8+
__tracker__ = "https://github.com/vcs-python/g/issues"
9+
__pypi__ = "https://pypi.org/project/g/"
10+
__email__ = "tony@git-pull.com"
11+
__license__ = "MIT"
12+
__copyright__ = "Copyright 2022- Tony Narlock"

‎g/__init__.py

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#!/usr/bin/env python
2+
3+
import pathlib
4+
import subprocess
5+
import sys
6+
7+
vcspath_registry = {".git": "git", ".svn": "svn", ".hg": "hg"}
8+
9+
10+
def find_repo_type(path):
11+
for path in list(pathlib.Path(path).parents) + [pathlib.Path(path)]:
12+
for p in path.iterdir():
13+
if p.is_dir():
14+
if p.name in vcspath_registry:
15+
return vcspath_registry[p.name]
16+
17+
18+
DEFAULT = object()
19+
20+
21+
def run(cmd=DEFAULT, cmd_args=DEFAULT, *args, **kwargs):
22+
# Interpret default kwargs lazily for mockability of argv
23+
if cmd is DEFAULT:
24+
cmd = find_repo_type(pathlib.Path.cwd())
25+
if cmd_args is DEFAULT:
26+
cmd_args = sys.argv[1:]
27+
proc = subprocess.Popen([cmd, *cmd_args])
28+
proc.communicate()
29+
if __name__ != "__main__":
30+
return proc
31+
32+
33+
if __name__ == "__main__":
34+
run()

‎poetry.lock

+1,259
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎pyproject.toml

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
[tool.poetry]
2+
name = "g"
3+
version = "0.0.0a0"
4+
description = "cli command to easily sync current directory"
5+
license = "MIT"
6+
authors = ["Tony Narlock <tony@git-pull.com>"]
7+
classifiers = [
8+
"Development Status :: 4 - Beta",
9+
"License :: OSI Approved :: MIT License",
10+
"Environment :: Web Environment",
11+
"Intended Audience :: Developers",
12+
"Operating System :: POSIX",
13+
"Operating System :: MacOS :: MacOS X",
14+
"Programming Language :: Python",
15+
"Programming Language :: Python :: 3",
16+
"Programming Language :: Python :: 3.7",
17+
"Programming Language :: Python :: 3.8",
18+
"Programming Language :: Python :: 3.9",
19+
"Programming Language :: Python :: 3.10",
20+
"Topic :: Utilities",
21+
"Topic :: System :: Shells"
22+
]
23+
packages = [
24+
{ include = "g" },
25+
]
26+
include = [
27+
{ path = "tests", format = "sdist" },
28+
]
29+
readme = 'README.md'
30+
keywords = ["g", "git", "vcs", "svn", "g", "mercurial", "cli", "sync", "pull", "update", "libvcs"]
31+
32+
homepage = "https://g.git-pull.com"
33+
34+
[tool.poetry.urls]
35+
"Bug Tracker" = "https://github.com/vcs-python/g/issues"
36+
Documentation = "https://g.git-pull.com"
37+
Repository = "https://github.com/vcs-python/g"
38+
Changes = "https://github.com/vcs-python/g/blob/master/CHANGES"
39+
40+
[tool.poetry.scripts]
41+
g = 'g:run'
42+
43+
[tool.poetry.dependencies]
44+
python = "^3.7"
45+
46+
[tool.poetry.dev-dependencies]
47+
### Docs ###
48+
sphinx = "*"
49+
furo = "^2022.2.23"
50+
sphinx-issues = "^3.0.0"
51+
sphinx-autodoc-typehints = "~1.17.0"
52+
sphinx-autobuild = "^2021.3.14"
53+
myst_parser = "~0.17.0"
54+
55+
### Testing ###
56+
pytest = "*"
57+
pytest-rerunfailures = "*"
58+
pytest-watcher = "^0.2.3"
59+
60+
### Coverage ###
61+
codecov = "*"
62+
coverage = "*"
63+
pytest-cov = "*"
64+
65+
### Format ###
66+
black = "*"
67+
isort = "*"
68+
69+
### Lint ###
70+
flake8 = "*"
71+
72+
[tool.poetry.extras]
73+
docs = ["sphinx", "sphinx-issues", "sphinx-autodoc-typehints", "myst_parser", "sphinx-autobuild", "furo"]
74+
test = ["pytest", "pytest-rerunfailures", "pytest-watcher"]
75+
coverage = ["codecov", "coverage", "pytest-cov"]
76+
format = ["black", "isort"]
77+
lint = ["flake8"]
78+
79+
[build-system]
80+
requires = ["poetry_core>=1.0.0", "setuptools>60"]
81+
build-backend = "poetry.core.masonry.api"

‎setup.cfg

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
[flake8]
2+
exclude = .*/,.tox,*.egg,g/_compat.py,g/__*__.py,
3+
select = E,W,F,N
4+
max-line-length = 88
5+
# Stuff we ignore thanks to black: https://github.com/ambv/black/issues/429
6+
ignore = E111,
7+
E121,
8+
E122,
9+
E123,
10+
E124,
11+
E125,
12+
E126,
13+
E201,
14+
E202,
15+
E203,
16+
E221,
17+
E222,
18+
E225,
19+
E226,
20+
E227,
21+
E231,
22+
E241,
23+
E251,
24+
E261,
25+
E262,
26+
E265,
27+
E271,
28+
E272,
29+
E302,
30+
E303,
31+
E306,
32+
E502,
33+
E701,
34+
E702,
35+
E703,
36+
E704,
37+
W291,
38+
W292,
39+
W293,
40+
W391,
41+
W503
42+
43+
[isort]
44+
combine_as_imports= true
45+
default_section = THIRDPARTY
46+
include_trailing_comma = true
47+
multi_line_output = 3
48+
known_pytest = pytest,py
49+
known_first_party = g
50+
sections = FUTURE,STDLIB,PYTEST,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
51+
line_length = 88

‎tests/test_cli.py

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import subprocess
2+
from unittest.mock import patch
3+
4+
import pytest
5+
6+
from g import run
7+
8+
9+
def get_output(*args, **kwargs):
10+
try:
11+
result = subprocess.check_output(*args, **kwargs)
12+
return result
13+
except subprocess.CalledProcessError as exc:
14+
return exc.output
15+
16+
17+
@pytest.mark.parametrize(
18+
"argv_args,expect_cmd",
19+
[
20+
(["g"], "git"),
21+
(["g", "--help"], "git --help"),
22+
],
23+
)
24+
def test_command_line(capsys, argv_args, expect_cmd):
25+
from g import sys as gsys
26+
27+
with patch.object(gsys, "argv", argv_args):
28+
run(stdout=subprocess.STDOUT, stderr=subprocess.STDOUT)
29+
captured = capsys.readouterr().out
30+
with capsys.disabled():
31+
assert captured == get_output(expect_cmd, shell=True, stderr=subprocess.STDOUT)

0 commit comments

Comments
 (0)
Please sign in to comment.