mirror of
https://github.com/odoo/documentation.git
synced 2026-01-02 09:49:17 +07:00
[IMP] redirects: split redirects.txt into multiple, per-version, files
The `redirects.txt` file used to specify redirect rules for renamed or
moved documentation pages is starting to grow too big to be easily
maintainable. The main reason is that the number of redirect rules that
were thought to be required has been largely underestimated when
implementing the 'redirects' extension. At first, we believed that no
guidelines or structure were necessary because only a small amount of
redirect rules would be specified. This proved wrong and the file is now
becoming a mess, making it increasingly difficult to figure out where,
why, when, and if a redirect rule is specified in the file.
As the file is versioned, another issue emerges: conflicts occur every
time a commit is forward-ported to a later version if that commit adds a
redirect rule at the end of the file or at a line that was changed in
the later version. As redirect rules are frequently added, and since
blocks of redirect rules for new versions are added at the end of the
file, this tends to happen a lot.
This commit attempts to hit two birds with one stone by splitting the
`redirects.txt` file into multiple files, one per version. While doing
so, the existing redirect rules are ordered alphabetically and moved
into contextual blocks. Instructions and guidelines on how to create
redirect rules are also listed in the `redirects/MANUAL.md` file. By
sorting the redirect rules and adding them in different files, the
number of conflicts should decrease by a lot.
task-2891912
closes odoo/documentation#2292
X-original-commit: 0417b95514
Signed-off-by: Antoine Vandevenne (anv) <anv@odoo.com>
This commit is contained in:
@@ -11,56 +11,60 @@ TEMPLATE = '<html><head><meta http-equiv="refresh" content="0; url=%s"/></head><
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def generate_redirects(app):
|
||||
path = os.path.join(app.confdir, app.config.redirects_file)
|
||||
if not os.path.exists(path):
|
||||
logger.warning("Could not find redirects file at '%s'", path)
|
||||
return
|
||||
|
||||
source_suffix = next(iter(app.config.source_suffix))
|
||||
def generate_redirects(app):
|
||||
redirects_dir = Path(app.confdir, app.config.redirects_dir)
|
||||
if not redirects_dir.exists():
|
||||
logger.warning("Could not find redirects dir at '%s'", redirects_dir)
|
||||
return
|
||||
|
||||
if not type(app.builder) == builders.StandaloneHTMLBuilder:
|
||||
logger.info("Redirects are only supported by the 'html' builder. Skipping...")
|
||||
return
|
||||
|
||||
with open(path) as redirects:
|
||||
escaped_source_suffix = source_suffix.replace('.', '\.')
|
||||
pattern = re.compile(
|
||||
r'^[ \t]*([\w\-/]+{0})[ \t]+([\w\-/]+{0})[ \t]*(#.*)?$'.format(escaped_source_suffix)
|
||||
)
|
||||
for line in redirects.readlines():
|
||||
# Exclude comment or empty lines
|
||||
if not line.rstrip() or line.startswith('#'):
|
||||
continue
|
||||
source_suffix = next(iter(app.config.source_suffix))
|
||||
escaped_source_suffix = source_suffix.replace('.', '\.')
|
||||
pattern = re.compile(
|
||||
r'^[ \t]*([\w\-/]+{0})[ \t]+([\w\-/]+{0})[ \t]*(?:#.*)?$'.format(escaped_source_suffix)
|
||||
)
|
||||
for redirects_file in redirects_dir.iterdir():
|
||||
if redirects_file.is_dir() or redirects_file.suffix != '.txt':
|
||||
continue
|
||||
|
||||
match_result = pattern.match(line)
|
||||
with redirects_file.open(mode='r') as f:
|
||||
for line in f.readlines():
|
||||
# Exclude comment or empty lines.
|
||||
if not line.rstrip() or line.startswith('#'):
|
||||
continue
|
||||
|
||||
# Log malformed rules
|
||||
if not match_result:
|
||||
logger.error(
|
||||
"Ignoring malformed redirection: {0}"
|
||||
"Please use this format: old_page{1} new_page{1} # optional comment".format(
|
||||
line, source_suffix)
|
||||
)
|
||||
continue
|
||||
# Match a redirect rule in the line.
|
||||
match_result = pattern.match(line)
|
||||
|
||||
# Parse the rule
|
||||
from_file, to_file, _ = match_result.groups()
|
||||
logger.debug("Redirecting '%s' to '%s'", from_file, to_file)
|
||||
# Exclude malformed rules.
|
||||
if not match_result:
|
||||
logger.error(
|
||||
"Ignoring malformed redirect rule: %s\n"
|
||||
"See redirects/MANUAL.md to learn how to make redirect rules.", line
|
||||
)
|
||||
continue
|
||||
|
||||
# Prepare source and destination paths
|
||||
to_path_prefix = '../' * from_file.count('/')
|
||||
from_html_file = from_file.replace(source_suffix, '.html')
|
||||
to_html_file = to_path_prefix + to_file.replace(source_suffix, '.html')
|
||||
absolute_from_path = Path(app.builder.outdir) / from_html_file
|
||||
# Parse the rule.
|
||||
from_file, to_file = match_result.groups()
|
||||
logger.debug("Redirecting '%s' to '%s'", from_file, to_file)
|
||||
|
||||
# Create the redirection
|
||||
absolute_from_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
absolute_from_path.write_text(TEMPLATE % to_html_file)
|
||||
# Prepare the source and destination paths.
|
||||
to_path_prefix = '../' * from_file.count('/')
|
||||
from_html_file = from_file.replace(source_suffix, '.html')
|
||||
to_html_file = to_path_prefix + to_file.replace(source_suffix, '.html')
|
||||
absolute_from_path = Path(app.builder.outdir) / from_html_file
|
||||
|
||||
# Create the redirection.
|
||||
absolute_from_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
absolute_from_path.write_text(TEMPLATE % to_html_file)
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.add_config_value('redirects_file', 'redirects', 'env')
|
||||
app.add_config_value('redirects_dir', 'redirects', 'env')
|
||||
app.connect('builder-inited', generate_redirects)
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user