Doughnut is a Personal Knowledge Management (PKM) tool combining zettelkasten style of knowledge capture with some features to enhance learning (spaced-repetition, smart reminders) and ability to share knowledge bits with other people (for buddy/team learning).
For more background info you can read::
π From the root of doughnut directory, in a terminal, run:
Please ensure your git configuration is appropriate for your OS to respect the correct line endings:
git config --global core.autocrlf input
git add --renormalize .Install Nix package manager if you haven't already with
./setup-doughnut-dev.shFor developers on macOS 15 Sequoia, please run the below if you face issue installing or starting up nix (see here for full details)
curl --proto '=https' --tlsv1.2 -sSf -L https://github.com/NixOS/nix/raw/master/scripts/sequoia-nixbld-user-migration.sh | bash -Install direnv and activate direnv
macOS: brew install direnv
Ubuntu/Debian (includes WSL2 with Ubuntu): sudo apt-get install -y direnv
Fedora: sudo dnf install direnv
Change directory to your cloned doughnut folder path and run the below:
echo 'eval "$(direnv hook bash)"' >> ~/.bashrc
echo 'eval "$(direnv hook zsh)"' >> ~/.zshrc
direnv allowSubsequently, each time your change directory into your doughnut cloned folder, nix flakes will be auto loaded. Each time you change directory away from doughnut directory, the nix environment will be auto unloaded.
Ensure your OS (WSL2/Ubuntu/Fedora, etc) has /bin/sh point to bash.
If you are using Ubuntu where /bin/sh is symlinked to dash, please
run sudo dpkg-reconfigure dash and answer "No" to reconfigure to bash as default.
πͺ π¨ WSL2 with WSLg:
Additional things to note for Microsoft Windows10/Windows11 developers using WSL2g with Ubuntu-24.04.
π¨ DO NOT CLONE doughnut source to a MS Windows directory (e.g. /mnt/c/)!!! Instead, in your WSL2 session, cd ~ then git clone [email protected]:nerds-odd-e/doughnut.git
~/.sdkman dir and comment out sdkman related config in ~/.<SHELL>rc.
π¦ π§ π¨ ONLY if you hit problems with the above quick-start setup, you should manually walk through the local development environment nix setup.
From the root of your doughnut directory, start your doughnut nix development environment with
If you have direnv installed & configured right, just cd to the path where you cloned doughnut Github source code and the nix develop environment will autoload, OTHERWISE run:
nix developStart the complete development environment (RECOMMENDED)
pnpm sutThis single command starts everything you need for local development:
- Backend (with auto-reload on Java code changes)
- Frontend (with hot module replacement on Vue code changes)
- Mountebank (mock external services)
- Cypress IDE (for running/debugging e2e tests)
All services will automatically restart when you make code changes, so you can focus on development without manual restarts.
If you only need the backend for testing or development:
pnpm backend:sut- The backend will automatically restart when you change backend Java code (powered by Spring Boot DevTools + Gradle continuous build).
- You only need to rerun it manually if you reset the database.
- From doughnut source root directory:
pnpm backend:verifyWe use cucumber Gherkin + cypress (test driver) Javascript/Typescript framework to drive the end-to-end test suite.
The Cypress+Cucumber tests are in JavaScript/TypeScript.
-
We use mountebank to mock external backend services.
- To run mountebank in debug mode, run
pnpm mb --loglevel debug.
- To run mountebank in debug mode, run
For MS Windows WSL2 users:
- you need to ensure your WSL2 Linux has
xvfbinstalled manually before you can run cypress. This is not managed by Nix! export NODE_OPTIONS="--max-old-space-size=4096"before running any cypress related commands ( e.g.cy:openorcypress run).
| Purpose | Command (run from doughnut source root directory) |
|---|---|
| π Start full dev environment (RECOMMENDED) | pnpm sut (starts backend, frontend, mountebank & Cypress IDE - all with auto-reload) |
| Install needed e2e tooling | pnpm --frozen-lockfile recursive install |
| Start backend only | pnpm backend:sut (starts backend SUT with auto-reload) |
| Start Mock for external backend | pnpm start:mb (starts mocked external backend ONLY) |
| Start ONLY the Cypress IDE | pnpm cy:open (starts Cypress IDE ONLY) |
| Run one feature headlessly | pnpm cypress run --spec **/name.feature (expect services are already running, run the matched feature files only in headless mode) |
| Run all e2e test | pnpm verify (compile frontend assets, start backend SUT, mountebank virtual service provider & cypress headless e2e testing) |
| Generate TypeScript Interfaces | pnpm generateTypeScript (Generate TypeScript Interfaces from backend JSON classes. Should run manually every time backend service changes) |
| Purpose | Location |
|---|---|
| feature files | e2e_test/features/*.feature |
| step definitions | e2e_test/step_definitions/*.ts |
| custom DSL | e2e_test/support/*.ts |
| cucumber hooks | e2e_test/step_definitions/common/hook.ts |
| test fixtures | e2e_test/fixtures/*.* |
| cypress config | e2e_test/config/*.json |
| cypress plugins | e2e_test/plugins/index.ts |
You can find the database migrations in backend/src/main/resources/db/migration/.
The migrations are run automatically when the backend app starts up.
It will also run the migrations for test when you run pnpm backend:test.
To trigger the test DB migration manually, run backend/gradlew migrateTestDB.
To connect to the local DB: mysql -S $MYSQL_HOME/mysql.sock -u doughnut -p (password=doughnut).
We chose Vue3 + Vite to build our frontend.
The TypeScript code calling the backend services is generated from the backend code. Run
pnpm generateTypeScriptTo do the code generation. There are two steps in this command:
- Generate openAPI docs from the backend service into
./open_api_docs.yaml. - Generate TypeScript interfaces from the openAPI docs, into
frontend/src/generated.
If the step 1 is not done, a unit test will fail. If the step 2 is not done, CI will fail (./assert_generated_type_script_up_to_date.sh).
From doughnut source root directory
pnpm frontend:verifypnpm frontend:sutBuild & Bundle Vue3 frontend web-app assets and startup backend app (backend webapp will launch on port 9081)
pnpm frontend:build
pnpm backend:sutExpect to find minified and uglified web bundle assets in backend/src/main/resources/static
directory:
β― pwd
/home/lia/doughnut/backend/src/main/resources/static
β― tree -L 3
.
βββ assets
βΒ Β βββ main.32137c85.js
βΒ Β βββ main.b097c993.css
βΒ Β βββ vendor.8f9eb49d.js
βββ index.html
βββ odd-e.ico
βββ odd-e.png
1 directory, 6 filesWhen you have the backend and frontend running, you can manually test the application.
Visit http://localhost:5173/ to see the frontend web-app. The backend API is available at http://localhost:9081, and you will see the built frontend web-app there as well, but it wil not auto-reload on changes. So stay with the 5173 port.
Local test accounts:
- User: 'old_learner', Password: 'password'
- User: 'another_old_learner', Password: 'password'
- User: 'admin', Password: 'password'
- pnpm: To clean up packages installed by pnpm, you can run pnpm store prune to remove unused packages from the store. To remove all packages for a specific project, navigate to the project directory and run pnpm recursive uninstall to uninstall all dependencies in the project and its subdirectories.
- direnv: To stop direnv from automatically loading the environment, you can simply delete the .envrc/ file in the project directory or run direnv deny in the project directory. To uninstall direnv, use the package manager you installed it with (e.g., brew uninstall direnv for macOS).
- Nix: If you want to remove the Nix package manager and all packages installed through it, you can run sudo rm -rf /nix to delete the Nix store. To uninstall Nix completely, follow the official Nix documentation for uninstallation instructions.
- We welcome product ideas and code contribution.
- Collaborate over:
- GitHub Discussions for product ideas/features,
- GitHub Issues for reporting issues or bugs, OR
- doughnut gitter.im
- FOSS style; Fork and submit GitHub PR.
- Please keep the PR small and on only one topic
- The code need to come with tests.