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
16 changes: 14 additions & 2 deletions docs/strictdoc_01_user_guide.sdoc
Original file line number Diff line number Diff line change
Expand Up @@ -3947,11 +3947,23 @@ To activate the Diff/Changelog screen, add/edit the strictdoc.toml config file i
"DIFF"
]

With the feature enabled, the editable web server interface displays the corresponding Diff/Changelog screen, where users can select Git revisions to compare for change tracking.

To use the feature with a command-line interface:

.. code::

strictdoc export . --generate-diff-git="HEAD^..HEAD"

.. admonition:: Robust MID-based change tracking
:class: note

For optimal results when using the Diff/Changelog feature in a StrictDoc-based project, it is strongly recommended to enable Machine Identifiers (MIDs) for all project artifacts, such as TEXT, REQUIREMENT, etc.
Without MIDs, StrictDoc cannot ensure accurate change tracking. If a node lacks an MID, StrictDoc is unable to reliably detect whether it has been modified or relocated in subsequent versions of the documentation tree. For further details, refer to [LINK: SECTION-UG-Machine-identifiers-MID].
For optimal results when using the Diff/Changelog feature in a StrictDoc-based project, it is strongly recommended to enable Machine Identifiers (MIDs) for all project artifacts, such as TEXT, REQUIREMENT, and others. Without MIDs, StrictDoc relies on change tracking based on node UIDs, which is less reliable due to at least the following two issues:

1. The need to maintain UIDs for sections and text nodes, not only for requirements.
2. Possible changes to node UIDs. If a node UID changes, for example due to a change in project conventions, StrictDoc cannot reliably determine whether the node has been modified or relocated in later versions of the documentation tree.

For more details, see [LINK: SECTION-UG-Machine-identifiers-MID].
<<<

[[/SECTION]]
Expand Down
4 changes: 3 additions & 1 deletion docs/strictdoc_04_release_notes.sdoc
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ TITLE: Unreleased
[TEXT]
MID: 12345f3b28ea4bfe9ca8afe6b21826a8
STATEMENT: >>>
This release includes the removal of legacy @sdoc markers, several bug fixes, and enhancements for edge cases.
This release includes an enhancement to the Diff/Changelog feature, the removal of legacy @sdoc markers, several bug fixes, and improvements for edge cases.

The Diff/Changelog feature has been extended to support the new --generate-diff-git option which allows generating the Diff/Changelog screens for a given pair of Git revisions.

The legacy ``@sdoc`` marker has been removed from the codebase. From now on, only the ``@relation`` markers are recognized when linking requirements with source code files.

Expand Down
64 changes: 24 additions & 40 deletions strictdoc/cli/cli_arg_parser.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import argparse
import os
from typing import Any, List, Optional
from typing import Any, List, Optional, Tuple

