Giter Site home page Giter Site logo

juspay / omnix Goto Github PK

View Code? Open in Web Editor NEW
63.0 11.0 5.0 790 KB

๐Ÿšง A Nix wrapper to improve developer experience

Home Page: https://omnix.page

License: GNU Affero General Public License v3.0

Nix 10.39% Rust 88.65% CSS 0.03% Just 0.53% JavaScript 0.29% Shell 0.11%
developer-experience nix nixos nix-flakes

omnix's Introduction

project chat

omnix

Pronounced /ษ’mหˆnษชks/

Note

๐Ÿšง omnix is in active development. It aims to supplement the Nix CLI to improve developer experience.

Usage

See https://omnix.page/

Developing

  1. Install Nix
  2. Setup direnv
  3. Clone this repo, cd to it, and run direnv allow.

This will automatically activate the nix develop shell. Open VSCode and install recommended extensions, ensuring that direnv activates in VSCode as well.

Note

If you would like to learn the tools & technology involved in this project, follow along this README noting the places where the emoji ๐ŸŽ“ is used.

Running locally

To run omnix-cli,

just watch # Or `just w`; you can also pass args, e.g.: `just w show`

To run omnix-gui,

just watch-gui # Or `just wg`

just watch-gui runs dx serve (with hot reload disabled) that will restart the desktop app after compilation.

Nix workflows

Inside the nix develop shell (activated by direnv) you can use any of the cargo or rustc commands, as well as just workflows. Nix specific commands can also be used to work with the project:

# Full nix build of CLI & GUI
nix build .#default .#gui

# Build and run the CLI
nix run
# Build and run the GUI
nix run .#gui

Contributing

Tip

Run just fmt to autoformat the source tree.

  • Run just ci to run CI locally.
  • Add documentation wherever useful.
    • Run just doc run to preview website docs; edit, and run just doc check
    • To preview Rust API docs, run just doc cargo.
  • Changes to library crates must accompany a corresponding CHANGELOG.md entry.1

Tech

GUI app (omnix-gui)

We use Dioxus to build the GUI using web technologies, as well as dioxus-signals for data reactivity.

Styling

We use Tailwind for styling; ๐ŸŽ“ familiarize yourself with it! Tailwind enables developers not familiar with design to create reasonably good looking sites. You should also ๐ŸŽ“ get familiar with CSS flexboxes (see Flexbox Froggy).

Color palette

See tailwind.config.js for colour aliases we use throughout the app. Instead of, say, text-pink-500 we use text-primary-500 ("primary" is more semantic than "pink").

Crates

Crate Description
./crates/nix_rs Rust interface to the Nix command line
./crates/nix_health Nix health check library and executable
./crates/nixci Define and build CI for Nix projects anywhere
./crates/flakreate Rich flake templates
https://github.com/juspay/direnv-rs Rust bindings for direnv

Footnotes

  1. We don't use any automatic changelog generator for this repo. โ†ฉ

omnix's People

Contributors

1vipulgupta avatar aravindgopall avatar dependabot[bot] avatar divinenaman avatar rsrohitsingh682 avatar sectore avatar shivaraj-bh avatar srid avatar vimalkumar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

omnix's Issues

Format per-check status output

Presently, we just dump the raw string representation of a check in the HTML view:

image

Instead this should be formatted nicely depending on the health check. For the cache check, for example, it should use <li> to list the caches.

[Extended scope] AI

What if we, ultimately (ie., future goal), integrated AI into the app, so the user can "talk" to the app (like in Copilot Chat)?

Example

User asks: "How do I build the docker image?"

