Skip to content
Draft
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
4eb63a8
Working Archive + deploy command
kaixin-hc Apr 2, 2022
e180361
Fix archived site links + streamline functions
kaixin-hc Apr 2, 2022
c229160
Fix URL bug
kaixin-hc Apr 4, 2022
e64f91c
clean up comments in cli file
kaixin-hc Apr 9, 2022
778f3cb
Exclude archived site from being archived with markbind archive
kaixin-hc Apr 9, 2022
95298d4
Add documentation for the CLI command
kaixin-hc Apr 9, 2022
8eed90c
Docs: Write Versioning Documentation
kaixin-hc Apr 9, 2022
8453f7a
Fix Error logging
kaixin-hc Apr 9, 2022
1ba8c91
Revert changes to deploy
kaixin-hc Apr 16, 2022
f113c22
Make changes according to Yongliang's suggestions
kaixin-hc Apr 16, 2022
0769bc7
Merge in master branch changes
kaixin-hc Apr 16, 2022
aca406b
Correctly ignore subsites versions
kaixin-hc Apr 18, 2022
7f559b1
Merge master branch changes in
kaixin-hc Apr 18, 2022
792c156
Amend spacing in cliCommands
kaixin-hc Apr 18, 2022
4fc9090
Merge branch 'master' into site-versioning
kaixin-hc Apr 18, 2022
798d63f
Fix error made when merging
kaixin-hc Apr 18, 2022
b85641a
Working to copy over files for serve
kaixin-hc Apr 21, 2022
9beec61
Change versions.json formatting
kaixin-hc Apr 21, 2022
ad5f0ff
Correctly deploy selected versions
kaixin-hc Apr 21, 2022
601d343
Add documentation about versioning
kaixin-hc Apr 21, 2022
b52a341
Correctly exclude site whose baseUrls do not match
kaixin-hc Apr 21, 2022
039c0bd
Update versioning example and add additional warning
kaixin-hc Apr 21, 2022
f394060
correct typo
kaixin-hc Apr 21, 2022
c77b95e
Fix some comments
kaixin-hc May 2, 2022
5f8e427
Merge in master
kaixin-hc Jun 9, 2022
2362390
Change behaviour of --version flag & set archivePath flag + nits
kaixin-hc Jun 15, 2022
3337749
Merge branch 'master' into site-versioning
kaixin-hc Jun 20, 2022
46632f1
Refactor copying of versions & versions information, fix bug
kaixin-hc Jun 20, 2022
5ef1776
Add read from versions file
kaixin-hc Jun 20, 2022
850aa18
Add write version file tests + fix bugs + warning message
kaixin-hc Jun 21, 2022
d6cc776
Add testcases for copying selected versions
kaixin-hc Jun 22, 2022
a4505ce
Delete superfluous test
kaixin-hc Jun 22, 2022
f8ee5d7
Add missing test files due to versioning
kaixin-hc Jun 22, 2022
1bdb924
Add ignore site tests + fix bug
kaixin-hc Jun 22, 2022
3745f7a
Fixing paths for windows
kaixin-hc Jun 22, 2022
d89e2a6
Chore: fix bug?
kaixin-hc Jun 22, 2022
7d8125d
Update documentation
kaixin-hc Jun 23, 2022
14fe6ec
Chore: Documentation changes
kaixin-hc Jun 25, 2022
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
1 change: 1 addition & 0 deletions docs/_markbind/layouts/userGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
* [Making the Site Searchable]({{baseUrl}}/userGuide/makingTheSiteSearchable.html)
* [Applying Themes]({{baseUrl}}/userGuide/themes.html)
* [Deploying the Site]({{baseUrl}}/userGuide/deployingTheSite.html)
* [Versioning]({{baseUrl}}/userGuide/versioning.html)
* [MarkBind in the Project Workflow]({{baseUrl}}/userGuide/markBindInTheProjectWorkflow.html)
* **References** :expanded:
* [CLI Commands]({{baseUrl}}/userGuide/cliCommands.html)
Expand Down
76 changes: 68 additions & 8 deletions docs/userGuide/cliCommands.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,23 @@
### Overview

An overview of MarkBind's Command Line Interface (CLI) can be referenced with `markbind --help`:
```

```bash
$ markbind --help
Usage: markbind <command>

