Merge remote-tracking branch 'master' into wip/rename

Conflicts:
	.reuse/dep5
	Cargo.toml
	api/cpp/README.md
	api/cpp/docs/conf.py
	api/rs/slint/Cargo.toml
	docs/development.md
This commit is contained in:
Olivier Goffart 2022-02-02 15:04:22 +01:00
commit ad4eea9e96
10 changed files with 17 additions and 370 deletions

View file

@ -24,7 +24,7 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Set up rgb crate rustdoc link - name: Set up rgb crate rustdoc link
run: | run: |
rgb_version=`grep 'rgb = ' sixtyfps_runtime/corelib/Cargo.toml | sed 's/^.*"\(.*\)"/\1/'` rgb_version=`grep 'rgb = ' internal/core/Cargo.toml | sed 's/^.*"\(.*\)"/\1/'`
echo "RUSTDOCFLAGS=$RUSTDOCFLAGS --extern-html-root-url rgb=https://docs.rs/rgb/$rgb_version/ -Z unstable-options" >> $GITHUB_ENV echo "RUSTDOCFLAGS=$RUSTDOCFLAGS --extern-html-root-url rgb=https://docs.rs/rgb/$rgb_version/ -Z unstable-options" >> $GITHUB_ENV
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@v1 uses: actions/setup-node@v1

View file

@ -23,13 +23,13 @@ jobs:
git ls-files | grep Cargo.toml | xargs sed -i 's/\(sixtyfps.*version = \)"=[0-9]*\.[0-9]*\.[0-9]*"/\1"=${{ github.event.inputs.new_version }}"/' git ls-files | grep Cargo.toml | xargs sed -i 's/\(sixtyfps.*version = \)"=[0-9]*\.[0-9]*\.[0-9]*"/\1"=${{ github.event.inputs.new_version }}"/'
# Update the version in CmakeLists.txt # Update the version in CmakeLists.txt
sed -i 's/ VERSION [0-9]*\.[0-9]*\.[0-9]*$/ VERSION ${{ github.event.inputs.new_version }}/' api/sixtyfps-cpp/CMakeLists.txt sed -i 's/ VERSION [0-9]*\.[0-9]*\.[0-9]*$/ VERSION ${{ github.event.inputs.new_version }}/' api/cpp/CMakeLists.txt
sed -i "s/(CPACK_PACKAGE_VERSION_MAJOR [0-9]*)/(CPACK_PACKAGE_VERSION_MAJOR `echo ${{ github.event.inputs.new_version }} | sed "s/\([0-9]*\)\.\([0-9]*\).\([0-9]*\)/\1/"`)/" api/sixtyfps-cpp/CMakeLists.txt sed -i "s/(CPACK_PACKAGE_VERSION_MAJOR [0-9]*)/(CPACK_PACKAGE_VERSION_MAJOR `echo ${{ github.event.inputs.new_version }} | sed "s/\([0-9]*\)\.\([0-9]*\).\([0-9]*\)/\1/"`)/" api/cpp/CMakeLists.txt
sed -i "s/(CPACK_PACKAGE_VERSION_MINOR [0-9]*)/(CPACK_PACKAGE_VERSION_MINOR `echo ${{ github.event.inputs.new_version }} | sed "s/\([0-9]*\)\.\([0-9]*\).\([0-9]*\)/\2/"`)/" api/sixtyfps-cpp/CMakeLists.txt sed -i "s/(CPACK_PACKAGE_VERSION_MINOR [0-9]*)/(CPACK_PACKAGE_VERSION_MINOR `echo ${{ github.event.inputs.new_version }} | sed "s/\([0-9]*\)\.\([0-9]*\).\([0-9]*\)/\2/"`)/" api/cpp/CMakeLists.txt
sed -i "s/(CPACK_PACKAGE_VERSION_PATCH [0-9]*)/(CPACK_PACKAGE_VERSION_PATCH `echo ${{ github.event.inputs.new_version }} | sed "s/\([0-9]*\)\.\([0-9]*\).\([0-9]*\)/\3/"`)/" api/sixtyfps-cpp/CMakeLists.txt sed -i "s/(CPACK_PACKAGE_VERSION_PATCH [0-9]*)/(CPACK_PACKAGE_VERSION_PATCH `echo ${{ github.event.inputs.new_version }} | sed "s/\([0-9]*\)\.\([0-9]*\).\([0-9]*\)/\3/"`)/" api/cpp/CMakeLists.txt
# The version is also in these files # The version is also in these files
sed -i "s/^version = \"[0-9]*\.[0-9]*\.[0-9]*\"/version = \"${{ github.event.inputs.new_version }}\"/" api/sixtyfps-cpp/docs/conf.py sed -i "s/^version = \"[0-9]*\.[0-9]*\.[0-9]*\"/version = \"${{ github.event.inputs.new_version }}\"/" api/cpp/docs/conf.py
# Version in package.json files # Version in package.json files
git ls-files | grep package.json | xargs sed -i 's/"version": ".*"/"version": "${{ github.event.inputs.new_version }}"/' git ls-files | grep package.json | xargs sed -i 's/"version": ".*"/"version": "${{ github.event.inputs.new_version }}"/'

