Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 1 addition & 21 deletions doc/package.rst
Original file line number Diff line number Diff line change
Expand Up @@ -102,27 +102,7 @@ existing package. When the requested output directory exists, it will
prompt for permission to delete the existing directory.

After instantiation, the package is immediately installable via
:program:`zkg`. You'll see details of how it got generated in its
initial commit, and the newly minted ``zkg.meta`` has details of the
provided user variables:

.. code-block:: console

$ cat foobar/zkg.meta
...
[template]
source = package-template
version = master
zkg_version = 2.8.0
features = plugin

[template_vars]
name = Foobar
namespace = MyOrg

This information is currently informational only, but in the future
will enable baselining changes in package templates to assist with
package modernization.
:program:`zkg`.

To keep templates in sync with :program:`zkg` versions, templates
employ semantic API versioning. An incompatible template will refuse
Expand Down
12 changes: 1 addition & 11 deletions testing/baselines/tests.template-create/out3.zkg.meta
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,4 @@
script_dir = scripts
summary = TODO: A summary of test3 in one line
description = TODO: A more detailed description of test3.
It can span multiple lines, with this indentation.

[template]
source = foo
version = unversioned
features = readme

[template_vars]
name = test3
readme = This is a README.

It can span multiple lines, with this indentation.
11 changes: 1 addition & 10 deletions testing/baselines/tests.template-create/out4.zkg.meta
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,4 @@
script_dir = scripts
summary = TODO: A summary of test4 in one line
description = TODO: A more detailed description of test4.
It can span multiple lines, with this indentation.

[template]
source = https://example.com/zeek/package-template
version = master
commit = xxxxxxxx

[template_vars]
name = test4

It can span multiple lines, with this indentation.
92 changes: 20 additions & 72 deletions zeekpkg/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
make_dir,
)
from .package import (
METADATA_FILENAME,
name_from_path,
)

Expand Down Expand Up @@ -762,83 +761,17 @@ def do_instantiate(
) -> None:
self._prepare_packagedir(packagedir)
super().do_instantiate(tmpl, packagedir, use_force)
self._update_metadata(tmpl)
self._git_init(tmpl)

def _prepare_packagedir(self, packagedir: str) -> None:
os.makedirs(packagedir, exist_ok=True)

def _update_metadata(self, tmpl: Template) -> None:
"""Updates the package's zkg.meta with template information.

This information allows re-running template instantiation with
identical inputs at a later time.
"""
config = configparser.ConfigParser(delimiters="=")
config.optionxform = str # type: ignore
assert self._packagedir
manifest_file = os.path.join(self._packagedir, METADATA_FILENAME)

# Best-effort: if the template populated the file, adopt the
# content, otherwise create with just our metadata.
config.read(manifest_file)

section = "template"
config.remove_section(section)
config.add_section(section)
config.set(section, "source", tmpl.name())

if tmpl.has_repo():
tmplinfo = tmpl.info()
if tmplinfo["origin"] != "unavailable":
config.set(section, "source", tmplinfo["origin"])

if tmpl.version():
# If we're on a branch, disambiguate the version by also mentioning
# the exact commit.
if tmpl.version_branch():
config.set(section, "version", tmpl.version_branch())
sha = tmpl.version_sha()
assert sha
config.set(section, "commit", sha[:8])
else:
config.set(section, "version", tmpl.version())
else:
config.set(section, "version", tmpl.version() or "unversioned")

config.set(section, "zkg_version", __version__)

if self._features:
val = ",".join(sorted([f.name() for f in self._features]))
config.set(section, "features", val)

section = "template_vars"
config.remove_section(section)
config.add_section(section)

for uvar in tmpl._get_user_vars():
if uvar.val() is not None:
config.set(section, uvar.name(), uvar.val())

with open(manifest_file, "w") as hdl:
config.write(hdl)

def _git_init(self, tmpl: Template) -> None:
"""Initialize git repo and commit instantiated content."""
repo = git.Repo.init(self._packagedir)
for fname in repo.untracked_files:
repo.index.add(fname)

features_info = ""
if self._features:
names = sorted(['"' + f.name() + '"' for f in self._features])
if len(names) == 1:
features_info = f", with feature {names[0]}"
else:
features_info = ", with features "
features_info += ", ".join(names[:-1])
features_info += " and " + names[-1]

ver_info = tmpl.version()
ver_sha = tmpl.version_sha()

Expand All @@ -852,12 +785,27 @@ def _git_init(self, tmpl: Template) -> None:
if ver_sha:
ver_info += " (" + ver_sha[:8] + ")"

repo.index.commit(
f"""Initial commit.
tmpl_source = tmpl.name()
if tmpl.has_repo():
if (source := tmpl.info()["origin"]) != "unavailable":
tmpl_source = source

zkg {__version__} created this package from template "{tmpl.name()}"
using {ver_info}{features_info}.""",
)
commit_msg = f"""Initial commit.

zkg {__version__} created this package from template "{tmpl_source}"
using {ver_info}."""

if self._features:
features = "\n".join(sorted([f"- {f.name()}" for f in self._features]))
commit_msg += f"""\n\nFeatures:\n\n{features}"""

if user_vars := tmpl._get_user_vars():
set_vars = filter(lambda v: v is not None, user_vars)
uvars = "\n".join([f"- {v.name()}: {v.val()}" for v in set_vars])

commit_msg += f"""\n\nVariables:\n\n{uvars}"""

repo.index.commit(commit_msg)


class Feature(_Content):
Expand Down
Loading