diff --git a/.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..65667de --- /dev/null +++ b/.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md @@ -0,0 +1,17 @@ +## Expected Behavior + + +## Actual Behavior + + +## Steps to Reproduce the Problem + + 1. + 1. + 1. + +## Specifications + + - Version: + - Platform: + - Operating System: \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..dd84ea7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..bbcbbe7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..d5e3ee4 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,7 @@ +# Fixes + +## Proposed Changes + + - + - + - \ No newline at end of file diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 7282312..aca121d 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -4,9 +4,9 @@ on: schedule: - cron: "0 0 * * 0" push: - branches: [main, develop, "feature/**"] + branches: [main, develop, "feature/**", "release/**"] pull_request: - branches: [main, develop, "feature/**"] + branches: [main, develop, "feature/**", "release/**"] jobs: build: @@ -27,4 +27,23 @@ jobs: - name: Install dependencies run: dotnet restore src/Tomas.Terminal - name: Build - run: dotnet build src/Tomas.Terminal -c Release --no-restore + run: dotnet build src/Tomas.Terminal -c Release --no-restore --nologo + + test: + timeout-minutes: 15 + continue-on-error: true + runs-on: ubuntu-latest + strategy: + matrix: + dotnet: ["6.0.x"] + + steps: + - uses: actions/checkout@v2 + - name: Setup .NET + uses: actions/setup-dotnet@v1 + with: + dotnet-version: ${{ matrix.dotnet }} + - name: Install test dependencies + run: dotnet restore src/Tomas.Tests + - name: Test + run: dotnet test src --no-restore --nologo \ No newline at end of file diff --git a/Changelog.md b/Changelog.md index 9453408..038027e 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,10 +2,10 @@ ## v23.0 -- Calendar versioning, `YY.MINOR.MICRO` - +- Split versioning systems between kernal and terminal + - Calendar versioning, `YY.MINOR.MICRO`, for kernal + - Semantic versioning for terminal - If the file system is activate, system activity will be logged - - Build number based on commit hash Due to the huge time skip and architectural changes, I've (retroactively) switched to calendar versioning with ``v0.1`` now known as ``v20.1`` as well. diff --git a/README.md b/README.md index 41a0ebc..0a66f0d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,20 @@ # TOMAS - +

+ +
+ +


+

+

+ GitHub license + GitHub Workflow Status + GitHub commit activity +
+ Contributor Covenant + Code Climate maintainability + Code Climate technical debt +

