зеркало из https://github.com/github/docs.git
remove overloaded helper functions and move code directly where it is used
This commit is contained in:
Родитель
355f074c89
Коммит
33f93e39c7
|
@ -7,6 +7,7 @@ const yaml = require('js-yaml')
|
|||
const contentDir = path.join(process.cwd(), 'content')
|
||||
const frontmatter = require('@github-docs/frontmatter')
|
||||
const getApplicableVersions = require('./get-applicable-versions')
|
||||
const removeFPTFromPath = require('./remove-fpt-from-path')
|
||||
|
||||
// the product order is determined by data/products.yml
|
||||
const productsFile = path.join(process.cwd(), 'data/products.yml')
|
||||
|
@ -46,7 +47,7 @@ sortedProductIds.forEach(productId => {
|
|||
const toc = slash(path.join(dir, 'index.md'))
|
||||
const { data } = frontmatter(fs.readFileSync(toc, 'utf8'))
|
||||
const applicableVersions = getApplicableVersions(data.versions, toc)
|
||||
const href = slash(path.join('/', applicableVersions[0], productId))
|
||||
const href = removeFPTFromPath(`/${applicableVersions[0]}/${productId}`)
|
||||
|
||||
internalProducts[productId] = {
|
||||
id: productId,
|
||||
|
|
|
@ -9,7 +9,7 @@ const latestNonNumberedRelease = 'latest'
|
|||
const plans = [
|
||||
{
|
||||
plan: 'free-pro-team',
|
||||
planTitle: 'Free, Pro, and Team',
|
||||
planTitle: process.env.FEATURE_REMOVE_FPT ? 'Dotcom TBD' : 'Free, Pro, and Team',
|
||||
releases: [latestNonNumberedRelease],
|
||||
latestRelease: latestNonNumberedRelease,
|
||||
nonEnterpriseDefault: true, // permanent way to refer to this plan if the name changes
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
const findPage = require('./find-page')
|
||||
const getApplicableVersions = require('./get-applicable-versions')
|
||||
|
||||
module.exports = function findPageInVersion (href, pageMap, redirects, languageCode, version, isDotcomOnly = false) {
|
||||
// findPage() will throw an error if an English page can't be found
|
||||
const page = findPage(href, pageMap, redirects, languageCode)
|
||||
if (!page) return null
|
||||
|
||||
// if the link is on the homepage, return the page as soon as it's found
|
||||
if (version === 'homepage') return page
|
||||
|
||||
// if the link is dotcom-only, return the page as soon as it's found
|
||||
if (isDotcomOnly) return page
|
||||
|
||||
// otherwise, get the versions that the found page is available in
|
||||
const applicableVersions = getApplicableVersions(page.versions, page.fullPath)
|
||||
|
||||
// return null if the found page's available versions do not include the specified version
|
||||
if (!applicableVersions.includes(version)) return null
|
||||
|
||||
return page
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
const slash = require('slash')
|
||||
const patterns = require('./patterns')
|
||||
const allVersions = Object.keys(require('./all-versions'))
|
||||
const { getVersionedPathWithLanguage } = require('./path-utils')
|
||||
|
||||
module.exports = function findPage (href, pageMap, redirects = {}, languageCode = 'en', sourceLanguage = null) {
|
||||
// Convert Windows backslashes to forward slashes
|
||||
// remove trailing slash
|
||||
href = slash(href).replace(patterns.trailingSlash, '$1')
|
||||
|
||||
// do an initial lookup on the path as-is
|
||||
let page = pageMap[removeFragment(href)]
|
||||
if (page) return page
|
||||
|
||||
// check all potential versions
|
||||
const versionedPathsToCheck = [...new Set(allVersions.map(version => {
|
||||
return getVersionedPathWithLanguage(href, version, languageCode)
|
||||
}))]
|
||||
|
||||
// get the first found path of the page (account for redirects)
|
||||
let pathToPage = versionedPathsToCheck.find(path => {
|
||||
path = redirects[path] || path
|
||||
return pageMap[removeFragment(path)]
|
||||
})
|
||||
|
||||
// need to account for redirects again
|
||||
pathToPage = redirects[pathToPage] || pathToPage
|
||||
|
||||
// try finding the page again
|
||||
page = pageMap[removeFragment(pathToPage)]
|
||||
|
||||
if (page) return page
|
||||
|
||||
if (process.env.NODE_ENV !== 'test' && languageCode === 'en') {
|
||||
const error = sourceLanguage
|
||||
? `href not found in ${sourceLanguage} pages (no English fallback found)`
|
||||
: 'href not found'
|
||||
|
||||
// if English page can't be found, throw an error
|
||||
// because these errors should be surfaced and fixed right away
|
||||
if (sourceLanguage === 'en') {
|
||||
throw new Error(`${error}: ${href}`)
|
||||
} else {
|
||||
console.error(`${error}: ${href}`)
|
||||
}
|
||||
}
|
||||
|
||||
// if English page can't be found in tests, don't throw an error
|
||||
// or the tests will stall
|
||||
if (process.env.NODE_ENV === 'test' && languageCode === 'en') {
|
||||
if (sourceLanguage === 'en') console.log(`href not found: ${href}`)
|
||||
return null
|
||||
}
|
||||
|
||||
// if localized page can't be found, fall back to English
|
||||
// because localized content is not yet synced
|
||||
if (languageCode !== 'en') {
|
||||
// pass the source language so we can surface it in error messages
|
||||
return findPage(href, pageMap, redirects, 'en', languageCode)
|
||||
}
|
||||
}
|
||||
|
||||
// some redirects include fragments
|
||||
// need to remove the fragment to find the page
|
||||
function removeFragment (path) {
|
||||
if (!path) return
|
||||
|
||||
return path.replace(/#.*$/, '')
|
||||
}
|
|
@ -2,9 +2,8 @@ const path = require('path')
|
|||
const assert = require('assert')
|
||||
const Liquid = require('liquid')
|
||||
const liquid = new Liquid.Engine()
|
||||
const { getPathWithLanguage } = require('../path-utils')
|
||||
const LiquidTag = require('./liquid-tag')
|
||||
const findPageInVersion = require('../find-page-in-version')
|
||||
const getApplicableVersions = require('../get-applicable-versions')
|
||||
|
||||
// This class supports a set of link tags. Each tag expects one parameter, a language-agnostic href:
|
||||
//
|
||||
|
@ -52,17 +51,21 @@ module.exports = class Link extends LiquidTag {
|
|||
}
|
||||
|
||||
// add language code
|
||||
fullPath = getPathWithLanguage(fullPath, ctx.currentLanguage)
|
||||
fullPath = path.join('/', ctx.currentLanguage, fullPath)
|
||||
|
||||
// find the page based on the full path
|
||||
const page = findPageInVersion(fullPath, ctx.pages, ctx.redirects, ctx.currentLanguage, ctx.currentVersion)
|
||||
const page = ctx.pages[fullPath] || ctx.pages[ctx.redirects[fullPath]]
|
||||
|
||||
// if found page should NOT render in current version, return early with an empty string
|
||||
// also return if it's a hidden link on a non-hidden page (hidden links on hidden pages are OK)
|
||||
// return an empty string if it's a hidden link on a non-hidden page (hidden links on hidden pages are OK)
|
||||
if (!page || (page.hidden && !ctx.page.hidden)) {
|
||||
return ''
|
||||
}
|
||||
|
||||
// also return early if the found page should not render in current version
|
||||
if (!getApplicableVersions(page.versions).includes(ctx.currentVersion)) {
|
||||
return ''
|
||||
}
|
||||
|
||||
// find and render the props
|
||||
const title = opts.shortTitle
|
||||
? await page.renderProp('shortTitle', ctx, { textOnly: true, encodeEntities: true })
|
||||
|
|
|
@ -1,77 +1,11 @@
|
|||
const slash = require('slash')
|
||||
const path = require('path')
|
||||
const patterns = require('./patterns')
|
||||
const { deprecated, latest } = require('./enterprise-server-releases')
|
||||
const { latest } = require('./enterprise-server-releases')
|
||||
const allProducts = require('./all-products')
|
||||
const allVersions = require('./all-versions')
|
||||
const supportedVersions = new Set(Object.keys(allVersions))
|
||||
const { getNewVersionedPath } = require('./old-versions-utils')
|
||||
|
||||
// This function constructs an appropriate versioned path for any given HREF.
|
||||
// NOTE: this gets called by findPage and various other functions, and
|
||||
// has to return a proper versioned link given a wide variety of incoming
|
||||
// modern or legacy-formatted links, so it is somewhat overloaded. At some point
|
||||
// this could probably be broken up into separate functions to handle different incoming
|
||||
// paths. But it is currently optimized to handle lots of edge cases.
|
||||
function getVersionedPathWithoutLanguage (href, version) {
|
||||
// Start clean without language code or trailing slash
|
||||
href = getPathWithoutLanguage(href.replace(patterns.trailingSlash, '$1'))
|
||||
|
||||
// If this is an old versioned path that includes a deprecated version, do not change!
|
||||
// example: /enterprise/11.10.340/admin/articles/upgrading-to-the-latest-release
|
||||
const oldEnterpriseVersionNumber = href.match(patterns.getEnterpriseVersionNumber)
|
||||
if (oldEnterpriseVersionNumber && deprecated.includes(oldEnterpriseVersionNumber[1])) {
|
||||
return href
|
||||
}
|
||||
|
||||
// Try to derive the current version from the path
|
||||
// example: enterprise-server@2.22 or free-pro-team@latest
|
||||
let versionFromPath = getVersionStringFromPath(href)
|
||||
|
||||
// If a supported version was found, add it to the path so we can go through the rest of the checks
|
||||
if (supportedVersions.has(versionFromPath)) {
|
||||
href = href.replace(href.split('/')[1], versionFromPath)
|
||||
}
|
||||
|
||||
// If a currently supported version was NOT found...
|
||||
let productObjectFromPath
|
||||
if (!supportedVersions.has(versionFromPath)) {
|
||||
// First check if the segment is instead a current product;
|
||||
// example: /admin/foo or /desktop/foo
|
||||
productObjectFromPath = allProducts[versionFromPath]
|
||||
|
||||
// If so, add the first supported version for that product to the href
|
||||
// (this is just to get a path with all the expected segments; the version will be updated later if needed)
|
||||
if (productObjectFromPath) {
|
||||
href = path.join('/', productObjectFromPath.versions[0], href)
|
||||
versionFromPath = productObjectFromPath.versions[0]
|
||||
} else {
|
||||
// Otherwise, this may be an old path that should be converted to new path;
|
||||
// OLD: /enterprise/2.22/admin/installation OR /enterprise/admin/installation
|
||||
// NEW: /enterprise-server@2.22/admin/installation
|
||||
href = getNewVersionedPath(href)
|
||||
versionFromPath = getVersionStringFromPath(href)
|
||||
}
|
||||
}
|
||||
|
||||
// If not previously found, derive the product object from the path (e.g., github or admin)
|
||||
if (!productObjectFromPath) {
|
||||
productObjectFromPath = getProductObjectFromPath(href)
|
||||
}
|
||||
|
||||
// If the product's versions don't include the specified version, nothing to change!
|
||||
if (productObjectFromPath && !productObjectFromPath.versions.includes(version)) {
|
||||
return slash(href)
|
||||
}
|
||||
|
||||
// Update the version and return the path
|
||||
return slash(href.replace(versionFromPath, version))
|
||||
}
|
||||
|
||||
// Add language code to a versioned path
|
||||
function getVersionedPathWithLanguage (href, version, languageCode) {
|
||||
return getPathWithLanguage(getVersionedPathWithoutLanguage(href, version), languageCode)
|
||||
}
|
||||
const nonEnterpriseDefaultVersion = require('./non-enterprise-default-version')
|
||||
|
||||
// Add the language to the given HREF
|
||||
// /articles/foo -> /en/articles/foo
|
||||
|
@ -100,9 +34,15 @@ function getVersionStringFromPath (href) {
|
|||
return 'homepage'
|
||||
}
|
||||
|
||||
// Check if the first segment is a supported version
|
||||
// Get the first segment
|
||||
const versionFromPath = href.split('/')[1]
|
||||
|
||||
// If the first segment is a supported product, assume this is FPT
|
||||
if (allProducts[versionFromPath]) {
|
||||
return nonEnterpriseDefaultVersion
|
||||
}
|
||||
|
||||
// Otherwise, check if it's a supported version
|
||||
if (supportedVersions.has(versionFromPath)) {
|
||||
return versionFromPath
|
||||
}
|
||||
|
@ -133,9 +73,12 @@ function getVersionObjectFromPath (href) {
|
|||
// Return the product segment from the path
|
||||
function getProductStringFromPath (href) {
|
||||
href = getPathWithoutLanguage(href)
|
||||
const productString = href.split('/')[2]
|
||||
|
||||
return productString || 'homepage'
|
||||
if (href === '/') return 'homepage'
|
||||
|
||||
return allProducts[href.split('/')[2]]
|
||||
? href.split('/')[2]
|
||||
: href.split('/')[1]
|
||||
}
|
||||
|
||||
// Return the corresponding object for the product segment in a path
|
||||
|
@ -146,8 +89,6 @@ function getProductObjectFromPath (href) {
|
|||
}
|
||||
|
||||
module.exports = {
|
||||
getVersionedPathWithLanguage,
|
||||
getVersionedPathWithoutLanguage,
|
||||
getPathWithLanguage,
|
||||
getPathWithoutLanguage,
|
||||
getPathWithoutVersion,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
const assert = require('assert')
|
||||
const path = require('path')
|
||||
const patterns = require('./patterns')
|
||||
const pathUtils = require('./path-utils')
|
||||
const getApplicableVersions = require('./get-applicable-versions')
|
||||
const allVersions = require('./all-versions')
|
||||
const removeFPTFromPath = require('./remove-fpt-from-path')
|
||||
|
||||
class Permalink {
|
||||
constructor (languageCode, pageVersion, relativePath, title) {
|
||||
|
@ -14,7 +14,7 @@ class Permalink {
|
|||
|
||||
const permalinkSuffix = this.constructor.relativePathToSuffix(relativePath)
|
||||
|
||||
this.href = pathUtils.getVersionedPathWithLanguage(permalinkSuffix, pageVersion, languageCode)
|
||||
this.href = removeFPTFromPath(path.join('/', languageCode, pageVersion, permalinkSuffix))
|
||||
|
||||
this.pageVersionTitle = allVersions[pageVersion].versionTitle
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const patterns = require('../patterns')
|
||||
const { latest } = require('../enterprise-server-releases')
|
||||
const { getVersionedPathWithLanguage } = require('../path-utils')
|
||||
const { getPathWithoutLanguage } = require('../path-utils')
|
||||
|
||||
// This function takes a known pre-migration path from developer.github.com and
|
||||
// infers and returns a current, correct docs.github.com path.
|
||||
|
@ -73,7 +73,7 @@ module.exports = function getDocsPathFromDeveloperPath (oldDeveloperPath, allRed
|
|||
|
||||
// old developer routes that include 'enterprise-admin' should always redirect to enterprise server
|
||||
if (fragment && newPath.includes('/rest/reference/enterprise-admin') && !patterns.enterpriseServer.test(newPath)) {
|
||||
newPath = getVersionedPathWithLanguage(newPath, `enterprise-server@${latest}`, 'en')
|
||||
newPath = `/en/enterprise-server@${latest}${getPathWithoutLanguage(newPath)}`
|
||||
}
|
||||
|
||||
// show an error if the page to be redirected to doesn't exist
|
||||
|
|
|
@ -57,13 +57,22 @@ module.exports = function getOldPathsFromPath (currentPath, languageCode, curren
|
|||
// ------ BEGIN MODERN VERSION FORMAT REPLACEMENTS ------//
|
||||
if (currentlySupportedVersions.includes(currentVersion) || versionSatisfiesRange(currentVersion, `>${lastReleaseWithLegacyFormat}`)) {
|
||||
(new Set(oldPaths)).forEach(oldPath => {
|
||||
// create old path /github from new path /free-pro-team@latest/github
|
||||
oldPaths.add(oldPath
|
||||
.replace(`/${nonEnterpriseDefaultVersion}`, ''))
|
||||
if (!process.env.FEATURE_REMOVE_FPT) {
|
||||
// create old path /github from new path /free-pro-team@latest/github
|
||||
oldPaths.add(oldPath
|
||||
.replace(`/${nonEnterpriseDefaultVersion}`, ''))
|
||||
|
||||
// create old path /free-pro-team/github from new path /free-pro-team@latest/github
|
||||
oldPaths.add(oldPath
|
||||
.replace('@latest', ''))
|
||||
// create old path /free-pro-team/github from new path /free-pro-team@latest/github
|
||||
oldPaths.add(oldPath
|
||||
.replace('@latest', ''))
|
||||
}
|
||||
|
||||
// TODO THIS ONE IS TRICKY BECAUSE OF VERSIONS TO ENABLE
|
||||
// if (process.env.FEATURE_REMOVE_FPT) {
|
||||
// // create old path /free-pro-team@latest/github from new path /github
|
||||
// oldPaths.add(oldPath
|
||||
// .replace(`/${nonEnterpriseDefaultVersion}`, ''))
|
||||
// }
|
||||
|
||||
// create old path /enterprise/<version> from new path /enterprise-server@<version>
|
||||
oldPaths.add(oldPath
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
const path = require('path')
|
||||
const patterns = require('../patterns')
|
||||
const { getVersionedPathWithLanguage } = require('../path-utils')
|
||||
const supportedVersions = new Set(Object.keys(require('../all-versions')))
|
||||
const getOldPathsFromPermalink = require('./get-old-paths-from-permalink')
|
||||
const removeFPTFromPath = require('../remove-fpt-from-path')
|
||||
const { getVersionStringFromPath } = require('../path-utils')
|
||||
const { getNewVersionedPath } = require('../old-versions-utils')
|
||||
|
||||
module.exports = function generateRedirectsForPermalinks (permalinks, redirectFrontmatter) {
|
||||
// account for Array or String frontmatter entries
|
||||
|
@ -33,7 +36,9 @@ module.exports = function generateRedirectsForPermalinks (permalinks, redirectFr
|
|||
}
|
||||
|
||||
// get the old path for the current permalink version
|
||||
const versionedFrontmatterOldPath = getVersionedPathWithLanguage(frontmatterOldPath, permalink.pageVersion, permalink.languageCode)
|
||||
let versionedFrontmatterOldPath = path.join('/', permalink.languageCode, getNewVersionedPath(frontmatterOldPath))
|
||||
const versionFromPath = getVersionStringFromPath(versionedFrontmatterOldPath)
|
||||
versionedFrontmatterOldPath = removeFPTFromPath(versionedFrontmatterOldPath.replace(versionFromPath, permalink.pageVersion))
|
||||
|
||||
// add it to the redirects object
|
||||
redirects[versionedFrontmatterOldPath] = permalink.href
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
const path = require('path')
|
||||
const slash = require('slash')
|
||||
const patterns = require('../patterns')
|
||||
const { latest } = require('../enterprise-server-releases')
|
||||
const getOldPathsFromPermalink = require('../redirects/get-old-paths-from-permalink')
|
||||
const getDocsPathFromDevPath = require('../redirects/get-docs-path-from-developer-path')
|
||||
const DEVELOPER_ROUTES = require('../redirects/static/developer-docs-routes-for-supported-versions')
|
||||
const ARCHIVED_ROUTES = require('../redirects/static/archived-routes-from-213-to-217')
|
||||
const nonEnterpriseDefaultVersion = require('../non-enterprise-default-version')
|
||||
|
||||
// This function runs at server warmup and precompiles possible redirect routes.
|
||||
// It outputs them in key-value pairs within a neat Javascript object: { oldPath: newPath }
|
||||
|
@ -59,27 +56,6 @@ module.exports = function precompileRedirects (pageList, pageMap) {
|
|||
allRedirects[developerRouteWithoutVersion] = newPathOnLatestVersion
|
||||
allRedirects[developerRouteWithLanguageWithoutVersion] = newPathOnLatestVersion
|
||||
}
|
||||
|
||||
// given a developer route like `/enterprise/2.19/v3/activity`,
|
||||
// add a veriation like `/enterprise/2.19/user/v3/activity`;
|
||||
// we need to do this because all links in content get rewritten
|
||||
// by lib/rewrite-local-links to include `/user`
|
||||
if (developerRoute.includes('/enterprise/')) {
|
||||
const developerRouteWithUserPath = developerRoute.replace(/\/(v[34])/, '/user/$1')
|
||||
const developerRouteWithUserPathAndLanguage = `/en${developerRouteWithUserPath}`
|
||||
allRedirects[developerRouteWithUserPath] = newPath
|
||||
allRedirects[developerRouteWithUserPathAndLanguage] = newPath
|
||||
}
|
||||
|
||||
// given a developer route like `/v3/gists/comments`,
|
||||
// add a veriation like `/free-pro-team@latest/v3/gists/comments`;
|
||||
// again, we need to do this because all links in content get rewritten
|
||||
if (!developerRoute.startsWith('/enterprise/')) {
|
||||
const developerRouteWithVersion = slash(path.join(nonEnterpriseDefaultVersion, developerRoute))
|
||||
const developerRouteWithVersionAndLanguage = `/en/${developerRouteWithVersion}`
|
||||
allRedirects[developerRouteWithVersion] = newPath
|
||||
allRedirects[developerRouteWithVersionAndLanguage] = newPath
|
||||
}
|
||||
})
|
||||
|
||||
return allRedirects
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
const slash = require('slash')
|
||||
const patterns = require('./patterns')
|
||||
const nonEnterpriseDefaultVersion = require('./non-enterprise-default-version')
|
||||
|
||||
module.exports = function removeFPTFromPath (path) {
|
||||
path = process.env.FEATURE_REMOVE_FPT
|
||||
? slash(path.replace(`/${nonEnterpriseDefaultVersion}`, ''))
|
||||
: path
|
||||
|
||||
return path.replace(patterns.trailingSlash, '$1')
|
||||
}
|
|
@ -1,7 +1,12 @@
|
|||
const externalRedirects = Object.keys(require('./redirects/external-sites'))
|
||||
const pathUtils = require('./path-utils')
|
||||
const assert = require('assert')
|
||||
const path = require('path')
|
||||
const externalRedirects = Object.keys(require('./redirects/external-sites'))
|
||||
const { getPathWithoutLanguage, getVersionStringFromPath } = require('./path-utils')
|
||||
const { getNewVersionedPath } = require('./old-versions-utils')
|
||||
const patterns = require('./patterns')
|
||||
const { latest } = require('./enterprise-server-releases')
|
||||
const nonEnterpriseDefaultVersion = require('./non-enterprise-default-version')
|
||||
const removeFPTFromPath = require('./remove-fpt-from-path')
|
||||
const allVersions = require('./all-versions')
|
||||
const supportedVersions = Object.keys(allVersions)
|
||||
const supportedPlans = Object.values(allVersions).map(v => v.plan)
|
||||
|
@ -28,7 +33,6 @@ function getNewHref (link, languageCode, version) {
|
|||
if (externalRedirects.includes(href)) return
|
||||
|
||||
let newHref
|
||||
|
||||
// If the link has a hardcoded plan or version in it, do not update the version, just add the language code
|
||||
// Examples:
|
||||
// /enterprise-server@2.20/rest/reference/oauth-authorizations
|
||||
|
@ -36,15 +40,40 @@ function getNewHref (link, languageCode, version) {
|
|||
// /enterprise-server@latest/rest/reference/oauth-authorizations (this redirects to the latest version)
|
||||
const firstLinkSegment = href.split('/')[1]
|
||||
if ([...supportedPlans, ...supportedVersions, 'enterprise-server@latest'].includes(firstLinkSegment)) {
|
||||
newHref = pathUtils.getPathWithLanguage(href, languageCode)
|
||||
newHref = path.join('/', languageCode, href)
|
||||
}
|
||||
|
||||
// If link is dotcom-only, just get the language code
|
||||
// Otherwise, get the versioned path with language code
|
||||
if (!newHref) {
|
||||
newHref = link.hasClass('dotcom-only')
|
||||
? pathUtils.getVersionedPathWithLanguage(href, nonEnterpriseDefaultVersion, languageCode)
|
||||
: pathUtils.getVersionedPathWithLanguage(href, version, languageCode)
|
||||
// start clean with no language (TOC pages already include the lang codes via lib/liquid-tags/link.js)
|
||||
const hrefWithoutLang = getPathWithoutLanguage(href).replace(patterns.trailingSlash, '$1')
|
||||
|
||||
// normalize any legacy links so they conform to new link structure
|
||||
newHref = path.join('/', languageCode, getNewVersionedPath(hrefWithoutLang))
|
||||
|
||||
// get the current version from the link
|
||||
const versionFromHref = getVersionStringFromPath(newHref)
|
||||
|
||||
// ------ BEGIN ONE-OFF OVERRIDES ------//
|
||||
// dotcom-only links always point to dotcom
|
||||
if (link.hasClass('dotcom-only')) {
|
||||
version = nonEnterpriseDefaultVersion
|
||||
}
|
||||
|
||||
// desktop links always point to dotcom
|
||||
if (patterns.desktop.test(hrefWithoutLang)) {
|
||||
version = nonEnterpriseDefaultVersion
|
||||
}
|
||||
|
||||
// admin links always point to Enterprise
|
||||
if (patterns.adminProduct.test(hrefWithoutLang)) {
|
||||
version = `enterprise-server@${latest}`
|
||||
}
|
||||
// ------ END ONE-OFF OVERRIDES ------//
|
||||
|
||||
// update the version in the link
|
||||
newHref = removeFPTFromPath(newHref.replace(versionFromHref, version))
|
||||
}
|
||||
|
||||
if (href !== newHref) link.attr('href', newHref)
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
const path = require('path')
|
||||
const findPageInVersion = require('./find-page-in-version')
|
||||
const products = Object.values(require('../lib/all-products'))
|
||||
const { getVersionedPathWithLanguage, getPathWithLanguage } = require('./path-utils')
|
||||
const products = Object.values(require('./all-products'))
|
||||
const languageCodes = Object.keys(require('./languages'))
|
||||
const addTitlesToTree = require('./site-tree-titles')
|
||||
const allVersions = Object.keys(require('./all-versions'))
|
||||
const { getVersionStringFromPath } = require('./path-utils')
|
||||
const getApplicableVersions = require('./get-applicable-versions')
|
||||
const removeFPTFromPath = require('./remove-fpt-from-path')
|
||||
|
||||
// This module builds a localized tree of every page on the site
|
||||
// It includes single-source pages that have different variants
|
||||
|
@ -35,16 +36,20 @@ module.exports = async function buildSiteTree (pageMap, site, redirects) {
|
|||
return
|
||||
}
|
||||
|
||||
// we don't want versioned product links because these links already have a default version in them
|
||||
product.href = getPathWithLanguage(item.href, languageCode)
|
||||
product.href = path.join('/', languageCode, item.href)
|
||||
|
||||
// find the product TOC page and get TOC items
|
||||
const page = findPageInVersion(item.href, pageMap, redirects, languageCode, version)
|
||||
// find the product TOC page so we have access to the TOC items
|
||||
const page = pageMap[item.href] || pageMap[redirects[item.href]]
|
||||
|
||||
// skip if page can't be found in this version
|
||||
if (!page) return
|
||||
if (!getApplicableVersions(page.versions).includes(version)) return
|
||||
|
||||
product.categories = buildCategoriesTree(page.tocItems, product.href, pageMap, redirects, version, languageCode)
|
||||
// item.hrefs have a default version via lib/all-products, so update to the current version
|
||||
const versionFromPath = getVersionStringFromPath(item.href)
|
||||
const versionedProductHref = removeFPTFromPath(path.join('/', languageCode, item.href.replace(versionFromPath, version)))
|
||||
|
||||
product.categories = buildCategoriesTree(page.tocItems, versionedProductHref, pageMap, redirects, version)
|
||||
|
||||
productTree[item.id] = product
|
||||
return null
|
||||
|
@ -59,24 +64,21 @@ module.exports = async function buildSiteTree (pageMap, site, redirects) {
|
|||
return siteTree
|
||||
}
|
||||
|
||||
function buildCategoriesTree (tocItems, productHref, pageMap, redirects, version, languageCode) {
|
||||
function buildCategoriesTree (tocItems, versionedProductHref, pageMap, redirects, version) {
|
||||
const categoryTree = {}
|
||||
|
||||
// for every category in a product TOC...
|
||||
tocItems.forEach(item => {
|
||||
const category = {}
|
||||
|
||||
const categoryHref = path.join(productHref, item.href)
|
||||
|
||||
// we DO want versioned category links
|
||||
const versionedCategoryHref = getVersionedPathWithLanguage(categoryHref, version, languageCode)
|
||||
category.href = versionedCategoryHref
|
||||
category.href = path.join(versionedProductHref, item.href)
|
||||
|
||||
// find the category TOC page and get its TOC items
|
||||
const page = findPageInVersion(versionedCategoryHref, pageMap, redirects, languageCode, version)
|
||||
const page = pageMap[category.href] || pageMap[redirects[category.href]]
|
||||
|
||||
// skip if page can't be found in this version
|
||||
if (!page) return
|
||||
if (!getApplicableVersions(page.versions).includes(version)) return
|
||||
|
||||
category.title = page.shortTitle || page.title
|
||||
|
||||
|
@ -92,19 +94,19 @@ function buildCategoriesTree (tocItems, productHref, pageMap, redirects, version
|
|||
// if TOC contains maptopics, build a maptopics tree
|
||||
// otherwise build an articles tree
|
||||
if (hasMaptopics) {
|
||||
category.maptopics = buildMaptopicsTree(page.tocItems, versionedCategoryHref, pageMap, redirects, version, languageCode)
|
||||
category.maptopics = buildMaptopicsTree(page.tocItems, category.href, pageMap, redirects, version)
|
||||
} else {
|
||||
category.articles = buildArticlesTree(page.tocItems, versionedCategoryHref, pageMap, redirects, version, languageCode)
|
||||
category.articles = buildArticlesTree(page.tocItems, category.href, pageMap, redirects, version)
|
||||
}
|
||||
}
|
||||
|
||||
categoryTree[versionedCategoryHref] = category
|
||||
categoryTree[category.href] = category
|
||||
})
|
||||
|
||||
return categoryTree
|
||||
}
|
||||
|
||||
function buildMaptopicsTree (tocItems, versionedCategoryHref, pageMap, redirects, version, languageCode) {
|
||||
function buildMaptopicsTree (tocItems, versionedCategoryHref, pageMap, redirects, version) {
|
||||
const maptopicTree = {}
|
||||
|
||||
// for every maptopic in a category TOC...
|
||||
|
@ -113,14 +115,14 @@ function buildMaptopicsTree (tocItems, versionedCategoryHref, pageMap, redirects
|
|||
.forEach(item => {
|
||||
const maptopic = {}
|
||||
|
||||
const versionedMaptopicHref = path.join(versionedCategoryHref, item.href)
|
||||
maptopic.href = versionedMaptopicHref
|
||||
maptopic.href = path.join(versionedCategoryHref, item.href)
|
||||
|
||||
// find the category TOC page and get its TOC items
|
||||
const page = findPageInVersion(versionedMaptopicHref, pageMap, redirects, languageCode, version)
|
||||
const page = pageMap[maptopic.href] || pageMap[redirects[maptopic.href]]
|
||||
|
||||
// skip if page can't be found in this version
|
||||
if (!page) return
|
||||
if (!getApplicableVersions(page.versions).includes(version)) return
|
||||
|
||||
// if this is not a maptopic, return early
|
||||
if (!page.mapTopic) return
|
||||
|
@ -130,15 +132,15 @@ function buildMaptopicsTree (tocItems, versionedCategoryHref, pageMap, redirects
|
|||
maptopic.hidden = page.hidden
|
||||
// make the child articles accessible to the page object for maptopic rendering
|
||||
maptopic.childArticles = getChildArticles(tocItems, item.href)
|
||||
maptopic.articles = buildArticlesTree(maptopic.childArticles, versionedCategoryHref, pageMap, redirects, version, languageCode)
|
||||
maptopic.articles = buildArticlesTree(maptopic.childArticles, versionedCategoryHref, pageMap, redirects, version)
|
||||
|
||||
maptopicTree[versionedMaptopicHref] = maptopic
|
||||
maptopicTree[maptopic.href] = maptopic
|
||||
})
|
||||
|
||||
return maptopicTree
|
||||
}
|
||||
|
||||
function buildArticlesTree (tocItems, versionedCategoryHref, pageMap, redirects, version, languageCode) {
|
||||
function buildArticlesTree (tocItems, versionedCategoryHref, pageMap, redirects, version) {
|
||||
const articleTree = {}
|
||||
|
||||
// REST categories may not have TOC items
|
||||
|
@ -148,18 +150,18 @@ function buildArticlesTree (tocItems, versionedCategoryHref, pageMap, redirects,
|
|||
tocItems.forEach(item => {
|
||||
const article = {}
|
||||
|
||||
const versionedArticleHref = path.join(versionedCategoryHref, item.href)
|
||||
article.href = versionedArticleHref
|
||||
article.href = path.join(versionedCategoryHref, item.href)
|
||||
|
||||
// find the category TOC page and get its TOC items
|
||||
const page = findPageInVersion(versionedArticleHref, pageMap, redirects, languageCode, version)
|
||||
const page = pageMap[article.href] || pageMap[redirects[article.href]]
|
||||
|
||||
// skip if page can't be found in this version
|
||||
if (!page) return
|
||||
if (!getApplicableVersions(page.versions).includes(version)) return
|
||||
|
||||
article.title = page.shortTitle || page.title
|
||||
|
||||
articleTree[versionedArticleHref] = article
|
||||
articleTree[article.href] = article
|
||||
})
|
||||
|
||||
return articleTree
|
||||
|
|
|
@ -5,7 +5,6 @@ const patterns = require('../lib/patterns')
|
|||
const versionSatisfiesRange = require('../lib/version-satisfies-range')
|
||||
const isArchivedVersion = require('../lib/is-archived-version')
|
||||
const got = require('got')
|
||||
const findPage = require('../lib/find-page')
|
||||
|
||||
// This module handles requests for deprecated GitHub Enterprise versions
|
||||
// by routing them to static content in help-docs-archived-enterprise-versions
|
||||
|
@ -77,7 +76,7 @@ function getFallbackRedirects (req, requestedVersion) {
|
|||
const pathWithNewVersion = req.path.replace(requestedVersion, latest)
|
||||
|
||||
// look for a page with the same path on a currently supported version
|
||||
const currentlySupportedPage = findPage(pathWithNewVersion, req.context.pages, req.context.redirects)
|
||||
const currentlySupportedPage = req.context.pages[pathWithNewVersion] || req.context.pages[req.context.redirects[pathWithNewVersion]]
|
||||
if (!currentlySupportedPage) return
|
||||
|
||||
// get an array of viable old paths
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
const path = require('path')
|
||||
const { getPathWithoutLanguage } = require('../lib/path-utils')
|
||||
const nonEnterpriseDefaultVersion = require('../lib/non-enterprise-default-version')
|
||||
|
||||
module.exports = async (req, res, next) => {
|
||||
if (!req.context.page) return next()
|
||||
|
@ -16,9 +17,6 @@ module.exports = async (req, res, next) => {
|
|||
// drop first '/'
|
||||
pathParts.shift()
|
||||
|
||||
// drop the version segment so pathParts now starts with /product
|
||||
pathParts.shift()
|
||||
|
||||
const productPath = path.posix.join('/', req.context.currentProduct)
|
||||
const product = req.context.siteTree[req.language][req.context.currentVersion].products[req.context.currentProduct]
|
||||
|
||||
|
@ -31,6 +29,19 @@ module.exports = async (req, res, next) => {
|
|||
title: product.title
|
||||
}
|
||||
|
||||
// drop the version segment so pathParts now starts with /product
|
||||
if (!process.env.FEATURE_REMOVE_FPT) {
|
||||
pathParts.shift()
|
||||
}
|
||||
|
||||
if (process.env.FEATURE_REMOVE_FPT) {
|
||||
// if this is not FPT, drop the version segment so pathParts now starts with /product
|
||||
// if this is FPT, there is no version segment so pathParts already starts with /product
|
||||
if (req.context.currentVersion !== nonEnterpriseDefaultVersion) {
|
||||
pathParts.shift()
|
||||
}
|
||||
}
|
||||
|
||||
if (!pathParts[1]) return next()
|
||||
|
||||
// get category path
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
const path = require('path')
|
||||
const rest = require('../../lib/rest')
|
||||
const { getVersionedPathWithLanguage } = require('../../lib/path-utils')
|
||||
const removeFPTFromPath = require('../../lib/remove-fpt-from-path')
|
||||
|
||||
module.exports = async function (req, res, next) {
|
||||
req.context.rest = rest
|
||||
|
||||
// link to include in `Works with GitHub Apps` notes
|
||||
// e.g. /ja/rest/reference/apps or /en/enterprise/2.20/user/rest/reference/apps
|
||||
req.context.restGitHubAppsLink = getVersionedPathWithLanguage(
|
||||
'/developers/apps',
|
||||
req.context.restGitHubAppsLink = removeFPTFromPath(path.join(
|
||||
'/',
|
||||
req.context.currentLanguage,
|
||||
req.context.currentVersion,
|
||||
req.context.currentLanguage
|
||||
)
|
||||
'/developers/apps'
|
||||
))
|
||||
|
||||
// ignore requests to non-REST reference paths
|
||||
if (!req.path.includes('rest/reference')) return next()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
const findPageInVersion = require('../lib/find-page-in-version')
|
||||
const { getVersionedPathWithLanguage } = require('../lib/path-utils')
|
||||
const path = require('path')
|
||||
const removeFPTFromPath = require('../lib/remove-fpt-from-path')
|
||||
|
||||
// this middleware adds properties to the context object
|
||||
module.exports = async (req, res, next) => {
|
||||
|
@ -25,11 +25,10 @@ async function getLinkData (rawLinks, context) {
|
|||
const links = []
|
||||
|
||||
for (const link of rawLinks) {
|
||||
const href = link.href
|
||||
? getVersionedPathWithLanguage(link.href, context.currentVersion, context.currentLanguage)
|
||||
: getVersionedPathWithLanguage(link, context.currentVersion, context.currentLanguage)
|
||||
const linkPath = link.href || link
|
||||
const href = removeFPTFromPath(path.join('/', context.currentLanguage, context.currentVersion, linkPath))
|
||||
|
||||
const linkedPage = findPageInVersion(href, context.pages, context.redirects, context.currentLanguage, context.currentVersion)
|
||||
const linkedPage = context.pages[href] || context.pages[context.redirects[href]]
|
||||
if (!linkedPage) continue
|
||||
|
||||
const opts = { textOnly: true, encodeEntities: true }
|
||||
|
|
|
@ -3,10 +3,8 @@ const { union, uniq } = require('lodash')
|
|||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const { getVersionStringFromPath } = require('../../lib/path-utils')
|
||||
const patterns = require('../../lib/patterns')
|
||||
const { deprecated } = require('../../lib/enterprise-server-releases')
|
||||
const findPageInVersion = require('../../lib/find-page-in-version')
|
||||
const rest = require('../../middleware/contextualizers/rest')
|
||||
const graphql = require('../../middleware/contextualizers/graphql')
|
||||
const contextualize = require('../../middleware/context')
|
||||
|
@ -145,11 +143,8 @@ class LinksChecker {
|
|||
if (gheVersionInLink && deprecated.includes(gheVersionInLink[1])) continue
|
||||
// ------ END ONEOFF EXCLUSIONS -------///
|
||||
|
||||
// the link at this point should include a version via lib/rewrite-local-links
|
||||
const versionFromHref = getVersionStringFromPath(link)
|
||||
|
||||
// look for linked page
|
||||
const linkedPage = findPageInVersion(link, context.pages, context.redirects, this.languageCode, versionFromHref)
|
||||
const linkedPage = context.pages[link] || context.pages[context.redirects[link]]
|
||||
this.checkedLinksCache.add(link)
|
||||
|
||||
if (!linkedPage) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче