-
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.
Merge pull request #7 from thiagojacinto/dev
feat: version 0.1.1 🎉 - more tests and CI/CD config
- Loading branch information
Showing
14 changed files
with
445 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,40 @@ | ||
# This workflow will install Python dependencies, run tests and lint with a single version of Python | ||
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python | ||
|
||
name: Python application | ||
|
||
on: | ||
push: | ||
branches: [ "main", "dev" ] | ||
pull_request: | ||
branches: [ "main", "dev" ] | ||
|
||
permissions: | ||
contents: read | ||
|
||
jobs: | ||
build: | ||
|
||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- uses: actions/checkout@v3 | ||
- name: Set up Python 3.10.9 | ||
uses: actions/setup-python@v3 | ||
with: | ||
python-version: "3.10.9" | ||
- name: Install dependencies | ||
run: | | ||
python -m pip install --upgrade pip | ||
pip install flake8 pytest | ||
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi | ||
- name: Lint with flake8 | ||
run: | | ||
# stop the build if there are Python syntax errors or undefined names | ||
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics | ||
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide | ||
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics | ||
- name: Test with pytest | ||
run: | | ||
pytest | ||
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,40 @@ | ||
# This workflow will upload a Python Package using Twine when a release is created | ||
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries | ||
|
||
# This workflow uses actions that are not certified by GitHub. | ||
# They are provided by a third-party and are governed by | ||
# separate terms of service, privacy policy, and support | ||
# documentation. | ||
|
||
name: Upload Python Package | ||
|
||
on: | ||
release: | ||
types: [published] | ||
branches: [ "main" ] | ||
|
||
permissions: | ||
contents: read | ||
|
||
jobs: | ||
deploy: | ||
|
||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- uses: actions/checkout@v3 | ||
- name: Set up Python | ||
uses: actions/setup-python@v3 | ||
with: | ||
python-version: '3.x' | ||
- name: Install dependencies | ||
run: | | ||
python -m pip install --upgrade pip | ||
pip install build | ||
- name: Build package | ||
run: python -m build | ||
- name: Publish package | ||
uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 | ||
with: | ||
user: __token__ | ||
password: ${{ secrets.PYPI_API_TOKEN }} |
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,29 @@ | ||
# time-until-cli | ||
Application that calculate time duration until reach a given date. | ||
> Application that calculate time duration until reach a given date. | ||
**Main objective**: Understanding the logic of _Python_ app publishing and documenting it on a simple project. | ||
|
||
## Usage | ||
|
||
```bash | ||
time_until 22h | ||
``` | ||
|
||
## Application flow & use cases | ||
|
||
Using CLI to calculate time duration to a given input date or timestamp. | ||
|
||
| Input | Output / Response | | ||
| :---- | :---------------- | | ||
| `time-until 23h` | Time remaining: 8 hour(s) 22 minute(s) 42 second(s) | | ||
| `time-until 2023-02-27` | Time remaining: 04 month(s) 14 day(s) 8 hour(s) 22 minute(s) 42 second(s) | | ||
|
||
 | ||
