mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-22 21:41:37 +00:00
Implement auto-download feature for syncback command
- Enhanced the `syncback` command to automatically download Roblox place files from the asset delivery API, allowing for zero-argument usage. - Updated `Cargo.toml` to include compression features for `reqwest` and moved `tempfile` to dependencies. - Introduced a new `download` argument in `SyncbackCommand` to specify place IDs for downloading. - Implemented logic to resolve input file paths, prioritizing downloads when necessary. - Added sourcemap generation after successful syncback and refreshed the git index if in a repository. - Updated tests to validate the new download functionality and sourcemap creation.
This commit is contained in:
parent
8fe908740f
commit
2b2ada219e
32 changed files with 1180 additions and 125 deletions
|
|
@ -5,7 +5,7 @@ todos: []
|
|||
isProject: false
|
||||
---
|
||||
|
||||
# Destructive Syncback Mode
|
||||
# Destructive Syncback Mode (Clean by Default)
|
||||
|
||||
## Root Cause Analysis
|
||||
|
||||
|
|
@ -50,41 +50,46 @@ if let Some(old_child) = old_child_map.remove(new_child.name.as_str()) {
|
|||
}
|
||||
```
|
||||
|
||||
## Solution: Add `--clean` Flag
|
||||
## Solution: Clean Mode by Default with `--incremental` Flag
|
||||
|
||||
Add a `--clean` flag that makes syncback treat all instances as "new" by setting `old` references to `None`, ensuring consistent output regardless of existing filesystem state.
|
||||
Make clean (destructive) mode the default behavior, with an `--incremental` flag to opt into the legacy structure-preserving behavior.
|
||||
|
||||
### Ensuring No Residue Files
|
||||
|
||||
The key challenge: if we set `old = None`, the `removed_children` logic won't work (nothing to compare against). We need a two-phase approach:
|
||||
|
||||
1. **Phase 1**: Collect ALL existing paths from the old tree before syncback
|
||||
2. **Phase 2**: After computing new paths, remove any old paths that aren't in the new set
|
||||
|
||||
This guarantees no orphaned files remain.
|
||||
|
||||
### Changes Required
|
||||
|
||||
#### 1. Add CLI Flag (`[src/cli/syncback.rs](src/cli/syncback.rs)`)
|
||||
|
||||
Add `--clean` flag to the command definition:
|
||||
Add `--incremental` flag (clean mode is now default):
|
||||
|
||||
```rust
|
||||
/// If provided, syncback will ignore existing file structure and create
|
||||
/// a fresh project layout. This ensures consistent output regardless of
|
||||
/// existing filesystem state.
|
||||
#[clap(long)]
|
||||
pub clean: bool,
|
||||
/// If provided, syncback will preserve existing file structure and middleware
|
||||
/// formats when possible. Without this flag, syncback creates a fresh project
|
||||
/// layout that exactly matches the input file.
|
||||
#[clap(long, short = 'n')]
|
||||
pub incremental: bool,
|
||||
```
|
||||
|
||||
#### 2. Pass Flag to `syncback_loop` (`[src/cli/syncback.rs](src/cli/syncback.rs)`)
|
||||
|
||||
Modify the `syncback_loop` call to pass the clean flag:
|
||||
|
||||
```rust
|
||||
let snapshot = syncback_loop(
|
||||
session_old.vfs(),
|
||||
&mut dom_old,
|
||||
dom_new,
|
||||
session_old.root_project(),
|
||||
self.clean, // New parameter
|
||||
self.incremental, // false = clean mode (default)
|
||||
)?;
|
||||
```
|
||||
|
||||
#### 3. Modify `syncback_loop` (`[src/syncback/mod.rs](src/syncback/mod.rs)`)
|
||||
|
||||
Update function signature and initial snapshot:
|
||||
#### 3. Modify `syncback_loop` Signature (`[src/syncback/mod.rs](src/syncback/mod.rs)`)
|
||||
|
||||
```rust
|
||||
pub fn syncback_loop(
|
||||
|
|
@ -92,67 +97,120 @@ pub fn syncback_loop(
|
|||
old_tree: &mut RojoTree,
|
||||
mut new_tree: WeakDom,
|
||||
project: &Project,
|
||||
clean_mode: bool, // New parameter
|
||||
incremental: bool, // false = clean mode (default)
|
||||
) -> anyhow::Result<FsSnapshot>
|
||||
```
|
||||
|
||||
When `clean_mode` is true, set the initial `old` reference to `None`:
|
||||
#### 4. Collect Existing Paths Before Syncback (`[src/syncback/mod.rs](src/syncback/mod.rs)`)
|
||||
|
||||
Before the main loop, collect all existing filesystem paths (respecting ignore patterns):
|
||||
|
||||
```rust
|
||||
// Collect all existing paths from old tree for cleanup in clean mode
|
||||
let existing_paths: HashSet<PathBuf> = if !incremental {
|
||||
let mut paths = HashSet::new();
|
||||
for ref_id in descendants(old_tree.inner(), old_tree.get_root_id()) {
|
||||
if let Some(inst) = old_tree.get_instance(ref_id) {
|
||||
for path in inst.metadata().relevant_paths.iter() {
|
||||
// Skip paths matching ignore patterns
|
||||
if is_valid_path(&ignore_patterns, project_path, path) {
|
||||
paths.insert(path.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
paths
|
||||
} else {
|
||||
HashSet::new()
|
||||
};
|
||||
```
|
||||
|
||||
#### 5. Set `old = None` in Clean Mode (`[src/syncback/mod.rs](src/syncback/mod.rs)`)
|
||||
|
||||
```rust
|
||||
let mut snapshots = vec![SyncbackSnapshot {
|
||||
data: syncback_data,
|
||||
old: if clean_mode { None } else { Some(old_tree.get_root_id()) },
|
||||
old: if incremental { Some(old_tree.get_root_id()) } else { None },
|
||||
new: new_tree.root_ref(),
|
||||
path: project.file_location.clone(),
|
||||
middleware: Some(Middleware::Project),
|
||||
}];
|
||||
```
|
||||
|
||||
#### 4. Track Removed Files in Clean Mode (`[src/syncback/mod.rs](src/syncback/mod.rs)`)
|
||||
#### 6. Remove Orphaned Files After Syncback (`[src/syncback/mod.rs](src/syncback/mod.rs)`)
|
||||
|
||||
In clean mode, we need to remove all existing files in the target paths. Add logic to collect existing paths for removal:
|
||||
After the main loop, remove any existing paths that weren't written to:
|
||||
|
||||
```rust
|
||||
if clean_mode {
|
||||
// Collect all existing paths under the project tree for removal
|
||||
for ref_id in descendants(old_tree.inner(), old_tree.get_root_id()) {
|
||||
if let Some(inst) = old_tree.get_instance(ref_id) {
|
||||
for path in inst.metadata().relevant_paths.iter() {
|
||||
if path.is_dir() {
|
||||
fs_snapshot.remove_dir(path);
|
||||
// In clean mode, remove any existing paths that weren't overwritten
|
||||
if !incremental {
|
||||
let added_paths: HashSet<&Path> = fs_snapshot.added_paths().iter().map(|p| p.as_path()).collect();
|
||||
|
||||
for old_path in &existing_paths {
|
||||
// Skip if this path (or a parent) is being written to
|
||||
if added_paths.contains(old_path.as_path()) {
|
||||
continue;
|
||||
}
|
||||
// Skip if a parent directory is being added (the new structure will replace it)
|
||||
if added_paths.iter().any(|p| old_path.starts_with(p)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if old_path.is_dir() {
|
||||
fs_snapshot.remove_dir(old_path);
|
||||
} else {
|
||||
fs_snapshot.remove_file(path);
|
||||
}
|
||||
}
|
||||
fs_snapshot.remove_file(old_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 5. Update Child Snapshot Creation (`[src/snapshot_middleware/dir.rs](src/snapshot_middleware/dir.rs)`)
|
||||
#### 7. Skip Hash Comparison in Clean Mode (`[src/syncback/mod.rs](src/syncback/mod.rs)`)
|
||||
|
||||
The `SyncbackSnapshot::with_joined_path` method already handles `old = None` correctly - it will create a fresh child snapshot without old references.
|
||||
The hash-based skipping should be disabled in clean mode since we want to rewrite everything:
|
||||
|
||||
```rust
|
||||
// Skip hash comparison in clean mode - we want to rewrite everything
|
||||
if incremental {
|
||||
if let Some(old_ref) = snapshot.old {
|
||||
match (old_hashes.get(&old_ref), new_hashes.get(&snapshot.new)) {
|
||||
(Some(old), Some(new)) => {
|
||||
if old == new {
|
||||
log::trace!(
|
||||
"Skipping {inst_path} due to it being identically hashed as {old:?}"
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
_ => unreachable!("All Instances in both DOMs should have hashes"),
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Data Flow Diagram
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
subgraph currentBehavior [Current Behavior]
|
||||
A1[Syncback on Existing Files] --> B1{Old Instance Exists?}
|
||||
B1 -->|Yes| C1[Preserve Filename]
|
||||
B1 -->|Yes| D1[Preserve Middleware]
|
||||
B1 -->|Yes| E1[Match Children by Name]
|
||||
C1 --> F1[Inconsistent Structure]
|
||||
D1 --> F1
|
||||
E1 --> F1
|
||||
subgraph cleanMode [Default: Clean Mode]
|
||||
A1[rojo syncback -i game.rbxl] --> B1[Collect existing paths]
|
||||
B1 --> C1[Set old = None for all snapshots]
|
||||
C1 --> D1[Generate fresh filenames]
|
||||
C1 --> E1[Choose best middleware]
|
||||
C1 --> F1[All children treated as new]
|
||||
D1 --> G1[Compute new paths]
|
||||
E1 --> G1
|
||||
F1 --> G1
|
||||
G1 --> H1[Remove orphaned files]
|
||||
H1 --> I1[Consistent 1:1 Structure]
|
||||
end
|
||||
|
||||
subgraph cleanMode [Clean Mode]
|
||||
A2[Syncback with --clean] --> B2[Set old = None]
|
||||
B2 --> C2[Generate Fresh Filename]
|
||||
B2 --> D2[Choose Best Middleware]
|
||||
B2 --> E2[All Children Are New]
|
||||
C2 --> F2[Consistent 1:1 Structure]
|
||||
subgraph incrementalMode [With --incremental Flag]
|
||||
A2[rojo syncback -i game.rbxl --incremental] --> B2{Old Instance Exists?}
|
||||
B2 -->|Yes| C2[Preserve Filename]
|
||||
B2 -->|Yes| D2[Preserve Middleware]
|
||||
B2 -->|Yes| E2[Match Children by Name]
|
||||
C2 --> F2[Legacy Behavior]
|
||||
D2 --> F2
|
||||
E2 --> F2
|
||||
end
|
||||
|
|
@ -163,16 +221,30 @@ flowchart TD
|
|||
### Usage
|
||||
|
||||
```bash
|
||||
# Current behavior (preserves existing structure)
|
||||
# Default: Clean mode (creates fresh, consistent layout)
|
||||
rojo syncback -i game.rbxl
|
||||
|
||||
# Destructive mode (ignores existing structure, creates fresh layout)
|
||||
rojo syncback -i game.rbxl --clean
|
||||
# Preview what clean mode would do
|
||||
rojo syncback -i game.rbxl --list --dry-run
|
||||
|
||||
# Combine with other flags
|
||||
rojo syncback -i game.rbxl --clean --list --dry-run
|
||||
# Legacy behavior (preserves existing structure)
|
||||
rojo syncback -i game.rbxl --incremental
|
||||
rojo syncback -i game.rbxl -n
|
||||
|
||||
# Combine flags
|
||||
rojo syncback -i game.rbxl --incremental --list
|
||||
```
|
||||
|
||||
### Alternative Consideration
|
||||
### Project-Level Configuration (Optional Enhancement)
|
||||
|
||||
If you also want to support project-level configuration (so you don't need to pass `--clean` every time), we could add a `syncbackRules.cleanMode: true` option in the project file. Let me know if you'd prefer that approach.
|
||||
If you want to make incremental mode the default for a specific project without passing the flag, we could also add:
|
||||
|
||||
```json5
|
||||
{
|
||||
"syncbackRules": {
|
||||
"incremental": true // Opt into legacy behavior per-project
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This would be read in `syncback_loop` and combined with the CLI flag (CLI takes precedence).
|
||||
276
.cursor/plans/syncback_auto-downloader_0508b4bb.plan.md
Normal file
276
.cursor/plans/syncback_auto-downloader_0508b4bb.plan.md
Normal file
|
|
@ -0,0 +1,276 @@
|
|||
---
|
||||
name: Syncback Auto-Downloader
|
||||
overview: Add an auto-download feature to the syncback command that fetches the .rbxl file from Roblox's asset delivery API, with sensible defaults to make `rojo syncback` work with zero arguments.
|
||||
todos:
|
||||
- id: update-cargo
|
||||
content: Add gzip/brotli/deflate features to reqwest, move tempfile to dependencies
|
||||
status: completed
|
||||
- id: download-function
|
||||
content: Implement download_place() function with no-cache headers and cookie auth
|
||||
status: completed
|
||||
- id: update-args
|
||||
content: "Update SyncbackCommand args: --download, new defaults, --interactive flip"
|
||||
status: completed
|
||||
- id: input-resolution
|
||||
content: Implement input file resolution logic (download vs existing file)
|
||||
status: completed
|
||||
- id: sourcemap-gen
|
||||
content: Add automatic sourcemap.json generation after syncback
|
||||
status: completed
|
||||
- id: git-refresh
|
||||
content: Add git update-index --refresh for git repos
|
||||
status: completed
|
||||
- id: testing
|
||||
content: Test the complete flow with various argument combinations
|
||||
status: completed
|
||||
isProject: false
|
||||
---
|
||||
|
||||
# Syncback Auto-Downloader Feature
|
||||
|
||||
## Overview
|
||||
|
||||
Enhance the `rojo syncback` command to automatically download place files from Roblox's asset delivery API, generate sourcemaps after completion, and refresh the git index. The goal is to make `rojo syncback` work with zero arguments.
|
||||
|
||||
## Key Files to Modify
|
||||
|
||||
- `[src/cli/syncback.rs](src/cli/syncback.rs)` - Main syncback command implementation
|
||||
- `[Cargo.toml](Cargo.toml)` - Add compression features to reqwest, move tempfile to dependencies
|
||||
|
||||
## Implementation Details
|
||||
|
||||
### 1. Update Dependencies in `Cargo.toml`
|
||||
|
||||
```toml
|
||||
# Add compression features to reqwest
|
||||
reqwest = { version = "0.11.27", default-features = false, features = [
|
||||
"blocking",
|
||||
"json",
|
||||
"rustls-tls",
|
||||
"gzip",
|
||||
"brotli",
|
||||
"deflate",
|
||||
] }
|
||||
|
||||
# Move tempfile from dev-dependencies to dependencies
|
||||
tempfile = "3.24.0"
|
||||
```
|
||||
|
||||
### 2. Add Download Arguments to `SyncbackCommand`
|
||||
|
||||
In `src/cli/syncback.rs`, modify the struct:
|
||||
|
||||
```rust
|
||||
pub struct SyncbackCommand {
|
||||
/// Path to the project to sync back to.
|
||||
#[clap(default_value = "default.project.json5")]
|
||||
pub project: PathBuf,
|
||||
|
||||
/// Path to the Roblox file to pull Instances from.
|
||||
#[clap(long, short, default_value = "Project.rbxl")]
|
||||
pub input: PathBuf,
|
||||
|
||||
/// Download the place file from Roblox. If no place ID is provided,
|
||||
/// uses the first ID from servePlaceIds in the project file.
|
||||
#[clap(long, short = 'd')]
|
||||
pub download: Option<Option<u64>>,
|
||||
|
||||
/// Interactive mode - prompts before writing. Disabled by default.
|
||||
#[clap(long, short = 'i')]
|
||||
pub interactive: bool,
|
||||
|
||||
// ... rest of existing fields
|
||||
}
|
||||
```
|
||||
|
||||
Note: Flip `--non-interactive` to `--interactive` (new default is non-interactive).
|
||||
|
||||
### 3. Download Function Implementation
|
||||
|
||||
Create the download logic with these characteristics:
|
||||
|
||||
- **URL**: `https://assetdelivery.roblox.com/v1/asset/?id={PLACEID}`
|
||||
- **Auth**: `ROBLOSECURITY` cookie from environment variable
|
||||
- **No-cache headers**:
|
||||
- `Cache-Control: no-cache, no-store, must-revalidate`
|
||||
- `Pragma: no-cache`
|
||||
- `Expires: 0`
|
||||
- **Compression**: Request `Accept-Encoding: gzip, deflate, br` (reqwest handles decompression)
|
||||
- **Temp file**: Use `tempfile::NamedTempFile` with `.rbxl` extension, keep it alive during processing
|
||||
|
||||
```rust
|
||||
fn download_place(place_id: u64) -> anyhow::Result<tempfile::NamedTempFile> {
|
||||
let cookie = std::env::var("ROBLOSECURITY")
|
||||
.context("ROBLOSECURITY environment variable not set")?;
|
||||
|
||||
let url = format!("https://assetdelivery.roblox.com/v1/asset/?id={}", place_id);
|
||||
|
||||
let client = reqwest::blocking::Client::builder()
|
||||
.gzip(true)
|
||||
.brotli(true)
|
||||
.deflate(true)
|
||||
.no_proxy() // Avoid proxy caching
|
||||
.build()?;
|
||||
|
||||
let response = client
|
||||
.get(&url)
|
||||
.header(COOKIE, format!(".ROBLOSECURITY={}", cookie))
|
||||
.header(CACHE_CONTROL, "no-cache, no-store, must-revalidate")
|
||||
.header(PRAGMA, "no-cache")
|
||||
.header("Expires", "0")
|
||||
.header(USER_AGENT, "Rojo")
|
||||
.send()?;
|
||||
|
||||
// Create temp file with .rbxl extension
|
||||
let mut temp_file = tempfile::Builder::new()
|
||||
.suffix(".rbxl")
|
||||
.tempfile()?;
|
||||
|
||||
// Stream response to file
|
||||
let bytes = response.bytes()?;
|
||||
std::io::copy(&mut bytes.as_ref(), &mut temp_file)?;
|
||||
|
||||
Ok(temp_file)
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Resolve Place ID Logic
|
||||
|
||||
When `--download` is provided without a value:
|
||||
|
||||
1. Load the project file first
|
||||
2. Extract `serve_place_ids` from the project
|
||||
3. Take the first place ID from the set (convert HashSet to Vec, sort for determinism, take first)
|
||||
4. Error if `servePlaceIds` is empty or not set
|
||||
|
||||
### 5. Input File Resolution Logic
|
||||
|
||||
In the `run()` method:
|
||||
|
||||
```rust
|
||||
// Determine the actual input path
|
||||
let input_path = if let Some(download_opt) = &self.download {
|
||||
// --download was specified
|
||||
if !self.input_exists() || download_opt.is_some() {
|
||||
// Download needed: either file doesn't exist or explicit place ID
|
||||
let place_id = match download_opt {
|
||||
Some(id) => *id,
|
||||
None => {
|
||||
// Load project to get servePlaceIds
|
||||
let project = Project::load_fuzzy(&path_old)?;
|
||||
project.serve_place_ids
|
||||
.as_ref()
|
||||
.and_then(|ids| ids.iter().min().copied())
|
||||
.context("No servePlaceIds in project and no place ID provided")?
|
||||
}
|
||||
};
|
||||
|
||||
eprintln!("Downloading place {}...", place_id);
|
||||
let temp_file = download_place(place_id)?;
|
||||
// Keep temp_file alive during processing
|
||||
DownloadedInput::Temp(temp_file)
|
||||
} else {
|
||||
DownloadedInput::Existing(resolve_path(&self.input).into_owned())
|
||||
}
|
||||
} else if self.input.exists() {
|
||||
DownloadedInput::Existing(resolve_path(&self.input).into_owned())
|
||||
} else {
|
||||
anyhow::bail!("Input file {} not found. Use --download to fetch from Roblox.", self.input.display())
|
||||
};
|
||||
```
|
||||
|
||||
### 6. Sourcemap Generation After Syncback
|
||||
|
||||
After successful syncback, generate `sourcemap.json` in the project root:
|
||||
|
||||
```rust
|
||||
// After snapshot.write_to_vfs()
|
||||
let sourcemap_path = session_old.root_project().folder_location().join("sourcemap.json");
|
||||
write_sourcemap(&session_old, Some(&sourcemap_path), filter_nothing, false)?;
|
||||
eprintln!("Generated sourcemap at {}", sourcemap_path.display());
|
||||
```
|
||||
|
||||
This requires extracting or sharing the `write_sourcemap` function from `sourcemap.rs` (likely needs to be made `pub(crate)`).
|
||||
|
||||
### 7. Git Index Refresh
|
||||
|
||||
After syncback completes, check if in a git repo and refresh the index:
|
||||
|
||||
```rust
|
||||
fn refresh_git_index(project_dir: &Path) {
|
||||
// Check if .git exists in project dir or any parent
|
||||
let mut check_dir = Some(project_dir);
|
||||
let mut is_git_repo = false;
|
||||
while let Some(dir) = check_dir {
|
||||
if dir.join(".git").exists() {
|
||||
is_git_repo = true;
|
||||
break;
|
||||
}
|
||||
check_dir = dir.parent();
|
||||
}
|
||||
|
||||
if is_git_repo {
|
||||
let result = std::process::Command::new("git")
|
||||
.arg("update-index")
|
||||
.arg("--refresh")
|
||||
.current_dir(project_dir)
|
||||
.stdout(std::process::Stdio::null())
|
||||
.stderr(std::process::Stdio::null())
|
||||
.status();
|
||||
|
||||
if let Err(e) = result {
|
||||
log::warn!("Failed to refresh git index: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 8. Summary of Default Changes
|
||||
|
||||
|
||||
| Argument | Old Default | New Default |
|
||||
| ------------------- | ------------------ | ----------------------------------------------------------------- |
|
||||
| `project` | `""` (current dir) | `default.project.json5` |
|
||||
| `--input` | Required | `Project.rbxl` |
|
||||
| `--non-interactive` | `false` | Removed, replaced with `--interactive` (default: non-interactive) |
|
||||
|
||||
|
||||
## Flow Diagram
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start[rojo syncback] --> CheckDownload{--download flag?}
|
||||
CheckDownload -->|No| CheckInput{Input file exists?}
|
||||
CheckDownload -->|Yes| CheckPlaceId{Place ID provided?}
|
||||
|
||||
CheckPlaceId -->|Yes| Download[Download from Roblox]
|
||||
CheckPlaceId -->|No| LoadProject[Load project.json5]
|
||||
LoadProject --> GetPlaceId[Get first servePlaceIds]
|
||||
GetPlaceId --> Download
|
||||
|
||||
Download --> TempFile[Save to temp file]
|
||||
TempFile --> ProcessDom[Process DOM]
|
||||
|
||||
CheckInput -->|Yes| UseExisting[Use existing file]
|
||||
CheckInput -->|No| Error[Error: file not found]
|
||||
|
||||
UseExisting --> ProcessDom
|
||||
ProcessDom --> Syncback[Run syncback]
|
||||
Syncback --> WriteFiles[Write to filesystem]
|
||||
WriteFiles --> GenSourcemap[Generate sourcemap.json]
|
||||
GenSourcemap --> GitRefresh[git update-index --refresh]
|
||||
GitRefresh --> Cleanup[Cleanup temp file]
|
||||
Cleanup --> End[Done]
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Edge Cases
|
||||
|
||||
- If `--input` file exists and `--download` not specified: use existing file (no download)
|
||||
- If `--input` file exists but `--download <placeid>` explicitly given: download anyway (override)
|
||||
- If `--download` with no arg and no `servePlaceIds` in project: error with helpful message
|
||||
- If `ROBLOSECURITY` not in environment: error with helpful message
|
||||
- If download fails: error with status code and helpful message
|
||||
- If not a git repo: silently skip git refresh
|
||||
|
||||
556
Cargo.lock
generated
556
Cargo.lock
generated
|
|
@ -39,12 +39,36 @@ dependencies = [
|
|||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "alloc-no-stdlib"
|
||||
version = "2.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3"
|
||||
|
||||
[[package]]
|
||||
name = "alloc-stdlib"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece"
|
||||
dependencies = [
|
||||
"alloc-no-stdlib",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anes"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
|
||||
dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.21"
|
||||
|
|
@ -113,12 +137,30 @@ version = "0.3.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb"
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
|
||||
|
||||
[[package]]
|
||||
name = "async-compression"
|
||||
version = "0.4.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d10e4f991a553474232bc0a31799f6d24b034a84c0971d80d2e2f78b2e576e40"
|
||||
dependencies = [
|
||||
"compression-codecs",
|
||||
"compression-core",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
|
|
@ -151,6 +193,18 @@ dependencies = [
|
|||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base-x"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.21.7"
|
||||
|
|
@ -184,6 +238,17 @@ version = "2.10.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
|
||||
|
||||
[[package]]
|
||||
name = "blake2b_simd"
|
||||
version = "0.5.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"arrayvec 0.5.2",
|
||||
"constant_time_eq 0.1.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "blake3"
|
||||
version = "1.8.3"
|
||||
|
|
@ -191,10 +256,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "2468ef7d57b3fb7e16b576e8377cdbde2320c60e1491e961d11da40fc4f02a2d"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"arrayvec",
|
||||
"arrayvec 0.7.6",
|
||||
"cc",
|
||||
"cfg-if 1.0.4",
|
||||
"constant_time_eq",
|
||||
"constant_time_eq 0.4.2",
|
||||
"cpufeatures",
|
||||
]
|
||||
|
||||
|
|
@ -207,6 +272,27 @@ dependencies = [
|
|||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "brotli"
|
||||
version = "8.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560"
|
||||
dependencies = [
|
||||
"alloc-no-stdlib",
|
||||
"alloc-stdlib",
|
||||
"brotli-decompressor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "brotli-decompressor"
|
||||
version = "5.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03"
|
||||
dependencies = [
|
||||
"alloc-no-stdlib",
|
||||
"alloc-stdlib",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "1.12.1"
|
||||
|
|
@ -224,6 +310,12 @@ version = "3.19.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
|
|
@ -299,9 +391,13 @@ version = "2.34.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"atty",
|
||||
"bitflags 1.3.2",
|
||||
"strsim 0.8.0",
|
||||
"textwrap",
|
||||
"unicode-width",
|
||||
"vec_map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -323,7 +419,7 @@ dependencies = [
|
|||
"anstream",
|
||||
"anstyle",
|
||||
"clap_lex",
|
||||
"strsim",
|
||||
"strsim 0.11.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -335,7 +431,7 @@ dependencies = [
|
|||
"heck",
|
||||
"proc-macro2 1.0.106",
|
||||
"quote 1.0.44",
|
||||
"syn",
|
||||
"syn 2.0.114",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -350,6 +446,24 @@ version = "1.0.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
|
||||
|
||||
[[package]]
|
||||
name = "compression-codecs"
|
||||
version = "0.4.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00828ba6fd27b45a448e57dbfe84f1029d4c9f26b368157e9a448a5f49a2ec2a"
|
||||
dependencies = [
|
||||
"brotli",
|
||||
"compression-core",
|
||||
"flate2",
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "compression-core"
|
||||
version = "0.4.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75984efb6ed102a0d42db99afb6c1948f0380d1d91808d5529916e6c08b49d8d"
|
||||
|
||||
[[package]]
|
||||
name = "console"
|
||||
version = "0.15.11"
|
||||
|
|
@ -362,12 +476,34 @@ dependencies = [
|
|||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const_fn"
|
||||
version = "0.4.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f8a2ca5ac02d09563609681103aada9e1777d54fc57a5acd7a41404f9c93b6e"
|
||||
|
||||
[[package]]
|
||||
name = "constant_time_eq"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
|
||||
|
||||
[[package]]
|
||||
name = "constant_time_eq"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b"
|
||||
|
||||
[[package]]
|
||||
name = "cookie"
|
||||
version = "0.15.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc6e25dfc584d06a3dbf775d207ff00d7de98d824c952dd2233dfbb261889a42"
|
||||
dependencies = [
|
||||
"time 0.2.27",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.4"
|
||||
|
|
@ -393,6 +529,15 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "criterion"
|
||||
version = "0.3.6"
|
||||
|
|
@ -542,6 +687,15 @@ version = "2.10.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea"
|
||||
|
||||
[[package]]
|
||||
name = "deranged"
|
||||
version = "0.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587"
|
||||
dependencies = [
|
||||
"powerfmt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diff"
|
||||
version = "0.1.13"
|
||||
|
|
@ -558,6 +712,17 @@ dependencies = [
|
|||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"redox_users 0.3.5",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "2.0.2"
|
||||
|
|
@ -584,7 +749,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"redox_users",
|
||||
"redox_users 0.4.6",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
|
|
@ -596,10 +761,16 @@ checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
|
|||
dependencies = [
|
||||
"libc",
|
||||
"option-ext",
|
||||
"redox_users",
|
||||
"redox_users 0.4.6",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "discard"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
|
||||
|
||||
[[package]]
|
||||
name = "displaydoc"
|
||||
version = "0.2.5"
|
||||
|
|
@ -608,7 +779,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
|
|||
dependencies = [
|
||||
"proc-macro2 1.0.106",
|
||||
"quote 1.0.44",
|
||||
"syn",
|
||||
"syn 2.0.114",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -624,7 +795,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "e62abb876c07e4754fae5c14cafa77937841f01740637e17d78dc04352f32a5e"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"rustc_version",
|
||||
"rustc_version 0.4.1",
|
||||
"toml 0.5.11",
|
||||
"vswhom",
|
||||
"winreg 0.10.1",
|
||||
|
|
@ -655,6 +826,19 @@ dependencies = [
|
|||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"humantime",
|
||||
"log",
|
||||
"regex",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.11.8"
|
||||
|
|
@ -707,6 +891,16 @@ version = "0.1.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b375d6465b98090a5f25b1c7703f3859783755aa9a80433b36e0379a3ec2f369"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "float-cmp"
|
||||
version = "0.9.0"
|
||||
|
|
@ -837,7 +1031,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
|
|||
dependencies = [
|
||||
"proc-macro2 1.0.106",
|
||||
"quote 1.0.44",
|
||||
"syn",
|
||||
"syn 2.0.114",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -895,6 +1089,17 @@ dependencies = [
|
|||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.4",
|
||||
"libc",
|
||||
"wasi 0.9.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.17"
|
||||
|
|
@ -903,7 +1108,7 @@ checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
|
|||
dependencies = [
|
||||
"cfg-if 1.0.4",
|
||||
"libc",
|
||||
"wasi",
|
||||
"wasi 0.11.1+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1348,7 +1553,7 @@ checksum = "e0c84ee7f197eca9a86c6fd6cb771e55eb991632f15f2bc3ca6ec838929e6e78"
|
|||
dependencies = [
|
||||
"proc-macro2 1.0.106",
|
||||
"quote 1.0.44",
|
||||
"syn",
|
||||
"syn 2.0.114",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1527,6 +1732,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
|
||||
dependencies = [
|
||||
"adler2",
|
||||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1555,7 +1761,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasi",
|
||||
"wasi 0.11.1+wasi-snapshot-preview1",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
|
|
@ -1621,6 +1827,12 @@ dependencies = [
|
|||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-conv"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
|
|
@ -1748,7 +1960,7 @@ dependencies = [
|
|||
"pest_meta",
|
||||
"proc-macro2 1.0.106",
|
||||
"quote 1.0.44",
|
||||
"syn",
|
||||
"syn 2.0.114",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1779,6 +1991,19 @@ version = "0.3.32"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
||||
|
||||
[[package]]
|
||||
name = "plist"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "740ebea15c5d1428f910cd1a5f52cebf8d25006245ed8ade92702f4943d91e07"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"indexmap 2.13.0",
|
||||
"quick-xml",
|
||||
"serde",
|
||||
"time 0.3.46",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "plotters"
|
||||
version = "0.3.7"
|
||||
|
|
@ -1831,6 +2056,12 @@ dependencies = [
|
|||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "powerfmt"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.21"
|
||||
|
|
@ -1897,7 +2128,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "52717f9a02b6965224f95ca2a81e2e0c5c43baacd28ca057577988930b6c3d5b"
|
||||
dependencies = [
|
||||
"quote 1.0.44",
|
||||
"syn",
|
||||
"syn 2.0.114",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-xml"
|
||||
version = "0.38.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b66c2058c55a409d601666cffe35f04333cf1013010882cec174a7467cd4e21c"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1980,7 +2220,7 @@ version = "2.0.1"
|
|||
dependencies = [
|
||||
"ahash",
|
||||
"criterion 0.5.1",
|
||||
"env_logger",
|
||||
"env_logger 0.11.8",
|
||||
"heck",
|
||||
"insta",
|
||||
"log",
|
||||
|
|
@ -1994,6 +2234,23 @@ dependencies = [
|
|||
"zstd",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rbx_cookie"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62d81c3d7cd53ac75f48a7b526e145d0b72c19d695364edb343e9248192d3f17"
|
||||
dependencies = [
|
||||
"byteorder 0.5.3",
|
||||
"clap 2.34.0",
|
||||
"cookie",
|
||||
"dirs 1.0.5",
|
||||
"env_logger 0.9.3",
|
||||
"log",
|
||||
"plist",
|
||||
"winapi 0.3.9",
|
||||
"winreg 0.10.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rbx_dom_weak"
|
||||
version = "4.1.0"
|
||||
|
|
@ -2047,7 +2304,7 @@ version = "2.0.1"
|
|||
dependencies = [
|
||||
"ahash",
|
||||
"base64 0.22.1",
|
||||
"env_logger",
|
||||
"env_logger 0.11.8",
|
||||
"heck",
|
||||
"insta",
|
||||
"log",
|
||||
|
|
@ -2057,6 +2314,12 @@ dependencies = [
|
|||
"xml-rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.18"
|
||||
|
|
@ -2075,6 +2338,17 @@ dependencies = [
|
|||
"bitflags 2.10.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
|
||||
dependencies = [
|
||||
"getrandom 0.1.16",
|
||||
"redox_syscall 0.1.57",
|
||||
"rust-argon2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.4.6"
|
||||
|
|
@ -2121,6 +2395,7 @@ version = "0.11.27"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62"
|
||||
dependencies = [
|
||||
"async-compression",
|
||||
"base64 0.21.7",
|
||||
"bytes",
|
||||
"encoding_rs",
|
||||
|
|
@ -2147,6 +2422,7 @@ dependencies = [
|
|||
"system-configuration",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
"tokio-util",
|
||||
"tower-service",
|
||||
"url",
|
||||
"wasm-bindgen",
|
||||
|
|
@ -2238,7 +2514,7 @@ dependencies = [
|
|||
"csv",
|
||||
"data-encoding",
|
||||
"embed-resource",
|
||||
"env_logger",
|
||||
"env_logger 0.11.8",
|
||||
"float-cmp",
|
||||
"fs-err",
|
||||
"futures",
|
||||
|
|
@ -2260,6 +2536,7 @@ dependencies = [
|
|||
"profiling",
|
||||
"rayon",
|
||||
"rbx_binary",
|
||||
"rbx_cookie",
|
||||
"rbx_dom_weak",
|
||||
"rbx_reflection",
|
||||
"rbx_reflection_database",
|
||||
|
|
@ -2270,7 +2547,7 @@ dependencies = [
|
|||
"rmp-serde",
|
||||
"roblox_install",
|
||||
"rojo-insta-ext",
|
||||
"semver",
|
||||
"semver 1.0.27",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
"serde_json",
|
||||
|
|
@ -2295,19 +2572,40 @@ dependencies = [
|
|||
"serde_yaml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-argon2"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb"
|
||||
dependencies = [
|
||||
"base64 0.13.1",
|
||||
"blake2b_simd",
|
||||
"constant_time_eq 0.1.5",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||
dependencies = [
|
||||
"semver 0.9.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
|
||||
dependencies = [
|
||||
"semver",
|
||||
"semver 1.0.27",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2397,12 +2695,27 @@ dependencies = [
|
|||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||
dependencies = [
|
||||
"semver-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.228"
|
||||
|
|
@ -2450,7 +2763,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
|||
dependencies = [
|
||||
"proc-macro2 1.0.106",
|
||||
"quote 1.0.44",
|
||||
"syn",
|
||||
"syn 2.0.114",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2499,6 +2812,15 @@ dependencies = [
|
|||
"yaml-rust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770"
|
||||
dependencies = [
|
||||
"sha1_smol",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1"
|
||||
version = "0.10.6"
|
||||
|
|
@ -2510,6 +2832,12 @@ dependencies = [
|
|||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1_smol"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d"
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.9"
|
||||
|
|
@ -2536,6 +2864,12 @@ version = "1.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "simd-adler32"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2"
|
||||
|
||||
[[package]]
|
||||
name = "similar"
|
||||
version = "2.7.0"
|
||||
|
|
@ -2589,6 +2923,70 @@ version = "1.2.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
|
||||
|
||||
[[package]]
|
||||
name = "standback"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff"
|
||||
dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stdweb"
|
||||
version = "0.4.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5"
|
||||
dependencies = [
|
||||
"discard",
|
||||
"rustc_version 0.2.3",
|
||||
"stdweb-derive",
|
||||
"stdweb-internal-macros",
|
||||
"stdweb-internal-runtime",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stdweb-derive"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.106",
|
||||
"quote 1.0.44",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stdweb-internal-macros"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11"
|
||||
dependencies = [
|
||||
"base-x",
|
||||
"proc-macro2 1.0.106",
|
||||
"quote 1.0.44",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"sha1 0.6.1",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stdweb-internal-runtime"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
|
|
@ -2613,7 +3011,18 @@ dependencies = [
|
|||
"heck",
|
||||
"proc-macro2 1.0.106",
|
||||
"quote 1.0.44",
|
||||
"syn",
|
||||
"syn 2.0.114",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.106",
|
||||
"quote 1.0.44",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2641,7 +3050,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
|
|||
dependencies = [
|
||||
"proc-macro2 1.0.106",
|
||||
"quote 1.0.44",
|
||||
"syn",
|
||||
"syn 2.0.114",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2722,7 +3131,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
|||
dependencies = [
|
||||
"proc-macro2 1.0.106",
|
||||
"quote 1.0.44",
|
||||
"syn",
|
||||
"syn 2.0.114",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2733,7 +3142,7 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
|
|||
dependencies = [
|
||||
"proc-macro2 1.0.106",
|
||||
"quote 1.0.44",
|
||||
"syn",
|
||||
"syn 2.0.114",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2745,6 +3154,75 @@ dependencies = [
|
|||
"cfg-if 1.0.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.2.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4752a97f8eebd6854ff91f1c1824cd6160626ac4bd44287f7f4ea2035a02a242"
|
||||
dependencies = [
|
||||
"const_fn",
|
||||
"libc",
|
||||
"standback",
|
||||
"stdweb",
|
||||
"time-macros 0.1.1",
|
||||
"version_check",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.46"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9da98b7d9b7dad93488a84b8248efc35352b0b2657397d4167e7ad67e5d535e5"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"itoa",
|
||||
"num-conv",
|
||||
"powerfmt",
|
||||
"serde_core",
|
||||
"time-core",
|
||||
"time-macros 0.2.26",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time-core"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"
|
||||
|
||||
[[package]]
|
||||
name = "time-macros"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1"
|
||||
dependencies = [
|
||||
"proc-macro-hack",
|
||||
"time-macros-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time-macros"
|
||||
version = "0.2.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78cc610bac2dcee56805c99642447d4c5dbde4d01f752ffea0199aee1f601dc4"
|
||||
dependencies = [
|
||||
"num-conv",
|
||||
"time-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time-macros-impl"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f"
|
||||
dependencies = [
|
||||
"proc-macro-hack",
|
||||
"proc-macro2 1.0.106",
|
||||
"quote 1.0.44",
|
||||
"standback",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinystr"
|
||||
version = "0.8.2"
|
||||
|
|
@ -2788,7 +3266,7 @@ checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5"
|
|||
dependencies = [
|
||||
"proc-macro2 1.0.106",
|
||||
"quote 1.0.44",
|
||||
"syn",
|
||||
"syn 2.0.114",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2964,14 +3442,14 @@ version = "0.20.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"byteorder 1.5.0",
|
||||
"bytes",
|
||||
"data-encoding",
|
||||
"http",
|
||||
"httparse",
|
||||
"log",
|
||||
"rand",
|
||||
"sha1",
|
||||
"sha1 0.10.6",
|
||||
"thiserror 1.0.69",
|
||||
"url",
|
||||
"utf-8",
|
||||
|
|
@ -3038,7 +3516,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "18b19e258aa08450f93369cf56dd78063586adf19e92a75b338a800f799a0208"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"byteorder",
|
||||
"byteorder 1.5.0",
|
||||
"lazy_static",
|
||||
"parking_lot",
|
||||
"serde",
|
||||
|
|
@ -3080,6 +3558,12 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
|
|
@ -3125,6 +3609,12 @@ dependencies = [
|
|||
"try-lock",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.9.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.1+wasi-snapshot-preview1"
|
||||
|
|
@ -3186,7 +3676,7 @@ dependencies = [
|
|||
"bumpalo",
|
||||
"proc-macro2 1.0.106",
|
||||
"quote 1.0.44",
|
||||
"syn",
|
||||
"syn 2.0.114",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
|
|
@ -3614,7 +4104,7 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d"
|
|||
dependencies = [
|
||||
"proc-macro2 1.0.106",
|
||||
"quote 1.0.44",
|
||||
"syn",
|
||||
"syn 2.0.114",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
|
|
@ -3635,7 +4125,7 @@ checksum = "1328722bbf2115db7e19d69ebcc15e795719e2d66b60827c6a69a117365e37a0"
|
|||
dependencies = [
|
||||
"proc-macro2 1.0.106",
|
||||
"quote 1.0.44",
|
||||
"syn",
|
||||
"syn 2.0.114",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3655,7 +4145,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
|
|||
dependencies = [
|
||||
"proc-macro2 1.0.106",
|
||||
"quote 1.0.44",
|
||||
"syn",
|
||||
"syn 2.0.114",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
|
|
@ -3689,7 +4179,7 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3"
|
|||
dependencies = [
|
||||
"proc-macro2 1.0.106",
|
||||
"quote 1.0.44",
|
||||
"syn",
|
||||
"syn 2.0.114",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
|||
|
|
@ -72,11 +72,16 @@ log = "0.4.29"
|
|||
num_cpus = "1.17.0"
|
||||
opener = "0.5.2"
|
||||
rayon = "1.11.0"
|
||||
rbx_cookie = "0.1.5"
|
||||
reqwest = { version = "0.11.27", default-features = false, features = [
|
||||
"blocking",
|
||||
"json",
|
||||
"rustls-tls",
|
||||
"gzip",
|
||||
"brotli",
|
||||
"deflate",
|
||||
] }
|
||||
tempfile = "3.24.0"
|
||||
ritz = "0.1.0"
|
||||
roblox_install = "1.0.0"
|
||||
serde = { version = "1.0.228", features = ["derive", "rc"] }
|
||||
|
|
@ -121,5 +126,4 @@ paste = "1.0.15"
|
|||
pretty_assertions = "1.4.1"
|
||||
regex = "1"
|
||||
serde_yaml = "0.8.26"
|
||||
tempfile = "3.24.0"
|
||||
walkdir = "2.5.0"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
source: tests/rojo_test/syncback_util.rs
|
||||
expression: "String::from_utf8_lossy(&output.stdout)"
|
||||
expression: normalized_stdout
|
||||
---
|
||||
Writing OnlyOneCopy/child_of_one.luau
|
||||
Writing ReplicatedStorage/child_replicated_storage.luau
|
||||
Created sourcemap at <TEMP>/child_but_not\sourcemap.json
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
---
|
||||
source: tests/rojo_test/syncback_util.rs
|
||||
expression: "String::from_utf8_lossy(&output.stdout)"
|
||||
expression: normalized_stdout
|
||||
---
|
||||
Writing src/csv.csv
|
||||
Writing src/csv_init/init.csv
|
||||
Writing src/csv_init
|
||||
Created sourcemap at <TEMP>/csv\sourcemap.json
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
source: tests/rojo_test/syncback_util.rs
|
||||
expression: "String::from_utf8_lossy(&output.stdout)"
|
||||
expression: normalized_stdout
|
||||
---
|
||||
Writing container.model.json5
|
||||
Created sourcemap at <TEMP>/duplicate_rojo_id\sourcemap.json
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
---
|
||||
source: tests/rojo_test/syncback_util.rs
|
||||
expression: "String::from_utf8_lossy(&output.stdout)"
|
||||
expression: normalized_stdout
|
||||
---
|
||||
Writing src/ignored_part.model.json5
|
||||
Writing src/int_value.model.json5
|
||||
Writing src/subfolder/string_value.txt
|
||||
Writing src/subfolder
|
||||
Created sourcemap at <TEMP>/ignore_paths_adding\sourcemap.json
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
source: tests/rojo_test/syncback_util.rs
|
||||
expression: "String::from_utf8_lossy(&output.stdout)"
|
||||
expression: normalized_stdout
|
||||
---
|
||||
Writing src/non-init.luau
|
||||
Writing src/init-file
|
||||
Created sourcemap at <TEMP>/ignore_paths_init\sourcemap.json
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
source: tests/rojo_test/syncback_util.rs
|
||||
expression: "String::from_utf8_lossy(&output.stdout)"
|
||||
expression: normalized_stdout
|
||||
---
|
||||
Writing src/Message.model.json5
|
||||
Created sourcemap at <TEMP>/ignore_paths_removing\sourcemap.json
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
source: tests/rojo_test/syncback_util.rs
|
||||
expression: "String::from_utf8_lossy(&output.stdout)"
|
||||
expression: normalized_stdout
|
||||
---
|
||||
Writing src/IncludeMe/.gitkeep
|
||||
Writing src/IncludeMe
|
||||
Created sourcemap at <TEMP>/ignore_trees_adding\sourcemap.json
|
||||
|
|
|
|||
|
|
@ -3,3 +3,4 @@ source: tests/rojo_test/syncback_util.rs
|
|||
expression: normalized_stdout
|
||||
---
|
||||
Removing src
|
||||
Created sourcemap at <TEMP>/ignore_trees_removing\sourcemap.json
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
---
|
||||
source: tests/rojo_test/syncback_util.rs
|
||||
expression: "String::from_utf8_lossy(&output.stdout)"
|
||||
expression: normalized_stdout
|
||||
---
|
||||
Writing src/dir_with_meta/init.meta.json5
|
||||
Writing src/model_json.model.json5
|
||||
Writing src/project_json.project.json5
|
||||
Writing src/dir_with_meta
|
||||
Created sourcemap at <TEMP>/json_middlewares\sourcemap.json
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
source: tests/rojo_test/syncback_util.rs
|
||||
expression: "String::from_utf8_lossy(&output.stdout)"
|
||||
expression: normalized_stdout
|
||||
---
|
||||
Writing nested.project.json5
|
||||
Writing string_value.txt
|
||||
Created sourcemap at <TEMP>/nested_projects\sourcemap.json
|
||||
|
|
|
|||
|
|
@ -6,3 +6,4 @@ Writing src/modules/ClientModule.luau
|
|||
Writing src/modules/ServerModule.luau
|
||||
Removing client-only.project.json5
|
||||
Removing server-only.project.json5
|
||||
Created sourcemap at <TEMP>/nested_projects_weird\sourcemap.json
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
source: tests/rojo_test/syncback_util.rs
|
||||
expression: "String::from_utf8_lossy(&output.stdout)"
|
||||
expression: normalized_stdout
|
||||
---
|
||||
Writing src/init.luau
|
||||
Writing src
|
||||
Created sourcemap at <TEMP>/project_init\sourcemap.json
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
source: tests/rojo_test/syncback_util.rs
|
||||
expression: "String::from_utf8_lossy(&output.stdout)"
|
||||
expression: normalized_stdout
|
||||
---
|
||||
Writing attribute_mismatch.luau
|
||||
Writing property_mismatch.project.json5
|
||||
Created sourcemap at <TEMP>/project_reserialize\sourcemap.json
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
---
|
||||
source: tests/rojo_test/syncback_util.rs
|
||||
expression: "String::from_utf8_lossy(&output.stdout)"
|
||||
expression: normalized_stdout
|
||||
---
|
||||
Writing src/ChildWithoutDuplicates/Child/.gitkeep
|
||||
Writing src/ChildWithDuplicates
|
||||
Writing src/ChildWithoutDuplicates
|
||||
Writing src/ChildWithoutDuplicates/Child
|
||||
Created sourcemap at <TEMP>/rbxm_fallback\sourcemap.json
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
source: tests/rojo_test/syncback_util.rs
|
||||
expression: "String::from_utf8_lossy(&output.stdout)"
|
||||
expression: normalized_stdout
|
||||
---
|
||||
Writing src/pointer.model.json5
|
||||
Writing src/target.model.json5
|
||||
Created sourcemap at <TEMP>/ref_properties\sourcemap.json
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
source: tests/rojo_test/syncback_util.rs
|
||||
expression: "String::from_utf8_lossy(&output.stdout)"
|
||||
expression: normalized_stdout
|
||||
---
|
||||
Writing src/pointer.model.json5
|
||||
Writing src/target.txt
|
||||
Created sourcemap at <TEMP>/ref_properties_blank\sourcemap.json
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
---
|
||||
source: tests/rojo_test/syncback_util.rs
|
||||
expression: "String::from_utf8_lossy(&output.stdout)"
|
||||
expression: normalized_stdout
|
||||
---
|
||||
Writing src/Pointer_1.model.json5
|
||||
Writing src/Pointer_2.model.json5
|
||||
Writing src/Target_1.model.json5
|
||||
Writing src/Target_2.model.json5
|
||||
Created sourcemap at <TEMP>/ref_properties_conflict\sourcemap.json
|
||||
|
|
|
|||
|
|
@ -7,3 +7,4 @@ Writing src/Pointer_2.model.json5
|
|||
Writing src/Target/init.meta.json5
|
||||
Writing src/Target
|
||||
Removing src/Target.model.json5
|
||||
Created sourcemap at <TEMP>/ref_properties_duplicate\sourcemap.json
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
---
|
||||
source: tests/rojo_test/syncback_util.rs
|
||||
expression: "String::from_utf8_lossy(&output.stdout)"
|
||||
expression: normalized_stdout
|
||||
---
|
||||
Writing src/Pointer1.model.json5
|
||||
Writing src/Pointer2.model.json5
|
||||
Writing src/Pointer3.model.json5
|
||||
Created sourcemap at <TEMP>/ref_properties_pruned\sourcemap.json
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
---
|
||||
source: tests/rojo_test/syncback_util.rs
|
||||
expression: "String::from_utf8_lossy(&output.stdout)"
|
||||
expression: normalized_stdout
|
||||
---
|
||||
Writing default.project.json5
|
||||
Writing src/model_json.model.json5
|
||||
Writing src/rbxm.rbxm
|
||||
Writing src/rbxmx.rbxmx
|
||||
Created sourcemap at <TEMP>/respect_old_middleware\sourcemap.json
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
source: tests/rojo_test/syncback_util.rs
|
||||
expression: "String::from_utf8_lossy(&output.stdout)"
|
||||
expression: normalized_stdout
|
||||
---
|
||||
Writing default.project.json5
|
||||
Writing src/adjacent.luau
|
||||
|
|
@ -8,3 +8,4 @@ Writing src/adjacent.meta.json5
|
|||
Writing src/init/init.meta.json5
|
||||
Writing src/model.model.json5
|
||||
Writing src/init
|
||||
Created sourcemap at <TEMP>/schema_roundtrip\sourcemap.json
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
source: tests/rojo_test/syncback_util.rs
|
||||
expression: "String::from_utf8_lossy(&output.stdout)"
|
||||
expression: normalized_stdout
|
||||
---
|
||||
Writing default.project.json5
|
||||
Writing string_value.txt
|
||||
Created sourcemap at <TEMP>/string_value_project\sourcemap.json
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
source: tests/rojo_test/syncback_util.rs
|
||||
expression: "String::from_utf8_lossy(&output.stdout)"
|
||||
expression: normalized_stdout
|
||||
---
|
||||
Writing src/module.modulescript
|
||||
Writing src/text.text
|
||||
Created sourcemap at <TEMP>/sync_rules\sourcemap.json
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
source: tests/rojo_test/syncback_util.rs
|
||||
expression: "String::from_utf8_lossy(&output.stdout)"
|
||||
expression: normalized_stdout
|
||||
---
|
||||
Writing default.project.json5
|
||||
Created sourcemap at <TEMP>/unscriptable_properties\sourcemap.json
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ impl SourcemapCommand {
|
|||
}
|
||||
}
|
||||
|
||||
fn filter_nothing(_instance: &InstanceWithMeta) -> bool {
|
||||
pub(crate) fn filter_nothing(_instance: &InstanceWithMeta) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
|
|
@ -229,7 +229,7 @@ fn recurse_create_node<'a>(
|
|||
})
|
||||
}
|
||||
|
||||
fn write_sourcemap(
|
||||
pub(crate) fn write_sourcemap(
|
||||
session: &ServeSession,
|
||||
output: Option<&Path>,
|
||||
filter: fn(&InstanceWithMeta) -> bool,
|
||||
|
|
|
|||
|
|
@ -2,23 +2,31 @@ use std::{
|
|||
io::{self, BufReader, Write as _},
|
||||
mem::forget,
|
||||
path::{Path, PathBuf},
|
||||
process::{Command, Stdio},
|
||||
time::Instant,
|
||||
};
|
||||
|
||||
use anyhow::Context;
|
||||
use anyhow::{bail, Context};
|
||||
use clap::Parser;
|
||||
use fs_err::File;
|
||||
use memofs::Vfs;
|
||||
use rbx_dom_weak::{InstanceBuilder, WeakDom};
|
||||
use reqwest::header::{CACHE_CONTROL, COOKIE, PRAGMA, USER_AGENT};
|
||||
use tempfile::NamedTempFile;
|
||||
use termcolor::{BufferWriter, Color, ColorChoice, ColorSpec, WriteColor};
|
||||
|
||||
use crate::{
|
||||
path_serializer::display_absolute,
|
||||
project::Project,
|
||||
serve_session::ServeSession,
|
||||
syncback::{syncback_loop, FsSnapshot},
|
||||
};
|
||||
|
||||
use super::{resolve_path, GlobalOptions};
|
||||
use super::{
|
||||
resolve_path,
|
||||
sourcemap::{filter_nothing, write_sourcemap},
|
||||
GlobalOptions,
|
||||
};
|
||||
|
||||
const UNKNOWN_INPUT_KIND_ERR: &str = "Could not detect what kind of file was inputted. \
|
||||
Expected input file to end in .rbxl, .rbxlx, .rbxm, or .rbxmx.";
|
||||
|
|
@ -34,16 +42,21 @@ const UNKNOWN_INPUT_KIND_ERR: &str = "Could not detect what kind of file was inp
|
|||
#[derive(Debug, Parser)]
|
||||
pub struct SyncbackCommand {
|
||||
/// Path to the project to sync back to.
|
||||
#[clap(default_value = "")]
|
||||
#[clap(default_value = "default.project.json5")]
|
||||
pub project: PathBuf,
|
||||
|
||||
/// Path to the Roblox file to pull Instances from.
|
||||
#[clap(long, short)]
|
||||
#[clap(long, short = 'f', default_value = "Project.rbxl")]
|
||||
pub input: PathBuf,
|
||||
|
||||
/// Download the place file from Roblox with the specified place ID,
|
||||
/// ignoring any existing input file.
|
||||
#[clap(long, short = 'd')]
|
||||
pub download: Option<u64>,
|
||||
|
||||
/// If provided, a list all of the files and directories that will be
|
||||
/// added or removed is emitted into stdout.
|
||||
#[clap(long, short)]
|
||||
#[clap(long, short = 'l')]
|
||||
pub list: bool,
|
||||
|
||||
/// If provided, syncback will not actually write anything to the file
|
||||
|
|
@ -51,9 +64,10 @@ pub struct SyncbackCommand {
|
|||
#[clap(long)]
|
||||
pub dry_run: bool,
|
||||
|
||||
/// If provided, the prompt for writing to the file system is skipped.
|
||||
#[clap(long, short = 'y')]
|
||||
pub non_interactive: bool,
|
||||
/// If provided, prompts before writing to the file system.
|
||||
/// By default, syncback runs non-interactively.
|
||||
#[clap(long, short = 'i')]
|
||||
pub interactive: bool,
|
||||
|
||||
/// If provided, syncback will preserve existing file structure and middleware
|
||||
/// formats when possible. Without this flag (default), syncback creates a fresh
|
||||
|
|
@ -65,7 +79,53 @@ pub struct SyncbackCommand {
|
|||
impl SyncbackCommand {
|
||||
pub fn run(&self, global: GlobalOptions) -> anyhow::Result<()> {
|
||||
let path_old = resolve_path(&self.project);
|
||||
let path_new = resolve_path(&self.input);
|
||||
|
||||
// Determine if we need to download the input file
|
||||
let resolved_input = resolve_path(&self.input);
|
||||
let _temp_file: Option<NamedTempFile>;
|
||||
|
||||
// Logic:
|
||||
// - If --download=PLACEID: always download that specific place
|
||||
// - If input file exists: use it
|
||||
// - If input file doesn't exist: auto-download using servePlaceIds
|
||||
let path_new = match &self.download {
|
||||
Some(place_id) => {
|
||||
// --download=PLACEID: always download this specific place
|
||||
eprintln!("Downloading place {}...", place_id);
|
||||
let download_timer = Instant::now();
|
||||
let temp = download_place(*place_id)?;
|
||||
eprintln!(
|
||||
"Downloaded in {:.02}s",
|
||||
download_timer.elapsed().as_secs_f32()
|
||||
);
|
||||
let temp_path = temp.path().to_path_buf();
|
||||
_temp_file = Some(temp);
|
||||
temp_path
|
||||
}
|
||||
None if resolved_input.exists() => {
|
||||
// No --download flag, input file exists: use it
|
||||
_temp_file = None;
|
||||
resolved_input.into_owned()
|
||||
}
|
||||
None => {
|
||||
// No --download flag, input file doesn't exist: auto-download
|
||||
let place_id = get_place_id_from_project(&path_old)?;
|
||||
eprintln!(
|
||||
"Input file '{}' not found, downloading place {}...",
|
||||
resolved_input.display(),
|
||||
place_id
|
||||
);
|
||||
let download_timer = Instant::now();
|
||||
let temp = download_place(place_id)?;
|
||||
eprintln!(
|
||||
"Downloaded in {:.02}s",
|
||||
download_timer.elapsed().as_secs_f32()
|
||||
);
|
||||
let temp_path = temp.path().to_path_buf();
|
||||
_temp_file = Some(temp);
|
||||
temp_path
|
||||
}
|
||||
};
|
||||
|
||||
let input_kind = FileKind::from_path(&path_new).context(UNKNOWN_INPUT_KIND_ERR)?;
|
||||
let dom_start_timer = Instant::now();
|
||||
|
|
@ -127,8 +187,12 @@ impl SyncbackCommand {
|
|||
list_files(&snapshot, global.color.into(), base_path)?;
|
||||
}
|
||||
|
||||
// Drop dom_old early to release the mutex - we don't need it anymore
|
||||
// and write_sourcemap needs to acquire the same lock
|
||||
drop(dom_old);
|
||||
|
||||
if !self.dry_run {
|
||||
if !self.non_interactive {
|
||||
if self.interactive {
|
||||
eprintln!(
|
||||
"Would write {} files/folders and remove {} files/folders.",
|
||||
snapshot.added_paths().len(),
|
||||
|
|
@ -146,7 +210,14 @@ impl SyncbackCommand {
|
|||
}
|
||||
eprintln!("Writing to the file system...");
|
||||
snapshot.write_to_vfs(base_path, session_old.vfs())?;
|
||||
eprintln!("Finished syncback.")
|
||||
eprintln!("Finished syncback.");
|
||||
|
||||
// Generate sourcemap after successful syncback
|
||||
let sourcemap_path = base_path.join("sourcemap.json");
|
||||
write_sourcemap(&session_old, Some(&sourcemap_path), filter_nothing, false)?;
|
||||
|
||||
// Refresh git index if in a git repository
|
||||
refresh_git_index(base_path);
|
||||
} else {
|
||||
eprintln!(
|
||||
"Would write {} files/folders and remove {} files/folders.",
|
||||
|
|
@ -159,13 +230,124 @@ impl SyncbackCommand {
|
|||
// It is potentially prohibitively expensive to drop a ServeSession,
|
||||
// and the program is about to exit anyway so we're just going to forget
|
||||
// about it.
|
||||
drop(dom_old);
|
||||
forget(session_old);
|
||||
|
||||
// Temp file is automatically cleaned up when _temp_file is dropped
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the first place ID from the project's servePlaceIds field.
|
||||
fn get_place_id_from_project(project_path: &Path) -> anyhow::Result<u64> {
|
||||
// Use oneshot Vfs to avoid file watching issues
|
||||
let temp_vfs = Vfs::new_oneshot();
|
||||
let project =
|
||||
Project::load_fuzzy(&temp_vfs, project_path)?.context("Could not find project file")?;
|
||||
let serve_place_ids = project.serve_place_ids.as_ref().context(
|
||||
"No servePlaceIds in project file. Add servePlaceIds to your project or use --download=PLACEID",
|
||||
)?;
|
||||
// Get the smallest ID for deterministic behavior
|
||||
serve_place_ids
|
||||
.iter()
|
||||
.min()
|
||||
.copied()
|
||||
.context("servePlaceIds is empty in project file")
|
||||
}
|
||||
|
||||
/// Downloads a place file from Roblox's asset delivery API.
|
||||
///
|
||||
/// Uses rbx_cookie to get the authentication cookie from the system.
|
||||
fn download_place(place_id: u64) -> anyhow::Result<NamedTempFile> {
|
||||
let cookie = rbx_cookie::get_value()
|
||||
.context("Could not find Roblox authentication cookie. Please log into Roblox Studio.")?;
|
||||
|
||||
let url = format!("https://assetdelivery.roblox.com/v1/asset/?id={}", place_id);
|
||||
|
||||
let client = reqwest::blocking::Client::builder()
|
||||
.gzip(true)
|
||||
.brotli(true)
|
||||
.deflate(true)
|
||||
.build()?;
|
||||
|
||||
let response = client
|
||||
.get(&url)
|
||||
.header(COOKIE, format!(".ROBLOSECURITY={}", cookie))
|
||||
.header(CACHE_CONTROL, "no-cache, no-store, must-revalidate")
|
||||
.header(PRAGMA, "no-cache")
|
||||
.header("Expires", "0")
|
||||
.header(USER_AGENT, "Rojo")
|
||||
.send()?;
|
||||
|
||||
let status = response.status();
|
||||
if !status.is_success() {
|
||||
bail!(
|
||||
"Failed to download place {}: HTTP {} - {}",
|
||||
place_id,
|
||||
status,
|
||||
response.text().unwrap_or_default()
|
||||
);
|
||||
}
|
||||
|
||||
// Create temp file with .rbxl extension
|
||||
let mut temp_file = tempfile::Builder::new()
|
||||
.prefix("rojo-syncback-")
|
||||
.suffix(".rbxl")
|
||||
.tempfile()
|
||||
.context("Failed to create temporary file")?;
|
||||
|
||||
// Write response body to temp file
|
||||
let bytes = response.bytes()?;
|
||||
io::copy(&mut bytes.as_ref(), &mut temp_file)?;
|
||||
temp_file.flush()?;
|
||||
|
||||
log::debug!(
|
||||
"Downloaded {} bytes to {}",
|
||||
bytes.len(),
|
||||
temp_file.path().display()
|
||||
);
|
||||
|
||||
Ok(temp_file)
|
||||
}
|
||||
|
||||
/// Refreshes the git index if the project is in a git repository.
|
||||
///
|
||||
/// This is useful because syncback may rewrite files with identical content,
|
||||
/// which can cause git to report them as modified due to timestamp changes.
|
||||
fn refresh_git_index(project_dir: &Path) {
|
||||
// Check if .git exists in project dir or any parent
|
||||
let mut check_dir = Some(project_dir);
|
||||
let mut is_git_repo = false;
|
||||
while let Some(dir) = check_dir {
|
||||
if dir.join(".git").exists() {
|
||||
is_git_repo = true;
|
||||
break;
|
||||
}
|
||||
check_dir = dir.parent();
|
||||
}
|
||||
|
||||
if is_git_repo {
|
||||
log::debug!("Refreshing git index...");
|
||||
let result = Command::new("git")
|
||||
.args(["update-index", "--refresh"])
|
||||
.current_dir(project_dir)
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::null())
|
||||
.status();
|
||||
|
||||
match result {
|
||||
Ok(status) => {
|
||||
if !status.success() {
|
||||
log::debug!("git update-index --refresh exited with: {}", status);
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
log::warn!("Failed to run git update-index --refresh: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn read_dom(path: &Path, file_kind: FileKind) -> anyhow::Result<WeakDom> {
|
||||
let content = BufReader::new(File::open(path)?);
|
||||
match file_kind {
|
||||
|
|
|
|||
|
|
@ -75,7 +75,6 @@ fn run_syncback_test_impl(name: &str, incremental: bool, callback: impl FnOnce(&
|
|||
project_path.to_str().unwrap(),
|
||||
"--input",
|
||||
input_file.to_str().unwrap(),
|
||||
"--non-interactive",
|
||||
"--list",
|
||||
];
|
||||
|
||||
|
|
@ -118,11 +117,20 @@ fn run_syncback_test_impl(name: &str, incremental: bool, callback: impl FnOnce(&
|
|||
|
||||
// Normalize temp directory paths in the output to make snapshots deterministic.
|
||||
// Paths like "C:/Users/Joe/AppData/Local/Temp/.tmpXXXXXX/test_name/..."
|
||||
// or "\\?\C:\Users\Joe\AppData\Local\Temp\.tmpXXXXXX\test_name\..."
|
||||
// become "<TEMP>/test_name/..."
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
|
||||
// Handle forward slash paths (Unix-style)
|
||||
let temp_path_regex = Regex::new(r"[A-Za-z]:/[^\s]*/\.tmp[^/]*/").expect("Invalid regex");
|
||||
let normalized_stdout = temp_path_regex.replace_all(&stdout, "<TEMP>/");
|
||||
|
||||
// Handle backslash paths with optional UNC prefix (Windows-style)
|
||||
// Matches: \\?\C:\...\temp dir\ or C:\...\temp dir\
|
||||
let windows_temp_regex =
|
||||
Regex::new(r"(?:\\\\?\?\\)?[A-Za-z]:\\[^\s]*\\\.tmp[^\\]*\\").expect("Invalid regex");
|
||||
let normalized_stdout = windows_temp_regex.replace_all(&normalized_stdout, "<TEMP>/");
|
||||
|
||||
settings.bind(|| assert_snapshot!(format!("{name}-stdout"), normalized_stdout));
|
||||
|
||||
settings.bind(|| callback(project_path.as_path()))
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ fn run_syncback(project_path: &Path, input_path: &Path, incremental: bool) -> bo
|
|||
project_path.to_str().unwrap(),
|
||||
"--input",
|
||||
input_path.to_str().unwrap(),
|
||||
"--non-interactive",
|
||||
];
|
||||
|
||||
if incremental {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue