mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-04-22 21:55:15 +00:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
300975f49c | ||
|
|
325cf56457 | ||
|
|
71b1320aa8 | ||
|
|
c5abc87dbd | ||
|
|
bd7ab593d5 | ||
|
|
c93da3f6b2 | ||
|
|
8b90e98696 | ||
|
|
bc40ec8a5a | ||
|
|
f19cbccdd5 | ||
|
|
f25ae914e4 | ||
|
|
fb7bfa928a | ||
|
|
100d69262c | ||
|
|
5e01658846 | ||
|
|
ccec93aee8 | ||
|
|
a089d82023 | ||
|
|
82ba583fa0 | ||
|
|
1b82044d7d | ||
|
|
0d49a2e0af | ||
|
|
1343d3a2a9 |
16
CHANGES.md
16
CHANGES.md
@@ -1,6 +1,22 @@
|
|||||||
# Rojo Change Log
|
# Rojo Change Log
|
||||||
|
|
||||||
## Current master
|
## Current master
|
||||||
|
* *No changes*
|
||||||
|
|
||||||
|
## 0.4.13 (November 12, 2018)
|
||||||
|
* When `rojo.json` points to a file or directory that does not exist, Rojo now issues a warning instead of throwing an error and exiting
|
||||||
|
|
||||||
|
## 0.4.12 (June 21, 2018)
|
||||||
|
* Fixed obscure assertion failure when renaming or deleting files ([#78](https://github.com/LPGhatguy/rojo/issues/78))
|
||||||
|
* Added a `PluginAction` for the sync in command, which should help with some automation scripts ([#80](https://github.com/LPGhatguy/rojo/pull/80))
|
||||||
|
|
||||||
|
## 0.4.11 (June 10, 2018)
|
||||||
|
* Defensively insert existing instances into RouteMap; should fix most duplication cases when syncing into existing trees.
|
||||||
|
* Fixed incorrect synchronization from `Plugin:_pull` that would cause polling to create issues
|
||||||
|
* Fixed incorrect file routes being assigned to `init.lua` and `init.model.json` files
|
||||||
|
* Untangled route handling-internals slightly
|
||||||
|
|
||||||
|
## 0.4.10 (June 2, 2018)
|
||||||
* Added support for `init.model.json` files, which enable versioning `Tool` instances (among other things) with Rojo. ([#66](https://github.com/LPGhatguy/rojo/issues/66))
|
* Added support for `init.model.json` files, which enable versioning `Tool` instances (among other things) with Rojo. ([#66](https://github.com/LPGhatguy/rojo/issues/66))
|
||||||
* Fixed obscure error when syncing into an invalid service.
|
* Fixed obscure error when syncing into an invalid service.
|
||||||
* Fixed multiple sync processes occurring when a server ID mismatch is detected.
|
* Fixed multiple sync processes occurring when a server ID mismatch is detected.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<a href="https://travis-ci.org/LPGhatguy/rojo">
|
<a href="https://travis-ci.org/LPGhatguy/rojo">
|
||||||
<img src="https://api.travis-ci.org/LPGhatguy/rojo.svg?branch=master" alt="Travis-CI Build Status" />
|
<img src="https://api.travis-ci.org/LPGhatguy/rojo.svg?branch=master" alt="Travis-CI Build Status" />
|
||||||
</a>
|
</a>
|
||||||
<img src="https://img.shields.io/badge/latest_version-0.4.9-brightgreen.svg" alt="Current server version" />
|
<img src="https://img.shields.io/badge/latest_version-0.4.13-brightgreen.svg" alt="Current server version" />
|
||||||
<a href="https://lpghatguy.github.io/rojo">
|
<a href="https://lpghatguy.github.io/rojo">
|
||||||
<img src="https://img.shields.io/badge/documentation-website-brightgreen.svg" alt="Rojo Documentation" />
|
<img src="https://img.shields.io/badge/documentation-website-brightgreen.svg" alt="Rojo Documentation" />
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -20,4 +20,7 @@ To install the plugin, either:
|
|||||||
* Install the plugin from the [Roblox plugin page](https://www.roblox.com/library/1211549683/Rojo).
|
* Install the plugin from the [Roblox plugin page](https://www.roblox.com/library/1211549683/Rojo).
|
||||||
* This gives you less control over what version you install -- you will always have the latest version.
|
* This gives you less control over what version you install -- you will always have the latest version.
|
||||||
* Or, download the latest release from [the GitHub releases section](https://github.com/LPGhatguy/rojo/releases) and install it into your Roblox plugins folder
|
* Or, download the latest release from [the GitHub releases section](https://github.com/LPGhatguy/rojo/releases) and install it into your Roblox plugins folder
|
||||||
* You can open this folder by clicking the "Plugins Folder" button from the Plugins toolbar in Roblox Studio
|
* You can open this folder by clicking the "Plugins Folder" button from the Plugins toolbar in Roblox Studio
|
||||||
|
|
||||||
|
## Visual Studio Code Extension
|
||||||
|
If you use Visual Studio Code on Windows, you can install [Evaera's unofficial Rojo extension](https://marketplace.visualstudio.com/items?itemName=evaera.vscode-rojo), which will install both halves of Rojo for you. It even has a nifty UI to add partitions and start/stop the Rojo server!
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
return {
|
return {
|
||||||
pollingRate = 0.2,
|
pollingRate = 0.3,
|
||||||
version = {0, 4, 9},
|
version = {0, 4, 13},
|
||||||
expectedServerVersionString = "0.4.x",
|
expectedServerVersionString = "0.4.x",
|
||||||
protocolVersion = 1,
|
protocolVersion = 1,
|
||||||
icons = {
|
icons = {
|
||||||
|
|||||||
@@ -55,15 +55,20 @@ local function main()
|
|||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
toolbar:CreateButton("Sync In", "Sync into Roblox Studio", Config.icons.syncIn)
|
local function syncIn()
|
||||||
.Click:Connect(function()
|
checkUpgrade()
|
||||||
checkUpgrade()
|
|
||||||
|
|
||||||
pluginInstance:syncIn()
|
pluginInstance:syncIn()
|
||||||
:catch(function(err)
|
:catch(function(err)
|
||||||
warn(err)
|
warn(err)
|
||||||
end)
|
end)
|
||||||
end)
|
end
|
||||||
|
|
||||||
|
local shortDescription = "Sync In"
|
||||||
|
local longDescription = "Sync into Roblox Studio"
|
||||||
|
|
||||||
|
toolbar:CreateButton(shortDescription, longDescription, Config.icons.syncIn).Click:Connect(syncIn)
|
||||||
|
plugin:CreatePluginAction("RojoSyncIn", shortDescription, longDescription).Triggered:Connect(syncIn)
|
||||||
|
|
||||||
toolbar:CreateButton("Toggle Polling", "Poll server for changes", Config.icons.togglePolling)
|
toolbar:CreateButton("Toggle Polling", "Poll server for changes", Config.icons.togglePolling)
|
||||||
.Click:Connect(function()
|
.Click:Connect(function()
|
||||||
|
|||||||
@@ -169,38 +169,34 @@ function Plugin:stopPolling()
|
|||||||
return Promise.resolve(true)
|
return Promise.resolve(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Plugin:_pull(api, project, routes)
|
function Plugin:_pull(api, project, fileRoutes)
|
||||||
return api:read(routes)
|
return api:read(fileRoutes)
|
||||||
:andThen(function(items)
|
:andThen(function(items)
|
||||||
for index = 1, #routes do
|
for index = 1, #fileRoutes do
|
||||||
local itemRoute = routes[index]
|
local fileRoute = fileRoutes[index]
|
||||||
local partitionName = itemRoute[1]
|
local partitionName = fileRoute[1]
|
||||||
local partition = project.partitions[partitionName]
|
local partition = project.partitions[partitionName]
|
||||||
local item = items[index]
|
local item = items[index]
|
||||||
|
|
||||||
local partitionRoute = collectMatch(partition.target, "[^.]+")
|
local partitionTargetRbxRoute = collectMatch(partition.target, "[^.]+")
|
||||||
|
|
||||||
-- If the item route's length was 1, we need to rename the instance to
|
-- If the item route's length was 1, we need to rename the instance to
|
||||||
-- line up with the partition's root object name.
|
-- line up with the partition's root object name.
|
||||||
--
|
if item ~= nil and #fileRoute == 1 then
|
||||||
-- This is a HACK!
|
local objectName = partition.target:match("[^.]+$")
|
||||||
if #itemRoute == 1 then
|
item.Name = objectName
|
||||||
if item then
|
|
||||||
local objectName = partition.target:match("[^.]+$")
|
|
||||||
item.Name = objectName
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local fullRoute = {}
|
local itemRbxRoute = {}
|
||||||
for _, piece in ipairs(partitionRoute) do
|
for _, piece in ipairs(partitionTargetRbxRoute) do
|
||||||
table.insert(fullRoute, piece)
|
table.insert(itemRbxRoute, piece)
|
||||||
end
|
end
|
||||||
|
|
||||||
for i = 2, #itemRoute do
|
for i = 2, #fileRoute do
|
||||||
table.insert(fullRoute, itemRoute[i])
|
table.insert(itemRbxRoute, fileRoute[i])
|
||||||
end
|
end
|
||||||
|
|
||||||
self._reconciler:reconcileRoute(fullRoute, item, itemRoute)
|
self._reconciler:reconcileRoute(itemRbxRoute, item, fileRoute)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
@@ -283,15 +279,20 @@ function Plugin:syncIn()
|
|||||||
return Promise.reject(info)
|
return Promise.reject(info)
|
||||||
end
|
end
|
||||||
|
|
||||||
local routes = {}
|
local fileRoutes = {}
|
||||||
|
|
||||||
for name in pairs(info.project.partitions) do
|
for name in pairs(info.project.partitions) do
|
||||||
table.insert(routes, {name})
|
table.insert(fileRoutes, {name})
|
||||||
end
|
end
|
||||||
|
|
||||||
self:_pull(api, info.project, routes)
|
local pullSuccess, pullResult = self:_pull(api, info.project, fileRoutes):await()
|
||||||
|
|
||||||
self._syncInProgress = false
|
self._syncInProgress = false
|
||||||
|
|
||||||
|
if not pullSuccess then
|
||||||
|
return Promise.reject(pullResult)
|
||||||
|
end
|
||||||
|
|
||||||
print("Rojo: Sync successful!")
|
print("Rojo: Sync successful!")
|
||||||
end)
|
end)
|
||||||
:catch(function(err)
|
:catch(function(err)
|
||||||
|
|||||||
@@ -170,6 +170,8 @@ function Reconciler:reconcile(rbx, item)
|
|||||||
-- Item was deleted
|
-- Item was deleted
|
||||||
if item == nil then
|
if item == nil then
|
||||||
if rbx ~= nil then
|
if rbx ~= nil then
|
||||||
|
-- TODO: If this is a partition root, should we leave it alone?
|
||||||
|
|
||||||
self._routeMap:removeByRbx(rbx)
|
self._routeMap:removeByRbx(rbx)
|
||||||
rbx:Destroy()
|
rbx:Destroy()
|
||||||
end
|
end
|
||||||
@@ -190,18 +192,24 @@ function Reconciler:reconcile(rbx, item)
|
|||||||
return self:_reify(item)
|
return self:_reify(item)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- It's possible that the instance we're associating with this item hasn't
|
||||||
|
-- been inserted into the RouteMap yet.
|
||||||
|
if item.Route ~= nil then
|
||||||
|
self._routeMap:insert(item.Route, rbx)
|
||||||
|
end
|
||||||
|
|
||||||
applyProperties(rbx, item.Properties)
|
applyProperties(rbx, item.Properties)
|
||||||
self:_reconcileChildren(rbx, item)
|
self:_reconcileChildren(rbx, item)
|
||||||
|
|
||||||
return rbx
|
return rbx
|
||||||
end
|
end
|
||||||
|
|
||||||
function Reconciler:reconcileRoute(route, item, itemRoute)
|
function Reconciler:reconcileRoute(rbxRoute, item, fileRoute)
|
||||||
local parent
|
local parent
|
||||||
local rbx = game
|
local rbx = game
|
||||||
|
|
||||||
for i = 1, #route do
|
for i = 1, #rbxRoute do
|
||||||
local piece = route[i]
|
local piece = rbxRoute[i]
|
||||||
|
|
||||||
local child = rbx:FindFirstChild(piece)
|
local child = rbx:FindFirstChild(piece)
|
||||||
|
|
||||||
@@ -217,7 +225,7 @@ function Reconciler:reconcileRoute(route, item, itemRoute)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- We don't want to create a folder if we're reaching our target item!
|
-- We don't want to create a folder if we're reaching our target item!
|
||||||
if child == nil and i ~= #route then
|
if child == nil and i ~= #rbxRoute then
|
||||||
child = Instance.new("Folder")
|
child = Instance.new("Folder")
|
||||||
child.Parent = rbx
|
child.Parent = rbx
|
||||||
child.Name = piece
|
child.Name = piece
|
||||||
@@ -229,12 +237,14 @@ function Reconciler:reconcileRoute(route, item, itemRoute)
|
|||||||
|
|
||||||
-- Let's check the route map!
|
-- Let's check the route map!
|
||||||
if rbx == nil then
|
if rbx == nil then
|
||||||
rbx = self._routeMap:get(itemRoute)
|
rbx = self._routeMap:get(fileRoute)
|
||||||
end
|
end
|
||||||
|
|
||||||
rbx = self:reconcile(rbx, item)
|
rbx = self:reconcile(rbx, item)
|
||||||
|
|
||||||
reparent(rbx, parent)
|
if rbx ~= nil then
|
||||||
|
reparent(rbx, parent)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return Reconciler
|
return Reconciler
|
||||||
|
|||||||
2
server/Cargo.lock
generated
2
server/Cargo.lock
generated
@@ -636,7 +636,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rojo"
|
name = "rojo"
|
||||||
version = "0.4.10"
|
version = "0.4.13"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "rojo"
|
name = "rojo"
|
||||||
version = "0.4.10"
|
version = "0.4.13"
|
||||||
authors = ["Lucien Greathouse <me@lpghatguy.com>"]
|
authors = ["Lucien Greathouse <me@lpghatguy.com>"]
|
||||||
description = "A tool to create robust Roblox projects"
|
description = "A tool to create robust Roblox projects"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ impl Plugin for JsonModelPlugin {
|
|||||||
|
|
||||||
rbx_item.name.clear();
|
rbx_item.name.clear();
|
||||||
rbx_item.name.push_str(vfs_item.name());
|
rbx_item.name.push_str(vfs_item.name());
|
||||||
|
rbx_item.route = Some(vfs_item.route().to_vec());
|
||||||
|
|
||||||
for (child_name, child_item) in children {
|
for (child_name, child_item) in children {
|
||||||
if child_name == init_item.name() {
|
if child_name == init_item.name() {
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ impl Plugin for ScriptPlugin {
|
|||||||
|
|
||||||
rbx_item.name.clear();
|
rbx_item.name.clear();
|
||||||
rbx_item.name.push_str(vfs_item.name());
|
rbx_item.name.push_str(vfs_item.name());
|
||||||
|
rbx_item.route = Some(vfs_item.route().to_vec());
|
||||||
|
|
||||||
for (child_name, child_item) in children {
|
for (child_name, child_item) in children {
|
||||||
if child_name == init_item.name() {
|
if child_name == init_item.name() {
|
||||||
|
|||||||
@@ -83,7 +83,8 @@ impl VfsWatcher {
|
|||||||
match watcher.watch(&root_path, RecursiveMode::Recursive) {
|
match watcher.watch(&root_path, RecursiveMode::Recursive) {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
panic!("Unable to watch partition {}, with path {}! Make sure that it's a file or directory.", partition_name, root_path.display());
|
eprintln!("WARNING: Unable to watch partition {}, with path {}\nMake sure that it's a file or directory.", partition_name, root_path.display());
|
||||||
|
continue;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,10 @@
|
|||||||
"extra": {
|
"extra": {
|
||||||
"path": "extra-script.lua",
|
"path": "extra-script.lua",
|
||||||
"target": "ReplicatedStorage.ExtraScript"
|
"target": "ReplicatedStorage.ExtraScript"
|
||||||
|
},
|
||||||
|
"does-not-exist": {
|
||||||
|
"path": "hahah",
|
||||||
|
"target": "ReplicatedStorage.Never"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user