Options:
-V, --version output the version number
-h, --help output usage information
-V, --version output the version number
-h, --help output usage information

Commands:
init|i [options] [root] init a markbind website project
serve|s [options] [root] build then serve a website from a directory
build|b [options] [root] [output] build a website
deploy|d [options] deploy the site to the repo's GitHub pages
init|i [options] [root] init a markbind website project
serve|s [options] [root] build then serve a website from a directory
build|b [options] [root] [output] build a website
archive|ar [options] [versionName] [archivePath] archive the current version of the site
deploy|d [options] deploy the site to the repo's GitHub pages
```

<hr><!-- ========================================================================== -->
<div id="markbind-init">

Expand Down Expand Up @@ -116,13 +119,16 @@ The caveat is that not building all pages during the initial process, or not reb
Force live reload to process all files in the site, instead of just the relevant files. This option is useful when you are modifying a file that is not a file type monitored by the <trigger trigger="click" for="modal:cliCommands-livePreview">live preview</trigger> feature.

* `-p <port>`, `--port <port>`<br>
Serve the website in the specified port.
Serve the website in the specified port.

* `-v [versionNames...]`, `--versions [versionNames...]` <br>
Specify version names to be deployed, separated by spaces. If the flag is used without specification, deploy all versions saved.

{{ icon_examples }}
* `markbind serve`
* `markbind serve ./myWebsite`
* `markbind serve -p 8888 -s otherSite.json`
* `markbind serve -n -v` : Serve the site without opening a live preview in the browser, with all saved versions deployed

</panel>

Expand Down Expand Up @@ -158,10 +164,63 @@ The caveat is that not building all pages during the initial process, or not reb
Specify the site config file (default: `site.json`)<br>
{{ icon_example }} `-s otherSite.json`

* `-v [versionNames...]`, `--versions [versionNames...]` <br>
Specify version names to be deployed, separated by spaces. If the flag is used without specification, deploy all versions saved.

**{{ icon_examples }}**
* `markbind build`
* `markbind build ./myWebsite ./myOutDir`
* `markbind build ./stagingDir --baseUrl staging`
* `markbind build -v v2.1.1` : Build the site and also deploy the version named 'v2.1.1'

</panel>

<hr><!-- ========================================================================== -->

### `archive` Command
<br>

**Format:** `markbind archive [options] [versionName] [archivePath]`

**Alias:** `markbind ar`

**Description:** Does the following steps:

1. Builds the current site, ignoring previously archived versions.
1. Updates or creates a `versions.json` file to track the newly archived version.
1. Puts the generated files in a folder of the specified name in the specified place.

**Arguments:**

<div id="archiveWarning">
<box type="warning">

Warning: If the folder at `<archivePath>/<versionName>` already exists, the contents will be overwritten and your previous files may be lost. Only do so if you need to replace all the archived files with the current site files.
</box>
</div>

* `[versionName]`<br>
The name of the version, and the folder which the generated HTML files and assets will be stored in.<br>
{{ icon_example }} `v1`, `v1.1.1`, `sem1-2022`

* `[archivePath]`<br>
All archived versions are stored in the folder `<archivePath>`. The default archivePath is `version/${versionName}` <br>
{{ icon_example }} `custom_archive_path`

<panel header="**Options** :fas-cogs:" type="minimal" expanded>

**Options** :fas-cogs:

* `-s <file>`, `--site-config <file>`<br>
Specify the site config file (default: `site.json`)<br>
{{ icon_example }} `-s otherSite.json`

**{{ icon_examples }}**

* `markbind archive v1`: Stores the site in the directory `./version/v1`
* `markbind archive version_1 custom_archive_path`: Stores the site in the directory `./custom_archive_path`

%%{{ icon_info }} Related: [User Guide: Site Versioning](versioning.md).%%

</panel>

Expand Down Expand Up @@ -200,5 +259,6 @@ The caveat is that not building all pages during the initial process, or not reb
**Description:** Prints a summary of MarkBind commands or a detailed usage guide for the given `command`.

{{ icon_examples }}

* `markbind --help` : Prints a summary of MarkBind commands.
* `markbind serve --help` : Prints a detailed usage guide for the `serve` command.
2 changes: 1 addition & 1 deletion docs/userGuide/deployingTheSite.md
Original file line number Diff line number Diff line change
Expand Up @@ -538,4 +538,4 @@ For more information on Surge, you may refer to [Surge's docs](https://surge.sh/
</panel>

{% from "njk/common.njk" import previous_next %}
{{ previous_next('themes', 'markBindInTheProjectWorkflow') }}
{{ previous_next('themes', 'versioning') }}
2 changes: 1 addition & 1 deletion docs/userGuide/markBindInTheProjectWorkflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,4 @@ To convert your existing project, follow these steps:
</box>

{% from "njk/common.njk" import previous_next %}
{{ previous_next('deployingTheSite', '') }}
{{ previous_next('versioning', '') }}
9 changes: 8 additions & 1 deletion docs/userGuide/siteJsonFile.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ Here is a typical `site.json` file:
"headingIndexingLevel": 4,
"intrasiteLinkValidation": {
"enabled": false
}
},
"versions" : ["v1"]
}
```

Expand Down Expand Up @@ -268,3 +269,9 @@ To disable this validation **entirely**, you may add the following to `site.json
```

</div>

#### **`versions`**

**A list of version names to deploy by default when building and serving the site**. If this list is not present, by default no versions will be deployed. (You can override these settings by passing the `--versions` flag to build and serve -- see the [MarkBind CLI page](cliCommands.md) for more.)

The version names to specify should be the same ones as in `versions.json`. Refer to the [Site Versioning](versioning.md) for more details.
78 changes: 78 additions & 0 deletions docs/userGuide/versioning.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
{% set title = "Site Versioning" %}
{% set filename = "versioning" %}
<span id="title" class="d-none">{{ title }}</span>

<frontmatter>
title: "User Guide: {{ title }}"
layout: userGuide.md
</frontmatter>

<span id="link" class="d-none">
<md>[_User Guide → {{ title }}_]({{ filename }}.html)</md>
</span>

# {{ title }}

<div class="lead" id="overview">

Site versioning is key for documentation use, and websites may want to keep past versions for archival purposes. MarkBind can help you easily archive your site.
</div>

## Archiving with a CLI command

Markbind allows you to easily save a version of the site you've built to be hosted at the same site with a modified URL with a [single CLI command](cliCommands.md#archive-command). All intralinks within the archived site will point to the respective archived pages. By default, the archived site is stored in a folder `version/<versionName>`, but you may specify your own archivePath.

For example, if your site's base URL relative to your domain is `my_site`, and you archive a version named `v1` in the default archive folder, then by navigating to the URL `<domain>/my_site/version/v1/<someFile>` you can have accessed the archived version of `someFile`.

A `versions.json` file will be created to track the archived sites you have made, and to exclude the archived sites from being re-archived the next time you make a new version. This file is **automatically updated** every time you archive a version.

<box type="warning">

Modify versions.json with caution as it may result in unnecessary files being included or necessary files being excluded.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion, as its a little difficult to see how this will pan out, we could leave this to be entirely internally managed by the cli commands for now:

Suggested change
Modify versions.json with caution as it may result in unnecessary files being included or necessary files being excluded.
Avoid modifying versions.json as it may result in unnecessary files being included or necessary files being excluded.
// remove the rest

if we don't want support these, could also move these chunks on versions.json further below or as a separate section -- as "extra non user-facing information"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mm, I agree with you, its just that I haven't implemented CLI commands to manage this yet so it might become necessary to edit it as a stopgap measure (changing the name of versions, for example, or deleting versions). I think using CLI commands to support renaming, deletion and maybe moving would be ideal, but might be outside the scope of this PR? Though I don't think it would be too difficult!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Modify versions.json with caution as it may result in unnecessary files being included or necessary files being excluded.
Avoid modifying `versions.json` as it may result in unnecessary files being included or necessary files being excluded.


