Skip to content

Commit

Permalink
feat: use Init command and service from upstream
Browse files Browse the repository at this point in the history
This is *almost* a chore, as the templates, supported profiles, etc are all
unchanged. However, the upstream command adds support for the "--project-dir"
argument, so this is ends up being a feature.

Fixes #753
  • Loading branch information
tigarmo committed Nov 28, 2024
1 parent d77ac5a commit 484099f
Show file tree
Hide file tree
Showing 21 changed files with 344 additions and 440 deletions.
1 change: 1 addition & 0 deletions docs/.wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ fileset
filesets
filesystem
filesystems
filetree
fs
gc
GiB
Expand Down
2 changes: 1 addition & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ colorama==0.4.6
# via sphinx-autobuild
coverage==7.6.8
# via rockcraft (pyproject.toml)
craft-application==4.4.0
craft-application==4.5.0
# via rockcraft (pyproject.toml)
craft-archives==2.0.1
# via
Expand Down
2 changes: 1 addition & 1 deletion requirements-doc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ click==8.1.7
# via uvicorn
colorama==0.4.6
# via sphinx-autobuild
craft-application==4.4.0
craft-application==4.5.0
# via rockcraft (pyproject.toml)
craft-archives==2.0.1
# via
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ chardet==5.2.0
# via python-debian
charset-normalizer==3.4.0
# via requests
craft-application==4.4.0
craft-application==4.5.0
# via rockcraft (pyproject.toml)
craft-archives==2.0.1
# via
Expand Down
6 changes: 6 additions & 0 deletions rockcraft/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ def _configure_services(self, provider_name: str | None) -> None:
"package",
build_plan=self._build_plan,
)
self.services.update_kwargs(
"init",
default_name="my-rock-name",
name_regex=project.PROJECT_NAME_COMPILED_REGEX,
invalid_name_message=project.MESSAGE_INVALID_NAME,
)
super()._configure_services(provider_name)

@override
Expand Down
6 changes: 0 additions & 6 deletions rockcraft/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,6 @@ def _create_app() -> "Rockcraft":

app = Rockcraft(app=APP_METADATA, services=services)

