pnezis

pnezis

Workspace - A set of tools for working with Elixir monorepos

:tada: We are open sourcing workspace a set of tools for working with elixir monorepos, inspired by rust workspaces and nx.dev. Twitter announcement

You can find the docs here.

There are many reasons for having a monorepo but working with them may be cumbersome. Workspace provides a set of tools for working with big monorepos efficiently.

What is a workspace?

A workspace is nothing more than a git repository hosting multiple mix projects in any arbitrary folder structure. Path dependencies are used for cross project dependencies similarly to umbrellas.

The central concept of the workspace is the workspace graph. This is a directed acyclic graph where the nodes represent projects and the edges the dependencies between projects.

Workspace uses git to get the changes between two revisions. Knowing which files have changed we can deduce which project is modified or affected:

status

Running tasks

You can run any command from the root on all or a subset of the workspace projects. You can also run time consuming tasks only on the affected projects significantly improving CI times for large codebases.

run

Checking your workspace

When your workspace grows, it can go out of hand quickly. You need a way to check that your projects are properly defined. With the workspace.check task you can among other:

  • Ensure that specific dependencies are set on all projects, e.g. ex_doc.
  • Ensure that external dependencies versions match the expected ones.
  • Verify that no forbidden dependencies are defined.
  • Ensure that all projects have common build paths

Enforcing boundaries

One of the main purposes of monorepos is to help you split your codebase into independent, cohesive and reusable packages. You can enforce a clean architecture by tagging your projects and enforcing boundaries between them.

Creating a workspace

You can create a new workspace with the workspace.new scaffolder:

mix archive.install hex workspace_new

mix workspace.new your_workspace

Helper packages

The workspace repo is itself a workspace and comes with two extra small packages.

  • cli_options - provides an opinionated way to parse CLI options based on a schema similarly to NimbleOptions
  • cascade - is a small library for generating code for templates.

Disclaimer

Despite being stable (we successfully use it internally to manage a massive elixir codebase consisting of hundreds of packages) this is still a 0.x.x project and breaking changes may happen.

Most Liked

davydog187

davydog187

This is a really exciting start!

We’ve recently moved to GitHub - casey/just: 🤖 Just a command runner after we gave up on running various tasks through Mix. We will definitely give this a try and report back

pnezis

pnezis

@mindreframer This is a sample workspace project with some boundaries rules enabled :slight_smile: (all projects are mix hello world projects)

pnezis

pnezis

You are right, I have noticed it as well but forgot to mention it in the docs. What I do as a workaround is to run mix phx.new outside of apps and then just mv it in it.

The phx.new task is only looking if there is a parent apps folder and if it exists it is treated as an umbrella project. Maybe a --no-umbrella option option would help.

mindreframer

mindreframer

Awesome! I didn’t notice, that workspace itself uses workspace, that’s cool! Yep, I guess I will have some fun time study-ing the codebase.

Thanks a lot!

cmo

cmo

Do it once, commit the json config to your source control and you’re done. Not sure how much simpler we can get than native IDE support? You could write a script to generate the workspace config file if you want.

Where Next?

Popular in Libraries Top

tompave
Hello there, I would like to share a feature toggles library (AKA feature flags) I’ve been working on. The main package is FunWithFlags...
New
nikokozak
Hello all, I’ve been working on Svonix - a library for quickly integrating Svelte components into Phoenix views. It’s a much-needed succ...
New
New
blatyo
https://www.conduitframework.com/ The best overview for how things are tied together is this presentation. Modules and functions are pre...
New
Jskalc
Hi! Today, after a couple weeks of development I’ve released v0.1 of LiveVue. It’s a seamless integration of Vue and Phoenix LiveView, i...
New
Crowdhailer
Experimenting with this code. OK.try do user <- fetch_user(1) cart <- fetch_cart(1) order = checkout(cart, user) save_or...
New
vic
Expat is a tiny experiment I did for extracting patterns and being able to reuse them (compose and share patterns between elixir librarie...
New
handnot2
Samly can be used to enable SAML 2.0 Single Sign On in a Plug/Phoenix application. This library uses Erlang esaml to provide plug enabl...
New
mischov
import Meeseeks.CSS html = HTTPoison.get!("https://news.ycombinator.com/").body for story <- Meeseeks.all(html, css("tr.athing")) do...
New
wojtekmach
Hey everyone! Req is an HTTP client for Elixir that I’ve been working on for quite some time. There is already a lot of HTTP clients out...
New

Other popular topics Top

shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New

Sub Categories:

We're in Beta

About us Mission Statement