diff --git a/pages/_document.js b/pages/_document.js index df1e5185f4..881ce73f45 100644 --- a/pages/_document.js +++ b/pages/_document.js @@ -4,7 +4,8 @@ import reset from 'styled-reset' import { global } from '../src/styles' import Router from 'next/router' -const DESCRIPTION = `Open-source version control system for Data Science and` + +const DESCRIPTION = + `Open-source version control system for Data Science and` + ` Machine Learning projects. Track your data, models, and experiments with` + ` a Git-like tool.` const KEYWORDS = `data version control machine learning models management` diff --git a/pages/doc.js b/pages/doc.js index 61bcd1ed71..6ea34a2147 100644 --- a/pages/doc.js +++ b/pages/doc.js @@ -8,27 +8,22 @@ import { RightPanel } from '../src/Documentation/RightPanel/RightPanel' import Page from '../src/Page' import SearchForm from '../src/SearchForm' import Page404 from '../src/Page404' -import PerfectScrollbar from 'perfect-scrollbar' import Hamburger from '../src/Hamburger' // utils import fetch from 'isomorphic-fetch' import kebabCase from 'lodash.kebabcase' -import compact from 'lodash.compact' -import flatten from 'lodash.flatten' import { scroller, animateScroll } from 'react-scroll' -import 'core-js/fn/array/find-index' // styles import styled from 'styled-components' import { media } from '../src/styles' -// json -import sidebar from '../src/Documentation/sidebar' +// sidebar data and helpers +import sidebar, { getItemByPath } from '../src/Documentation/SidebarMenu/helper' export default class Documentation extends Component { constructor() { super() this.state = { - currentSection: 0, - currentFile: null, + currentItem: {}, markdown: '', headings: [], pageNotFound: false, @@ -54,52 +49,14 @@ export default class Documentation extends Component { search: false }) } - window.addEventListener('popstate', this.loadStateFromURL) - this.ps = new PerfectScrollbar('#sidebar-menu', { - // wheelPropagation: window.innerWidth <= 572 - wheelPropagation: true - }) - } - componentDidUpdate() { - this.ps.update() + window.addEventListener('popstate', this.loadStateFromURL) } componentWillUnmount() { window.removeEventListener('popstate', this.loadStateFromURL) } - loadStateFromURL = () => { - const { pathname } = window.location - const sectionURL = pathname.split('/')[2] // match section from URL - const sectionIndex = sidebar.findIndex( - section => (section.slug || kebabCase(section.name)) === sectionURL - ) - if (sectionIndex === -1) { - sectionURL - ? this.setState({ pageNotFound: true }) - : this.onSectionSelect(0) - } else { - const fileURL = pathname.split('/')[3] // match file from URL - const sectionFiles = flatten(sidebar[sectionIndex].files) - const fileIndex = sectionFiles.findIndex( - file => kebabCase(file.slice(0, -3)) === fileURL - ) - if (fileIndex === -1) { - fileURL - ? this.setState({ pageNotFound: true }) - : this.onSectionSelect(sectionIndex) - } else { - this.loadFile({ - section: sectionIndex, - file: sectionFiles[fileIndex], - parseHeadings: true, - pageNotFound: false - }) - } - } - } - initDocsearch = () => { docsearch({ apiKey: '755929839e113a981f481601c4f52082', @@ -109,54 +66,42 @@ export default class Documentation extends Component { }) } - getLinkHref = (section, file) => { - const sectionSlug = - sidebar[section].slug || kebabCase(sidebar[section].name) - const fileSlug = file ? kebabCase(file.slice(0, -3)) : undefined - return `/doc/${compact([sectionSlug, fileSlug]).join('/')}` - } - - setCurrentPath = (section, file) => { - window.history.pushState(null, null, this.getLinkHref(section, file)) - } - - onSectionSelect = (section, e) => { + onNavigate = (path, e) => { e && e.preventDefault() - const { indexFile, files } = sidebar[section] - const file = indexFile || flatten(files)[0] - e && this.setCurrentPath(section, indexFile ? undefined : file) - this.loadFile({ file, section, parseHeadings: false }) + window.history.pushState(null, null, path) + this.loadPath(path) } - onFileSelect = (file, section, e) => { - e && e.preventDefault() - this.setCurrentPath(section, file) - this.loadFile({ file, section, parseHeadings: true }) - } + loadStateFromURL = () => this.loadPath(window.location.pathname) + + loadPath = path => { + const item = getItemByPath(path) - loadFile = ({ file, section, parseHeadings }) => { - fetch(`${sidebar[section].folder}/${file}`) - .then(res => { - res.text().then(text => { - this.setState( - { - currentSection: section, - currentFile: file, - markdown: text, - headings: [], - pageNotFound: false, - isMenuOpen: false - }, - () => { - this.scrollTop() - parseHeadings && this.parseHeadings(text) - } - ) + if (!item) { + this.setState({ pageNotFound: true, currentItem: {} }) + } else { + fetch(item.source) + .then(res => { + res.text().then(text => { + this.setState( + { + markdown: text, + headings: [], + pageNotFound: false, + isMenuOpen: false, + currentItem: item + }, + () => { + this.scrollTop() + this.parseHeadings(text) + } + ) + }) }) - }) - .catch(() => { - window.location.reload() - }) + .catch(() => { + window.location.reload() + }) + } } parseHeadings = text => { @@ -208,21 +153,18 @@ export default class Documentation extends Component { render() { const { - currentSection, - currentFile, + currentItem: { source, path, label, next, prev }, headings, markdown, pageNotFound, isMenuOpen } = this.state - const directory = sidebar[currentSection].folder - const githubLink = `https://github.com/iterative/dvc.org/blob/master${directory}/${currentFile}` - const sectionName = sidebar[currentSection].name + const githubLink = `https://github.com/iterative/dvc.org/blob/master${source}` return ( - + @@ -239,13 +181,10 @@ export default class Documentation extends Component { @@ -255,12 +194,11 @@ export default class Documentation extends Component { )} - { const chat = /^\/(help|chat)\/?$/i if (req.headers.host === 'man.dvc.org') { - const doc_pathname = '/doc/commands-reference' + pathname + let normalized_pathname = + pathname !== '/import-url' ? pathname.replace(/-/i, '/') : pathname + const doc_pathname = '/doc/commands-reference' + normalized_pathname res.writeHead(301, { Location: 'https://dvc.org' + doc_pathname }) res.end() } else if (req.headers.host === 'pycon2019.dvc.org') { diff --git a/src/Documentation/Markdown/Markdown.js b/src/Documentation/Markdown/Markdown.js index 12160744f2..fc759c8b73 100644 --- a/src/Documentation/Markdown/Markdown.js +++ b/src/Documentation/Markdown/Markdown.js @@ -1,4 +1,4 @@ -import React, { Component } from 'react' +import React from 'react' // components import ReactMarkdown from 'react-markdown' import { LightButton } from '../LightButton' @@ -23,8 +23,6 @@ import kebabCase from 'lodash.kebabcase' // styles import styled from 'styled-components' import { media } from '../../../src/styles' -// json -import sidebar from '../../../src/Documentation/sidebar' registerLanguage('dvc', dvc) registerLanguage('python', python) @@ -77,7 +75,7 @@ const CodeBlock = ({ value, language }) => { ) } -export default class Markdown extends Component { +export default class Markdown extends React.PureComponent { constructor() { super() this.touchstartX = 0 @@ -115,27 +113,19 @@ export default class Markdown extends Component { handleSwipeGesture = () => { if (this.isCodeBlock) return - const { section, file, onFileSelect } = this.props - const files = sidebar[section].files - const fileIndex = files.findIndex(f => f === file) - const showPrev = fileIndex > 0 - const showNext = fileIndex + 1 < sidebar[section].files.length + const { prev, next, onNavigate } = this.props if (this.touchstartX - this.touchendX > 100) { - showNext && onFileSelect(files[fileIndex + 1], section) + next && onNavigate(next) } if (this.touchendX - this.touchstartX > 100) { - showPrev && onFileSelect(files[fileIndex - 1], section) + prev && onNavigate(prev) } } render() { - const { markdown, githubLink, section, file, onFileSelect } = this.props - const files = sidebar[section].files - const fileIndex = files.findIndex(f => f === file) - const showPrev = fileIndex > 0 - const showNext = fileIndex + 1 < sidebar[section].files.length + const { markdown, githubLink, prev, next, onNavigate } = this.props return ( @@ -143,7 +133,7 @@ export default class Markdown extends Component { Edit on Github - - diff --git a/src/Documentation/Markdown/utils/remark-linker.js b/src/Documentation/Markdown/utils/remark-linker.js index c0b14b2cc4..8b9ccfec0b 100644 --- a/src/Documentation/Markdown/utils/remark-linker.js +++ b/src/Documentation/Markdown/utils/remark-linker.js @@ -1,23 +1,41 @@ ;`use strict` import visit from 'unist-util-visit' +import { getItemByPath } from '../../SidebarMenu/helper' + +const DVC_REGEXP = /dvc\s+[a-z][a-z-.]*/ +const COMMAND_REGEXP = /^[a-z][a-z-]*$/ +const COMMAND_ROOT = '/doc/commands-reference/' function linker() { function transformer(tree) { visit(tree, 'inlineCode', function(node, index, parent) { - if (parent.type !== 'link' && /dvc\s+[a-z-.]+/.test(node.value)) { + if (parent.type !== 'link' && DVC_REGEXP.test(node.value)) { let parts = node.value.split(/\s+/) - let url = '/doc/commands-reference/' + parts[1] + let url + + const hasThirdSegment = parts[2] && COMMAND_REGEXP.test(parts[2]) + const isCommandPageExists = getItemByPath(`${COMMAND_ROOT}${parts[1]}`) + const isSubcommandPageExists = + isCommandPageExists && + hasThirdSegment && + getItemByPath(`${COMMAND_ROOT}${parts[1]}/${parts[2]}`) - if (parts.length > 2) { - url += '#' + parts[2] + if (isSubcommandPageExists) { + url = `${COMMAND_ROOT}${parts[1]}/${parts[2]}` + } else if (isCommandPageExists && hasThirdSegment) { + url = `${COMMAND_ROOT}${parts[1]}#${parts[2]}` + } else if (isCommandPageExists) { + url = `${COMMAND_ROOT}${parts[1]}` } - parent.children[index] = { - type: 'link', - url: url, - children: [node], - position: node.position + if (url) { + parent.children[index] = { + type: 'link', + url: url, + children: [node], + position: node.position + } } } }) diff --git a/src/Documentation/SidebarMenu/SidebarMenu.js b/src/Documentation/SidebarMenu/SidebarMenu.js index 7a19f4fed9..c37b409b03 100644 --- a/src/Documentation/SidebarMenu/SidebarMenu.js +++ b/src/Documentation/SidebarMenu/SidebarMenu.js @@ -1,133 +1,94 @@ -import React, { Fragment } from 'react' -import $ from 'jquery' +import React from 'react' +import PerfectScrollbar from 'perfect-scrollbar' // components import DownloadButton from '../../DownloadButton' // utils -import startCase from 'lodash.startcase' import includes from 'lodash.includes' // styles import styled from 'styled-components' import { media, OnlyDesktop } from '../../styles' +// sidebar helpers +import { getParentsListFromPath } from './helper' -export default class SidebarMenu extends React.Component { - constructor(props) { - super(props) - this.collapse = this.collapse.bind(this) +const blankStyle = {} + +class SidebarMenuItem extends React.PureComponent { + state = { + style: {} } - collapse() { - setTimeout(function() { - $('[data-open=true]').slideDown() - $('[data-open=false]').slideUp() - }) + + componentDidMount() { + if (this.props.children) { + const height = this.linkRef.scrollHeight + this.setState({ style: { height } }) + } } + + render() { + const { children, label, path, activePaths, onNavigate } = this.props + const { style } = this.state + const isActive = activePaths && includes(activePaths, path) + const isRootParent = + activePaths && activePaths.length > 1 && activePaths[0] === path + + return ( + <> + onNavigate(path, e)} + isActive={isActive} + className={isRootParent ? 'docSearch-lvl0' : ''} + > + {label} + + {children && ( + (this.linkRef = r)} + > + {children.map(item => ( + + ))} + + )} + + ) + } +} + +export default class SidebarMenu extends React.Component { componentDidMount() { - this.collapse() + this.ps = new PerfectScrollbar('#sidebar-menu', { + // wheelPropagation: window.innerWidth <= 572 + wheelPropagation: true + }) } - componentWillReceiveProps(nextProps) { - if ( - nextProps.currentSection !== this.props.currentSection || - nextProps.currentFile !== this.props.currentFile - ) { - this.collapse() - } + + componentDidUpdate() { + this.ps.update() } + render() { - let self = this - const { - sidebar, - currentSection, - currentFile, - onSectionSelect, - onFileSelect, - getLinkHref - } = this.props + const { sidebar, currentPath, onNavigate } = this.props + const activePaths = currentPath && getParentsListFromPath(currentPath) return ( - {sidebar.map( - ({ name, files = [], labels = {}, indexFile }, index) => { - const isSectionActive = currentSection === index - return ( -
- onSectionSelect(index, e)} - className={isSectionActive ? 'docSearch-lvl0' : ''} - isActive={isSectionActive} - > - {name} - - - {/* Section Files */} - - {files && - files.map((fileOrGroup, fileIndex) => { - const file = Array.isArray(fileOrGroup) - ? fileOrGroup[0] - : fileOrGroup - const subgroup = Array.isArray(fileOrGroup) - ? fileOrGroup.slice(1) - : null - const isFileActive = currentFile === file - return ( - -
- onFileSelect(file, index, e)} - isActive={isFileActive} - > - {labels[file] || startCase(file.slice(0, -3))} - -
- - {/* Subgroup files */} - {subgroup && ( - - {subgroup.map((sub, subIndex) => { - return ( -
- - onFileSelect(sub, index, e) - } - isActive={currentFile === sub} - > - {labels[sub] || - startCase(sub.slice(0, -3))} - -
- ) - })} -
- )} -
- ) - })} -
-
- ) - } - )} + {sidebar.map(item => ( + + ))}
@@ -183,7 +144,13 @@ const SectionLink = styled.a` padding-bottom: 5px; padding-left: 15px; cursor: pointer; - margin: 0; + margin: 0 0 0 5px; + + ${props => + props.isActive && + ` + color: #40364d; + `}; &:hover { color: #3c3937; @@ -205,36 +172,13 @@ const SectionLink = styled.a` transform: rotate(-90deg); `}; } - - ${props => - props.level === 1 && - ` - margin-left: 5px; - `} ${props => - props.level === 2 && - ` - margin-left: 30px; - `}; - - ${props => - props.level === 3 && - ` - margin-left: 45px; - - &::before { - display: none; - } - `}; - - ${props => - props.isActive && - ` - color: #40364d; - `}; ` const Collapse = styled.div` - display: none; + overflow: hidden; + height: 0; + transition: height 400ms; + padding-left: 20px; ` const SideFooter = styled.div` diff --git a/src/Documentation/SidebarMenu/helper.js b/src/Documentation/SidebarMenu/helper.js new file mode 100644 index 0000000000..47979890a0 --- /dev/null +++ b/src/Documentation/SidebarMenu/helper.js @@ -0,0 +1,166 @@ +import startCase from 'lodash.startcase' + +import sidebar from '../sidebar' + +/* + We will use this helper to normalize sidebar structure and create + all of the resurces we need to prevent future recalculations. + + Target structure example: + + { + label: "Add Files or Directories", + path: "/doc/get-started/add-files", + source: "/static/docs/get-started/add-files.md", + prev: "/doc/get-started/configure", + next: "/doc/get-started/share-data", + children: [] + } +*/ + +const PATH_ROOT = '/doc/' +const FILE_ROOT = '/static/docs/' +const FILE_EXTENSION = '.md' + +// Inner helpers + +function findItem(data, targetPath) { + if (data.length) { + for (let i = 0; i < data.length; i++) { + const { path, children } = data[i] + + if (path === targetPath) { + return data[i] + } else if (children) { + const result = findItem(children, targetPath) + if (result) { + return result + } + } + } + } +} + +function findChildWithSource(item) { + return item.source ? item : findChildWithSource(item.children[0]) +} + +function findPrevItemWithSource(data, item) { + if (item.source) { + return item + } else if (item.prev) { + const prevItem = findItem(data, item.prev) + + return findPrevItemWithSource(data, prevItem) + } +} + +function validateRawItem({ slug, source, children }) { + const isSourceDisabled = source === false + + if (!slug) { + throw Error("'slug' field is required in objects in sidebar.json") + } + + if (isSourceDisabled && (!children || !children.length)) { + throw Error( + "If you set 'source' to false, you had to add at least one child" + ) + } +} + +// Normalization + +function normalizeItem({ item, parentPath, resultRef, prevRef }) { + validateRawItem(item) + + const { label, slug, source } = item + + // If prev item doesn't have source we need to recirsively search for it + const prevItemWithSource = + prevRef && findPrevItemWithSource(resultRef, prevRef) + + const prev = prevItemWithSource && prevItemWithSource.path + + const sourceFileName = source ? source : slug + FILE_EXTENSION + const sourcePath = FILE_ROOT + parentPath + sourceFileName + + return { + path: PATH_ROOT + parentPath + slug, + source: source === false ? false : sourcePath, + label: label ? label : startCase(slug), + prev, + next: undefined + } +} + +function normalizeSidebar({ + data, + parentPath, + parentResultRef, + startingPrevRef +}) { + const currentResult = [] + const resultRef = parentResultRef || currentResult + let prevRef = startingPrevRef + + data.forEach(rawItem => { + const isShortcut = typeof rawItem === 'string' + const item = isShortcut ? { slug: rawItem } : rawItem + const normalizedItem = normalizeItem({ + item, + parentPath, + resultRef, + prevRef + }) + + if (prevRef) { + prevRef.next = normalizedItem.path + } + + prevRef = normalizedItem // Set it before children to preserve order + + if (item.children) { + normalizedItem.children = normalizeSidebar({ + data: item.children, + parentPath: `${parentPath}${item.slug}/`, + parentResultRef: resultRef, + startingPrevRef: prevRef + }) + } + + currentResult.push(normalizedItem) + }) + + return currentResult +} + +const normalizedSidebar = normalizeSidebar({ + data: sidebar, + parentPath: '' +}) + +// Exports + +export function getItemByPath(path) { + const isRoot = path === PATH_ROOT.slice(0, -1) + const item = isRoot ? normalizedSidebar[0] : findItem(normalizedSidebar, path) + + return item && findChildWithSource(item) +} + +export function getParentsListFromPath(path) { + let currentPath = PATH_ROOT.slice(0, -1) + + return path + .replace(PATH_ROOT, '') + .split('/') + .map(part => { + const path = `${currentPath}/${part}` + currentPath = path + + return path + }) +} + +export default normalizedSidebar diff --git a/src/Documentation/sidebar.json b/src/Documentation/sidebar.json index 9e685fa17c..2c24b159cb 100644 --- a/src/Documentation/sidebar.json +++ b/src/Documentation/sidebar.json @@ -1,217 +1,336 @@ [ { - "name": "Get Started", - "folder": "/static/docs/get-started", - "indexFile": "index.md", - "files": [ - "agenda.md", - "install.md", - "initialize.md", - "configure.md", - "add-files.md", - "share-data.md", - "retrieve-data.md", - "connect-code-and-data.md", - "pipeline.md", - "visualize.md", - "reproduce.md", - "metrics.md", - "experiments.md", - "compare-experiments.md", - "older-versions.md", - "example-versioning.md", - "example-pipeline.md" - ], - "labels": { - "connect-code-and-data.md": "Connect with Code", - "example-pipeline.md": "Example: Pipelines", - "example-versioning.md": "Example: Versioning", - "older-versions.md": "Get Older Files" - } + "slug": "get-started", + "source": "get-started/index.md", + "children": [ + "agenda", + "install", + "initialize", + "configure", + "add-files", + "share-data", + "retrieve-data", + { + "label": "Connect with Code", + "slug": "connect-code-and-data" + }, + "pipeline", + "visualize", + "reproduce", + "metrics", + "experiments", + "compare-experiments", + { + "label": "Get Older Files", + "slug": "older-versions" + }, + { + "label": "Example: Versioning", + "slug": "example-versioning" + }, + { + "label": "Example: Pipelines", + "slug": "example-pipeline" + } + ] }, { - "name": "Use Cases", - "folder": "/static/docs/use-cases", - "indexFile": "index.md", - "files": [ - "data-and-model-files-versioning.md", - "share-data-and-model-files.md", - "multiple-data-scientists-on-a-single-machine.md" - ], - "labels": { - "data-and-model-files-versioning.md": "Data & Model Files Versioning", - "share-data-and-model-files.md": "Share Data & Model Files", - "multiple-data-scientists-on-a-single-machine.md": "Shared Development Machine" - } + "slug": "use-cases", + "source": "use-cases/index.md", + "children": [ + { + "label": "Data & Model Files Versioning", + "slug": "data-and-model-files-versioning" + }, + { + "label": "Share Data & Model Files", + "slug": "share-data-and-model-files" + }, + { + "label": "Shared Development Machine", + "slug": "multiple-data-scientists-on-a-single-machine" + } + ] }, { - "name": "User Guide", - "folder": "/static/docs/user-guide", - "files": [ - "dvc-files-and-directories.md", - "dvc-file-format.md", - "large-dataset-optimization.md", - "external-dependencies.md", - "external-outputs.md", - "development.md", - "contributing.md", - "contributing-documentation.md", - "update-tracked-file.md", - "autocomplete.md", - "plugins.md", - "analytics.md", - "dvcignore.md", - "running-dvc-on-windows.md" - ], - "labels": { - "dvc-files-and-directories.md": "Files and Directories", - "dvc-file-format.md": "File Format (.dvc)", - "large-dataset-optimization.md": "Large Dataset Optimization", - "development.md": "Development Version", - "external-dependencies.md": "External Dependencies", - "external-outputs.md": "Managing External Data", - "contributing.md": "Contributing", - "contributing-documentation.md": "Contributing Documentation", - "update-tracked-file.md": "Update a Tracked File", - "autocomplete.md": "Shell Autocomplete", - "plugins.md": "Plugins & Integrations", - "analytics.md": "Anonymized Usage Analytics", - "running-dvc-on-windows.md": "Running DVC on Windows" - } + "slug": "user-guide", + "source": false, + "children": [ + { + "label": "Files and Directories", + "slug": "dvc-files-and-directories" + }, + { + "label": "File Format (.dvc)", + "slug": "dvc-file-format" + }, + "large-dataset-optimization", + "external-dependencies", + { + "label": "Managing External Data", + "slug": "external-outputs" + }, + { + "label": "Development Version", + "slug": "development" + }, + "contributing", + "contributing-documentation", + { + "label": "Update a Tracked File", + "slug": "update-tracked-file" + }, + { + "label": "Shell Autocomplete", + "slug": "autocomplete" + }, + { + "label": "Plugins & Integrations", + "slug": "plugins" + }, + { + "label": "Anonymized Usage Analytics", + "slug": "analytics" + }, + "dvcignore", + { + "label": "Running DVC on Windows", + "slug": "running-dvc-on-windows" + } + ] }, { - "name": "Commands Reference", - "folder": "/static/docs/commands-reference", - "indexFile": "index.md", - "files": [ - "add.md", - ["cache.md", "cache_dir.md"], - "checkout.md", - "commit.md", - "config.md", - "destroy.md", - "diff.md", - "fetch.md", - "get-url.md", - "get.md", - "gc.md", - "import-url.md", - "import.md", - "init.md", - "install.md", - "lock.md", - [ - "metrics.md", - "metrics_add.md", - "metrics_modify.md", - "metrics_remove.md", - "metrics_show.md" - ], - "move.md", - ["pipeline.md", "pipeline_list.md", "pipeline_show.md"], - "pull.md", - "push.md", - [ - "remote.md", - "remote_add.md", - "remote_default.md", - "remote_list.md", - "remote_modify.md", - "remote_remove.md" - ], - "remove.md", - "repro.md", - "root.md", - "run.md", - "status.md", - "unlock.md", - "unprotect.md", - "update.md", - "version.md" - ], - "labels": { - "add.md": "add", - "cache.md": "cache", - "cache_dir.md": "cache dir", - "checkout.md": "checkout", - "commit.md": "commit", - "config.md": "config", - "destroy.md": "destroy", - "diff.md": "diff", - "fetch.md": "fetch", - "get-url.md": "get-url", - "get.md": "get", - "gc.md": "gc", - "import-url.md": "import-url", - "import.md": "import", - "init.md": "init", - "install.md": "install", - "lock.md": "lock", - "metrics.md": "metrics", - "metrics_add.md": "metrics add", - "metrics_show.md": "metrics show", - "metrics_modify.md": "metrics modify", - "metrics_remove.md": "metrics remove", - "move.md": "move", - "pipeline.md": "pipeline", - "pipeline_list.md": "pipeline list", - "pipeline_show.md": "pipeline show", - "pull.md": "pull", - "push.md": "push", - "remote.md": "remote", - "remote_add.md": "remote add", - "remote_default.md": "remote default", - "remote_list.md": "remote list", - "remote_modify.md": "remote modify", - "remote_remove.md": "remote remove", - "remove.md": "remove", - "repro.md": "repro", - "root.md": "root", - "run.md": "run", - "status.md": "status", - "unlock.md": "unlock", - "unprotect.md": "unprotect", - "update.md": "update", - "version.md": "version" - } + "slug": "commands-reference", + "source": "commands-reference/index.md", + "children": [ + { + "label": "add", + "slug": "add" + }, + { + "label": "cache", + "slug": "cache", + "source": "cache/index.md", + "children": [ + { + "label": "cache dir", + "slug": "dir" + } + ] + }, + { + "label": "checkout", + "slug": "checkout" + }, + { + "label": "commit", + "slug": "commit" + }, + { + "label": "config", + "slug": "config" + }, + { + "label": "destroy", + "slug": "destroy" + }, + { + "label": "diff", + "slug": "diff" + }, + { + "label": "fetch", + "slug": "fetch" + }, + { + "label": "get-url", + "slug": "get-url" + }, + { + "label": "get", + "slug": "get" + }, + { + "label": "gc", + "slug": "gc" + }, + { + "label": "import-url", + "slug": "import-url" + }, + { + "label": "import", + "slug": "import" + }, + { + "label": "init", + "slug": "init" + }, + { + "label": "install", + "slug": "install" + }, + { + "label": "lock", + "slug": "lock" + }, + { + "label": "metrics", + "slug": "metrics", + "source": "metrics/index.md", + "children": [ + { + "label": "metrics add", + "slug": "add" + }, + { + "label": "metrics modify", + "slug": "modify" + }, + { + "label": "metrics remove", + "slug": "remove" + }, + { + "label": "metrics show", + "slug": "show" + } + ] + }, + { + "label": "move", + "slug": "move" + }, + { + "label": "pipeline", + "slug": "pipeline", + "source": "pipeline/index.md", + "children": [ + { + "label": "pipeline list", + "slug": "list" + }, + { + "label": "pipeline show", + "slug": "show" + } + ] + }, + { + "label": "pull", + "slug": "pull" + }, + { + "label": "push", + "slug": "push" + }, + { + "label": "remote", + "slug": "remote", + "source": "remote/index.md", + "children": [ + { + "label": "remote add", + "slug": "add" + }, + { + "label": "remote default", + "slug": "default" + }, + { + "label": "remote list", + "slug": "list" + }, + { + "label": "remote modify", + "slug": "modify" + }, + { + "label": "remote remove", + "slug": "remove" + } + ] + }, + { + "label": "remove", + "slug": "remove" + }, + { + "label": "repro", + "slug": "repro" + }, + { + "label": "root", + "slug": "root" + }, + { + "label": "run", + "slug": "run" + }, + { + "label": "status", + "slug": "status" + }, + { + "label": "unlock", + "slug": "unlock" + }, + { + "label": "unprotect", + "slug": "unprotect" + }, + { + "label": "update", + "slug": "update" + }, + { + "label": "version", + "slug": "version" + } + ] }, { - "name": "Tutorial", - "folder": "/static/docs/tutorial", - "indexFile": "index.md", - "files": [ - "preparation.md", - "define-ml-pipeline.md", - "reproducibility.md", - "sharing-data.md" - ], - "labels": { - "define-ml-pipeline.md": "Define ML Pipeline" - } + "slug": "tutorial", + "source": "tutorial/index.md", + "children": [ + "preparation", + { + "label": "Define ML Pipeline", + "slug": "define-ml-pipeline" + }, + "reproducibility", + "sharing-data" + ] }, { - "name": "Understanding DVC", - "folder": "/static/docs/understanding-dvc", - "files": [ - "collaboration-issues.md", - "existing-tools.md", - "what-is-dvc.md", - "core-features.md", - "how-it-works.md", - "related-technologies.md", - "resources.md" - ], - "labels": { - "what-is-dvc.md": "What is DVC?" - } + "label": "Understanding DVC", + "slug": "understanding-dvc", + "source": false, + "children": [ + "collaboration-issues", + "existing-tools", + { + "label": "What is DVC?", + "slug": "what-is-dvc" + }, + "core-features", + "how-it-works", + "related-technologies", + "resources" + ] }, { - "name": "Changelog", - "folder": "/static/docs/changelog", - "files": ["0.35.md", "0.18.md"], - "labels": { - "0.18.md": "v0.12 - v0.18", - "0.35.md": "v0.19 - v0.35" - } + "slug": "changelog", + "source": false, + "children": [ + { + "label": "v0.12 - v0.18", + "slug": "0.18" + }, + { + "label": "v0.19 - v0.35", + "slug": "0.25" + } + ] } ] diff --git a/static/docs/commands-reference/cache_dir.md b/static/docs/commands-reference/cache/dir.md similarity index 100% rename from static/docs/commands-reference/cache_dir.md rename to static/docs/commands-reference/cache/dir.md diff --git a/static/docs/commands-reference/cache.md b/static/docs/commands-reference/cache/index.md similarity index 96% rename from static/docs/commands-reference/cache.md rename to static/docs/commands-reference/cache/index.md index 4377d018b3..fe0e06dc18 100644 --- a/static/docs/commands-reference/cache.md +++ b/static/docs/commands-reference/cache/index.md @@ -1,7 +1,7 @@ # cache Contains a helper command to set the cache directory location: -[dir](/doc/commands-reference/cache-dir). +[dir](/doc/commands-reference/cache/dir). ## Synopsis diff --git a/static/docs/commands-reference/import.md b/static/docs/commands-reference/import.md index 3b14aebaa9..16d695c941 100644 --- a/static/docs/commands-reference/import.md +++ b/static/docs/commands-reference/import.md @@ -94,16 +94,16 @@ artifact as a special `repo` md5: 7de90e7de7b432ad972095bc1f2ec0f8 wdir: . deps: -- path: data/data.xml - repo: - url: git@github.com:iterative/example-get-started - rev_lock: 6c73875a5f5b522f90b5afa9ab12585f64327ca7 + - path: data/data.xml + repo: + url: git@github.com:iterative/example-get-started + rev_lock: 6c73875a5f5b522f90b5afa9ab12585f64327ca7 outs: -- md5: a304afb96060aad90176268345e10355 - path: data.xml - cache: true - metric: false - persist: false + - md5: a304afb96060aad90176268345e10355 + path: data.xml + cache: true + metric: false + persist: false ``` Several of the values above are pulled from the original stage file diff --git a/static/docs/commands-reference/metrics_add.md b/static/docs/commands-reference/metrics/add.md similarity index 100% rename from static/docs/commands-reference/metrics_add.md rename to static/docs/commands-reference/metrics/add.md diff --git a/static/docs/commands-reference/metrics.md b/static/docs/commands-reference/metrics/index.md similarity index 86% rename from static/docs/commands-reference/metrics.md rename to static/docs/commands-reference/metrics/index.md index b52db7e2f8..062a9a6634 100644 --- a/static/docs/commands-reference/metrics.md +++ b/static/docs/commands-reference/metrics/index.md @@ -1,10 +1,10 @@ # metrics A set of commands to collect and display project metrics: -[add](/doc/commands-reference/metrics-add), -[show](/doc/commands-reference/metrics-show), -[modify](/doc/commands-reference/metrics-modify), and -[remove](/doc/commands-reference/metrics-remove). +[add](/doc/commands-reference/metrics/add), +[show](/doc/commands-reference/metrics/show), +[modify](/doc/commands-reference/metrics/modify), and +[remove](/doc/commands-reference/metrics/remove). ## Synopsis @@ -27,10 +27,10 @@ metrics to track. Metrics are usually any project specific numbers - `AUC`, Usually these numbers are produced by the model evaluation script and serve as a way to compare and pick the best performing experiment variant. -[Add](/doc/commands-reference/metrics-add), -[show](/doc/commands-reference/metrics-show), -[modify](/doc/commands-reference/metrics-modify), and -[remove](/doc/commands-reference/metrics-remove) commands are available to set +[Add](/doc/commands-reference/metrics/add), +[show](/doc/commands-reference/metrics/show), +[modify](/doc/commands-reference/metrics/modify), and +[remove](/doc/commands-reference/metrics/remove) commands are available to set up and manage DVC metrics. ## Options diff --git a/static/docs/commands-reference/metrics_modify.md b/static/docs/commands-reference/metrics/modify.md similarity index 100% rename from static/docs/commands-reference/metrics_modify.md rename to static/docs/commands-reference/metrics/modify.md diff --git a/static/docs/commands-reference/metrics_remove.md b/static/docs/commands-reference/metrics/remove.md similarity index 100% rename from static/docs/commands-reference/metrics_remove.md rename to static/docs/commands-reference/metrics/remove.md diff --git a/static/docs/commands-reference/metrics_show.md b/static/docs/commands-reference/metrics/show.md similarity index 94% rename from static/docs/commands-reference/metrics_show.md rename to static/docs/commands-reference/metrics/show.md index 64ecca7ea0..934cadca3a 100644 --- a/static/docs/commands-reference/metrics_show.md +++ b/static/docs/commands-reference/metrics/show.md @@ -23,8 +23,8 @@ The optional `path` argument can represent a DVC metric file or a directory. If with the `-R` option. Providing `type` (via `-t` CLI option), overrides the full metric specification -(both, `type` and `xpath`) defined in the DVC-file (usually, using `dvc metrics -modify` command). +(both, `type` and `xpath`) defined in the DVC-file (usually, using +`dvc metrics modify` command). If `type` (via `-t`) is not specified and only `xpath` (`-x`) is, only `xpath` is overridden. It will try to read type from the DVC-file. The `type` can be @@ -50,7 +50,7 @@ detected by the file extension automatically. get a only one of them. Only single path is allowed. If multiple metric files exist in the project, the same parser and path will be applied to all of them. If xpath for particular metric has been set using - [`dvc metrics modify`](https://dvc.org/doc/commands-reference/metrics-modify#options) + [`dvc metrics modify`](https://dvc.org/doc/commands-reference/metrics/modify#options) `xpath` passed in this option will owervrite it, only for current command run. It may fail to produce any results or parse files that are not in a corresponding format in this case. Accepted value depends on the metric file @@ -89,9 +89,9 @@ detected by the file extension automatically. ## Examples -Examples in [add](/doc/commands-reference/metrics-add), -[modify](/doc/commands-reference/metrics-modify), and -[remove](/doc/commands-reference/metrics-remove) cover most of the basic cases +Examples in [add](/doc/commands-reference/metric/add), +[modify](/doc/commands-reference/metrics/modify), and +[remove](/doc/commands-reference/metrics/remove) cover most of the basic cases for the `dvc metrics show`. Example in the [compare experiments](/doc/get-started/compare-experiments) diff --git a/static/docs/commands-reference/pipeline.md b/static/docs/commands-reference/pipeline/index.md similarity index 100% rename from static/docs/commands-reference/pipeline.md rename to static/docs/commands-reference/pipeline/index.md diff --git a/static/docs/commands-reference/pipeline_list.md b/static/docs/commands-reference/pipeline/list.md similarity index 100% rename from static/docs/commands-reference/pipeline_list.md rename to static/docs/commands-reference/pipeline/list.md diff --git a/static/docs/commands-reference/pipeline_show.md b/static/docs/commands-reference/pipeline/show.md similarity index 100% rename from static/docs/commands-reference/pipeline_show.md rename to static/docs/commands-reference/pipeline/show.md diff --git a/static/docs/commands-reference/pull.md b/static/docs/commands-reference/pull.md index 4151501b80..eb27f266ca 100644 --- a/static/docs/commands-reference/pull.md +++ b/static/docs/commands-reference/pull.md @@ -115,7 +115,7 @@ r1 ssh://_username_@_host_/path/to/dvc/cache/directory ``` > DVC supports several remote types. For details, see the -> [`remote add`](/doc/commands-reference/remote-add) documentation. +> [`remote add`](/doc/commands-reference/remote/add) documentation. With a remote cache containing some images and other files, we can pull all changed files from the current Git branch: diff --git a/static/docs/commands-reference/push.md b/static/docs/commands-reference/push.md index 7acb56fda1..1aec92bd61 100644 --- a/static/docs/commands-reference/push.md +++ b/static/docs/commands-reference/push.md @@ -123,7 +123,7 @@ r1 ssh://_username_@_host_/path/to/dvc/cache/directory ``` > DVC supports several remote types. For details, see the -> [`remote add`](/doc/commands-reference/remote-add) documentation. +> [`remote add`](/doc/commands-reference/remote/add) documentation. Push all data file caches from the current Git branch to the default remote: diff --git a/static/docs/commands-reference/remote_add.md b/static/docs/commands-reference/remote/add.md similarity index 97% rename from static/docs/commands-reference/remote_add.md rename to static/docs/commands-reference/remote/add.md index 0c33f3778b..e1c170b8aa 100644 --- a/static/docs/commands-reference/remote_add.md +++ b/static/docs/commands-reference/remote/add.md @@ -5,10 +5,10 @@ Add a new data remote. > Depending on your storage type, you may also need `dvc remote modify` to > provide credentials and/or configure other remote parameters. -See also [default](/doc/commands-reference/remote-default), -[list](/doc/commands-reference/remote-list), -[modify](/doc/commands-reference/remote-modify), and -[remove](/doc/commands-reference/remote-remove) commands to manage data remotes. +See also [default](/doc/commands-reference/remote/default), +[list](/doc/commands-reference/remote/list), +[modify](/doc/commands-reference/remote/modify), and +[remove](/doc/commands-reference/remote/remove) commands to manage data remotes. ## Synopsis diff --git a/static/docs/commands-reference/remote_default.md b/static/docs/commands-reference/remote/default.md similarity index 91% rename from static/docs/commands-reference/remote_default.md rename to static/docs/commands-reference/remote/default.md index 0d9f0c4dc4..b9aa8ef804 100644 --- a/static/docs/commands-reference/remote_default.md +++ b/static/docs/commands-reference/remote/default.md @@ -5,10 +5,10 @@ Set/unset a default data remote. > Depending on your storage type, you may also need `dvc remote modify` to > provide credentials and/or configure other remote parameters. -See also [add](/doc/commands-reference/remote-add), -[list](/doc/commands-reference/remote-list), -[modify](/doc/commands-reference/remote-modify), and -[remove](/doc/commands-reference/remote-remove) commands to manage data remotes. +See also [add](/doc/commands-reference/remote/add), +[list](/doc/commands-reference/remote/list), +[modify](/doc/commands-reference/remote/modify), and +[remove](/doc/commands-reference/remote/remove) commands to manage data remotes. ## Synopsis diff --git a/static/docs/commands-reference/remote.md b/static/docs/commands-reference/remote/index.md similarity index 86% rename from static/docs/commands-reference/remote.md rename to static/docs/commands-reference/remote/index.md index 213e550371..d69ecce46e 100644 --- a/static/docs/commands-reference/remote.md +++ b/static/docs/commands-reference/remote/index.md @@ -1,11 +1,11 @@ # remote A set of commands to set up and manage data remotes: -[add](/doc/commands-reference/remote-add), -[default](/doc/commands-reference/remote-default), -[list](/doc/commands-reference/remote-list), -[modify](/doc/commands-reference/remote-modify), and -[remove](/doc/commands-reference/remote-remove). +[add](/doc/commands-reference/remote/add), +[default](/doc/commands-reference/remote/default), +[list](/doc/commands-reference/remote/list), +[modify](/doc/commands-reference/remote/modify), and +[remove](/doc/commands-reference/remote/remove). ## Synopsis @@ -43,11 +43,11 @@ Using DVC with a remote data storage is optional. By default, DVC is configured to use a local data storage only (usually `.dvc/cache` directory inside your repository), which enables basic DVC usage scenarios out of the box. -[Add](/doc/commands-reference/remote-add), -[default](/doc/commands-reference/remote-default), -[list](/doc/commands-reference/remote-list), -[modify](/doc/commands-reference/remote-modify), and -[remove](/doc/commands-reference/remote-remove) commands read or modify DVC +[Add](/doc/commands-reference/remote/add), +[default](/doc/commands-reference/remote/default), +[list](/doc/commands-reference/remote/list), +[modify](/doc/commands-reference/remote/modify), and +[remove](/doc/commands-reference/remote/remove) commands read or modify DVC [config files](/doc/commands-reference/config). Alternatively, `dvc config` can be used or these files could be edited manually. diff --git a/static/docs/commands-reference/remote_list.md b/static/docs/commands-reference/remote/list.md similarity index 85% rename from static/docs/commands-reference/remote_list.md rename to static/docs/commands-reference/remote/list.md index 87e890e823..cac4550813 100644 --- a/static/docs/commands-reference/remote_list.md +++ b/static/docs/commands-reference/remote/list.md @@ -2,10 +2,10 @@ Show all available remotes. -See also [add](/doc/commands-reference/remote-add), -[default](/doc/commands-reference/remote-default), -[modify](/doc/commands-reference/remote-modify), and -[remove](/doc/commands-reference/remote-remove) commands to manage data remotes. +See also [add](/doc/commands-reference/remote/add), +[default](/doc/commands-reference/remote/default), +[modify](/doc/commands-reference/remote/modify), and +[remove](/doc/commands-reference/remote/remove) commands to manage data remotes. ## Synopsis diff --git a/static/docs/commands-reference/remote_modify.md b/static/docs/commands-reference/remote/modify.md similarity index 96% rename from static/docs/commands-reference/remote_modify.md rename to static/docs/commands-reference/remote/modify.md index fb60283b3f..10d882af15 100644 --- a/static/docs/commands-reference/remote_modify.md +++ b/static/docs/commands-reference/remote/modify.md @@ -3,13 +3,13 @@ Modify configuration of remotes. > This command is commonly needed after `dvc remote add` or -> [default](/doc/commands-reference/remote-default) to setup credentials or +> [default](/doc/commands-reference/remote/default) to setup credentials or > other customizations to each remote type. -See also [add](/doc/commands-reference/remote-add), -[default](/doc/commands-reference/remote-default), -[list](/doc/commands-reference/remote-list), and -[remove](/doc/commands-reference/remote-remove) commands to manage data remotes. +See also [add](/doc/commands-reference/remote/add), +[default](/doc/commands-reference/remote/default), +[list](/doc/commands-reference/remote/list), and +[remove](/doc/commands-reference/remote/remove) commands to manage data remotes. ## Synopsis diff --git a/static/docs/commands-reference/remote_remove.md b/static/docs/commands-reference/remote/remove.md similarity index 86% rename from static/docs/commands-reference/remote_remove.md rename to static/docs/commands-reference/remote/remove.md index 8dcaf94540..78628f0a53 100644 --- a/static/docs/commands-reference/remote_remove.md +++ b/static/docs/commands-reference/remote/remove.md @@ -3,10 +3,10 @@ Remove a specified remote. This command affects DVC configuration files only, it does not physically remove data files stored remotely. -See also [add](/doc/commands-reference/remote-add), -[default](/doc/commands-reference/remote-default), -[list](/doc/commands-reference/remote-list), and -[modify](/doc/commands-reference/remote-modify) commands to manage data remotes. +See also [add](/doc/commands-reference/remote/add), +[default](/doc/commands-reference/remote/default), +[list](/doc/commands-reference/remote/list), and +[modify](/doc/commands-reference/remote/modify) commands to manage data remotes. ## Synopsis diff --git a/static/docs/commands-reference/status.md b/static/docs/commands-reference/status.md index 99a0950093..395acf8519 100644 --- a/static/docs/commands-reference/status.md +++ b/static/docs/commands-reference/status.md @@ -200,5 +200,4 @@ Preparing to collect status from s3://dvc-remote ``` The output shows where the location of the remote cache as well as any -differences between the local cache and remote cache. - +differences between the local cache and remote cache. diff --git a/static/docs/commands-reference/unprotect.md b/static/docs/commands-reference/unprotect.md index 3ec765b744..9e2f2dd9dc 100644 --- a/static/docs/commands-reference/unprotect.md +++ b/static/docs/commands-reference/unprotect.md @@ -48,7 +48,7 @@ when cache protected mode is enabled: Enable cache protected mode is enabled: ```dvc - $ dvc config cache.protected true +$ dvc config cache.protected true ``` Put a data file under DVC control: diff --git a/static/docs/use-cases/share-data-and-model-files.md b/static/docs/use-cases/share-data-and-model-files.md index 38b1b7d0fc..951d60d7c9 100644 --- a/static/docs/use-cases/share-data-and-model-files.md +++ b/static/docs/use-cases/share-data-and-model-files.md @@ -44,7 +44,7 @@ remote = myremote ``` `dvc remote` provides a wide variety of options to configure S3 bucket. For more -information visit [`dvc remote modify`](/doc/commands-reference/remote-modify). +information visit [`dvc remote modify`](/doc/commands-reference/remote/modify). Let's, commit your changes and push your code: