diff --git a/.github/workflows/docs.yml b/.github/workflows/website.yml similarity index 78% rename from .github/workflows/docs.yml rename to .github/workflows/website.yml index 8b70f4712..caa8a0a71 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/website.yml @@ -16,21 +16,21 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout uutils.github.io Repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: uutils/uutils.github.io path: './uutils.github.io' fetch-depth: 0 - name: Checkout Coreutils Repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: uutils/coreutils path: './coreutils' fetch-depth: 0 - name: Checkout Findutils Repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: repository: uutils/findutils path: './findutils' @@ -39,44 +39,51 @@ jobs: - name: Install `rust` toolchain uses: dtolnay/rust-toolchain@stable - - name: Install `libacl` + - name: Install system deps run: | - sudo apt install libacl1-dev + sudo apt install libacl1-dev libselinux1-dev - name: Download tldr archive run: | curl https://tldr.sh/assets/tldr.zip --output coreutils/docs/tldr.zip - - name: Install necessary tools (oranda, mdbook and mdbook-toc) + - name: Install necessary tools (mdbook and mdbook-toc) uses: taiki-e/install-action@v2 with: - tool: oranda,mdbook,mdbook-toc + tool: mdbook,mdbook-toc - name: Build Coreutils Docs run: | cd coreutils cargo run --bin uudoc --all-features - oranda build + cd docs + mdbook build - name: Build Findutils Docs run: | cd findutils - oranda build + cd docs + mdbook build + + - name: Run Zola + uses: shalzz/zola-deploy-action@v0.21.0 + env: + BUILD_DIR: uutils.github.io + BUILD_ONLY: true - name: Collect results into `public` folder run: | - mkdir public - cp -r coreutils/public public/coreutils - cp -r findutils/public public/findutils - cp -r uutils.github.io/homepage/* public + cp -r uutils.github.io/public public + cp -r coreutils/docs/book public/coreutils/docs + cp -r findutils/docs/book public/findutils/docs - name: Upload artifact for checking the output - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: path: ./public - name: Upload artifact for pages - uses: actions/upload-pages-artifact@v2 + uses: actions/upload-pages-artifact@v4 with: path: ./public @@ -151,7 +158,8 @@ jobs: url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest needs: build + if: (github.event_name == 'push' && github.ref == 'refs/heads/main') || github.event_name == 'schedule' steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v3 + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..d90d7f863 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/public/ +/static/syntax-* diff --git a/README.md b/README.md index 2baf0d1c4..f67b8508e 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,10 @@ This repository generates the user and dev documentations of https://github.com/ ## User documentation It is available on: -https://uutils.github.io/user/ +https://uutils.github.io/coreutils/docs/ Can be generated with: -``` +```bash cargo run --bin uudoc --all-features cd docs mdbook build @@ -20,7 +20,7 @@ It is available on: https://uutils.github.io/dev/coreutils/ Can be generated with: -``` +```bash cargo doc --no-deps --all-features --workspace ``` diff --git a/config.toml b/config.toml new file mode 100644 index 000000000..35730ecbb --- /dev/null +++ b/config.toml @@ -0,0 +1,19 @@ +# The URL the site will be built for +base_url = "https://uutils.github.io" + +title = "uutils" + +description = "" + +default_language = "en" + +generate_feeds = true + +[markdown] +highlight_code = true +highlight_theme = "css" + +highlight_themes_css = [ + { theme = "OneHalfDark", filename = "syntax-theme-dark.css" }, + { theme = "OneHalfLight", filename = "syntax-theme-light.css" }, +] diff --git a/content/_index.md b/content/_index.md new file mode 100644 index 000000000..d5781f237 --- /dev/null +++ b/content/_index.md @@ -0,0 +1,73 @@ ++++ +title = "Home" +template = "index.html" ++++ + +
+ + + + +
uutils
+
+ +The uutils project reimplements ubiquitous command line utilities in +Rust. Our goal is to modernize the utils, while retaining full +compatibility with the existing utilities. + +We are planning to replace all essential Linux tools. + +# Projects + +
+ +

coreutils

+

+ The commands you use everyday: ls, cp, etc. Production ready! +

+
+ +

findutils

+

+ Finding what you need: find, locate, updatedb & xargs. +

+
+ +

diffutils

+

+ Comparing text and files: diff, cmp, diff3, sdiff. +

+
+
+ +# Crates + +We maintain a variety of public crates to support our projects, +which are published on [crates.io](https://crates.io/). + +- [`ansi-width`](https://github.com/uutils/ansi-width) +- [`parse_datetime`](https://github.com/uutils/parse_datetime) +- [`platform-info`](https://github.com/uutils/platform-info) +- [`uutils-term-grid`](https://github.com/uutils/uutils-term-grid) + +# Contributing + +You can help us out by: + +- Contributing code +- Contributing documentation +- Reporting bugs (e.g. incompatibilities with GNU utilities) +- Triaging bugs +- [Sponsoring uutils on GitHub](https://github.com/sponsors/uutils) + +You can join our [Discord server](https://discord.gg/wQVJbvJ) to discuss or ask anything concerning uutils. We're happy to help you get started with contributing! + +# Friends of uutils + +We collaborate with and build upon many other projects in the Rust +community, either by using or providing crates. We highly recommend +giving these projects a look! + +- [`nushell`](https://www.nushell.sh/) +- [`ripgrep`](https://github.com/burntsushi/ripgrep) +- [`eza`](https://github.com/eza-community/eza) diff --git a/content/blog/2025-02-extending.md b/content/blog/2025-02-extending.md new file mode 100644 index 000000000..b1a66784a --- /dev/null +++ b/content/blog/2025-02-extending.md @@ -0,0 +1,90 @@ ++++ +title = "Extending the Coreutils project - Rewriting base tools in Rust" +date = 2025-02-01 +page_template = "post.html" +authors = ["Sylvestre Ledru"] ++++ + +As I [just presented at FOSDEM](https://sylvestre.ledru.info/coreutils-fosdem-2025/), we are moving into the next phase of the uutils project. + +Over the last five years, we have been working on reimplementing some of the key Linux tools in Rust. We started with the [Coreutils](https://github.com/uutils/coreutils) and [findutils](https://github.com/uutils/findutils). + +As we approach feature parity with the GNU Coreutils implementation, and as its adoption in production environments continues to expand, we have been thinking about what is next. + +Given the very positive feedback around this initiative, we are going to extend our efforts to rewrite other parts of the modern Linux/Unix/Mac stack in Rust (still with Windows support in mind when relevant). These efforts will be managed under the [uutils umbrella](https://github.com/uutils/), which will allow us to maintain a cohesive and unified approach across various utilities. + +We also noticed a lot of contributions on these projects coming from a diverse group of hackers (530 different contributors on Coreutils alone!). With the growing enthusiasm for Rust and the eagerness to learn it, now is the best time to push this project forward. Rewriting in Rust will help with the long-term maintenance of the ecosystem, ensuring it stays robust, safe, and welcoming for new generations of contributors. + +### Vision for the Future + +As we expand the scope of the project, we are working on a future where Rust becomes the backbone of essential Linux, Unix, and potentially macOS system tools. Our focus will be on improving security, ensuring long-term maintainability, and optimizing performance for both modern and legacy systems. Through the uutils umbrella, we aim to create a more secure, efficient, and scalable alternative to the traditional tools, replacing software developed in older, less secure programming languages like C. + +This project is also an investment for the future. C is becoming less popular with the next generation of developers. Just like how the Linux kernel continues to evolve and includes Rust, it is our responsibility to upgrade the core utilities of the system to a modern, safer programming language. By doing so, we ensure that the essential tools used in Linux/Unix systems remain relevant, maintainable, and accessible to future contributors. + +### Specific Benefits of Rust + +Rust offers several advantages over C/C++, particularly in terms of memory safety, concurrency, and performance. By eliminating common security issues such as null pointer dereferences and buffer overflows, Rust allows us to build tools that are inherently safer. Its modern compiler tooling also enables us to optimize performance without sacrificing code safety, ensuring that our utilities can handle the demands of modern computing environments while remaining easy to maintain. + +### Challenges and Opportunities + +As with any large-scale reimplementation, there are challenges to overcome. Porting complex utilities from C to Rust requires careful consideration of edge cases and platform-specific behaviors. Additionally, ensuring full compatibility across Linux, Unix, and macOS environments presents unique challenges. However, these challenges also offer opportunities for growth and innovation, allowing us to extend and refine core system utilities for modern needs. Rust's modern design gives us the chance to improve both security and performance while maintaining cross-platform compatibility. + +### Next Steps + +For the next phase of the project, we are adopting the same approach: a drop-in replacement of the C implementations. Here's what's coming next: + +| Name | Description | Status | +|----------------------------------------------------|----------------------------------------------------|-----------------------------| +| [acl](https://github.com/uutils/acl) | Access control list utilities | | +| [bsdutils](https://github.com/uutils/bsdutils) | Basic utilities for BSD compatibility | | +| [coreutils](https://github.com/uutils/coreutils) | Basic utilities for the system | Production level | +| [diffutils](https://github.com/uutils/diffutils) | File comparison utilities | Almost ready | +| [findutils](https://github.com/uutils/findutils) | Utilities for finding files | Getting close to completion | +| [hostname](https://github.com/uutils/hostname) | Utility to show or set system hostname | | +| [login](https://github.com/uutils/login) | User login management utilities | | +| [procps](https://github.com/uutils/procps) | Utilities for monitoring and controlling processes | | +| [util-linux](https://github.com/uutils/util-linux) | Utilities essential for Linux systems | | + +These packages are part of the essential list for Debian and Ubuntu, and we're excited to push their Rust reimplementation further. + +### GSoC 2024 Participation + +In 2024, we had the pleasure of mentoring three students during Google Summer of Code (GSoC): + +1. **Sreehari Prasad** worked on improving the support of Rust CCoreutils. His focus was on making uutils compatible with the GNU coreutils test suite. Sreehari resolved most of the failing tests for the `cp`, `mv`, and `ls` utilities and significantly enhanced compatibility. + +2. **Hanbings** tackled the implementation of key GNU `findutils` utilities like `xargs` and `find` in Rust. His work focused on improving compatibility with the GNU suite while enhancing performance, resulting in major progress on missing features and test code. + +3. **Krysztal Huang** worked on implementing the `procps` suite, which includes utilities like `slabtop`, `top`, `pgrep`, `pidof`, `ps`, `pidwait`, and `snice`. This project involved implementing some of these commands. + +### Call to Action for Contributors + +Contributors who are passionate about system-level programming and Rust are always welcome. Whether you're experienced with GNU utilities or just learning Rust, your contributions will be invaluable to this +project. You can get involved by picking up good-first issues, reviewing code, or even helping us test new features across various platforms. The [uutils GitHub organization](https://github.com/uutils) has all the information you need to get started. +You can also sponsor the project through [GitHub Sponsors](https://github.com/sponsors/uutils). + +### FAQ + +**How long is it going to take?** + +Some programs, like `diff`, `acl`, or `hostname`, could be completed quickly, while others will take years to finish. + +**Do you hate the GNU project?** + +Not at all. We often contribute to the upstream implementations when we identify issues, add missing tests, and so on. + +**Why the MIT License?** + +For consistency purposes. We're not interested in a license debate and will continue to use the MIT license, as we did with Coreutils. + +**The binaries are too big. Does it really matter?** + +Yes, Rust binaries are generally bigger than GNU's, but we don't think it's a blocker, even for embedded devices. + +**Is it really safer?** + +While Rust is better than C/C++ for security, these programs are often already very safe. Security is not the key argument for us in this rewrite even if Rust provides some automatic improvements. + +**What about performance?** + +Although we haven't started optimizing yet, Rust's design facilitates performance improvements naturally. We are confident that, in time, these tools will match or exceed the performance of their GNU counterparts. diff --git a/content/blog/_index.md b/content/blog/_index.md new file mode 100644 index 000000000..e16b5390b --- /dev/null +++ b/content/blog/_index.md @@ -0,0 +1,8 @@ ++++ +template = "section.html" +sort_by = "date" +page_template = "post.html" +title = "Blog" ++++ + +You can subscribe to this blog with this [atom feed](/atom.xml). diff --git a/content/blog/test.md b/content/blog/test.md new file mode 100644 index 000000000..b145f4217 --- /dev/null +++ b/content/blog/test.md @@ -0,0 +1,10 @@ ++++ +title = "Test post" +draft = true +date = 2024-01-31 +authors = ["Terts Diepraam"] ++++ + +This is a test post + +# Heading 1 \ No newline at end of file diff --git a/content/coreutils.md b/content/coreutils.md new file mode 100644 index 000000000..4d38ef14c --- /dev/null +++ b/content/coreutils.md @@ -0,0 +1,24 @@ ++++ + +title = "coreutils" +template = "project.html" + ++++ + +uutils coreutils is a cross-platform reimplementation of the GNU coreutils in Rust. While all programs have been implemented, some options might be missing or different behavior might be experienced. + +# Goals + +This project aims to be a drop-in replacement for the GNU utils. Differences with GNU are treated as bugs. + +uutils aims to work on as many platforms as possible, to be able to use the same utils on Linux, Mac, Windows and other platforms. This ensures, for example, that scripts can be easily transferred between platforms. + +# Contributing + +To contribute to uutils coreutils, please see [CONTRIBUTING](https://github.com/uutils/coreutils/blob/main/CONTRIBUTING.md). + +# License + +uutils coreutils is licensed under the MIT License - see the [LICENSE](https://github.com/uutils/coreutils/blob/main/LICENSE) file for details. + +GNU Coreutils is licensed under the GPL 3.0 or later. diff --git a/content/diffutils.md b/content/diffutils.md new file mode 100644 index 000000000..fbcc854d2 --- /dev/null +++ b/content/diffutils.md @@ -0,0 +1,16 @@ ++++ + +title = "diffutils" +template = "project.html" + ++++ + +Rust implementation of GNU diffutils: `diff`, `cmp`, `diff3` and `sdiff`. + +This project aims to be a drop-in replacement of the original commands. + +# License + +uutils diffutils is licensed under the MIT or Apache License - see the [LICENSE-MIT](https://github.com/uutils/diffutils/blob/main/LICENSE-MIT) and [LICENSE-APACHE](https://github.com/uutils/diffutils/blob/main/LICENSE-MIT) file for details. + +GNU diffutils is licensed under the GPL 3.0 or later. diff --git a/content/findutils.md b/content/findutils.md new file mode 100644 index 000000000..28a0796c2 --- /dev/null +++ b/content/findutils.md @@ -0,0 +1,20 @@ ++++ + +title = "findutils" +template = "project.html" + ++++ + +Rust implementation of GNU findutils: `xargs`, `find`, `locate` and `updatedb`. + +This project aims to be a drop-in replacement of the original commands. + +# Contributing + +To contribute to uutils findutils, please see [CONTRIBUTING](https://github.com/uutils/findutils/blob/main/CONTRIBUTING.md). + +# License + +uutils findutils is licensed under the MIT License - see the [LICENSE](https://github.com/uutils/findutils/blob/main/LICENSE) file for details. + +GNU findutils is licensed under the GPL 3.0 or later. diff --git a/content/gsoc.md b/content/gsoc.md new file mode 100644 index 000000000..77ba7b010 --- /dev/null +++ b/content/gsoc.md @@ -0,0 +1,321 @@ ++++ +title = "Uutils at GSOC" ++++ + +Google summer of code is: + +> Google Summer of Code is a global, online program focused on bringing +> new contributors into open source software development. GSoC +> Contributors work with an open source organization on a 12+ week +> programming project under the guidance of mentors. + +If you want to know more about how it works, check out the links below. + +**Useful links**: +* [GSOC Contributor Guide](https://google.github.io/gsocguides/student/) +* [GSOC FAQ](https://developers.google.com/open-source/gsoc/faq) +* [GSOC Timeline](https://developers.google.com/open-source/gsoc/timeline) (important for deadlines!) + +# What is it about? + +The [uutils project](https://github.com/uutils/) is aiming at rewriting key Linux utilities in Rust, targeting [coreutils](https://github.com/uutils/coreutils), [findutils](https://github.com/uutils/findutils), [diffutils](https://github.com/uutils/diffutils), [procps](https://github.com/uutils/procps), [util-linux](https://github.com/uutils/util-linux), and [bsdutils](https://github.com/uutils/bsdutils). Their goal is to create fully compatible, high-performance drop-in replacements, ensuring reliability through upstream test suites. Significant progress has been made with coreutils, diffutils, and findutils, while the other utilities are in the early stages of development. + +# How to get started + +Here are some steps to follow if you want to apply for a GSOC project +with uutils. + +1. **Check the requirements.** You have to meet + [Google's requirements](https://developers.google.com/open-source/gsoc/faq#what_are_the_eligibility_requirements_for_participation) to apply. Specifically for uutils, it's best if you at + least know some Rust and have some familiarity with using the + coreutils and the other tools. +1. **Reach out to us!** We are happy to discuss potential projects and help you find a meaningful project for uutils. Tell us what interests you about the project and what experience you have and we can find a suitable project together. You can talk to the uutils maintainers on the [Discord server](https://discord.gg/wQVJbvJ). In particular, you can contact: + * Sylvestre Ledru (@sylvestre on GitHub and Discord) + * Terts Diepraam (@tertsdiepraam on GitHub and @terts on Discord) +2. **Get comfortable with uutils.** To find a good project you need to understand the codebase. We recommend that you take a look at the code, the issue tracker and maybe try to tackle some [good-first-issues](https://github.com/uutils/coreutils/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22). Also take a look at our [contributor guidelines](https://github.com/uutils/coreutils/blob/main/CONTRIBUTING.md). +3. **Find a project and a mentor.** We have a [list of potential projects](https://github.com/uutils/coreutils/wiki/GSOC-Project-Ideas) you can adapt or use as inspiration. Make sure discuss your ideas with the maintainers! Some project ideas below have suggested mentors you could contact. +4. **Write the application.** You can do this with your mentor. The application has to go through Google, so make sure to follow all the advice in Google's [Contributor Guide](https://google.github.io/gsocguides/student/writing-a-proposal). Please make sure you include your prior contributions to uutils in your application. + +# Tips + +- Make sure the project is concrete and well-defined. +- Communication is super important! +- Try to tackle some issues to get familiar with uutils and demonstrate your motivation. + +# Project Ideas + +This page contains project ideas for the Google Summer of Code for +uutils. Feel free to suggest project ideas of your own. + +[Guidelines for the project list](https://google.github.io/gsocguides/mentor/defining-a-project-ideas-list) + +Summarizing that page, each project should include: +- Title +- Description +- Expected outputs +- Skills required/preferred +- Possible mentors +- Size (either ~175 or ~350 hours) +- Difficulty (easy, medium or hard) + +## Complete the `ls` GNU compatibility + +Most of the features in `ls` have been implemented by now. +However, a bunch of work remains on the color side for a full GNU compat. Other tests are failing. +We have 12 remaining failing tests. + +To get the list of failing tests, run: +```bash +$ ./util/remaining-gnu-error.py | grep "/ls/" +``` + +- Difficulty: Medium +- Size: 175 +- Mentors: Sylvestre +- Required skills: + - Rust + - Basic knowledge about the terminal + +## Complete the `cp` GNU compatibility + +Most of the features in `cp` have been implemented by now. +However, some corner cases needs to be implemented. We have 16 remaining failing tests. + +To get the list of failing tests, run: +```bash +$ ./util/remaining-gnu-error.py | grep "/cp/" +``` + +- Difficulty: Medium +- Size: 175 +- Mentors: Sylvestre +- Required skills: + - Rust + - Basic knowledge about the terminal + +## Complete the `mv` GNU compatibility + +Most of the features in `mv` have been implemented by now. +However, some corner cases needs to be implemented. We have 10 remaining failing tests. + +To get the list of failing tests, run: +```bash +$ ./util/remaining-gnu-error.py | grep "/mv/" +``` + +- Difficulty: Medium +- Size: 175 +- Mentors: Sylvestre +- Required skills: + - Rust + - Basic knowledge about the terminal + +## Improve `stty` +The `stty` utility is currently only partially implemented and should be expanded. + +See issues: [#3859](https://github.com/uutils/coreutils/issues/3859), [#3860](https://github.com/uutils/coreutils/issues/3860), [#3861](https://github.com/uutils/coreutils/issues/3861), [#3862](https://github.com/uutils/coreutils/issues/3862), [#3863](https://github.com/uutils/coreutils/issues/3863). + +- Difficulty: Medium +- Size: 175 +- Mentors: Terts Diepraam +- Required skills: + - Rust + - Basic knowledge about the terminal + +## Improve findutils coverage + +[More than half](https://github.com/uutils/findutils-tracking/) of the findutils GNU & BFS are passing. The goal of this project is to improve the compatibility of uutils/findutils with regard to GNU's implementation. + +See [https://github.com/uutils/findutils](https://github.com/uutils/findutils) + + +To achieve this, we should invest in fuzzing findutils: +Just like we are [doing with some](https://github.com/uutils/coreutils/tree/main/fuzz/fuzz_targets) [Coreutils programs](https://github.com/uutils/coreutils/blob/main/.github/workflows/fuzzing.yml), we should: +* fuzz findutils +* do some differential testing with GNU's implementation (and potentially others) + +- Difficulty: Medium +- Size: 175 +- Mentors: Sylvestre +- Required skills: + - Rust + - Basic knowledge about the terminal usage + +## Localization +Support for localization for formatting, quoting & sorting in various utilities, like `date`, `ls` and `sort`. For this project, we need to figure out how to deal with locale data. The first option is to use the all-Rust `icu4x` library, which has a different format than what distributions usually provide. In this case a solution _could_ be to write a custom `localedef`-like command. The second option is to use a wrapper around the C `icu` library, which comes with the downside of being a C dependency. + +This is described in detail in [issue #3997](https://github.com/uutils/coreutils/issues/3997). + +And was also discussed in [#1919](https://github.com/uutils/coreutils/issues/1919#issuecomment-846471073), [#3584](https://github.com/uutils/coreutils/issues/3584). + +- Difficulty: Hard +- Size: TBD +- Mentors: TBD +- Required skills: + - Rust + +## `procps`: Development of Process Management and Information Tools in Rust + +This project focuses on creating Rust-based implementations of process management and information tools: `ps`, `pgrep`, `pidwait`, `pkill`, `skill`, and `snice`. The goal is to ensure full compatibility with all options and successful passing of GNU tests, maintaining the functionality and reliability of these essential tools. + +- **Description:** Develop Rust-based versions of key process management and information tools, ensuring compatibility with all options and GNU tests. +- **Expected Outputs:** Efficient, reliable tools with full option compatibility and passing GNU tests. +- **Skills Required/Preferred:** Proficiency in Rust, understanding of Linux process management, experience with GNU testing methodologies. +- **Possible Mentors:** [To be determined] +- **Size:** ~350 hours. +- **Difficulty:** Medium. + +## `procps`: Development of System Monitoring and Statistics Tools in Rust + +This project involves the Rust-based development of system monitoring and statistics tools: `top`, `vmstat`, `tload`, `w`, and `watch`. The objective is to achieve full compatibility with all options and to pass GNU tests, ensuring these tools provide accurate and reliable system insights. + +- **Description:**: Create Rust versions of system monitoring and statistics tools, with a focus on full option compatibility and passing GNU tests. +- **Expected Outputs:**: Robust tools for system monitoring and statistics, fully compatible with existing options and verified by GNU tests. +- **Skills Required/Preferred:**: Rust expertise, knowledge of system performance metrics, familiarity with GNU testing frameworks. +- **Possible Mentors:**: [To be determined] +- **Size:**: ~350 hours. +- **Difficulty:**: Medium. + +## `procps`: Development of Memory and Resource Analysis Tools in Rust + +The aim of this project is to develop Rust-based versions of memory and resource analysis tools: `pmap` and `slabtop`. The project will focus on ensuring full compatibility with all options and passing GNU tests, providing in-depth and reliable analysis of memory usage and kernel resources. + +- **Description:**: Implement Rust versions of memory and resource analysis tools, with emphasis on option compatibility and passing GNU tests. +- **Expected Outputs:**: Advanced tools for memory and resource analysis, fully compatible with existing options and validated by GNU tests. +- **Skills Required/Preferred:**: Proficiency in Rust, deep understanding of memory management and kernel resources, experience with GNU testing methodologies. +- **Possible Mentors:**: [To be determined] +- **Size:**: ~175 hours. +- **Difficulty:**: Medium. + +## `util-linux`: Reimplementation of essential system utilities in Rust + +The objective of this project is to reimplement essential system utilities from the util-linux package in Rust. This initiative will include the development of Rust-based versions of various utilities, such as `dmesg`, `lscpu`, `lsipc`, `lslocks`, `lsmem`, and `lsns`. The primary focus will be on ensuring that these Rust implementations provide full compatibility with existing options and pass GNU tests, delivering reliable and efficient system utilities for Linux users. + +- **Description:**: Reimplement essential system utilities, including `dmesg`, `lscpu`, `lsipc`, `lslocks`, `lsmem`, and `lsns`, using Rust while emphasizing compatibility with existing options and GNU test validation. +- **Expected Outputs:**: Rust-based system utilities that mirror the functionality of their counterparts, ensuring full compatibility and reliability, validated by GNU tests. +- **Skills Required/Preferred:**: Proficiency in Rust programming, knowledge of system utilities and their functionality, experience with GNU testing methodologies. +- **Possible Mentors:**: [To be determined] +- **Size:**: ~175 hours. +- **Difficulty:**: Medium. + +## `util-linux`: Process and Resource Management: Reimplementation in Rust + +This project focuses on the reimplementations of crucial Linux utilities related to process and resource management in the Rust programming language. The target utilities include `runuser`, `sulogin`, `chrt`, `ionice`, `kill`, `renice`, `prlimit`, `taskset`, and `uclampset`. The primary goal is to create Rust-based versions of these utilities, ensuring compatibility with their original counterparts, and validating their functionality with GNU tests. + +- **Description:**: Reimplement key Linux utilities for process and resource management, such as `runuser`, `sulogin`, `chrt`, `ionice`, `kill`, `renice`, `prlimit`, `taskset`, and `uclampset`, in the Rust programming language. The emphasis is on maintaining compatibility with the original utilities and validating their functionality using GNU tests. +- **Expected Outputs:**: Rust-based versions of the specified utilities that seamlessly integrate into Linux systems, providing the same functionality and passing GNU tests for reliability. +- **Skills Required/Preferred:**: Proficiency in Rust programming, understanding of process and resource management on Linux, experience with GNU testing methodologies. +- **Possible Mentors:**: [To be determined] +- **Size:**: ~175 hours. +- **Difficulty:**: Medium. + +## `util-linux`: User and Session Management: Reimplementation in Rust + +This project focuses on the reimplementations of essential Linux utilities related to user and session management in the Rust programming language. The target utilities include `su`, `agetty`, `ctrlaltdel`, `pivot_root`, `switch_root`, `last`, `lslogins`, `mesg`, `setsid`, and `setterm`. The primary goal is to create Rust-based versions of these utilities, ensuring compatibility with their original counterparts, and validating their functionality with GNU tests. + +- **Description:**: Reimplement essential Linux utilities for user and session management, such as `su`, `agetty`, `ctrlaltdel`, `pivot_root`, `switch_root`, `last`, `lslogins`, `mesg`, `setsid`, and `setterm`, in the Rust programming language. The emphasis is on maintaining compatibility with the original utilities and validating their functionality using GNU tests. +- **Expected Outputs:**: Rust-based versions of the specified utilities that seamlessly integrate into Linux systems, providing the same functionality and passing GNU tests for reliability. +- **Skills Required/Preferred:**: Proficiency in Rust programming, understanding of user and session management on Linux, experience with GNU testing methodologies. +- **Possible Mentors:**: [To be determined] +- **Size:**: ~175 hours. +- **Difficulty:**: Medium. + +This project aims to modernize and enhance critical Linux utilities related to user and session management, ensuring they remain efficient, reliable, and fully compatible with existing systems. + +## Code refactoring for `procps`, `util-linux`, and `bsdutils` + +Refactoring the Rust-based versions of procps, util-linux, and bsdutils to reduce code duplication. + +- **Title:**: Code Optimization and Refactoring for procps, util-linux, and bsdutils in Rust +- **Description:**: This project involves optimizing and refactoring the Rust-based versions of procps, util-linux, and bsdutils. The focus will be on eliminating duplicated code across these utilities, particularly in areas like uudoc, the test framework, and support for single/multicall binaries. +- **Expected outputs:**: A streamlined codebase with reduced duplication, improved maintainability for procps, util-linux, and bsdutils. +- **Skills required/preferred:**: Proficiency in Rust programming, understanding of Linux utilities, experience with code optimization and refactoring. +- **Possible mentors:**: Sylvestre +- **Size:**: 175 hours +- **Difficulty:**: Medium + +## A multicall binary and core library for `findutils` + +`findutils` currently exists of a few unconnected binaries. It would be nice to have a multicall binary (like +`coreutils`) and a library of shared functions (like `uucore`). + +This also might require thinking about sharing code between coreutils and findutils. + +- **Difficulty**: Medium +- **Size**: 175 hours +- **Mentors**: TBD +- Required skills: + - Rust + +## Implementation of GNU Test Execution for `procps`, `util-linux`, `diffutils`, and `bsdutils` + +The project aims at integrating the GNU test suite execution using the Rust-based versions of `procps`, `util-linux`, `diffutils`, and `bsdutils`, ensuring compatibility, crucial for seamless drop-in replacement integration. We have been doing such operation successfully for the Coreutils using [GitHub Actions](https://github.com/uutils/coreutils/blob/main/.github/workflows/GnuTests.yml), a [build script](https://github.com/uutils/coreutils/blob/main/util/build-gnu.sh) and a [run script](https://github.com/uutils/coreutils/blob/main/util/run-gnu-test.sh). + +- **Description:**: Run the GNU test suite on the Rust-based versions of procps, util-linux, diffutils, and bsdutils +- **Expected Outputs:**: The GNU test suite execution for each utility, ensuring functionality meets expected standards +- **Skills Required/Preferred:**: GitHub action understanding, Proficiency in Rust, experience with GNU testing methodologies, familiarity with Linux system utilities, and understanding of software testing principles. +- **Possible Mentors:**: Sylvestre +- **Size:**: ~175 hours +- **Difficulty:**: Medium + +## Refactoring `factor` + +The uutils `factor` is currently significantly slower than +GNU `factor` and only supports numbers up to 2^64-1. See [issue 1559](https://github.com/uutils/coreutils/issues/1559) +and [issue 1456](https://github.com/uutils/coreutils/issues/1456) for more information. + +- Difficulty: Hard +- Size: 175 hours +- Mentors: TBD +- Required skills: + - Rust + - Optimization techniques + - Mathematics + +## Symbolic/Fuzz Testing and Formal Verification of Tool Grammars + +See [Using Lightweight Formal Methods to Validate a Key Value Storage Node In Amazon S3](https://www.amazon.science/publications/using-lightweight-formal-methods-to-validate-a-key-value-storage-node-in-amazon-s3). + +Most KLEE scaffolding was done for [KLEE 2021](https://project-oak.github.io/rust-verification-tools/2021/07/14/coreutils.html). + +Start with `wc`, formalize the command line grammar. Get it working under AFL++ and Klee. Add several proofs of resource use and correctness - especially proofs about operating system calls and memory/cache usage. Generalize to other tools. Try to unify the seeds for the fuzzer and KLEE so they can help each other find new paths. Use QEMU to test several operating systems and architectures. Automate detection of performance regressions - try to hunt for [accidentally quadratic](https://accidentallyquadratic.tumblr.com) behavior. + +Specific to `wc` - formalize the inner loop over a UTF-8 buffer into a finite state automata with counters that can generalize into SIMD width operations like [simdjson](https://simdjson.org). Further generalize into a monoid so K processors can combine results. + +- Difficulty: Mixed +- Size: Mixed +- Mentors: TBD - informally @chadbrewbaker +- Required skills: + - Rust + - KLEE + - Fuzzers like AFL++ + - Grammar testing frameworks like [LARK](https://github.com/ligurio/lark-grammars/tree/master/lark_grammars/grammars) + - /usr/bin/time -v (and similar tools for Widows/OSX). + - Alloy, TLA+, [P](https://github.com/p-org/P) + - System call tracing with [strace](https://jvns.ca/blog/2014/02/17/spying-on-ssh-with-strace/), [uftrace](https://github.com/namhyung/uftrace) etc. + - SMT solvers like [Z3](https://www.philipzucker.com/programming-and-interactive-proving-with-z3py/) and CVC5 for superoptimization and proofs of automata equivalence. + - [SOUPER](https://github.com/google/souper) and [CompilerExplorer](https://godbolt.org) + - Basic statistics on quantiles (histograms) for outlier detection. The math is simple as generalizing from one to k medians but the formal notation is [complex](https://aakinshin.net/posts/thdqe-hdi/). + - [MPI-IO](https://wgropp.cs.illinois.edu/courses/cs598-s16/lectures/lecture32.pdf), just enough to read a file into k parts and combine "wc" outputs to understand multicore scaling. + +## Development of advanced terminal session recording and replay tools in Rust + +This project involves creating Rust-based implementations of `/usr/bin/script`, `/usr/bin/scriptlive`, and `/usr/bin/scriptreplay`. The `/usr/bin/script` command will record terminal sessions, `/usr/bin/scriptlive` will offer real-time recording features, and `/usr/bin/scriptreplay` will be used to replay recorded sessions. + +The work will happen in https://github.com/uutils/bsdutils. + +- **Description:**: Develop Rust-based versions of `/usr/bin/script`, `/usr/bin/scriptlive`, and `/usr/bin/scriptreplay` for terminal session recording and replaying. +- **Expected Outputs:**: Robust and cross-platform terminal session recording and replay tools, with real-time features in `scriptlive`. +- **Skills Required/Preferred:**: Proficiency in Rust, understanding of terminal emulation, experience with cross-platform development. +- **Possible Mentors:**: [To be determined] +- **Size:**: ~175 hours +- **Difficulty:**: Medium + +## Official Redox support +We want to support the Redox operating system, but are not actively testing against it. Since the last round of fixes in [#2550](https://github.com/uutils/coreutils/pull/2550), many changes have probably been introduced that break Redox support. This project would involve setting up Redox in the CI and fixing any issues that arise and porting features over. + +- Difficulty: Medium +- Size: 175 hours +- Mentors: TBD +- Required skills: + - Rust diff --git a/homepage/index.html b/homepage/index.html deleted file mode 100644 index d3a6a8236..000000000 --- a/homepage/index.html +++ /dev/null @@ -1,344 +0,0 @@ - - - - uutils - - - - - -
-
- -
-
- -

