Skip to content

Commit

Permalink
fix: switch from progress to message for init (#604)
Browse files Browse the repository at this point in the history
- Snapcraft uses message, progress hides the docs url as it is
  "uni-line"
- Use a similar message to what is done in Snapcraft
- Improve the test for initializing flask-framework
- Use the correct documentation slug

---------

Co-authored-by: Tiago Nobrega <[email protected]>
  • Loading branch information
sergiusens and tigarmo authored Jun 22, 2024
1 parent 5ca1009 commit 2d9c6fc
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 19 deletions.
29 changes: 20 additions & 9 deletions rockcraft/commands/init.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ class InitCommand(AppCommand):
# - libpq5
"""
),
doc_slug="/reference/extensions/#the-flask-framework-extension",
doc_slug="/reference/extensions/flask-framework",
),
"django-framework": _InitProfile(
rockcraft_yaml=textwrap.dedent(
Expand Down Expand Up @@ -241,16 +241,27 @@ def run(self, parsed_args: "argparse.Namespace") -> None:
name = "my-rock-name"
emit.debug(f"Set project name to '{name}'")

context = {"name": name, "snake_name": name.replace("-", "_").lower()}

# Get the init profile
init_profile = self._PROFILES[parsed_args.profile]
rockcraft_yaml_path = init(init_profile.rockcraft_yaml.format(**context))

message = f"Created {rockcraft_yaml_path}."
# Setup the reference documentation link if available
profile_reference_docs: str | None = None
if self._app.docs_url and init_profile.doc_slug:
profile_reference = self._app.docs_url + init_profile.doc_slug
profile_reference_docs = self._app.docs_url + init_profile.doc_slug

# Format the template, all templates should be tested to avoid risk of
# expecting documentation when there isn't any set
context = {
"name": name,
"snake_name": name.replace("-", "_").lower(),
"profile_reference_docs": profile_reference_docs,
}
rockcraft_yaml_path = init(init_profile.rockcraft_yaml.format(**context))

message = f"Created {str(rockcraft_yaml_path)!r}."
if profile_reference_docs:
message += (
f"\nRead more about the {parsed_args.profile!r} at: {profile_reference}"
f"\nGo to {profile_reference_docs} to read more about the "
f"{parsed_args.profile!r} profile."
)

emit.progress(message)
emit.message(message)
4 changes: 2 additions & 2 deletions tests/spread/rockcraft/init/task.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
summary: rockcraft init test

execute: |
run_rockcraft init --name=my-rock-name 2> output.txt
run_rockcraft init --name=my-rock-name > output.txt
# Output of init must be exactly this line, and nothing else.
echo "Created rockcraft.yaml." > expected.txt
echo "Created 'rockcraft.yaml'." > expected.txt
diff output.txt expected.txt
test -f rockcraft.yaml
Expand Down
93 changes: 85 additions & 8 deletions tests/unit/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import pathlib
import sys
from pathlib import Path
import textwrap
from unittest.mock import DEFAULT, call

import pytest
Expand Down Expand Up @@ -117,12 +118,15 @@ def test_run_init_fallback_name(mocker):
assert rock_project.name == "my-rock-name"


@pytest.mark.usefixtures("new_dir")
def test_run_init_flask(mocker, tmp_path, monkeypatch):
(tmp_path / "requirements.txt").write_text("flask")
(tmp_path / "app.py").write_text("app = object()")
mock_ended_ok = mocker.patch.object(emit, "ended_ok")
mocker.patch.object(sys, "argv", ["rockcraft", "init", "--profile=flask-framework"])
def test_run_init_flask(mocker, emitter, monkeypatch, new_dir, tmp_path):
(new_dir / "requirements.txt").write_text("Flask", encoding="utf-8")
(new_dir / "app.py").write_text("app = object()", encoding="utf-8")

mocker.patch.object(
sys,
"argv",
["rockcraft", "init", "--profile=flask-framework", "--name", "test-name"],
)

cli.run()

Expand All @@ -131,7 +135,80 @@ def test_run_init_flask(mocker, tmp_path, monkeypatch):

assert len(rock_project_yaml["summary"]) < 80
assert len(rock_project_yaml["description"].split()) < 100
assert mock_ended_ok.mock_calls == [call()]

assert rockcraft_yaml_path.read_text() == textwrap.dedent(
"""\
name: test-name
# see https://documentation.ubuntu.com/rockcraft/en/stable/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 test-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.
platforms: # the platforms this rock should be built on and run on
amd64:
# 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 https://documentation.ubuntu.com/rockcraft/en/stable/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 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 packages to build a python package. Add them here if necessary.
# 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 https://documentation.ubuntu.com/rockcraft/en/latest/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
# flask-framework/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
# flask-framework/runtime-debs:
# plugin: nil
# stage-packages:
# # list required Debian packages for your flask application below.
# - libpq5
"""
)
emitter.assert_message(
textwrap.dedent(
"""\
Created 'rockcraft.yaml'.
Go to https://documentation.ubuntu.com/rockcraft/en/stable/reference/extensions/flask-framework to read more about the 'flask-framework' profile."""
)
)
monkeypatch.setenv("ROCKCRAFT_ENABLE_EXPERIMENTAL_EXTENSIONS", "0")
project.Project.unmarshal(extensions.apply_extensions(tmp_path, rock_project_yaml))

0 comments on commit 2d9c6fc

Please sign in to comment.