App responds with the command (looking at the current flake output): docker load -i $(nix build .#dockerImage --print-out-paths --no-link)

Search & pagination

Large flakes, like <nixpkgs> can have thousands of outputs (such as packages). Provide an option to search and paginate them.

This functionality can also be used to latter search the module option tree.

Implementation notes

Show flake `inputs`

Currently, our flake browser displays the outputs of the flake. But we should also display the inputs. Furthermore, when the user clicks on any of these inputs, it should switch to browsing that flake (which is no different to the user manually entering that input flake's URL in the HTML input box).

CLI: Add verbosity flags

The CLI should take the following args:

  • --verbose or -v: print DEBUG logs
  • -vv: print TRACE logs
  • -q: print WARN log and above (not INFO)

(Note: you can't use -q and -v* together; is it possible to enforce this constraint using clap library? Let's make -q a stretch goal, not necessary for first PR)

The tracing library has different levels. Currently, we set the log-level to INFO. But we want the user to control that.

It should also affect the frontend logging level.

`omnix-cli` MVP roadmap

omnix-cli will be a "super CLI" for Nix of some sort. Where possible, we will expose the functionality as Rust libraries (which can be used by other clients, like omnix-gui).

To begin with, we will have omnix-cli to do two things:

Initialize flakes

om init

This should support a registry of flake templates (use our various flake-parts modules), initialize them using nix flake init as well as fill in any user-specific content using the templateGenerators idea in flake-parts/templates#7 (comment)

The goal is to have om init create flakes for any kind of stack, eventually.

See #152

Inspect flakes

Warning

To be fleshed out.

om show

On a flakified project, display a "dynamic README" of some sort that tells any product-oriented person as to how to interact with it. Eg. build the project or run it. If there are services, tell how to run these services. The 'metadata' for this should be standardized somehow. At a basic level, meta.description can be used to describe derivations (including devShells); how do we want to describe, for example, services?

Note

om show should also show a status indicator for om health (which runs https://github.com/juspay/nix-health)


Progress

Use available port if default port is already bound

โฏ nix run github:juspay/nix-browser
Launching http://127.0.0.1:3000

This works, but if the user already has a process bound to port 3000 this will fail. We want nix-browser to automatically find an available port and use that if the default port is unavailable.

Add CLI args, and `--no-open`

  • Use the clap crate to parse command line args into a Rust struct; see example, or this more complex example
  • Use the open crate to automatically open the app in the user's browser, unless --no-open is passed (which we'll use for #11)
    • Both nix run the devshell's just watch should open in the default browser

`nix_health`: Flake-specific health checks

Each flake can export the metadata (as https://github.com/DeterminateSystems/flake-schemas?) for nix_health do checks on. This includes:

  • Which Nix caches to check
  • Does the project require/recommend direnv? If so, check for direnv allow state #70
  • Minimum recommended memory
{
  flake.nix-health.default.checks = {
    caches.required = [ "nammyatri.cachix.org" ];
    direnv.enable = true;
  };
}

Some of these checks (like direnv) will require a specific flake to check against. In the case of direnv, it would also have to be a local path flake.

Add `--site-addr` option

nix run github:juspay/nix-browser -- --site-addr=127.0.0.1:9090 for example should run nix-browser in port 9090.

Add "open directory" button to open a local flake

Add a "Open directory" button here:

image

This should ideally bring up the user's native file-open dialog allowing them to select their local project directory. Then the input box is replaced with that local path (eg: /Users/user/Projects/nammayatri) which then triggers a reload of the flake info.

Implementation notes

Trusted Users can be a group of which you are part

Putting yourself into a group of trusted users is also valid.

โŒ Trusted Users
   trusted-users = @wheel
   User 'xyz' not present in trusted_users
   Add `nix.trustedUsers = [ "root" "xyz" ];` to your nixos configuration

This is in the nix manual:
image

Improve `dx fmt` and add to treefmt

See https://dioxuslabs.com/blog/release-030#autoformatting

The dx fmt command in the dev shell of #79 can be used to format the render! HTML DSL functions, but it is pretty limited.

The PR's justfile defines just fmt like this:

# Auto-format the source tree
fmt:
    treefmt
    find src/app/ -name \*.rs | grep -v state.rs | xargs -n 1 dx fmt -f

Our goal here is to remove that line, so that just fmt runs nothing but treefmt.

To do this, two things need to happen:

  1. Open a PR on https://github.com/numtide/treefmt-nix adding the dioxus formatter. Use the leptos PR for reference: numtide/treefmt-nix#108
    • Note: Dioxus is available in nixpkgs, as pkgs.dioxus-cli
  2. Create corresponding PRs on the dioxus repo to improve integration with treefmt, just like we did with leptosfmt for the aforementioned PR

Show nix command output

In some cases, a nix command can take a while to run (cf. IFD use in nammayatri). When that happens, it is useful to see live feedback (command's stdout/stderr) in the browser itself.

This can also come in handy when interacting with Nix from the browser (eg: #9).

Potential libraries to use,

Scaffold Rescript hello world

  • Choose and use a web framework for the Rust project
  • Scaffold a Rescript project in ./frontend sub directory
    • Write the necessary default.nix for it.
  • Have the Rust backend use the Rescript frontend (just Hello World)

In effect, running nix run in this repo should spin up a web server that serves the Hello World frontend.

Stale indicator for flake view

We now load flake from the signal cache (since #101), and run nix flake show only if the flake is missing from cache or the requests it by pressing the refresh button (see below):

image

We also store the SystemTime when the flake was fetched in its cache. If the flake wasn't refreshed for more than T time since it was refreshed, we should indicate somehow in the UI that the flake is "stale" and encourage the user to refresh it.

Extract and relicense nix_rs?

Hi,

I would be interested in using your nix_rs crate in one of my projects and potentially adding more functionality to it.

Would you be interested in extracting the nix_rs crate from this repository and put it into a new repository (I can help with extracting the commit history of the /crates/nix_rs/ subtree if you want) and release it under another license?
For example MIT + Apache 2.0 is the most common used license for libraries in the rust ecosystem, or maybe MPL-2.0 which - to my understanding - is something like GPL but for libraries(, as LGPL does not work for libraries in the rust ecosystem because of static linking).

(all above with "I am not a lawyer" of course).

Would love to hear your opinion on this.

Begin with visualizing `nix flake show`

As a first step, this project can simply run nix flake show --allow-import-from-derivation --json and visualize the output tree suitably, providing help suggestions (like how to nix run an app).

  • mvp #39
  • load any flake from UI (default: .)
    • handle errors
  • simpler view {apps, packages, etc.} #42
    • Demote tree view of raw show output as collapsed div below for advanced users
  • Investigate slowness on large flakes [Violation] 'click' handler took 326ms (will be solved by #107)

stretch,

`nix-health`: Add option to be quiet

Add a --quiet option that will not log anything except failing checks (that are required).

This is useful for use in shellHook of project dev shells.

Introduce persistent application state

Use a sqlite db dioxus persistance to store application state which includes:

  • Recent flakes accessed #98
  • Flake output structure #101
    • Once we "cache" the outputs in the DB, it can be shown without having re-evaluate the flake again. This can be useful for large projects with IFD, like nammayatri, or even nixpkgs. The UI will open ready to do search for packages, etc.
  • UI indicator for stale data. If a flake is out of date, encourage user to update it. Then update the SystemTime in the cache.
  • User settings if any (in the future)

`nix_health`: check $USER is in trusted-users

To catch scenarios like this, we need a health check that checks the user is in trusted-user.

โฏ nix run nixpkgs#cachix use nammayatri

This user doesn't have permissions to configure binary caches.

You can either:

a) Run the same command as root to configure them globally.

b) Run the following command to add your user as trusted
   and then try again:

  echo "trusted-users = root srid" | sudo tee -a /etc/nix/nix.conf && sudo pkill nix-daemon

To implement this, you can add a new field to the NixConfig struct called trusted_users, and add a new health check (like #32) to test the current user is in it.

`nix_health`: per check configuration

Each check type should take a configuration that can be overridden in two places:

  • CLI args passed by user (eg: nix-health --disable=rosetta)
  • flake.nix attrset (eg: See #60, { flake.nix-health.direnv.enable = true; })

Memoize server fn results

Having to run nix show-config again and again, for example, is really unnecessary. We should memoize these server fns - either in frontend or backend.

  • Use leptos_query #33
  • Avoid re-fetching on route switches

Explore reading flake info from Nix itself rather than CLI commands

Instead of using nix flake show (and nix flake metadata) -- which reveal less information than we want -- consider adopting the devour-flake approach to inspect a flake from Nix itself, output a JSON and use that from Rust.

Examples of information lacking in CLI commands:

  • meta.description is present, but meta.longDescription (markdown formatted long description) is not.
  • Which packages (or devShells, checks, apps, etc.) are aliases of which (cf. packages.default = packages.emanote)

Brainstorming on custom metadata

(This is undecided)

  • meta.highlight = true; for flakes having numerous packages, but want to highlighting the important ones. cf. nammayatri

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.