View file

@ -20,7 +20,6 @@ members = [
'examples/slide_puzzle', 'examples/slide_puzzle',
'examples/todo/rust', 'examples/todo/rust',
'helper_crates/const-field-offset', 'helper_crates/const-field-offset',
'helper_crates/document-features',
'helper_crates/vtable', 'helper_crates/vtable',
'helper_crates/vtable/macro', 'helper_crates/vtable/macro',
'internal/backends/gl', 'internal/backends/gl',

View file

@ -37,7 +37,7 @@ FetchContent_Declare(
SixtyFPS SixtyFPS
GIT_REPOSITORY https://github.com/sixtyfpsui/sixtyfps.git GIT_REPOSITORY https://github.com/sixtyfpsui/sixtyfps.git
GIT_TAG v0.1.6 GIT_TAG v0.1.6
SOURCE_SUBDIR api/cpp SOURCE_SUBDIR api/sixtyfps-cpp
) )
FetchContent_MakeAvailable(SixtyFPS) FetchContent_MakeAvailable(SixtyFPS)
``` ```
@ -113,7 +113,7 @@ FetchContent_Declare(
SixtyFPS SixtyFPS
GIT_REPOSITORY https://github.com/sixtyfpsui/sixtyfps.git GIT_REPOSITORY https://github.com/sixtyfpsui/sixtyfps.git
GIT_TAG v0.1.6 GIT_TAG v0.1.6
SOURCE_SUBDIR api/cpp SOURCE_SUBDIR api/sixtyfps-cpp
) )
FetchContent_MakeAvailable(SixtyFPS) FetchContent_MakeAvailable(SixtyFPS)

View file

@ -10,6 +10,10 @@ In version 0.2.0 we have increased the minimum version of C++. You need to have
If you are building SixtyFPS from source, you need to make sure that your Rust installation is up-to-date. If you have installed Rust using `rustup`, then you can upgrade to the latest Version of Rust by running `rustup update`. If you are building SixtyFPS from source, you need to make sure that your Rust installation is up-to-date. If you have installed Rust using `rustup`, then you can upgrade to the latest Version of Rust by running `rustup update`.
### CMakeLists.txt
- When using `FetchContent`, the `SOURCE_SUBDIR` has changed from `api/sixtyfps-cpp` to `api/cpp`
### Models ### Models
`Model::row_data` returns now a `std::optional<ModelData>` and can thus be used with indices that are out of bounds. `Model::row_data` returns now a `std::optional<ModelData>` and can thus be used with indices that are out of bounds.

View file

