add 'tzk convert' to switch between Node & single-file
This commit is contained in:
parent
cf69aa54dd
commit
91b27c6e40
@ -1,14 +1,16 @@
|
||||
from abc import ABC, abstractmethod, abstractclassmethod
|
||||
import argparse
|
||||
import os
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import sys
|
||||
import traceback
|
||||
from typing import Optional
|
||||
|
||||
from tzk.config import cm
|
||||
from tzk.config import cm, DEFAULT_INIT_OPTS
|
||||
from tzk import git
|
||||
from tzk import tw
|
||||
from tzk.util import BuildError, fail, numerize, require_dependencies
|
||||
from tzk.util import BuildError, fail, numerize, require_dependencies, pushd
|
||||
|
||||
|
||||
class CliCommand(ABC):
|
||||
@ -127,19 +129,19 @@ class InitCommand(CliCommand):
|
||||
"-n", "--wiki-name",
|
||||
metavar="NAME",
|
||||
help="The wiki will be installed in a subfolder of the current directory, called NAME.",
|
||||
default="wiki",
|
||||
default=DEFAULT_INIT_OPTS['wiki_name'],
|
||||
)
|
||||
parser.add_argument(
|
||||
"-v", "--tiddlywiki-version-spec",
|
||||
metavar="SPEC",
|
||||
help="NPM version spec for the version of TiddlyWiki to start your package.json at.",
|
||||
default="^5.1.23",
|
||||
default=DEFAULT_INIT_OPTS['tw_version_spec'],
|
||||
)
|
||||
parser.add_argument(
|
||||
"-a", "--author",
|
||||
metavar="AUTHOR_NAME",
|
||||
help="The author to be credited in the package.json, if not your current username.",
|
||||
default=None,
|
||||
default=DEFAULT_INIT_OPTS['author'],
|
||||
)
|
||||
|
||||
def _precheck(self):
|
||||
@ -257,6 +259,93 @@ class BuildCommand(CliCommand):
|
||||
print(f"tzk: Build of product '{args.product}' completed successfully.")
|
||||
|
||||
|
||||
class ConvertCommand(CliCommand):
|
||||
cmd = "convert"
|
||||
help = "Convert a tzk repository to a single-file wiki or vice versa."
|
||||
|
||||
@classmethod
|
||||
def setup_arguments(cls, parser: argparse.ArgumentParser) -> None:
|
||||
parser.add_argument(
|
||||
"source",
|
||||
metavar="SOURCE",
|
||||
help="Wiki to convert. "
|
||||
"Either a folder containing a tzk_config.py file or an HTML file.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"destination",
|
||||
metavar="DEST",
|
||||
help="Output location for the converted wiki. "
|
||||
"Either a folder (existing or not) or the name of an HTML file."
|
||||
)
|
||||
parser.add_argument(
|
||||
"-f", "--force",
|
||||
action="store_true",
|
||||
help="Overwrite the destination location if it already exists.",
|
||||
)
|
||||
|
||||
def _precheck(self, args: argparse.Namespace) -> None:
|
||||
if not os.path.exists(args.source):
|
||||
fail(f"The source location '{args.source}' does not exist.")
|
||||
if os.path.exists(args.destination) and not args.force:
|
||||
fail(f"The destination location '{args.source}' already exists. "
|
||||
f"(Use --force to overwrite it.)")
|
||||
|
||||
|
||||
def execute(self, args: argparse.Namespace) -> None:
|
||||
require_dependencies()
|
||||
self._precheck(args)
|
||||
|
||||
source = Path(args.source).absolute()
|
||||
destination = Path(args.destination)
|
||||
source_type = 'file' if source.is_file() else 'folder'
|
||||
dest_type = 'file' if destination.name.endswith(".html") else 'folder'
|
||||
|
||||
# If types are the same, there's nothing to convert...
|
||||
if source_type == dest_type:
|
||||
fail("The source or the destination may not be of the same type. "
|
||||
"One must be a folder and the other an HTML file.")
|
||||
|
||||
# Conversion from folder to file using --render.
|
||||
if source_type == 'folder':
|
||||
if not Path(source / "tzk_config.py").exists():
|
||||
fail("The source folder '{source}' does not contain "
|
||||
"a tzk_config.py file.")
|
||||
|
||||
with pushd(str(source)):
|
||||
source_wiki_folder = cm().wiki_folder
|
||||
|
||||
tw.exec(
|
||||
(
|
||||
("output", str(destination.parent)),
|
||||
("render", "$:/core/save/all", destination.name, "text/plain"),
|
||||
),
|
||||
base_wiki_folder=source_wiki_folder
|
||||
)
|
||||
|
||||
# Conversion from file to folder using --savewikifolder.
|
||||
elif source_type == 'file':
|
||||
if destination.exists() and args.force:
|
||||
doing_what = "Overwriting existing"
|
||||
shutil.rmtree(destination)
|
||||
else:
|
||||
doing_what = "Creating new"
|
||||
print(f"tzk: {doing_what} tzk repository in destination '{destination}'...")
|
||||
os.mkdir(destination)
|
||||
|
||||
def installer(wiki_name):
|
||||
tw.exec(
|
||||
(
|
||||
("load", str(source)),
|
||||
("savewikifolder", wiki_name),
|
||||
),
|
||||
)
|
||||
with pushd(str(destination)):
|
||||
tw.install(_tw_func=installer, **DEFAULT_INIT_OPTS) # type: ignore
|
||||
|
||||
else:
|
||||
raise AssertionError(f"Invalid source type {source_type}.")
|
||||
|
||||
|
||||
def chdir_to_wiki():
|
||||
"""
|
||||
For most operations, we want the current directory to be the wiki folder.
|
||||
|
@ -12,6 +12,13 @@ from typing import Any
|
||||
from tzk.util import fail
|
||||
|
||||
|
||||
DEFAULT_INIT_OPTS = {
|
||||
'wiki_name': 'wiki',
|
||||
'tw_version_spec': '^5.1.23',
|
||||
'author': None,
|
||||
}
|
||||
|
||||
|
||||
class ConfigurationManager:
|
||||
def __init__(self):
|
||||
self.initialize_cm()
|
||||
|
13
tzk/tw.py
13
tzk/tw.py
@ -5,7 +5,7 @@ import os
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
from textwrap import dedent
|
||||
from typing import Optional, Sequence
|
||||
from typing import Callable, Optional, Sequence
|
||||
|
||||
from tzk import config
|
||||
from tzk import git
|
||||
@ -159,9 +159,13 @@ def _initial_commit() -> None:
|
||||
print('\n'.join(output.split('\n')[0:2]))
|
||||
|
||||
|
||||
def install(wiki_name: str, tw_version_spec: str, author: Optional[str]):
|
||||
def install(wiki_name: str, tw_version_spec: str, author: Optional[str],
|
||||
_tw_func: Optional[Callable[[str], None]] = None):
|
||||
"""
|
||||
Install TiddlyWiki on Node.js in the current directory and set up a new wiki.
|
||||
|
||||
If _tw_func is provided, call it to create the TiddlyWiki in the new tzk repository
|
||||
rather than the default routine. It receives one argument, the name of the new wiki.
|
||||
"""
|
||||
# assert: caller has checked npm and git are installed
|
||||
|
||||
@ -170,7 +174,12 @@ def install(wiki_name: str, tw_version_spec: str, author: Optional[str]):
|
||||
|
||||
_init_tzk_config()
|
||||
_init_npm(wiki_name, tw_version_spec, author)
|
||||
|
||||
if _tw_func is not None:
|
||||
_tw_func(wiki_name)
|
||||
else:
|
||||
_init_tw(wiki_name)
|
||||
|
||||
_add_filesystem_plugins(wiki_name)
|
||||
_init_gitignore()
|
||||
_initial_commit()
|
||||
|
Loading…
Reference in New Issue
Block a user