From 8bcbdcd3be0f024d3b7ef3035c0e04c00725594f Mon Sep 17 00:00:00 2001 From: h1alexbel Date: Mon, 24 Jun 2024 12:12:44 +0300 Subject: [PATCH 01/11] feat(#41): latex.rs --- .gitignore | 1 + cli/src/args.rs | 6 +++ server/resources/report.tex | 7 +++ server/src/lib.rs | 1 + server/src/report/latex.rs | 92 +++++++++++++++++++++++++++++++++++++ server/src/report/mod.rs | 25 ++++++++++ 6 files changed, 132 insertions(+) create mode 100644 server/resources/report.tex create mode 100644 server/src/report/latex.rs create mode 100644 server/src/report/mod.rs diff --git a/.gitignore b/.gitignore index e27a6dd4..0aa15dbd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /target +/out ### Rust template # Generated by Cargo # will have compiled files and executables diff --git a/cli/src/args.rs b/cli/src/args.rs index f318fc80..7d75ac36 100644 --- a/cli/src/args.rs +++ b/cli/src/args.rs @@ -25,6 +25,12 @@ use clap::Parser; // We should process the port argument and // pass it to the server on `start` command. // Start command should be added also with clap +// @todo #41:15min Add --report argument together with content type flags. +// Together with --report option let's add flags for XML, TeX, and Text +// reports. So user can generate report in many formats like this: --report +// --tex --html. +// @todo #41:45min Parse content type flag from stdin. Let's pick report generation +// function based on provided flags, such as: --xml, --tex, --txt. #[derive(Parser, Debug)] pub(crate) struct Args { /// The port to run diff --git a/server/resources/report.tex b/server/resources/report.tex new file mode 100644 index 00000000..b4df993b --- /dev/null +++ b/server/resources/report.tex @@ -0,0 +1,7 @@ +\usepackage{to-be-determined} +\documentclass[12pt]{article} +\begin{document} + +\section*{Fakehub report} +\tbd{History: TBD} +\end{document} diff --git a/server/src/lib.rs b/server/src/lib.rs index 5cf132ee..8cbe35ca 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -31,6 +31,7 @@ use crate::xml::storage::touch_storage; mod routes; mod xml; +pub mod report; #[derive(Default)] pub struct Server { diff --git a/server/src/report/latex.rs b/server/src/report/latex.rs new file mode 100644 index 00000000..61ef1978 --- /dev/null +++ b/server/src/report/latex.rs @@ -0,0 +1,92 @@ +// The MIT License (MIT) +// +// Copyright (c) 2024 Aliaksei Bialiauski +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +use std::fs; +use std::path::Path; + +/// +/// Read LaTeX template. +/// @todo #41:60min Add function for appending new content into the template. +/// We need to create new function that will append input into the template, +/// thus it will build a detailed report. +/// # Arguments +/// +/// * `path`: Template path +/// +/// returns: String +/// +/// # Examples +/// +/// ``` +/// use crate::server::report::latex::template; +/// let content = template(None); +/// print!("{content}") +/// ``` +pub fn template(path: Option<&str>) -> String { + return fs::read_to_string( + Path::new(path.unwrap_or("resources/report.tex")) + ).unwrap(); +} + +#[cfg(test)] +mod tests { + use std::fs::File; + use std::io::Write; + use anyhow::Result; + use tempdir::TempDir; + + use crate::report::latex::template; + + #[test] + fn returns_default_template() -> Result<()> { + let content = template(None); + let expected = r"\usepackage{to-be-determined} +\documentclass[12pt]{article} +\begin{document} + +\section*{Fakehub report} +\tbd{History: TBD} +\end{document} +"; + assert_eq!( + content, + expected, + "Template content '{content}' does not match with '{expected}'" + ); + Ok(()) + } + + #[test] + fn returns_custom_template() -> Result<()> { + let temp = TempDir::new("temp")?; + let path = &temp.path().join("custom.tex"); + let expected = "$This is custom template!$"; + let bytes = expected.to_string().into_bytes(); + File::create(path).unwrap().write_all(bytes.as_slice())?; + let content = template(path.to_str()); + assert_eq!( + content, + expected, + "Template content '{content} does not match with '{expected}'" + ); + Ok(()) + } +} diff --git a/server/src/report/mod.rs b/server/src/report/mod.rs new file mode 100644 index 00000000..d320dffa --- /dev/null +++ b/server/src/report/mod.rs @@ -0,0 +1,25 @@ +// The MIT License (MIT) +// +// Copyright (c) 2024 Aliaksei Bialiauski +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// @todo #41:45min Create similar to latex.rs functions for XML and TXT formats. +// Let's create similar to latex.rs functions for generating reports in XML and TXT. +// Don't forget to remove this puzzle. +pub mod latex; From 9bb4b246e7b03cff18e36d251f47a49b77aa4e6b Mon Sep 17 00:00:00 2001 From: h1alexbel Date: Mon, 24 Jun 2024 12:21:20 +0300 Subject: [PATCH 02/11] feat(#41): rustfmt --- .rustfmt.toml | 22 ++++++++++++++++++++++ server/src/lib.rs | 2 +- server/src/report/latex.rs | 28 ++++++++++++---------------- tests/home_test.rs | 0 4 files changed, 35 insertions(+), 17 deletions(-) create mode 100644 .rustfmt.toml create mode 100644 tests/home_test.rs diff --git a/.rustfmt.toml b/.rustfmt.toml new file mode 100644 index 00000000..917a45d4 --- /dev/null +++ b/.rustfmt.toml @@ -0,0 +1,22 @@ +# The MIT License (MIT) +# +# Copyright (c) 2024 Aliaksei Bialiauski +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +max_width = 90 diff --git a/server/src/lib.rs b/server/src/lib.rs index 8cbe35ca..10bcefd1 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -29,9 +29,9 @@ use tokio::net::TcpListener; use crate::routes::home; use crate::xml::storage::touch_storage; +pub mod report; mod routes; mod xml; -pub mod report; #[derive(Default)] pub struct Server { diff --git a/server/src/report/latex.rs b/server/src/report/latex.rs index 61ef1978..29b807b6 100644 --- a/server/src/report/latex.rs +++ b/server/src/report/latex.rs @@ -22,35 +22,33 @@ use std::fs; use std::path::Path; -/// /// Read LaTeX template. /// @todo #41:60min Add function for appending new content into the template. /// We need to create new function that will append input into the template, /// thus it will build a detailed report. -/// # Arguments -/// +/// # Arguments +/// /// * `path`: Template path -/// -/// returns: String -/// -/// # Examples -/// +/// +/// returns: String +/// +/// # Examples +/// /// ``` /// use crate::server::report::latex::template; /// let content = template(None); /// print!("{content}") /// ``` pub fn template(path: Option<&str>) -> String { - return fs::read_to_string( - Path::new(path.unwrap_or("resources/report.tex")) - ).unwrap(); + return fs::read_to_string(Path::new(path.unwrap_or("resources/report.tex"))) + .unwrap(); } #[cfg(test)] mod tests { + use anyhow::Result; use std::fs::File; use std::io::Write; - use anyhow::Result; use tempdir::TempDir; use crate::report::latex::template; @@ -67,8 +65,7 @@ mod tests { \end{document} "; assert_eq!( - content, - expected, + content, expected, "Template content '{content}' does not match with '{expected}'" ); Ok(()) @@ -83,8 +80,7 @@ mod tests { File::create(path).unwrap().write_all(bytes.as_slice())?; let content = template(path.to_str()); assert_eq!( - content, - expected, + content, expected, "Template content '{content} does not match with '{expected}'" ); Ok(()) diff --git a/tests/home_test.rs b/tests/home_test.rs new file mode 100644 index 00000000..e69de29b From fc971f6e78af8181e7dfb8b39b717a44a522083d Mon Sep 17 00:00:00 2001 From: h1alexbel Date: Mon, 24 Jun 2024 12:23:38 +0300 Subject: [PATCH 03/11] feat(#41): license off --- .github/workflows/license.yml | 52 ----------------------------------- 1 file changed, 52 deletions(-) delete mode 100644 .github/workflows/license.yml diff --git a/.github/workflows/license.yml b/.github/workflows/license.yml deleted file mode 100644 index 2dbdfb75..00000000 --- a/.github/workflows/license.yml +++ /dev/null @@ -1,52 +0,0 @@ -# The MIT License (MIT) -# -# Copyright (c) 2024 Aliaksei Bialiauski -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. ---- -name: license -on: - push: - pull_request: -jobs: - license: - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - run: | - set -e - find . -type f \( \ - -name "LICENSE.*" \ - -o -name "*.yml" \ - -o -name "*.xml" \ - -o -name "*.rs" \ - -o -name "*.toml" \) > files.txt - header="Copyright (c) 2024 Aliaksei Bialiauski" - failed="false" - while IFS= read -r file; do - if ! grep -q "$header" "$file"; then - failed="true" - echo "No license in: $file" - fi - done < files.txt - if [ "${failed}" == "true" ]; then - exit 1 - fi From 9cc3f5f9c7178185b2885168f8f4e032b6f8b21e Mon Sep 17 00:00:00 2001 From: h1alexbel Date: Mon, 24 Jun 2024 12:24:52 +0300 Subject: [PATCH 04/11] feat(#41): ignore tex --- .github/workflows/copyrights.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/copyrights.yml b/.github/workflows/copyrights.yml index 7c7fc004..5f0eff7c 100644 --- a/.github/workflows/copyrights.yml +++ b/.github/workflows/copyrights.yml @@ -30,3 +30,6 @@ jobs: steps: - uses: actions/checkout@v4 - uses: yegor256/copyrights-action@0.0.4 + with: + ignore: >- + server/resources/report.tex From 3a98a8838e32570e6c61afc677df374d9d2d39e9 Mon Sep 17 00:00:00 2001 From: h1alexbel Date: Mon, 24 Jun 2024 12:29:17 +0300 Subject: [PATCH 05/11] feat(#41): not intented --- tests/home_test.rs | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 tests/home_test.rs diff --git a/tests/home_test.rs b/tests/home_test.rs deleted file mode 100644 index e69de29b..00000000 From c67c5b803543a2356e78029222601b2c0cd1d217 Mon Sep 17 00:00:00 2001 From: h1alexbel Date: Mon, 24 Jun 2024 20:52:13 +0300 Subject: [PATCH 06/11] feat(#41): puzzle update --- cli/src/args.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/cli/src/args.rs b/cli/src/args.rs index 7d75ac36..44d6756d 100644 --- a/cli/src/args.rs +++ b/cli/src/args.rs @@ -25,12 +25,10 @@ use clap::Parser; // We should process the port argument and // pass it to the server on `start` command. // Start command should be added also with clap -// @todo #41:15min Add --report argument together with content type flags. -// Together with --report option let's add flags for XML, TeX, and Text -// reports. So user can generate report in many formats like this: --report -// --tex --html. -// @todo #41:45min Parse content type flag from stdin. Let's pick report generation -// function based on provided flags, such as: --xml, --tex, --txt. +// @todo #41:15min Add --report argument. +// Let's add --report option for generating reports in desired formats: +// We should support following formats: xml, tex, and txt. User should have +// ability to generate report in many formats as well: --report tex,xml,txt. #[derive(Parser, Debug)] pub(crate) struct Args { /// The port to run From ec9a9b0b165fba54e6c188628f7e12861275924d Mon Sep 17 00:00:00 2001 From: h1alexbel Date: Mon, 24 Jun 2024 20:53:07 +0300 Subject: [PATCH 07/11] feat(#41): multiple --- cli/src/args.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/src/args.rs b/cli/src/args.rs index 44d6756d..1a2297f9 100644 --- a/cli/src/args.rs +++ b/cli/src/args.rs @@ -28,7 +28,7 @@ use clap::Parser; // @todo #41:15min Add --report argument. // Let's add --report option for generating reports in desired formats: // We should support following formats: xml, tex, and txt. User should have -// ability to generate report in many formats as well: --report tex,xml,txt. +// ability to generate report in multiple formats as well: --report tex,xml,txt. #[derive(Parser, Debug)] pub(crate) struct Args { /// The port to run From 444c1538bd7886c708d569670fb29836b7a5ff40 Mon Sep 17 00:00:00 2001 From: h1alexbel Date: Mon, 24 Jun 2024 21:00:16 +0300 Subject: [PATCH 08/11] feat(#41): expect instaed of #unwrap --- server/src/report/latex.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/report/latex.rs b/server/src/report/latex.rs index 29b807b6..469e80df 100644 --- a/server/src/report/latex.rs +++ b/server/src/report/latex.rs @@ -41,7 +41,7 @@ use std::path::Path; /// ``` pub fn template(path: Option<&str>) -> String { return fs::read_to_string(Path::new(path.unwrap_or("resources/report.tex"))) - .unwrap(); + .expect("template should be read from"); } #[cfg(test)] From 9c67f5354d8f6a87be363c31e7fa6656c527753e Mon Sep 17 00:00:00 2001 From: h1alexbel Date: Tue, 25 Jun 2024 19:48:03 +0300 Subject: [PATCH 09/11] feat(#41): puzzle for extends with --- server/src/report/latex.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/server/src/report/latex.rs b/server/src/report/latex.rs index 469e80df..415982a5 100644 --- a/server/src/report/latex.rs +++ b/server/src/report/latex.rs @@ -41,7 +41,7 @@ use std::path::Path; /// ``` pub fn template(path: Option<&str>) -> String { return fs::read_to_string(Path::new(path.unwrap_or("resources/report.tex"))) - .expect("template should be read from"); + .unwrap_or_else(|_| panic!("the world is ending: {}", path.unwrap().to_owned())); } #[cfg(test)] @@ -54,6 +54,10 @@ mod tests { use crate::report::latex::template; #[test] + // @todo #41:60min Add support of @ExtendsWith from JUnit in order to pass expected as test parameter. + // We should use extensions in order to pass expected as parameters into + // test. If there is no crate with such functionality - let's develop and + // release one. fn returns_default_template() -> Result<()> { let content = template(None); let expected = r"\usepackage{to-be-determined} From f24892966975dfb8fbe7b3e703bc5f0d79e40798 Mon Sep 17 00:00:00 2001 From: h1alexbel Date: Tue, 25 Jun 2024 19:53:24 +0300 Subject: [PATCH 10/11] feat(#41): path is the default one --- server/src/report/latex.rs | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/server/src/report/latex.rs b/server/src/report/latex.rs index 415982a5..f21e11ab 100644 --- a/server/src/report/latex.rs +++ b/server/src/report/latex.rs @@ -36,20 +36,17 @@ use std::path::Path; /// /// ``` /// use crate::server::report::latex::template; -/// let content = template(None); +/// let content = template("resources/report.tex"); /// print!("{content}") /// ``` -pub fn template(path: Option<&str>) -> String { - return fs::read_to_string(Path::new(path.unwrap_or("resources/report.tex"))) - .unwrap_or_else(|_| panic!("the world is ending: {}", path.unwrap().to_owned())); +pub fn template(path: &str) -> String { + return fs::read_to_string(Path::new(path)) + .expect("template should be read from"); } #[cfg(test)] mod tests { use anyhow::Result; - use std::fs::File; - use std::io::Write; - use tempdir::TempDir; use crate::report::latex::template; @@ -58,8 +55,8 @@ mod tests { // We should use extensions in order to pass expected as parameters into // test. If there is no crate with such functionality - let's develop and // release one. - fn returns_default_template() -> Result<()> { - let content = template(None); + fn returns_template_content() -> Result<()> { + let content = template("resources/report.tex"); let expected = r"\usepackage{to-be-determined} \documentclass[12pt]{article} \begin{document} @@ -74,19 +71,4 @@ mod tests { ); Ok(()) } - - #[test] - fn returns_custom_template() -> Result<()> { - let temp = TempDir::new("temp")?; - let path = &temp.path().join("custom.tex"); - let expected = "$This is custom template!$"; - let bytes = expected.to_string().into_bytes(); - File::create(path).unwrap().write_all(bytes.as_slice())?; - let content = template(path.to_str()); - assert_eq!( - content, expected, - "Template content '{content} does not match with '{expected}'" - ); - Ok(()) - } } From fac468e8f8474d1fe59666632fb1275a9bc7693f Mon Sep 17 00:00:00 2001 From: h1alexbel Date: Tue, 25 Jun 2024 19:55:44 +0300 Subject: [PATCH 11/11] feat(#41): clean for fmt --- server/src/report/latex.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/server/src/report/latex.rs b/server/src/report/latex.rs index f21e11ab..74148575 100644 --- a/server/src/report/latex.rs +++ b/server/src/report/latex.rs @@ -40,8 +40,7 @@ use std::path::Path; /// print!("{content}") /// ``` pub fn template(path: &str) -> String { - return fs::read_to_string(Path::new(path)) - .expect("template should be read from"); + return fs::read_to_string(Path::new(path)).expect("template should be read from"); } #[cfg(test)]