app.add_command_group(
"Other",
[
commands.InitCommand,
],
)
app.add_command_group(
"Extensions",
[
Expand Down
2 changes: 0 additions & 2 deletions rockcraft/commands/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@
ExtensionsCommand,
ListExtensionsCommand,
)
from .init import InitCommand

__all__ = [
"InitCommand",
"ExpandExtensionsCommand",
"ExtensionsCommand",
"ListExtensionsCommand",
Expand Down
406 changes: 0 additions & 406 deletions rockcraft/commands/init.py

This file was deleted.

4 changes: 2 additions & 2 deletions rockcraft/models/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
- must contain only lowercase letters [a-z], numbers [0-9] or hyphens
- must not end with a hyphen, and must not contain two or more consecutive hyphens
"""
_PROJECT_NAME_COMPILED_REGEX = re.compile(PROJECT_NAME_REGEX)
PROJECT_NAME_COMPILED_REGEX = re.compile(PROJECT_NAME_REGEX)

MESSAGE_INVALID_NAME = (
"invalid name for rock: Names can only use ASCII lowercase letters, numbers, and hyphens. "
Expand All @@ -80,7 +80,7 @@
ProjectName = Annotated[
str,
pydantic.BeforeValidator(
get_validator_by_regex(_PROJECT_NAME_COMPILED_REGEX, MESSAGE_INVALID_NAME)
get_validator_by_regex(PROJECT_NAME_COMPILED_REGEX, MESSAGE_INVALID_NAME)
),
pydantic.Field(
min_length=1,
Expand Down
2 changes: 2 additions & 0 deletions rockcraft/services/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@
"""Rockcraft services."""

from rockcraft.services.image import RockcraftImageService
from rockcraft.services.init import RockcraftInitService
from rockcraft.services.lifecycle import RockcraftLifecycleService
from rockcraft.services.package import RockcraftPackageService
from rockcraft.services.provider import RockcraftProviderService
from rockcraft.services.service_factory import RockcraftServiceFactory

__all__ = [
"RockcraftImageService",
"RockcraftInitService",
"RockcraftLifecycleService",
"RockcraftPackageService",
"RockcraftProviderService",
Expand Down
58 changes: 58 additions & 0 deletions rockcraft/services/init.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
#
# Copyright 2024 Canonical Ltd.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""Rockcraft Init Service."""
import pathlib
from typing import Any

from craft_application.services import InitService
from craft_cli import emit
from overrides import override # type: ignore[reportUnknownVariableType]


class RockcraftInitService(InitService):
"""Rockcraft specialization of the InitService."""

@override
def initialise_project(
self,
*,
project_dir: pathlib.Path,
project_name: str,
template_dir: pathlib.Path,
) -> None:
super().initialise_project(
project_dir=project_dir,
project_name=project_name,
template_dir=template_dir,
)

init_profile = template_dir.name
if init_profile != "simple":
versioned_docs = self._app.versioned_docs_url
reference_docs = f"{versioned_docs}/reference/extensions/{init_profile}"
emit.message(
f"Go to {reference_docs} to read more about the "
f"{init_profile!r} profile."
)

@override
def _get_context(self, name: str, *, project_dir: pathlib.Path) -> dict[str, Any]:
context = super()._get_context(name, project_dir=project_dir)
context["snake_name"] = context["name"].replace("-", "_").lower()
context["versioned_url"] = self._app.versioned_docs_url

return context
3 changes: 3 additions & 0 deletions rockcraft/services/service_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ class RockcraftServiceFactory(ServiceFactory):
ProviderClass: type[ # type: ignore[reportIncompatibleVariableOverride]
services.RockcraftProviderService
] = services.RockcraftProviderService
InitClass: type[ # type: ignore[reportIncompatibleVariableOverride]
services.RockcraftInitService
] = services.RockcraftInitService

if TYPE_CHECKING:
image: services.RockcraftImageService = None # type: ignore[assignment]
43 changes: 43 additions & 0 deletions rockcraft/templates/django-framework/rockcraft.yaml.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: {{name}}
# see {{versioned_url}}/explanation/bases/
# for more information about bases and using 'bare' bases for chiselled rocks
base: [email protected] # the base environment for this Django application
version: '0.1' # just for humans. Semantic versioning is recommended
summary: A summary of your Django application # 79 char long summary
description: |
This is {{name}}'s description. You have a paragraph or two to tell the
most important story about it. Keep it under 100 words though,
we live in tweetspace and your description wants to look good in the
container registries out there.
# the platforms this rock should be built on and run on.
# you can check your architecture with `dpkg --print-architecture`
platforms:
amd64:
# arm64:
# ppc64el:
# s390x:

# to ensure the django-framework extension functions properly, your Django project
# should have a structure similar to the following with ./{{snake_name}}/{{snake_name}}/wsgi.py
# being the WSGI entry point and contain an application object.
# +-- {{snake_name}}
# | |-- {{snake_name}}
# | | |-- wsgi.py
# | | +-- ...
# | |-- manage.py
# | |-- migrate.sh
# | +-- some_app
# | |-- views.py
# | +-- ...
# |-- requirements.txt
# +-- rockcraft.yaml

extensions:
- django-framework

# uncomment the sections you need and adjust according to your requirements.
# parts:
# django-framework/dependencies:
# stage-packages:
# # list required packages or slices for your Django application below.
# - libpq-dev
56 changes: 56 additions & 0 deletions rockcraft/templates/fastapi-framework/rockcraft.yaml.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: {{name}}
# see {{versioned_url}}/explanation/bases/
# for more information about bases and using 'bare' bases for chiselled rocks
base: [email protected] # the base environment for this FastAPI application
version: '0.1' # just for humans. Semantic versioning is recommended
summary: A summary of your FastAPI application # 79 char long summary
description: |
This is fastapi project's description. You have a paragraph or two to tell the
most important story about it. Keep it under 100 words though,
we live in tweetspace and your description wants to look good in the
container registries out there.
# the platforms this rock should be built on and run on.
# you can check your architecture with `dpkg --print-architecture`
platforms:
amd64:
# arm64:
# ppc64el:
# s390x:

# to ensure the FastAPI-framework extension works properly, your FastAPI application
# should have an ASGI entrypoint variable named `app`. This variable has to be defined
# in one of the following places:
# 1. `app.py` file in the base directory
# 2. In any of the following directories, the extension will look for the variable
# in the files __init__.py, app.py or main.py:
# a. `app` directory.
# b. `src` directory.
# c. A directory with the same name as the project.
# a `requirements.txt` file with at least the fastapi/starlette package should also
# exist in the base directory.
# see {{versioned_url}}/reference/extensions/fastapi-framework
# for more information.
extensions:
- fastapi-framework

# uncomment the sections you need and adjust according to your requirements.
# parts: # you need to uncomment this line to add or update any part.

# fastapi-framework/install-app:
# prime:
# # by default, only the files in app.py, app/, src/, "project name/" templates/,
# # static/, migrate, migrate.sh, migrate.py and main.py are copied into the image.
# # You can modify the list below to override the default list and
# # include or exclude specific files/directories in your project.
# # note: prefix each entry with "app/" followed by the local path.
# - app/app
# - app/templates
# - app/static

# you may need Ubuntu packages to build a python dependency. Add them here if necessary.
# fastapi-framework/dependencies:
# build-packages:
# # for example, if you need pkg-config and libxmlsec1-dev to build one
# # of your packages:
# - pkg-config
# - libxmlsec1-dev
71 changes: 71 additions & 0 deletions rockcraft/templates/flask-framework/rockcraft.yaml.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: {{name}}
# see {{versioned_url}}/explanation/bases/
# for more information about bases and using 'bare' bases for chiselled rocks
base: [email protected] # the base environment for this Flask application
version: '0.1' # just for humans. Semantic versioning is recommended
summary: A summary of your Flask application # 79 char long summary
description: |
This is {{name}}'s description. You have a paragraph or two to tell the
most important story about it. Keep it under 100 words though,
we live in tweetspace and your description wants to look good in the
container registries out there.
# the platforms this rock should be built on and run on.
# you can check your architecture with `dpkg --print-architecture`
platforms:
amd64:
# arm64:
# ppc64el:
# s390x:

# to ensure the flask-framework extension works properly, your Flask application
# should have an `app.py` file with an `app` object as the WSGI entrypoint.
# a `requirements.txt` file with at least the flask package should also exist.
# see {{versioned_url}}/reference/extensions/flask-framework
# for more information.
extensions:
- flask-framework

# uncomment the sections you need and adjust according to your requirements.
# parts: # you need to uncomment this line to add or update any part.

# flask-framework/install-app:
# prime:
# # by default, only the files in app/, templates/, static/, migrate, migrate.sh,
# # migrate.py and app.py are copied into the image. You can modify the list
# # below to override the default list and include or exclude specific
# # files/directories in your project.
# # note: prefix each entry with "flask/app/" followed by the local path.
# - flask/app/.env
# - flask/app/app.py
# - flask/app/webapp
# - flask/app/templates
# - flask/app/static

# you may need Ubuntu packages to build a python dependency. Add them here if necessary.
# flask-framework/dependencies:
# build-packages:
# # for example, if you need pkg-config and libxmlsec1-dev to build one
# # of your packages:
# - pkg-config
# - libxmlsec1-dev

# you can add package slices or Debian packages to the image.
# package slices are subsets of Debian packages, which result
# in smaller and more secure images.
# see {{versioned_url}}/explanation/chisel/

# add this part if you want to add packages slices to your image.
# you can find a list of packages slices at https://github.com/canonical/chisel-releases
# runtime-slices:
# plugin: nil
# stage-packages:
# # list the required package slices for your flask application below.
# # for example, for the slice libs of libpq5:
# - libpq5_libs

# if you want to add a Debian package to your image, add the next part
# runtime-debs:
# plugin: nil
# stage-packages:
# # list required Debian packages for your flask application below.
# - libpq5
Loading

0 comments on commit 484099f

Please sign in to comment.