Move all output from bin/gen
to target/gen
To make it clearer what is and isn't generated content, make gen place all generated output in `target/gen`. Also, try to make the readme clearer about the location of build artifacts. type: development
This commit is contained in:
parent
bf29d74b3e
commit
e7872f56f2
8
.github/workflows/build.yaml
vendored
8
.github/workflows/build.yaml
vendored
|
@ -108,7 +108,7 @@ jobs:
|
|||
if: matrix.os == 'macos-latest'
|
||||
run: |
|
||||
brew install help2man
|
||||
cargo run --package gen all
|
||||
cargo run --package gen -- --bin target/debug/imdl all
|
||||
git diff --no-ext-diff --exit-code
|
||||
|
||||
- name: Install `mdbook`
|
||||
|
@ -118,7 +118,7 @@ jobs:
|
|||
|
||||
- name: Build Book
|
||||
run: |
|
||||
cargo run --package gen book
|
||||
cargo run --package gen -- --bin target/debug/imdl book
|
||||
mdbook build book --dest-dir ../www/book
|
||||
|
||||
- name: Record Git Revision
|
||||
|
@ -139,12 +139,12 @@ jobs:
|
|||
shell: bash
|
||||
run: ./bin/package ${{github.ref}} ${{matrix.os}} ${{matrix.target}}
|
||||
|
||||
- name: Publish
|
||||
- name: Publish Release Archive
|
||||
uses: softprops/action-gh-release@v1
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
draft: false
|
||||
files: ${{steps.package.outputs.archive}}
|
||||
prerelease: false
|
||||
prerelease: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||
|
|
12
.gitignore
vendored
12
.gitignore
vendored
|
@ -1,17 +1,5 @@
|
|||
**/*.rs.bk
|
||||
/CHANGELOG.md
|
||||
/book/book
|
||||
/book/src/SUMMARY.md
|
||||
/book/src/bittorrent.md
|
||||
/book/src/changelog.md
|
||||
/book/src/commands.md
|
||||
/book/src/commands/
|
||||
/book/src/faq.md
|
||||
/book/src/introduction.md
|
||||
/book/src/references
|
||||
/book/src/references.md
|
||||
/completions
|
||||
/man
|
||||
/target
|
||||
/wiki
|
||||
/www/book
|
||||
|
|
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -354,6 +354,12 @@ version = "1.0.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
|
||||
|
||||
[[package]]
|
||||
name = "fs_extra"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f2a4a2034423744d2cc7ca2068453168dcdb82c438419e639a26bd87839c674"
|
||||
|
||||
[[package]]
|
||||
name = "gen"
|
||||
version = "0.0.0"
|
||||
|
@ -363,10 +369,9 @@ dependencies = [
|
|||
"cargo_toml",
|
||||
"chrono",
|
||||
"fehler",
|
||||
"fs_extra",
|
||||
"git2",
|
||||
"globset",
|
||||
"ignore",
|
||||
"lexiclean",
|
||||
"libc",
|
||||
"log",
|
||||
"pretty_env_logger",
|
||||
|
@ -379,7 +384,6 @@ dependencies = [
|
|||
"strum_macros",
|
||||
"tempfile",
|
||||
"url",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
57
README.md
57
README.md
|
@ -31,10 +31,7 @@ For more about the project and its goals, check out
|
|||
- [Examples](#examples)
|
||||
- [FAQ](#faq)
|
||||
- [Notes for Packagers](#notes-for-packagers)
|
||||
- [Package Artifacts](#package-artifacts)
|
||||
- [Binary](#binary)
|
||||
- [Man Pages](#man-pages)
|
||||
- [Completion Scripts](#completion-scripts)
|
||||
- [Build Artifacts](#build-artifacts)
|
||||
- [Release Updates](#release-updates)
|
||||
- [Chat](#chat)
|
||||
- [Contributing](#contributing)
|
||||
|
@ -181,46 +178,38 @@ Intermodal is distributed under the
|
|||
a public domain dedication with a fallback all-permissive license. The SPDX
|
||||
identifier of the CC0 is [CC0-1.0](https://spdx.org/licenses/CC0-1.0.html).
|
||||
|
||||
### Package Artifacts
|
||||
### Build Artifacts
|
||||
|
||||
There are three primary build artifacts: the binary, the man pages, and the
|
||||
shell completion scripts.
|
||||
There are a number of build artifacts: the binary, the man pages, the
|
||||
changelog, and the shell completion scripts.
|
||||
|
||||
#### Binary
|
||||
The binary is built with `cargo`, and the other artifacts are built `gen`,
|
||||
located in `bin/gen`.
|
||||
|
||||
The binary is called `imdl`, and can be built with:
|
||||
The binary can be built with:
|
||||
|
||||
```
|
||||
cargo build --release
|
||||
```
|
||||
cargo build --release
|
||||
|
||||
After building, the binary will be present at `target/release/imdl`.
|
||||
_`gen` requires [`help2man`](https://www.gnu.org/software/help2man/) to be
|
||||
installed, which is used to generate man pages from subcommand `--help`
|
||||
strings._
|
||||
|
||||
#### Man Pages
|
||||
The rest of the build artifacts can be built with `gen`:
|
||||
|
||||
Intermodal has a number of subcommands, each of which has a man page. The man
|
||||
pages are generated from the `--help` text using
|
||||
[`help2man`](https://www.gnu.org/software/help2man/).
|
||||
cargo run --package gen -- --bin target/release/imdl all
|
||||
|
||||
To generate the man pages, ensure `help2man` is available, and run:
|
||||
_The path to the built `imdl` executable should be passed to `gen` with the `--bin` flag._
|
||||
|
||||
```
|
||||
mkdir -p man
|
||||
cargo run --package gen man
|
||||
```
|
||||
After running the above commands, the following table shows the location of the
|
||||
built artifacts.
|
||||
|
||||
After building, the man pages will be available in `man`.
|
||||
|
||||
#### Completion Scripts
|
||||
|
||||
Completion scripts are available for a number of shells. To generate them, run:
|
||||
|
||||
```
|
||||
mkdir -p completions
|
||||
cargo run --release completions --dir completions
|
||||
```
|
||||
|
||||
After running, the completion scripts will be available in `completions`.
|
||||
| Artifact | Location |
|
||||
|--------------------|----------------------------|
|
||||
| Binary | `target/release/imdl` |
|
||||
| Man Pages | `target/gen/man/*` |
|
||||
| Completion Scripts | `target/gen/completions/*` |
|
||||
| Changelog | `target/gen/CHANGELOG.md` |
|
||||
| Readme | `target/gen/README.md` |
|
||||
|
||||
### Release Updates
|
||||
|
||||
|
|
|
@ -11,10 +11,9 @@ askama = "0.9.0"
|
|||
cargo_toml = "0.8.0"
|
||||
chrono = "0.4.11"
|
||||
fehler = "1.0.0"
|
||||
fs_extra = "1.1.0"
|
||||
git2 = "0.13.1"
|
||||
globset = "0.4.5"
|
||||
ignore = "0.4.14"
|
||||
lexiclean = "0.0.1"
|
||||
libc = "0.2.69"
|
||||
log = "0.4.8"
|
||||
pretty_env_logger = "0.4.0"
|
||||
|
@ -25,7 +24,6 @@ structopt = "0.3.12"
|
|||
strum = "0.18.0"
|
||||
strum_macros = "0.18.0"
|
||||
tempfile = "3.1.0"
|
||||
walkdir = "2.3.1"
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1.0.106"
|
||||
|
|
16
bin/gen/src/arguments.rs
Normal file
16
bin/gen/src/arguments.rs
Normal file
|
@ -0,0 +1,16 @@
|
|||
use crate::common::*;
|
||||
|
||||
#[derive(StructOpt)]
|
||||
pub(crate) struct Arguments {
|
||||
#[structopt(flatten)]
|
||||
options: Options,
|
||||
#[structopt(subcommand)]
|
||||
subcommand: Subcommand,
|
||||
}
|
||||
|
||||
impl Arguments {
|
||||
#[throws]
|
||||
pub(crate) fn run(self) {
|
||||
self.subcommand.run(self.options)?;
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ use crate::common::*;
|
|||
|
||||
pub(crate) struct Bin {
|
||||
path: PathBuf,
|
||||
pub(crate) subcommands: Vec<Subcommand>,
|
||||
pub(crate) subcommands: Vec<BinSubcommand>,
|
||||
}
|
||||
|
||||
impl Bin {
|
||||
|
@ -22,7 +22,7 @@ impl Bin {
|
|||
|
||||
#[throws]
|
||||
fn add_subcommands(&mut self, command: &mut Vec<String>) {
|
||||
let subcommand = Subcommand::new(&self.path, command.clone())?;
|
||||
let subcommand = BinSubcommand::new(&self.path, command.clone())?;
|
||||
|
||||
for name in &subcommand.subcommands {
|
||||
command.push(name.into());
|
||||
|
|
150
bin/gen/src/bin_subcommand.rs
Normal file
150
bin/gen/src/bin_subcommand.rs
Normal file
|
@ -0,0 +1,150 @@
|
|||
use crate::common::*;
|
||||
|
||||
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq)]
|
||||
pub(crate) struct BinSubcommand {
|
||||
pub(crate) bin: PathBuf,
|
||||
pub(crate) command: Vec<String>,
|
||||
pub(crate) subcommands: Vec<String>,
|
||||
}
|
||||
|
||||
impl BinSubcommand {
|
||||
#[throws]
|
||||
pub(crate) fn new(bin: &Path, command: Vec<String>) -> Self {
|
||||
let wide_help = Command::new(bin)
|
||||
.args(command.as_slice())
|
||||
.env("IMDL_TERM_WIDTH", "200")
|
||||
.arg("--help")
|
||||
.out()?;
|
||||
|
||||
const MARKER: &str = "\nSUBCOMMANDS:\n";
|
||||
|
||||
let mut subcommands = Vec::new();
|
||||
|
||||
if let Some(marker) = wide_help.find(MARKER) {
|
||||
let block = &wide_help[marker + MARKER.len()..];
|
||||
|
||||
for line in block.lines() {
|
||||
let name = line.trim().split_whitespace().next().unwrap();
|
||||
subcommands.push(name.into());
|
||||
}
|
||||
}
|
||||
|
||||
Self {
|
||||
bin: bin.into(),
|
||||
command,
|
||||
subcommands,
|
||||
}
|
||||
}
|
||||
|
||||
#[throws]
|
||||
fn help(&self) -> String {
|
||||
info!("Getting help for `{}`", self.command_line());
|
||||
|
||||
Command::new(&self.bin)
|
||||
.args(self.command.as_slice())
|
||||
.env("IMDL_TERM_WIDTH", "80")
|
||||
.arg("--help")
|
||||
.out()?
|
||||
}
|
||||
|
||||
#[throws]
|
||||
pub(crate) fn man(&self) -> String {
|
||||
let command_line = self.command_line();
|
||||
|
||||
info!("Generating man page for `{}`", command_line);
|
||||
|
||||
let name = command_line.replace(" ", "\\ ");
|
||||
|
||||
let help = self.help()?;
|
||||
|
||||
let description = if self.command.is_empty() {
|
||||
"A 40' shipping container for the Internet".to_string()
|
||||
} else {
|
||||
help.lines().nth(1).unwrap().into()
|
||||
};
|
||||
|
||||
let include = format!(
|
||||
"\
|
||||
[NAME]
|
||||
\\fB{}\\fR
|
||||
- {}
|
||||
",
|
||||
name, description
|
||||
);
|
||||
|
||||
let tmp = tempfile::tempdir().context(error::Tempdir)?;
|
||||
|
||||
let include_path = tmp.path().join("include");
|
||||
|
||||
fs::write(&include_path, include).context(error::Filesystem {
|
||||
path: &include_path,
|
||||
})?;
|
||||
|
||||
let version = cmd!(&self.bin, "--version")
|
||||
.out()?
|
||||
.split_whitespace()
|
||||
.nth(1)
|
||||
.unwrap()
|
||||
.to_owned();
|
||||
|
||||
info!("Running help2man for `{}`", command_line);
|
||||
|
||||
let mut command = self.bin.as_os_str().to_owned();
|
||||
for arg in &self.command {
|
||||
command.push(" ");
|
||||
command.push(arg);
|
||||
}
|
||||
|
||||
let output = cmd!(
|
||||
"help2man",
|
||||
"--include",
|
||||
&include_path,
|
||||
"--manual",
|
||||
"Intermodal Manual",
|
||||
"--no-info",
|
||||
"--source",
|
||||
&format!("Intermodal {}", version),
|
||||
command
|
||||
)
|
||||
.out()?;
|
||||
|
||||
let man = output
|
||||
.replace("📦 ", "\n")
|
||||
.replace("\n.SS ", "\n.SH ")
|
||||
.replace("\"USAGE:\"", "\"SYNOPSIS:\"");
|
||||
|
||||
let re = Regex::new(r"(?ms).SH DESCRIPTION.*?.SH").unwrap();
|
||||
|
||||
let man = re.replace(&man, ".SH").into_owned();
|
||||
|
||||
man
|
||||
}
|
||||
|
||||
pub(crate) fn slug(&self) -> String {
|
||||
let mut slug = "imdl".to_string();
|
||||
|
||||
for name in &self.command {
|
||||
slug.push('-');
|
||||
slug.push_str(&name);
|
||||
}
|
||||
|
||||
slug
|
||||
}
|
||||
|
||||
pub(crate) fn command_line(&self) -> String {
|
||||
let mut line = "imdl".to_string();
|
||||
|
||||
for name in &self.command {
|
||||
line.push(' ');
|
||||
line.push_str(&name);
|
||||
}
|
||||
|
||||
line
|
||||
}
|
||||
|
||||
#[throws]
|
||||
pub(crate) fn page(&self) -> String {
|
||||
let help = self.help()?;
|
||||
format!("# `{}`\n```\n{}\n```", self.command_line(), help)
|
||||
}
|
||||
}
|
|
@ -17,8 +17,6 @@ pub(crate) use cargo_toml::Manifest;
|
|||
pub(crate) use chrono::{DateTime, NaiveDateTime, Utc};
|
||||
pub(crate) use fehler::{throw, throws};
|
||||
pub(crate) use git2::{Commit, Oid, Repository};
|
||||
pub(crate) use ignore::overrides::OverrideBuilder;
|
||||
pub(crate) use lexiclean::Lexiclean;
|
||||
pub(crate) use libc::EXIT_FAILURE;
|
||||
pub(crate) use log::info;
|
||||
pub(crate) use regex::Regex;
|
||||
|
@ -29,7 +27,6 @@ pub(crate) use structopt::StructOpt;
|
|||
pub(crate) use strum::VariantNames;
|
||||
pub(crate) use strum_macros::{EnumVariantNames, IntoStaticStr};
|
||||
pub(crate) use url::Url;
|
||||
pub(crate) use walkdir::WalkDir;
|
||||
|
||||
// modules
|
||||
pub(crate) use crate::error;
|
||||
|
@ -39,9 +36,9 @@ pub(crate) use crate::{command_ext::CommandExt, row::Row, slug::Slug, template_e
|
|||
|
||||
// structs and enums
|
||||
pub(crate) use crate::{
|
||||
bin::Bin, changelog::Changelog, config::Config, entry::Entry, error::Error, example::Example,
|
||||
faq::Faq, faq_entry::FaqEntry, introduction::Introduction, kind::Kind, metadata::Metadata,
|
||||
opt::Opt, package::Package, project::Project, readme::Readme, reference::Reference,
|
||||
reference_section::ReferenceSection, release::Release, subcommand::Subcommand, summary::Summary,
|
||||
table::Table,
|
||||
arguments::Arguments, bin::Bin, bin_subcommand::BinSubcommand, changelog::Changelog,
|
||||
config::Config, entry::Entry, error::Error, example::Example, faq::Faq, faq_entry::FaqEntry,
|
||||
introduction::Introduction, kind::Kind, metadata::Metadata, options::Options, package::Package,
|
||||
project::Project, readme::Readme, reference::Reference, reference_section::ReferenceSection,
|
||||
release::Release, subcommand::Subcommand, summary::Summary, table::Table,
|
||||
};
|
||||
|
|
|
@ -58,6 +58,12 @@ pub(crate) enum Error {
|
|||
dst: PathBuf,
|
||||
source: io::Error,
|
||||
},
|
||||
#[snafu(display("I/O error copying `{}` to `{}`: {}", src.display(), dst.display(), source))]
|
||||
FilesystemRecursiveCopy {
|
||||
src: PathBuf,
|
||||
dst: PathBuf,
|
||||
source: fs_extra::error::Error,
|
||||
},
|
||||
#[snafu(display("Git error: {}", source))]
|
||||
Git { source: git2::Error },
|
||||
#[snafu(display("Regex compilation error: {}", source))]
|
||||
|
@ -73,10 +79,6 @@ pub(crate) enum Error {
|
|||
TemplateRender { source: askama::Error },
|
||||
#[snafu(display("Failed to get workdir for repo at `{}`", repo.display()))]
|
||||
Workdir { repo: PathBuf },
|
||||
#[snafu(display("Failed to build overrides: {}", source))]
|
||||
Ignore { source: ignore::Error },
|
||||
#[snafu(display("Failed to traverse worktree: {}", source))]
|
||||
Walkdir { source: walkdir::Error },
|
||||
#[snafu(display("Failed to strip path prefix: {}", source))]
|
||||
StripPrefix { source: StripPrefixError },
|
||||
}
|
||||
|
@ -98,15 +100,3 @@ impl From<cargo_toml::Error> for Error {
|
|||
Self::CargoToml { source }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ignore::Error> for Error {
|
||||
fn from(source: ignore::Error) -> Self {
|
||||
Self::Ignore { source }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<walkdir::Error> for Error {
|
||||
fn from(source: walkdir::Error) -> Self {
|
||||
Self::Walkdir { source }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,9 @@ use crate::common::*;
|
|||
#[macro_use]
|
||||
mod cmd;
|
||||
|
||||
mod arguments;
|
||||
mod bin;
|
||||
mod bin_subcommand;
|
||||
mod changelog;
|
||||
mod command_ext;
|
||||
mod common;
|
||||
|
@ -16,7 +18,7 @@ mod faq_entry;
|
|||
mod introduction;
|
||||
mod kind;
|
||||
mod metadata;
|
||||
mod opt;
|
||||
mod options;
|
||||
mod package;
|
||||
mod project;
|
||||
mod readme;
|
||||
|
@ -33,7 +35,7 @@ mod template_ext;
|
|||
fn main() {
|
||||
pretty_env_logger::init();
|
||||
|
||||
if let Err(error) = Opt::from_args().run() {
|
||||
if let Err(error) = Arguments::from_args().run() {
|
||||
let bold = Style::new().bold();
|
||||
let red = Style::new().fg(ansi_term::Color::Red).bold();
|
||||
eprintln!("{}: {}", red.paint("error"), bold.paint(error.to_string()));
|
||||
|
|
|
@ -1,283 +0,0 @@
|
|||
use crate::common::*;
|
||||
|
||||
#[derive(StructOpt)]
|
||||
pub(crate) enum Opt {
|
||||
#[structopt(about("Update all generated docs"))]
|
||||
All,
|
||||
#[structopt(about("Generate book"))]
|
||||
Book,
|
||||
#[structopt(about("Generate the changelog"))]
|
||||
Changelog,
|
||||
#[structopt(about("Print a commit template to standard output"))]
|
||||
CommitTemplate,
|
||||
#[structopt(about("Print possible values for `type` field of commit metadata"))]
|
||||
CommitTypes,
|
||||
#[structopt(about("Generate completion scripts"))]
|
||||
CompletionScripts,
|
||||
#[structopt(about("Diff generated content between commits"))]
|
||||
Diff,
|
||||
#[structopt(about("Generate readme"))]
|
||||
Readme,
|
||||
#[structopt(about("Generate man pages"))]
|
||||
Man,
|
||||
}
|
||||
|
||||
#[throws]
|
||||
fn blank(path: impl AsRef<Path>, title: &str) {
|
||||
let path = path.as_ref();
|
||||
|
||||
info!("Writing blank page to `{}`…", path.display());
|
||||
|
||||
let text = format!(
|
||||
"
|
||||
# {}
|
||||
|
||||
This page intentionally left blank.
|
||||
",
|
||||
title
|
||||
);
|
||||
|
||||
fs::write(&path, text).context(error::Filesystem { path })?;
|
||||
}
|
||||
|
||||
#[throws]
|
||||
fn clean_dir(path: impl AsRef<Path>) {
|
||||
let path = path.as_ref();
|
||||
|
||||
info!("Cleaning `{}`…", path.display());
|
||||
|
||||
if path.is_dir() {
|
||||
fs::remove_dir_all(path).context(error::Filesystem { path: &path })?;
|
||||
}
|
||||
|
||||
fs::create_dir_all(path).context(error::Filesystem { path: &path })?;
|
||||
}
|
||||
|
||||
impl Opt {
|
||||
#[throws]
|
||||
pub(crate) fn run(self) {
|
||||
let project = Project::load()?;
|
||||
|
||||
match self {
|
||||
Self::Changelog => Self::changelog(&project)?,
|
||||
Self::CommitTemplate => {
|
||||
println!("{}", Metadata::default().to_string());
|
||||
}
|
||||
Self::CommitTypes => {
|
||||
for kind in Kind::VARIANTS {
|
||||
println!("{}", kind)
|
||||
}
|
||||
}
|
||||
Self::CompletionScripts => Self::completion_scripts(&project)?,
|
||||
Self::Readme => Self::readme(&project)?,
|
||||
Self::Book => Self::book(&project)?,
|
||||
Self::Man => Self::man(&project)?,
|
||||
Self::Diff => Self::diff(&project)?,
|
||||
Self::All => Self::all(&project)?,
|
||||
}
|
||||
}
|
||||
|
||||
#[throws]
|
||||
pub(crate) fn all(project: &Project) {
|
||||
Self::changelog(&project)?;
|
||||
Self::completion_scripts(&project)?;
|
||||
Self::readme(&project)?;
|
||||
Self::book(&project)?;
|
||||
Self::man(&project)?;
|
||||
}
|
||||
|
||||
#[throws]
|
||||
pub(crate) fn changelog(project: &Project) {
|
||||
info!("Generating changelog…");
|
||||
let changelog = Changelog::new(&project)?;
|
||||
|
||||
let path = project.root.join("CHANGELOG.md");
|
||||
|
||||
fs::write(&path, changelog.render(false)?).context(error::Filesystem { path })?;
|
||||
}
|
||||
|
||||
#[throws]
|
||||
pub(crate) fn completion_scripts(project: &Project) {
|
||||
info!("Generating completion scripts…");
|
||||
let completions = project.root.join("completions");
|
||||
|
||||
clean_dir(&completions)?;
|
||||
|
||||
cmd!(
|
||||
"cargo",
|
||||
"run",
|
||||
"--package",
|
||||
"imdl",
|
||||
"completions",
|
||||
"--dir",
|
||||
completions
|
||||
)
|
||||
.status_into_result()?
|
||||
}
|
||||
|
||||
#[throws]
|
||||
pub(crate) fn diff(project: &Project) {
|
||||
let tmp = tempfile::tempdir().context(error::Tempdir)?;
|
||||
|
||||
let generated = &[
|
||||
"/CHANGELOG.md",
|
||||
"/README.md",
|
||||
"/book/src/SUMMARY.md",
|
||||
"/book/src/bittorrent.md",
|
||||
"/book/src/changelog.md",
|
||||
"/book/src/commands.md",
|
||||
"/book/src/commands/*",
|
||||
"/book/src/faq.md",
|
||||
"/book/src/introduction.md",
|
||||
"/book/src/references.md",
|
||||
"/book/src/references/*",
|
||||
"/completions/*",
|
||||
"/man/*",
|
||||
];
|
||||
|
||||
let gen = |name: &str| -> Result<(), Error> {
|
||||
cmd!("cargo", "run", "--package", "gen", "all").status_into_result()?;
|
||||
|
||||
let dir = tmp.path().join(name);
|
||||
|
||||
fs::create_dir(&dir).context(error::Filesystem { path: &dir })?;
|
||||
|
||||
let mut builder = OverrideBuilder::new(&project.root);
|
||||
|
||||
for pattern in generated {
|
||||
builder.add(pattern)?;
|
||||
}
|
||||
|
||||
let overrides = builder.build()?;
|
||||
|
||||
for result in WalkDir::new(&project.root) {
|
||||
let entry = result?;
|
||||
|
||||
let src = entry.path();
|
||||
|
||||
if src.is_dir() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if !overrides.matched(&src, false).is_whitelist() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let relative = src
|
||||
.strip_prefix(&project.root)
|
||||
.context(error::StripPrefix)?;
|
||||
|
||||
let dst = dir.join(relative);
|
||||
|
||||
let dst_dir = dst.join("..").lexiclean();
|
||||
|
||||
fs::create_dir_all(&dst_dir).context(error::Filesystem { path: dst_dir })?;
|
||||
|
||||
fs::copy(&src, &dst).context(error::FilesystemCopy { src, dst })?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
};
|
||||
|
||||
const HEAD: &str = "HEAD";
|
||||
|
||||
gen(HEAD)?;
|
||||
|
||||
let head = project.repo.head()?;
|
||||
|
||||
let head_commit = head.peel_to_commit()?;
|
||||
|
||||
let parent = head_commit.parent(0)?;
|
||||
|
||||
let parent_hash = parent.id().to_string();
|
||||
|
||||
cmd!("git", "checkout", &parent_hash).status_into_result()?;
|
||||
|
||||
gen(&parent_hash)?;
|
||||
|
||||
cmd!("colordiff", "-ur", parent_hash, HEAD)
|
||||
.current_dir(tmp.path())
|
||||
.status_into_result()
|
||||
.ok();
|
||||
|
||||
cmd!(
|
||||
"git",
|
||||
"checkout",
|
||||
head
|
||||
.shorthand()
|
||||
.map(str::to_owned)
|
||||
.unwrap_or_else(|| head_commit.id().to_string())
|
||||
)
|
||||
.status_into_result()?;
|
||||
}
|
||||
|
||||
#[throws]
|
||||
pub(crate) fn readme(project: &Project) {
|
||||
info!("Generating readme…");
|
||||
|
||||
let template = project.root.join("bin/gen/templates/README.md");
|
||||
|
||||
let readme = Readme::load(&project.config, &template)?;
|
||||
|
||||
let text = readme.render_newline()?;
|
||||
|
||||
let path = project.root.join("README.md");
|
||||
fs::write(&path, text).context(error::Filesystem { path })?;
|
||||
}
|
||||
|
||||
#[throws]
|
||||
pub(crate) fn book(project: &Project) {
|
||||
info!("Generating book…");
|
||||
|
||||
blank(project.root.join("book/src/commands.md"), "Commands")?;
|
||||
blank(project.root.join("book/src/bittorrent.md"), "BitTorrent")?;
|
||||
blank(project.root.join("book/src/references.md"), "References")?;
|
||||
|
||||
let commands = project.root.join("book/src/commands/");
|
||||
|
||||
clean_dir(&commands)?;
|
||||
|
||||
for subcommand in &project.bin.subcommands {
|
||||
let page = subcommand.page()?;
|
||||
|
||||
let dst = commands.join(format!("{}.md", subcommand.slug()));
|
||||
|
||||
fs::write(&dst, page).context(error::Filesystem { path: dst })?;
|
||||
}
|
||||
|
||||
clean_dir(&project.root.join("book/src/references/"))?;
|
||||
|
||||
for section in &project.config.references {
|
||||
section.render_to(project.root.join("book/src").join(section.path()))?;
|
||||
}
|
||||
|
||||
Faq::new(&project.config.faq).render_to(project.root.join("book/src/faq.md"))?;
|
||||
|
||||
Summary::new(project).render_to(project.root.join("book/src/SUMMARY.md"))?;
|
||||
|
||||
Introduction::new(&project.config).render_to(project.root.join("book/src/introduction.md"))?;
|
||||
|
||||
let changelog = Changelog::new(&project)?;
|
||||
|
||||
let dst = project.root.join("book/src/changelog.md");
|
||||
fs::write(&dst, changelog.render(true)?).context(error::Filesystem { path: dst })?;
|
||||
}
|
||||
|
||||
#[throws]
|
||||
pub(crate) fn man(project: &Project) {
|
||||
info!("Generating man pages…");
|
||||
let mans = project.root.join("man");
|
||||
|
||||
clean_dir(&mans)?;
|
||||
|
||||
for subcommand in &project.bin.subcommands {
|
||||
let man = subcommand.man()?;
|
||||
|
||||
let dst = mans.join(format!("{}.1", subcommand.slug()));
|
||||
|
||||
info!("Writing man page to `{}`", dst.display());
|
||||
|
||||
fs::write(&dst, man).context(error::Filesystem { path: dst })?;
|
||||
}
|
||||
}
|
||||
}
|
11
bin/gen/src/options.rs
Normal file
11
bin/gen/src/options.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
use crate::common::*;
|
||||
|
||||
#[derive(StructOpt)]
|
||||
pub(crate) struct Options {
|
||||
#[structopt(
|
||||
long("bin"),
|
||||
value_name("EXECUTABLE"),
|
||||
help("Path to the `imdl` binary.")
|
||||
)]
|
||||
pub(crate) bin: PathBuf,
|
||||
}
|
|
@ -5,11 +5,12 @@ pub(crate) struct Project {
|
|||
pub(crate) root: PathBuf,
|
||||
pub(crate) config: Config,
|
||||
pub(crate) bin: Bin,
|
||||
pub(crate) executable: PathBuf,
|
||||
}
|
||||
|
||||
impl Project {
|
||||
#[throws]
|
||||
pub(crate) fn load() -> Self {
|
||||
pub(crate) fn load(options: &Options) -> Self {
|
||||
let start_dir = env::current_dir().context(error::CurrentDir)?;
|
||||
|
||||
let repo = Repository::discover(&start_dir).context(error::RepositoryDiscover { start_dir })?;
|
||||
|
@ -23,7 +24,7 @@ impl Project {
|
|||
|
||||
let config = Config::load(&root)?;
|
||||
|
||||
let bin = Bin::new(&root.join("target/debug/imdl"))?;
|
||||
let bin = Bin::new(&options.bin)?;
|
||||
|
||||
let example_commands = config
|
||||
.examples
|
||||
|
@ -45,10 +46,22 @@ impl Project {
|
|||
}
|
||||
|
||||
Project {
|
||||
executable: options.bin.clone(),
|
||||
bin,
|
||||
config,
|
||||
repo,
|
||||
root,
|
||||
config,
|
||||
bin,
|
||||
}
|
||||
}
|
||||
|
||||
#[throws]
|
||||
pub(crate) fn gen(&self) -> PathBuf {
|
||||
let gen = self.root.join("target").join("gen");
|
||||
|
||||
if !gen.is_dir() {
|
||||
fs::create_dir_all(&gen).context(error::Filesystem { path: &gen })?;
|
||||
}
|
||||
|
||||
gen
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,6 @@ pub(crate) struct ReferenceSection {
|
|||
|
||||
impl ReferenceSection {
|
||||
pub(crate) fn path(&self) -> String {
|
||||
format!("./references/{}.md", self.title.slug())
|
||||
format!("references/{}.md", self.title.slug())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,164 +1,240 @@
|
|||
use crate::common::*;
|
||||
|
||||
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq)]
|
||||
pub(crate) struct Subcommand {
|
||||
pub(crate) bin: PathBuf,
|
||||
pub(crate) command: Vec<String>,
|
||||
pub(crate) subcommands: Vec<String>,
|
||||
#[derive(StructOpt)]
|
||||
pub(crate) enum Subcommand {
|
||||
#[structopt(about("Update all generated docs"))]
|
||||
All,
|
||||
#[structopt(about("Generate book"))]
|
||||
Book,
|
||||
#[structopt(about("Generate the changelog"))]
|
||||
Changelog,
|
||||
#[structopt(about("Print a commit template to standard output"))]
|
||||
CommitTemplate,
|
||||
#[structopt(about("Print possible values for `type` field of commit metadata"))]
|
||||
CommitTypes,
|
||||
#[structopt(about("Generate completion scripts"))]
|
||||
CompletionScripts,
|
||||
#[structopt(about("Diff generated content between commits"))]
|
||||
Diff,
|
||||
#[structopt(about("Generate readme"))]
|
||||
Readme,
|
||||
#[structopt(about("Generate man pages"))]
|
||||
Man,
|
||||
}
|
||||
|
||||
#[throws]
|
||||
fn blank(path: impl AsRef<Path>, title: &str) {
|
||||
let path = path.as_ref();
|
||||
|
||||
info!("Writing blank page to `{}`…", path.display());
|
||||
|
||||
let text = format!(
|
||||
"
|
||||
# {}
|
||||
|
||||
This page intentionally left blank.
|
||||
",
|
||||
title
|
||||
);
|
||||
|
||||
fs::write(&path, text).context(error::Filesystem { path })?;
|
||||
}
|
||||
|
||||
#[throws]
|
||||
fn clean_dir(path: impl AsRef<Path>) {
|
||||
let path = path.as_ref();
|
||||
|
||||
info!("Cleaning `{}`…", path.display());
|
||||
|
||||
if path.is_dir() {
|
||||
fs::remove_dir_all(path).context(error::Filesystem { path: &path })?;
|
||||
}
|
||||
|
||||
fs::create_dir_all(path).context(error::Filesystem { path: &path })?;
|
||||
}
|
||||
|
||||
impl Subcommand {
|
||||
#[throws]
|
||||
pub(crate) fn new(bin: &Path, command: Vec<String>) -> Self {
|
||||
let wide_help = Command::new(bin)
|
||||
.args(command.as_slice())
|
||||
.env("IMDL_TERM_WIDTH", "200")
|
||||
.arg("--help")
|
||||
.out()?;
|
||||
pub(crate) fn run(self, options: Options) {
|
||||
let project = Project::load(&options)?;
|
||||
|
||||
const MARKER: &str = "\nSUBCOMMANDS:\n";
|
||||
|
||||
let mut subcommands = Vec::new();
|
||||
|
||||
if let Some(marker) = wide_help.find(MARKER) {
|
||||
let block = &wide_help[marker + MARKER.len()..];
|
||||
|
||||
for line in block.lines() {
|
||||
let name = line.trim().split_whitespace().next().unwrap();
|
||||
subcommands.push(name.into());
|
||||
match self {
|
||||
Self::Changelog => Self::changelog(&project)?,
|
||||
Self::CommitTemplate => {
|
||||
println!("{}", Metadata::default().to_string());
|
||||
}
|
||||
}
|
||||
|
||||
Self {
|
||||
bin: bin.into(),
|
||||
command,
|
||||
subcommands,
|
||||
Self::CommitTypes => {
|
||||
for kind in Kind::VARIANTS {
|
||||
println!("{}", kind)
|
||||
}
|
||||
}
|
||||
Self::CompletionScripts => Self::completion_scripts(&project)?,
|
||||
Self::Readme => Self::readme(&project)?,
|
||||
Self::Book => Self::book(&project)?,
|
||||
Self::Man => Self::man(&project)?,
|
||||
Self::Diff => Self::diff(&project)?,
|
||||
Self::All => Self::all(&project)?,
|
||||
}
|
||||
}
|
||||
|
||||
#[throws]
|
||||
fn help(&self) -> String {
|
||||
info!("Getting help for `{}`", self.command_line());
|
||||
|
||||
Command::new(&self.bin)
|
||||
.args(self.command.as_slice())
|
||||
.env("IMDL_TERM_WIDTH", "80")
|
||||
.arg("--help")
|
||||
.out()?
|
||||
pub(crate) fn all(project: &Project) {
|
||||
Self::changelog(&project)?;
|
||||
Self::completion_scripts(&project)?;
|
||||
Self::readme(&project)?;
|
||||
Self::book(&project)?;
|
||||
Self::man(&project)?;
|
||||
}
|
||||
|
||||
#[throws]
|
||||
pub(crate) fn man(&self) -> String {
|
||||
let command_line = self.command_line();
|
||||
pub(crate) fn changelog(project: &Project) {
|
||||
info!("Generating changelog…");
|
||||
let changelog = Changelog::new(&project)?;
|
||||
|
||||
info!("Generating man page for `{}`", command_line);
|
||||
let path = project.gen()?.join("CHANGELOG.md");
|
||||
|
||||
let name = command_line.replace(" ", "\\ ");
|
||||
fs::write(&path, changelog.render(false)?).context(error::Filesystem { path })?;
|
||||
}
|
||||
|
||||
let help = self.help()?;
|
||||
#[throws]
|
||||
pub(crate) fn completion_scripts(project: &Project) {
|
||||
info!("Generating completion scripts…");
|
||||
let completions = project.gen()?.join("completions");
|
||||
|
||||
let description = if self.command.is_empty() {
|
||||
"A 40' shipping container for the Internet".to_string()
|
||||
} else {
|
||||
help.lines().nth(1).unwrap().into()
|
||||
};
|
||||
clean_dir(&completions)?;
|
||||
|
||||
let include = format!(
|
||||
"\
|
||||
[NAME]
|
||||
\\fB{}\\fR
|
||||
- {}
|
||||
",
|
||||
name, description
|
||||
);
|
||||
cmd!(&project.executable, "completions", "--dir", completions).status_into_result()?
|
||||
}
|
||||
|
||||
#[throws]
|
||||
pub(crate) fn diff(project: &Project) {
|
||||
let tmp = tempfile::tempdir().context(error::Tempdir)?;
|
||||
|
||||
let include_path = tmp.path().join("include");
|
||||
let gen = |name: &str| -> Result<(), Error> {
|
||||
let src = Path::new("target/gen");
|
||||
|
||||
fs::write(&include_path, include).context(error::Filesystem {
|
||||
path: &include_path,
|
||||
})?;
|
||||
fs::remove_dir_all(src).context(error::Filesystem { path: src })?;
|
||||
|
||||
let version = cmd!(&self.bin, "--version")
|
||||
.out()?
|
||||
.split_whitespace()
|
||||
.nth(1)
|
||||
.unwrap()
|
||||
.to_owned();
|
||||
cmd!("cargo", "run", "--package", "gen", "all").status_into_result()?;
|
||||
|
||||
info!("Running help2man for `{}`", command_line);
|
||||
let dir = tmp.path().join(name);
|
||||
|
||||
let mut command = self.bin.as_os_str().to_owned();
|
||||
for arg in &self.command {
|
||||
command.push(" ");
|
||||
command.push(arg);
|
||||
}
|
||||
fs::create_dir(&dir).context(error::Filesystem { path: &dir })?;
|
||||
|
||||
let output = cmd!(
|
||||
"help2man",
|
||||
"--include",
|
||||
&include_path,
|
||||
"--manual",
|
||||
"Intermodal Manual",
|
||||
"--no-info",
|
||||
"--source",
|
||||
&format!("Intermodal {}", version),
|
||||
command
|
||||
fs_extra::dir::copy(src, &dir, &fs_extra::dir::CopyOptions::new())
|
||||
.context(error::FilesystemRecursiveCopy { src, dst: dir })?;
|
||||
|
||||
Ok(())
|
||||
};
|
||||
|
||||
const HEAD: &str = "HEAD";
|
||||
|
||||
gen(HEAD)?;
|
||||
|
||||
let head = project.repo.head()?;
|
||||
|
||||
let head_commit = head.peel_to_commit()?;
|
||||
|
||||
let parent = head_commit.parent(0)?;
|
||||
|
||||
let parent_hash = parent.id().to_string();
|
||||
|
||||
cmd!("git", "checkout", &parent_hash).status_into_result()?;
|
||||
|
||||
gen(&parent_hash)?;
|
||||
|
||||
cmd!("colordiff", "-ur", parent_hash, HEAD)
|
||||
.current_dir(tmp.path())
|
||||
.status_into_result()
|
||||
.ok();
|
||||
|
||||
cmd!(
|
||||
"git",
|
||||
"checkout",
|
||||
head
|
||||
.shorthand()
|
||||
.map(str::to_owned)
|
||||
.unwrap_or_else(|| head_commit.id().to_string())
|
||||
)
|
||||
.out()?;
|
||||
|
||||
let man = output
|
||||
.replace("📦 ", "\n")
|
||||
.replace("\n.SS ", "\n.SH ")
|
||||
.replace("\"USAGE:\"", "\"SYNOPSIS:\"");
|
||||
|
||||
let re = Regex::new(r"(?ms).SH DESCRIPTION.*?.SH").unwrap();
|
||||
|
||||
let man = re.replace(&man, ".SH").into_owned();
|
||||
|
||||
man
|
||||
}
|
||||
|
||||
pub(crate) fn slug(&self) -> String {
|
||||
let mut slug = self
|
||||
.bin
|
||||
.display()
|
||||
.to_string()
|
||||
.split('/')
|
||||
.last()
|
||||
.unwrap()
|
||||
.to_owned();
|
||||
|
||||
for name in &self.command {
|
||||
slug.push('-');
|
||||
slug.push_str(&name);
|
||||
}
|
||||
|
||||
slug
|
||||
}
|
||||
|
||||
pub(crate) fn command_line(&self) -> String {
|
||||
let mut line = self
|
||||
.bin
|
||||
.display()
|
||||
.to_string()
|
||||
.split('/')
|
||||
.last()
|
||||
.unwrap()
|
||||
.to_owned();
|
||||
|
||||
for name in &self.command {
|
||||
line.push(' ');
|
||||
line.push_str(&name);
|
||||
}
|
||||
|
||||
line
|
||||
.status_into_result()?;
|
||||
}
|
||||
|
||||
#[throws]
|
||||
pub(crate) fn page(&self) -> String {
|
||||
let help = self.help()?;
|
||||
format!("# `{}`\n```\n{}\n```", self.command_line(), help)
|
||||
pub(crate) fn readme(project: &Project) {
|
||||
info!("Generating readme…");
|
||||
|
||||
let template = project.root.join("bin/gen/templates/README.md");
|
||||
|
||||
let readme = Readme::load(&project.config, &template)?;
|
||||
|
||||
let text = readme.render_newline()?;
|
||||
|
||||
let path = project.gen()?.join("README.md");
|
||||
fs::write(&path, &text).context(error::Filesystem { path })?;
|
||||
|
||||
let path = project.root.join("README.md");
|
||||
fs::write(&path, &text).context(error::Filesystem { path })?;
|
||||
}
|
||||
|
||||
#[throws]
|
||||
pub(crate) fn book(project: &Project) {
|
||||
info!("Generating book…");
|
||||
|
||||
let gen = project.gen()?;
|
||||
|
||||
let out = gen.join("book");
|
||||
|
||||
fs::create_dir_all(&out).context(error::Filesystem { path: &out })?;
|
||||
|
||||
blank(out.join("commands.md"), "Commands")?;
|
||||
blank(out.join("bittorrent.md"), "BitTorrent")?;
|
||||
blank(out.join("references.md"), "References")?;
|
||||
|
||||
let commands = out.join("commands");
|
||||
|
||||
clean_dir(&commands)?;
|
||||
|
||||
for subcommand in &project.bin.subcommands {
|
||||
let page = subcommand.page()?;
|
||||
|
||||
let dst = commands.join(format!("{}.md", subcommand.slug()));
|
||||
|
||||
fs::write(&dst, page).context(error::Filesystem { path: dst })?;
|
||||
}
|
||||
|
||||
clean_dir(&out.join("references"))?;
|
||||
|
||||
for section in &project.config.references {
|
||||
section.render_to(out.join(section.path()))?;
|
||||
}
|
||||
|
||||
Faq::new(&project.config.faq).render_to(out.join("faq.md"))?;
|
||||
|
||||
Summary::new(project).render_to(out.join("SUMMARY.md"))?;
|
||||
|
||||
Introduction::new(&project.config).render_to(out.join("introduction.md"))?;
|
||||
|
||||
let changelog = Changelog::new(&project)?;
|
||||
|
||||
let dst = out.join("changelog.md");
|
||||
fs::write(&dst, changelog.render(true)?).context(error::Filesystem { path: dst })?;
|
||||
}
|
||||
|
||||
#[throws]
|
||||
pub(crate) fn man(project: &Project) {
|
||||
info!("Generating man pages…");
|
||||
let mans = project.gen()?.join("man");
|
||||
|
||||
clean_dir(&mans)?;
|
||||
|
||||
for subcommand in &project.bin.subcommands {
|
||||
let man = subcommand.man()?;
|
||||
|
||||
let dst = mans.join(format!("{}.1", subcommand.slug()));
|
||||
|
||||
info!("Writing man page to `{}`", dst.display());
|
||||
|
||||
fs::write(&dst, man).context(error::Filesystem { path: dst })?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -154,46 +154,38 @@ Intermodal is distributed under the
|
|||
a public domain dedication with a fallback all-permissive license. The SPDX
|
||||
identifier of the CC0 is [CC0-1.0](https://spdx.org/licenses/CC0-1.0.html).
|
||||
|
||||
### Package Artifacts
|
||||
### Build Artifacts
|
||||
|
||||
There are three primary build artifacts: the binary, the man pages, and the
|
||||
shell completion scripts.
|
||||
There are a number of build artifacts: the binary, the man pages, the
|
||||
changelog, and the shell completion scripts.
|
||||
|
||||
#### Binary
|
||||
The binary is built with `cargo`, and the other artifacts are built `gen`,
|
||||
located in `bin/gen`.
|
||||
|
||||
The binary is called `imdl`, and can be built with:
|
||||
The binary can be built with:
|
||||
|
||||
```
|
||||
cargo build --release
|
||||
```
|
||||
cargo build --release
|
||||
|
||||
After building, the binary will be present at `target/release/imdl`.
|
||||
_`gen` requires [`help2man`](https://www.gnu.org/software/help2man/) to be
|
||||
installed, which is used to generate man pages from subcommand `--help`
|
||||
strings._
|
||||
|
||||
#### Man Pages
|
||||
The rest of the build artifacts can be built with `gen`:
|
||||
|
||||
Intermodal has a number of subcommands, each of which has a man page. The man
|
||||
pages are generated from the `--help` text using
|
||||
[`help2man`](https://www.gnu.org/software/help2man/).
|
||||
cargo run --package gen -- --bin target/release/imdl all
|
||||
|
||||
To generate the man pages, ensure `help2man` is available, and run:
|
||||
_The path to the built `imdl` executable should be passed to `gen` with the `--bin` flag._
|
||||
|
||||
```
|
||||
mkdir -p man
|
||||
cargo run --package gen man
|
||||
```
|
||||
After running the above commands, the following table shows the location of the
|
||||
built artifacts.
|
||||
|
||||
After building, the man pages will be available in `man`.
|
||||
|
||||
#### Completion Scripts
|
||||
|
||||
Completion scripts are available for a number of shells. To generate them, run:
|
||||
|
||||
```
|
||||
mkdir -p completions
|
||||
cargo run --release completions --dir completions
|
||||
```
|
||||
|
||||
After running, the completion scripts will be available in `completions`.
|
||||
| Artifact | Location |
|
||||
|--------------------|----------------------------|
|
||||
| Binary | `target/release/imdl` |
|
||||
| Man Pages | `target/gen/man/*` |
|
||||
| Completion Scripts | `target/gen/completions/*` |
|
||||
| Changelog | `target/gen/CHANGELOG.md` |
|
||||
| Readme | `target/gen/README.md` |
|
||||
|
||||
### Release Updates
|
||||
|
||||
|
|
31
bin/package
31
bin/package
|
@ -6,7 +6,7 @@ version=${1#"refs/tags/"}
|
|||
os=$2
|
||||
target=$3
|
||||
src=`pwd`
|
||||
dist=$src/dist
|
||||
dist=$src/target/dist
|
||||
bin=imdl
|
||||
|
||||
echo "Packaging $bin $version for $target..."
|
||||
|
@ -38,32 +38,35 @@ case $os in
|
|||
esac
|
||||
|
||||
echo "Building completions..."
|
||||
rm -rf completions
|
||||
mkdir completions
|
||||
$executable completions --dir completions
|
||||
cargo run --package gen -- --bin $executable completion-scripts
|
||||
|
||||
echo "Generating changelog..."
|
||||
cargo run --package gen changelog
|
||||
cargo run --package gen -- --bin $executable changelog
|
||||
|
||||
echo "Copying release files..."
|
||||
mkdir dist
|
||||
echo "Generating readme..."
|
||||
cargo run --package gen -- --bin $executable readme
|
||||
|
||||
echo "Copying static files..."
|
||||
mkdir $dist
|
||||
cp -r \
|
||||
$executable \
|
||||
CHANGELOG.md \
|
||||
CONTRIBUTING \
|
||||
Cargo.lock \
|
||||
Cargo.toml \
|
||||
LICENSE \
|
||||
README.md \
|
||||
completions \
|
||||
$dist
|
||||
|
||||
echo "Copying generated files..."
|
||||
cp -r \
|
||||
target/gen/README.md \
|
||||
target/gen/CHANGELOG.md \
|
||||
target/gen/completions \
|
||||
$dist
|
||||
|
||||
if [[ $os != windows-latest ]]; then
|
||||
echo "Building man pages..."
|
||||
rm -rf man
|
||||
mkdir man
|
||||
cargo run --package gen man
|
||||
cp -r man $dist/man
|
||||
cargo run --package gen -- --bin $executable man
|
||||
cp -r target/gen/man $dist/man
|
||||
fi
|
||||
|
||||
cd $dist
|
||||
|
|
1
book/src/SUMMARY.md
Symbolic link
1
book/src/SUMMARY.md
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../target/gen/book/SUMMARY.md
|
1
book/src/bittorrent.md
Symbolic link
1
book/src/bittorrent.md
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../target/gen/book/bittorrent.md
|
1
book/src/changelog.md
Symbolic link
1
book/src/changelog.md
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../target/gen/book/changelog.md
|
1
book/src/commands
Symbolic link
1
book/src/commands
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../target/gen/book/commands
|
1
book/src/commands.md
Symbolic link
1
book/src/commands.md
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../target/gen/book/commands.md
|
1
book/src/faq.md
Symbolic link
1
book/src/faq.md
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../target/gen/book/faq.md
|
1
book/src/introduction.md
Symbolic link
1
book/src/introduction.md
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../target/gen/book/introduction.md
|
1
book/src/references
Symbolic link
1
book/src/references
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../target/gen/book/references
|
1
book/src/references.md
Symbolic link
1
book/src/references.md
Symbolic link
|
@ -0,0 +1 @@
|
|||
../../target/gen/book/references.md
|
Loading…
Reference in New Issue
Block a user