|
||
## Main goals | ||
|
||
Build a Python app that works as a CLI (Command-line Interface) that receives a future date or time and returns a calculation of remaining time from now until that given date or time. | ||
|
||
Once working, this project must be configured and submitted as Python package thru PyPI Modules. The process of development, build, release and publishing is the core of the project, to understand it and provice ideas and thoghts of process automation. | ||
|
||
Feel free to initiate a discusison, open a issue or a pull request to this project. All kinds of contributions and ideas are welcome. **_Let's code!_** |
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 @@ | ||
<mxfile host="app.diagrams.net" modified="2023-02-26T13:07:53.290Z" agent="5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36" etag="bepQZm-S_8wZlN24tvgk" version="14.6.3" type="device"><diagram id="iOcOu5OnF31ByhzuMogO" name="Página-1">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</diagram></mxfile> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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,34 @@ | ||
[build-system] | ||
requires = ["setuptools>=61.0"] | ||
build-backend = "setuptools.build_meta" | ||
|
||
[project] | ||
name = "time_until" | ||
authors = [ | ||
{ name="Thiago Jacinto", email="[email protected]" }, | ||
] | ||
description = "Application that calculate time duration until reach a given date" | ||
readme = "README.md" | ||
requires-python = ">=3.10.9" | ||
classifiers = [ | ||
"Programming Language :: Python :: 3", | ||
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)", | ||
"Operating System :: OS Independent", | ||
"Development Status :: 4 - Beta" | ||
] | ||
dynamic = [ | ||
"version", | ||
"dependencies" | ||
] | ||
|
||
[project.scripts] | ||
time_until = "time_until:app" | ||
|
||
[project.urls] | ||
"Homepage" = "https://github.com/thiagojacinto/time-until-cli" | ||
"Bug Tracker" = "https://github.com/thiagojacinto/time-until-cli/issues" | ||
"General Discussions" = "https://github.com/thiagojacinto/time-until-cli/discussions" | ||
|
||
[tool.setuptools.dynamic] | ||
version = {attr = "time_until.__version__"} | ||
dependencies = {file = ["requirements.txt"]} |
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,16 @@ | ||
attrs==22.2.0 | ||
click==8.1.3 | ||
colorama==0.4.6 | ||
commonmark==0.9.1 | ||
exceptiongroup==1.1.0 | ||
iniconfig==2.0.0 | ||
packaging==23.0 | ||
pluggy==1.0.0 | ||
Pygments==2.14.0 | ||
pytest==7.2.1 | ||
python-dateutil==2.8.2 | ||
rich==12.6.0 | ||
shellingham==1.5.0.post1 | ||
six==1.16.0 | ||
tomli==2.0.1 | ||
typer==0.7.0 |
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,15 @@ | ||
attrs==22.2.0 | ||
click==8.1.3 | ||
colorama==0.4.6 | ||
commonmark==0.9.1 | ||
exceptiongroup==1.1.0 | ||
iniconfig==2.0.0 | ||
packaging==23.0 | ||
pluggy==1.0.0 | ||
Pygments==2.14.0 | ||
python-dateutil==2.8.2 | ||
rich==12.6.0 | ||
shellingham==1.5.0.post1 | ||
six==1.16.0 | ||
tomli==2.0.1 | ||
typer==0.7.0 |
Empty file.
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,2 @@ | ||
from time_until import app | ||
app() |
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,68 @@ | ||
"""Application that calculate time duration until reach a given date.""" | ||
from datetime import datetime | ||
from typing import Optional | ||
import typer | ||
from dateutil.relativedelta import relativedelta | ||
from dateutil.parser import parse | ||
|
||
__version__ = "0.1.1" | ||
|
||
app = typer.Typer( | ||
pretty_exceptions_show_locals=False, | ||
help="Application that calculate time duration until reach a given date." | ||
) | ||
|
||
def version_callback(value: bool): | ||
if value: | ||
print(f"time_until CLI Version: {__version__}") | ||
raise typer.Exit() | ||
|
||
def validate_date(target: str): | ||
"""Validate with the reference date format""" | ||
parsed_target = parse(target) | ||
return (True, parsed_target) | ||
|
||
def calculate_delta(origin: datetime, target: datetime): | ||
"""calculate time duration from ORIGIN to TARGET""" | ||
return relativedelta(origin, target) | ||
|
||
def print_output(delta: relativedelta): | ||
"""Define a way to output information from the `relativedelta` input""" | ||
result=[] | ||
if delta.years > 0: | ||
result.append("{} year(s) ".format(delta.years)) | ||
if delta.months > 0: | ||
result.append("{} month(s) ".format(delta.months)) | ||
if delta.days > 0: | ||
result.append("{} day(s) ".format(delta.days)) | ||
if delta.hours > 0: | ||
result.append("{} hour(s) ".format(delta.hours)) | ||
if delta.minutes > 0: | ||
result.append("{} minute(s) ".format(delta.minutes)) | ||
if delta.seconds > 0: | ||
result.append("{} second(s) ".format(delta.seconds)) | ||
|
||
result.insert(0, 'Time remaining: ') | ||
print(''.join(result)) | ||
|
||
@app.command() | ||
def time_until( | ||
target: str = typer.Argument(..., help="Future date or time used as reference."), | ||
version: Optional[bool] = typer.Option( | ||
None, "--version", callback=version_callback, is_eager=True | ||
) | ||
): | ||
"""Application that calculate time duration until reach a given date.""" | ||
|
||
is_valid, parsed_target = validate_date(target) | ||
rightnow = datetime.now() | ||
|
||
if parsed_target < datetime.now(): | ||
raise ValueError("Not possible to calculate duration to a past date or time. Try again with future date OR time.") | ||
|
||
if is_valid: | ||
result = calculate_delta(parsed_target, rightnow) | ||
print_output(result) | ||
|
||
if __name__ == "__main__": | ||
app() |
Empty file.
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,48 @@ | ||
from datetime import datetime | ||
from dateutil.relativedelta import relativedelta | ||
|
||
class DateBuilder: | ||
"""Builder to generate a Date entity""" | ||
|
||
def __init__(self): | ||
"""Initialise with datetime object of current time""" | ||
self._date = datetime.now() | ||
|
||
def with_years_ahead(self, years_from_now : int): | ||
"""Set the the number of years from now""" | ||
self._date += relativedelta(years=years_from_now) | ||
return self | ||
|
||
def with_months_ahead(self, months_from_now : int): | ||
"""Set the the number of months from now""" | ||
self._date += relativedelta(months=months_from_now) | ||
return self | ||
|
||
def with_days_ahead(self, days_from_now : int): | ||
"""Set the the number of days from now""" | ||
self._date += relativedelta(days=days_from_now) | ||
return self | ||
|
||
def with_hours_ahead(self, hours_from_now : int): | ||
"""Set the the number of hours from now""" | ||
self._date += relativedelta(hours=hours_from_now) | ||
return self | ||
|
||
def with_minutes_ahead(self, minutes_from_now : int): | ||
"""Set the the number of minutes from now""" | ||
self._date += relativedelta(minutes=minutes_from_now) | ||
return self | ||
|
||
def with_seconds_ahead(self, seconds_from_now : int): | ||
"""Set the the number of seconds from now""" | ||
self._date += relativedelta(seconds=seconds_from_now) | ||
return self | ||
|
||
def with_seconds_ago(self, seconds_ago : int): | ||
"""Set the the number of seconds ago from the current time""" | ||
self._date -= relativedelta(seconds=seconds_ago) | ||
return self | ||
|
||
def build(self): | ||
"""Return the curret datetime entity""" | ||
return self._date |
Oops, something went wrong.