{};
3 |
4 | stdenv.mkDerivation {
5 | name = "rust-env";
6 | buildInputs = [
7 | rustc cargo
8 |
9 | # dependencies
10 | graphviz
11 | emscripten
12 | ];
13 |
14 | RUST_BACKTRACE=1;
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/artifact-frontend/src/example.rs:
--------------------------------------------------------------------------------
1 | /* artifact: the requirements tracking tool made for developers
2 | * Copyright (C) 2018 Rett Berg <@vitiral, vitiral@gmail.com>
3 | *
4 | * The source code is Licensed under either of
5 | *
6 | * * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
7 | * http://www.apache.org/licenses/LICENSE-2.0)
8 | * * MIT license ([LICENSE-MIT](LICENSE-MIT) or
9 | * http://opensource.org/licenses/MIT)
10 | *
11 | * at your option.
12 | *
13 | * Unless you explicitly state otherwise, any contribution intentionally submitted
14 | * for inclusion in the work by you, as defined in the Apache-2.0 license, shall
15 | * be dual licensed as above, without any additional terms or conditions.
16 | * */
17 | pub const YAML: &str = r###"
18 | settings:
19 | base: "/fake"
20 | code_paths: []
21 | exclude_code_paths: []
22 |
23 | artifact_paths:
24 | - /fake/design
25 | exclude_artifact_paths: []
26 |
27 | settings_path: "/fake/.art/settings.toml"
28 |
29 | code_impls: {}
30 |
31 | artifacts:
32 | REQ-purpose:
33 | id: "gQ7cdQ7bvyIoaUTEUsxMsg"
34 | name: REQ-purpose
35 | file: /fake/design/purpose.md
36 | partof: []
37 | parts: []
38 | completed: {spc: 0.0, tst: 0.0}
39 | text: This text was updated
40 | impl_:
41 | type: NotImpl
42 | value: null
43 | subnames: []
44 | REQ-single:
45 | id: "gp7cdQ7bvyIoaUTEUsxMsg"
46 | name: REQ-single
47 | file: /fake/design/purpose.md
48 | partof: []
49 | parts: []
50 | completed: {spc: 0.0, tst: 0.0}
51 | text: |- # note `|-` => strip newline at the end
52 | This is a single line of text
53 | impl_:
54 | type: NotImpl
55 | value: null
56 | subnames: []
57 | REQ-completed:
58 | id: "gp9cdQ7bvyIoaUTEUsxMsg"
59 | name: REQ-completed
60 | file: /fake/design/purpose.md
61 | partof: []
62 | parts:
63 | - SPC-completed
64 | - SPC-wut
65 | completed: {spc: 0.25, tst: 1.0}
66 | text: |
67 | Basic demonstration of completeness
68 |
69 | Has some subnames:
70 | - [[.one]]
71 | - [[.two]]
72 | impl_:
73 | type: NotImpl
74 | value: null
75 | subnames:
76 | - .one
77 | - .two
78 | SPC-completed:
79 | id: "gp9ckQ7bvyIoaUTEUsxMsg"
80 | name: SPC-completed
81 | file: /fake/design/purpose.md
82 | partof:
83 | - REQ-completed
84 | parts: []
85 | completed: {spc: 1.0, tst: 1.0}
86 | text: |-
87 | Just marked as done
88 | impl_:
89 | type: Done
90 | value: "this is done"
91 | subnames: []
92 | SPC-wut:
93 | id: "gp9ckQ7bvyzoaUTEUsxMsg"
94 | name: SPC-wut
95 | file: /fake/design/purpose.md
96 | partof:
97 | - REQ-completed
98 | parts: []
99 | completed: {spc: 1.0, tst: 1.0}
100 | text: |-
101 | Just marked as done
102 | impl_:
103 | type: Done
104 | value: "this is done"
105 | subnames: []
106 | "###;
107 |
--------------------------------------------------------------------------------
/artifact-frontend/src/graph.rs:
--------------------------------------------------------------------------------
1 | /* artifact: the requirements tracking tool made for developers
2 | * Copyright (C) 2018 Rett Berg <@vitiral, vitiral@gmail.com>
3 | *
4 | * The source code is Licensed under either of
5 | *
6 | * * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
7 | * http://www.apache.org/licenses/LICENSE-2.0)
8 | * * MIT license ([LICENSE-MIT](LICENSE-MIT) or
9 | * http://opensource.org/licenses/MIT)
10 | *
11 | * at your option.
12 | *
13 | * Unless you explicitly state otherwise, any contribution intentionally submitted
14 | * for inclusion in the work by you, as defined in the Apache-2.0 license, shall
15 | * be dual licensed as above, without any additional terms or conditions.
16 | * */
17 |
18 | use artifact_ser::md_graph;
19 | use stdweb::web::Node;
20 | use yew::virtual_dom::VNode;
21 |
22 | use crate::dev_prelude::*;
23 | use crate::view::ser_markdown;
24 |
25 | /// The small graph at the top of every artifact, displaying it's `partof` and `parts`.
26 | pub(crate) fn artifact_part_html(model: &Model, art: &ArtifactSer) -> HtmlApp {
27 | let md = ser_markdown(model);
28 | let dot = md_graph::artifact_part_dot(&md, art);
29 | dot_html(&dot)
30 | }
31 |
32 | pub(crate) fn graph_html(model: &Model) -> ViewResult {
33 | let page = html![
34 |
35 | { graph_html_results(model) }
36 |
37 | ];
38 |
39 | let nav_extra = Some(html![
40 |
41 | { "Filter:" }
42 |
48 |
49 |
50 | ]);
51 |
52 | ViewResult { page, nav_extra }
53 | }
54 |
55 | /// Get the dot html for untrusted dot.
56 | pub(crate) fn dot_html_string(dot: &str) -> String {
57 | let html = js! {
58 | try {
59 | var svg = Viz(@{dot});
60 | return svg;
61 | } catch ( error ) {
62 | return (
63 | "ERROR: Invalid SVG
\n" + error.message
64 | + "\n" + @{dot} + "\n
\n"
65 | );
66 | }
67 | };
68 | expect!(html.into_string())
69 | }
70 |
71 | /// Convert DOT to HTML
72 | pub(crate) fn dot_html(dot: &str) -> HtmlApp {
73 | let dot_string = dot_html_string(dot);
74 | let dot_string = format!("{}
", dot_string);
75 | let node = expect!(Node::from_html(&dot_string), "invalid html");
76 | let svg = VNode::VRef(node);
77 | html![
78 |
79 | { svg }
80 |
81 | ]
82 | }
83 |
84 | /// The "search graph".
85 | fn graph_html_results(model: &Model) -> HtmlApp {
86 | let md = ser_markdown(model);
87 |
88 | let re = match parse_regex(&model.graph.search) {
89 | Ok(r) => r,
90 | Err(e) => return e,
91 | };
92 | let mut dot = String::new();
93 |
94 | let focus: HashMap<&Name, &ArtifactSer> = model
95 | .shared
96 | .artifacts
97 | .iter()
98 | .filter(|(n, _)| re.is_match(n.as_str()))
99 | .collect();
100 |
101 | for (name, art) in &focus {
102 | dot.push_str(&md_graph::name_dot(&md, name, true));
103 |
104 | // push the parts+partof, but only if they are not also
105 | // in focus (if they are in focus they will be pushed
106 | // separately)
107 | for part in &art.parts {
108 | if !focus.contains_key(part) {
109 | dot.push_str(&md_graph::name_dot(&md, part, false));
110 | }
111 | }
112 |
113 | for part in &art.partof {
114 | if !focus.contains_key(part) {
115 | dot.push_str(&md_graph::name_dot(&md, part, false));
116 | }
117 | }
118 | }
119 |
120 | let mut connections: HashSet<(&Name, &Name)> = HashSet::new();
121 |
122 | for (name, art) in &focus {
123 | for part in &art.parts {
124 | connections.insert((name, part));
125 | }
126 | for part in &art.partof {
127 | connections.insert((part, name));
128 | }
129 | }
130 |
131 | for (from, to) in connections {
132 | dot.push_str(&md_graph::connect_names_dot(from, to));
133 | }
134 |
135 | dot_html(&md_graph::wrap_dot(&dot, false))
136 | }
137 |
--------------------------------------------------------------------------------
/artifact-frontend/src/name.rs:
--------------------------------------------------------------------------------
1 | use crate::dev_prelude::*;
2 |
3 | pub(crate) fn name_html(model: &Model, name: &Name) -> HtmlApp {
4 | let color = match model.shared.artifacts.get(name) {
5 | Some(art) => art.completed.name_color(),
6 | None => GRAY,
7 | };
8 |
9 | html![]
12 | }
13 |
--------------------------------------------------------------------------------
/artifact-frontend/src/view.rs:
--------------------------------------------------------------------------------
1 | /* artifact: the requirements tracking tool made for developers
2 | * Copyright (C) 2018 Rett Berg <@vitiral, vitiral@gmail.com>
3 | *
4 | * The source code is Licensed under either of
5 | *
6 | * * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
7 | * http://www.apache.org/licenses/LICENSE-2.0)
8 | * * MIT license ([LICENSE-MIT](LICENSE-MIT) or
9 | * http://opensource.org/licenses/MIT)
10 | *
11 | * at your option.
12 | *
13 | * Unless you explicitly state otherwise, any contribution intentionally submitted
14 | * for inclusion in the work by you, as defined in the Apache-2.0 license, shall
15 | * be dual licensed as above, without any additional terms or conditions.
16 | * */
17 | use yew_simple;
18 |
19 | use crate::dev_prelude::*;
20 | use crate::graph;
21 | use artifact_ser;
22 |
23 | lazy_static! {
24 | static ref NAME_URL: Regex = expect!(Regex::new(&format!(
25 | r"(?i)(?:artifacts/)?({})",
26 | NAME_VALID_STR
27 | )));
28 | static ref EDIT_URL: Regex = expect!(Regex::new(r"(?i)edit/(\d+)"));
29 | static ref REPLACE_TEXT_RE: Regex = expect!(Regex::new(
30 | r#"(?xim)
31 | (?:^```dot\s*\n(?P[\s\S]+?\n)```$) # graphviz dot rendering
32 | "#,
33 | ));
34 | }
35 |
36 | /// The function used for routing urls.
37 | #[allow(clippy::needless_pass_by_value)]
38 | pub(crate) fn router_fn(info: yew_simple::RouteInfo) -> Msg {
39 | let hash = info.url.fragment().unwrap_or_default();
40 | let view = View::from_hash(hash);
41 | Msg::SetView(view)
42 | }
43 |
44 | impl View {
45 | pub(crate) fn from_hash(hash: &str) -> View {
46 | if hash.to_ascii_lowercase() == "graph" || hash == "" {
47 | View::Graph
48 | } else if let Some(cap) = NAME_URL.captures(hash) {
49 | let name = name!(&cap[1]);
50 | View::Artifact(name)
51 | } else if let Some(cap) = EDIT_URL.captures(hash) {
52 | let id = match usize::from_str(&cap[1]) {
53 | Ok(id) => id,
54 | Err(_) => return View::NotFound,
55 | };
56 | View::Edit(id)
57 | } else {
58 | View::NotFound
59 | }
60 | }
61 | }
62 |
63 | /// Render the markdown correctly.
64 | ///
65 | /// `parent` is the parent's name, which may or may not exist/be-valid.
66 | pub(crate) fn markdown_html(model: &Model, parent: &str, markdown: &str) -> HtmlApp {
67 | let md = ser_markdown(model);
68 | let markdown = md.replace_markdown(parent, markdown);
69 | let markdown = replace_markdown(&markdown).to_string();
70 | let value = js! {
71 | var reader = new commonmark.Parser();
72 | var writer = new commonmark.HtmlRenderer();
73 | var parsed = reader.parse(@{markdown});
74 | return writer.render(parsed);
75 | };
76 |
77 | let mut md_html = expect!(value.into_string(), "markdown not a string");
78 | md_html.insert_str(0, "");
79 | md_html.push_str("
");
80 | let node = expect!(Node::from_html(md_html.trim()), "md-html: {}", md_html);
81 | VNode::VRef(node)
82 | }
83 |
84 | /// Return the default SerMarkdown object for the frontend.
85 | pub(crate) fn ser_markdown(model: &Model) -> artifact_ser::markdown::SerMarkdown<'_> {
86 | use artifact_ser::markdown::*;
87 | let settings = SerMarkdownSettings {
88 | code_url: model.shared.settings.code_url.clone(),
89 | family: SettingsMdFamily::Dot,
90 | dot: SettingsMdDot::Ignore,
91 | name_prefix: "".to_string(),
92 | // md_plain: false,
93 | // md_details: SettingsMdDetails::default(),
94 | };
95 |
96 | SerMarkdown::with_settings(&model.shared, settings)
97 | }
98 |
99 | fn replace_markdown<'t>(markdown: &'t str) -> Cow<'t, str> {
100 | let replacer = |cap: &::ergo_std::regex::Captures<'_>| -> String {
101 | if let Some(dot) = cap.name("dot") {
102 | replace_markdown_dot(dot.as_str())
103 | } else {
104 | panic!("Got unknown match in md: {:?}", cap);
105 | }
106 | };
107 | REPLACE_TEXT_RE.replace_all(markdown, replacer)
108 | }
109 |
110 | fn replace_markdown_dot(dot: &str) -> String {
111 | let html = graph::dot_html_string(dot);
112 | format!("\n\n{0}\n\n", html)
113 | }
114 |
--------------------------------------------------------------------------------
/artifact-frontend/static/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Artifacts
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/artifact-frontend/static/initial.json:
--------------------------------------------------------------------------------
1 | {
2 | "project": null,
3 | "web_type": "Static"
4 | }
5 |
--------------------------------------------------------------------------------
/artifact-lib/.gitignore:
--------------------------------------------------------------------------------
1 | target
2 |
--------------------------------------------------------------------------------
/artifact-lib/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "artifact_lib"
3 | version = "0.1.0"
4 | authors = ["Garrett Berg "]
5 | edition = "2018"
6 |
7 | [dependencies]
8 | base64 = "0.9.2"
9 | path_abs = {git="https://github.com/vitiral/path_abs"}
10 | serde = "1.0.66"
11 | serde_derive = "1.0.66"
12 | failure = "0.1.1"
13 | failure_derive = "0.1.1"
14 | expect_macro = "0.2.1"
15 | ergo_std = {git="https://github.com/rust-crates/ergo", branch="path_abs-4.0"}
16 | ergo_config = {git="https://github.com/rust-crates/ergo", branch="path_abs-4.0"}
17 | siphasher = "0.2.2"
18 | artifact_ser = { path = "../artifact-ser" }
19 |
--------------------------------------------------------------------------------
/artifact-lib/src/dev_prelude.rs:
--------------------------------------------------------------------------------
1 | /* artifact: the requirements tracking tool made for developers
2 | * Copyright (C) 2018 Rett Berg <@vitiral, vitiral@gmail.com>
3 | *
4 | * The source code is Licensed under either of
5 | *
6 | * * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
7 | * http://www.apache.org/licenses/LICENSE-2.0)
8 | * * MIT license ([LICENSE-MIT](LICENSE-MIT) or
9 | * http://opensource.org/licenses/MIT)
10 | *
11 | * at your option.
12 | *
13 | * Unless you explicitly state otherwise, any contribution intentionally submitted
14 | * for inclusion in the work by you, as defined in the Apache-2.0 license, shall
15 | * be dual licensed as above, without any additional terms or conditions.
16 | * */
17 | pub use ergo_config::*;
18 | pub use ergo_std::*;
19 | pub use expect_macro::*;
20 | pub use failure::Error;
21 | pub use failure::*;
22 | pub use path_abs::*;
23 | pub use std::result;
24 |
--------------------------------------------------------------------------------
/artifact-ser/.gitignore:
--------------------------------------------------------------------------------
1 | target
2 |
--------------------------------------------------------------------------------
/artifact-ser/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "artifact_ser"
3 | version = "0.1.0"
4 | authors = ["Garrett Berg "]
5 | edition = "2018"
6 |
7 | [dependencies]
8 | serde = "1.0.66"
9 | serde_derive = "1.0.66"
10 | expect_macro = "0.2.1"
11 | lazy_static = "1.0.1"
12 | indexmap = "1.0.1"
13 | ergo_std = {git="https://github.com/rust-crates/ergo", branch="path_abs-4.0"}
14 | ergo_config = {git="https://github.com/rust-crates/ergo", branch="path_abs-4.0"}
15 | base64 = "0.9.2"
16 | derive-error = "0.0.4"
17 | strfmt = "0.1.6"
18 |
--------------------------------------------------------------------------------
/artifact-ser/src/dev_prelude.rs:
--------------------------------------------------------------------------------
1 | /* artifact: the requirements tracking tool made for developers
2 | * Copyright (C) 2018 Rett Berg <@vitiral, vitiral@gmail.com>
3 | *
4 | * The source code is Licensed under either of
5 | *
6 | * * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
7 | * http://www.apache.org/licenses/LICENSE-2.0)
8 | * * MIT license ([LICENSE-MIT](LICENSE-MIT) or
9 | * http://opensource.org/licenses/MIT)
10 | *
11 | * at your option.
12 | *
13 | * Unless you explicitly state otherwise, any contribution intentionally submitted
14 | * for inclusion in the work by you, as defined in the Apache-2.0 license, shall
15 | * be dual licensed as above, without any additional terms or conditions.
16 | * */
17 |
18 | pub use ergo_config::*;
19 | pub use ergo_std::*;
20 |
--------------------------------------------------------------------------------
/artifact-ser/src/expand_names.rs:
--------------------------------------------------------------------------------
1 | /* artifact: the requirements tracking tool made for developers
2 | * Copyright (C) 2018 Rett Berg <@vitiral, vitiral@gmail.com>
3 | *
4 | * The source code is Licensed under either of
5 | *
6 | * * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
7 | * http://www.apache.org/licenses/LICENSE-2.0)
8 | * * MIT license ([LICENSE-MIT](LICENSE-MIT) or
9 | * http://opensource.org/licenses/MIT)
10 | *
11 | * at your option.
12 | *
13 | * Unless you explicitly state otherwise, any contribution intentionally submitted
14 | * for inclusion in the work by you, as defined in the Apache-2.0 license, shall
15 | * be dual licensed as above, without any additional terms or conditions.
16 | * */
17 | //! Module for defining logic for parsing collapsed artifact names and
18 | //! recollapsing them for tests
19 | //!
20 | //! This feature was added before artifact 1.0 and was purposely preserved.
21 | //! It is *definitely* a "poweruser" feature, but it can come in handy.
22 | //!
23 | //! However, the implementation is not ideal. In particular I would like
24 | //! to use a legitamite parsing library instead of the hand crafted
25 | //! regression parsing seen here. However, I do believe this works.
26 | //!
27 | //! Notes: this is tested in `test_family.rs`
28 |
29 | use crate::dev_prelude::*;
30 | use crate::name::{Name, NameError};
31 |
32 | /// Expand a string of names into multiple names.
33 | ///
34 | /// i.e. `"REQ-[foo, bar]"` -> `["REQ-foo", "REQ-bar"]`
35 | pub fn expand_names(raw: &str) -> Result, NameError> {
36 | parse_collapsed(&mut raw.chars(), false)?
37 | .iter()
38 | .map(|n| Name::from_str(n))
39 | .collect()
40 | }
41 |
42 | // Private: Expanding Names. Use `Name::from_str`
43 |
44 | /// subfunction to parse names from a names-str recusively
45 | fn parse_collapsed(raw: &mut I, in_brackets: bool) -> Result, NameError>
46 | where
47 | I: Iterator- ,
48 | {
49 | // hello-[there, you-[are, great]]
50 | // hello-there, hello-you-are, hello-you-great
51 | let mut strout = String::new();
52 | let mut current = String::new();
53 | loop {
54 | let c = match raw.next() {
55 | Some(c) => c,
56 | None => {
57 | if in_brackets {
58 | return Err(NameError::InvalidCollapsed {
59 | msg: "brackets are not closed".into(),
60 | }
61 | .into());
62 | }
63 | break;
64 | }
65 | };
66 | match c {
67 | ' ' | '\n' | '\r' => {}
68 | // ignore whitespace
69 | '[' => {
70 | if current == "" {
71 | // SPC-names.2: more validation
72 | let msg = "cannot have '[' after characters ',' or ']'\
73 | or at start of string";
74 | return Err(NameError::InvalidCollapsed { msg: msg.into() }.into());
75 | }
76 | for p in r#try!(parse_collapsed(raw, true)) {
77 | strout.push_str(¤t);
78 | strout.push_str(&p);
79 | strout.push(',');
80 | }
81 | current.clear();
82 | }
83 | ']' => {
84 | if !in_brackets {
85 | let err = NameError::InvalidCollapsed {
86 | msg: "`]` character wasn't opened".into(),
87 | };
88 | return Err(err.into());
89 | } else {
90 | break;
91 | }
92 | }
93 | ',' => {
94 | strout.write_str(¤t).unwrap();
95 | strout.push(',');
96 | current.clear();
97 | }
98 | _ => current.push(c),
99 | }
100 | }
101 | strout.write_str(¤t).unwrap();
102 | Ok(strout
103 | .split(',')
104 | .filter(|s| s != &"")
105 | .map(|s| s.to_string())
106 | .collect())
107 | }
108 |
--------------------------------------------------------------------------------
/artifact-test/.gitignore:
--------------------------------------------------------------------------------
1 | /_gh-pages
2 | # Generated by Cargo
3 | # will have compiled files and executables
4 | /target/
5 | /target-install/
6 | .cache
7 | *.log
8 | node_modules
9 | *.ropeproject
10 | result
11 |
--------------------------------------------------------------------------------
/artifact-test/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "artifact_test"
3 | version = "0.1.0"
4 | authors = ["Garrett Berg "]
5 | edition = "2018"
6 |
7 | [dependencies]
8 | artifact_data = { path = "../artifact-data" }
9 | artifact_lib = { path = "../artifact-lib" }
10 | pretty_assertions = "0.5.1"
11 | proptest = "0.7.1"
12 | regex_generate = "0.2.0"
13 | tempdir = "0.3.7"
14 | unicode-segmentation = "1.2.1"
15 |
16 | base64 = "0.9.2"
17 | ergo = {git="https://github.com/rust-crates/ergo", branch="path_abs-4.0"}
18 | expect_macro = "0.2.1"
19 | matches = "0.1.6"
20 | petgraph = "0.4.12"
21 | rayon = "1.0.1"
22 | serde = "1.0.66"
23 | serde_derive = "1.0.66"
24 | siphasher = "0.2.2"
25 | time = "0.1.40"
26 | failure = "0.1.1"
27 | failure_derive = "0.1.1"
28 | log = "0.4.2"
29 |
--------------------------------------------------------------------------------
/artifact-test/README.md:
--------------------------------------------------------------------------------
1 | # Testing framework and Property Based Testing
2 |
3 | This subcrate is to provide a common testing framework/functions
4 | for testing artifact.
5 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/basic/.art/settings.toml:
--------------------------------------------------------------------------------
1 | # artifact project settings
2 |
3 | # Note: {cwd} == current directory of THIS file
4 | # {repo} == directory of the `.art` file
5 |
6 | # directories containing artifact toml files
7 | artifact_paths = ["{repo}/design"]
8 |
9 | # artifact paths to exclude. This is how you can avoid trying
10 | # to load .git/.hg/etc directories (or anything else you don't
11 | # want to include
12 | exclude_artifact_paths = []
13 |
14 | # directories containing code that has artifact links
15 | code_paths = ["/src", "/build.rs"]
16 |
17 | # directories to exclude when searching through code
18 | exclude_code_paths = []
19 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/basic/Cargo.lock:
--------------------------------------------------------------------------------
1 | [[package]]
2 | name = "basic"
3 | version = "0.1.0"
4 |
5 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/basic/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "basic"
3 | version = "0.1.0"
4 | authors = ["Garrett Berg "]
5 |
6 | [dependencies]
7 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/basic/assert-cases/basic/assert_load_lints.yaml:
--------------------------------------------------------------------------------
1 | # no lints
2 | error: []
3 | other: []
4 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/basic/assert-cases/basic/assert_project_lints.yaml:
--------------------------------------------------------------------------------
1 | error: []
2 | other: []
3 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/basic/build.rs:
--------------------------------------------------------------------------------
1 | //! #SPC-build
2 | //!
3 | //! Build file, included by direct path
4 |
5 | // And some test: #TST-build (but not subpart)
6 | // Also a unit test: #SPC-build.tst-unit
7 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/basic/design/foo.md:
--------------------------------------------------------------------------------
1 | # SPC-foo
2 | This is the spec for foo, it does lots of foo.
3 |
4 | It is some foo subparts:
5 | - [[.no]]: not done
6 | - [[.yes]]: done
7 |
8 |
9 | # SPC-foo_done
10 | partof:
11 | - SPC-foo
12 | - REQ-foo
13 |
14 | done: this is done
15 | ###
16 | This is done and is weird?
17 |
18 |
19 | # TST-foo
20 | Partially done foo test with some subparts
21 |
22 | - [[.no1]]
23 | - [[.no2]]
24 | - [[.yes1]]
25 | - [[.yes2]]
26 | - [[.yes3]]
27 | - [[.yes4]]
28 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/basic/design/purpose.md:
--------------------------------------------------------------------------------
1 | # REQ-purpose
2 | The purpose of this project is is to test a basic
3 | project... that's it!
4 |
5 | # REQ-lib
6 | partof: REQ-purpose
7 | ###
8 | Lib is definitely a library
9 |
10 |
11 | # REQ-foo
12 | partof: REQ-purpose
13 | ###
14 | foo needs to do the foo thing
15 |
16 | # REQ-baz
17 | implemented directly in source!
18 |
19 | Not a partof anything...
20 |
21 | # SPC-build
22 | partof: REQ-purpose
23 | ###
24 | This has a build file.
25 |
26 | Unit tests:
27 | - [[.tst-unit]]
28 |
29 | # TST-build
30 | partof: REQ-purpose
31 | ###
32 | direct link to REQ-purpose
33 |
34 | - [[.no]]
35 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/basic/src/baz.rs:
--------------------------------------------------------------------------------
1 | /// #REQ-baz
2 | /// Just implement baz directly
3 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/basic/src/foo/fab.rs:
--------------------------------------------------------------------------------
1 | //! This has foo stuff
2 |
3 |
4 | /// #SPC-foo.yes
5 | /// Do foo?
6 | fn foo() {
7 | }
8 |
9 | #[test]
10 | /// #TST-foo.yes4
11 | fn test_samefile() {
12 | println!("TST-foo"); // nothing happens without `#`
13 | }
14 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/basic/src/foo/mod.rs:
--------------------------------------------------------------------------------
1 | /// #SPC-foo
2 | ///
3 | /// This is where foo is implemented
4 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/basic/src/foo/test.rs:
--------------------------------------------------------------------------------
1 | /// Test foo and stuff. Don't link TST-foo directly
2 |
3 |
4 | #[test]
5 | /// #TST-foo.yes1
6 | fn foo_1() {
7 | // #TST-foo.yes2
8 | // #TST-foo.yes3
9 | }
10 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/basic/src/lib.rs:
--------------------------------------------------------------------------------
1 | #[cfg(test)]
2 | mod tests {
3 | #[test]
4 | fn it_works() {
5 | assert_eq!(2 + 2, 4);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/design_only/.art/settings.toml:
--------------------------------------------------------------------------------
1 | # artifact project settings
2 |
3 | # Note: {cwd} == current directory of THIS file
4 | # {repo} == directory of the `.art` file
5 |
6 | # directories containing artifact toml files
7 | artifact_paths = ["{repo}/design"]
8 |
9 | # artifact paths to exclude. This is how you can avoid trying
10 | # to load .git/.hg/etc directories (or anything else you don't
11 | # want to include
12 | exclude_artifact_paths = []
13 |
14 | # directories containing code that has artifact links
15 | code_paths = []
16 |
17 | # directories to exclude when searching through code
18 | exclude_code_paths = []
19 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/design_only/assert-cases/basic/assert_load_lints.yaml:
--------------------------------------------------------------------------------
1 | # no lints
2 | error: []
3 | other: []
4 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/design_only/assert-cases/basic/assert_project.yaml:
--------------------------------------------------------------------------------
1 | # Empty project
2 | #
3 | # This file is also used as a template
4 | settings:
5 | code_paths: []
6 | exclude_code_paths: []
7 |
8 | artifact_paths:
9 | - design
10 | exclude_artifact_paths: []
11 |
12 | code_impls: {}
13 |
14 | artifacts:
15 | REQ-purpose:
16 | name: REQ-purpose
17 | file: design/purpose.md
18 | partof: []
19 | parts: []
20 | completed: {spc: 0.0, tst: 0.0}
21 | text: | # note `|` => multiline string
22 | The purpose of this project is to test loading artifact designs.
23 |
24 | This is on a new line.
25 | impl_: null
26 | subnames: []
27 | REQ-single:
28 | name: REQ-single
29 | file: design/purpose.md
30 | partof: []
31 | parts: []
32 | completed: {spc: 0.0, tst: 0.0}
33 | text: |- # note `|-` => strip newline at the end
34 | This is a single line of text
35 | impl_: null
36 | subnames: []
37 | REQ-completed:
38 | name: REQ-completed
39 | file: design/purpose.md
40 | partof: []
41 | parts:
42 | - SPC-completed
43 | completed: {spc: 0.25, tst: 1.0}
44 | text: |
45 | Basic demonstration of completeness
46 |
47 | Has some subnames:
48 | - [[.one]]
49 | - [[.two]]
50 | impl_: null
51 | subnames:
52 | - .one
53 | - .two
54 | SPC-completed:
55 | name: SPC-completed
56 | file: design/purpose.md
57 | partof:
58 | - REQ-completed
59 | parts: []
60 | completed: {spc: 1.0, tst: 1.0}
61 | text: |-
62 | Just marked as done
63 | impl_: "this is done"
64 | subnames: []
65 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/design_only/assert-cases/delete/assert_load_lints.yaml:
--------------------------------------------------------------------------------
1 | # no lints
2 | error: []
3 | other: []
4 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/design_only/assert-cases/delete/assert_project.yaml:
--------------------------------------------------------------------------------
1 | # Empty project
2 | #
3 | # This file is also used as a template
4 | settings:
5 | code_paths: []
6 | exclude_code_paths: []
7 |
8 | artifact_paths:
9 | - design
10 | exclude_artifact_paths: []
11 |
12 | code_impls: {}
13 |
14 | artifacts:
15 | REQ-single:
16 | name: REQ-single
17 | file: design/purpose.md
18 | partof: []
19 | parts: []
20 | completed: {spc: 0.0, tst: 0.0}
21 | text: |- # note `|-` => strip newline at the end
22 | This is a single line of text
23 | impl_: null
24 | subnames: []
25 | REQ-completed:
26 | name: REQ-completed
27 | file: design/purpose.md
28 | partof: []
29 | parts:
30 | - SPC-completed
31 | completed: {spc: 0.25, tst: 1.0}
32 | text: |
33 | Basic demonstration of completeness
34 |
35 | Has some subnames:
36 | - [[.one]]
37 | - [[.two]]
38 | impl_: null
39 | subnames:
40 | - .one
41 | - .two
42 | SPC-completed:
43 | name: SPC-completed
44 | file: design/purpose.md
45 | partof:
46 | - REQ-completed
47 | parts: []
48 | completed: {spc: 1.0, tst: 1.0}
49 | text: |-
50 | Just marked as done
51 | impl_: "this is done"
52 | subnames: []
53 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/design_only/assert-cases/delete/modify.yaml:
--------------------------------------------------------------------------------
1 | -
2 | op: delete
3 | name: REQ-purpose
4 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/design_only/assert-cases/multi/assert_load_lints.yaml:
--------------------------------------------------------------------------------
1 | # no lints
2 | error: []
3 | other: []
4 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/design_only/assert-cases/multi/assert_project.yaml:
--------------------------------------------------------------------------------
1 | # Empty project
2 | #
3 | # This file is also used as a template
4 | settings:
5 | code_paths: []
6 | exclude_code_paths: []
7 |
8 | artifact_paths:
9 | - design
10 | exclude_artifact_paths: []
11 |
12 | code_impls: {}
13 |
14 | artifacts:
15 | REQ-purpose:
16 | name: REQ-purpose
17 | file: design/purpose.md
18 | partof: []
19 | parts: [REQ-new]
20 | completed: {spc: 0.0, tst: 0.0}
21 | text: |
22 | The purpose of this project is to test loading artifact designs.
23 |
24 | This is on a new line.
25 | impl_: null
26 | subnames: []
27 | REQ-new:
28 | name: REQ-new
29 | file: design/new.md
30 | partof:
31 | - REQ-purpose
32 | parts: []
33 | completed: {spc: 0.0, tst: 0.0}
34 | text: |-
35 | This was created out of whole cloth
36 | impl_: null
37 | subnames: []
38 | REQ-completed:
39 | name: REQ-completed
40 | file: design/purpose.md
41 | partof: []
42 | parts:
43 | - SPC-completed-changed
44 | completed: {spc: 0.25, tst: 1.0}
45 | text: |
46 | Basic demonstration of completeness
47 |
48 | Has some subnames:
49 | - [[.one]]
50 | - [[.two]]
51 | impl_: null
52 | subnames:
53 | - .one
54 | - .two
55 | SPC-completed-changed:
56 | name: SPC-completed-changed
57 | file: design/purpose.md
58 | partof:
59 | - REQ-completed
60 | parts: []
61 | completed: {spc: 1.0, tst: 1.0}
62 | text: |-
63 | Still just marked as done.
64 | impl_: "still done"
65 | subnames: []
66 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/design_only/assert-cases/multi/modify.yaml:
--------------------------------------------------------------------------------
1 | -
2 | op: update
3 | name: SPC-completed
4 | artifact:
5 | name: SPC-completed-changed
6 | file: design/purpose.md
7 | partof:
8 | - REQ-completed
9 | done: "still done"
10 | text: |-
11 | Still just marked as done.
12 | -
13 | op: delete
14 | name: REQ-single
15 | -
16 | op: create
17 | artifact:
18 | name: REQ-new
19 | file: design/new.md
20 | partof:
21 | - REQ-purpose
22 | done: null
23 | text: |-
24 | This was created out of whole cloth
25 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/design_only/assert-cases/overlap/assert_modify_fail.yaml:
--------------------------------------------------------------------------------
1 | error:
2 | -
3 | level: Error
4 | path: null
5 | line: null
6 | category: IdOverlap
7 | msg: "Attempting to operate twice on REQ-purpose"
8 | other: []
9 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/design_only/assert-cases/overlap/modify.yaml:
--------------------------------------------------------------------------------
1 | -
2 | op: update
3 | name: REQ-purpose
4 | artifact:
5 | name: REQ-purpose
6 | file: design/purpose.md
7 | partof: []
8 | done: null
9 | text: This text was updated
10 | -
11 | op: update
12 | name: REQ-purpose
13 | artifact:
14 | name: REQ-purpose
15 | file: design/purpose.md
16 | partof: []
17 | done: null
18 | text: This text was updated
19 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/design_only/assert-cases/update-dne/assert_modify_fail.yaml:
--------------------------------------------------------------------------------
1 | error:
2 | -
3 | level: Error
4 | path: null
5 | line: null
6 | category: UpdateDne
7 | msg: "Attempt to update 'TST-dne' failed, hash-id does not exist"
8 | other: []
9 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/design_only/assert-cases/update-dne/modify.yaml:
--------------------------------------------------------------------------------
1 | -
2 | op: update
3 | name: TST-dne
4 | artifact:
5 | name: TST-dne
6 | file: design/purpose.md
7 | partof: []
8 | done: null
9 | text: This test does not exist
10 |
11 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/design_only/assert-cases/update-invalid-id/assert_modify_fail.yaml:
--------------------------------------------------------------------------------
1 | error:
2 | -
3 | level: Error
4 | path: null
5 | line: null
6 | category: UpdateDne
7 | msg: "Attempt to update 'REQ-purpose' failed, hash-id does not exist"
8 | other: []
9 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/design_only/assert-cases/update-invalid-id/modify.yaml:
--------------------------------------------------------------------------------
1 | -
2 | op: update
3 | name: REQ-purpose
4 | artifact:
5 | name: REQ-purpose
6 | file: design/purpose.md
7 | partof: []
8 | done: null
9 | text: "changing stuff, wrong id"
10 | id: "gQ7cdQ7IvyIoaUTEUsxMsg"
11 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/design_only/assert-cases/update/assert_load_lints.yaml:
--------------------------------------------------------------------------------
1 | # no lints
2 | error: []
3 | other: []
4 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/design_only/assert-cases/update/assert_project.yaml:
--------------------------------------------------------------------------------
1 | # Empty project
2 | #
3 | # This file is also used as a template
4 | settings:
5 | code_paths: []
6 | exclude_code_paths: []
7 |
8 | artifact_paths:
9 | - design
10 | exclude_artifact_paths: []
11 |
12 | code_impls: {}
13 |
14 | artifacts:
15 | REQ-purpose:
16 | name: REQ-purpose
17 | file: design/purpose.md
18 | partof: []
19 | parts: []
20 | completed: {spc: 0.0, tst: 0.0}
21 | text: This text was updated
22 | impl_: null
23 | subnames: []
24 | REQ-single:
25 | name: REQ-single
26 | file: design/purpose.md
27 | partof: []
28 | parts: []
29 | completed: {spc: 0.0, tst: 0.0}
30 | text: |- # note `|-` => strip newline at the end
31 | This is a single line of text
32 | impl_: null
33 | subnames: []
34 | REQ-completed:
35 | name: REQ-completed
36 | file: design/purpose.md
37 | partof: []
38 | parts:
39 | - SPC-completed
40 | completed: {spc: 0.25, tst: 1.0}
41 | text: |
42 | Basic demonstration of completeness
43 |
44 | Has some subnames:
45 | - [[.one]]
46 | - [[.two]]
47 | impl_: null
48 | subnames:
49 | - .one
50 | - .two
51 | SPC-completed:
52 | name: SPC-completed
53 | file: design/purpose.md
54 | partof:
55 | - REQ-completed
56 | parts: []
57 | completed: {spc: 1.0, tst: 1.0}
58 | text: |-
59 | Just marked as done
60 | impl_: "this is done"
61 | subnames: []
62 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/design_only/assert-cases/update/modify.yaml:
--------------------------------------------------------------------------------
1 | -
2 | op: update
3 | name: REQ-purpose
4 | artifact:
5 | name: REQ-purpose
6 | file: design/purpose.md
7 | partof: []
8 | done: null
9 | text: This text was updated
10 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/design_only/design/purpose.md:
--------------------------------------------------------------------------------
1 | # REQ-purpose
2 | The purpose of this project is to test loading artifact designs.
3 |
4 | This is on a new line.
5 |
6 | # REQ-single
7 | This is a single line of text
8 |
9 | # REQ-completed
10 | Basic demonstration of completeness
11 |
12 | Has some subnames:
13 | - [[.one]]
14 | - [[.two]]
15 |
16 | # SPC-completed
17 | done: this is done
18 | ###
19 | Just marked as done
20 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/empty/.art/settings.toml:
--------------------------------------------------------------------------------
1 | # artifact project settings
2 |
3 | # Note: {cwd} == current directory of THIS file
4 | # {repo} == directory of the `.art` file
5 |
6 | # directories containing artifact toml files
7 | artifact_paths = ["{repo}/design"]
8 |
9 | # artifact paths to exclude. This is how you can avoid trying
10 | # to load .git/.hg/etc directories (or anything else you don't
11 | # want to include
12 | exclude_artifact_paths = []
13 |
14 | # directories containing code that has artifact links
15 | code_paths = []
16 |
17 | # directories to exclude when searching through code
18 | exclude_code_paths = []
19 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/empty/assert-cases/basic/assert_load_lints.yaml:
--------------------------------------------------------------------------------
1 | # no lints
2 | error: []
3 | other: []
4 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/empty/assert-cases/basic/assert_project.yaml:
--------------------------------------------------------------------------------
1 | # Empty project
2 | #
3 | # This file is also used as a template
4 | settings:
5 | code_paths: []
6 | exclude_code_paths: []
7 |
8 | artifact_paths: [
9 | "design",
10 | ]
11 | exclude_artifact_paths: []
12 |
13 | code_impls: {}
14 | # TST-pyinit:
15 | # primary:
16 | # file: pylib/__init__.py
17 | # line: 0
18 | # secondary: {}
19 |
20 | artifacts: {}
21 | # REQ-purpose:
22 | # name: REQ-foo
23 | # file: design/purpose.md
24 | # partof: []
25 | # parts: []
26 | # completed: {spc: 0.0, tst: 0.0}
27 | # text: | # note `|` => multiline string. Use `|-` to strip newlines
28 | # The purpose of this project is to test loading artifact designs.
29 | #
30 | # This is on a new line.
31 | # impl_: null
32 | # subnames: []
33 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/empty/assert-cases/basic/assert_project_lints.yaml:
--------------------------------------------------------------------------------
1 | error: []
2 | other: []
3 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/empty/assert-cases/create-one/assert_load_lints.yaml:
--------------------------------------------------------------------------------
1 | # no lints
2 | error: []
3 | other: []
4 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/empty/assert-cases/create-one/assert_project.yaml:
--------------------------------------------------------------------------------
1 | # Empty project
2 | #
3 | # This file is also used as a template
4 | settings:
5 | code_paths: []
6 | exclude_code_paths: []
7 |
8 | artifact_paths: [
9 | "design",
10 | ]
11 | exclude_artifact_paths: []
12 |
13 | code_impls: {}
14 | # TST-pyinit:
15 | # primary:
16 | # file: pylib/__init__.py
17 | # line: 0
18 | # secondary: {}
19 |
20 | artifacts:
21 | REQ-foo:
22 | name: REQ-foo
23 | file: design/purpose.md
24 | partof: []
25 | parts: []
26 | completed: {spc: 0.0, tst: 0.0}
27 | text: "This is foo"
28 | impl_: null
29 | subnames: []
30 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/empty/assert-cases/create-one/assert_project_lints.yaml:
--------------------------------------------------------------------------------
1 | error: []
2 | other: []
3 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/empty/assert-cases/create-one/modify.yaml:
--------------------------------------------------------------------------------
1 | -
2 | op: create
3 | artifact:
4 | name: "REQ-foo"
5 | file: "design/purpose.md"
6 | partof: []
7 | done: null
8 | text: "This is foo"
9 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/empty/design/.empty:
--------------------------------------------------------------------------------
1 | this file exists just so git will keep the folder around
2 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/lints/.art/settings.toml:
--------------------------------------------------------------------------------
1 | # artifact project settings
2 |
3 | # Note: {cwd} == current directory of THIS file
4 | # {repo} == directory of the `.art` file
5 |
6 | # directories containing artifact toml files
7 | artifact_paths = ["{repo}/design"]
8 |
9 | # artifact paths to exclude. This is how you can avoid trying
10 | # to load .git/.hg/etc directories (or anything else you don't
11 | # want to include
12 | exclude_artifact_paths = []
13 |
14 | # directories containing code that has artifact links
15 | code_paths = ["/src"]
16 |
17 | # directories to exclude when searching through code
18 | exclude_code_paths = []
19 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/lints/assert-cases/basic/assert_project_lints.yaml:
--------------------------------------------------------------------------------
1 | error:
2 | -
3 | level: Error
4 | path: design/purpose.md
5 | line: null
6 | category: Artifact
7 | msg: "REQ-exists defines partof=REQ-dne which does not exist"
8 | -
9 | level: Error
10 | path: design/purpose.md
11 | line: null
12 | category: Artifact
13 | msg: "REQ-exists cannot have `partof` SPC-exists: invalid types."
14 | -
15 | level: Error
16 | path: design/purpose.md
17 | line: null
18 | category: Artifact
19 | msg: "REQ-exists cannot have `partof` TST-exists: invalid types."
20 | -
21 | level: Error
22 | path: design/purpose.md
23 | line: null
24 | category: Artifact
25 | msg: "SPC-exists cannot have `partof` TST-exists: invalid types."
26 | -
27 | level: Error
28 | path: design/purpose.md
29 | line: null
30 | category: Artifact
31 | msg: "TST-exists: subnames are defined when the `done` field is set."
32 | -
33 | level: Error
34 | path: design/text.toml
35 | line: null
36 | category: Artifact
37 | msg: "REQ-text text is invalid: Cannot have a line of the form \"# ART-name\" as that
38 | specifies a new artifact in the markdown format."
39 | -
40 | level: Error
41 | path: design/text.toml
42 | line: null
43 | category: Artifact
44 | msg: "REQ-text text is invalid: Cannot have a line of the form \"###+\" as that
45 | specifies the end of the metadata in the markdown format."
46 | other:
47 | -
48 | level: Warn
49 | path: design/purpose.md
50 | line: null
51 | category: Artifact
52 | msg: "TST-exists has soft reference [[REQ-dne]] which does not exist."
53 | -
54 | level: Warn
55 | path: design/purpose.md
56 | line: null
57 | category: Artifact
58 | msg: "TST-exists has soft reference [[REQ-dne.sub]] which does not exist."
59 | -
60 | level: Warn
61 | path: design/purpose.md
62 | line: null
63 | category: Artifact
64 | msg: "TST-exists has soft reference [[REQ-exists.dne]] which does not exist."
65 | -
66 | level: Warn
67 | path: src/lib.rs
68 | line: 4
69 | category: ImplCode
70 | msg: "Invalid code impl #SPC-exists.dne. Subname [[.dne]] does not exist in artifact's text"
71 | -
72 | level: Warn
73 | path: src/lib.rs
74 | line: 6
75 | category: ImplCode
76 | msg: "Invalid code impl #SPC-dne. Artifact SPC-dne does not exist"
77 | -
78 | level: Warn
79 | path: src/lib.rs
80 | line: 7
81 | category: ImplCode
82 | msg: "Invalid code impl #SPC-dne.sub. Artifact SPC-dne does not exist"
83 | -
84 | level: Warn
85 | path: src/lib.rs
86 | line: 9
87 | category: ImplCode
88 | msg: "Invalid code impl #TST-exists. Artifact's done field is set"
89 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/lints/design/purpose.md:
--------------------------------------------------------------------------------
1 | # REQ-exists
2 | partof:
3 | - REQ-dne # dne
4 | - SPC-exists # invalid type
5 | - TST-exists # invalid type
6 | ###
7 |
8 | # SPC-exists
9 | partof:
10 | - TST-exists # invalid type
11 | ###
12 | - [[.sub]]: has a sub, horray
13 |
14 | # TST-exists
15 | done: "this is done baby"
16 | ###
17 | but... also has subparts
18 | [[.foo]]
19 |
20 | ## Invalid references
21 | [[REQ-dne]] [[REQ-dne.sub]]
22 |
23 | [[REQ-exists.dne]]
24 |
25 | ## Valid references
26 | [[REQ-exists]]
27 |
28 | [[SPC-exists]] [[SPC-exists.sub]]
29 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/lints/design/text.toml:
--------------------------------------------------------------------------------
1 | [REQ-text]
2 | text = """
3 | This has some invalid text
4 |
5 | # REQ-foo
6 | ^^^ doesn't work in markdown
7 |
8 | ###
9 | ^^^ also doesn't work in markdown.
10 | """
11 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/lints/src/lib.rs:
--------------------------------------------------------------------------------
1 | // a library to link to things
2 | //
3 | // #SPC-exists -- yay we got one right!
4 | // #SPC-exists.sub -- another one, on a role baby
5 | // #SPC-exists.dne -- oops, oh well!
6 | //
7 | // #SPC-dne -- boo
8 | // #SPC-dne.sub -- double boo
9 | //
10 | // #TST-exists -- has `done` set
11 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/lints2/.art/settings.toml:
--------------------------------------------------------------------------------
1 | # artifact project settings
2 |
3 | # Note: {cwd} == current directory of THIS file
4 | # {repo} == directory of the `.art` file
5 |
6 | # directories containing artifact toml files
7 | artifact_paths = ["{repo}/design"]
8 |
9 | # artifact paths to exclude. This is how you can avoid trying
10 | # to load .git/.hg/etc directories (or anything else you don't
11 | # want to include
12 | exclude_artifact_paths = []
13 |
14 | # directories containing code that has artifact links
15 | code_paths = ["/src"]
16 |
17 | # directories to exclude when searching through code
18 | exclude_code_paths = []
19 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/lints2/Cargo.lock:
--------------------------------------------------------------------------------
1 | [[package]]
2 | name = "basic"
3 | version = "0.1.0"
4 |
5 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/lints2/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "basic"
3 | version = "0.1.0"
4 | authors = ["Garrett Berg "]
5 |
6 | [dependencies]
7 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/lints2/README.md:
--------------------------------------------------------------------------------
1 | The reason for this test's existance is primarily because the lints in the first lint test
2 | were causing some code to not even be executed.
3 |
4 | TODO: why was the graphing code not executed with the lints in the interop lints.
5 |
6 | Also, this should a strong need to finish fuzz testing for whole projects.
7 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/lints2/assert-cases/basic/assert_load_lints.yaml:
--------------------------------------------------------------------------------
1 | error:
2 | -
3 | level: Error
4 | path: design/purpose.md
5 | line: null
6 | category: Artifact
7 | msg: "SPC-partof_dne defines partof=SPC-dne which does not exist"
8 | other: []
9 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/lints2/assert-cases/basic/assert_project.yaml:
--------------------------------------------------------------------------------
1 | # Basic project
2 | #
3 | # This contains a "sunny day" project with no errors for basic testing of
4 | # - loading artifact
5 | # - linking artifacts to source code
6 | settings:
7 | code_paths:
8 | - src
9 |
10 | exclude_code_paths: []
11 |
12 | artifact_paths:
13 | - design
14 |
15 | exclude_artifact_paths: []
16 |
17 | code_impls: {}
18 | artifacts:
19 | SPC-partof_dne:
20 | name: SPC-partof_dne
21 | file: design/purpose.md
22 | partof:
23 | - SPC-dne
24 | parts: []
25 | completed:
26 | spc: 0
27 | tst: 0
28 | text: |
29 |
30 | This specification's partof does not exist.
31 |
32 | impl_: null
33 | subnames: []
34 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/lints2/assert-cases/basic/assert_project_lints.yaml:
--------------------------------------------------------------------------------
1 | error:
2 | -
3 | level: Error
4 | path: design/purpose.md
5 | line: null
6 | category: Artifact
7 | msg: "SPC-partof_dne defines partof=SPC-dne which does not exist"
8 | other: []
9 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/lints2/design/purpose.md:
--------------------------------------------------------------------------------
1 | # SPC-partof_dne
2 | partof: SPC-dne
3 | ###
4 |
5 | This specification's partof does not exist.
6 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/lints2/src/lib.rs:
--------------------------------------------------------------------------------
1 | #[cfg(test)]
2 | mod tests {
3 | #[test]
4 | fn it_works() {
5 | assert_eq!(2 + 2, 4);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/lints2/target/.rustc_info.json:
--------------------------------------------------------------------------------
1 | {"rustc_fingerprint":15893297361853315868,"outputs":{"15337506775154344876":["___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/home/garrett/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu\ndebug_assertions\nproc_macro\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"mmx\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_thread_local\ntarget_vendor=\"unknown\"\nunix\n",""],"1164083562126845933":["rustc 1.28.0-nightly (967c1f3be 2018-06-15)\nbinary: rustc\ncommit-hash: 967c1f3be1c9ce0469ae9e30659bdf4da5346a9f\ncommit-date: 2018-06-15\nhost: x86_64-unknown-linux-gnu\nrelease: 1.28.0-nightly\nLLVM version: 6.0\n",""],"1617349019360157463":["___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/home/garrett/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu\ndebug_assertions\nproc_macro\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"mmx\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_thread_local\ntarget_vendor=\"unknown\"\nunix\n",""]}}
--------------------------------------------------------------------------------
/artifact-test/interop_tests/lints2/target/debug/.cargo-lock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/artifact-test/interop_tests/lints2/target/debug/.cargo-lock
--------------------------------------------------------------------------------
/artifact-test/interop_tests/lints2/target/debug/build/basic-2ccdec1e4884b553/build_script_build-2ccdec1e4884b553.d:
--------------------------------------------------------------------------------
1 | /home/garrett/code/artifact/artifact-test/interop_tests/warning/target/debug/build/basic-2ccdec1e4884b553/build_script_build-2ccdec1e4884b553: build.rs
2 |
3 | /home/garrett/code/artifact/artifact-test/interop_tests/warning/target/debug/build/basic-2ccdec1e4884b553/build_script_build-2ccdec1e4884b553.d: build.rs
4 |
5 | build.rs:
6 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/lints2/target/debug/incremental/build_script_build-2mpg4k3gfwhp5/s-f2qdvys262-ewn7ea.lock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/artifact-test/interop_tests/lints2/target/debug/incremental/build_script_build-2mpg4k3gfwhp5/s-f2qdvys262-ewn7ea.lock
--------------------------------------------------------------------------------
/artifact-test/interop_tests/settings/.art/settings.toml:
--------------------------------------------------------------------------------
1 | # artifact project settings
2 |
3 | # directories containing artifact toml files
4 | artifact_paths = ["{repo}/design"]
5 |
6 | # artifact paths to exclude. This is how you can avoid trying
7 | # to load .git/.hg/etc directories (or anything else you don't
8 | # want to include
9 | exclude_artifact_paths = []
10 |
11 | # directories containing code that has artifact links
12 | code_paths = ["/src", "/build.rs"]
13 |
14 | # directories to exclude when searching through code
15 | exclude_code_paths = []
16 |
17 | [parse]
18 | md_name = { type = "prefix", value = "#" }
19 |
20 | [format]
21 | md_attrs = {type = "code", prefix = "yaml"}
22 |
23 | [export]
24 | md_name = { type = "prefix", value = "#" }
25 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/settings/Cargo.lock:
--------------------------------------------------------------------------------
1 | [[package]]
2 | name = "basic"
3 | version = "0.1.0"
4 |
5 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/settings/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "basic"
3 | version = "0.1.0"
4 | authors = ["Garrett Berg "]
5 |
6 | [dependencies]
7 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/settings/assert-cases/basic/assert_load_lints.yaml:
--------------------------------------------------------------------------------
1 | # no lints
2 | error: []
3 | other: []
4 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/settings/assert-cases/basic/assert_project_lints.yaml:
--------------------------------------------------------------------------------
1 | error: []
2 | other: []
3 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/settings/build.rs:
--------------------------------------------------------------------------------
1 | //! #SPC-build
2 | //!
3 | //! Build file, included by direct path
4 |
5 | // And some test: #TST-build (but not subpart)
6 | // Also a unit test: #SPC-build.tst-unit
7 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/settings/design/foo.md:
--------------------------------------------------------------------------------
1 | ## SPC-foo
2 | This is the spec for foo, it does lots of foo.
3 |
4 | It is some foo subparts:
5 | - [[.no]]: not done
6 | - [[.yes]]: done
7 |
8 |
9 | ## SPC-foo_done
10 | ```yaml art
11 | done: this is done
12 |
13 | partof:
14 | - REQ-foo
15 | - SPC-foo
16 | ```
17 | This is done and is weird?
18 |
19 |
20 | ## TST-foo
21 | Partially done foo test with some subparts
22 |
23 | - [[.no1]]
24 | - [[.no2]]
25 | - [[.yes1]]
26 | - [[.yes2]]
27 | - [[.yes3]]
28 | - [[.yes4]]
--------------------------------------------------------------------------------
/artifact-test/interop_tests/settings/design/purpose.md:
--------------------------------------------------------------------------------
1 | ## REQ-baz
2 | implemented directly in source!
3 |
4 | Not a partof anything...
5 |
6 |
7 | ## REQ-foo
8 | ```yaml art
9 | partof: REQ-purpose
10 | ```
11 | foo needs to do the foo thing
12 |
13 |
14 | ## REQ-lib
15 | ```yaml art
16 | partof: REQ-purpose
17 | ```
18 | Lib is definitely a library
19 |
20 |
21 | ## REQ-purpose
22 | The purpose of this project is is to test a basic
23 | project... that's it!
24 |
25 |
26 | ## SPC-build
27 | ```yaml art
28 | partof: REQ-purpose
29 | ```
30 | This has a build file.
31 |
32 | Unit tests:
33 | - [[.tst-unit]]
34 |
35 |
36 | ## TST-build
37 | ```yaml art
38 | partof: REQ-purpose
39 | ```
40 | direct link to REQ-purpose
41 |
42 | - [[.no]]
--------------------------------------------------------------------------------
/artifact-test/interop_tests/settings/src/baz.rs:
--------------------------------------------------------------------------------
1 | /// #REQ-baz
2 | /// Just implement baz directly
3 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/settings/src/foo/fab.rs:
--------------------------------------------------------------------------------
1 | //! This has foo stuff
2 |
3 |
4 | /// #SPC-foo.yes
5 | /// Do foo?
6 | fn foo() {
7 | }
8 |
9 | #[test]
10 | /// #TST-foo.yes4
11 | fn test_samefile() {
12 | println!("TST-foo"); // nothing happens without `#`
13 | }
14 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/settings/src/foo/mod.rs:
--------------------------------------------------------------------------------
1 | /// #SPC-foo
2 | ///
3 | /// This is where foo is implemented
4 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/settings/src/foo/test.rs:
--------------------------------------------------------------------------------
1 | /// Test foo and stuff. Don't link TST-foo directly
2 |
3 |
4 | #[test]
5 | /// #TST-foo.yes1
6 | fn foo_1() {
7 | // #TST-foo.yes2
8 | // #TST-foo.yes3
9 | }
10 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/settings/src/lib.rs:
--------------------------------------------------------------------------------
1 | #[cfg(test)]
2 | mod tests {
3 | #[test]
4 | fn it_works() {
5 | assert_eq!(2 + 2, 4);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/source_invalid/.art/settings.toml:
--------------------------------------------------------------------------------
1 | # artifact project settings
2 |
3 | # Note: {cwd} == current directory of THIS file
4 | # {repo} == directory of the `.art` file
5 |
6 | # directories containing artifact toml files
7 | artifact_paths = []
8 |
9 | # artifact paths to exclude. This is how you can avoid trying
10 | # to load .git/.hg/etc directories (or anything else you don't
11 | # want to include
12 | exclude_artifact_paths = []
13 |
14 | # directories containing code that has artifact links
15 | code_paths = ["/src"]
16 |
17 | # directories to exclude when searching through code
18 | exclude_code_paths = []
19 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/source_invalid/assert-cases/basic/assert_load_lints.yaml:
--------------------------------------------------------------------------------
1 | error:
2 | -
3 | level: Error
4 | path: src/one.py
5 | line: 2
6 | category: ParseCodeImplementations
7 | msg: "duplicate detected: SPC-one"
8 | -
9 | level: Error
10 | path: src/one.py
11 | line: 3
12 | category: ParseCodeImplementations
13 | msg: "duplicate detected: SPC-one"
14 | -
15 | level: Error
16 | path: src/two.py
17 | line: 2
18 | category: ParseCodeImplementations
19 | msg: "duplicate detected: SPC-two"
20 | -
21 | level: Error
22 | path: src/two.py
23 | line: 3
24 | category: ParseCodeImplementations
25 | msg: "duplicate detected: SPC-two.a"
26 | -
27 | level: Error
28 | path: src/two-b.py
29 | line: 2
30 | category: ParseCodeImplementations
31 | msg: "duplicate detected: SPC-two"
32 | -
33 | level: Error
34 | path: src/two-b.py
35 | line: 3
36 | category: ParseCodeImplementations
37 | msg: "duplicate detected: SPC-two.a"
38 | other: []
39 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/source_invalid/src/one.py:
--------------------------------------------------------------------------------
1 | # This has two identical locations
2 |
3 | #SPC-one
4 | #SPC-one
5 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/source_invalid/src/two-b.py:
--------------------------------------------------------------------------------
1 | # The other identical location
2 |
3 | #SPC-two
4 | #SPC-two.a
5 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/source_invalid/src/two.py:
--------------------------------------------------------------------------------
1 | # This has one of the identical ones
2 |
3 | #SPC-two
4 | #SPC-two.a
5 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/source_only/.art/settings.toml:
--------------------------------------------------------------------------------
1 | # artifact project settings
2 |
3 | # Note: {cwd} == current directory of THIS file
4 | # {repo} == directory of the `.art` file
5 |
6 | # directories containing artifact toml files
7 | artifact_paths = []
8 |
9 | # artifact paths to exclude. This is how you can avoid trying
10 | # to load .git/.hg/etc directories (or anything else you don't
11 | # want to include
12 | exclude_artifact_paths = []
13 |
14 | # directories containing code that has artifact links
15 | code_paths = ["src", "pylib/"]
16 |
17 | # directories to exclude when searching through code
18 | exclude_code_paths = ["pylib/noinclude", "pylib/noinclude.py"]
19 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/source_only/assert-cases/basic/assert_project.yaml:
--------------------------------------------------------------------------------
1 | # Source only example project.
2 | #
3 | # This just asserts that the source files are parsed as expected.
4 | settings:
5 | code_paths:
6 | - pylib
7 | - src
8 | exclude_code_paths:
9 | - pylib/noinclude
10 | - pylib/noinclude.py
11 | artifact_paths: []
12 | exclude_artifact_paths: []
13 | code_impls:
14 | TST-pyinit:
15 | primary:
16 | file: pylib/__init__.py
17 | line: 0
18 | secondary: {}
19 | SPC-pylib:
20 | primary: null
21 | secondary:
22 | .example:
23 | file: pylib/example.py
24 | line: 1
25 | REQ-rust:
26 | primary:
27 | file: src/lib.rs
28 | line: 0
29 | secondary: {}
30 | artifacts: {}
31 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/source_only/pylib/__init__.py:
--------------------------------------------------------------------------------
1 | #TST-pyinit
2 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/source_only/pylib/example.py:
--------------------------------------------------------------------------------
1 | # this is an example.
2 | # #SPC-pylib.example
3 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/source_only/pylib/noinclude.py:
--------------------------------------------------------------------------------
1 | #SPC-not_here
2 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/source_only/pylib/noinclude/foo.py:
--------------------------------------------------------------------------------
1 | #SPC-not_here
2 |
--------------------------------------------------------------------------------
/artifact-test/interop_tests/source_only/src/lib.rs:
--------------------------------------------------------------------------------
1 | #REQ-rust
2 |
--------------------------------------------------------------------------------
/artifact-test/src/artifact.rs:
--------------------------------------------------------------------------------
1 | /* artifact: the requirements tracking tool made for developers
2 | * Copyright (C) 2018 Rett Berg <@vitiral, vitiral@gmail.com>
3 | *
4 | * The source code is Licensed under either of
5 | *
6 | * * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
7 | * http://www.apache.org/licenses/LICENSE-2.0)
8 | * * MIT license ([LICENSE-MIT](LICENSE-MIT) or
9 | * http://opensource.org/licenses/MIT)
10 | *
11 | * at your option.
12 | *
13 | * Unless you explicitly state otherwise, any contribution intentionally submitted
14 | * for inclusion in the work by you, as defined in the Apache-2.0 license, shall
15 | * be dual licensed as above, without any additional terms or conditions.
16 | * */
17 | //! This module is for testing fully realized artifacts.
18 |
19 | use super::dev_prelude::*;
20 | use super::implemented::random_impl_links;
21 | use super::raw::arb_raw_artifacts;
22 | use artifact_lib::*;
23 |
24 | const GEN_REL_FILE_PATH_RE: &str = r#"(?x)
25 | ([a-zA-Z0-9_]{1,7}/){0,3} # an optional number of subdirs
26 | [a-zA-Z0-9_]{1,7}.(md|json|toml) # the required file name
27 | "#;
28 |
29 | pub fn arb_rel_file_path() -> BoxedStrategy {
30 | GEN_REL_FILE_PATH_RE.prop_map(|s| s.to_string()).boxed()
31 | }
32 |
33 | /// Arbitrary _relative_ file paths.
34 | ///
35 | /// Always generates at least 1. size must be `> 0`
36 | pub fn arb_rel_file_paths(size: usize) -> BoxedStrategy> {
37 | prop::collection::hash_set(arb_rel_file_path(), 1..size).boxed()
38 | }
39 |
40 | // TODO: use the file paths above to construct the artifacts.
41 | // pub fn arb_artifacts(size: usize) -> BoxedStrategy> {
42 | // arb_raw_artifacts(size)
43 | // .prop_perturb(|artifacts, mut rng| {
44 | // unimplemented!()
45 | // })
46 | // .boxed()
47 | // }
48 |
49 | // fn get_settings(raw: BTreeMap) -> (Settings, BTreeMap) {
50 | // unimplemented!();
51 | // }
52 |
--------------------------------------------------------------------------------
/artifact-test/src/graph.rs:
--------------------------------------------------------------------------------
1 | /* artifact: the requirements tracking tool made for developers
2 | * Copyright (C) 2018 Rett Berg <@vitiral, vitiral@gmail.com>
3 | *
4 | * The source code is Licensed under either of
5 | *
6 | * * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
7 | * http://www.apache.org/licenses/LICENSE-2.0)
8 | * * MIT license ([LICENSE-MIT](LICENSE-MIT) or
9 | * http://opensource.org/licenses/MIT)
10 | *
11 | * at your option.
12 | *
13 | * Unless you explicitly state otherwise, any contribution intentionally submitted
14 | * for inclusion in the work by you, as defined in the Apache-2.0 license, shall
15 | * be dual licensed as above, without any additional terms or conditions.
16 | * */
17 | //! This module defines tests for the graph implementation details of
18 | //! computing artifacts.
19 |
20 | use super::dev_prelude::*;
21 | use artifact_data::graph::{self, round_ratio};
22 |
23 | /// create the `partof`s and the graphs
24 | pub fn simple_graph() -> (IndexMap>, graph::Graphs) {
25 | let partofs = indexmap! {
26 | name!("REQ-aaa") => indexset!{},
27 | name!("REQ-bbb") => indexset!{name!("REQ-aaa")},
28 | name!("REQ-ccc") => indexset!{name!("REQ-bbb")},
29 | name!("SPC-bbb") => indexset!{name!("REQ-bbb")},
30 | name!("SPC-bbb-a") => indexset!{name!("SPC-bbb")},
31 | name!("SPC-bbb-b") => indexset!{name!("SPC-bbb")},
32 | name!("TST-aaa") => indexset!{name!("SPC-bbb")},
33 | name!("TST-aaa-a") => indexset!{name!("TST-aaa")},
34 | };
35 |
36 | let graphs = graph::determine_graphs(&partofs);
37 | (partofs, graphs)
38 | }
39 |
--------------------------------------------------------------------------------
/artifact-test/src/implemented.rs:
--------------------------------------------------------------------------------
1 | /* artifact: the requirements tracking tool made for developers
2 | * Copyright (C) 2018 Rett Berg <@vitiral, vitiral@gmail.com>
3 | *
4 | * The source code is Licensed under either of
5 | *
6 | * * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
7 | * http://www.apache.org/licenses/LICENSE-2.0)
8 | * * MIT license ([LICENSE-MIT](LICENSE-MIT) or
9 | * http://opensource.org/licenses/MIT)
10 | *
11 | * at your option.
12 | *
13 | * Unless you explicitly state otherwise, any contribution intentionally submitted
14 | * for inclusion in the work by you, as defined in the Apache-2.0 license, shall
15 | * be dual licensed as above, without any additional terms or conditions.
16 | * */
17 | /// Test the "implemented" (i.e. source code parsing) module.
18 | use regex_generate;
19 |
20 | use super::dev_prelude::*;
21 | use super::raw_names::arb_names_raw;
22 | use artifact_data::implemented::{join_locations, parse_locations};
23 | use artifact_data::raw_names::NamesRaw;
24 |
25 | // ------------------------------
26 | // -- FUZZ METHODS
27 |
28 | /// Generate a list of names along with randomly generated sub-names.
29 | ///
30 | /// It is guaranteed that all names are represented.
31 | pub fn random_impl_links(
32 | rng: &mut R,
33 | names: &NamesRaw,
34 | ) -> IndexSet<(Name, Option)> {
35 | let mut textgen =
36 | regex_generate::Generator::parse(r"\.((tst-)?[a-zA-Z0-9_]{1,10})", rng.clone()).unwrap();
37 | let mut buffer: Vec = Vec::with_capacity(10);
38 | let mut out = IndexSet::new();
39 | for name in names.iter() {
40 | // Base name is always included
41 | out.insert((name.clone(), None));
42 | if rng.next_f32() < 0.3 {
43 | // 30% chance ahere are no subnames
44 | continue;
45 | }
46 | for _ in 0..rng.gen_range(1, 5) {
47 | buffer.clear();
48 | textgen.generate(&mut buffer).unwrap();
49 | let sub = subname!(str::from_utf8(&buffer).unwrap());
50 | out.insert((name.clone(), Some(sub)));
51 | }
52 | }
53 | out
54 | }
55 |
56 | /// Generate random source code text with links to all the given `name[.sub]`s.
57 | pub fn random_source_code(
58 | rng: &mut R,
59 | locations: &IndexSet<(Name, Option)>,
60 | ) -> String {
61 | let mut lines = random_lines(rng);
62 | if lines.is_empty() {
63 | lines.push(vec!["".into()]);
64 | }
65 | for &(ref name, ref sub) in locations.iter() {
66 | insert_word(rng, &mut lines, format!("#{}", name_ref_string(name, sub)));
67 | }
68 | lines.iter().map(|line| line.iter().join(" ")).join("\n")
69 | }
70 |
71 | /// Arbitrary single source code file
72 | pub fn arb_source_code(
73 | size: usize,
74 | ) -> BoxedStrategy<(NamesRaw, IndexSet<(Name, Option)>, String)> {
75 | arb_names_raw(size)
76 | .prop_perturb(|names, mut rng| {
77 | let locations = random_impl_links(&mut rng, &names);
78 | let code = random_source_code(&mut rng, &locations);
79 | (names, locations, code)
80 | })
81 | .boxed()
82 | }
83 |
84 | // METHODS
85 |
86 | pub fn replace_links(raw: &str) -> String {
87 | raw.replace('%', "#")
88 | }
89 |
--------------------------------------------------------------------------------
/artifact-test/src/lib.rs:
--------------------------------------------------------------------------------
1 | /* artifact: the requirements tracking tool made for developers
2 | * Copyright (C) 2018 Rett Berg <@vitiral, vitiral@gmail.com>
3 | *
4 | * The source code is Licensed under either of
5 | *
6 | * * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
7 | * http://www.apache.org/licenses/LICENSE-2.0)
8 | * * MIT license ([LICENSE-MIT](LICENSE-MIT) or
9 | * http://opensource.org/licenses/MIT)
10 | *
11 | * at your option.
12 | *
13 | * Unless you explicitly state otherwise, any contribution intentionally submitted
14 | * for inclusion in the work by you, as defined in the Apache-2.0 license, shall
15 | * be dual licensed as above, without any additional terms or conditions.
16 | * */
17 | //! This subcrate is to provide a common testing framework/functions
18 | //! for testing artifact.
19 | //!
20 | //! Related:
21 | //! - #TST-unit
22 | //! - #TST-fuzz
23 | #![allow(unused_imports)]
24 | #![allow(dead_code)]
25 | #![allow(unused_macros)]
26 |
27 | pub use base64;
28 | pub use ergo;
29 | #[macro_use]
30 | pub extern crate expect_macro;
31 | pub use failure;
32 | #[macro_use]
33 | pub extern crate matches;
34 | pub use petgraph;
35 | pub use rayon;
36 | pub use siphasher;
37 |
38 | #[macro_use]
39 | pub extern crate failure_derive;
40 | pub use time;
41 |
42 | #[macro_use]
43 | pub extern crate artifact_data;
44 | #[macro_use]
45 | pub extern crate artifact_lib;
46 | #[macro_use]
47 | extern crate log;
48 |
49 | #[macro_use]
50 | extern crate proptest;
51 |
52 | #[macro_use]
53 | extern crate pretty_assertions;
54 |
55 | // #[cfg(test)]
56 | // extern crate rand;
57 |
58 | use regex_generate;
59 |
60 | pub mod artifact;
61 | pub mod dev_prelude;
62 | pub mod family;
63 | pub mod graph;
64 | pub mod implemented;
65 | pub mod name;
66 | pub mod raw;
67 | #[macro_use]
68 | pub mod raw_names;
69 | pub mod framework;
70 |
71 | pub use crate::dev_prelude::*;
72 | pub use crate::framework::{
73 | assert_stuff_data, run_generic_interop_test, run_generic_interop_tests, ExpectStuff,
74 | };
75 | pub use artifact_data::*; // for macros
76 | pub use proptest::*;
77 |
--------------------------------------------------------------------------------
/artifact-test/src/name.rs:
--------------------------------------------------------------------------------
1 | /* artifact: the requirements tracking tool made for developers
2 | * Copyright (C) 2018 Rett Berg <@vitiral, vitiral@gmail.com>
3 | *
4 | * The source code is Licensed under either of
5 | *
6 | * * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
7 | * http://www.apache.org/licenses/LICENSE-2.0)
8 | * * MIT license ([LICENSE-MIT](LICENSE-MIT) or
9 | * http://opensource.org/licenses/MIT)
10 | *
11 | * at your option.
12 | *
13 | * Unless you explicitly state otherwise, any contribution intentionally submitted
14 | * for inclusion in the work by you, as defined in the Apache-2.0 license, shall
15 | * be dual licensed as above, without any additional terms or conditions.
16 | * */
17 | //! This module defines all operations around testing artifact names
18 |
19 | use ergo::json;
20 |
21 | use super::dev_prelude::*;
22 |
23 | // HELPERS and TRAITS
24 |
25 | // this purposely doesn't use the definition from `name.rs`
26 | const GEN_NAME_RE: &str = r#"(?x)
27 | (REQ|SPC|TST)- # the type followed by `-`
28 | ([a-zA-Z0-9_]{1,7}-){0,3} # an optional number of `elem-` elements
29 | [a-zA-Z0-9_]{1,7} # required final element
30 | "#;
31 |
32 | // lazy_static!{
33 | // static ref GEN_NAME_PROP: Arc> =
34 | // Arc::new(prop::string::string_regex(GEN_NAME_RE).unwrap());
35 | // }
36 |
37 | #[inline(always)]
38 | pub fn arb_name_string() -> BoxedStrategy {
39 | GEN_NAME_RE.prop_map(|s| s.to_string()).boxed()
40 | }
41 |
42 | #[inline(always)]
43 | pub fn arb_name() -> BoxedStrategy {
44 | arb_name_string().prop_map(|n| name!(n)).boxed()
45 | }
46 |
47 | /// Return a vector of the `raw` names
48 | pub fn names_raw(names: &[Name]) -> Vec {
49 | names.iter().map(|n| n.raw.clone()).collect()
50 | }
51 |
52 | /// Assert that the name is valid
53 | pub fn assert_names_valid(raw: &[&str]) {
54 | let errors = raw
55 | .iter()
56 | .map(|r| (*r, Name::from_str(r)))
57 | .filter_map(|(raw, result)| match result {
58 | Ok(name) => {
59 | if raw == name.raw {
60 | None
61 | } else {
62 | panic!("raw was different: {} => {}", raw, name.raw);
63 | }
64 | }
65 | Err(_) => Some(raw),
66 | })
67 | .collect::>();
68 | if !errors.is_empty() {
69 | panic!("The following names were not valid:\n{:#?}", errors);
70 | }
71 | }
72 |
73 | /// Assert that the name is valid
74 | pub fn assert_names_invalid(raw: &[&str]) {
75 | let errors = raw
76 | .iter()
77 | .map(|r| (r, Name::from_str(r)))
78 | .filter_map(|(raw, result)| match result {
79 | Ok(_) => Some(raw),
80 | Err(_) => None,
81 | })
82 | .collect::>();
83 | if !errors.is_empty() {
84 | panic!(
85 | "The following names were valid but shouldn't have been:\n{:#?}",
86 | errors
87 | );
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/artifact-test/src/raw_names.rs:
--------------------------------------------------------------------------------
1 | /* artifact: the requirements tracking tool made for developers
2 | * Copyright (C) 2018 Rett Berg <@vitiral, vitiral@gmail.com>
3 | *
4 | * The source code is Licensed under either of
5 | *
6 | * * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
7 | * http://www.apache.org/licenses/LICENSE-2.0)
8 | * * MIT license ([LICENSE-MIT](LICENSE-MIT) or
9 | * http://opensource.org/licenses/MIT)
10 | *
11 | * at your option.
12 | *
13 | * Unless you explicitly state otherwise, any contribution intentionally submitted
14 | * for inclusion in the work by you, as defined in the Apache-2.0 license, shall
15 | * be dual licensed as above, without any additional terms or conditions.
16 | * */
17 |
18 | //! Test serializing/deserializing raw names
19 |
20 | use ergo::{json, toml, yaml};
21 |
22 | use super::dev_prelude::*;
23 | use super::name::arb_name;
24 | use artifact_data::raw_names::NamesRaw;
25 |
26 | pub fn arb_names_raw(size: usize) -> BoxedStrategy {
27 | prop::collection::hash_set(arb_name(), 0..size)
28 | .prop_map(|hs| NamesRaw::from(hs))
29 | .boxed()
30 | }
31 |
--------------------------------------------------------------------------------
/book/.gitignore:
--------------------------------------------------------------------------------
1 | out
2 |
--------------------------------------------------------------------------------
/book/book.toml:
--------------------------------------------------------------------------------
1 | [book]
2 | authors = ["Garrett Berg"]
3 | multilingual = false
4 | src = "src"
5 | title = "Simple Quality with Artifact"
6 |
7 | [build]
8 | build-dir = "out/book"
9 |
--------------------------------------------------------------------------------
/book/src/Addendum.md:
--------------------------------------------------------------------------------
1 | # Addendum
2 |
3 | This section contains the addendum to this guide, including the spec, FAQ and
4 | other materials.
5 |
6 |
--------------------------------------------------------------------------------
/book/src/ArtifactIntro.md:
--------------------------------------------------------------------------------
1 | # Artifact Intro
2 |
3 | This is an introduction to how we start integrating the Artifact tool into our
4 | design and development workflow. It is intended to be interactive, so please
5 | follow along with everything installed!
6 |
7 | > **Exercise 1: ensuring your environment works:**
8 | >
9 | > You should have at least done the [Starting Project](./StartingProject.html)
10 | > chapter before attempting this one.
11 | >
12 | > Run `art ls`, you should see something like:
13 | >
14 | > ```
15 | > spc% tst% | name | parts
16 | > 0.0 0.0 | REQ-purpose |
17 | > ```
18 |
19 | ## Converting our README.md into an artifact.
20 |
21 | The first thing we want to do is use the `README.md` file we have already been writing
22 | as our artifact file.
23 |
24 | To do this, let's make a couple of changes:
25 | - Move our `README.md` into `design/purpose.md`
26 | - Clean up the headers so they are artifacts.
27 |
28 | To move your README.md, simply type:
29 | ```
30 | mv README.md purpose.md
31 | ```
32 |
33 | > **Check In:** run `art ls`. It shows nothing because we have not specified
34 | > any artifacts.
35 |
36 | We now need to convert our headers into artifacts. Let's start with our purpose.
37 | Change the `# Purpose` line (from [Specifying Your Purpose](./Purpose.html)) to
38 | `# REQ-purpose`. Your file should now look something like:
39 |
40 | ```markdown
41 | # REQ-purpose
42 | Write a flash card quizzer ...
43 |
44 | ```
45 |
46 | Do the same thing to your specifications from
47 | [High Level Design](./Design.html):
48 | - `# Execution Method` -> `# SPC-cli`
49 | - `# Final Results` -> `# SPC-report`
50 | - `# Question File Format` -> `# SPC-format`
51 |
52 | Now `art ls` should show:
53 | ```bash
54 | $ art ls
55 | spc% tst% | name | parts
56 | 0.0 0.0 | REQ-purpose |
57 | 0.0 0.0 | SPC-cli |
58 | 0.0 0.0 | SPC-format |
59 | 0.0 0.0 | SPC-report |
60 | ```
61 |
62 | This is closer, but notice that none of them are linked. Let's fix that.
63 |
64 | For `SPC-cli` make it look like this:
65 |
66 | ```markdown
67 | # SPC-cli
68 | partof:
69 | - REQ-purpose
70 | ###
71 | The minimum viable product ...
72 | ```
73 |
74 | Do the same for `SPC-format` and `SPC-report`, also making them partof
75 | `REQ-purpose`. You should now have:
76 | ```
77 | $ art ls
78 | spc% tst% | name | parts
79 | 0.0 0.0 | REQ-purpose | SPC-cli, SPC-format, SPC-report
80 | 0.0 0.0 | SPC-cli |
81 | 0.0 0.0 | SPC-format |
82 | 0.0 0.0 | SPC-report |
83 |
84 | ```
85 |
86 | Now is also a good time to run `art serve`. This will serve your project
87 | locally so that you can view and edit it through the Web UI.
88 |
89 | [Here is an example of the project in its current state](examples/part1/index.html)
90 |
91 |
92 |
--------------------------------------------------------------------------------
/book/src/BestPractices.md:
--------------------------------------------------------------------------------
1 | These are a few of the (alpha) best practices when using artifact.
2 |
3 | ### use-features: use the features of artifact
4 | Artifact contains several useful features. Use them!
5 | - `art check`: makes sure your references are all valid both in code and in your
6 | artifacts.
7 | - `art fmt`: format your artifacts
8 |
9 | ### too-many-pieces: Do not break into too many pieces
10 | Artifact is a great tool for breaking up your design, so much so that it is
11 | tempting to specify every detail as it's own artifact
12 |
13 | Avoid this:
14 | - SPC-ui-cmd
15 | - SPC-ui-cmd-ls
16 | - SPC-ui-cmd-fmt
17 | - SPC-ui-web
18 | - SPC-ui-web-list
19 | - SPC-ui-web-edit
20 | - SPC-ui-gui
21 | - ... etc...
22 |
23 | There is no reason to have the `ui` prefix -- each of these are almost
24 | completely different components and doesn't aid in understanding your
25 | design documents.
26 |
27 | Instead, consider having:
28 |
29 | - REQ-ui: high level ui requirements
30 | - REQ-cmd: partof=REQ-ui
31 | - REQ-web: partof=REQ-ui
32 | - REQ-gui: partof=REQ-ui
33 |
34 | This keeps the breakdown obvious but also keeps the names short.
35 |
36 | ### short-names: Keep artifact names as short as possible
37 | Nobody wants to read `REQ-ui-web-design-frontend-edit-text`. That level of
38 | nesting is simply not necessary. Something like `REQ-web-edit` will suffice.
39 |
40 | Try and combine such detail into a single artifact. Auto-linking is cool, but
41 | don't get carried away! It's okay to specify `partof` when it makes
42 | your tree simpler.
43 |
44 | ### no-numbers: Use only human readable names
45 | Artifact names should avoid using numbers. If you are tempted to call something
46 | `SPC-foo-1` just break down the different items of `foo` in a bullet point list
47 | in its `text` field and use subnames.
48 |
49 | ### abbreviations: abbreviate names
50 | Artifact is intended to be used as a cmd line tool, so keeping names short is
51 | very nice.
52 |
53 | This is mostly useful for larger projects.
54 |
55 | ### prefix-acronyms: create acronyms for your prefixes
56 | Use an acronym or abbreviation for your prefixes.
57 |
58 | One of the main use cases of short names is for the categories of your
59 | artifacts. For instance, say your storage product had the following features:
60 | - transport
61 | - data availability
62 | - data recovery
63 | - remote replication
64 |
65 | It would be annoying to have artifacts like `REQ-transport-drive` or
66 | `REQ-remote_replication-protocol`. Instead, use an acronyms:
67 |
68 | - **TP**: transport
69 | - **DA**: data availability
70 | - **DR**: data recovery
71 | - **RR**: remote replication
72 |
73 | Now your artifacts look like `REQ-TP-drive` and `REQ-RR-protocol`,
74 | which is much shorter and more readable when looking at a large list.
75 |
76 | ### uniformity: keep names uniform
77 | Artifact automatically makes `SPC-foo` a partof `REQ-foo` and that is because
78 | they should be related. Make sure your names have meaning so this doesn't
79 | accidentally become a gotcha for your project.
80 |
81 |
--------------------------------------------------------------------------------
/book/src/CleaningUp.md:
--------------------------------------------------------------------------------
1 | # Cleaning Up
2 | There are two more commands that it is critical to know:
3 | - `art check`: for checking for errors and warnings.
4 | - `art fmt`: for formatting your arguments.
5 |
6 | `art check` checks a whole range of things:
7 | - All artifacts in `partof` exist.
8 | - The soft references (i.e. `[[REQ-foo]]`) exist.
9 | - Code references are valid and not duplicated.
10 |
11 | `art fmt` standardizes the format of your artifacts and makes them easier to read.
12 |
13 | > Note: `art fmt` is automatically run whenever you edit any artifacts via the
14 | > Web UI.
15 |
16 |
17 | ## Documenting and Hosting your own project
18 | To start documenting your own project, run `art init` in your project and
19 | edit `.art/settings.toml` with the paths on where to find your
20 | design docs and code.
21 |
22 | Have your build system export your design documents as html for easy viewing.
23 | See: [Exporting Html](./ExportingHtml.html)
24 |
25 |
26 | ## Artifact Advice
27 | Here are a words when using artifact:
28 |
29 | 1. You should always write a good README and other documentation for your users
30 | -- design docs SHOULD be used for bringing developers of your project up
31 | to speed but they aren't the best format for general users.
32 | 2. Keep your design docs fairly high level -- don't try to design every detail
33 | using artifact. Using artifact does not mean that you shouldn't use code
34 | comments!
35 | 3. Use `art ls` and `art check` often, and fix those error messages!
36 | 4. Follow the [artifact best practices](./BestPractices.html).
37 | 5. Don't be afraid to refactor your design docs. It is actually easier than it
38 | might sound, as the tool will help you find broken links and incomplete
39 | items in real time. Not to mention that if you use revision control
40 | (you should), your artifacts can be tracked with your project -- no more
41 | having your documentation and your code be wildly out of sync!
42 |
43 | This tutorial took you part of the way through developing a simple project
44 | using artifact. Continue onto the next section or simply try using artifact for
45 | one of your smaller personal projects and see the benefits that design
46 | documents can give -- it's your choice!
47 |
48 | Have some fun with the tool, try to break it. If you find bugs or have any
49 | suggestions, please open a ticket at:
50 | https://github.com/vitiral/artifact/issues
51 |
52 | Good luck!
53 |
--------------------------------------------------------------------------------
/book/src/Design.md:
--------------------------------------------------------------------------------
1 | # High Level Design
2 |
3 | Once you know the purpose of your project, it is important for you to write
4 | down the approach you plan to take. This is important because:
5 | - There may be gaps when you don't work on your project. If you go on vacation
6 | for a month, having a reference of your thoughts at the time you were focused
7 | can jumpstart your productivity.
8 | - It is important to be able to reference a design doc for new contributors and
9 | newbie developers.
10 |
11 | Your high level requirements should go in your `README.md`, just below your purpose
12 | section:
13 |
14 | ```markdown
15 | # Execution Method
16 | The minimum viable product shall be a command line utility
17 | that is given the path to one or more question files as
18 | arguments
19 |
20 | Additional arguments will include:
21 | - `-t`: specify the time allowed for each question
22 | - `-T`: specify the total time allowed for the whole quiz
23 | - `-r NUM`: repeat questions only a certain number of times.
24 | By default there is no limit
25 |
26 | The program will ask one question at a time, recording how
27 | many answers the user got correct/incorrect and weighting
28 | future questions accordingly.
29 |
30 | When the program is complete it will report:
31 | - time taken, broken up by whole quiz and each question
32 | - the user's score
33 |
34 |
35 | # Final Results
36 | When the program is complete a report shall be printed with:
37 | - time taken, broken up by whole quiz and each question
38 | - the user's total score
39 | - questions ranked by ones the user had the most difficulty
40 |
41 |
42 | # Question File Format
43 | The user shall be able to easily configure the quiz
44 | questions through a simple csv format consisting of two
45 | columns: the question and the answer.
46 | ```
47 |
48 | Again, just like the purpose documentation, this documentation aims to be
49 | brief and help you during your design process.
50 |
51 | > ### Exercise 1:
52 | > What are some other items that we can detail at a high level?
53 | > Try writing them out yourself in this section.
54 |
--------------------------------------------------------------------------------
/book/src/DetailedDesign.md:
--------------------------------------------------------------------------------
1 | # Detailed Design
2 |
3 | Now that we have our high level design, let's start desiging how we are
4 | actually going to _build_ our flash card application. The first thing
5 | we might want to design is: how does the user specify questions?
6 |
7 | We already answered this to some degree in `SPC-format`. Let's expand it a bit.
8 |
9 | ```markdown
10 | # SPC-format
11 | partof:
12 | - REQ-purpose
13 | ###
14 | The user shall be able to easily configure the quiz
15 | questions through a simple csv format consisting of two
16 | columns: the question and the answer.
17 |
18 | The format of the csv file **shall** be a csv file of the form:
19 |
20 | City, Capitol
21 |
22 | > Note: whitespace will be ignored
23 |
24 | ## [[.question]]
25 | The `Question` class shall be the primary datatype used for questions in the
26 | application. Quetions shall:
27 | - Store the question and answer.
28 | - Provide a method `ask` to ask the user the question
29 | and validate the answer.
30 |
31 | ## [[.validate]]
32 | Input questions **shall** be validated to:
33 | - Guarantee against duplicates.
34 | - Guarantee that the data format is correct.
35 | ```
36 |
37 | There are a few things here, so let's take a look:
38 | - We expanded _how_ the user can configure the questions (the CSV format itself)
39 | - We created two subartifacts, `.question` and `.validate`.
40 | - Having the `[[.subart]]` anywhere within the text is enough to create
41 | these.
42 | - We can now link these subarts in code and they are necessary for our
43 | artifact to be considered "complete".
44 |
45 | # Define Tests
46 |
47 | Let's also define a couple of unit tests. You could do this using a new
48 | `TST-format` (or any other name) artifact.
49 |
50 | However, artifact has what are called tst-subarts specifically for the purpose
51 | of defining unit test coverage that you want. Simply add the following section
52 | to `SPC-format`:
53 |
54 | ```markdown
55 | ## Unit Tests:
56 | - Invalid: make sure invalid inputs don't work
57 | - [[.tst-invalid_cols]]: Test invalid number of columns (0, 1, and 3).
58 | - [[.tst-duplicates]]: Test duplicate names.
59 | - Make sure loading works.
60 | - [[.tst-basic]]: Loading a raw string and validating it.
61 | - [[.tst-load]]: Loading a valid csv file path and validating it.
62 | ```
63 |
64 | These will allow us to implement testing for SPC-format without having to
65 | create new artifacts.
66 |
--------------------------------------------------------------------------------
/book/src/ExampleFile.md:
--------------------------------------------------------------------------------
1 | # REQ-learn
2 | Welcome to the artifact tutorial! This file is written just like artifact
3 | markdown files are. Artifact files can be written in a range of formats, the
4 | currently supported ones being markdown, toml and yaml.
5 |
6 | An artifact file is simply a set of artifacts, each one written like so:
7 | ```
8 | # REQ-NAME
9 |
10 | ```
11 |
12 | Artifacts can be a requirement (REQ), design-specification (SPC)
13 | or test (TST)
14 |
15 | The artifact you are reading now is a requirement, therefore it begins with
16 | "REQ".
17 |
18 |
19 | # REQ-markdown
20 | partof:
21 | - REQ-learn
22 | ###
23 |
24 | Artifact files like this one are written in a slightly extended markdown
25 | format. You can read more about markdown here:
26 | http://commonmark.org/help/tutorial/
27 |
28 | The "extended" part is that artifact treats the following syntax as special:
29 | ```
30 | # ART-name
31 |
32 | ###
33 |
34 | ```
35 |
36 | Where `ART` is one of `REQ`, `SPC`, `TST` and `` is
37 | a few items like `partof` and `done` fields. We will get to those later.
38 |
39 |
40 | # SPC-learn
41 | partof:
42 | - REQ-markdown
43 | ###
44 |
45 | Anything starting with SPC is a design specification.
46 |
47 | Requirements (REQ) should be used for:
48 | - Detailing what you want your application to do.
49 | - What the architecture of your application should be.
50 |
51 | Specifications (SPC) should be used for:
52 | - How you intend to write your application (lower level details).
53 |
54 | There are also tests (TST) which we will learn about later.
55 |
56 |
57 | # SPC-partof
58 | partof:
59 | - REQ-learn
60 | ###
61 |
62 | Artifact uses the names of artifacts to automatically link them and track
63 | progress. This makes it easy for the user to intuitively link together
64 | requirements with their specification and reduces boilerplate.
65 |
66 | For instance, `[[SPC-learn]]` is automatically a "partof" `REQ-learn` because
67 | the names after the type are the same ("-learn").
68 |
69 | You can also explicitly link artifacts like so:
70 | ```
71 | # SPC-name
72 | partof:
73 | - SPC-other
74 | -
75 | ###
76 |
77 | ```
78 |
79 | Here is a graph of valid partof relations between artifacts:
80 | ```
81 | REQ <-- SPC <-- TST
82 | ```
83 |
84 | In other words:
85 | - A REQ can be partof a REQ only
86 | - A SPC an be partof a REQ or SPC
87 | - A TST can be partof a REQ, SPC or TST
88 |
89 | # SPC-valid
90 |
91 | There are only a few rules for defining artifacts:
92 | - Case is ignored for all names.
93 | - Names cannot overlap, even in different files.
94 | - All names must start with either REQ, SPC or TST.
95 |
96 |
97 | # TST-definition
98 | TST artifacts (and subartifacts) are used to document test design and are the
99 | only way that an artifact can be considered "tested" (besides the `done`
100 | field).
101 |
102 | Artifact makes it easy to track the "progress" of your application because `art
103 | ls` (and the web-ui) gives you easy to easy to read completion and tested
104 | percentages for all your artifacts based on which ones are implemented in
105 | source code (more on that later).
106 |
107 |
108 | # SPC-implementing
109 | Artifacts are implemented by putting links anywhere your source code, i.e.
110 | `#SPC-name`. There are also subartifacts, i.e. `#SPC-name.sub`.
111 |
112 | Subartifacts are defined by putting `[[.subart]]` anywhere in the text. These
113 | artifacts are used to break down how to implement an artifact in pieces which
114 | should then be linked in code.
115 |
116 | Unit tests can be specified by using `[[.tst-name]]`. These kind of subarts
117 | contribute to an artifact's `tst%`.
118 |
119 |
--------------------------------------------------------------------------------
/book/src/ExportingHtml.md:
--------------------------------------------------------------------------------
1 | The `art export html $DEST` command can be used to create a static site which
2 | is included on github. For an example, see
3 | [artifact's own design docs](http://vitiral.github.io/artifact/index.html)
4 |
5 | In order to make a github page for your site that hosts your design documents:
6 | - [Activate github pages](https://pages.github.com/) (we will be using the
7 | `index.html` option)
8 | - Run `art export html`, which will generate an `index.html` file among other
9 | necessary files and folders.
10 | - Run `git add index.html css` to add the generated files.
11 | - Push to master or to `gh-pages` branch.
12 |
13 | That's it! You should be able to navigate to
14 | `http://.github.io//` to view your page!
15 |
--------------------------------------------------------------------------------
/book/src/FAQ.md:
--------------------------------------------------------------------------------
1 | ## Why is it named artifact?
2 | Artifact is simply named after what it does: it is a way to write and track
3 | your [artifacts](https://en.wikipedia.org/wiki/Artifact_(software_development))
4 |
5 | ### Why is (extended) markdown the default language?
6 | Because it is human/readable and writeable. Adding the metadata block was also
7 | not difficult and fit within the syntax.
8 |
9 | ### An artifact is "implemented" in code but not 100% done?
10 | All artifacts are only as done as their parts + implementation/done.
11 |
12 | If you have:
13 | ```toml
14 | [SPC-1]
15 | [SPC-1-a]
16 | [SPC-1-b]
17 | ```
18 |
19 | And then the code:
20 | ```python
21 | def hello():
22 | """partof: #SPC-1"""
23 | ```
24 |
25 | `SPC-1` will only be 1/3 "done" since it still has two incomplete parts.
26 |
27 | This also applies to the "done" field.
28 |
--------------------------------------------------------------------------------
/book/src/Feedback.md:
--------------------------------------------------------------------------------
1 | # Reporting an Issue
2 |
3 | If you have any issues with artifact, please report a bug at it's [issue
4 | tracker][0].
5 |
6 | # Feedback on Artifact
7 |
8 | Below is feedback I have compiled on artifact so far. If you would like to
9 | leave feedback please [open a ticket][0], contact me on twitter
10 | [@vitiral](https://twitter.com/vitiral) or
11 | [on reddit](https://www.reddit.com/user/vitiral).
12 |
13 | - [omniaVincitVeritas, June 2017][1]: I like this idea a lot. Our profession
14 | has a real problem with massively overengineered architecture tools, but
15 | artifact is like fresh summer rain.
16 |
17 | [0]: https://github.com/vitiral/artifact/issues
18 | [1]: https://www.reddit.com/r/rust/comments/6lhnbp/artifact_081_released_finalfinal_beta/djv60xp/
19 |
--------------------------------------------------------------------------------
/book/src/Finishing.md:
--------------------------------------------------------------------------------
1 | # Finishing The Project
2 |
3 | This is a continuation of the last section and is still a work in progress. We
4 | are going to flush out the design for the rest of the flash challenge and
5 | implement an MVP.
6 |
--------------------------------------------------------------------------------
/book/src/GettingStarted.md:
--------------------------------------------------------------------------------
1 | # InteractiveTutorial
2 |
--------------------------------------------------------------------------------
/book/src/Installation.md:
--------------------------------------------------------------------------------
1 | This is the installation guide. For more information see the
2 | [project home page][1]
3 |
4 | ## Typical Installation
5 | artifact is compiled for linux, mac and windows. You can find releases on the
6 | **[github release page](https://github.com/vitiral/artifact/releases)**.
7 |
8 | For Linux and Mac, simply download and unpack the tarball with
9 | `tar -zxvf .tar.gz`. Then put it somewhere in your [PATH][10]
10 |
11 | [10]: http://unix.stackexchange.com/questions/26047/how-to-correctly-add-a-path-to-path
12 |
13 | ### Windows
14 |
15 | The recommended method of installation for windows is to use the **scoop**
16 | package manager.
17 |
18 | First, [install scoop](http://scoop.sh/) from a powershell terminal:
19 | ```
20 | iex (new-object net.webclient).downloadstring('https://get.scoop.sh')
21 | ```
22 |
23 | Then install artifact:
24 | ```
25 | scoop install artifact
26 | ```
27 |
28 | ### Arch Linux
29 | In addition to the installation methods above, Artifact is maintained as a
30 | package on the Arch AUR by [@rubdos][4]:
31 |
32 | https://aur.archlinux.org/packages/artifact/
33 |
34 | ## Building From Source
35 | Simply execute the following:
36 | ```bash
37 | git clone https://github.com/vitiral/artifact
38 | cd artifact
39 | cargo build --release
40 | ```
41 |
42 | > Note: you may need `cargo-web` installed as well.
43 |
44 | Do a full suite of tests with:
45 | ```bash
46 | cargo test
47 | ```
48 |
49 | ## Installing with [cargo](https://github.com/rust-lang/cargo)
50 |
51 | Install rust with [rustup](https://github.com/rust-lang-nursery/rustup.rs) and
52 | type `cargo install artifact-app`
53 |
54 | Note this may never be feature complete and is not the recommended method of
55 | installation.
56 |
57 | [1]: https://github.com/vitiral/artifact
58 | [2]: https://github.com/vitiral/artifact/blob/master/docs/ExportingHtml.md
59 | [3]: https://github.com/vitiral/artifact/tree/server
60 | [4]: https://github.com/rubdos
61 |
--------------------------------------------------------------------------------
/book/src/Introduction.md:
--------------------------------------------------------------------------------
1 | # Artifact Introduction
2 |
3 | Welcome to the Artifact Tutorial and Simple Quality Leaflet!
4 |
5 | This "book" (it is a very small book) also serves as the tutorial for
6 | [artifact][artifact], the design documentation tool made for everybody
7 | (including developers!). You can get this book on the project's home
8 | design documents (**TODO: add link**) and it also ships with the Web UI of
9 | every artifact (just follow the **docs** in the header).
10 |
11 | Artifact is a simple, linkable and trackable design documentation tool for
12 | everybody. It allows anyone to write and link their design documents both to
13 | each other and to source code, making it easy to know how complete their
14 | project is. Documents are revision controllable, can be edited in the browser
15 | and have a full suite of command line tools for searching, displaying,
16 | checking, exporting and formatting them.
17 |
18 | This book is broken into 3 main sections:
19 | - Artifact introduction: introducing you to the syntax and basic philosophy of
20 | artifact.
21 | - Simple Quality: an interactive guide for achieving high quality with minimal
22 | effort geared more towards beginner to intermediate software developers.
23 | - Addendum: complete list of features, fullpage specification, etc.
24 |
25 | [artifact]: https://github.com/vitiral/artifact
26 |
--------------------------------------------------------------------------------
/book/src/License.md:
--------------------------------------------------------------------------------
1 | # Artifact Documentation Directory License
2 |
3 | All documents in this directory are released under the CC0 Creative Commons
4 | Public Domain License with the intent that you should feel free to copy, paste
5 | and modify any of the designs, guides or examples for any purpose. You can read
6 | more about CC0 here:
7 |
8 | [https://creativecommons.org/publicdomain/](https://creativecommons.org/publicdomain/)
9 |
--------------------------------------------------------------------------------
/book/src/Purpose.md:
--------------------------------------------------------------------------------
1 | # Specifying Your Purpose
2 |
3 | One of the most critical pieces of documentation is your purpose documentation.
4 | Without purpose documentation, it is easy to get lost and forget what your
5 | project was trying to accomplish.
6 |
7 | We are going to start by writing our requirements in our `README.md`. Later we
8 | are going to use artifact to track them.
9 |
10 | Open up your `README.md` in your favorite plain-text editor and write out
11 | something like the following:
12 |
13 | ```markdown
14 | # Purpose:
15 | Write a flash card quizzer from scratch and learn about
16 | quality best practices while doing so.
17 |
18 | The example tutorial can be found here:
19 | http://wiki.openhatch.org/Flash_card_challenge
20 |
21 | It should be easy for users to input questions to the
22 | quizzer in a simple and open format. Additionally, the
23 | quizzer should use effective memorization techniques.
24 | Some possible ideas include:
25 | - asking items in a random order
26 | - telling the correct answer after the user answers incorrectly
27 | - asking items more often if they were answered incorrectly
28 | - allowing users to configure time limits, so they can
29 | compare results between quizzes.
30 | ```
31 |
32 | Notice that we try to keep our purpose documentation as brief and simple as
33 | possible. This is important for all documents, but is especially important for
34 | high level docs. There is a basic rule: documentation that is not brief and
35 | clear will not be read. You want to keep your docs readable, otherwise they
36 | will only weigh down your project.
37 |
38 | > ##### Exercise 1:
39 | > In your `README.md`, break down the purpose documentation above into some high
40 | > level requirements. Then give a high level specification for how you would
41 | > approach those requirements. What programming language would you use? What
42 | > libraries would you use? What would be your overall approach to each problem?
43 |
44 | > ##### Exercise 2:
45 | > Assume your program user interface would be over the command line. What kind
46 | > of arguments and user configuration would you accept? Would you let the user
47 | > use only one quiz file at a time, or use multiple of them? Write down your
48 | > answers.
49 |
50 | > ##### Exercise 3:
51 | > Skim through the [markdown format][1] specification. Markdown is a great
52 | > format for keeping docs, since it allows you to write docs in plain text
53 | > (so they can be revision controlled) but the simple formatting rules
54 | > render beautifully on sites like github.
55 | >
56 | > Markdown is easy to learn, easy to read and has become the defacto standard
57 | > for writing docs for open source projects. It is worth learning!
58 |
59 | [1]: https://gitbookio.gitbooks.io/markdown/content/
60 |
--------------------------------------------------------------------------------
/book/src/PurposeArtifact.md:
--------------------------------------------------------------------------------
1 | # Purpose in Artifact
2 |
--------------------------------------------------------------------------------
/book/src/RunningTests.md:
--------------------------------------------------------------------------------
1 | # Running Tests
2 |
3 | If you followed along with the artifact interactive tutorial, you should feel
4 | pretty confident by now that our load component is well designed and *should*
5 | be implemented and tested. However, you haven't actually run any code yet, so
6 | you can't be sure! We are going to change that.
7 |
8 | The first thing you need to do is make sure you are running python2.7. Running:
9 | ```
10 | python --version
11 | pip --version
12 | ```
13 |
14 | Should return something like:
15 | ```
16 | Python 2.7.13
17 | pip 9.0.1 from /usr/lib/python2.7/site-packages (python 2.7)
18 | ```
19 |
20 | As long as they are both python2.7.X (but not python3.X), you are good to go.
21 |
22 | > If not... python can be very difficult to configure. Search on google for
23 | > how to have both python2 and python3 installed. You will have to do a similar
24 | > exercise for `pip`.
25 |
26 | > If it is too much of a pain, you can also just use python3 (or any other
27 | > language), it shouldn't be difficult -- you will just have to fix any errors
28 | > that come up.
29 | >
30 | > If you are using another language, refer to that language's unit testing
31 | > guide.
32 |
33 | Now install `py.test`:
34 | ```
35 | pip install pytest
36 | ```
37 | > Note: it is recommended you add `--user` to the end or use a virtualenv.
38 | > Using a virtualenv with python is out of scope of this tutorial.
39 |
40 | Now run your unit tests:
41 | ```
42 | py.test flash/
43 | ```
44 |
45 | Congratulations, you've designed, written and run unit tests!
46 |
47 |
--------------------------------------------------------------------------------
/book/src/SPECIFICATION.md:
--------------------------------------------------------------------------------
1 | # Artifact Document Specification
2 |
3 | This document outlines the specification for the Artifact data format.
4 | All specifications in this document are released as Creative Commons CC0
5 | public domain. You can read more about this license here:
6 | https://creativecommons.org/publicdomain/
7 |
8 | ## Document Type
9 |
10 | Artifact documents can be specified in multiple formats.
11 |
12 | ### TOML Format
13 | The TOML format adheres to a subset of the [TOML][1] format and are documents
14 | of the form:
15 |
16 | ```toml
17 | [ART-baz]
18 | partof = "ART-baa"
19 | text = '''
20 | multi-line
21 | description
22 | '''
23 |
24 | [ART-foo-bar]
25 | partof = [
26 | "ART-baz",
27 | ]
28 | text = '''
29 | multi-line
30 | description
31 | '''
32 | ```
33 |
34 | Where `partof` can be either a single string or a list of strings.
35 |
36 | ### Markdown Format
37 | The markdown format uses extended Commonmark (**TODO: link**) format.
38 | It is of the form:
39 |
40 | ```
41 | # REQ-foo
42 |
43 | ###
44 |
45 | ```
46 |
47 | Where the yaml section is completely optional (the `###` can be skipped if it
48 | doesn't need it.
49 |
50 | ## Artifact Types
51 |
52 | Instead of `ART` as defined in Document Type, the user must select from
53 | 3 artifact types:
54 | - `REQ`: specifying a requirement. `REQ` can only have `REQ` in its
55 | `partof` field.
56 | - `SPC`: specifying a design specification. `SPC` can only have
57 | `REQ` or `SPC` in its `partof` field.
58 | - `TST`: specifying a test of a `SPC`. `TST` can have any of
59 | `REQ`, `SPC` or `TST` in its `partof` field.
60 |
61 | ## Automatic Links
62 |
63 | The following will be automatically linked:
64 | - parents: `REQ-foo` will automatically be a `partof`
65 | `REQ-foo-bar`
66 | - common-prefix for `REQ -> SPC -> TST` links
67 | - `REQ-foo` will automatically be a `partof` `SPC-foo`
68 | *if `REQ-foo` exists*
69 | - `SPC-foo` will automatically be a `partof` `TST-foo`
70 | *if `SPC-foo` exists*
71 |
72 | ## Linking an artifact in source code
73 | Artifacts can be linked in source code, which "completes" their `spc%`.
74 |
75 | The way to link to an artifact is to place `#ART-name` anywhere in the source
76 | code file.
77 |
78 | ## Sub Artifacts (subart)
79 | A sub artifact is defined by placing `[[.subart]]` anywhere in the `text` field
80 | of an artifact.
81 |
82 | Subarts can be linked in source code as well by placing `#ART-name.subart`
83 | anywhere in the source code file.
84 |
85 | A special subart is `[[.tst-subart]]` which will contribute to both `tst%` and
86 | `spc%`.
87 |
88 |
89 | [1]: https://github.com/toml-lang/toml
90 |
--------------------------------------------------------------------------------
/book/src/SUMMARY.md:
--------------------------------------------------------------------------------
1 | # Summary
2 |
3 | - [Introduction](./Introduction.md)
4 | - [Installation](./Installation.md)
5 | - [Cheat Sheet](./CheatSheet.md)
6 | - [Example](./ExampleFile.md)
7 |
8 | - [Simple Quality with Artifact](./SimpleQuality.md)
9 | - [Starting Your Project](./StartingProject.md)
10 | - [Specifying Your Purpose](./Purpose.md)
11 | - [High Level Design](./Design.md)
12 | - [Vocabulary](./Vocabulary.md)
13 | - [Tools](./Tools.md)
14 | - [Artifact Intro](./ArtifactIntro.md)
15 | - [Detailed Design](./DetailedDesign.md)
16 | - [Implementation](./Implementation.md)
17 | - [Cleaning Up](./CleaningUp.md)
18 |
19 | - [Finishing The Project](Finishing.md)
20 | - [Running Tests](./RunningTests.md)
21 | - [TODO](./TODO.md)
22 |
23 | - [Addendum](./Addendum.md)
24 | - [FAQ](./FAQ.md)
25 | - [Best Practices](./BestPractices.md)
26 | - [Exporting Html](./ExportingHtml.md)
27 | - [Feedback](./Feedback.md)
28 | - [Specification](./SPECIFICATION.md)
29 | - [License](./License.md)
30 |
--------------------------------------------------------------------------------
/book/src/SimpleQuality.md:
--------------------------------------------------------------------------------
1 | # Simple Quality
2 | *A short guide to quality best practices for developers.*
3 |
4 | By Garrett Berg
5 |
6 | ## Introduction
7 | This is a short and open-source leaflet aimed at helping software developers
8 | improve their software quality. It is also the primary user guide for the design
9 | documentation tool [artifact][4]. Its targeted audience are those who:
10 | - Know at least one programming language.
11 | - Know revision control. If you don't know one, learn git.
12 | - Want a brief guide on how to have fewer bugs, re-designs and headaches
13 | in all of their projects.
14 |
15 | This book is shiped as part of the artifact Web UI and can also be read at
16 | (**TODO: add link**).
17 |
18 | If you have suggestions or edits, please [open a ticket](./Feedback.html).
19 |
20 | The goal of this book is to make developing software simpler and more fun. Think
21 | back to the time you first learned revision control. Think about how you were
22 | backing up files before then? Maybe you were copying folders to some `backups`
23 | folder? Maybe you were not backing up at all?
24 |
25 | However you did (or didn't) track your changes, think about your life before and after
26 | revision control. Things were a lot different, and all you had to learn in order
27 | to use revision control were:
28 | - Some simple vocabulary.
29 | - An easy to use tool.
30 | - A new way of looking at things.
31 |
32 | This is the central premise of this book: you don't need to understand technical
33 | jargon or complex test methodologies to realize huge gains in the quality of
34 | your software. Some simple vocabulary, new tools and new ways of looking at
35 | things are all you need.
36 |
37 | > All code/documentation examples in this book are public domain. For more
38 | > information see the [License](./License.html)
39 |
40 | [2]: https://github.com/vitiral/simple-quality/issues
41 | [3]: https://www.google.com/search?q=gnu+gpl+v3&ie=utf-8&oe=utf-8
42 | [4]: https://github.com/vitiral
43 |
44 |
45 | ## Why This Book Exists
46 | There is a lack of good documentation unifying and extending quality best
47 | practices. While there have been several advancements made in how to develop
48 | quality software, they have largely been piecemeal and lacked the tools to
49 | fit them all together. Several of the recent advancements include:
50 | - better revision control tools and best practices
51 | - new emphasis on unit tests as part of the development process
52 | - linters and auto-formatters to help projects have easy to read code
53 | - more emphasis on documentation, including inline developer documentation
54 | - the agile process and associated tools
55 |
56 | One of the things in common about all of these: developers tend to agree
57 | that their lives are **better** after using them. Programming is easier,
58 | more fun and more fulfilling. However, all of these lack the processes,
59 | tools and vocabulary necessary to bring them together into an organized whole.
60 |
61 | This book will give you the knowledge of how to unify and track all these quality
62 | best practices as well as give you an intro to artifact, the open-source documentation
63 | tool artifact. The tools presented in this book will not only allow you to write
64 | better software, but will help your day-to-day workflow in the same ways that
65 | good unit tests do.
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/book/src/StartingProject.md:
--------------------------------------------------------------------------------
1 | # Starting Your Project
2 |
3 | The primary teaching method that this book will employ is "learning by doing".
4 | This is an approach that many developers are familiar with and is used in some
5 | of the most effective tutorials on software development.
6 |
7 | The project we will be implementing is the [flash card challenge][2] created
8 | by Open Hatch. There are several reasons this project was chosen:
9 | - It has a clear goal with targeted users.
10 | - It is simple to define and yet can be extremely broad.
11 | - The guide is written in python which largely reads like pseudo code.
12 | You should be able to follow along in any language.
13 |
14 | One of the best tutorials on C (in my opinion), [learn C the hard way][3] has
15 | this to say about itself:
16 |
17 | > [This tutorial] teaches real robust C coding and defensive programming
18 | > tactics on real hardware rather than abstract machines and pedantic theory.
19 | > The book emphasizes breaking your code on purpose, and in the process teaches
20 | > a plethora of important topics.
21 |
22 | There are three important aspects to the "Learn The Hard Way" method that
23 | this tutorial will use:
24 | 1. It is designed for absolute beginners: you should know the basics of a
25 | programming language and revision control, but that's all you need.
26 | 2. It focuses on teaching simple concepts and tools which deliver immediate
27 | real-world value.
28 | 3. It uses exercises as the primary teaching method. You must
29 | **actually do the excersies** if you want to understand how the tools and
30 | processes you are reading about are useful.
31 |
32 | ## Before we start
33 |
34 | Before we start, install the following tools:
35 | - [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
36 | - [artifact](https://github.com/vitiral/artifact/blob/master/docs/Installation.md)
37 |
38 | Now run the following:
39 | ```
40 | mkdir ~/learn-art # or whatever directory you want
41 | cd ~/learn-art
42 | git init
43 | art init
44 | ```
45 |
46 | This will set up your project as an artifact tutorial project and initialize
47 | git. It is your job to know how to use git as we progress through the
48 | tutorial. I recommend committing the files you have now, including the `.art/`
49 | directory that was created.
50 |
51 | > ##### Exercise 1:
52 | > Create a `README.md` file in this directory and take notes while you read the
53 | > [flash card challenge][2] webpage. Pay close attention to:
54 | > - what is the use case (how will this software be used)?
55 | > - what are the inputs/outputs of the program?
56 | >
57 | > Then write a paragraph answering the question "how would I develop
58 | > this application, knowing only what I know now?"
59 |
60 | [1]: https://github.com/vitiral/artifact
61 | [2]: http://wiki.openhatch.org/Flash_card_challenge
62 | [3]: https://learncodethehardway.org/c/
63 |
64 |
--------------------------------------------------------------------------------
/book/src/TODO.md:
--------------------------------------------------------------------------------
1 | # TODO
2 |
3 | The rest of these documents are not yet complete. Sorry for the inconvieneice!
4 |
5 |
--------------------------------------------------------------------------------
/book/src/WebUi.md:
--------------------------------------------------------------------------------
1 | # Artifact Web UI
2 |
3 | For an example web ui, see [artifact's own design docs][2]
4 |
5 | The artifact Web UI is intended to be simple and intuitive, however
6 | it can be helpful to have some context.
7 |
8 | For more information about artifact, see it's [homepage][1]
9 |
10 | [1]: https://github.com/vitiral/artifact
11 | [2]: http://vitiral.github.io/artifact/#artifacts/req-1
12 |
13 | ## Artifact Color
14 |
15 | An "artifact" is something with a name like "ART-name" where "ART" is
16 | one of:
17 | - `REQ`: a requirement
18 | - `SPC`: a design specification
19 | - `TST`: a test
20 |
21 | Artifacts can take on different colors representing:
22 | - green: artifact is completed and tested
23 | - blue: artifact is completed but not tested (or partially complete and tested)
24 | - yellow: artifact is somewhat complete/tested
25 | - red: artifact is not very complete or tested
26 |
27 | ## List View
28 |
29 | The base view is the List View. It contains a column selector at the top
30 | left, a search bar at the top right, and a list of the searched artifacts
31 | below.
32 |
33 | ### Column Selector
34 | The column selector lets you select columns you wish to view. Displayed
35 | columns will be black and hidden columns will be grey.
36 |
37 | ### Search Bar
38 | The search bar allows you to search in the `name`, `parts`, `partof` and/or
39 | `text` fields for the value in the search bar. By default it searches for
40 | (case insensitive) text, but you can also enable regex searching with the
41 | button to the right of the search bar.
42 |
--------------------------------------------------------------------------------
/book/src/data/artifact-thumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/book/src/data/artifact-thumb.png
--------------------------------------------------------------------------------
/book/src/data/attribution/Attribution.md:
--------------------------------------------------------------------------------
1 | # Attribution for files in this folder
2 | - [b0rk-design-documents.jpg-large](https://twitter.com/b0rk/status/833419052194357248): twitter @b0rk
3 |
--------------------------------------------------------------------------------
/book/src/data/attribution/b0rk-design-documents.jpg-large:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/book/src/data/attribution/b0rk-design-documents.jpg-large
--------------------------------------------------------------------------------
/book/src/data/example-hello.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/book/src/data/example-hello.png
--------------------------------------------------------------------------------
/book/src/data/quickstart/images.xcf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/book/src/data/quickstart/images.xcf
--------------------------------------------------------------------------------
/book/src/data/quickstart/text-REQ-purpose.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/book/src/data/quickstart/text-REQ-purpose.png
--------------------------------------------------------------------------------
/book/src/data/quickstart/text-req-parts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/book/src/data/quickstart/text-req-parts.png
--------------------------------------------------------------------------------
/book/src/data/quickstart/web-create-btn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/book/src/data/quickstart/web-create-btn.png
--------------------------------------------------------------------------------
/book/src/data/quickstart/web-create.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/book/src/data/quickstart/web-create.png
--------------------------------------------------------------------------------
/book/src/data/quickstart/web-edit-btn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/book/src/data/quickstart/web-edit-btn.png
--------------------------------------------------------------------------------
/book/src/data/quickstart/web-edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/book/src/data/quickstart/web-edit.png
--------------------------------------------------------------------------------
/book/src/data/quickstart/web-implemented-link.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/book/src/data/quickstart/web-implemented-link.png
--------------------------------------------------------------------------------
/book/src/data/quickstart/web-save-btn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/book/src/data/quickstart/web-save-btn.png
--------------------------------------------------------------------------------
/book/src/data/quickstart/web-select.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/book/src/data/quickstart/web-select.png
--------------------------------------------------------------------------------
/book/src/data/quickstart/web-source-code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/book/src/data/quickstart/web-source-code.png
--------------------------------------------------------------------------------
/book/src/data/quickstart/web-spc-world-done.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/book/src/data/quickstart/web-spc-world-done.png
--------------------------------------------------------------------------------
/book/src/data/web-ui.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/book/src/data/web-ui.png
--------------------------------------------------------------------------------
/book/src/examples/part1/artifact-frontend.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/book/src/examples/part1/artifact-frontend.wasm
--------------------------------------------------------------------------------
/book/src/examples/part1/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Artifacts
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/book/src/examples/part1/initial.json:
--------------------------------------------------------------------------------
1 | {"project":{"paths":{"base":"/home/garrett/tmp/learn-art","code_paths":[],"exclude_code_paths":[],"artifact_paths":["/home/garrett/tmp/learn-art/design"],"exclude_artifact_paths":[]},"code_impls":{},"artifacts":{"REQ-purpose":{"id":"DoWdPsuX4839k2qxuZTMvA","name":"REQ-purpose","file":"/home/garrett/tmp/learn-art/design/purpose.md","partof":[],"parts":["SPC-cli","SPC-format","SPC-report"],"completed":{"spc":0.0,"tst":0.0},"text":"Write a flash card quizzer from scratch and learn about\nquality best practices while doing so.\n\nThe example tutorial can be found here:\n http://wiki.openhatch.org/Flash_card_challenge\n\nIt should be easy for users to input questions to the\nquizzer in a simple and open format. Additionally, the\nquizzer should use effective memorization techniques.\nSome possible ideas include:\n- asking items in a random order\n- telling the correct answer after the user answers incorrectly\n- asking items more often if they were answered incorrectly\n- allowing users to configure time limits, so they can\n compare results between quizzes.\n","impl_":{"type":"NotImpl"},"subnames":[]},"SPC-cli":{"id":"dbuUzJ9Wq49iD2zxFn9NpA","name":"SPC-cli","file":"/home/garrett/tmp/learn-art/design/purpose.md","partof":["REQ-purpose"],"parts":[],"completed":{"spc":0.0,"tst":0.0},"text":"\nThe minimum viable product shall be a command line utility\nthat is given the path to one or more question files as\narguments\n\nAdditional arguments will include:\n- `-t`: specify the time allowed for each question\n- `-T`: specify the total time allowed for the whole quiz\n- `-r NUM`: repeat questions only a certain number of times.\n By default there is no limit\n\nThe program will ask one question at a time, recording how\nmany answers the user got correct/incorrect and weighting\nfuture questions accordingly.\n\nWhen the program is complete it will report:\n- time taken, broken up by whole quiz and each question\n- the user's score\n","impl_":{"type":"NotImpl"},"subnames":[]},"SPC-format":{"id":"VM5AuyTYowZV6azM2wSdgA","name":"SPC-format","file":"/home/garrett/tmp/learn-art/design/purpose.md","partof":["REQ-purpose"],"parts":[],"completed":{"spc":0.0,"tst":0.0},"text":"The user shall be able to easily configure the quiz\nquestions through a simple csv format consisting of two\ncolumns: the question and the answer.\n","impl_":{"type":"NotImpl"},"subnames":[]},"SPC-report":{"id":"dhK_a1g7CMdYnKbRzVCwaw","name":"SPC-report","file":"/home/garrett/tmp/learn-art/design/purpose.md","partof":["REQ-purpose"],"parts":[],"completed":{"spc":0.0,"tst":0.0},"text":"When the program is complete a report shall be printed with:\n- time taken, broken up by whole quiz and each question\n- the user's total score\n- questions ranked by ones the user had the most difficulty\n","impl_":{"type":"NotImpl"},"subnames":[]}}},"web_type":"Static"}
--------------------------------------------------------------------------------
/book/src/examples/part2/artifact-frontend.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/book/src/examples/part2/artifact-frontend.wasm
--------------------------------------------------------------------------------
/book/src/examples/part2/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Artifacts
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/book/src/logo/logo-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/book/src/logo/logo-logo.png
--------------------------------------------------------------------------------
/book/src/logo/logo-medium.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/book/src/logo/logo-medium.png
--------------------------------------------------------------------------------
/book/src/logo/logo-small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/book/src/logo/logo-small.png
--------------------------------------------------------------------------------
/book/src/logo/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/book/src/logo/logo.png
--------------------------------------------------------------------------------
/ci/before_deploy.ps1:
--------------------------------------------------------------------------------
1 | # This script takes care of packaging the build artifacts that will go in the
2 | # release zipfile
3 |
4 | $SRC_DIR = $PWD.Path
5 | $STAGE = [System.Guid]::NewGuid().ToString()
6 |
7 | Set-Location $ENV:Temp
8 | New-Item -Type Directory -Name $STAGE
9 | Set-Location $STAGE
10 |
11 | $ZIP = "$SRC_DIR\$($Env:CRATE_NAME)-$($Env:APPVEYOR_REPO_TAG_NAME)-$($Env:TARGET).zip"
12 |
13 | # TODO Update this to package the right artifacts
14 | Copy-Item "$SRC_DIR\target\$($Env:TARGET)\release\hello.exe" '.\'
15 |
16 | 7z a "$ZIP" *
17 |
18 | Push-AppveyorArtifact "$ZIP"
19 |
20 | Remove-Item *.* -Force
21 | Set-Location ..
22 | Remove-Item $STAGE
23 | Set-Location $SRC_DIR
24 |
--------------------------------------------------------------------------------
/ci/before_deploy.sh:
--------------------------------------------------------------------------------
1 | # This script takes care of building your crate and packaging it for release
2 |
3 | set -ex
4 |
5 | main() {
6 | local src=$(pwd) \
7 | stage=
8 |
9 | case $TRAVIS_OS_NAME in
10 | linux)
11 | stage=$(mktemp -d)
12 | ;;
13 | osx)
14 | stage=$(mktemp -d -t tmp)
15 | ;;
16 | esac
17 |
18 | test -f Cargo.lock || cargo generate-lockfile
19 |
20 | # $BTOOL rustc --bin art --target $TARGET --release -- -C lto
21 | $BTOOL build -p artifact-app --target $TARGET --release
22 |
23 | cp target/$TARGET/release/art $stage/
24 |
25 | cd $stage
26 | tar czf $src/${RELEASE_NAME}.tar.gz *
27 | cd $src
28 | ls -al
29 |
30 | rm -rf $stage
31 | }
32 |
33 | main
34 |
--------------------------------------------------------------------------------
/ci/data/artifact-thumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/ci/data/artifact-thumb.png
--------------------------------------------------------------------------------
/ci/data/attribution/Attribution.md:
--------------------------------------------------------------------------------
1 | # Attribution for files in this folder
2 | - [b0rk-design-documents.jpg-large](https://twitter.com/b0rk/status/833419052194357248): twitter @b0rk
3 |
--------------------------------------------------------------------------------
/ci/data/attribution/b0rk-design-documents.jpg-large:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/ci/data/attribution/b0rk-design-documents.jpg-large
--------------------------------------------------------------------------------
/ci/data/logo/logo-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/ci/data/logo/logo-logo.png
--------------------------------------------------------------------------------
/ci/data/logo/logo-medium.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/ci/data/logo/logo-medium.png
--------------------------------------------------------------------------------
/ci/data/logo/logo-small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/ci/data/logo/logo-small.png
--------------------------------------------------------------------------------
/ci/data/logo/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/ci/data/logo/logo.png
--------------------------------------------------------------------------------
/ci/install.sh:
--------------------------------------------------------------------------------
1 | set -ex
2 |
3 | install_cross() {
4 | local target=
5 | if [ $TRAVIS_OS_NAME = linux ]; then
6 | target=x86_64-unknown-linux-musl
7 | sort=sort
8 | else
9 | target=x86_64-apple-darwin
10 | sort=gsort # for `sort --sort-version`, from brew's coreutils.
11 | fi
12 |
13 | # Builds for iOS are done on OSX, but require the specific target to be
14 | # installed.
15 | case $TARGET in
16 | aarch64-apple-ios)
17 | rustup target install aarch64-apple-ios
18 | ;;
19 | armv7-apple-ios)
20 | rustup target install armv7-apple-ios
21 | ;;
22 | armv7s-apple-ios)
23 | rustup target install armv7s-apple-ios
24 | ;;
25 | i386-apple-ios)
26 | rustup target install i386-apple-ios
27 | ;;
28 | x86_64-apple-ios)
29 | rustup target install x86_64-apple-ios
30 | ;;
31 | esac
32 |
33 | # This fetches latest stable release
34 | local tag=$(git ls-remote --tags --refs --exit-code https://github.com/japaric/cross \
35 | | cut -d/ -f3 \
36 | | grep -E '^v[0.1.0-9.]+$' \
37 | | $sort --version-sort \
38 | | tail -n1)
39 | curl -LSfs https://japaric.github.io/trust/install.sh | \
40 | sh -s -- \
41 | --force \
42 | --git japaric/cross \
43 | --tag $tag \
44 | --target $target
45 | }
46 |
47 | main() {
48 | # install_cross
49 |
50 | # TODO: remove this
51 | # give windows a place to put the book
52 | mkdir -p ./book/out/book
53 |
54 | cargo install cargo-web --debug || echo "cargo-web already installed"
55 | cargo install mdbook --debug || echo "mdbook already installed"
56 | # mkdir -p target/deps
57 |
58 | # cp `which cargo-web` target/deps
59 | # cp `which mdbook` target/deps
60 | # ls -al target/deps
61 | }
62 |
63 | main
64 |
--------------------------------------------------------------------------------
/ci/script.sh:
--------------------------------------------------------------------------------
1 | # This script takes care of testing your crate
2 |
3 | set -ex
4 |
5 | main() {
6 | # must be done first
7 | cargo-web deploy -p artifact-frontend --release --target=wasm32-unknown-unknown
8 | $BTOOL build -p artifact-app --target $TARGET
9 |
10 | if [ ! -z $DISABLE_TESTS ]; then
11 | return
12 | fi
13 |
14 | $BTOOL test -p artifact-app --target $TARGET
15 |
16 | $BTOOL run -p artifact-app --target $TARGET -- help
17 | }
18 |
19 | # we don't run the "test phase" when doing deploys
20 | if [ -z $TRAVIS_TAG ]; then
21 | main
22 | fi
23 |
--------------------------------------------------------------------------------
/design/cli.md:
--------------------------------------------------------------------------------
1 | # SPC-cli
2 | partof: REQ-purpose
3 | ###
4 |
5 | The CLI is the primary developer interatction with artifact, alongside the Web
6 | UI for visualizing the artifacts. The main goal of the CLI is to provide the
7 | tools that every developer is used to in a typical development tool. This
8 | includes:
9 |
10 |
11 | - [[.init]]: Initialize a project for using artifact. This is pretty basic, just need
12 | a `.art` folder with a `settings.toml` and an initial `design/` folder.
13 | - [[.check]]: checking for errors AND warnings with a return code if there is an error.
14 | - If there are only warnings the return code == 2. Otherwise it == 1.
15 | - [[.fmt]]: auto format the project.
16 | - `--type` flag to change the filetype.
17 | - [[SPC-cli-ls]]: listing/searching for artifacts, see the full specification.
18 | - [[.serve]]: the command to start the web backend.
19 |
20 |
21 | All subcommands should include the following flags:
22 | - `-v / --verbose` for setting the logging verbosity.
23 | - `--work-dir` for setting the working directory to run the command out of.
24 |
25 |
26 | # SPC-cli-ls
27 | The `art ls` command shall be used to list information about the artifacts in a
28 | project.
29 |
30 | `ls` is the primary window into a user's artifacts, creating a simple interface
31 | to glimpse large amounts of information.
32 |
33 | ## [[.args]]: Arguments
34 | `art ls` with no commands will simply print all artifacts with standard
35 | settings, each on a single line.
36 |
37 | The args are as follows:
38 | - `SEARCH str`: positional argument detailing which artifacts to display
39 | By default, this will be interpreted as an Artifact Name and can therefore
40 | only display one artifact. However, if pattern searching is selected, it
41 | will be interpreted as a rust regexp
42 | - `display`: flags that control what information will be displayed
43 | - `pattern`: searh SEARCH with a regex pattern. The flag specifies which fields
44 | should be searched.
45 | - `completed/tested`: flags which control what percentage completed/tested to
46 | display
47 | - [[.long]]: the `-l` flag prints the artifact in "long" form. Without it it
48 | is printed in [[.table]] form.
49 |
50 | ## [[.color]]: Color
51 | In order to make viewing of information via cmdline easier, artifact **shall**
52 | colorize it's output to make it clear which items are done or not done or in
53 | error.
54 |
55 | The following are the general rules:
56 | - Names that are complete will be `green`.
57 | - Names that are almost complete will be `blue`.
58 | - Names that are somewhat complete will be `yellow`.
59 | - Names that are very litle or not complete will be `red`.
60 | - Names that are in ERROR will be `bold red`.
61 |
62 | For [[.color_spc]], the levels are:
63 | - `( 100%, 70%, 40%, 0%)`: percentage spc
64 | - `( 3, 2, 1, 0)`: points
65 | - `(green, blue, yellow, red)`: colors
66 |
67 | For [[.color_tst]], the levels are:
68 | - `( 100%, 50%, 0%)`: percentage tst
69 | - `( 2, 1, 0)`: points
70 | - `(green, yellow, red)`: colors for tst
71 |
72 | For [[.color_name]] you add the two points together:
73 | - 5: Name is Green
74 | - 3-4: name is blue
75 | - 1-2: name is yellow
76 | - 0: name is red
--------------------------------------------------------------------------------
/design/data/cache.md:
--------------------------------------------------------------------------------
1 | # SPC-read-cache
2 | > This specification only exists to improve performance
3 |
4 | Significant speed gains can be made by caching artifact data into a local
5 | SQLite database in `.art/db.sql`. For linux specifically (and probably MacOS,
6 | don't know about windows) you can get the timestamp when any file was modified.
7 |
8 | - If we only parsed files where the timestamp changed we could speed things up
9 | significantly for just querying their results from an sql database. This is
10 | especially true for files that don't have *any* links.
--------------------------------------------------------------------------------
/design/data/family.md:
--------------------------------------------------------------------------------
1 | # SPC-family
2 | partof: REQ-data
3 | ###
4 | An artifact (name) has the following "family" defined:
5 |
6 | ```dot
7 | digraph G {
8 | subgraph cluster_allowed {
9 | label=<allowed partof>;
10 | REQ -> SPC -> TST;
11 | REQ -> TST;
12 |
13 | REQ -> REQ;
14 | SPC -> SPC;
15 | TST -> TST;
16 | }
17 |
18 | subgraph cluster_relationship {
19 | label=<auto family>;
20 | "REQ-root"
21 | -> {"REQ-root-child" [color=blue]}
22 | [label="is parent of"; color=blue; fontcolor=blue];
23 | "REQ-root" -> "SPC-root" [label="is auto-partof"];
24 | "SPC-root"
25 | -> {"SPC-root-child" [color=blue]}
26 | [label="is parent of"; color=blue; fontcolor=blue];
27 | "SPC-root" -> "TST-root" [label="is auto-partof"];
28 | }
29 | }
30 | ```
31 |
32 | ## Allowed Partof
33 | The first graph shows what relationships are "allowed". It specifies that:
34 | - `REQ` can be `partof` any type
35 | - `SPC` can be `partof` `SPC` and `TST`
36 | - `TST` can only be `partof` itself.
37 |
38 | In essense:
39 | - You can always create "subtypes", i.e. a more specific requirement
40 | - You can create a specification that is "partof" a requirement. This makes
41 | sense as you want to define your specifications based on your requirements.
42 | - You can create a test that is "partof" a specification OR a requirement.
43 | For example, white box testing will be based on a specification whereas
44 | blackbox ("requirements based") testing will be based on a requirement.
45 |
46 | ## Lints
47 | Lints are required to make sure the above is upheld
48 |
49 | - [[.lint_partof_exists]]: Make sure any partof references actually exist.
50 | - [[.lint_types]]: Make sure that `partof` links are only made between valid types.
51 |
52 | ## [[.auto]]: Auto Relationships
53 | The second graph shows the "automatic relationships" of nodes to their
54 | parents.
55 |
56 | - A node is automatically a `partof` both its parent and it's auto-partof.
57 | - Artifacts that have only one element are "root" (i.e. REQ-root, REQ-foo, SPC-foo)
58 | - Any artifact that is *not* root has a single parent, which it will automatically
59 | be a "partof". That parent **must** be defined by the user or it is a hard error
60 | - SPC and TST artifacts have auto-partof elements of the higher-order type (see
61 | [[SPC-name]]. This element is **not required** to exist, but if it does
62 | they will be linked automatically.
63 |
64 | A node can always be partof another node of the same type. In addition, the following type links are allowed
65 |
66 | ```dot
67 |
68 | ```
69 |
70 |
71 | # SPC-read-family
72 | The method of determining family is fairly straightforward, as is
73 | detailed in the graph below:
74 |
75 | ```dot
76 | digraph G {
77 | [[.parent]] -> { "if" [label="if elem-len > 1"; shape=diamond] };
78 | "if" -> "return None" [label = "no"];
79 | "if" -> {"clone raw string" [
80 | shape=box;
81 | ]} -> {"pop last element and create new Name" [
82 | shape=box;
83 | ]} -> "return new name";
84 |
85 | [[.auto_partof]] -> { if_req [label="type is REQ"; shape=diamond] };
86 | if_req -> "return None" [label="yes"];
87 | if_req -> {"get higher-order type" [
88 | shape=box;
89 | ]} -> {"clone raw name" [
90 | shape=box;
91 | ]} -> {"swap type with higher-order one" [
92 | shape=box;
93 | ]} -> "return new Name";
94 | }
95 | ```
96 |
97 | # [[.auto]]
98 | Once family is created and the artifacts are loaded, the artifacts have
99 | to be automatically linked to their parent+auto_partof. This is easy
100 | to determine given the artifacts that exist.
101 |
102 | Note: make sure to ONLY link to artifacts that exists!
103 |
104 | # [[.deauto]]
105 | In order to reserialize the artifacts, their "auto" partof has to be unlinked
106 |
--------------------------------------------------------------------------------
/design/data/implemented.md:
--------------------------------------------------------------------------------
1 | # SPC-impl
2 | partof: REQ-data
3 | ###
4 | Implementing artifacts is fairly straight forward:
5 | - [[.done]]: the artifact can define itself as done. If it does this, it must
6 | not have any subnames and must not be implemented (linked) in source.
7 | - [[.subnames]]: subnames can be defined in the `text` field of the artifact
8 | (see the beginning of this line for an example!)
9 | - [[SPC-read-impl]]: source code can link to either the artifact itself or one
10 | of its subnames through `#ART-name` or `#ART-name.sub` respectively.
11 | -
12 |
13 |
14 | # SPC-read-impl
15 | partof: SPC-impl
16 | ###
17 | ## Loading source code (implementation) links
18 |
19 | ### [[.load]]: Loading Locations
20 | The process for loading implementation locations is fairly straightforward:
21 | - Define the regular expression of valid names. Valid names inclue:
22 | - `SRC` and `TST` types ONLY.
23 | - Any valid postfix name (i.e. `SPC-foo-bar-baz_bob`)
24 | - (optional) a sub-name specified by a period (i.e. `SPC-foo.sub_impl`).
25 | - Walk the `code_paths`, iterating over each line for the regex and pulling
26 | out any `Name` or `SubName` locations.
27 |
28 | This results in two maps for each file:
29 | - `Name => CodeLoc`
30 | - `SubName => CodeLoc`
31 |
32 | ## Lints
33 | All lints related to source code are only WARNINGS
34 |
35 | - [[.lint_done]]: an artifact with its `done` field set is also linked
36 | in code.
37 | - [[.lint_exists]]: the artifact name does not exists but it does not specify the
38 | linked
39 | - [[.lint_subname_exists]]: the artifact name exists but the artifact does not specify
40 | the linked subname.
41 |
42 | ### [[.join]]: Joining Locations
43 | The `Name` and `SubName` maps from each file are joined into two large maps
44 | respectively (with any collisions put in the linting vectors which are also
45 | joined).
46 |
47 | We must then construct a map of `Name => Implementation` in order for later
48 | steps to construct the full `Artifact` object. We do this by:
49 | - Constructing a map of `Name => Map`, where `Name` is the
50 | prefix/name of the underlying `SubName`s.
51 | - Building the `Name => Implementation` map by:
52 | - Draining the `Name => CodeLoc` map and inserting `Implementation` objects.
53 | - Draining the just created `Name => Map` and either
54 | modifying or inserting `Implementation` objects.
55 |
56 | > Note: we do not worry about whether such `Name` or `SubName`s actually exist.
57 | > That is the job of a later linting step.
--------------------------------------------------------------------------------
/design/data/modify.md:
--------------------------------------------------------------------------------
1 | # SPC-modify
2 | partof: REQ-data
3 | ###
4 | The modify operation takes in only the `project_path` and an array of
5 | `ArtifactOp` (see [[SPC-structs]]).
6 |
7 | From there, the control flow and high level architecture are
8 | as follows:
9 |
10 | ```dot
11 | digraph G {
12 | node [
13 | shape=box;
14 | ];
15 |
16 | edge [weight=10];
17 |
18 | {start [shape=oval]}
19 | -> {read1 [label="read(project_path)" shape=cylinder]}
20 | -> {if_compare_id [
21 | label="compare ids: orig w/ load?"]}
22 | -> {update [
23 | label="perform updates and\n create new project"]}
24 | -> {backup [label="backup orig files" shape=cylinder]}
25 | -> {save [label="save new project to disk" shape=cylinder]}
26 | -> {read2 [label="read(project_path)" shape=cylinder]}
27 | -> {clean [label="clean (delete)\nbackup files" shape=cylinder]}
28 | -> {return [label="return new project" shape=oval]};
29 |
30 | // error paths
31 | read1 -> {read1_err [label="ERR: db\ncorrupted by user"
32 | shape=oval fontcolor=red]}
33 | [label=err fontcolor=red];
34 | if_compare_id -> {compare_err [label="ERR: not\nupdated"
35 | shape=oval fontcolor=red]}
36 | [label=err fontcolor=red];
37 | update -> {update_err [
38 | label="ERR: return lints" shape=oval fontcolor=red]}
39 | [label=err fontcolor=red];
40 | read2 -> {restore [label="restore backups" fontcolor=red shape=cylinder]}
41 | [label=err fontcolor=red];
42 | restore -> {read2_err [label="ERR: internal error"
43 | fontcolor=red shape=oval]};
44 |
45 | {rank=same {read1, read1_err}};
46 | {rank=same {if_compare_id, compare_err}};
47 | {rank=same {update, update_err}};
48 | {rank=same {read2, restore}};
49 | {rank=same {clean, read2_err}};
50 | }
51 | ```
52 |
53 | Overall this is *relatively simple*. The only new stuff is:
54 | - [[.compare_id]]: compare the `orig_hash` of the requested changes to the hashes
55 | of the loaded values. If they don't match it means that the person requesting changes
56 | did so *with an out of date version of the artifact*. This is a no-no!
57 | - [[SPC-modify-update]]: update the loaded project with the requested changes.
58 | - [[.backup]]: backup files by moving them to (for example) `path/to/file.md` ->
59 | `path/to/file.md.art_bk`. Restoring is just moving them back to their
60 | original place. Cleaning is just deleting them.
61 |
62 | > This requires a LOT of filesystem operations, some of them seemingly
63 | > redundant. However, I believe all of them are justified. Theoretically we
64 | > could remove the "checking" one at the very end, but I prefer to keep it for
65 | > a *very* long time.
66 |
67 |
68 | # SPC-modify-update
69 | We are given a `Vec` and loaded `Project` and we want to perform
70 | the requested updates on the project, ensuring there are no new errors.
71 |
72 | The basic process is:
73 | - Ensure that there are no conflicts in the `ArtifactOp`'s original `HashIm`s
74 | or new `HashIm`s. For instance, ensure that they aren't trying to delete
75 | and create the same `HashIm`.
76 | - We _already have_ the project as a `Map`.
77 | - Note: we don't care in the next phase about whether `Name`s colide. We are
78 | hashed by `HashIm`, NOT by `Name`!
79 | - We simply perform the operations requested -- blindly changing the artifacts.
80 | - `ArtifactOp::Create` is inserting the `HashIm` into the map with the new
81 | artifact.
82 | - `ArtifactOp::Update` is removing the original `HashIm` and inserting the
83 | new one.
84 | - `ArtifactOp::Delete` is deleting the requested `HashIm`
85 | - We then rebuild the project and do all _error level_ lints.
--------------------------------------------------------------------------------
/design/data/name.md:
--------------------------------------------------------------------------------
1 | # SPC-name
2 | partof: REQ-data
3 | ###
4 | The following attributes must be definable by the user:
5 | - `name`: the artifact name must be given in the form `ART-name`, where `ART`
6 | is used to determine the type (see below).
7 | - `done`: if any string is given, the artifact is "defined as done", meaning it
8 | is 100% complete for both implementation and test.
9 | - `partof`: a list (or compressed syntax) of artifact names which this artifact
10 | is a "partof". Valid and automatic links are defined in [[SPC-family]].
11 | - `text`: the description of the artifact which can contain "soft links" to
12 | other artifacts as well as to code implementations.
13 |
14 | ## [[.type]]: Artifact Type
15 | The type of an artifact is simply its prefix, which must be one of:
16 | - `REQ`: requirement
17 | - `SPC`: design specification
18 | - `TST`: test specification
19 |
20 | The order of precedence is:
21 | - `REQ` is "higher order" than `SPC` or `TST`
22 | - `SPC` is "higher order" than `TST`
23 |
24 | ```dot
25 | digraph G {
26 | graph [rankdir=LR; splines=ortho]
27 | REQ -> SPC -> TST
28 | }
29 | ```
30 |
31 | See [[SPC-family]] for how these are related.
32 |
33 | ## [[.attrs]]: Attributes/Getters
34 |
35 | The `Name` type shall be the exported "key" of artifacts. Internally it is
36 | reference counted, externally it exposes itself with the following methods:
37 | - `Name.ty`: get the name's type
38 | - `Name.from_str(s)`: create or automatically load the name.
39 | - `Name.as_str()`: get the string representation of the name. This must always
40 | be the same string as the user gave.
41 | - `Name.key_str()`: get the name's "key" representation
42 |
43 | Internally the name is an atomically reference counted pointer (`Arc`), meaning
44 | that cloning it is extremely cheap.
--------------------------------------------------------------------------------
/design/data/structs.md:
--------------------------------------------------------------------------------
1 | # SPC-structs
2 | partof: REQ-data
3 | ###
4 | This requirement details the high level `struct`s and `enum`s that must be
5 | exported by this module, as well as their features.
6 |
7 | In many cases this would be a *specification*, but since this is a library,
8 | the exported structs and their characteristics practically ARE the
9 | requirement.
10 |
11 | It's critical that the valid types are defined at a high level, since
12 | they determine how everything works together.
13 |
14 | ### Exported Types
15 | These are the types that make up the exported "product" of this library. The
16 | major type is the **Artifact** and its associated **Name**.
17 |
18 | TODO: the original graph broke with the update to newer graphiz. Rewrite with the format below.
19 |
20 | ```dot
21 | digraph G {
22 | node [shape=record];
23 | Animal [
24 | label =
25 | "{Animal
26 | \l|+ name : string
27 | \l+ age : int
28 | \l|+ die() : void
29 | \l}"
30 | ]
31 | }
32 | ```
33 |
34 | ### Raw Data Types
35 | These types define the "raw data" format of artifact and are only used
36 | for de/serializing.
37 |
38 | #### [[.artifact_raw]]: ArtifactRaw: (stored with key of `Name`)
39 | - done: `Option[String]`
40 | - partof: `Option[HashSet[Name]]`
41 | - text: `Option[TextRaw]`
42 |
43 | #### [[.text_raw]]: TextRaw: just a newtype with some serialization guarantees
44 | to make it prettier and ensure serialization is possible between
45 | all of the supported formats.
46 |
47 | ### Intermediate (`Im`) Data Types
48 | Intermediate "stripped down" forms of the artifact. These types are used for:
49 | - linting after reading the project
50 | - inteacting with the CRUD interface.
51 |
52 | #### [[.artifact_op]]: ArtifactOp:
53 | - `Create(ArtifactIm)`: create an artifact, it must not already exist.
54 | - `Update(HashIm, ArtifactIm)`: update the artifact with the specified hash.
55 | - `Delete(HashIm)`: delete the artifact with the specifed hash.
56 |
57 | This is the "operation" command used by [[SPC-modify]] for modifying artifacts.
58 | `Read` is ommitted as it is covered by [[SPC-read]].
59 |
60 | #### [[.artifact_im]]: ArtifactIm:
61 | - name: `Name`
62 | - file: `PathAbs`
63 | - partof: `Set` (auto-partofs are stripped)
64 | - done: `Option`
65 | - text: `String`
66 |
67 | The `ArtifactIm` is used to create a unique 128 bit hash of the artifacts and
68 | for specifying *what* should be updated when an update is requested.
69 |
70 | This is also the primary type used when linting.
71 |
72 | #### HashIm:
73 | This is simply a 128 bit SipHash created by the [`siphasher` crate][1].
74 |
75 | [1]: https://doc.servo.org/siphasher/sip128/struct.Hash128.html
76 |
77 |
78 | ## Type Details
79 |
80 | **Artifact**: ([[.artifact]]) the artifact is the primary exported type. It contains:
81 | - `name`: the unique identifier of the artifact.
82 | - `file`: the file where the artifact is defined.
83 | - `partof` and `parts`: automatic and user-defined relationship to other
84 | artifacts where `B in A.partof` means that B is a "parent" of A.
85 | More details are in [[SPC-family]].
86 | - `completed`: the `spc` and `tst` completion ratios, detailing how much of
87 | the artifact's specification and test design has been implemented.
88 | - `text`: the user defined text in the markdown format.
89 | - `impl_`: how the artifact is implemented (if it is implemented at all). Can
90 | be `Done(str)`, `Code(ImplCode)` or `NotIMpl`.
91 | - `subnames`: a list of subnames defined in `text` using `{{.subname}}`
92 | except `[[]]` instead of `[[]]`. These can be linked in code to complete
93 | the artifact.
94 | - `orig_hash`: the original hash of the `ArtifactIm` this was created from.
95 |
96 | **Name**:
97 | - name is of the form `ART-name` where ART is one of {`REQ`, `SPC` or `TST`}
98 | - more details are in [[SPC-name]].
99 |
100 | **Impl**:
101 | - Defines how the artifact is implemented.
102 | - `Done`: can be "defined as done" through the `done` field in the
103 | `ArtifactRaw`.
104 | - `Code`: can be implemented in code, where source code just puts `#ART-name`
105 | anywhere to mark an artifact as implemented.
--------------------------------------------------------------------------------
/justfile:
--------------------------------------------------------------------------------
1 | build-frontend:
2 | cargo-web deploy -p artifact-frontend --release --target=wasm32-unknown-unknown
3 |
4 | check: build-frontend
5 | cargo check -p artifact-app -j$(( $(nproc) * 3))
6 |
7 | build: build-frontend
8 | cargo build -p artifact-app -j$(( $(nproc) * 3))
9 |
10 | build-release: build-frontend
11 | cargo build -p artifact-app --release -j$(( $(nproc) * 3))
12 |
13 | test: build-frontend
14 | cargo test -p artifact-app -j$(( $(nproc) * 3))
15 |
--------------------------------------------------------------------------------
/scripts/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/*
2 | __pycache__
3 |
--------------------------------------------------------------------------------
/scripts/db.dump:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vitiral/artifact/2b46103a2f8a4012b4f0555fbcf3cc151c93a6af/scripts/db.dump
--------------------------------------------------------------------------------
/scripts/interact.py:
--------------------------------------------------------------------------------
1 | """Interact with the artifact server.
2 |
3 | TODO: this is still a work in progress. We need:
4 | - an Artifact data type with from_dict and to_dict methods
5 | and an `__init__` that we can use for making artifacts
6 | - all methods should ONLY accept and return the Artifact
7 | data type
8 | - better command line interface for interacting with the API
9 |
10 | """
11 |
12 | from __future__ import print_function
13 |
14 | import argparse
15 | import code
16 | import pprint
17 |
18 | from py_helpers.json_rpc import JsonRpc
19 |
20 |
21 | class CrudApi(JsonRpc):
22 | """Class for interacting with the artifact CRUD server API."""
23 |
24 | def create_artifacts(self, params):
25 | """create a list of artifacts."""
26 | payload = {
27 | 'method': 'CreateArtifacts',
28 | 'params': params,
29 | }
30 | return self.put(self.address, json=payload)
31 |
32 | def read_artifacts(self, params=None):
33 | """read the artifacts in a list."""
34 | payload = {
35 | 'method': 'ReadArtifacts',
36 | 'params': params,
37 | }
38 | r = self.put(self.address, json=payload)
39 | r.raise_for_status()
40 | return r.json()
41 |
42 | def update_artifacts(self, params):
43 | """update the list of artifacts.
44 |
45 | Artifacts must already exist.
46 |
47 | """
48 | payload = {
49 | 'method': 'UpdateArtifacts',
50 | 'params': params,
51 | }
52 | return self.put(self.address, json=payload)
53 |
54 | def delete_artifacts(self, params):
55 | """delete the list of artifact ids."""
56 | payload = {
57 | 'method': 'DeleteArtifacts',
58 | 'params': params,
59 | }
60 | return self.put(self.address, json=payload)
61 |
62 |
63 | def parse_args(args=None):
64 | """parse cmdline arguments."""
65 | parser = argparse.ArgumentParser()
66 | parser.add_argument(
67 | 'address', nargs='?',
68 | default="http://127.0.0.1:5373", help='address of artifact server')
69 |
70 | parser.add_argument(
71 | '-i', '--interactive',
72 | help='open python shell to interact with the server',
73 | action='store_true')
74 |
75 | return parser.parse_args(args=args)
76 |
77 |
78 | def readline_setup(exports):
79 | """setup readline completion, if available.
80 |
81 | :param exports: the namespace to be used for completion
82 | :return: True on success
83 |
84 | """
85 | try:
86 | import readline
87 | except ImportError:
88 | # no completion for you.
89 | readline = None
90 | return False
91 | else:
92 | import rlcompleter
93 | readline.set_completer(
94 | rlcompleter.Completer(namespace=exports).complete)
95 | return True
96 |
97 |
98 | # pylint: disable=unused-variable
99 | def start_interactive(api):
100 | """start an interactive shell for the API.
101 |
102 | :param CrudApi api: the CrudApi session object.
103 |
104 | """
105 | # make pretty-printing easier
106 | pp = pprint.pprint
107 |
108 | create = api.create_artifacts
109 | read = api.read_artifacts
110 | update = api.update_artifacts
111 | delete = api.delete_artifacts
112 |
113 | local = locals()
114 | exports = globals().copy()
115 | exports.update(local)
116 |
117 | # completion for global and local namespace
118 | readline_setup(exports)
119 | # dir() will only show locals()
120 | code.interact(banner=__doc__, local=local)
121 |
122 |
123 | def main():
124 | """execute as a script."""
125 | args = parse_args()
126 | api = CrudApi(args.address)
127 | if args.interactive:
128 | start_interactive(api)
129 | else:
130 | raise NotImplementedError('sorry, the rest is not implemented, yet')
131 |
132 |
133 | if __name__ == '__main__':
134 | main()
135 |
--------------------------------------------------------------------------------
/scripts/lic_header.txt:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2017 Garrett Berg, vitiral@gmail.com
2 | *
3 | * Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be
6 | * copied, modified, or distributed except according to those terms.
7 | */
8 |
--------------------------------------------------------------------------------
/scripts/license.py:
--------------------------------------------------------------------------------
1 | import argparse
2 |
3 | SOURCE = 'source'
4 | OLD_HEADER = 'old_header'
5 | NEW_HEADER = 'new_header'
6 |
7 | parser = argparse.ArgumentParser()
8 | parser.add_argument(SOURCE)
9 | parser.add_argument(OLD_HEADER)
10 | parser.add_argument(NEW_HEADER)
11 |
12 | args = parser.parse_args()
13 |
14 | with open(args.source) as f:
15 | source = f.read()
16 |
17 | with open(args.old_header) as f:
18 | old_header = f.read()
19 |
20 | with open(args.new_header) as f:
21 | new_header = f.read()
22 |
23 | with open(args.source, 'w') as f:
24 | f.truncate(0)
25 | f.write(source.replace(old_header, new_header))
26 |
--------------------------------------------------------------------------------
/scripts/requirements.txt:
--------------------------------------------------------------------------------
1 | requests
2 | selenium
3 | pytest
4 | pylint
5 | docformatter
6 | autopep8
7 | toml
8 | aenum
9 |
--------------------------------------------------------------------------------