Push first version
This commit is contained in:
1
MANIFEST.in
Normal file
1
MANIFEST.in
Normal file
@@ -0,0 +1 @@
|
|||||||
|
recursive-include completions *
|
||||||
121
README.md
Normal file
121
README.md
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
# GenPass
|
||||||
|
|
||||||
|
**Secure password generator CLI** written in Python.
|
||||||
|
Generate strong, random passwords from the command line with customizable character sets.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Specify password length and quantity
|
||||||
|
- Include/exclude:
|
||||||
|
- Lowercase letters (`--lower`)
|
||||||
|
- Uppercase letters (`--upper`)
|
||||||
|
- Digits (`--digits`)
|
||||||
|
- Symbols (`--symbols`)
|
||||||
|
- Optional custom symbol set (`--symbol-set`)
|
||||||
|
- Ensure at least one character from each selected type (can be disabled with `--no-ensure`)
|
||||||
|
- Shell completions for **bash**, **zsh**, and **fish**
|
||||||
|
- Easy installation via **pipx** or local script
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### 1. Via pipx (recommended)
|
||||||
|
```bash
|
||||||
|
pipx install git+https://github.com/yourusername/genpass
|
||||||
|
````
|
||||||
|
|
||||||
|
### 2. Local installation
|
||||||
|
|
||||||
|
Clone the repo and run the install script:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/yourusername/genpass.git
|
||||||
|
cd genpass
|
||||||
|
./install.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
This will also set up shell completions for bash, zsh, and fish.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Generate a single password (default 16 characters):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
genpass --lower --upper --digits --symbols
|
||||||
|
```
|
||||||
|
|
||||||
|
Generate 5 passwords of length 20:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
genpass -l 20 -n 5 --lower --upper --digits --symbols
|
||||||
|
```
|
||||||
|
|
||||||
|
Use a custom symbol set:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
genpass --symbols --symbol-set "!@#%&"
|
||||||
|
```
|
||||||
|
|
||||||
|
Disable "ensure each type" rule:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
genpass --lower --upper --digits --no-ensure
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Shell Completion
|
||||||
|
|
||||||
|
After installation, completions are automatically copied to your shell folders.
|
||||||
|
Restart your shell or source the completion files manually:
|
||||||
|
|
||||||
|
**Bash**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
source ~/.local/share/bash-completion/completions/genpass
|
||||||
|
```
|
||||||
|
|
||||||
|
**Zsh**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
source ~/.local/share/zsh/site-functions/_genpass
|
||||||
|
```
|
||||||
|
|
||||||
|
**Fish**
|
||||||
|
|
||||||
|
```fish
|
||||||
|
source ~/.local/share/fish/vendor_completions.d/genpass.fish
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
1. Install in editable mode for development:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pipx install --editable .
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Make changes in `genpass/cli.py` and test immediately.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
Contributions are welcome! Please fork the repo and submit pull requests.
|
||||||
|
Ensure code follows PEP8 style and add shell completion tests if applicable.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This project is licensed under the **MIT License** – see the [LICENSE](LICENSE) file for details.
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
7
completions/genpass.bash
Normal file
7
completions/genpass.bash
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
_genpass() {
|
||||||
|
local cur opts
|
||||||
|
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||||
|
opts="--help -l --length -n --count --lower --upper --digits --symbols --symbol-set --no-ensure"
|
||||||
|
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
|
||||||
|
}
|
||||||
|
complete -F _genpass genpass
|
||||||
8
completions/genpass.fish
Normal file
8
completions/genpass.fish
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
complete -c genpass -l length -s l -d "Password length"
|
||||||
|
complete -c genpass -l count -s n -d "Number of passwords"
|
||||||
|
complete -c genpass -l lower -d "Lowercase letters"
|
||||||
|
complete -c genpass -l upper -d "Uppercase letters"
|
||||||
|
complete -c genpass -l digits -d "Digits"
|
||||||
|
complete -c genpass -l symbols -d "Symbols"
|
||||||
|
complete -c genpass -l symbol-set -d "Custom symbol set"
|
||||||
|
complete -c genpass -l no-ensure -d "Disable character guarantees"
|
||||||
10
completions/genpass.zsh
Normal file
10
completions/genpass.zsh
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#compdef genpass
|
||||||
|
_arguments \
|
||||||
|
'--length[-l]:password length:' \
|
||||||
|
'--count[-n]:number of passwords:' \
|
||||||
|
'--lower[use lowercase letters]' \
|
||||||
|
'--upper[use uppercase letters]' \
|
||||||
|
'--digits[use digits]' \
|
||||||
|
'--symbols[use symbols]' \
|
||||||
|
'--symbol-set[custom symbol set]' \
|
||||||
|
'--no-ensure[do not enforce each type]'
|
||||||
0
genpass/__init__.py
Normal file
0
genpass/__init__.py
Normal file
47
genpass/cli.py
Normal file
47
genpass/cli.py
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import argparse
|
||||||
|
import secrets
|
||||||
|
import string
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def generate_password(length, pools, ensure_each=True):
|
||||||
|
if not pools:
|
||||||
|
raise ValueError("No character sets selected")
|
||||||
|
password = []
|
||||||
|
if ensure_each:
|
||||||
|
if length < len(pools):
|
||||||
|
raise ValueError("Password length too small")
|
||||||
|
for pool in pools:
|
||||||
|
password.append(secrets.choice(pool))
|
||||||
|
all_chars = "".join(pools)
|
||||||
|
while len(password) < length:
|
||||||
|
password.append(secrets.choice(all_chars))
|
||||||
|
secrets.SystemRandom().shuffle(password)
|
||||||
|
return "".join(password)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(prog="genpass", description="Secure password generator")
|
||||||
|
parser.add_argument("-l", "--length", type=int, default=16)
|
||||||
|
parser.add_argument("-n", "--count", type=int, default=1)
|
||||||
|
parser.add_argument("--lower", action="store_true")
|
||||||
|
parser.add_argument("--upper", action="store_true")
|
||||||
|
parser.add_argument("--digits", action="store_true")
|
||||||
|
parser.add_argument("--symbols", action="store_true")
|
||||||
|
parser.add_argument("--symbol-set", default="!@#$%^&*()-_=+[]{};:,.<>?")
|
||||||
|
parser.add_argument("--no-ensure", action="store_true")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
pools = []
|
||||||
|
if args.lower: pools.append(string.ascii_lowercase)
|
||||||
|
if args.upper: pools.append(string.ascii_uppercase)
|
||||||
|
if args.digits: pools.append(string.digits)
|
||||||
|
if args.symbols: pools.append(args.symbol_set)
|
||||||
|
|
||||||
|
if not pools:
|
||||||
|
print("Select at least one character set", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
for _ in range(args.count):
|
||||||
|
print(generate_password(args.length, pools, ensure_each=not args.no_ensure))
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
23
install.sh
Executable file
23
install.sh
Executable file
@@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if ! command -v pipx >/dev/null; then
|
||||||
|
echo "[!] pipx not found. Install it first:"
|
||||||
|
echo " python3 -m pip install --user pipx"
|
||||||
|
echo " pipx ensurepath"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
pipx install .
|
||||||
|
|
||||||
|
PREFIX="${XDG_DATA_HOME:-$HOME/.local/share}"
|
||||||
|
|
||||||
|
mkdir -p "$PREFIX/bash-completion/completions"
|
||||||
|
mkdir -p "$PREFIX/zsh/site-functions"
|
||||||
|
mkdir -p "$PREFIX/fish/vendor_completions.d"
|
||||||
|
|
||||||
|
cp completions/genpass.bash "$PREFIX/bash-completion/completions/genpass"
|
||||||
|
cp completions/genpass.zsh "$PREFIX/zsh/site-functions/_genpass"
|
||||||
|
cp completions/genpass.fish "$PREFIX/fish/vendor_completions.d/genpass.fish"
|
||||||
|
|
||||||
|
echo "[✓] Installation complete. Restart your shell."
|
||||||
14
pyproject.toml
Normal file
14
pyproject.toml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
[project]
|
||||||
|
name = "genpass"
|
||||||
|
version = "1.0.0"
|
||||||
|
description = "Secure password generator CLI"
|
||||||
|
authors = [{ name = "Ilya Kom" }]
|
||||||
|
readme = "README.md"
|
||||||
|
license = "MIT"
|
||||||
|
requires-python = ">= 3.8"
|
||||||
|
|
||||||
|
[project.scripts]
|
||||||
|
genpass = "genpass.cli:main"
|
||||||
|
|
||||||
|
[tool.setuptools]
|
||||||
|
packages = ["genpass"]
|
||||||
Reference in New Issue
Block a user