Skip to content

Commit

Permalink
feat(cli): meta undeploy subcommand (#508)
Browse files Browse the repository at this point in the history
<!--
Pull requests are squash merged using:
- their title as the commit message
- their description as the commit body

Having a good title and description is important for the users to get
readable changelog and understand when they need to update his code and
how.
-->

### Describe your change

Add `undeploy` subcommand to the meta CLI.

### Motivation and context

- Allow user to undeploy a typegraph.
- We always had resource leak error when deploying a typegraph from a
test step. This subcommand would allow us to undeploy the typegraph at
the end of the test step.

### Checklist

- [x] The change come with new or modified tests
- [x] Hard-to-understand functions have explanatory comments
- [ ] ~End-user documentation is updated to reflect the change~: *N/A*
  • Loading branch information
Natoandro authored Dec 7, 2023
1 parent 747919d commit 381d958
Show file tree
Hide file tree
Showing 15 changed files with 271 additions and 161 deletions.
2 changes: 1 addition & 1 deletion dev/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ const tmpDir = join(projectDir, "tmp");
const env: Record<string, string> = {
"RUST_LOG": "off,xtask=debug,meta=debug",
"LOG_LEVEL": "DEBUG",
"NO_COLOR": "1",
// "NO_COLOR": "1",
"DEBUG": "true",
"PACKAGED": "false",
"TG_SECRET":
Expand Down
3 changes: 3 additions & 0 deletions meta-cli/src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub(crate) mod doctor;
pub(crate) mod new;
pub(crate) mod serialize;
pub(crate) mod typegate;
pub(crate) mod undeploy;
pub(crate) mod upgrade;

#[derive(Parser, Debug)]
Expand Down Expand Up @@ -66,6 +67,8 @@ pub(crate) enum Commands {
Dev(dev::Dev),
/// Push typegraph(s) to typegate
Deploy(deploy::DeploySubcommand),
/// Undeploy typegraph(s) from typegate
Undeploy(undeploy::Undeploy),
/// Generate materializers code from typegraph definition
Codegen(codegen::Codegen),
/// Upgrade
Expand Down
66 changes: 66 additions & 0 deletions meta-cli/src/cli/undeploy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright Metatype OÜ, licensed under the Mozilla Public License Version 2.0.
// SPDX-License-Identifier: MPL-2.0

use crate::{
config::Config,
utils::{graphql::Query, Node},
};
use anyhow::{Context, Result};
use async_trait::async_trait;
use clap::Parser;
use indoc::indoc;

use super::{Action, CommonArgs};

#[derive(Parser, Debug)]
pub struct Undeploy {
#[command(flatten)]
node: CommonArgs,

#[clap(short, long)]
pub target: String,

/// Typegraph names
#[clap(long = "typegraph")]
pub typegraphs: Vec<String>,
}

#[async_trait]
impl Action for Undeploy {
async fn run(&self, args: super::GenArgs) -> Result<()> {
let dir = args.dir()?;
let config_path = args.config.clone();
let config = Config::load_or_find(config_path, &dir)?;
let node_config = config.node(&self.node, &self.target);
let node = node_config.build(&dir).await?;
node.undeploy(&self.typegraphs).await?;

Ok(())
}
}

impl Node {
async fn undeploy(&self, typegraphs: &[String]) -> Result<()> {
let res = self
.post("/typegate")?
.gql(
indoc! {"
mutation($names: [String!]!) {
removeTypegraphs(names: $names)
}"}
.to_string(),
Some(serde_json::json!({
"names": typegraphs,
})),
)
.await?;

let res: bool = res
.data("removeTypegraphs")
.context("removeTypegraph reponse")?;
if !res {
anyhow::bail!("undeploy failed");
}
Ok(())
}
}
5 changes: 1 addition & 4 deletions meta-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,7 @@ fn main() -> Result<()> {

let args = match Args::try_parse() {
Ok(cli) => cli,
Err(e) => {
e.print()?;
return Ok(());
}
Err(e) => e.exit(),
};

if args.version {
Expand Down
16 changes: 9 additions & 7 deletions typegate/src/runtimes/typegate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ export class TypeGateRuntime extends Runtime {
if (name === "addTypegraph") {
return this.addTypegraph;
}
if (name === "removeTypegraph") {
return this.removeTypegraph;
if (name === "removeTypegraphs") {
return this.removeTypegraphs;
}
if (name === "typegraphs") {
return this.typegraphs;
Expand Down Expand Up @@ -128,11 +128,13 @@ export class TypeGateRuntime extends Runtime {
};
};

removeTypegraph: Resolver = ({ name }) => {
if (SystemTypegraph.check(name)) {
throw new Error(`Typegraph ${name} cannot be removed`);
removeTypegraphs: Resolver = async ({ names }) => {
for (const name of names) {
if (SystemTypegraph.check(name)) {
throw new Error(`Typegraph ${name} cannot be removed`);
}
await this.typegate.register.remove(name);
}

return this.typegate.register.remove(name);
return true;
};
}
33 changes: 21 additions & 12 deletions typegate/src/typegraphs/typegate.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,18 @@
"typegraphs": 1,
"typegraph": 7,
"addTypegraph": 15,
"removeTypegraph": 32
"removeTypegraphs": 32
},
"required": [
"typegraphs",
"typegraph",
"addTypegraph",
"removeTypegraph"
"removeTypegraphs"
]
},
{
"type": "function",
"title": "func_35",
"title": "func_36",
"runtime": 1,
"policies": [
0
Expand Down Expand Up @@ -87,7 +87,7 @@
},
{
"type": "function",
"title": "func_36",
"title": "func_37",
"runtime": 1,
"policies": [
0
Expand Down Expand Up @@ -177,7 +177,7 @@
},
{
"type": "function",
"title": "func_37",
"title": "func_38",
"runtime": 1,
"policies": [
0
Expand Down Expand Up @@ -355,31 +355,40 @@
},
{
"type": "function",
"title": "func_38",
"title": "func_39",
"runtime": 1,
"policies": [
0
],
"config": {},
"as_id": false,
"input": 33,
"output": 35,
"output": 36,
"materializer": 5,
"rate_weight": null,
"rate_calls": true
},
{
"type": "object",
"title": "object_32",
"title": "object_33",
"runtime": 1,
"policies": [],
"config": {},
"as_id": false,
"properties": {
"name": 34
"names": 34
},
"required": []
},
{
"type": "list",
"title": "list_32",
"runtime": 1,
"policies": [],
"config": {},
"as_id": false,
"items": 35
},
{
"type": "string",
"title": "string_31",
Expand All @@ -389,8 +398,8 @@
"as_id": false
},
{
"type": "integer",
"title": "integer_33",
"type": "boolean",
"title": "boolean_34",
"runtime": 1,
"policies": [],
"config": {},
Expand Down Expand Up @@ -446,7 +455,7 @@
"data": {}
},
{
"name": "removeTypegraph",
"name": "removeTypegraphs",
"runtime": 1,
"effect": {
"effect": "delete",
Expand Down
20 changes: 10 additions & 10 deletions typegate/src/typegraphs/typegate.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@ def typegate(g: Graph):
raise Exception(add_typegraph_mat_id.value)
add_typegraph_mat = Materializer(add_typegraph_mat_id.value, effect=fx.create(True))

remove_typegraph_mat_id = runtimes.register_typegate_materializer(
store, TypegateOperation.REMOVE_TYPEGRAPH
remove_typegraphs_mat_id = runtimes.register_typegate_materializer(
store, TypegateOperation.REMOVE_TYPEGRAPHS
)
if isinstance(remove_typegraph_mat_id, Err):
raise Exception(remove_typegraph_mat_id.value)
remove_typegraph_mat = Materializer(
remove_typegraph_mat_id.value, effect=fx.delete(True)
if isinstance(remove_typegraphs_mat_id, Err):
raise Exception(remove_typegraphs_mat_id.value)
remove_typegraphs_mat = Materializer(
remove_typegraphs_mat_id.value, effect=fx.delete(True)
)

serialized_typegraph_mat_id = runtimes.register_typegate_materializer(
Expand Down Expand Up @@ -124,10 +124,10 @@ def typegate(g: Graph):
add_typegraph_mat,
rate_calls=True,
),
removeTypegraph=t.func(
t.struct({"name": t.string()}),
t.integer(),
remove_typegraph_mat,
removeTypegraphs=t.func(
t.struct({"names": t.list(t.string())}),
t.boolean(),
remove_typegraphs_mat,
rate_calls=True,
),
default_policy=admin_only,
Expand Down
Loading

0 comments on commit 381d958

Please sign in to comment.