Skip to content

Commit 48aed33

Browse files
committed
add bridge download/management
1 parent f86f23c commit 48aed33

File tree

6 files changed

+172
-29
lines changed

6 files changed

+172
-29
lines changed

crates/core/src/bridge.rs

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
use anyhow::{Context, Result, bail};
2+
use std::{
3+
fs::{self},
4+
path::{Path, PathBuf},
5+
time::Duration,
6+
};
7+
use version_compare::Version;
8+
9+
use crate::github;
10+
11+
#[cfg(target_os = "windows")]
12+
const EXE_SUFFIX: &'static str = ".exe";
13+
14+
#[cfg(not(target_os = "windows"))]
15+
const EXE_SUFFIX: &str = "";
16+
17+
#[cfg(target_os = "linux")]
18+
const NAME: &str = "linux-x86-defold-nvim-bridge";
19+
20+
#[cfg(all(target_os = "macos", target_arch = "x86_64"))]
21+
const NAME: &str = "macos-x86-defold-nvim-bridge";
22+
23+
#[cfg(all(target_os = "macos", target_arch = "aarch64"))]
24+
const NAME: &str = "macos-arm-defold-nvim-bridge";
25+
26+
#[cfg(target_os = "windows")]
27+
const NAME: &str = "windows-x86-defold-nvim-bridge";
28+
29+
const OWNER: &str = "atomicptr";
30+
const REPOSITORY: &str = "defold.nvim";
31+
32+
pub fn path(plugin_root: &Path) -> Result<PathBuf> {
33+
let exe = exe_name();
34+
35+
if plugin_root.exists() {
36+
let candidates = [
37+
plugin_root.join(&exe),
38+
plugin_root.join("target").join("debug").join(&exe),
39+
plugin_root.join("target").join("release").join(&exe),
40+
];
41+
42+
if let Some(bridge_path) = candidates.into_iter().find(|p| p.exists()) {
43+
return Ok(bridge_path);
44+
}
45+
}
46+
47+
install()
48+
}
49+
50+
fn exe_name() -> String {
51+
format!("defold-nvim-bridge{EXE_SUFFIX}")
52+
}
53+
54+
fn local_path() -> Result<PathBuf> {
55+
let dir = dirs::data_dir()
56+
.context("could not get state dir")?
57+
.join("defold.nvim")
58+
.join("bin");
59+
60+
fs::create_dir_all(&dir)?;
61+
62+
Ok(dir.join(exe_name()))
63+
}
64+
65+
fn version_path() -> Result<PathBuf> {
66+
let dir = dirs::data_dir()
67+
.context("could not get state dir")?
68+
.join("defold.nvim")
69+
.join("meta");
70+
71+
fs::create_dir_all(&dir)?;
72+
73+
Ok(dir.join("bridge_version"))
74+
}
75+
76+
fn version() -> Result<String> {
77+
let file = version_path()?;
78+
79+
if !file.exists() {
80+
bail!("Version not found");
81+
}
82+
83+
Ok(fs::read_to_string(file)?)
84+
}
85+
86+
fn is_update_available() -> Result<bool> {
87+
if version_path()?.exists() {
88+
// if the version file is younger than a week dont bother
89+
let last_modified = version_path()?.metadata()?.modified()?;
90+
if last_modified.elapsed()? < Duration::from_hours(24 * 7) {
91+
return Ok(false);
92+
}
93+
}
94+
95+
let Ok(v) = version() else {
96+
return Ok(true);
97+
};
98+
99+
// re-write the file again so that we only check once a week
100+
fs::write(version_path()?, &v)?;
101+
102+
tracing::debug!("Bridge Version {v} installed");
103+
104+
let Some(installed) = Version::from(&v) else {
105+
return Ok(true);
106+
};
107+
108+
let release = github::fetch_release(OWNER, REPOSITORY)?;
109+
110+
tracing::debug!("Bridge Version {} is newest", release.tag_name);
111+
112+
let Some(current) = Version::from(&release.tag_name) else {
113+
return Ok(false);
114+
};
115+
116+
Ok(current > installed)
117+
}
118+
119+
fn install() -> Result<PathBuf> {
120+
let path = local_path()?;
121+
122+
if path.exists() && !is_update_available()? {
123+
return local_path();
124+
}
125+
126+
let (downloaded_file, release) = github::download_release(OWNER, REPOSITORY, NAME)?;
127+
128+
tracing::debug!("New Bridge version found {}", release.tag_name);
129+
130+
fs::rename(downloaded_file, &path)?;
131+
fs::write(version_path()?, release.tag_name)?;
132+
133+
#[cfg(any(target_os = "linux", target_os = "macos"))]
134+
{
135+
use std::{fs::Permissions, os::unix::fs::PermissionsExt};
136+
fs::set_permissions(&path, Permissions::from_mode(0o700))?;
137+
}
138+
139+
github::clear_downloads(OWNER, REPOSITORY)?;
140+
141+
Ok(path)
142+
}

crates/core/src/editor_config.rs

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ use std::{
77
str::FromStr,
88
};
99

10+
use crate::bridge;
11+
1012
#[derive(Debug, Deserialize)]
1113
pub enum LauncherType {
1214
#[serde(rename = "neovide")]
@@ -104,31 +106,6 @@ const SCRIPT_EXT: &'static str = "bat";
104106
#[cfg(not(target_os = "windows"))]
105107
const SCRIPT_EXT: &str = "sh";
106108

107-
#[cfg(target_os = "windows")]
108-
const EXE_SUFFIX: &'static str = ".exe";
109-
110-
#[cfg(not(target_os = "windows"))]
111-
const EXE_SUFFIX: &str = "";
112-
113-
fn find_bridge_path(plugin_root: &Path) -> Result<PathBuf> {
114-
let exe = format!("defold-nvim-bridge{EXE_SUFFIX}");
115-
116-
if plugin_root.exists() {
117-
let candidates = [
118-
plugin_root.join(&exe),
119-
plugin_root.join("target").join("debug").join(&exe),
120-
plugin_root.join("target").join("release").join(&exe),
121-
];
122-
123-
if let Some(bridge_path) = candidates.into_iter().find(|p| p.exists()) {
124-
return Ok(bridge_path);
125-
}
126-
}
127-
128-
// TODO: if not lets download it
129-
bail!("not yet implemented")
130-
}
131-
132109
fn create_runner_script(
133110
plugin_root: &Path,
134111
launcher_settings: &LauncherSettings,
@@ -140,7 +117,7 @@ fn create_runner_script(
140117
fs::create_dir_all(&dir)?;
141118

142119
let script_path = dir.join(format!("run.{SCRIPT_EXT}"));
143-
let bridge_path = find_bridge_path(plugin_root)?;
120+
let bridge_path = bridge::path(plugin_root)?;
144121
let launch_args = launcher_settings.bridge_cli_args().join(" ");
145122

146123
fs::write(

crates/core/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
pub mod bridge;
12
pub mod cache;
23
pub mod defold_annotations;
34
pub mod editor;

crates/sidecar/src/lib.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use anyhow::Context;
2-
use defold_nvim_core::{editor, editor_config, mobdap, project};
2+
use defold_nvim_core::{bridge, editor, editor_config, mobdap, project};
33
use defold_nvim_core::{focus, game_project::GameProject};
44
use mlua::Value;
55
use mlua::prelude::*;
@@ -68,6 +68,7 @@ fn register_exports(lua: &Lua) -> LuaResult<LuaTable> {
6868
"set_default_editor",
6969
lua.create_function(set_default_editor)?,
7070
)?;
71+
exports.set("find_bridge_path", lua.create_function(find_bridge_path)?)?;
7172
exports.set("focus_neovim", lua.create_function(focus_neovim)?)?;
7273
exports.set("focus_game", lua.create_function(focus_game)?)?;
7374
exports.set("mobdap_install", lua.create_function(mobdap_install)?)?;
@@ -140,6 +141,15 @@ fn set_default_editor(
140141
Ok(())
141142
}
142143

144+
fn find_bridge_path(_lua: &Lua, plugin_root: String) -> LuaResult<String> {
145+
let path = bridge::path(&absolute(plugin_root)?)?;
146+
147+
Ok(path
148+
.to_str()
149+
.context("could not convert path to string")?
150+
.to_string())
151+
}
152+
143153
fn focus_neovim(_lua: &Lua, game_root: String) -> LuaResult<()> {
144154
focus::focus_neovim(absolute(game_root)?)?;
145155

lua/defold/init.lua

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,13 @@ end
219219

220220
---Makes sure the native library `sidecar` gets loaded
221221
function M.download()
222-
require "defold.sidecar"
222+
local log = require "defold.service.logger"
223+
local sidecar = require "defold.sidecar"
224+
225+
local ok, err = pcall(sidecar.find_bridge_path, M.plugin_root())
226+
if not ok then
227+
log.error(string.format("Could not setup bridge: %s", err))
228+
end
223229
end
224230

225231
function M.load_plugin()
@@ -239,7 +245,13 @@ function M.load_plugin()
239245
local project = require "defold.project"
240246

241247
log.debug "============= defold.nvim: Loaded plugin"
242-
log.debug("Sidecar Version:" .. sidecar.version)
248+
log.debug("Sidecar Version: " .. sidecar.version)
249+
250+
local bridge_ok, bridge_path = pcall(sidecar.find_bridge_path, M.plugin_root())
251+
if bridge_ok then
252+
log.debug("Bridge Path: " .. bridge_path)
253+
end
254+
243255
if debugger.mobdap_path() then
244256
log.debug("Mobdap Path: " .. debugger.mobdap_path())
245257
end

lua/defold/sidecar.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ package.cpath = package.cpath
123123
---@field list_commands function(port: integer|nil): table<string, string>
124124
---@field send_command function(port: integer|nil, cmd: string)
125125
---@field set_default_editor function(plugin_root: string, launcher_config: LauncherSettings)
126+
---@field find_bridge_path function(plugin_root: string): string
126127
---@field focus_neovim function(game_root: string)
127128
---@field focus_game function(game_root: string)
128129
---@field mobdap_install function(): string

0 commit comments

Comments
 (0)