@ -53,7 +53,7 @@ slint-macros = { version = "=0.2.0", path = "../macros" }
slint-backend-selector-internal = { version = "=0.2.0", path="../../../internal/backends/selector" } slint-backend-selector-internal = { version = "=0.2.0", path="../../../internal/backends/selector" }
const-field-offset = { version = "0.1.2", path = "../../../helper_crates/const-field-offset" } const-field-offset = { version = "0.1.2", path = "../../../helper_crates/const-field-offset" }
document-features = { version = "0.1.0", path = "../../../helper_crates/document-features" } document-features = "0.1.0"
vtable = { version = "0.1.5", path = "../../../helper_crates/vtable" } vtable = { version = "0.1.5", path = "../../../helper_crates/vtable" }
once_cell = { version = "1.5", default-features = false, features = ["alloc"] } once_cell = { version = "1.5", default-features = false, features = ["alloc"] }
@ -61,3 +61,4 @@ pin-weak = { version = "1.1", default-features = false }
[package.metadata.docs.rs] [package.metadata.docs.rs]
rustdoc-args = [ "--html-in-header", "docs/resources/slint-docs-preview.html", "--html-in-header", "docs/resources/slint-docs-highlight.html" ] rustdoc-args = [ "--html-in-header", "docs/resources/slint-docs-preview.html", "--html-in-header", "docs/resources/slint-docs-highlight.html" ]

View file

@ -1,25 +0,0 @@
# Copyright © SixtyFPS GmbH <info@sixtyfps.io>
# SPDX-License-Identifier: MIT OR Apache-2.0
[package]
name = "document-features"
version = "0.1.0"
authors = ["SixtyFPS <info@sixtyfps.io>"]
edition = "2021"
publish = false
license = "MIT OR Apache-2.0"
repository = "https://github.com/sixtyfpsui/sixtyfps"
homepage = "https://sixtyfps.io"
description = "Extract documentation for the feature flag from comments in Cargo.toml"
categories = ["development-tools"]
keywords = ["documentation", "features", "rustdoc", "macro"]
[lib]
proc-macro = true
path = "lib.rs"
[features]
default = []
## Internal feature used only for the tests, don't enable
self-test = []

View file

@ -1,333 +0,0 @@
// Copyright © SixtyFPS GmbH <info@sixtyfps.io>
// SPDX-License-Identifier: MIT OR Apache-2.0
/*!
Document your crate's feature flags.
This crate provide a macro that extracts "documentation" comments from Cargo.toml
In order to use this crate, simply add `#![doc = document_features::document_features!()]`
within your crate documentation.
The [`document_features!()`] reads the Cargo.toml file and generate a markdown string
suitable to be used within the documentation
Basic example:
```rust
//! Normal crate documentation goes here,
//!
//! ## Feature flags
#![doc = document_features::document_features!()]
// rest of the crate goes here.
```
## Documentation format:
The documentation of the features itself goes in the `Cargo.toml`.
Only the portion in the `[features]` section will be analyzed.
Just like rust has documentation comments like `///` and `//!`, the macro will
understands the comments that start with `## ` and `#! `. Note that the space
is important. Lines starting with `###` will not be understood as doc comment.
`## ` comments are meant to be *over* a feature and document that feature.
there can be several `## ` comments, but they must always be followed by a
feature name, and no other `#! ` comments in between.
`#! ` comments are not associated with a particular feature, and will be printed
in where they occurs. They are useful to do some grouping for example
## Examples:
*/
// Note: because rustdoc escapes the first `#` of a line starting with `#`,
// these docs comments have one more `#` ,
#![doc = self_test!(/**
[package]
name = "..."
## ...
[features]
default = ["foo"]
##! This comments goes on top
### The foo feature is enabling the `foo` functions
foo = []
### The bar feature enable the bar module
bar = []
##! ### Experimental features
##! The following features are experimental
### Enable the fusion reactor
fusion = []
*/
=>
/**
This comments goes on top
* **`foo`** *(enabled by default)* The foo feature is enabling the `foo` functions
* **`bar`** The bar feature enable the bar module
#### Experimental features
The following features are experimental
* **`fusion`** Enable the fusion reactor
*/
)]
extern crate proc_macro;
use proc_macro::TokenStream;
use std::collections::HashSet;
use std::fmt::Write;
use std::path::Path;
use std::str::FromStr;
fn error(e: &str) -> TokenStream {
TokenStream::from_str(&format!("::core::compile_error!{{\"{}\"}}", e.escape_default())).unwrap()
}
#[proc_macro]
pub fn document_features(_: TokenStream) -> TokenStream {
document_features_impl().unwrap_or_else(std::convert::identity)
}
fn document_features_impl() -> Result<TokenStream, TokenStream> {
let path = std::env::var("CARGO_MANIFEST_DIR").unwrap();
let mut cargo_toml = std::fs::read_to_string(Path::new(&path).join("Cargo.toml"))
.map_err(|e| error(&format!("Can't open Cargo.toml: {:?}", e)))?;
if !cargo_toml.contains("\n##") && !cargo_toml.contains("\n#!") {
// On crates.io, Cargo.toml is usually "normalized" and stripped of all comments.
// The original Cargo.toml has been renamed Cargo.toml.orig
if let Ok(orig) = std::fs::read_to_string(Path::new(&path).join("Cargo.toml.orig")) {
if orig.contains("##") || orig.contains("#!") {
cargo_toml = orig;
}
}
}
let result = process_toml(&cargo_toml).map_err(|e| error(&e))?;
Ok(std::iter::once(proc_macro::TokenTree::from(proc_macro::Literal::string(&result))).collect())
}
fn process_toml(cargo_toml: &str) -> Result<String, String> {
// Get all lines between the "[features]" and the next block
let lines = cargo_toml
.lines()
.map(str::trim)
.skip_while(|l| !l.starts_with("[features]"))
.skip(1) // skip the [features] line
.take_while(|l| !l.starts_with("["))
// and skip empty lines and comments that are not docs comments
.filter(|l| {
!l.is_empty() && (!l.starts_with("#") || l.starts_with("##") || l.starts_with("#!"))
});
let mut top_comment = String::new();
let mut current_comment = String::new();
let mut features = vec![];
let mut default_features = HashSet::new();
for line in lines {
if let Some(x) = line.strip_prefix("#!") {
if !x.is_empty() && !x.starts_with(" ") {
continue; // it's not a doc comment
}
if !current_comment.is_empty() {
return Err("Cannot mix ## and #! comments between features.".into());
}
writeln!(top_comment, "{}", x).unwrap();
} else if let Some(x) = line.strip_prefix("##") {
if !x.is_empty() && !x.starts_with(" ") {
continue; // it's not a doc comment
}
writeln!(current_comment, "{}", x).unwrap();
} else if let Some((dep, rest)) = line.split_once("=") {
if dep.trim() == "default" {
let defaults = rest
.trim()
.strip_prefix("[")
.and_then(|r| r.strip_suffix("]"))
.ok_or_else(|| format!("Parse error while parsing dependency {}", dep))?
.split(",")
.map(|d| d.trim().trim_matches(|c| c == '"' || c == '\'').trim())
.filter(|d| !d.is_empty());
default_features.extend(defaults);
} else {
// Do not show features that do not have documentation
if !current_comment.is_empty() {
features.push((
dep.trim(),
std::mem::take(&mut top_comment),
std::mem::take(&mut current_comment),
));
}
}
} else {
return Err(format!("Parse error while processing the line:\n{}", line));
}
}
if !current_comment.is_empty() {
return Err("Found comment not associated with a feature".into());
}
if features.is_empty() {
return Err("Could not find features in Cargo.toml".into());
}
let mut result = String::new();
for (f, top, comment) in features {
let default = if default_features.contains(f) { " *(enabled by default)*" } else { "" };
if !comment.trim().is_empty() {
write!(result, "{}* **`{}`**{} — {}", top, f, default, comment).unwrap();
} else {
writeln!(result, "{}* **`{}`**{}", top, f, default).unwrap();
}
}
result += &top_comment;
Ok(result)
}
#[cfg(feature = "self-test")]
#[proc_macro]
#[doc(hidden)]
/// Helper macro for the tests. Do not use
pub fn self_test_helper(input: TokenStream) -> TokenStream {
process_toml((&input).to_string().trim_matches(|c| c == '"' || c == '#')).map_or_else(
|e| error(&e),
|r| std::iter::once(proc_macro::TokenTree::from(proc_macro::Literal::string(&r))).collect(),
)
}
#[cfg(feature = "self-test")]
macro_rules! self_test {
(#[doc = $toml:literal] => #[doc = $md:literal]) => {
concat!(
"\n`````rust\n\
fn normalize_md(md : &str) -> String {
md.lines().skip_while(|l| l.is_empty()).map(|l| l.trim())
.collect::<Vec<_>>().join(\"\\n\")
}
assert_eq!(normalize_md(document_features::self_test_helper!(",
stringify!($toml),
")), normalize_md(",
stringify!($md),
"));\n`````\n\n"
)
};
}
#[cfg(not(feature = "self-test"))]
macro_rules! self_test {
(#[doc = $toml:literal] => #[doc = $md:literal]) => {
concat!(
"This contents in Cargo.toml:\n`````toml",
$toml,
"\n`````\n Generates the following:\n\
<table><tr><th>Preview</th></tr><tr><td>\n\n",
$md,
"\n</td></tr></table\n",
)
};
}
#[cfg(test)]
mod tests {
use super::process_toml;
#[track_caller]
fn test_error(toml: &str, expected: &str) {
let err = process_toml(toml).unwrap_err();
assert!(err.contains(expected), "{:?} does not contain {:?}", err, expected)
}
#[test]
fn parse_errors() {
test_error(
r#"
[features]
[dependencies]
foo = 4;
"#,
"Could not find features",
);
test_error(
r#"
[packages]
[dependencies]
"#,
"Could not find features",
);
test_error(
r#"
[features]
ff = []
abcd
efgh
[dependencies]
"#,
"Parse error while processing the line:\nabcd",
);
test_error(
r#"
[features]
## dd
## ff
#! ee
## ff
"#,
"Cannot mix",
);
test_error(
r#"
[features]
## dd
"#,
"not associated with a feature",
);
test_error(
r#"
[features]
# ff
foo = []
default = [
#ffff
# ff
"#,
"Parse error while parsing dependency default",
);
}
#[test]
fn basic() {
assert_eq!(
process_toml(
r#"
[abcd]
## aaa
#! aaa
[features]#xyz
#! abc
#
###
#! def
#!
## 123
## 456
feat1 = ["plop"]
#! ghi
no_doc = []
##
feat2 = ["momo"]
#! klm
default = ["feat1", "something_else"]
#! end
"#
)
.unwrap(),
" abc\n def\n\n* **`feat1`** *(enabled by default)* — 123\n 456\n ghi\n* **`feat2`**\n klm\n end\n"
);
}
}

View file

@ -52,7 +52,8 @@ num-traits = { version = "0.2", default-features = false }
once_cell = { version = "1.5", default-features = false } once_cell = { version = "1.5", default-features = false }
pin-project = "1" pin-project = "1"
pin-weak = { version = "1.1", default-features = false } pin-weak = { version = "1.1", default-features = false }
rgb = "0.8.27" # Note: the rgb version is extracted in ci.yaml for rustdoc builds # Note: the rgb version is extracted in ci.yaml for rustdoc builds
rgb = "0.8.27"
scoped-tls-hkt = { version = "0.1", optional = true } scoped-tls-hkt = { version = "0.1", optional = true }
scopeguard = { version = "1.1.0", default-features = false } scopeguard = { version = "1.1.0", default-features = false }
slab = { version = "0.4.3", default-features = false } slab = { version = "0.4.3", default-features = false }

View file

@ -64,7 +64,7 @@ generativity = "1"
lyon_path = { version = "0.17.3" } lyon_path = { version = "0.17.3" }
once_cell = "1.5" once_cell = "1.5"
thiserror = "1" thiserror = "1"
document-features = { version = "0.1.0", path = "../../helper_crates/document-features" } document-features = "0.1.0"
[dependencies.spin_on] [dependencies.spin_on]
version = "0.1" version = "0.1"