* You may safely change the `versionName` of a version, **provided that it is unique** in versions.json. If you have specified versions to deploy in `site.json`, make sure you update the [versions property](siteJsonFile.md#versions) there as well.

* The baseUrl is used when setting the intra-site links; if you later change the baseUrl, previously saved versions with the past baseUrl will not be built/deployed even if specified because it would be a broken implementation.
Comment on lines +58 to +60
Copy link
Contributor

@tlylt tlylt Jun 23, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps referring to the above comment thread from Ze Yu, we can make a new section of versions.json and move this down together with the versions.json example.


</box>

```json {heading="Example of a versions.json file"}
{
"versions": [
{
"versionName": "v1",
"buildVer": "3.1.1",
"archivePath": "version/v1",
"baseUrl": "/previousUrl"
},
{
"versionName": "v2",
"buildVer": "3.1.1",
"archivePath": "version/v2",
"baseUrl": "/markbind"
},
{
"versionName": "v3",
"buildVer": "3.1.1",
"archivePath": "version/v3",
"baseUrl": "/markbind"
}
]
}

```

<include src="cliCommands.md#archiveWarning" />

## Working with sites with multiple versions

You may not always want to build all your saved versions. To specify the "default versions to build", add a [versions property](siteJsonFile.md#versions) in your `site.json` file.

You may also specify which versions to build when using the build and serve cli commands([more information](cliCommands.md)).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You may also specify which versions to build when using the build and serve cli commands([more information](cliCommands.md)).
You may also specify which versions to build when using the [build and serve CLI commands](cliCommands.md).


## Note on subsites

At present, when a site is archived and includes a subsite, it archives the subsite as it was at that point in time. Navigating to previous or future versions of the subsite from the parent site is not supported, though you can archive the subsite.

{% from "njk/common.njk" import previous_next %}
{{ previous_next('deployingTheSite', 'markBindInTheProjectWorkflow') }}
31 changes: 28 additions & 3 deletions packages/cli/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ program
.option('-p, --port <port>', 'port for server to listen on (Default is 8080)')
.option('-s, --site-config <file>', 'specify the site config file (default: site.json)')
.option('-d, --dev', 'development mode, enabling live & hot reload for frontend source files.')
.option('-v, --versions [versionNames...]',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if there are no values passed in, there's no point in the flag? In that case, perhaps we can make the values compulsory? What do you think?
Also, may I check if there's a typo -> deploy no versions is it serve no versions? (Else, deploy seems a little ambiguous~).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Meant altering the defaults for the more common use case like how you're doing it for --versions currently

I think this part was missed out @kaixin-hc (more than likely if you archive a site you'll want to deploy it too. Also @tlylt's point above)

logically speaking, just this portion (SiteConfig.js)

this.versions = siteConfigJson.versions !== undefined
      ? siteConfigJson.versions
      : every version;

(implementation wise you might want to do the check here instead)

// change
if (versionsToGenerate === true) {
      // copy no versions if the version flag is passed without arguments
} else if (versionsToGenerate === false) {
      await this.copyVersions(desiredVersions
        .filter(vers => this.siteConfig.versions.includes(vers.versionName)));
} else {
     await this.copyVersions(desiredVersions
       .filter(vers => versionsToGenerate.includes(vers.versionName)));
}

// into 
if (versionsToGenerate === true) {
      // copy no versions if the version flag is passed without arguments
} else if (versionsToGenerate is an array) {
  // cli override takes precedence
  await this.copyVersions(desiredVersions
        .filter(vers => versionsToGenerate.includes(vers.versionName)))
} else if (/* versionsToGenerate === false (implied) && */ this.siteConfig.versions is an array) {
  // does site.json have the property? use it next if so
      await this.copyVersions(desiredVersions
        .filter(vers => this.siteConfig.versions.includes(vers.versionName)));
} else {
  // **the default** - deploy all previously archived versions versions
  await this.copyVersions(desiredVersions
      .filter(vers => versionsToGenerate.includes(vers.versionName)));
}

// and change (SiteConfig.js)
this.versions = siteConfigJson.versions !== undefined
    ? siteConfigJson.versions : [];

// into just 
this.versions = siteConfigJson.versions;

The flag behaviour looks good though!

'specify versions to be deployed. if flag is used without specification, deploy all versions')
.action((userSpecifiedRoot, options) => {
if (options.dev) {
logger.useDebugConsole();
Expand Down Expand Up @@ -262,7 +264,7 @@ program
serverConfig.open = serverConfig.open && `${config.baseUrl}/`;
}

return site.generate();
return site.generate(undefined, options.versions);
})
.then(() => {
const watcher = chokidar.watch(rootFolder, {
Expand Down Expand Up @@ -298,6 +300,8 @@ program
.option('--baseUrl [baseUrl]',
'optional flag which overrides baseUrl in site.json, leave argument empty for empty baseUrl')
.option('-s, --site-config <file>', 'specify the site config file (default: site.json)')
.option('-v, --versions [versionNames...]',
'specify versions to be deployed. if flag is used without specification, deploy all versions')
.description('build a website')
.action((userSpecifiedRoot, output, options) => {
// if --baseUrl contains no arguments (options.baseUrl === true) then set baseUrl to empty string
Expand All @@ -311,13 +315,33 @@ program
const defaultOutputRoot = path.join(rootFolder, '_site');
const outputFolder = output ? path.resolve(process.cwd(), output) : defaultOutputRoot;
new Site(rootFolder, outputFolder, undefined, undefined, options.siteConfig)
.generate(baseUrl)
.generate(baseUrl, options.versions)
.then(() => {
logger.info('Build success!');
})
.catch(handleError);
});

program
.command('archive [versionName] [archivePath]')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we put archivePath into a named parameter instead? (e.g. -p --archive-path)
Since we don't expect that most people would need to change this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, I agree with this! Will do so unless anyone else disagrees.

.alias('ar')
.option('-s, --site-config <file>', 'specify the site config file (default: site.json)')
.description('archive a version of the site, which is not affected by later changes to the site')
.action((versionName, userSpecifiedArchivePath, options) => {
if (!versionName) {
logger.error('Please specify a name for the archived version.');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe can throw an error here so that it will stop the archiving process if the version name is not specified?

Currently, it will be archived as undefined:
image

}
const archivePath = userSpecifiedArchivePath || `version/${versionName}`;
const rootFolder = path.resolve(process.cwd());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wonder if we should add in archive [root] <versionName> to make things consistent with the other commands (cliUtil.findRootFolder), but it should be backward compatible in any case so we can decide on this later.

I think minimally we could add in a small note in the cli commands page that the site archived is the cwd's one.

const outputFolder = path.join(rootFolder, archivePath);
new Site(rootFolder, outputFolder, undefined, undefined, options.siteConfig)
.archive(versionName, archivePath)
.then(() => {
logger.info(`Successfully archived ${versionName} at ${archivePath}`);
})
.catch(handleError);
});

program
.command('deploy')
.alias('d')
Expand All @@ -327,7 +351,8 @@ program
.action((options) => {
const rootFolder = path.resolve(process.cwd());
const outputRoot = path.join(rootFolder, '_site');
new Site(rootFolder, outputRoot, undefined, undefined, options.siteConfig).deploy(options.ci)
new Site(rootFolder, outputRoot, undefined, undefined, options.siteConfig)
.deploy(options.ci)
.then(depUrl => (depUrl !== null ? logger.info(
`The website has been deployed at: ${depUrl}`)
: logger.info('Deployed!')))
Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/Site/SiteConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ class SiteConfig {
*/
this.intrasiteLinkValidation = siteConfigJson.intrasiteLinkValidation || {};
this.intrasiteLinkValidation.enabled = this.intrasiteLinkValidation.enabled !== false;

/**
* @type {Array}
*/
this.versions = siteConfigJson.versions || [];
}
}

Expand Down
1 change: 1 addition & 0 deletions packages/core/src/Site/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ module.exports = {
PAGE_TEMPLATE_NAME: 'page.njk',
SITE_CONFIG_NAME: 'site.json',
SITE_DATA_NAME: 'siteData.json',
VERSIONS_DATA_NAME: 'versions.json',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
VERSIONS_DATA_NAME: 'versions.json',
VERSIONS_DATA_NAME: '_markbind/versions.json',

should we? in view of all the other stuff in there

LAYOUT_SITE_FOLDER_NAME: 'layouts',
LAZY_LOADING_SITE_FILE_NAME: 'LazyLiveReloadLoadingSite.html',
LAZY_LOADING_BUILD_TIME_RECOMMENDATION_LIMIT: 30000,
Expand Down
Loading