TOMAS (**To**ny's **Ma**naged Operating **S**ystem) is a hobby operating system based on the [COSMOS](https://github.com/CosmosOS/Cosmos) framework that comes with a respective terminal emulator. @@ -9,15 +23,11 @@ TOMAS (**To**ny's **Ma**naged Operating **S**ystem) is a hobby operating system ### Prerequisites - Windows 10 or later - - Visual Studio 2022 - - .NET 6 or later - - COSMOS User Kit v2022 or later - - VMWare Workstation Player ## License -This project is licensed under the BSD 3-Clause license - see the [LICENSE](LICENSE) file for details. +In jurisdictions that recognize copyright waivers, I've [waived all copyright](UNLICENSE) and related or neighboring rights for to this project. In areas where these waivers are not recognized, [BSD-3-Clause](LICENSE) is enforced. diff --git a/UNLICENSE b/UNLICENSE new file mode 100644 index 0000000..fdddb29 --- /dev/null +++ b/UNLICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +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 NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS 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. + +For more information, please refer to diff --git a/assets/logo.png b/assets/logo.png new file mode 100644 index 0000000..0122538 Binary files /dev/null and b/assets/logo.png differ diff --git a/assets/logo.svg b/assets/logo.svg new file mode 100644 index 0000000..57131e1 --- /dev/null +++ b/assets/logo.svg @@ -0,0 +1,246 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/screenshot.png b/assets/screenshot.png similarity index 100% rename from screenshot.png rename to assets/screenshot.png diff --git a/assets/social-preview.png b/assets/social-preview.png new file mode 100644 index 0000000..72e8c2e Binary files /dev/null and b/assets/social-preview.png differ diff --git a/assets/social-preview.xcf b/assets/social-preview.xcf new file mode 100644 index 0000000..70fef93 Binary files /dev/null and b/assets/social-preview.xcf differ diff --git a/code_of_conduct.md b/code_of_conduct.md new file mode 100644 index 0000000..1b9bfcd --- /dev/null +++ b/code_of_conduct.md @@ -0,0 +1,132 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +[INSERT CONTACT METHOD]. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available +at [https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations diff --git a/src/.editorconfig b/src/.editorconfig index 7868c26..ebdac3a 100644 --- a/src/.editorconfig +++ b/src/.editorconfig @@ -13,6 +13,8 @@ indent_style = space indent_size = 4 insert_final_newline = false trim_trailing_whitespace = true +dotnet_style_operator_placement_when_wrapping = beginning_of_line +tab_width = 4 # C# files [*.cs] @@ -50,7 +52,7 @@ dotnet_style_predefined_type_for_member_access = true:suggestion # Use camel_case for private or internal constant fields dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields -dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style +dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style dotnet_naming_symbols.constant_fields.applicable_kinds = field dotnet_naming_symbols.constant_fields.required_modifiers = const @@ -62,7 +64,7 @@ dotnet_naming_style.pascal_case_style.capitalization = pascal_case # internal and private fields should be _camel_case dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion dotnet_naming_rule.camel_case_for_private_internal_fields.symbols = private_internal_fields -dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style +dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style dotnet_naming_symbols.private_internal_fields.applicable_kinds = field dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal @@ -122,3 +124,9 @@ csharp_space_between_method_declaration_name_and_open_parenthesis = false csharp_space_between_method_declaration_parameter_list_parentheses = false csharp_space_between_parentheses = false csharp_space_between_square_brackets = false +csharp_using_directive_placement = outside_namespace:silent +csharp_prefer_simple_using_statement = true:suggestion +csharp_prefer_braces = when_multiline:silent +csharp_style_namespace_declarations = file_scoped:silent +csharp_style_prefer_method_group_conversion = true:silent +csharp_style_prefer_top_level_statements = true:silent diff --git a/src/TOMAS.sln b/src/TOMAS.sln index 5fff92d..d18435f 100644 --- a/src/TOMAS.sln +++ b/src/TOMAS.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.4.33205.214 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tomas.Common", "Tomas.Common\Tomas.Common.csproj", "{C50F3A6F-CFF4-4725-A1A5-21C5A2BC3321}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tomas.Core", "Tomas.Core\Tomas.Core.csproj", "{C50F3A6F-CFF4-4725-A1A5-21C5A2BC3321}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{59C9B3FC-B1EE-4C23-9BD9-D33074BF1334}" ProjectSection(SolutionItems) = preProject @@ -13,13 +13,16 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ..\LICENSE = ..\LICENSE ..\README.md = ..\README.md TOMAS.sln.licenseheader = TOMAS.sln.licenseheader + ..\UNLICENSE = ..\UNLICENSE EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tomas.Interface", "Tomas.Interface\Tomas.Interface.csproj", "{DAA9EDF4-83C7-4271-9805-FD6CE29E1796}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tomas.Terminal", "Tomas.Terminal\Tomas.Terminal.csproj", "{49E67E55-F9D2-419A-8097-38F39E98A95E}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tomas.Kernel", "Tomas.Kernal\Tomas.Kernel.csproj", "{20750C95-A3C7-4958-BA9F-56E4C3BD0293}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tomas.Kernel", "Tomas.Kernel\Tomas.Kernel.csproj", "{B70BDFD5-64BA-4FCE-A00F-DDD209C2C0FB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tomas.Tests", "Tomas.Tests\Tomas.Tests.csproj", "{76AD2140-2975-43DA-89A9-0BEC70B2ECDD}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -39,10 +42,14 @@ Global {49E67E55-F9D2-419A-8097-38F39E98A95E}.Debug|Any CPU.Build.0 = Debug|Any CPU {49E67E55-F9D2-419A-8097-38F39E98A95E}.Release|Any CPU.ActiveCfg = Release|Any CPU {49E67E55-F9D2-419A-8097-38F39E98A95E}.Release|Any CPU.Build.0 = Release|Any CPU - {20750C95-A3C7-4958-BA9F-56E4C3BD0293}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {20750C95-A3C7-4958-BA9F-56E4C3BD0293}.Debug|Any CPU.Build.0 = Debug|Any CPU - {20750C95-A3C7-4958-BA9F-56E4C3BD0293}.Release|Any CPU.ActiveCfg = Release|Any CPU - {20750C95-A3C7-4958-BA9F-56E4C3BD0293}.Release|Any CPU.Build.0 = Release|Any CPU + {B70BDFD5-64BA-4FCE-A00F-DDD209C2C0FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B70BDFD5-64BA-4FCE-A00F-DDD209C2C0FB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B70BDFD5-64BA-4FCE-A00F-DDD209C2C0FB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B70BDFD5-64BA-4FCE-A00F-DDD209C2C0FB}.Release|Any CPU.Build.0 = Release|Any CPU + {76AD2140-2975-43DA-89A9-0BEC70B2ECDD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {76AD2140-2975-43DA-89A9-0BEC70B2ECDD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {76AD2140-2975-43DA-89A9-0BEC70B2ECDD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {76AD2140-2975-43DA-89A9-0BEC70B2ECDD}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/TOMAS.sln.licenseheader b/src/TOMAS.sln.licenseheader index df33244..81ee8df 100644 --- a/src/TOMAS.sln.licenseheader +++ b/src/TOMAS.sln.licenseheader @@ -1,4 +1,8 @@ extensions: designer.cs generated.cs extensions: .cs .cpp .h .fs -// I license this project under the BSD 3-Clause license. -// See the LICENSE file in the project root for more information. \ No newline at end of file +/* +In jurisdictions that recognize copyright waivers, I've waived all copyright +and related or neighboring rights for to this project. In areas where these +waivers are not recognized, BSD-3-Clause is enforced. +See the (UN)LICENSE file in the project root for more information. +*/ \ No newline at end of file diff --git a/src/Tomas.Common/GlobalUsing.cs b/src/Tomas.Common/GlobalUsing.cs deleted file mode 100644 index c66f29a..0000000 --- a/src/Tomas.Common/GlobalUsing.cs +++ /dev/null @@ -1,2 +0,0 @@ -global using System.Diagnostics.CodeAnalysis; -global using Tomas.Interface; diff --git a/src/Tomas.Common/Programs/Clear.cs b/src/Tomas.Common/Programs/Clear.cs deleted file mode 100644 index afeec90..0000000 --- a/src/Tomas.Common/Programs/Clear.cs +++ /dev/null @@ -1,13 +0,0 @@ -// I license this project under the BSD 3-Clause license. -// See the LICENSE file in the project root for more information. - -namespace Tomas.Common.Programs; - -public class Clear : IProgram -{ - public bool Run(IShell shell) - { - Console.Clear(); - return true; - } -} \ No newline at end of file diff --git a/src/Tomas.Common/Programs/Commands.cs b/src/Tomas.Common/Programs/Commands.cs deleted file mode 100644 index c2590c2..0000000 --- a/src/Tomas.Common/Programs/Commands.cs +++ /dev/null @@ -1,16 +0,0 @@ -// I license this project under the BSD 3-Clause license. -// See the LICENSE file in the project root for more information. - -namespace Tomas.Common.Programs; - -public class Commands : IProgram -{ - public bool Run(IShell shell) - { - Console.WriteLine($"Commands:"); - var progs = shell.Programs; - foreach (var commands in progs.Keys) - Console.WriteLine(commands); - return true; - } -} \ No newline at end of file diff --git a/src/Tomas.Common/Programs/FenSay.cs b/src/Tomas.Common/Programs/FenSay.cs deleted file mode 100644 index 0dd73a4..0000000 --- a/src/Tomas.Common/Programs/FenSay.cs +++ /dev/null @@ -1,38 +0,0 @@ -// I license this project under the BSD 3-Clause license. -// See the LICENSE file in the project root for more information. - -namespace Tomas.Common.Programs; - -public class FenSay : IProgram -{ - - /// - /// Fennec art by Todd Vargo - /// - const string _fennec = @" \/ - /\ /\ - //\\_//\\ ____ - \_ _/ / / - / * * \ /^^^] - \_\O/_/ [ ] - / \_ [ / - \ \_ / / - [ [ / \/ _/ - _[ [ \ /_/"; - - readonly string[] _phrases = - { - "[SCREAMS IN FENNEC]", - "Some people call me a coffee fox.", - "Drink Soda. It makes you see faster.", - "10/10, Wouldn't Recommend." - }; - - public bool Run(IShell shell) - { - var rng = new Random(); - var phrases = _phrases[rng.Next(_phrases.Length)]; - Console.WriteLine($"{phrases}{Environment.NewLine}{_fennec}"); - return true; - } -} \ No newline at end of file diff --git a/src/Tomas.Core/Programs/Clear.cs b/src/Tomas.Core/Programs/Clear.cs new file mode 100644 index 0000000..080ae07 --- /dev/null +++ b/src/Tomas.Core/Programs/Clear.cs @@ -0,0 +1,16 @@ +/* +In jurisdictions that recognize copyright waivers, I've waived all copyright +and related or neighboring rights for to this project. In areas where these +waivers are not recognized, BSD-3-Clause is enforced. +See the (UN)LICENSE file in the project root for more information. +*/ +namespace Tomas.Core.Programs; + +public class Clear : IProgram +{ + public bool Run(IShell shell) + { + Console.Clear(); + return true; + } +} \ No newline at end of file diff --git a/src/Tomas.Core/Programs/Commands.cs b/src/Tomas.Core/Programs/Commands.cs new file mode 100644 index 0000000..70e0348 --- /dev/null +++ b/src/Tomas.Core/Programs/Commands.cs @@ -0,0 +1,19 @@ +/* +In jurisdictions that recognize copyright waivers, I've waived all copyright +and related or neighboring rights for to this project. In areas where these +waivers are not recognized, BSD-3-Clause is enforced. +See the (UN)LICENSE file in the project root for more information. +*/ +namespace Tomas.Core.Programs; + +public class Commands : IProgram +{ + public bool Run(IShell shell) + { + Console.WriteLine($"Commands:"); + var progs = shell.Programs; + foreach (var commands in progs.Keys) + Console.WriteLine(commands); + return true; + } +} \ No newline at end of file diff --git a/src/Tomas.Core/Programs/FenSay.cs b/src/Tomas.Core/Programs/FenSay.cs new file mode 100644 index 0000000..9b227cf --- /dev/null +++ b/src/Tomas.Core/Programs/FenSay.cs @@ -0,0 +1,41 @@ +/* +In jurisdictions that recognize copyright waivers, I've waived all copyright +and related or neighboring rights for to this project. In areas where these +waivers are not recognized, BSD-3-Clause is enforced. +See the (UN)LICENSE file in the project root for more information. +*/ +namespace Tomas.Core.Programs; + +public class FenSay : IProgram +{ + + /// + /// Fennec art by Todd Vargo + /// + const string _fennec = @" \/ + /\ /\ + //\\_//\\ ____ + \_ _/ / / + / * * \ /^^^] + \_\O/_/ [ ] + / \_ [ / + \ \_ / / + [ [ / \/ _/ + _[ [ \ /_/"; + + readonly string[] _phrases = + { + "[SCREAMS IN FENNEC]", + "Some people call me a coffee fox.", + "Drink Soda. It makes you see faster.", + "10/10, Wouldn't Recommend." + }; + + public bool Run(IShell shell) + { + var rng = new Random(); + var phrases = _phrases[rng.Next(_phrases.Length)]; + Console.WriteLine($"{phrases}{Environment.NewLine}{_fennec}"); + return true; + } +} \ No newline at end of file diff --git a/src/Tomas.Common/Tomas.Common.csproj b/src/Tomas.Core/Tomas.Core.csproj similarity index 51% rename from src/Tomas.Common/Tomas.Common.csproj rename to src/Tomas.Core/Tomas.Core.csproj index 6a91aed..665370e 100644 --- a/src/Tomas.Common/Tomas.Common.csproj +++ b/src/Tomas.Core/Tomas.Core.csproj @@ -9,11 +9,4 @@ - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - diff --git a/src/Tomas.Core/Usings.cs b/src/Tomas.Core/Usings.cs new file mode 100644 index 0000000..511e2b8 --- /dev/null +++ b/src/Tomas.Core/Usings.cs @@ -0,0 +1,9 @@ +/* +In jurisdictions that recognize copyright waivers, I've waived all copyright +and related or neighboring rights for to this project. In areas where these +waivers are not recognized, BSD-3-Clause is enforced. +See the (UN)LICENSE file in the project root for more information. +*/ +global using System.Diagnostics.CodeAnalysis; +global using System.Diagnostics; +global using Tomas.Interface; diff --git a/src/Tomas.Interface/IProgram.cs b/src/Tomas.Interface/IProgram.cs index ccdfb70..dd7cf90 100644 --- a/src/Tomas.Interface/IProgram.cs +++ b/src/Tomas.Interface/IProgram.cs @@ -1,14 +1,18 @@ -// I license this project under the BSD 3-Clause license. -// See the LICENSE file in the project root for more information. +/* +In jurisdictions that recognize copyright waivers, I've waived all copyright +and related or neighboring rights for to this project. In areas where these +waivers are not recognized, BSD-3-Clause is enforced. +See the (UN)LICENSE file in the project root for more information. +*/ namespace Tomas.Interface; public interface IProgram { - /// - /// The program's main entry point. Boolean behaves as an exit point. - /// True and False are the equivalent to C's 0 and 1, i.e. "Success" and "Failure," respectfully. - /// - /// Allows the program to interact with the shell. - /// Exit back to shell. - bool Run(IShell shell); + /// + /// The program's main entry point. Boolean behaves as an exit point. + /// True and False are the equivalent to C's 0 and 1, i.e. "Success" and "Failure," respectfully. + /// + /// Allows the program to interact with the shell. + /// Exit back to shell. + bool Run(IShell shell); } \ No newline at end of file diff --git a/src/Tomas.Interface/IShell.cs b/src/Tomas.Interface/IShell.cs index fce577d..398eb91 100644 --- a/src/Tomas.Interface/IShell.cs +++ b/src/Tomas.Interface/IShell.cs @@ -1,11 +1,14 @@ -// I license this project under the BSD 3-Clause license. -// See the LICENSE file in the project root for more information. - +/* +In jurisdictions that recognize copyright waivers, I've waived all copyright +and related or neighboring rights for to this project. In areas where these +waivers are not recognized, BSD-3-Clause is enforced. +See the (UN)LICENSE file in the project root for more information. +*/ namespace Tomas.Interface; public interface IShell { - string ReadLine { get; } + string ReadLine { get; } - Dictionary Programs { get; } + Dictionary Programs { get; } } \ No newline at end of file diff --git a/src/Tomas.Interface/Usings.cs b/src/Tomas.Interface/Usings.cs new file mode 100644 index 0000000..e69de29 diff --git a/src/Tomas.Kernal/GlobalUsing.cs b/src/Tomas.Kernal/GlobalUsing.cs deleted file mode 100644 index b847d34..0000000 --- a/src/Tomas.Kernal/GlobalUsing.cs +++ /dev/null @@ -1,7 +0,0 @@ -global using Tomas.Common.Programs; -global using Tomas.Interface; -global using Tomas.Kernel.Programs; -global using Cosmos.System.FileSystem; -global using Cosmos.System.FileSystem.VFS; -global using Tomas.Common; -global using Os = Cosmos.System; \ No newline at end of file diff --git a/src/Tomas.Kernal/Kernel.cs b/src/Tomas.Kernal/Kernel.cs deleted file mode 100644 index e5f4150..0000000 --- a/src/Tomas.Kernal/Kernel.cs +++ /dev/null @@ -1,51 +0,0 @@ -// I license this project under the BSD 3-Clause license. -// See the LICENSE file in the project root for more information. - -namespace Tomas.Kernel; - -public class Kernel : Os.Kernel -{ - - protected override void BeforeRun() - { - SysFS.Initialize(); - - if (!SysMeta.IsFSActive) - Console.WriteLine($"{SysMeta.NAME} booted with errors."); - else - Console.WriteLine($"{SysMeta.NAME} booted successfully."); - } - - protected override void Run() - { - while (true) - { - var shell = new Shell(); - var command = shell.ReadLine; - var programs = shell.Programs; - - if (!programs.TryGetValue(command, out var program)) - { - Console.WriteLine("Command Not Found."); - continue; - } - - try - { - var start = program.Run(shell); - switch (start) - { - case true: - continue; - case false: - Console.WriteLine("Program closed unexpectedly."); - continue; - } - } - catch (Exception err) - { - Console.WriteLine(err.Message); - } - } - } -} diff --git a/src/Tomas.Kernal/Programs/About.cs b/src/Tomas.Kernal/Programs/About.cs deleted file mode 100644 index 365c563..0000000 --- a/src/Tomas.Kernal/Programs/About.cs +++ /dev/null @@ -1,17 +0,0 @@ -// I license this project under the BSD 3-Clause license. -// See the LICENSE file in the project root for more information. - -namespace Tomas.Kernel.Programs; - -public class About : IProgram -{ - public bool Run(IShell shell) - { - Console.WriteLine($"TOMAS v{SysMeta.VERSION} ({SysMeta.BuildNumber}) is a hobby operating system written in C# using the COSMOS framework.{Environment.NewLine}Commands:"); - var progs = shell.Programs; - foreach (var commands in progs.Keys) - Console.WriteLine(commands); - - return true; - } -} \ No newline at end of file diff --git a/src/Tomas.Common/GitInfo.txt b/src/Tomas.Kernel/GitInfo.txt similarity index 100% rename from src/Tomas.Common/GitInfo.txt rename to src/Tomas.Kernel/GitInfo.txt diff --git a/src/Tomas.Kernel/Globalization/CST.cs b/src/Tomas.Kernel/Globalization/CST.cs new file mode 100644 index 0000000..1063563 --- /dev/null +++ b/src/Tomas.Kernel/Globalization/CST.cs @@ -0,0 +1,101 @@ +/* +In jurisdictions that recognize copyright waivers, I've waived all copyright +and related or neighboring rights for to this project. In areas where these +waivers are not recognized, BSD-3-Clause is enforced. +See the (UN)LICENSE file in the project root for more information. +*/ +namespace Tomas.Kernel.Globalization; + +public class CST +{ + const char CARET = '^'; + const string LF = "\u000A"; + const string CR = "\u000D"; + const string CRLF = "\u000D\u000A"; + const string LS = "\u2028"; + + /// + /// Gets the value from the digit-based key. + /// + /// Returns the entry + public static string Parse(string content, int key) => Parse(content, key.ToString()); + + /// + /// Gets the value from the string-based key. + /// + /// Returns the entry + public static string Parse(string content, string key) + { + var entries = NormalizeEntries(content); + return GetEntry(entries, key); + } + + /// + /// Replaces the document's line endings with the native system line endings. + /// + /// This stage ensures there are no crashes during parsing. + /// The content of the document. + /// The document's content with native system line endings. + static IEnumerable NormalizeEntries(string content) + { + // Check if the document already uses native system line endings. + if (!content.Contains(Environment.NewLine)) + { + // If not, check for and replace other line ending types. + if (content.Contains(LF)) + content = content.Replace(LF, Environment.NewLine); + + if (content.Contains(CR)) + content = content.Replace(CR, Environment.NewLine); + + if (content.Contains(CRLF)) + content = content.Replace(CRLF, Environment.NewLine); + + if (content.Contains(LS)) + content = content.Replace(LS, Environment.NewLine); + } + + // Split the content by the caret and newline characters. + var lines = content.Split(new[] { $"{CARET}{Environment.NewLine}" }, + StringSplitOptions.RemoveEmptyEntries); + + // Filter out any lines that start with "//", "#", "/*", or end with "*/". + return lines.Where(line => + !line.StartsWith("//") && + !line.StartsWith("#") && + !line.StartsWith("/*") && + !line.EndsWith("*/")) + .AsEnumerable(); + } + + /// + /// Retrieves the value for the specified key from the given entries. + /// + /// The entries to search through. + /// The key to search for. + /// The value for the specified key, or a default string if not found. + static string GetEntry(IEnumerable entries, string key) + { + // Iterate through the entries. + foreach (var entry in entries) + { + // If the line doesn't start with the key, keep searching. + if (!entry.StartsWith(key)) + continue; + + // Locate the index of the caret character. + var startIndex = entry.IndexOf(CARET); + // Get the line from the caret character to the end of the string. + var line = entry[startIndex..]; + + // Return the line with the caret characters trimmed. + return line.TrimStart(CARET).TrimEnd(CARET); + } + + // If no entry is found, return a default string. + return "***MISSING***"; + } + +} + + diff --git a/src/Tomas.Kernel/Globalization/IUIText.cs b/src/Tomas.Kernel/Globalization/IUIText.cs new file mode 100644 index 0000000..b570366 --- /dev/null +++ b/src/Tomas.Kernel/Globalization/IUIText.cs @@ -0,0 +1,23 @@ +/* +In jurisdictions that recognize copyright waivers, I've waived all copyright +and related or neighboring rights for to this project. In areas where these +waivers are not recognized, BSD-3-Clause is enforced. +See the (UN)LICENSE file in the project root for more information. +*/ +namespace Tomas.Kernel.Globalization; + +public interface IUIText +{ + /// + /// The base directory for the language files. + /// + string[] BasePath { get; set; } + + /// + /// Get the text for the given id and key. + /// + /// The id of the text. + /// The key of the text. + /// The text for the given id and key. + string GetText(int id, int key); +} diff --git a/src/Tomas.Kernel/Globalization/UIText.cs b/src/Tomas.Kernel/Globalization/UIText.cs new file mode 100644 index 0000000..4c9c3fe --- /dev/null +++ b/src/Tomas.Kernel/Globalization/UIText.cs @@ -0,0 +1,104 @@ +/* +In jurisdictions that recognize copyright waivers, I've waived all copyright +and related or neighboring rights for to this project. In areas where these +waivers are not recognized, BSD-3-Clause is enforced. +See the (UN)LICENSE file in the project root for more information. +*/ +namespace Tomas.Kernel.Globalization; + +public class UIText : IUIText +{ + /// + /// The language of the text. + /// + string Language { get; set; } = "english"; + + /// + /// The base directory for the language files. + /// + public string[] BasePath { get; set; } = { AppContext.BaseDirectory, "uitext" }; + + /// + /// Constructor for the UIText class. + /// + public UIText() { } + + /// + /// Constructor for the UIText class. + /// Loads the language file for the specified language. + /// + /// Language to load + public UIText(string language) + { + Language = language; + } + + /// + /// Constructor for the UIText class. + /// Loads the language file for the specified language and base directory. + /// + /// Language to load + /// Base directory for the language files. + public UIText(string language, params string[] baseBath) + { + Language = language; + BasePath = baseBath; + } + + /// + /// Get the text for the given id and key. + /// + /// The id of the text. + /// The key of the text. + /// The text for the given id and key. + public string GetText(int id, int key) => GetText(id, key.ToString()); + + /// + /// Get the text for the given id and key. + /// + /// The id of the text. + /// The key of the text. + /// The text for the given id and key. + public string GetText(int id, string key) + { + // Combine the base path and language path to get the full path of the language file. + var basePath = Path.Combine(BasePath); + var langPath = Path.Combine(basePath, $"{Language}.dir"); + + // Get all the files in the language directory. + var files = Directory.GetFiles(langPath); + + // Iterate through the files in the language directory. + foreach (var file in files) + { + // Skip files that do not have the ".cst" extension. + if (!file.Contains(".cst")) + continue; + + // Get the id of the current file. + var ids = Path.GetFileName(file); + var second = ids.IndexOf("_", 1, StringComparison.InvariantCultureIgnoreCase); + + if (second == -1) + continue; + + ids = ids.Substring(1, second - 1); + + // If the id of the current file does not match the id passed to the function, + // skip to the next file. + if (ids != id.ToString()) + continue; + + // Read the content of the current file. + var content = File.ReadAllText(file); + + // Return the text for the specified key. + return CST.Parse(content, key); + } + + // If no text is found, return a default string. + return "***MISSING***"; + } + +} + diff --git a/src/Tomas.Kernel/Kernel.cs b/src/Tomas.Kernel/Kernel.cs new file mode 100644 index 0000000..91048a7 --- /dev/null +++ b/src/Tomas.Kernel/Kernel.cs @@ -0,0 +1,73 @@ +/* +In jurisdictions that recognize copyright waivers, I've waived all copyright +and related or neighboring rights for to this project. In areas where these +waivers are not recognized, BSD-3-Clause is enforced. +See the (UN)LICENSE file in the project root for more information. +*/ +namespace Tomas.Kernel; + +public class Kernel : Os.Kernel +{ + // This method is called before the Run method + protected override void BeforeRun() + { + // Initialize the file system + SysFS.Initialize(); + + // If the file system is not enabled, print an error message indicating that the system booted with errors + if (!SysMeta.IsFSEnabled) + Console.WriteLine($"{SysMeta.NAME} booted with errors."); + // If the file system is enabled, print a message indicating that the system booted successfully + else + Console.WriteLine($"{SysMeta.NAME} booted successfully."); + } + + // This method is the main loop of the kernel, which handles input and runs programs + protected override void Run() + { + // Run the loop indefinitely + while (true) + { + // Create a new instance of the Shell class + var shell = new Shell(); + + // Read a line of input from the user + var command = shell.ReadLine; + + // Get the dictionary of programs from the shell + var programs = shell.Programs; + + // If the command is not a key in the dictionary of programs, print an error message + // and continue to the next iteration of the loop + if (!programs.TryGetValue(command, out var program)) + { + Console.WriteLine("Command Not Found."); + continue; + } + + // Try to run the program and handle any exceptions that may be thrown + try + { + // Run the program and store the returned value in the 'start' variable + var start = program.Run(shell); + + // Check the value of 'start' and take the appropriate action + switch (start) + { + case true: + // If 'start' is true, continue to the next iteration of the loop + continue; + case false: + // If 'start' is false, print an error message and continue to the next iteration of the loop + Console.WriteLine("Program closed unexpectedly."); + continue; + } + } + catch (Exception err) + { + // If an exception is caught, print the error message and continue to the next iteration of the loop + Console.WriteLine(err.Message); + } + } + } +} diff --git a/src/Tomas.Kernel/Programs/About.cs b/src/Tomas.Kernel/Programs/About.cs new file mode 100644 index 0000000..83fcb68 --- /dev/null +++ b/src/Tomas.Kernel/Programs/About.cs @@ -0,0 +1,20 @@ +/* +In jurisdictions that recognize copyright waivers, I've waived all copyright +and related or neighboring rights for to this project. In areas where these +waivers are not recognized, BSD-3-Clause is enforced. +See the (UN)LICENSE file in the project root for more information. +*/ +namespace Tomas.Kernel.Programs; + +public class About : IProgram +{ + public bool Run(IShell shell) + { + Console.WriteLine($"TOMAS v{SysMeta.VERSION} ({SysMeta.BuildNumber}) is a hobby operating system written in C# using the COSMOS framework.{Environment.NewLine}Commands:"); + var progs = shell.Programs; + foreach (var commands in progs.Keys) + Console.WriteLine(commands); + + return true; + } +} \ No newline at end of file diff --git a/src/Tomas.Kernal/Shell.cs b/src/Tomas.Kernel/Shell.cs similarity index 77% rename from src/Tomas.Kernal/Shell.cs rename to src/Tomas.Kernel/Shell.cs index 1b49aa5..85b109a 100644 --- a/src/Tomas.Kernal/Shell.cs +++ b/src/Tomas.Kernel/Shell.cs @@ -1,6 +1,9 @@ -// I license this project under the BSD 3-Clause license. -// See the LICENSE file in the project root for more information. - +/* +In jurisdictions that recognize copyright waivers, I've waived all copyright +and related or neighboring rights for to this project. In areas where these +waivers are not recognized, BSD-3-Clause is enforced. +See the (UN)LICENSE file in the project root for more information. +*/ namespace Tomas.Kernel; public class Shell : IShell diff --git a/src/Tomas.Kernal/SysFS.cs b/src/Tomas.Kernel/SysFS.cs similarity index 56% rename from src/Tomas.Kernal/SysFS.cs rename to src/Tomas.Kernel/SysFS.cs index 56f4d58..6ad6324 100644 --- a/src/Tomas.Kernal/SysFS.cs +++ b/src/Tomas.Kernel/SysFS.cs @@ -1,19 +1,26 @@ -// I license this project under the BSD 3-Clause license. -// See the LICENSE file in the project root for more information. - +/* +In jurisdictions that recognize copyright waivers, I've waived all copyright +and related or neighboring rights for to this project. In areas where these +waivers are not recognized, BSD-3-Clause is enforced. +See the (UN)LICENSE file in the project root for more information. +*/ namespace Tomas.Kernel; static class SysFS { // The root directory of the file system - const string ROOT_DIR = "0:\\"; + public const string ROOT_DIR = "0:\\"; // The system directory, located in the root directory static string SYSTEM_DIR = $"{ROOT_DIR}\\SYSTEM\\"; static string LOG_FILE = $"{SYSTEM_DIR}system.log"; - // An instance of the CosmosVFS class, used for accessing the virtual file system - static readonly CosmosVFS _fs = new(); + public const string FS_ERROR = "File system disabled."; + + /// + /// An instance of the CosmosVFS class, used for accessing the virtual file system + /// + static CosmosVFS fileSystem = new(); /// /// Initializes the file system by creating the system directory and sysinfo.txt file @@ -23,49 +30,40 @@ static class SysFS { try { - var createSysFiles = "Creating system files."; - var setSysPref = "Writing system info."; - var fsSuccess = "File system succesfully initialized."; + // File to store system information + const string sysInfoFile = "sysinfo.txt"; - // Register the CosmosVFS instance as the virtual file system - VFSManager.RegisterVFS(_fs); + // Create system directory if it doesn't exist + if (!Directory.Exists(SYSTEM_DIR)) + fileSystem.CreateDirectory(SYSTEM_DIR); - // Create the system directory - _fs.CreateDirectory(SYSTEM_DIR); + // Create system log file if it doesn't exist + if (!File.Exists($"{SYSTEM_DIR}{LOG_FILE}")) + fileSystem.CreateFile($"{SYSTEM_DIR}{LOG_FILE}"); - _fs.CreateFile($"{SYSTEM_DIR}{LOG_FILE}"); + // Create sysinfo.txt file if it doesn't exist + if (!File.Exists($"{SYSTEM_DIR}{sysInfoFile}")) + fileSystem.CreateFile($"{SYSTEM_DIR}{sysInfoFile}"); - Console.WriteLine(createSysFiles); - File.AppendAllText(LOG_FILE, createSysFiles); - - // Create the sysinfo.txt file in the system directory - _fs.CreateFile($"{SYSTEM_DIR}sysinfo.txt"); - - Console.WriteLine(setSysPref); - - File.AppendAllText(LOG_FILE, setSysPref); - - // Write the system name, version, and build number to the sysinfo.txt file + // Write system name, version, and build number to sysinfo.txt file File.WriteAllText($"{SYSTEM_DIR}sysinfo.txt", $"{SysMeta.NAME} v{SysMeta.VERSION} ({SysMeta.BuildNumber})"); - Console.WriteLine(fsSuccess); - File.AppendAllText(LOG_FILE, fsSuccess); + // Set IsFSEnabled property of SysMeta class to true + SysMeta.IsFSEnabled = true; - // Set the IsFSActive property of the SysMeta class to true - SysMeta.IsFSActive = true; - - // Read the contents of the sysinfo.txt file and print it to the console + // Read contents of sysinfo.txt file and print to console var systemInfo = File.ReadAllText($"{SYSTEM_DIR}sysinfo.txt"); - Console.WriteLine(systemInfo); } catch (Exception err) { - // If an exception is caught, print an error message indicating that the file system failed to load + // Print error message if an exception is caught Console.WriteLine($"{err.Message}{Environment.NewLine}Warning: Error messages will not logged."); } } + + /// /// Creates a new directory at the specified path /// @@ -74,8 +72,13 @@ static class SysFS { try { + // If file system isn't enabeld, throw exception + if (!SysMeta.IsFSEnabled) + throw new IOException(FS_ERROR); + // Create the directory using the CosmosVFS instance - _fs.CreateDirectory($"{ROOT_DIR}\\{directory}"); + if (!Directory.Exists($"{ROOT_DIR}\\{directory}")) + fileSystem.CreateDirectory($"{ROOT_DIR}\\{directory}"); } catch (IOException err) { @@ -94,8 +97,13 @@ static class SysFS { try { + // If file system isn't enabeld, throw exception + if (!SysMeta.IsFSEnabled) + throw new IOException(FS_ERROR); + // Create the file using the CosmosVFS instance - _fs.CreateFile($"{ROOT_DIR}\\{path}\\{file}"); + if (!File.Exists($"{ROOT_DIR}\\{path}\\{file}")) + fileSystem.CreateFile($"{ROOT_DIR}\\{path}\\{file}"); } catch (IOException err) { @@ -114,6 +122,10 @@ static class SysFS { try { + // If file system isn't enabeld, throw exception + if (!SysMeta.IsFSEnabled) + throw new IOException(FS_ERROR); + // Get the directories in the specified path using the Directory.GetDirectories method var dirs = Directory.GetDirectories(path); diff --git a/src/Tomas.Common/SysMeta.cs b/src/Tomas.Kernel/SysMeta.cs similarity index 79% rename from src/Tomas.Common/SysMeta.cs rename to src/Tomas.Kernel/SysMeta.cs index 79ffd67..0153a0e 100644 --- a/src/Tomas.Common/SysMeta.cs +++ b/src/Tomas.Kernel/SysMeta.cs @@ -1,13 +1,14 @@ -// I license this project under the BSD 3-Clause license. -// See the LICENSE file in the project root for more information. +/* +In jurisdictions that recognize copyright waivers, I've waived all copyright +and related or neighboring rights for to this project. In areas where these +waivers are not recognized, BSD-3-Clause is enforced. +See the (UN)LICENSE file in the project root for more information. +*/ using System.Text; -namespace Tomas.Common; +namespace Tomas.Kernel; -/// -/// System metdata, such as name, version and build number. -/// -public struct SysMeta +internal struct SysMeta { /// /// The name of the operating system. @@ -26,13 +27,12 @@ public struct SysMeta /// The build number is a 6-digit number, with the first 3 digits being the first 3 digits of the commit hash /// converted to a uint, and the last 3 digits being the last 3 digits of the commit hash converted to a uint. /// - [SuppressMessage("Usage", "CA2211:Non-constant fields should not be visible")] public static string BuildNumber = $"Build {BuildNumFromCommit}"; /// - /// Let's the system know that the file system is activated. + /// Let's the kernel know that the file system is activated. /// - public static bool IsFSActive { get; set; } = false; + public static bool IsFSEnabled { get; set; } = false; /// /// Generates the build number from the commit hash. diff --git a/src/Tomas.Kernal/Tomas.Kernel.csproj b/src/Tomas.Kernel/Tomas.Kernel.csproj similarity index 78% rename from src/Tomas.Kernal/Tomas.Kernel.csproj rename to src/Tomas.Kernel/Tomas.Kernel.csproj index f747da9..f15c019 100644 --- a/src/Tomas.Kernal/Tomas.Kernel.csproj +++ b/src/Tomas.Kernel/Tomas.Kernel.csproj @@ -5,6 +5,7 @@ cosmos false + enable True enable @@ -24,10 +25,14 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + - + diff --git a/src/Tomas.Kernel/Usings.cs b/src/Tomas.Kernel/Usings.cs new file mode 100644 index 0000000..b1bfac8 --- /dev/null +++ b/src/Tomas.Kernel/Usings.cs @@ -0,0 +1,15 @@ +/* +In jurisdictions that recognize copyright waivers, I've waived all copyright +and related or neighboring rights for to this project. In areas where these +waivers are not recognized, BSD-3-Clause is enforced. +See the (UN)LICENSE file in the project root for more information. +*/ +global using System.Diagnostics.CodeAnalysis; +global using System.Diagnostics; +global using Tomas.Core.Programs; +global using Tomas.Interface; +global using Tomas.Kernel.Programs; +global using Cosmos.System.FileSystem; +global using Cosmos.System.FileSystem.VFS; +global using Tomas.Core; +global using Os = Cosmos.System; \ No newline at end of file diff --git a/src/Tomas.Terminal/GitInfo.txt b/src/Tomas.Terminal/GitInfo.txt new file mode 100644 index 0000000..ceab6e1 --- /dev/null +++ b/src/Tomas.Terminal/GitInfo.txt @@ -0,0 +1 @@ +0.1 \ No newline at end of file diff --git a/src/Tomas.Terminal/GlobalUsing.cs b/src/Tomas.Terminal/GlobalUsing.cs deleted file mode 100644 index 6169845..0000000 --- a/src/Tomas.Terminal/GlobalUsing.cs +++ /dev/null @@ -1,2 +0,0 @@ -global using Tomas.Common.Programs; -global using Tomas.Interface; \ No newline at end of file diff --git a/src/Tomas.Terminal/Program.cs b/src/Tomas.Terminal/Program.cs index 80f945a..f95cf7d 100644 --- a/src/Tomas.Terminal/Program.cs +++ b/src/Tomas.Terminal/Program.cs @@ -1,40 +1,43 @@ -// I license this project under the BSD 3-Clause license. -// See the LICENSE file in the project root for more information. - +/* +In jurisdictions that recognize copyright waivers, I've waived all copyright +and related or neighboring rights for to this project. In areas where these +waivers are not recognized, BSD-3-Clause is enforced. +See the (UN)LICENSE file in the project root for more information. +*/ namespace Tomas.Terminal; class Program { - static void Main() + static void Main() + { + while (true) + { + var shell = new Shell(); + var command = shell.ReadLine; + var programs = shell.Programs; + + if (!programs.TryGetValue(command, out var program)) + { + Console.WriteLine("Command Not Found."); + continue; + } + + try + { + var start = program.Run(shell); + switch (start) { - while (true) - { - var shell = new Shell(); - var command = shell.ReadLine; - var programs = shell.Programs; - - if (!programs.TryGetValue(command, out var program)) - { - Console.WriteLine("Command Not Found."); - continue; - } - - try - { - var start = program.Run(shell); - switch (start) - { - case true: - continue; - case false: - Console.WriteLine("Program closed unexpectedly."); - continue; - } - } - catch (Exception err) - { - Console.WriteLine(err.Message); - } - } + case true: + continue; + case false: + Console.WriteLine("Program closed unexpectedly."); + continue; } + } + catch (Exception err) + { + Console.WriteLine(err.Message); + } + } + } } \ No newline at end of file diff --git a/src/Tomas.Terminal/Programs/About.cs b/src/Tomas.Terminal/Programs/About.cs index bf3e15f..b6cb3b7 100644 --- a/src/Tomas.Terminal/Programs/About.cs +++ b/src/Tomas.Terminal/Programs/About.cs @@ -1,15 +1,16 @@ -// I license this project under the BSD 3-Clause license. -// See the LICENSE file in the project root for more information. -using Tomas.Common; - +/* +In jurisdictions that recognize copyright waivers, I've waived all copyright +and related or neighboring rights for to this project. In areas where these +waivers are not recognized, BSD-3-Clause is enforced. +See the (UN)LICENSE file in the project root for more information. +*/ namespace Tomas.Terminal.Programs; public class About : IProgram { -public bool Run(IShell shell) -{ -Console.WriteLine($"{SysMeta.NAME} Terminal Emulator v{SysMeta.BuildNumber}{Environment.NewLine}" - + "TOMAS (Tony's Managed Operating System) is a operating system written in C# using the COSMOS framework."); -return true; -} + public bool Run(IShell shell) + { + Console.WriteLine($"{TermMeta.NAME} Terminal Emulator v{TermMeta.VERSION}"); + return true; + } } \ No newline at end of file diff --git a/src/Tomas.Terminal/Shell.cs b/src/Tomas.Terminal/Shell.cs index 097c79f..f9a3989 100644 --- a/src/Tomas.Terminal/Shell.cs +++ b/src/Tomas.Terminal/Shell.cs @@ -1,14 +1,18 @@ -// I license this project under the BSD 3-Clause license. -// See the LICENSE file in the project root for more information. +/* +In jurisdictions that recognize copyright waivers, I've waived all copyright +and related or neighboring rights for to this project. In areas where these +waivers are not recognized, BSD-3-Clause is enforced. +See the (UN)LICENSE file in the project root for more information. +*/ using Tomas.Terminal.Programs; namespace Tomas.Terminal; public class Shell : IShell { - const char SYMBOL = '$'; + const char SYMBOL = '$'; - public Dictionary Programs => new() + public Dictionary Programs => new() { {"about", new About()}, {"fensay", new FenSay()}, @@ -16,13 +20,13 @@ public class Shell : IShell {"commands", new Commands()} }; - public string ReadLine - { - get - { - Console.Write(SYMBOL); - var readl = Console.ReadLine(); - return readl; - } - } + public string ReadLine + { + get + { + Console.Write(SYMBOL); + var readl = Console.ReadLine(); + return readl; + } + } } \ No newline at end of file diff --git a/src/Tomas.Terminal/TermMeta.cs b/src/Tomas.Terminal/TermMeta.cs new file mode 100644 index 0000000..8451cdb --- /dev/null +++ b/src/Tomas.Terminal/TermMeta.cs @@ -0,0 +1,52 @@ +/* +In jurisdictions that recognize copyright waivers, I've waived all copyright +and related or neighboring rights for to this project. In areas where these +waivers are not recognized, BSD-3-Clause is enforced. +See the (UN)LICENSE file in the project root for more information. +*/ +using System.Text; + +namespace Tomas.Terminal; + +/// +/// System metdata, such as name, version and build number. +/// +public struct TermMeta +{ + /// + /// The name of the operating system. + /// + public const string NAME = "TOMAS Emulator"; + + /// + /// The version of the operating system, in the Calendar Versioning format: "yy.minor.patch". + /// The year, minor, and patch version numbers are automatically extracted from the Git repository + /// using the ThisAssembly.Git.SemVer object. + /// + public const string VERSION = $"{ThisAssembly.Git.SemVer.Major}.{ThisAssembly.Git.SemVer.Minor}.{ThisAssembly.Git.SemVer.Patch}"; + + /// + /// The build number of the operating system, generated from the commit hash. + /// The build number is a 6-digit number, with the first 3 digits being the first 3 digits of the commit hash + /// converted to a uint, and the last 3 digits being the last 3 digits of the commit hash converted to a uint. + /// + public static string BuildNumber = $"Build {BuildNumFromCommit}"; + + /// + /// Generates the build number from the commit hash. + /// + /// The build number as a uint. + static uint BuildNumFromCommit + { + get + { + // Get the bytes of the commit hash as a UTF-8 encoded string + var commit = Encoding.UTF8.GetBytes(ThisAssembly.Git.Commit); + + // Convert the first 4 bytes of the commit hash to a uint and return it modulo 1000000 + // (this will give us a 6-digit number with the first 3 digits being the first 3 digits of the commit hash + // and the last 3 digits being the last 3 digits of the commit hash) + return BitConverter.ToUInt32(commit, 0) % 1000000; + } + } +} diff --git a/src/Tomas.Terminal/Tomas.Terminal.csproj b/src/Tomas.Terminal/Tomas.Terminal.csproj index f466519..91627f1 100644 --- a/src/Tomas.Terminal/Tomas.Terminal.csproj +++ b/src/Tomas.Terminal/Tomas.Terminal.csproj @@ -8,7 +8,15 @@ - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + diff --git a/src/Tomas.Terminal/Usings.cs b/src/Tomas.Terminal/Usings.cs new file mode 100644 index 0000000..bbcdb99 --- /dev/null +++ b/src/Tomas.Terminal/Usings.cs @@ -0,0 +1,10 @@ +/* +In jurisdictions that recognize copyright waivers, I've waived all copyright +and related or neighboring rights for to this project. In areas where these +waivers are not recognized, BSD-3-Clause is enforced. +See the (UN)LICENSE file in the project root for more information. +*/ +global using System.Diagnostics.CodeAnalysis; +global using System.Diagnostics; +global using Tomas.Core.Programs; +global using Tomas.Interface; \ No newline at end of file diff --git a/src/Tomas.Tests/Shell/MockProgram.cs b/src/Tomas.Tests/Shell/MockProgram.cs new file mode 100644 index 0000000..3077976 --- /dev/null +++ b/src/Tomas.Tests/Shell/MockProgram.cs @@ -0,0 +1,16 @@ +/* +In jurisdictions that recognize copyright waivers, I've waived all copyright +and related or neighboring rights for to this project. In areas where these +waivers are not recognized, BSD-3-Clause is enforced. +See the (UN)LICENSE file in the project root for more information. +*/ +namespace Tomas.Tests.Shell; + +internal class MockProgram : IProgram +{ + public bool Run(IShell shell) + { + Debug.WriteLine("Test Program."); + return true; + } +} diff --git a/src/Tomas.Tests/Shell/MockShell.cs b/src/Tomas.Tests/Shell/MockShell.cs new file mode 100644 index 0000000..0ea450a --- /dev/null +++ b/src/Tomas.Tests/Shell/MockShell.cs @@ -0,0 +1,17 @@ +/* +In jurisdictions that recognize copyright waivers, I've waived all copyright +and related or neighboring rights for to this project. In areas where these +waivers are not recognized, BSD-3-Clause is enforced. +See the (UN)LICENSE file in the project root for more information. +*/ +namespace Tomas.Tests.Shell; + +internal class MockShell : IShell +{ + public string? ReadLine { get; } + + public Dictionary Programs => new() + { + { "test", new MockProgram() }, + }; +} diff --git a/src/Tomas.Tests/ShellTests.cs b/src/Tomas.Tests/ShellTests.cs new file mode 100644 index 0000000..0f7c04f --- /dev/null +++ b/src/Tomas.Tests/ShellTests.cs @@ -0,0 +1,26 @@ +/* +In jurisdictions that recognize copyright waivers, I've waived all copyright +and related or neighboring rights for to this project. In areas where these +waivers are not recognized, BSD-3-Clause is enforced. +See the (UN)LICENSE file in the project root for more information. +*/ +using Tomas.Tests.Shell; + +namespace Tomas.Tests; + +public class ShellTests +{ + // Create a new instance of the mock shell + readonly MockShell _mockShell = new(); + + [Fact] + public void ProgramTest() + { + // Create a mock program instance + var program = new MockProgram(); + + // Assert that the Run method of the program and returns true when passed the shell object. + Assert.True(program.Run(_mockShell)); + } + +} \ No newline at end of file diff --git a/src/Tomas.Tests/Tomas.Tests.csproj b/src/Tomas.Tests/Tomas.Tests.csproj new file mode 100644 index 0000000..5c6309a --- /dev/null +++ b/src/Tomas.Tests/Tomas.Tests.csproj @@ -0,0 +1,29 @@ + + + + net6.0 + enable + enable + enable + false + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + diff --git a/src/Tomas.Tests/Usings.cs b/src/Tomas.Tests/Usings.cs new file mode 100644 index 0000000..d97cace --- /dev/null +++ b/src/Tomas.Tests/Usings.cs @@ -0,0 +1,11 @@ +/* +In jurisdictions that recognize copyright waivers, I've waived all copyright +and related or neighboring rights for to this project. In areas where these +waivers are not recognized, BSD-3-Clause is enforced. +See the (UN)LICENSE file in the project root for more information. +*/ +global using Xunit; +global using System.Diagnostics.CodeAnalysis; +global using System.Diagnostics; +global using Tomas.Core; +global using Tomas.Interface; \ No newline at end of file