mirror of
https://github.com/joshuadavidthomas/django-language-server.git
synced 2025-07-07 20:55:02 +00:00
Refactor and reorganize primary djls
crate (#136)
This commit is contained in:
parent
ec141b7d09
commit
42c19e751d
5 changed files with 98 additions and 98 deletions
12
crates/djls/src/args.rs
Normal file
12
crates/djls/src/args.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
use clap::Parser;
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
pub struct Args {
|
||||
/// Do not print any output.
|
||||
#[arg(global = true, long, short, conflicts_with = "verbose")]
|
||||
pub quiet: bool,
|
||||
|
||||
/// Use verbose output.
|
||||
#[arg(global = true, action = clap::ArgAction::Count, long, short, conflicts_with = "quiet")]
|
||||
pub verbose: u8,
|
||||
}
|
28
crates/djls/src/cli.rs
Normal file
28
crates/djls/src/cli.rs
Normal file
|
@ -0,0 +1,28 @@
|
|||
use crate::args::Args;
|
||||
use crate::commands::{Command, DjlsCommand};
|
||||
use anyhow::Result;
|
||||
use clap::Parser;
|
||||
use std::process::ExitCode;
|
||||
|
||||
/// Main CLI structure that defines the command-line interface
|
||||
#[derive(Parser)]
|
||||
#[command(name = "djls")]
|
||||
#[command(version, about)]
|
||||
pub struct Cli {
|
||||
#[command(subcommand)]
|
||||
pub command: DjlsCommand,
|
||||
|
||||
#[command(flatten)]
|
||||
pub args: Args,
|
||||
}
|
||||
|
||||
/// Parse CLI arguments and execute the chosen command
|
||||
pub async fn run(args: Vec<String>) -> Result<ExitCode> {
|
||||
let cli = Cli::try_parse_from(args).unwrap_or_else(|e| {
|
||||
e.exit();
|
||||
});
|
||||
|
||||
match &cli.command {
|
||||
DjlsCommand::Serve(cmd) => cmd.execute(&cli.args).await,
|
||||
}
|
||||
}
|
|
@ -1,13 +1,16 @@
|
|||
use clap::{Parser, ValueEnum};
|
||||
pub mod serve;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct Serve {
|
||||
#[arg(short, long, default_value_t = ConnectionType::Stdio, value_enum)]
|
||||
connection_type: ConnectionType,
|
||||
use crate::args::Args;
|
||||
use anyhow::Result;
|
||||
use clap::Subcommand;
|
||||
use std::process::ExitCode;
|
||||
|
||||
pub trait Command {
|
||||
async fn execute(&self, args: &Args) -> Result<ExitCode>;
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, ValueEnum)]
|
||||
enum ConnectionType {
|
||||
Stdio,
|
||||
Tcp,
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum DjlsCommand {
|
||||
/// Start the LSP server
|
||||
Serve(self::serve::Serve),
|
||||
}
|
||||
|
|
24
crates/djls/src/commands/serve.rs
Normal file
24
crates/djls/src/commands/serve.rs
Normal file
|
@ -0,0 +1,24 @@
|
|||
use crate::args::Args;
|
||||
use crate::commands::Command;
|
||||
use anyhow::Result;
|
||||
use clap::{Parser, ValueEnum};
|
||||
use std::process::ExitCode;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct Serve {
|
||||
#[arg(short, long, default_value_t = ConnectionType::Stdio, value_enum)]
|
||||
connection_type: ConnectionType,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, ValueEnum)]
|
||||
enum ConnectionType {
|
||||
Stdio,
|
||||
Tcp,
|
||||
}
|
||||
|
||||
impl Command for Serve {
|
||||
async fn execute(&self, _args: &Args) -> Result<ExitCode> {
|
||||
djls_server::serve().await?;
|
||||
Ok(ExitCode::SUCCESS)
|
||||
}
|
||||
}
|
|
@ -1,45 +1,12 @@
|
|||
mod args;
|
||||
mod cli;
|
||||
mod commands;
|
||||
|
||||
use crate::commands::Serve;
|
||||
use anyhow::Result;
|
||||
use clap::{Parser, Subcommand};
|
||||
use pyo3::prelude::*;
|
||||
use std::env;
|
||||
use std::process::ExitCode;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(name = "djls")]
|
||||
#[command(version, about, long_about = None)]
|
||||
pub struct Cli {
|
||||
#[command(subcommand)]
|
||||
command: Command,
|
||||
|
||||
#[command(flatten)]
|
||||
args: Args,
|
||||
}
|
||||
|
||||
#[derive(Debug, Subcommand)]
|
||||
enum Command {
|
||||
/// Start the LSP server
|
||||
Serve(Serve),
|
||||
}
|
||||
|
||||
#[derive(Parser)]
|
||||
pub struct Args {
|
||||
#[command(flatten)]
|
||||
global: GlobalArgs,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct GlobalArgs {
|
||||
/// Do not print any output.
|
||||
#[arg(global = true, long, short, conflicts_with = "verbose")]
|
||||
pub quiet: bool,
|
||||
|
||||
/// Use verbose output.
|
||||
#[arg(global = true, action = clap::ArgAction::Count, long, short, conflicts_with = "quiet")]
|
||||
pub verbose: u8,
|
||||
}
|
||||
pub use cli::Cli;
|
||||
|
||||
#[pyfunction]
|
||||
fn entrypoint(_py: Python) -> PyResult<()> {
|
||||
|
@ -48,62 +15,28 @@ fn entrypoint(_py: Python) -> PyResult<()> {
|
|||
.chain(env::args().skip(2))
|
||||
.collect();
|
||||
|
||||
let runtime = tokio::runtime::Runtime::new().unwrap();
|
||||
let local = tokio::task::LocalSet::new();
|
||||
local.block_on(&runtime, async move {
|
||||
tokio::select! {
|
||||
// The main CLI program
|
||||
result = main(args) => {
|
||||
match result {
|
||||
Ok(code) => {
|
||||
if code != ExitCode::SUCCESS {
|
||||
std::process::exit(1);
|
||||
}
|
||||
Ok::<(), PyErr>(())
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Error: {}", e);
|
||||
if let Some(source) = e.source() {
|
||||
eprintln!("Caused by: {}", source);
|
||||
}
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Ctrl+C handling
|
||||
_ = tokio::signal::ctrl_c() => {
|
||||
println!("\nReceived Ctrl+C, shutting down...");
|
||||
// Cleanup code here if needed
|
||||
std::process::exit(130); // Standard Ctrl+C exit code
|
||||
}
|
||||
// SIGTERM handling (Unix only)
|
||||
_ = async {
|
||||
#[cfg(unix)]
|
||||
{
|
||||
use tokio::signal::unix::{signal, SignalKind};
|
||||
let mut term = signal(SignalKind::terminate()).unwrap();
|
||||
term.recv().await;
|
||||
}
|
||||
} => {
|
||||
println!("\nReceived termination signal, shutting down...");
|
||||
std::process::exit(143); // Standard SIGTERM exit code
|
||||
let runtime = tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let result = runtime.block_on(cli::run(args));
|
||||
|
||||
match result {
|
||||
Ok(code) => {
|
||||
if code != ExitCode::SUCCESS {
|
||||
std::process::exit(1);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Error: {}", e);
|
||||
if let Some(source) = e.source() {
|
||||
eprintln!("Caused by: {}", source);
|
||||
}
|
||||
std::process::exit(1);
|
||||
}
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn main(args: Vec<String>) -> Result<ExitCode> {
|
||||
let cli = Cli::try_parse_from(args).unwrap_or_else(|e| {
|
||||
e.exit();
|
||||
});
|
||||
|
||||
match cli.command {
|
||||
Command::Serve(_serve) => djls_server::serve().await?,
|
||||
}
|
||||
|
||||
Ok(ExitCode::SUCCESS)
|
||||
}
|
||||
|
||||
#[pymodule]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue