mirror of
https://github.com/joshuadavidthomas/django-language-server.git
synced 2025-09-11 21:06:31 +00:00
abstract zipapp to separate dedicated submodule (#215)
Some checks are pending
test / Python , Django () (push) Blocked by required conditions
lint / pre-commit (push) Waiting to run
lint / rustfmt (push) Waiting to run
lint / clippy (push) Waiting to run
lint / cargo-check (push) Waiting to run
release / build (push) Waiting to run
release / test (push) Waiting to run
release / release (push) Blocked by required conditions
test / generate-matrix (push) Waiting to run
test / tests (push) Blocked by required conditions
zizmor 🌈 / zizmor latest via PyPI (push) Waiting to run
Some checks are pending
test / Python , Django () (push) Blocked by required conditions
lint / pre-commit (push) Waiting to run
lint / rustfmt (push) Waiting to run
lint / clippy (push) Waiting to run
lint / cargo-check (push) Waiting to run
release / build (push) Waiting to run
release / test (push) Waiting to run
release / release (push) Blocked by required conditions
test / generate-matrix (push) Waiting to run
test / tests (push) Blocked by required conditions
zizmor 🌈 / zizmor latest via PyPI (push) Waiting to run
This commit is contained in:
parent
d99c96d6b6
commit
007a009d33
7 changed files with 64 additions and 57 deletions
|
@ -1,6 +1,7 @@
|
||||||
pub mod ipc;
|
pub mod ipc;
|
||||||
pub mod pool;
|
pub mod pool;
|
||||||
pub mod queries;
|
pub mod queries;
|
||||||
|
mod zipapp;
|
||||||
|
|
||||||
pub use queries::Query;
|
pub use queries::Query;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
|
@ -9,43 +9,25 @@ use std::process::Stdio;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use tempfile::NamedTempFile;
|
|
||||||
|
|
||||||
|
use super::zipapp::InspectorFile;
|
||||||
use super::DjlsRequest;
|
use super::DjlsRequest;
|
||||||
use super::DjlsResponse;
|
use super::DjlsResponse;
|
||||||
use crate::python::PythonEnvironment;
|
use crate::python::PythonEnvironment;
|
||||||
|
|
||||||
const INSPECTOR_PYZ: &[u8] = include_bytes!(concat!(
|
|
||||||
env!("CARGO_WORKSPACE_DIR"),
|
|
||||||
"/python/dist/djls_inspector.pyz"
|
|
||||||
));
|
|
||||||
|
|
||||||
pub struct InspectorProcess {
|
pub struct InspectorProcess {
|
||||||
child: Child,
|
child: Child,
|
||||||
stdin: std::process::ChildStdin,
|
stdin: std::process::ChildStdin,
|
||||||
stdout: BufReader<std::process::ChildStdout>,
|
stdout: BufReader<std::process::ChildStdout>,
|
||||||
_zipapp_file: NamedTempFile,
|
_zipapp_file: InspectorFile,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InspectorProcess {
|
impl InspectorProcess {
|
||||||
pub fn new(python_env: &PythonEnvironment, project_path: &Path) -> Result<Self> {
|
pub fn new(python_env: &PythonEnvironment, project_path: &Path) -> Result<Self> {
|
||||||
let mut zipapp_file = tempfile::Builder::new()
|
let zipapp_file = InspectorFile::create()?;
|
||||||
.prefix("djls_inspector_")
|
|
||||||
.suffix(".pyz")
|
|
||||||
.tempfile()
|
|
||||||
.context("Failed to create temp file for inspector")?;
|
|
||||||
|
|
||||||
zipapp_file
|
|
||||||
.write_all(INSPECTOR_PYZ)
|
|
||||||
.context("Failed to write inspector zipapp to temp file")?;
|
|
||||||
zipapp_file
|
|
||||||
.flush()
|
|
||||||
.context("Failed to flush inspector zipapp")?;
|
|
||||||
|
|
||||||
let zipapp_path = zipapp_file.path();
|
|
||||||
|
|
||||||
let mut cmd = Command::new(&python_env.python_path);
|
let mut cmd = Command::new(&python_env.python_path);
|
||||||
cmd.arg(zipapp_path)
|
cmd.arg(zipapp_file.path())
|
||||||
.stdin(Stdio::piped())
|
.stdin(Stdio::piped())
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.stderr(Stdio::inherit())
|
.stderr(Stdio::inherit())
|
||||||
|
|
|
@ -12,15 +12,6 @@ pub enum Query {
|
||||||
DjangoInit,
|
DjangoInit,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
|
||||||
#[serde(rename_all = "lowercase")]
|
|
||||||
pub enum VersionReleaseLevel {
|
|
||||||
Alpha,
|
|
||||||
Beta,
|
|
||||||
Candidate,
|
|
||||||
Final,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct PythonEnvironmentQueryData {
|
pub struct PythonEnvironmentQueryData {
|
||||||
pub sys_base_prefix: PathBuf,
|
pub sys_base_prefix: PathBuf,
|
||||||
|
@ -31,6 +22,15 @@ pub struct PythonEnvironmentQueryData {
|
||||||
pub sys_version_info: (u32, u32, u32, VersionReleaseLevel, u32),
|
pub sys_version_info: (u32, u32, u32, VersionReleaseLevel, u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "lowercase")]
|
||||||
|
pub enum VersionReleaseLevel {
|
||||||
|
Alpha,
|
||||||
|
Beta,
|
||||||
|
Candidate,
|
||||||
|
Final,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct TemplateTagQueryData {
|
pub struct TemplateTagQueryData {
|
||||||
pub templatetags: Vec<TemplateTag>,
|
pub templatetags: Vec<TemplateTag>,
|
||||||
|
@ -42,9 +42,3 @@ pub struct TemplateTag {
|
||||||
pub module: String,
|
pub module: String,
|
||||||
pub doc: Option<String>,
|
pub doc: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
|
||||||
pub struct DjangoInitQueryData {
|
|
||||||
pub success: bool,
|
|
||||||
pub message: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
36
crates/djls-project/src/inspector/zipapp.rs
Normal file
36
crates/djls-project/src/inspector/zipapp.rs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
use std::io::Write;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use anyhow::Context;
|
||||||
|
use anyhow::Result;
|
||||||
|
use tempfile::NamedTempFile;
|
||||||
|
|
||||||
|
const INSPECTOR_PYZ: &[u8] = include_bytes!(concat!(
|
||||||
|
env!("CARGO_WORKSPACE_DIR"),
|
||||||
|
"/python/dist/djls_inspector.pyz"
|
||||||
|
));
|
||||||
|
|
||||||
|
pub struct InspectorFile(NamedTempFile);
|
||||||
|
|
||||||
|
impl InspectorFile {
|
||||||
|
pub fn create() -> Result<Self> {
|
||||||
|
let mut zipapp_file = tempfile::Builder::new()
|
||||||
|
.prefix("djls_inspector_")
|
||||||
|
.suffix(".pyz")
|
||||||
|
.tempfile()
|
||||||
|
.context("Failed to create temp file for inspector")?;
|
||||||
|
|
||||||
|
zipapp_file
|
||||||
|
.write_all(INSPECTOR_PYZ)
|
||||||
|
.context("Failed to write inspector zipapp to temp file")?;
|
||||||
|
zipapp_file
|
||||||
|
.flush()
|
||||||
|
.context("Failed to flush inspector zipapp")?;
|
||||||
|
|
||||||
|
Ok(Self(zipapp_file))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn path(&self) -> &Path {
|
||||||
|
self.0.path()
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,7 +26,7 @@ pub struct DjangoProject {
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
env: Option<PythonEnvironment>,
|
env: Option<PythonEnvironment>,
|
||||||
template_tags: Option<TemplateTags>,
|
template_tags: Option<TemplateTags>,
|
||||||
inspector_pool: Arc<InspectorPool>,
|
inspector: Arc<InspectorPool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DjangoProject {
|
impl DjangoProject {
|
||||||
|
@ -36,7 +36,7 @@ impl DjangoProject {
|
||||||
path,
|
path,
|
||||||
env: None,
|
env: None,
|
||||||
template_tags: None,
|
template_tags: None,
|
||||||
inspector_pool: Arc::new(InspectorPool::new()),
|
inspector: Arc::new(InspectorPool::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ impl DjangoProject {
|
||||||
let request = DjlsRequest {
|
let request = DjlsRequest {
|
||||||
query: Query::DjangoInit,
|
query: Query::DjangoInit,
|
||||||
};
|
};
|
||||||
let response = self.inspector_pool.query(env, &self.path, &request)?;
|
let response = self.inspector.query(env, &self.path, &request)?;
|
||||||
|
|
||||||
if !response.ok {
|
if !response.ok {
|
||||||
anyhow::bail!("Failed to initialize Django: {:?}", response.error);
|
anyhow::bail!("Failed to initialize Django: {:?}", response.error);
|
||||||
|
@ -62,7 +62,7 @@ impl DjangoProject {
|
||||||
let request = DjlsRequest {
|
let request = DjlsRequest {
|
||||||
query: Query::Templatetags,
|
query: Query::Templatetags,
|
||||||
};
|
};
|
||||||
let response = self.inspector_pool.query(env, &self.path, &request)?;
|
let response = self.inspector.query(env, &self.path, &request)?;
|
||||||
|
|
||||||
if let Some(data) = response.data {
|
if let Some(data) = response.data {
|
||||||
self.template_tags = Some(TemplateTags::from_json(&data)?);
|
self.template_tags = Some(TemplateTags::from_json(&data)?);
|
||||||
|
|
|
@ -69,7 +69,8 @@ def handle_request(request: dict[str, Any]) -> DjlsResponse:
|
||||||
return DjlsResponse(ok=True, data=get_installed_templatetags())
|
return DjlsResponse(ok=True, data=get_installed_templatetags())
|
||||||
|
|
||||||
elif query == Query.DJANGO_INIT:
|
elif query == Query.DJANGO_INIT:
|
||||||
return DjlsResponse(ok=True, data=initialize_django())
|
success, error = initialize_django()
|
||||||
|
return DjlsResponse(ok=success, data=None, error=error)
|
||||||
|
|
||||||
return DjlsResponse(ok=False, error=f"Unhandled query type: {query}")
|
return DjlsResponse(ok=False, error=f"Unhandled query type: {query}")
|
||||||
|
|
||||||
|
|
|
@ -90,13 +90,8 @@ def get_installed_templatetags() -> TemplateTagQueryData:
|
||||||
return TemplateTagQueryData(templatetags=templatetags)
|
return TemplateTagQueryData(templatetags=templatetags)
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
def initialize_django() -> tuple[bool, str | None]:
|
||||||
class DjangoInitQueryData:
|
"""Initialize Django and return (success, error_message)."""
|
||||||
success: bool
|
|
||||||
message: str | None = None
|
|
||||||
|
|
||||||
|
|
||||||
def initialize_django() -> DjangoInitQueryData:
|
|
||||||
import os
|
import os
|
||||||
import django
|
import django
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
|
@ -122,9 +117,9 @@ def initialize_django() -> DjangoInitQueryData:
|
||||||
current_path = current_path.parent
|
current_path = current_path.parent
|
||||||
|
|
||||||
if not manage_py:
|
if not manage_py:
|
||||||
return DjangoInitQueryData(
|
return (
|
||||||
success=False,
|
False,
|
||||||
message="Could not find manage.py or DJANGO_SETTINGS_MODULE not set",
|
"Could not find manage.py or DJANGO_SETTINGS_MODULE not set",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add project directory to sys.path
|
# Add project directory to sys.path
|
||||||
|
@ -163,12 +158,10 @@ def initialize_django() -> DjangoInitQueryData:
|
||||||
if not apps.ready:
|
if not apps.ready:
|
||||||
django.setup()
|
django.setup()
|
||||||
|
|
||||||
return DjangoInitQueryData(
|
return True, None
|
||||||
success=True, message="Django initialized successfully"
|
|
||||||
)
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return DjangoInitQueryData(success=False, message=str(e))
|
return False, str(e)
|
||||||
|
|
||||||
|
|
||||||
QueryData = PythonEnvironmentQueryData | TemplateTagQueryData | DjangoInitQueryData
|
QueryData = PythonEnvironmentQueryData | TemplateTagQueryData
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue