Skip to content

Commit 92a0291

Browse files
authored
Add MarkdownPiece class to make manifest pieces better structured (#2238)
1 parent 4ee4f2b commit 92a0291

File tree

9 files changed

+82
-59
lines changed

9 files changed

+82
-59
lines changed

docs/maintaining/tagging.md

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,18 +69,14 @@ So, the `tag_value(container)` method gets a docker container as an input and re
6969

7070
### Manifest
7171

72-
`ManifestHeader` is a build manifest header.
73-
It contains the following sections: `Build timestamp`, `Docker image size`, and `Git commit` info.
74-
75-
All the other manifest classes are inherited from `ManifestInterface`:
72+
All manifest classes except `BuildInfo` are inherited from `ManifestInterface`
73+
and `markdown_piece(container)` method returns a piece of the build manifest.
7674

7775
```{literalinclude} ../../tagging/manifests/manifest_interface.py
7876
:language: py
7977
:start-at: class ManifestInterface
8078
```
8179

82-
- The `markdown_piece(container)` method returns a piece of markdown file to be used as a part of the build manifest.
83-
8480
`AptPackagesManifest` example:
8581

8682
```{literalinclude} ../../tagging/manifests/apt_packages.py

tagging/apps/write_manifest.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from tagging.hierarchy.get_taggers_and_manifests import (
1111
get_taggers_and_manifests,
1212
)
13-
from tagging.manifests.header import ManifestHeader
13+
from tagging.manifests.build_info import BuildInfo
1414
from tagging.manifests.manifest_interface import ManifestInterface
1515
from tagging.utils.config import Config
1616
from tagging.utils.docker_runner import DockerRunner
@@ -51,14 +51,17 @@ def write_build_history_line(
5151
def write_manifest_file(
5252
config: Config,
5353
filename: str,
54+
commit_hash_tag: str,
5455
manifests: list[ManifestInterface],
5556
container: Container,
5657
) -> None:
5758
manifest_names = [manifest.__class__.__name__ for manifest in manifests]
5859
LOGGER.info(f"Using manifests: {manifest_names}")
5960

60-
markdown_pieces = [ManifestHeader.create_header(config, BUILD_TIMESTAMP)] + [
61-
manifest.markdown_piece(container) for manifest in manifests
61+
markdown_pieces = [
62+
f"# Build manifest for image: {config.image}:{commit_hash_tag}",
63+
BuildInfo.markdown_piece(config, BUILD_TIMESTAMP).get_str(),
64+
*(manifest.markdown_piece(container).get_str() for manifest in manifests),
6265
]
6366
markdown_content = "\n\n".join(markdown_pieces) + "\n"
6467

@@ -82,7 +85,7 @@ def write_manifest(config: Config) -> None:
8285
tags_prefix + "-" + tagger.tag_value(container) for tagger in taggers
8386
]
8487
write_build_history_line(config, filename, all_tags)
85-
write_manifest_file(config, filename, manifests, container)
88+
write_manifest_file(config, filename, commit_hash_tag, manifests, container)
8689

8790

8891
if __name__ == "__main__":

tagging/manifests/apt_packages.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
# Distributed under the terms of the Modified BSD License.
33
from docker.models.containers import Container
44

5-
from tagging.manifests.manifest_interface import ManifestInterface
5+
from tagging.manifests.manifest_interface import ManifestInterface, MarkdownPiece
66
from tagging.utils.quoted_output import quoted_output
77

88

99
class AptPackagesManifest(ManifestInterface):
1010
@staticmethod
11-
def markdown_piece(container: Container) -> str:
12-
return f"""\
13-
## Apt Packages
14-
15-
{quoted_output(container, "apt list --installed")}"""
11+
def markdown_piece(container: Container) -> MarkdownPiece:
12+
return MarkdownPiece(
13+
title="## Apt Packages",
14+
sections=[quoted_output(container, "apt list --installed")],
15+
)

tagging/manifests/header.py renamed to tagging/manifests/build_info.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,18 @@
22
# Distributed under the terms of the Modified BSD License.
33
import plumbum
44

5+
from tagging.manifests.manifest_interface import MarkdownPiece
56
from tagging.utils.config import Config
67
from tagging.utils.git_helper import GitHelper
78

89
docker = plumbum.local["docker"]
910

1011

11-
class ManifestHeader:
12-
"""ManifestHeader doesn't fall under common interface, and we run it separately"""
12+
class BuildInfo:
13+
"""BuildInfo doesn't fall under common interface, and we run it separately"""
1314

1415
@staticmethod
15-
def create_header(config: Config, build_timestamp: str) -> str:
16+
def markdown_piece(config: Config, build_timestamp: str) -> MarkdownPiece:
1617
commit_hash = GitHelper.commit_hash()
1718
commit_hash_tag = GitHelper.commit_hash_tag()
1819
commit_message = GitHelper.commit_message()
@@ -27,11 +28,10 @@ def create_header(config: Config, build_timestamp: str) -> str:
2728
"{{.Size}}",
2829
]().rstrip()
2930

30-
return f"""\
31-
# Build manifest for image: {config.image}:{commit_hash_tag}
32-
33-
## Build Info
34-
31+
return MarkdownPiece(
32+
title="## Build Info",
33+
sections=[
34+
f"""\
3535
- Build timestamp: {build_timestamp}
3636
- Docker image: `{config.full_image()}:{commit_hash_tag}`
3737
- Docker image size: {image_size}
@@ -41,3 +41,5 @@ def create_header(config: Config, build_timestamp: str) -> str:
4141
```text
4242
{commit_message}
4343
```"""
44+
],
45+
)

tagging/manifests/conda_environment.py

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,20 @@
22
# Distributed under the terms of the Modified BSD License.
33
from docker.models.containers import Container
44

5-
from tagging.manifests.manifest_interface import ManifestInterface
5+
from tagging.manifests.manifest_interface import ManifestInterface, MarkdownPiece
66
from tagging.utils.docker_runner import DockerRunner
77
from tagging.utils.quoted_output import quoted_output
88

99

1010
class CondaEnvironmentManifest(ManifestInterface):
1111
@staticmethod
12-
def markdown_piece(container: Container) -> str:
13-
return f"""\
14-
## Python Packages
15-
16-
{DockerRunner.run_simple_command(container, "python --version")}
17-
18-
{quoted_output(container, "conda info")}
19-
20-
{quoted_output(container, "mamba info")}
21-
22-
{quoted_output(container, "mamba list")}"""
12+
def markdown_piece(container: Container) -> MarkdownPiece:
13+
return MarkdownPiece(
14+
title="## Python Packages",
15+
sections=[
16+
DockerRunner.run_simple_command(container, "python --version"),
17+
quoted_output(container, "conda info"),
18+
quoted_output(container, "mamba info"),
19+
quoted_output(container, "mamba list"),
20+
],
21+
)

tagging/manifests/julia_packages.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,19 @@
22
# Distributed under the terms of the Modified BSD License.
33
from docker.models.containers import Container
44

5-
from tagging.manifests.manifest_interface import ManifestInterface
5+
from tagging.manifests.manifest_interface import ManifestInterface, MarkdownPiece
66
from tagging.utils.quoted_output import quoted_output
77

88

99
class JuliaPackagesManifest(ManifestInterface):
1010
@staticmethod
11-
def markdown_piece(container: Container) -> str:
12-
return f"""\
13-
## Julia Packages
14-
15-
{quoted_output(container, "julia -E 'using InteractiveUtils; versioninfo()'")}
16-
17-
{quoted_output(container, "julia -E 'import Pkg; Pkg.status()'")}"""
11+
def markdown_piece(container: Container) -> MarkdownPiece:
12+
return MarkdownPiece(
13+
title="## Julia Packages",
14+
sections=[
15+
quoted_output(
16+
container, "julia -E 'using InteractiveUtils; versioninfo()'"
17+
),
18+
quoted_output(container, "julia -E 'import Pkg; Pkg.status()'"),
19+
],
20+
)
Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,26 @@
11
# Copyright (c) Jupyter Development Team.
22
# Distributed under the terms of the Modified BSD License.
3+
from dataclasses import dataclass
4+
35
from docker.models.containers import Container
46

57

8+
@dataclass(frozen=True)
9+
class MarkdownPiece:
10+
title: str
11+
sections: list[str]
12+
13+
def __post_init__(self) -> None:
14+
# All pieces are H2
15+
assert self.title.startswith("## ")
16+
17+
def get_str(self) -> str:
18+
return "\n\n".join([self.title, *self.sections])
19+
20+
621
class ManifestInterface:
722
"""Common interface for all manifests"""
823

924
@staticmethod
10-
def markdown_piece(container: Container) -> str:
25+
def markdown_piece(container: Container) -> MarkdownPiece:
1126
raise NotImplementedError

tagging/manifests/r_packages.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,19 @@
22
# Distributed under the terms of the Modified BSD License.
33
from docker.models.containers import Container
44

5-
from tagging.manifests.manifest_interface import ManifestInterface
5+
from tagging.manifests.manifest_interface import ManifestInterface, MarkdownPiece
66
from tagging.utils.quoted_output import quoted_output
77

88

99
class RPackagesManifest(ManifestInterface):
1010
@staticmethod
11-
def markdown_piece(container: Container) -> str:
12-
return f"""\
13-
## R Packages
14-
15-
{quoted_output(container, "R --version")}
16-
17-
{quoted_output(container, "R --silent -e 'installed.packages(.Library)[, c(1,3)]'")}"""
11+
def markdown_piece(container: Container) -> MarkdownPiece:
12+
return MarkdownPiece(
13+
title="## R Packages",
14+
sections=[
15+
quoted_output(container, "R --version"),
16+
quoted_output(
17+
container, "R --silent -e 'installed.packages(.Library)[, c(1,3)]'"
18+
),
19+
],
20+
)

tagging/manifests/spark_info.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@
22
# Distributed under the terms of the Modified BSD License.
33
from docker.models.containers import Container
44

5-
from tagging.manifests.manifest_interface import ManifestInterface
5+
from tagging.manifests.manifest_interface import ManifestInterface, MarkdownPiece
66
from tagging.utils.quoted_output import quoted_output
77

88

99
class SparkInfoManifest(ManifestInterface):
1010
@staticmethod
11-
def markdown_piece(container: Container) -> str:
12-
return f"""\
13-
## Apache Spark
14-
15-
{quoted_output(container, "/usr/local/spark/bin/spark-submit --version")}"""
11+
def markdown_piece(container: Container) -> MarkdownPiece:
12+
return MarkdownPiece(
13+
title="## Apache Spark",
14+
sections=[
15+
quoted_output(container, "/usr/local/spark/bin/spark-submit --version")
16+
],
17+
)

0 commit comments

Comments
 (0)