Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions src/ct/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions src/ct/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ edition = "2024"

[dependencies]
clap = { version = "4.5.49", features = ["derive"] }
# bundled feature statically links libsql
rusqlite = { version = "0.37.0", features = ["bundled"] }
53 changes: 53 additions & 0 deletions src/ct/src/db.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use std::sync::{LazyLock, Mutex};

use rusqlite::Connection;

use crate::paths::CODETRACER_PATHS;

pub static CONNECTION_MUTEX: LazyLock<Mutex<Connection>> = LazyLock::new(|| {
// TODO: better error handling maybe? (this is sufficient, but the errors aren't exactly user friendly)
// TODO: implement migrations

let res = Mutex::new(
Connection::open(
CODETRACER_PATHS
.lock()
.unwrap()
.data_path
.join("trace_index.db"),
)
.unwrap(),
);

{
let conn = res.lock().unwrap();
conn.execute(
"
CREATE TABLE IF NOT EXISTS traces (
id INTEGER PRIMARY KEY AUTOINCREMENT,
program text,
args text,
compileCommand text,
env text,
workdir text,
output text,
sourceFolders text,
lowLevelFolder text,
outputFolder text,
lang integer,
imported integer,
shellID integer,
rrPid integer,
exitCode integer,
calltrace integer,
calltraceMode string,
date text,
);
",
(),
)
.unwrap();
}

res
});
22 changes: 22 additions & 0 deletions src/ct/src/lang.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use clap::ValueEnum;

#[derive(ValueEnum, Clone, Debug)]
pub enum Lang {
Python,
Ruby,
Noir,
Wasm,
Small,
}

impl ToString for Lang {
fn to_string(&self) -> String {
match self {
Lang::Python => String::from("python"),
Lang::Ruby => String::from("ruby"),
Lang::Noir => String::from("noir"),
Lang::Wasm => String::from("wasm"),
Lang::Small => String::from("small"),
}
}
}
17 changes: 7 additions & 10 deletions src/ct/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
mod db;
mod lang;
mod paths;
mod subcommands;

use clap::{Parser, Subcommand, ValueEnum};
use clap::{Parser, Subcommand};

use crate::lang::Lang;

#[derive(Debug, Parser)]
#[command(
Expand All @@ -15,15 +20,6 @@ pub struct Args {
pub command: Command,
}

#[derive(ValueEnum, Clone, Debug)]
pub enum Lang {
Python,
Ruby,
Noir,
Wasm,
Small
}

#[derive(Debug, clap::Args)]
pub struct RecordOptions {
/// Override the language of the project. Used to determine which recorder is used.
Expand Down Expand Up @@ -56,6 +52,7 @@ pub enum Command {

fn main() {
let args = Args::parse();

match args.command {
Command::List => subcommands::run_list::<Args>(),
Command::External(args) => subcommands::run_external(&args),
Expand Down
33 changes: 33 additions & 0 deletions src/ct/src/paths.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use std::env;
use std::path::PathBuf;
use std::sync::{LazyLock, Mutex};

pub struct Paths {
pub tmp_path: PathBuf,
pub client_socket_path: PathBuf,
pub socket_path: PathBuf,
pub data_path: PathBuf,
}

impl Default for Paths {
fn default() -> Self {
let tmpdir: PathBuf = if cfg!(target_os = "macos") {
PathBuf::from(env::var("HOME").unwrap_or("/".to_string()))
.join("Library/Caches/com.codetracer.CodeTracer/")
} else {
env::temp_dir().join("codetracer/")
};

Self {
tmp_path: PathBuf::from(&tmpdir),
client_socket_path: PathBuf::from(&tmpdir).join("ct_client_socket"),
socket_path: PathBuf::from(&tmpdir).join("ct_socket"),
data_path: env::home_dir()
.unwrap_or(PathBuf::from("~"))
.join(".local/share/codetracer"), // TODO: handle non-UNIX stuff
}
}
}

pub static CODETRACER_PATHS: LazyLock<Mutex<Paths>> =
LazyLock::new(|| Mutex::new(Paths::default()));
15 changes: 13 additions & 2 deletions src/ct/src/subcommands/record.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
use std::{path::PathBuf, str::FromStr};

use crate::{Lang, RecordOptions};
use crate::{db, subcommands::run_external, Lang, RecordOptions};

pub fn run_record(options: RecordOptions) {
println!("{:#?}", options);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should return Result for most of the internal functions


let lang = options.lang.or_else(|| detect_language(&options.program));
println!("{:#?}", lang);
if lang.is_none() {
panic!("Can't determine language"); // TODO: better error and what to do?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return Err("..".into()) (or a more specific kind of error)

}

let lang = lang.unwrap();
let recorder_program = format!("codetracer-{}-recorder", lang.to_string());

run_external(&vec![recorder_program, options.program]);

let db = db::CONNECTION_MUTEX.lock();
}

fn detect_language(program: &str) -> Option<Lang> {
Expand Down
Loading