from strictdoc.cli.command_parser_builder import (
CommandParserBuilder,
Expand Down Expand Up @@ -127,6 +127,7 @@ def validate(self) -> None:
class ExportCommandConfig:
def __init__(
self,
*,
input_paths: List[str],
output_dir: Optional[str],
config_path: Optional[str],
Expand All @@ -142,6 +143,8 @@ def __init__(
reqif_multiline_is_xhtml: bool,
reqif_enable_mid: bool,
view: Optional[str],
generate_diff_git: Optional[str],
generate_diff_dirs: Optional[Tuple[str, str]],
chromedriver: Optional[str],
):
assert isinstance(input_paths, list), f"{input_paths}"
Expand All @@ -160,6 +163,8 @@ def __init__(
self.reqif_multiline_is_xhtml: bool = reqif_multiline_is_xhtml
self.reqif_enable_mid: bool = reqif_enable_mid
self.view: Optional[str] = view
self.generate_diff_git: Optional[str] = generate_diff_git
self.generate_diff_dirs: Optional[Tuple[str, str]] = generate_diff_dirs
self.chromedriver: Optional[str] = chromedriver

def get_path_to_config(self) -> str:
Expand Down Expand Up @@ -197,18 +202,6 @@ def __init__(self, output_file: str):
self.output_file: str = output_file


class DiffCommandConfig:
def __init__(
self,
path_to_lhs_tree: str,
path_to_rhs_tree: str,
output_dir: Optional[str],
):
self.path_to_lhs_tree: str = path_to_lhs_tree
self.path_to_rhs_tree: str = path_to_rhs_tree
self.output_dir: Optional[str] = output_dir


class SDocArgsParser:
def __init__(self, args: argparse.Namespace):
self.args: argparse.Namespace = args
Expand Down Expand Up @@ -250,10 +243,6 @@ def is_dump_grammar_command(self) -> bool:
def is_version_command(self) -> bool:
return str(self.args.command) == "version"

@property
def is_diff_command(self) -> bool:
return str(self.args.command) == "diff"

@property
def is_manage_autouid_command(self) -> bool:
return (
Expand All @@ -265,22 +254,24 @@ def get_export_config(self) -> ExportCommandConfig:
project_title: Optional[str] = self.args.project_title

return ExportCommandConfig(
self.args.input_paths,
self.args.output_dir,
self.args.config,
project_title,
self.args.formats,
self.args.fields,
self.args.generate_bundle_document,
self.args.no_parallelization,
self.args.enable_mathjax,
self.args.included_documents,
self.args.filter_nodes,
self.args.reqif_profile,
self.args.reqif_multiline_is_xhtml,
self.args.reqif_enable_mid,
self.args.view,
self.args.chromedriver,
input_paths=self.args.input_paths,
output_dir=self.args.output_dir,
config_path=self.args.config,
project_title=project_title,
formats=self.args.formats,
fields=self.args.fields,
generate_bundle_document=self.args.generate_bundle_document,
no_parallelization=self.args.no_parallelization,
enable_mathjax=self.args.enable_mathjax,
included_documents=self.args.included_documents,
filter_nodes=self.args.filter_nodes,
reqif_profile=self.args.reqif_profile,
reqif_multiline_is_xhtml=self.args.reqif_multiline_is_xhtml,
reqif_enable_mid=self.args.reqif_enable_mid,
view=self.args.view,
generate_diff_git=self.args.generate_diff_git,
generate_diff_dirs=self.args.generate_diff_dirs,
chromedriver=self.args.chromedriver,
)

def get_import_config_reqif(self, _: Any) -> ImportReqIFCommandConfig:
Expand Down Expand Up @@ -317,13 +308,6 @@ def get_server_config(self) -> ServerCommandConfig:
def get_dump_grammar_config(self) -> DumpGrammarCommandConfig:
return DumpGrammarCommandConfig(output_file=self.args.output_file)

def get_diff_config(self) -> DiffCommandConfig:
return DiffCommandConfig(
path_to_lhs_tree=self.args.path_to_lhs_tree,
path_to_rhs_tree=self.args.path_to_rhs_tree,
output_dir=self.args.output_dir,
)


def create_sdoc_args_parser(
testing_args: Optional[argparse.Namespace] = None,
Expand Down
55 changes: 29 additions & 26 deletions strictdoc/cli/command_parser_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,17 @@ def _check_reqif_import_markup(markup: Optional[str]) -> str:
return markup


def _check_git_revisions(git_revisions: str) -> str:
if ".." not in git_revisions:
message = (
"Invalid Git revision pair. "
'The expected format is: "<Git revision>..<Git revision>". '
'Example: "HEAD^..HEAD".'
)
raise argparse.ArgumentTypeError(message)
return git_revisions


def _parse_fields(fields: str) -> List[str]:
fields_array = fields.split(",")
return fields_array
Expand Down Expand Up @@ -125,7 +136,6 @@ def build(self) -> SDocArgumentParser:
self.add_import_command(command_subparsers)
self.add_version_command(command_subparsers)
self.add_dump_command(command_subparsers)
self.add_diff_command(command_subparsers)

return main_parser

Expand Down Expand Up @@ -250,6 +260,24 @@ def add_export_command(
type=str,
help="Choose which view will be exported.",
)
command_parser_export.add_argument(
"--generate-diff-git",
type=_check_git_revisions,
help=(
"Generate Diff/Changelog for a given pair of Git revisions. "
'Example: --generate-diff-git "HEAD^..HEAD"'
),
)
command_parser_export.add_argument(
"--generate-diff-dirs",
"--generate-diff-dirs",
metavar=("OLD_PATH", "NEW_PATH"),
nargs=2,
help=(
"Generate Diff/Changelog for a given pair of local directories. "
'Example: --generate-diff-dirs "./old_path" "./new_path"'
),
)
command_parser_export.add_argument(
"--chromedriver",
type=str,
Expand Down Expand Up @@ -458,28 +486,3 @@ def add_manage_command(
),
)
add_config_argument(command_parser_auto_uid)

@staticmethod
def add_diff_command(
command_subparsers: "argparse._SubParsersAction[SDocArgumentParser]",
) -> None:
diff_command_parser = command_subparsers.add_parser(
"diff",
help="Generate Diff between two SDoc project trees.",
formatter_class=formatter,
)
diff_command_parser.add_argument(
"path_to_lhs_tree",
type=str,
help="Path to the left-hand side project tree.",
)
diff_command_parser.add_argument(
"path_to_rhs_tree",
type=str,
help="Path to the right-hand side project tree.",
)
diff_command_parser.add_argument(
"--output-dir",
type=str,
help="A directory where to output the files to.",
)
11 changes: 0 additions & 11 deletions strictdoc/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
from strictdoc import environment
from strictdoc.cli.cli_arg_parser import (
CLIValidationError,
DiffCommandConfig,
DumpGrammarCommandConfig,
ExportCommandConfig,
ImportExcelCommandConfig,
Expand All @@ -27,7 +26,6 @@
create_sdoc_args_parser,
)
from strictdoc.commands.about_command import AboutCommand
from strictdoc.commands.diff_command import DiffCommand
from strictdoc.commands.dump_grammar_command import DumpGrammarCommand
from strictdoc.commands.manage_autouid_command import ManageAutoUIDCommand
from strictdoc.commands.version_command import VersionCommand
Expand Down Expand Up @@ -139,15 +137,6 @@ def _main(parallelizer: Parallelizer, parser: SDocArgsParser) -> None:
elif parser.is_about_command:
AboutCommand.execute()

elif parser.is_diff_command:
diff_config: DiffCommandConfig = parser.get_diff_config()
project_config = ProjectConfigLoader.load_from_path_or_get_default(
path_to_config=os.getcwd(),
)
DiffCommand.execute(
project_config=project_config, diff_config=diff_config
)

else:
raise NotImplementedError

Expand Down
Loading
Loading