uutils

-
-

- The uutils project reimplements ubiquitous command line utilities in - Rust. Our goal is to modernize the utils, while retaining full - compatibility with the existing utilities. -

-

Projects

- -

Crates

-

- We maintain a variety of public crates to support our projects, - which are published on crates.io. -

- -

Contributing

-

You can help us out by:

-
    -
  • Contributing code
  • -
  • Contributing documentation
  • -
  • Reporting bugs (e.g. incompatibilities with GNU utilities)
  • -
  • Triaging bugs
  • -
  • Sponsoring uutils on GitHub
  • -
-

You can join our Discord server to discuss or ask anything concerning uutils. We're happy to help you get started with contributing!

-

Friends of uutils

-

- We collaborate with and build upon many other projects in the Rust - community, either by using or providing crates. We highly recommend - giving these projects a look! -

- -
-
- -
- - diff --git a/static/logo-dark.svg b/static/logo-dark.svg new file mode 100644 index 000000000..dee38a04f --- /dev/null +++ b/static/logo-dark.svg @@ -0,0 +1,61 @@ + diff --git a/homepage/logo.svg b/static/logo.svg similarity index 100% rename from homepage/logo.svg rename to static/logo.svg diff --git a/static/style.css b/static/style.css new file mode 100644 index 000000000..1214b0641 --- /dev/null +++ b/static/style.css @@ -0,0 +1,440 @@ +:root { + /* Light theme colors (default) */ + + --accent-color: #c04828; + + --dark-fg-color: #fff; + --light-fg-color: #141414; + --light-bg-color: var(--dark-fg-color); + --dark-bg-color: var(--light-fg-color); + --fg-color: var(--light-fg-color); + --bg-color: var(--light-bg-color); + --link-color: var(--accent-color); + --light-highlight-bg-color: #ededed; + --light-highlight-fg-color: #595959; + --dark-highlight-bg-color: #27272a; + --dark-highlight-fg-color: #ededed; + --highlight-fg-color: var(--light-highlight-fg-color); + --highlight-bg-color: var(--light-highlight-bg-color); + --link-text-color: var(--accent-color); + --header-border-color: #ddd; + --post-bg-color: #e5e5e5; + --font-face: "Fira Sans", sans-serif; + + --github-icon: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23fff' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E"); + --github-icon-black: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='000' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E"); +} + +@media (prefers-color-scheme: dark) { + :root { + --fg-color: #e1e1e1; + --bg-color: #222222; + --link-color: var(--accent-color); + --light-highlight-bg-color: #2d2d2d; + --light-highlight-fg-color: #ffffff; + --dark-highlight-bg-color: #27272a; + --dark-highlight-fg-color: #ededed; + --highlight-fg-color: var(--light-highlight-fg-color); + --highlight-bg-color: var(--light-highlight-bg-color); + --link-text-color: var(--accent-color); + --header-border-color: #404040; + --post-bg-color: #2d2d2d; + } +} + +body { + background-color: var(--bg-color); + color: var(--fg-color); +} + +*, +::after, +::before { + border: 0 solid #e5e7eb; + box-sizing: border-box; +} + +html { + font-feature-settings: normal; + font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, + Segoe UI, Roboto, Helvetica Neue, Arial, Noto Sans, sans-serif, + Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji; + font-variation-settings: normal; + line-height: 1.5; + tab-size: 4; +} + +blockquote, +dd, +dl, +figure, +h1, +h2, +h3, +h4, +h5, +h6, +hr, +p, +pre { + margin: 0; +} + +a { + color: var(--link-color); + text-decoration: inherit; +} + +/* PAGE LAYOUT */ +html, +body { + font-family: var(--font-face); + height: 100%; + scroll-behavior: smooth; +} + +body { + line-height: inherit; + margin: 0; + display: flex; + flex-direction: column; +} + +.container { + display: flex; + flex-direction: column; + min-height: 100%; +} + +.page-body { + flex-grow: 1; +} + +/* HEADER */ +header { + display: grid; + grid-template-columns: repeat(2, max-content) max-content 1fr max-content; + column-gap: 1em; + align-items: center; + justify-items: center; + padding: 0.5rem 2rem; + width: 100%; + border-bottom: 1px solid var(--header-border-color); + font-size: 1.2rem; +} + +header .home { + color: black; + font-size: 2rem; + font-weight: bold; +} + +header .home:first-child { + display: flex; + align-items: center; + vertical-align: center; +} + +header .home svg { + height: 3rem; + width: 3rem; +} + +header a { + color: var(--fg-color); + border-bottom: 2px solid transparent; +} + +header a:hover:not(.home) { + border-bottom: 2px solid var(--link-text-color); +} + +.navigation-block { + display: flex; + flex-direction: row; + gap: 1rem; +} + +header .icon { + display: flex; + align-items: center; +} + +#mobile-open-navigation button { + display: none; +} + +#mobile-open-navigation { + justify-self: right; +} + +@media (max-width: 640px) { + #mobile-open-navigation button { + display: block; + flex-direction: column; + background-color: transparent; + } + + #mobile-open-navigation button div { + margin: 0.5em 0; + width: 2em; + border-bottom: 0.25em solid var(--fg-color); + } + + header { + grid-template-columns: max-content 1fr; + } + + .spacer { + display: none; + } + + .navigation-block { + margin-top: 0.5em; + grid-column: auto / span 2; + justify-self: left; + } + + header:not(.open) .spacer, + header:not(.open) .navigation-block { + display: none; + } +} + +/* HERO */ +.hero { + margin: 2rem 0; +} + +.hero img { + display: block; + height: 14em; + margin: auto; +} + +.hero div { + font-size: 3.75rem; + line-height: 1; + text-align: center; + padding-bottom: 0.5rem; + font-weight: bold; +} + +@media (min-width: 640px) { + .hero div { + font-size: 6rem; + line-height: 1; + } +} + +/* MAIN */ +main { + margin: 1rem auto; + width: 80%; + flex: 1; +} + +@media (min-width: 1024px) { + main { + max-width: 56rem; + } +} + +h1 { + font-size: 1.5rem; + font-weight: 900; + line-height: 2.25rem; + line-height: 1.25; + margin-bottom: 2rem; +} + +p { + font-size: 1rem; + line-height: 1.5rem; + line-height: 1.625; + margin-bottom: 2rem; +} + +@media (min-width: 640px) { + h1 { + font-size: 3rem; + line-height: 1; + } + + p { + font-size: 1.125rem; + line-height: 1.75rem; + } +} + +h2 { + font-size: 1.5rem; + font-weight: 700; + line-height: 2rem; + line-height: 1.25; + margin-bottom: 1.5rem; +} + +@media (min-width: 640px) { + h2 { + font-size: 3rem; + line-height: 1; + } +} + +h2, +h3 { + margin-top: 3rem; +} + +@media (min-width: 640px) { + li { + font-size: 1.125rem; + line-height: 1.75rem; + } +} + +ul { + margin-top: 0; + margin-bottom: 2rem; +} + +/* FOOTER */ +footer { + align-items: center; + background-color: var(--light-fg-color); + color: var(--light-bg-color); + display: flex; + flex-grow: 0; + flex-shrink: 1; + font-size: 0.75rem; + justify-content: space-between; + line-height: 1rem; + padding: 0.5rem 1rem; + width: 100%; +} + +.github-icon { + background-image: var(--github-icon); + height: 1.25rem; + width: 1.25rem; +} + +.github-icon-black { + background-image: var(--github-icon-black); + height: 1em; + width: 1em; +} + +@media (prefers-color-scheme: dark) { + .github-icon-black { + background-image: var(--github-icon); + } +} + +.projects { + display: flex; + flex-direction: column; + flex-wrap: wrap; + justify-content: space-between; + width: 100%; + gap: 2rem; + margin-bottom: 1.5rem; +} + +.project { + border-left: 0.3em solid gray; + padding: 1rem; + text-decoration: none; + color: var(--fg-color); + transition: text-decoration 0.3s; + transition: border-color 0.3s; +} + +.project h2 { + margin-top: 0; + font-family: monospace; +} + +.project p { + margin-bottom: 0; +} + +.project > span { + color: transparent; + transition: color 0.3s; +} + +.project:hover > span { + color: var(--fg-color); +} + +.project:hover { + border-color: #c04828; +} + +.title { + font-size: 3em; + font-weight: 900; + margin-bottom: 0.5em; + text-transform: capitalize; +} + +@media (min-width: 640px) { + .title { + font-size: 4rem; + line-height: 1; + } +} + +.details { + margin-bottom: 1.5em; + color: var(--fg-color); +} + +.post-thingy { + display: block; + padding: 1em; + color: var(--fg-color); + background: var(--post-bg-color); + border-radius: 0.3em; + border: 0.2em solid var(--post-bg-color); + margin-bottom: 0.5em; +} + +.post-thingy:hover { + border-color: var(--link-text-color); + background: transparent; +} + +.post-thingy h1 { + margin-bottom: 0.2em; +} + +blockquote { + border-left: 0.2em solid gray; + padding-left: 1em; +} + +.links { + display: flex; + flex-wrap: wrap; + justify-content: stretch; + gap: 1em; + margin-bottom: 2em; + font-size: 1.2em; +} + +.links > a { + padding: 0.2em 1em; + color: var(--link-text-color); + border: 2px solid #c04828; + flex: 1; + text-align: center; +} + +.links > a:hover { + color: var(--dark-fg-color); + background-color: #c04828; + border-color: #c04828; +} diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 000000000..c6d86070d --- /dev/null +++ b/templates/base.html @@ -0,0 +1,59 @@ + + + + + + {%- block title -%} + {{ config.title }} + {%- endblock title -%} + + + + + + + + + +
+ {% include "logo.html" %} +
+ +
+ +
+ +
+
+ {%- block main -%} + {%- endblock main -%} +
+ + + + diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 000000000..1228b1547 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,5 @@ +{%- extends "base.html" -%} + +{%- block main -%} + {{ section.content | safe }} +{%- endblock main -%} diff --git a/templates/logo.html b/templates/logo.html new file mode 100644 index 000000000..99b59fcbc --- /dev/null +++ b/templates/logo.html @@ -0,0 +1,61 @@ + \ No newline at end of file diff --git a/templates/page.html b/templates/page.html new file mode 100644 index 000000000..f3794a12a --- /dev/null +++ b/templates/page.html @@ -0,0 +1,10 @@ +{%- extends "base.html" -%} + +{%- block title -%} + {{ page.title }} | uutils +{%- endblock title -%} + +{%- block main -%} +
{{ page.title }}
+ {{ page.content | safe }} +{%- endblock main -%} diff --git a/templates/post.html b/templates/post.html new file mode 100644 index 000000000..ef86087ae --- /dev/null +++ b/templates/post.html @@ -0,0 +1,14 @@ +{%- extends "base.html" -%} + +{%- block title -%} + {{ page.title }} | uutils +{%- endblock title -%} + +{%- block main -%} +
{{ page.title }}
+
+
{{ page.date | date(format="%b %e, %Y") }}
+
{{ page.authors | join(sep=", ") }}
+
+ {{ page.content | safe }} +{%- endblock main -%} diff --git a/templates/project.html b/templates/project.html new file mode 100644 index 000000000..a70dd4506 --- /dev/null +++ b/templates/project.html @@ -0,0 +1,18 @@ +{%- extends "base.html" -%} + +{%- block title -%} + {{ page.title }} | uutils +{%- endblock title -%} + +{%- block main -%} +
{{ page.title }}
+ + + {{ page.content | safe }} +{%- endblock main -%} diff --git a/templates/section.html b/templates/section.html new file mode 100644 index 000000000..465981bd0 --- /dev/null +++ b/templates/section.html @@ -0,0 +1,15 @@ +{%- extends "base.html" -%} + +{%- block main -%} +
{{ section.title }}
+ {{ section.content | safe }} + + {% for post in section.pages %} + +

{{ post.title }}

+
{{ post.date | date(format="%b %e, %Y") }}
+
+ {% else %} + No posts yet. + {% endfor %} +{%- endblock main -%}