diff --git a/cookiecutter.json b/cookiecutter.json index 349add2..f47efea 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -1,21 +1,14 @@ { - "client_name": "ds", - "project_name": "default", - "__project_name_slug": "{{cookiecutter.project_name | slugify}}", - "__client_name_slug": "{{cookiecutter.client_name | slugify}}", - "repo_name": "{{cookiecutter.__client_name_slug}}-{{cookiecutter.__project_name_slug}}", - "ci": [ - "GitLab", - "Github", - "None" - ], - "jupytext": [ - "No", - "Yes" - ], - "python_package_name": "{{ cookiecutter.__project_name_slug.replace('-', '_') }}", - "__package_name": "{{ cookiecutter.python_package_name }}", - "_copy_without_render": [ - ".github/workflows/*.yml" - ] - } \ No newline at end of file + "client_name": "ds", + "project_name": "default", + "__project_name_slug": "{{cookiecutter.project_name | slugify}}", + "__client_name_slug": "{{cookiecutter.client_name | slugify}}", + "repo_name": "{{cookiecutter.__client_name_slug}}-{{cookiecutter.__project_name_slug}}", + "ci": ["Github", "GitLab", "None"], + "jupytext": ["No", "Yes"], + "docs": ["Sphinx", "No docs"], + "versioning": ["Bumpversion", "None"], + "python_package_name": "{{ cookiecutter.__project_name_slug.replace('-', '_') }}", + "__package_name": "{{ cookiecutter.python_package_name }}", + "_copy_without_render": [".github/workflows/*.yml", ".github/workflows/*.yaml"] +} diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py index 37a1eda..a806a90 100644 --- a/hooks/post_gen_project.py +++ b/hooks/post_gen_project.py @@ -4,33 +4,50 @@ print("Running post generation...") -ci = "{{ cookiecutter.ci }}" +files_to_be_removed = [] -REMOVE_PATHS = [] - -gitlab_files = [ +GITLAB_FILES = [ ".gitlab-ci.yml", "docker/precommit" ] -github_files = [ +GITHUB_FILES = [ ".github/", ] +DOCS_FILES = [ + "docs/", + "build_docs.sh", + ".github/workflows/documentation.yml" +] + +BUMPVERSION_FILES = [ + ".bumpversion.cfg", + "bump_version.sh" +] + {% if cookiecutter.ci != "GitLab" %} -REMOVE_PATHS.extend(gitlab_files) +files_to_be_removed.extend(GITLAB_FILES) {% endif %} {% if cookiecutter.ci != "Github" %} -REMOVE_PATHS.extend(github_files) +files_to_be_removed.extend(GITHUB_FILES) {% endif %} {% if cookiecutter.jupytext != "Yes" %} -REMOVE_PATHS.extend(["notebooks/example.py"]) +files_to_be_removed.append("notebooks/example.py") +{% endif %} + +{% if cookiecutter.docs == "No docs" %} +files_to_be_removed.extend(DOCS_FILES) +{% endif %} + +{% if cookiecutter.versioning != "Bumpversion" %} +files_to_be_removed.extend(BUMPVERSION_FILES) {% endif %} print("Cleaning files... 🌀") -for path in REMOVE_PATHS: +for path in files_to_be_removed: path = Path(path) if path.exists() and path.is_file(): print(f"Clean up file: '{path}'") @@ -44,4 +61,4 @@ for path in Path("").rglob("*.sh"): path.chmod(path.stat().st_mode | stat.S_IXUSR) -print("DONE 🎆") \ No newline at end of file +print("DONE 🎆") diff --git a/{{ cookiecutter.repo_name }}/.bumpversion.cfg b/{{ cookiecutter.repo_name }}/.bumpversion.cfg index 2006ad1..a9aa167 100644 --- a/{{ cookiecutter.repo_name }}/.bumpversion.cfg +++ b/{{ cookiecutter.repo_name }}/.bumpversion.cfg @@ -14,4 +14,6 @@ values = dev prod -[bumpversion:file:./src/{{cookiecutter.__package_name}}/VERSION] +[bumpversion:file:./src/{{cookiecutter.__package_name}}/__version__.py] +search = __version__ = '{current_version}' +replace = __version__ = '{new_version}' diff --git a/{{ cookiecutter.repo_name }}/.gitlab-ci.yml b/{{ cookiecutter.repo_name }}/.gitlab-ci.yml index d8ef467..a4eacf8 100644 --- a/{{ cookiecutter.repo_name }}/.gitlab-ci.yml +++ b/{{ cookiecutter.repo_name }}/.gitlab-ci.yml @@ -7,12 +7,11 @@ variables: DOCKER_REGISTRY: $CI_REGISTRY/$CI_PROJECT_PATH PRECOMMIT_IMAGE: $DOCKER_REGISTRY/precommit - # run CI on default branch or MR only workflow: rules: - - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' - - if: '$CI_MERGE_REQUEST_IID' + - if: "$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH" + - if: "$CI_MERGE_REQUEST_IID" stages: - preparation @@ -58,7 +57,7 @@ stages: stage: preparation image: docker:23 rules: - - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' + - if: "$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH" changes: - docker/precommit/Dockerfile - .pre-commit-config.yaml @@ -87,7 +86,6 @@ stages: # Consider to use stable commit SHA from main branch instead # and manual changes to reduce surprises. - # To overcome issue that latest might not be present # and assume that this either new project / done in # atomic merge request and is not main branch @@ -120,7 +118,7 @@ lint-precommit-changed: - docker/precommit/Dockerfile - .pre-commit-config.yaml when: always - - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' + - if: "$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH" when: never ############################################# @@ -140,6 +138,7 @@ lint-precommit-changed: ########################################### # Job to run pytest with code coverage + license check +# TODO make installing bump2version below conditional on cookiecutter parameter choice tests: image: $PYTHON_DOCKER_IMAGE stage: tests @@ -236,6 +235,8 @@ tests: rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + +{%- if cookiecutter.docs != "No docs" %} ############################################## # Job to build Sphinx docs and host it on GitLab Pages @@ -249,6 +250,8 @@ pages: - ./build_docs.sh artifacts: paths: - - public + - public rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + +{% endif -%} \ No newline at end of file diff --git a/{{ cookiecutter.repo_name }}/README.md b/{{ cookiecutter.repo_name }}/README.md index 2aaa1db..21a0945 100644 --- a/{{ cookiecutter.repo_name }}/README.md +++ b/{{ cookiecutter.repo_name }}/README.md @@ -49,6 +49,7 @@ Read more about different modes in [documentation](https://ipython.org/ipython-d All code should be in `src/` to make reusability and review straightforward, keep notebooks simple for exploratory data analysis. See also [Cookiecutter Data Science opinion](https://drivendata.github.io/cookiecutter-data-science/#notebooks-are-for-exploration-and-communication). +{%- if cookiecutter.docs != "No docs" %} # Project documentation In `docs/` directory are Sphinx RST/Markdown files. @@ -62,6 +63,7 @@ $ ./build_docs.sh Then open `public/index.html` file. Please read the official [Sphinx documentation](https://www.sphinx-doc.org/en/master/) for more details. +{% endif -%} {% if cookiecutter.ci == "GitLab" %} @@ -104,6 +106,7 @@ Treat them as read-only files and edit only notebooks. {%- endif -%} +{%- if cookiecutter.versioning == "Bumpversion" %} # Semantic version bump To bump version of the library please use `bump2version` which will update all version strings. @@ -123,6 +126,7 @@ $ ./bump_version.sh --dry-run major Script updates **VERSION** file and setup.cfg automatically uses that version. You can configure it to update version string in other files as well - please check out the bump2version configuration file. +{% endif -%} {% if cookiecutter.ci == "GitLab" %} diff --git a/{{ cookiecutter.repo_name }}/pyproject.toml b/{{ cookiecutter.repo_name }}/pyproject.toml index 10da5a8..bff0d5f 100644 --- a/{{ cookiecutter.repo_name }}/pyproject.toml +++ b/{{ cookiecutter.repo_name }}/pyproject.toml @@ -1,18 +1,13 @@ [build-system] -requires = [ - "setuptools >= 40.9.0", - "wheel", -] +requires = ["setuptools >= 40.9.0", "wheel"] build-backend = "setuptools.build_meta" [tool.isort] -multi_line_output=3 -line_length=120 +multi_line_output = 3 +line_length = 120 include_trailing_comma = true -known_first_party=[ - '{{ cookiecutter.__package_name }}' -] -known_third_party=[ # Most popular libraries. Extend if necessary. +known_first_party = ['{{ cookiecutter.__package_name }}'] +known_third_party = [ # Most popular libraries. Extend if necessary. 'IPython', 'PIL', 'cv2', @@ -47,13 +42,13 @@ known_third_party=[ # Most popular libraries. Extend if necessary. 'tqdm', 'typer', ] -skip_gitignore=true +skip_gitignore = true [tool.black] -line_length=120 +line_length = 120 [tool.pytest] -norecursedirs=[ +norecursedirs = [ '.git', '.tox', '.env', @@ -88,7 +83,7 @@ warn_unused_ignores = false show_error_codes = true check_untyped_defs = true no_implicit_optional = true -mypy_path=['src'] +mypy_path = ['src'] [[tool.mypy.overrides]] module = "{{ cookiecutter.__package_name }}.*" @@ -96,34 +91,34 @@ ignore_missing_imports = false disallow_untyped_defs = true [tool.pylint.basic] -good-names="i,j,x,y,z,x1,y1,z1,x2,y2,z2,cv,df,dx,dy,dz,w,h,c,b,g,qa,q,a" -max-args=8 +good-names = "i,j,x,y,z,x1,y1,z1,x2,y2,z2,cv,df,dx,dy,dz,w,h,c,b,g,qa,q,a" +max-args = 8 [tool.pylint.main] -load-plugins=["pylint.extensions.docparams"] +load-plugins = ["pylint.extensions.docparams"] [tool.pylint.messages_control] -disable=[ - "suppressed-message", - # therefore we wouldn't have to install full dependency set in order to lint - "import-error", - # sometimes we create a dataclass or Pydantic module and just don't need public methods - "too-few-public-methods", - # below is handled by pycln - "unused-import", - # below is handled by isort - "wrong-import-order", - # too restrictive - "too-many-instance-attributes", - # not necessary nor useful in our projects - "missing-module-docstring" - ] +disable = [ + "suppressed-message", + # therefore we wouldn't have to install full dependency set in order to lint + "import-error", + # sometimes we create a dataclass or Pydantic module and just don't need public methods + "too-few-public-methods", + # below is handled by pycln + "unused-import", + # below is handled by isort + "wrong-import-order", + # too restrictive + "too-many-instance-attributes", + # not necessary nor useful in our projects + "missing-module-docstring", +] [tool.pylint.format] -max-line-length=120 +max-line-length = 120 [tool.pylint.miscellaneous] -notes=["XXX"] +notes = ["XXX"] [tool.pylint.parameter_documentation] accept-no-param-doc = false @@ -133,13 +128,13 @@ accept-no-yields-doc = false default-docstring-type = "google" [tool.pylint.design] -max-locals=20 +max-locals = 20 [tool.pylint.similarities] -min-similarity-lines=10 +min-similarity-lines = 10 [tool.bandit] -exclude_dirs = ["venv",] +exclude_dirs = ["venv"] # B101 disables errors for asserts in the code # remember to not use asserts for security and control flows -skips = ["B101"] \ No newline at end of file +skips = ["B101"] diff --git a/{{ cookiecutter.repo_name }}/setup.cfg b/{{ cookiecutter.repo_name }}/setup.cfg index a78566e..84b5d3f 100644 --- a/{{ cookiecutter.repo_name }}/setup.cfg +++ b/{{ cookiecutter.repo_name }}/setup.cfg @@ -1,7 +1,7 @@ [metadata] name = {{ cookiecutter.__package_name }} # do not change version by hand: use bump_version.sh -version = file: src/{{ cookiecutter.__package_name }}/VERSION +version = attr: {{ cookiecutter.__package_name }}.__version__.__version__ description = "deepsense.ai project" author = deepsense.ai author_email = contact@deepsense.ai diff --git a/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.__package_name }}/VERSION b/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.__package_name }}/VERSION deleted file mode 100644 index 772a55e..0000000 --- a/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.__package_name }}/VERSION +++ /dev/null @@ -1 +0,0 @@ -0.0.1-dev \ No newline at end of file diff --git a/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.__package_name }}/__version__.py b/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.__package_name }}/__version__.py index 4d271e8..3742a1f 100644 --- a/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.__package_name }}/__version__.py +++ b/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.__package_name }}/__version__.py @@ -1,5 +1,3 @@ """Version information.""" -from pathlib import Path -version_file = Path(__file__).absolute().parents[0] / "VERSION" -__version__ = version_file.read_text(encoding="utf-8").strip() +__version__ = "0.0.1"