Files
windmill/backend/windmill-common/src/apps.rs
T
Pyra ed806bf9d0 fix(backend): rework dependency_map handling (#6598)
* v0

Signed-off-by: pyranota <pyra@duck.com>

* optimize relocks

* make it work with relative relative imports

Signed-off-by: pyranota <pyra@duck.com>

* use fallback

Signed-off-by: pyranota <pyra@duck.com>

* remove dbg and todos

Signed-off-by: pyranota <pyra@duck.com>

* future proof a bit

Signed-off-by: pyranota <pyra@duck.com>

* cleanup

Signed-off-by: pyranota <pyra@duck.com>

* more cleanup

Signed-off-by: pyranota <pyra@duck.com>

* remove final TODO

Signed-off-by: pyranota <pyra@duck.com>

* do not use bytemuck

Signed-off-by: pyranota <pyra@duck.com>

* optimize hashing

Signed-off-by: pyranota <pyra@duck.com>

* implementation 1

Signed-off-by: pyranota <pyra@duck.com>

* almost v0

Signed-off-by: pyranota <pyra@duck.com>

* v0

Signed-off-by: pyranota <pyra@duck.com>

* add comments and use fallback

Signed-off-by: pyranota <pyra@duck.com>

* call dissolve for apps

Signed-off-by: pyranota <pyra@duck.com>

* add comms

Signed-off-by: pyranota <pyra@duck.com>

* refactor v0 (partially tested + dirty)

Signed-off-by: pyranota <pyra@duck.com>

* finishing

Signed-off-by: pyranota <pyra@duck.com>

* remove TODO

Signed-off-by: pyranota <pyra@duck.com>

* Update SQLx metadata

* silence unused argument

Signed-off-by: pyranota <pyra@duck.com>

* cleanup

Signed-off-by: pyranota <pyra@duck.com>

* implement rebuild_map endpoint

Signed-off-by: pyranota <pyra@duck.com>

* update windmill api client

Signed-off-by: pyranota <pyra@duck.com>

* almost finish with tests

Signed-off-by: pyranota <pyra@duck.com>

* add proper testing

Signed-off-by: pyranota <pyra@duck.com>

* remove unused fixtures

Signed-off-by: pyranota <pyra@duck.com>

* Update SQLx metadata

* partial cleanup

Signed-off-by: pyranota <pyra@duck.com>

* Update backend/windmill-worker/src/scoped_dependency_map.rs

Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>

* Update backend/windmill-common/src/scripts.rs

Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>

* evil doings

Signed-off-by: pyranota <pyra@duck.com>

* more cleanup

* Update SQLx metadata

* more cleanup

Signed-off-by: pyranota <pyra@duck.com>

* fixing CI

Signed-off-by: pyranota <pyra@duck.com>

* remove python from default features

Signed-off-by: pyranota <pyra@duck.com>

---------

Signed-off-by: pyranota <pyra@duck.com>
Co-authored-by: Pyra <92104930+pyranye@users.noreply.github.com>
Co-authored-by: GitHub Action <action@github.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
2025-09-24 13:40:39 +00:00

106 lines
3.2 KiB
Rust

/*
* Author: Ruben Fiszel
* Copyright: Windmill Labs, Inc 2022
* This file and its contents are licensed under the AGPLv3 License.
* Please see the included NOTICE for copyright information and
* LICENSE-AGPL for a copy of the license.
*/
use std::{collections::HashMap, sync::Arc};
use serde::{Deserialize, Serialize};
use serde_json::{from_value, Value};
use tokio::sync::RwLock;
use crate::{error, scripts::ScriptLang};
lazy_static::lazy_static! {
pub static ref APP_WORKSPACED_ROUTE: Arc<RwLock<bool>> = Arc::new(RwLock::new(false));
}
/// Id in the `app_script` table.
#[derive(Serialize, Deserialize, Debug, Copy, Clone, Hash, Eq, PartialEq)]
#[serde(transparent)]
pub struct AppScriptId(pub i64);
#[derive(Deserialize)]
pub struct ListAppQuery {
pub starred_only: Option<bool>,
pub path_exact: Option<String>,
pub path_start: Option<String>,
pub include_draft_only: Option<bool>,
pub with_deployment_msg: Option<bool>,
}
#[derive(Deserialize)]
pub struct RawAppValue {
pub files: HashMap<String, String>,
}
pub struct AppInlineScript {
pub language: Option<ScriptLang>,
pub content: String,
pub lock: Option<String>,
}
/// Traverse FlowValue while invoking provided by caller callback on leafs
// #[async_recursion::async_recursion(?Send)]
pub fn traverse_app_inline_scripts<
C: FnMut(AppInlineScript, Option<String>) -> error::Result<()>,
>(
value: &Value,
// Set to None.
container_id: Option<String>,
cb: &mut C,
) -> error::Result<()> {
match value {
Value::Object(object) => {
if let Some(Value::Object(script)) = object.get("inlineScript") {
let (language, lock, code) = (
script
.get("language")
.cloned()
.map(|v| from_value::<ScriptLang>(v).ok())
.flatten(),
script
.get("lock")
.and_then(Value::as_str)
.map(str::to_owned),
script
.get("content")
.and_then(Value::as_str)
.map(str::to_owned)
.ok_or(error::Error::internal_err(
"Missing `content` in inlineScript".to_string(),
))?,
);
if language.is_some() {
cb(
AppInlineScript { language, content: code.to_owned(), lock },
container_id.clone(),
)?;
}
} else {
for (_, value) in object {
traverse_app_inline_scripts(
value,
object
.get("id")
.and_then(Value::as_str)
.map(str::to_owned)
.or(container_id.clone()),
cb,
)?;
}
}
}
Value::Array(array) => {
for value in array {
traverse_app_inline_scripts(value, container_id.clone(), cb)?;
}
}
_ => {}
}
Ok(())
}