Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
3401966
Update release workflow to always mark as prerelease
Jordonbc Dec 27, 2025
64207e8
Improve
Jordonbc Dec 28, 2025
f5efecd
Fixed compile issue
Jordonbc Dec 28, 2025
ed80217
Update ci.yml
Jordonbc Dec 28, 2025
7872f44
Fix compile issues
Jordonbc Dec 28, 2025
373d585
Fix compile issues
Jordonbc Dec 28, 2025
6c603bf
Update ci.yml
Jordonbc Dec 28, 2025
4ae51c3
Update Cargo.toml
Jordonbc Dec 28, 2025
3f036c4
Fixed issue
Jordonbc Dec 28, 2025
82965c0
Update ci.yml
Jordonbc Dec 28, 2025
0bdd548
Update backend_descriptor.rs
Jordonbc Dec 28, 2025
e803769
Added helpers
Jordonbc Dec 28, 2025
011dfc4
Update plugin_stdio.rs
Jordonbc Dec 28, 2025
3601da1
Update plugin_stdio.rs
Jordonbc Dec 28, 2025
bd61a77
Added logger
Jordonbc Dec 28, 2025
7d58052
Update plugin_stdio.rs
Jordonbc Dec 28, 2025
9c952d1
Improve core
Jordonbc Dec 28, 2025
0c74263
Improvements
Jordonbc Dec 28, 2025
dca4e78
Improved core
Jordonbc Dec 28, 2025
d2f51f7
Update lib.rs
Jordonbc Dec 31, 2025
0d31500
Create AGENTS.md
Jordonbc Dec 31, 2025
4628205
Update Cargo.toml
Jordonbc Dec 31, 2025
cf1a654
Update Cargo.toml
Jordonbc Dec 31, 2025
455b248
Added fmt requirement
Jordonbc Dec 31, 2025
5573461
Improved core
Jordonbc Dec 31, 2025
ab8249f
Update README.md
Jordonbc Dec 31, 2025
dc8a7f1
Update README.md
Jordonbc Dec 31, 2025
5e6cab0
Update
Jordonbc Dec 31, 2025
fa560c2
Version bump
Jordonbc Dec 31, 2025
e547092
Improved workflows
Jordonbc Dec 31, 2025
9fac442
Update plugin_runtime.rs
Jordonbc Dec 31, 2025
9d1977a
Update Justfile
Jordonbc Dec 31, 2025
5a8a6fb
Version bump
Jordonbc Dec 31, 2025
03c1c8f
Update release.yml
Jordonbc Dec 31, 2025
08ffa2e
Update release.yml
Jordonbc Dec 31, 2025
371276d
Version Bump
Jordonbc Dec 31, 2025
b833211
Remove duplicated cfg attribute from backend_descriptor.rs
Jordonbc Dec 31, 2025
e034c0d
Update AGENTS.md
Jordonbc Dec 31, 2025
7d281f0
agents: require 72-char commit title in AGENTS.md
Jordonbc Dec 31, 2025
dbaa322
docs: note sandbox requirements for and cargo commands in AGENTS.md
Jordonbc Dec 31, 2025
fd5e913
Update Cargo.lock
Jordonbc Jan 7, 2026
e9e0d64
Update version
Jordonbc Jan 7, 2026
27011b3
Bump github/codeql-action in the actions-minor-patch group (#5)
dependabot[bot] Jan 20, 2026
8215e59
Bump thiserror from 2.0.17 to 2.0.18 in the cargo-minor-patch group (#6)
dependabot[bot] Jan 20, 2026
aaed6f3
Bump the actions-minor-patch group with 2 updates (#7)
dependabot[bot] Jan 27, 2026
926243c
Bump github/codeql-action in the actions-minor-patch group (#8)
dependabot[bot] Feb 7, 2026
a436b4e
Update README with CI badges
Jordonbc Feb 7, 2026
8d4f306
Update lib.rs (#9)
Jordonbc Feb 7, 2026
c12bf17
Update version
Jordonbc Feb 7, 2026
8b409cf
Merge branch 'Stable' into Dev
Jordonbc Feb 7, 2026
8bb8788
Fix stdio timeout issues
Jordonbc Feb 7, 2026
f49cca7
Fix Backend registry issue
Jordonbc Feb 7, 2026
e9a87b2
Fix issues
Jordonbc Feb 7, 2026
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
SCCACHE_CACHE_SIZE: '2G'
steps:
- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0

Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0

- name: Initialize CodeQL
uses: github/codeql-action/init@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v3
uses: github/codeql-action/init@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v3
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
Expand All @@ -55,10 +55,10 @@ jobs:

- name: Autobuild
if: matrix.build-mode == 'autobuild'
uses: github/codeql-action/autobuild@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v3
uses: github/codeql-action/autobuild@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v3

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v3
uses: github/codeql-action/analyze@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v3
with:
category: "/language:${{ matrix.language }}"

4 changes: 2 additions & 2 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
ahead_count: ${{ steps.diff.outputs.ahead_count }}
steps:
- name: Checkout target ref
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ env.TARGET_REF }}
fetch-depth: 0
Expand Down Expand Up @@ -80,7 +80,7 @@ jobs:
SCCACHE_CACHE_SIZE: '2G'
steps:
- name: Checkout target ref
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ env.TARGET_REF }}
fetch-depth: 0
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
SCCACHE_CACHE_SIZE: '2G'
steps:
- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0

Expand Down
26 changes: 13 additions & 13 deletions Cargo.lock

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

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "openvcs-core"
version = "0.1.5"
version = "0.1.6"
edition = "2024"
description = "Core types and traits for OpenVCS."
license = "GPL-3.0-or-later"
Expand Down Expand Up @@ -31,10 +31,10 @@ default = ["plugin-protocol"]
plugin-protocol = ["dep:serde_json"]

# The VCS trait and VCS-related error type.
vcs = ["dep:thiserror", "backend-registry"]
vcs = ["dep:thiserror"]

# Backend discovery via the `BACKENDS` registry (link-time registration).
backend-registry = ["dep:linkme"]
backend-registry = ["dep:linkme", "vcs"]

[dependencies]
serde = { version = "1", features = ["derive"] }
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# OpenVCS Core (`openvcs-core`)

[![Dev CI (fast)](https://github.com/Open-VCS/OpenVCS-Core/actions/workflows/ci.yml/badge.svg)](https://github.com/Open-VCS/OpenVCS-Core/actions/workflows/ci.yml)
[![Nightly](https://github.com/Open-VCS/OpenVCS-Core/actions/workflows/nightly.yml/badge.svg?branch=Dev)](https://github.com/Open-VCS/OpenVCS-Core/actions/workflows/nightly.yml)
[![Dev](https://github.com/Open-VCS/OpenVCS-Core/actions/workflows/ci.yml/badge.svg?branch=Dev)](https://github.com/Open-VCS/OpenVCS-Core/actions/workflows/ci.yml)
[![Stable](https://github.com/Open-VCS/OpenVCS-Core/actions/workflows/release.yml/badge.svg?branch=Dev)](https://github.com/Open-VCS/OpenVCS-Core/actions/workflows/release.yml)

Shared Rust crate for:
- OpenVCS plugins (JSON-RPC over stdio)
Expand Down
25 changes: 17 additions & 8 deletions src/host.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::plugin_protocol::RpcRequest;
use crate::plugin_stdio::{PluginError, RequestIdState, call_host};
use crate::plugin_protocol::RpcResponse;
use crate::plugin_stdio::{PluginError, RequestIdState, SharedQueue, call_host};
use serde_json::Value;
use std::collections::VecDeque;
use std::io::{BufReader, LineWriter};
use std::sync::{Arc, Mutex, OnceLock};
use std::time::Duration;
Expand All @@ -13,7 +13,8 @@ pub type HostStdin = BufReader<std::io::Stdin>;
struct HostContext {
out: Arc<Mutex<HostStdout>>,
stdin: Arc<Mutex<HostStdin>>,
queue: Arc<Mutex<VecDeque<RpcRequest>>>,
queue: Arc<SharedQueue<RpcRequest>>,
responses: Arc<SharedQueue<RpcResponse>>,
ids: Arc<Mutex<RequestIdState>>,
timeout: Duration,
}
Expand All @@ -23,22 +24,30 @@ static HOST: OnceLock<HostContext> = OnceLock::new();
pub fn init_stdio_default(next_id: u64, timeout: Duration) {
let out = Arc::new(Mutex::new(LineWriter::new(std::io::stdout())));
let stdin = Arc::new(Mutex::new(BufReader::new(std::io::stdin())));
let queue = Arc::new(Mutex::new(VecDeque::new()));
let queue = Arc::new(SharedQueue::new());
let responses = Arc::new(SharedQueue::new());
let ids = Arc::new(Mutex::new(RequestIdState { next_id }));
init_default_stdio_host(out, stdin, queue, ids, timeout);
crate::plugin_stdio::start_reader_thread(
Arc::clone(&stdin),
Arc::clone(&queue),
Arc::clone(&responses),
);
init_default_stdio_host(out, stdin, queue, responses, ids, timeout);
}

pub fn init_default_stdio_host(
out: Arc<Mutex<HostStdout>>,
stdin: Arc<Mutex<HostStdin>>,
queue: Arc<Mutex<VecDeque<RpcRequest>>>,
queue: Arc<SharedQueue<RpcRequest>>,
responses: Arc<SharedQueue<RpcResponse>>,
ids: Arc<Mutex<RequestIdState>>,
timeout: Duration,
) {
let _ = HOST.set(HostContext {
out,
stdin,
queue,
responses,
ids,
timeout,
});
Expand All @@ -58,7 +67,7 @@ pub fn stdin() -> Result<&'static Arc<Mutex<HostStdin>>, PluginError> {
.stdin)
}

pub fn queue() -> Result<&'static Arc<Mutex<VecDeque<RpcRequest>>>, PluginError> {
pub fn queue() -> Result<&'static Arc<SharedQueue<RpcRequest>>, PluginError> {
Ok(&HOST
.get()
.ok_or_else(|| PluginError::code("host.uninitialized", "host not initialized"))?
Expand All @@ -82,7 +91,7 @@ pub fn call(method: &str, params: Value) -> Result<Value, PluginError> {
call_host(
&ctx.out,
&ctx.stdin,
&ctx.queue,
&ctx.responses,
&ctx.ids,
method,
params,
Expand Down
22 changes: 1 addition & 21 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub use crate::backend_id::BackendId;
#[doc(hidden)]
pub use log as __log;

#[cfg(feature = "backend-registry")]
#[cfg(all(feature = "backend-registry", feature = "vcs"))]
pub mod backend_descriptor;

#[cfg(feature = "plugin-protocol")]
Expand Down Expand Up @@ -273,26 +273,6 @@ pub trait Vcs: Send + Sync {
Err(VcsError::Unsupported(self.id()))
}

// lfs
fn lfs_fetch(&self) -> Result<()> {
Err(VcsError::Unsupported(self.id()))
}
fn lfs_pull(&self) -> Result<()> {
Err(VcsError::Unsupported(self.id()))
}
fn lfs_prune(&self) -> Result<()> {
Err(VcsError::Unsupported(self.id()))
}
fn lfs_track(&self, _paths: &[PathBuf]) -> Result<()> {
Err(VcsError::Unsupported(self.id()))
}
fn lfs_untrack(&self, _paths: &[PathBuf]) -> Result<()> {
Err(VcsError::Unsupported(self.id()))
}
fn lfs_is_tracked(&self, _path: &Path) -> Result<bool> {
Err(VcsError::Unsupported(self.id()))
}

// history operations
fn cherry_pick(&self, _rev: &str) -> Result<()> {
Err(VcsError::Unsupported(self.id()))
Expand Down
38 changes: 14 additions & 24 deletions src/plugin_runtime.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use crate::models::VcsEvent;
use crate::plugin_protocol::{PluginMessage, RpcRequest};
use crate::plugin_stdio::ok_null;
use crate::plugin_stdio::{PluginError, receive_message, respond_shared, send_message_shared};
use crate::plugin_stdio::{PluginError, SharedQueue, respond_shared, send_message_shared};
use std::collections::HashMap;
use std::collections::VecDeque;
use std::io::{self, BufReader, LineWriter};
use std::sync::{Arc, Mutex, OnceLock};
use std::time::Duration;
Expand Down Expand Up @@ -37,32 +36,17 @@ impl PluginCtx {
}
}

fn next_request(
queue: &Arc<Mutex<VecDeque<RpcRequest>>>,
stdin: &Arc<Mutex<BufReader<io::Stdin>>>,
) -> Option<RpcRequest> {
if let Ok(mut q) = queue.lock()
&& let Some(req) = q.pop_front()
{
fn next_request(queue: &Arc<SharedQueue<RpcRequest>>) -> Option<RpcRequest> {
if let Some(req) = queue.pop_now() {
return Some(req);
}

loop {
let msg = {
let mut lock = stdin.lock().ok()?;
receive_message(&mut *lock)?
};
match msg {
PluginMessage::Request(req) => return Some(req),
PluginMessage::Response(_) | PluginMessage::Event { .. } => continue,
}
}
queue.pop_wait()
}

pub struct PluginRuntime {
ctx: PluginCtx,
stdin: Arc<Mutex<BufReader<io::Stdin>>>,
queue: Arc<Mutex<VecDeque<RpcRequest>>>,
queue: Arc<SharedQueue<RpcRequest>>,
}

impl PluginRuntime {
Expand All @@ -77,20 +61,26 @@ impl PluginRuntime {

let stdout = Arc::new(Mutex::new(LineWriter::new(io::stdout())));
let stdin = Arc::new(Mutex::new(BufReader::new(io::stdin())));
let queue: Arc<Mutex<VecDeque<RpcRequest>>> = Arc::new(Mutex::new(VecDeque::new()));
let queue: Arc<SharedQueue<RpcRequest>> = Arc::new(SharedQueue::new());
let responses = Arc::new(SharedQueue::new());
let ids = Arc::new(Mutex::new(crate::plugin_stdio::RequestIdState { next_id }));
crate::plugin_stdio::start_reader_thread(
Arc::clone(&stdin),
Arc::clone(&queue),
Arc::clone(&responses),
);

crate::host::init_default_stdio_host(
Arc::clone(&stdout),
Arc::clone(&stdin),
Arc::clone(&queue),
Arc::clone(&responses),
Arc::clone(&ids),
timeout,
);

Self {
ctx: PluginCtx { stdout },
stdin,
queue,
}
}
Expand All @@ -103,7 +93,7 @@ impl PluginRuntime {
&mut self,
mut handle: impl FnMut(&mut PluginCtx, RpcRequest) -> HandlerResult,
) -> io::Result<bool> {
let Some(req) = next_request(&self.queue, &self.stdin) else {
let Some(req) = next_request(&self.queue) else {
return Ok(false);
};
let id = req.id;
Expand Down
Loading
Loading