Skip to content

Commit

Permalink
allow commit specification in git imports
Browse files Browse the repository at this point in the history
  • Loading branch information
kaikalii committed Jun 20, 2024
1 parent 026f975 commit 8d9d6c3
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 19 deletions.
14 changes: 10 additions & 4 deletions site/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::{

use crate::{editor::get_ast_time, weewuh};
use leptos::*;
use uiua::{Handle, Report, SysBackend, EXAMPLE_TXT, EXAMPLE_UA};
use uiua::{GitTarget, Handle, Report, SysBackend, EXAMPLE_TXT, EXAMPLE_UA};
use wasm_bindgen::prelude::*;
use wasm_bindgen_futures::JsFuture;
use web_sys::{Request, RequestInit, RequestMode, Response};
Expand Down Expand Up @@ -350,9 +350,15 @@ impl SysBackend for WebBackend {
while (instant::now() - start) / 1000.0 < seconds {}
Ok(())
}
fn load_git_module(&self, url: &str, branch: Option<&str>) -> Result<PathBuf, String> {
if branch.is_some() {
return Err("Git branch specification is not supported in the web backend".into());
fn load_git_module(&self, url: &str, target: GitTarget) -> Result<PathBuf, String> {
match target {
GitTarget::Default => {}
GitTarget::Branch(_) => {
return Err("Git branch specification is not supported in the web backend".into())
}
GitTarget::Commit(_) => {
return Err("Git commit specification is not supported in the web backend".into())
}
}
let mut parts = url.rsplitn(3, '/');
let repo_name = parts.next().ok_or("Invalid git url")?;
Expand Down
24 changes: 17 additions & 7 deletions src/compile/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use crate::{
lsp::{CodeMeta, SigDecl},
optimize::{optimize_instrs, optimize_instrs_mut},
parse::{count_placeholders, parse, split_words, unsplit_words},
Array, Assembly, BindingKind, Boxed, Diagnostic, DiagnosticKind, DocComment, Ident,
Array, Assembly, BindingKind, Boxed, Diagnostic, DiagnosticKind, DocComment, GitTarget, Ident,
ImplPrimitive, InputSrc, IntoInputSrc, IntoSysBackend, Primitive, RunMode, SemanticComment,
SysBackend, Uiua, UiuaError, UiuaErrorKind, UiuaResult, Value, CONSTANTS, EXAMPLE_UA, VERSION,
};
Expand Down Expand Up @@ -712,12 +712,22 @@ code:
/// Import a module
pub(crate) fn import_module(&mut self, path_str: &str, span: &CodeSpan) -> UiuaResult<PathBuf> {
// Resolve path
let path = if let Some(mut url) = path_str.strip_prefix("git:") {
let mut branch = None;
if let Some((a, b)) = url.split_once("branch:") {
url = a;
branch = Some(b.trim());
let path = if let Some(mut url) = path_str.trim().strip_prefix("git:") {
if url.contains("branch:") && url.contains("commit:") {
return Err(self.fatal_error(
span.clone(),
"Cannot specify both branch and commit in git import",
));
}
let target = if let Some((a, b)) = url.split_once("branch:") {
url = a;
GitTarget::Branch(b.trim().into())
} else if let Some((a, b)) = url.split_once("commit:") {
url = a;
GitTarget::Commit(b.trim().into())
} else {
GitTarget::Default
};
// Git import
let mut url = url.trim().trim_end_matches(".git").to_string();
if ![".com", ".net", ".org", ".io", ".dev"]
Expand All @@ -733,7 +743,7 @@ code:
url = format!("https://{url}");
}
self.backend()
.load_git_module(&url, branch)
.load_git_module(&url, target)
.map_err(|e| self.fatal_error(span.clone(), e))?
} else {
// Normal import
Expand Down
2 changes: 1 addition & 1 deletion src/compile/modifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,7 @@ impl Compiler {
self.push_instr(Instr::PushFunc(func));
}
}
Flop => {
Rear => {
let operand = modified.code_operands().next().unwrap().clone();
let (mut instrs, sig) = self.compile_operand_word(operand)?;
if sig.args != 2 {
Expand Down
4 changes: 2 additions & 2 deletions src/primitive/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ impl Primitive {
use SysOp::*;
matches!(
self,
(But | Flop)
(But | Rear)
| (Orient | Coordinate | Astar | Fft | Triangle | Case)
| Sys(Ffi | MemCopy | MemFree | TlsListen)
| (Stringify | Quote | Sig)
Expand Down Expand Up @@ -851,7 +851,7 @@ impl Primitive {
| Primitive::By
| Primitive::Gap
| Primitive::But
| Primitive::Flop
| Primitive::Rear
| Primitive::Un
| Primitive::Under
| Primitive::Content
Expand Down
14 changes: 13 additions & 1 deletion src/sys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1021,11 +1021,23 @@ pub trait SysBackend: Any + Send + Sync + 'static {
/// Load a git repo as a module
///
/// The returned path should be loadable via [`SysBackend::file_read_all`]
fn load_git_module(&self, url: &str, branch: Option<&str>) -> Result<PathBuf, String> {
fn load_git_module(&self, url: &str, target: GitTarget) -> Result<PathBuf, String> {
Err("Loading git modules is not supported in this environment".into())
}
}

/// A target for a git repository
#[derive(Debug, Clone, Default)]
pub enum GitTarget {
/// The latest commit on the default branch
#[default]
Default,
/// The latest commit on a specific branch
Branch(String),
/// A specific commit
Commit(String),
}

impl fmt::Debug for dyn SysBackend {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "<sys backend>")
Expand Down
22 changes: 19 additions & 3 deletions src/sys_native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use std::{
time::Duration,
};

use crate::{Handle, SysBackend};
use crate::{GitTarget, Handle, SysBackend};
use dashmap::DashMap;
use once_cell::sync::Lazy;

Expand Down Expand Up @@ -1009,7 +1009,7 @@ impl SysBackend for NativeSys {
crate::ffi_free(ptr);
Ok(())
}
fn load_git_module(&self, url: &str, branch: Option<&str>) -> Result<PathBuf, String> {
fn load_git_module(&self, url: &str, target: GitTarget) -> Result<PathBuf, String> {
if let Some(path) = NATIVE_SYS.git_paths.get(url) {
if path.is_err() || path.as_ref().unwrap().exists() {
return path.clone();
Expand Down Expand Up @@ -1052,7 +1052,7 @@ impl SysBackend for NativeSys {
if !submodule_path.exists() {
let submod_path = submodule_path.to_string_lossy();
let mut args = vec!["submodule", "add", "--force"];
if let Some(branch) = branch {
if let GitTarget::Branch(branch) = &target {
args.push("-b");
args.push(branch);
}
Expand All @@ -1071,6 +1071,22 @@ impl SysBackend for NativeSys {
stderr.read_to_string(&mut err).map_err(|e| e.to_string())?;
return Err(format!("Failed to add submodule: {err}"));
}
if let GitTarget::Commit(hash) = &target {
std::env::set_current_dir(&*submod_path).map_err(|e| e.to_string())?;
let mut child = Command::new("git")
.args(["checkout", hash])
.stderr(Stdio::piped())
.stdout(Stdio::null())
.spawn()
.map_err(|e| e.to_string())?;
let status = child.wait().map_err(|e| e.to_string())?;
if !status.success() {
let stderr = child.stderr.as_mut().unwrap();
let mut err = String::new();
stderr.read_to_string(&mut err).map_err(|e| e.to_string())?;
return Err(format!("Failed to checkout commit: {err}"));
}
}
}
Ok(path)
})();
Expand Down
1 change: 0 additions & 1 deletion todo.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

- 0.12
- Stabilize labels
- `branch:` and `commit:` specifiers for imports
- Goto definition/Ctrl+click on git imports to go to the URL
- `take` `&fras`/`&frab`
- Stack-source locality tutorial
Expand Down

0 comments on commit 8d9d6c3

Please sign in to comment.