@anysphere/file-service 0.0.0-e3fdf62d → 0.0.0-e492c95a
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +88 -4
- package/index.js +69 -4
- package/package.json +15 -9
- package/.yarnrc.yml +0 -1
- package/Cargo.toml +0 -28
- package/build.rs +0 -44
- package/src/file_utils.rs +0 -214
- package/src/git_utils.rs +0 -207
- package/src/lib.rs +0 -158
- package/src/lib2.rs +0 -212
- package/src/merkle_tree/local_construction.rs +0 -206
- package/src/merkle_tree/mod.rs +0 -982
- package/src/merkle_tree/remote_sync.rs +0 -40
- package/src/merkle_tree/test.rs +0 -126
- package/src/merkle_tree/test_files/1/test.txt +0 -0
package/index.d.ts
CHANGED
|
@@ -3,14 +3,98 @@
|
|
|
3
3
|
|
|
4
4
|
/* auto-generated by NAPI-RS */
|
|
5
5
|
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
export interface WalkDirConfig {
|
|
7
|
+
maxNumFiles: number
|
|
8
|
+
}
|
|
9
|
+
export const enum DiffType {
|
|
10
|
+
Insert = 'Insert',
|
|
11
|
+
Delete = 'Delete',
|
|
12
|
+
Equal = 'Equal'
|
|
13
|
+
}
|
|
14
|
+
export interface DiffChunk {
|
|
15
|
+
diffType: DiffType
|
|
16
|
+
text: string
|
|
17
|
+
}
|
|
18
|
+
export interface CommitData {
|
|
19
|
+
sha: string
|
|
20
|
+
date: number
|
|
21
|
+
message: string
|
|
22
|
+
author: string
|
|
23
|
+
parents: Array<string>
|
|
24
|
+
files: Array<CommitFile>
|
|
25
|
+
}
|
|
26
|
+
export interface CommitFile {
|
|
27
|
+
from: string
|
|
28
|
+
to: string
|
|
29
|
+
additions: number
|
|
30
|
+
deletions: number
|
|
31
|
+
status: CommitFileStatus
|
|
32
|
+
}
|
|
33
|
+
export const enum CommitFileStatus {
|
|
34
|
+
Added = 0,
|
|
35
|
+
Deleted = 1,
|
|
36
|
+
Modified = 2,
|
|
37
|
+
Renamed = 3
|
|
38
|
+
}
|
|
39
|
+
export const enum CommitChainGetFiles {
|
|
40
|
+
DoGetFiles = 0,
|
|
41
|
+
DontGetFiles = 1
|
|
42
|
+
}
|
|
43
|
+
export interface VerifyData {
|
|
44
|
+
commitTime: number
|
|
45
|
+
fileContent: string
|
|
46
|
+
filePath: string
|
|
47
|
+
}
|
|
48
|
+
export interface Candidate {
|
|
49
|
+
path: string
|
|
50
|
+
locations: Array<number>
|
|
51
|
+
weight: number
|
|
52
|
+
}
|
|
53
|
+
export declare class DiffClient {
|
|
54
|
+
constructor()
|
|
55
|
+
diff(text1: string, text2: string): Array<DiffChunk>
|
|
56
|
+
/**
|
|
57
|
+
* use https://docs.rs/diffmatchpatch/latest/diffmatchpatch/struct.DiffMatchPatch.html#method.diff_lines_to_chars
|
|
58
|
+
* then diff the chars.
|
|
59
|
+
* then convert back to lines.
|
|
60
|
+
*
|
|
61
|
+
* takes in two strings. splits based on newlines.
|
|
62
|
+
* returns diffs based on lines.
|
|
63
|
+
*/
|
|
64
|
+
diffLines(text1: string, text2: string): Array<DiffChunk>
|
|
65
|
+
}
|
|
66
|
+
export declare class MerkleClient {
|
|
67
|
+
constructor(absoluteRootDirectory: string)
|
|
68
|
+
isTooBig(maxFiles: number, gitIgnoredFiles: Array<string>, isGitRepo: boolean): Promise<boolean>
|
|
69
|
+
init(gitIgnoredFiles: Array<string>, isGitRepo: boolean): Promise<void>
|
|
70
|
+
initWithRipgrepIgnore(logFilesPath: string | undefined | null, config: WalkDirConfig): Promise<void>
|
|
71
|
+
computeMerkleTreeWithRipgrepIgnore(logFilesPath: string | undefined | null, config: WalkDirConfig): Promise<void>
|
|
72
|
+
computeMerkleTree(gitIgnoredFiles: Array<string>, isGitRepo: boolean): Promise<void>
|
|
9
73
|
updateFile(filePath: string): Promise<void>
|
|
10
74
|
deleteFile(filePath: string): Promise<void>
|
|
11
|
-
getSubtreeHash(
|
|
75
|
+
getSubtreeHash(relativePath: string): Promise<string>
|
|
12
76
|
getNumEmbeddableFiles(): Promise<number>
|
|
77
|
+
getImportantPaths(k: number): Promise<Array<string>>
|
|
13
78
|
getAllFiles(): Promise<Array<string>>
|
|
79
|
+
getAllDirFilesToEmbed(absoluteFilePath: string): Promise<Array<string>>
|
|
14
80
|
getNextFileToEmbed(): Promise<Array<string>>
|
|
81
|
+
getSpline(absoluteFilePath: string): Promise<Array<string>>
|
|
15
82
|
getHashesForFiles(files: Array<string>): Promise<Array<string>>
|
|
83
|
+
updateRootDirectory(rootDirectory: string): void
|
|
84
|
+
}
|
|
85
|
+
export declare class GitClient {
|
|
86
|
+
constructor(absoluteRootDirectory: string)
|
|
87
|
+
getTotalCommitCount(): Promise<number>
|
|
88
|
+
getCommitVerifyData(commit: string): Promise<VerifyData>
|
|
89
|
+
throwIfCommitDoesntExist(rootSha: string): Promise<void>
|
|
90
|
+
getVerifyCommit(): Promise<string>
|
|
91
|
+
getRepoHeadSha(): Promise<string | null>
|
|
92
|
+
getCommitChain(hash: string, depth: number, getFiles: CommitChainGetFiles): Promise<Array<CommitData>>
|
|
93
|
+
}
|
|
94
|
+
export declare class GitFile {
|
|
95
|
+
findSimilarFiles(lineno: number): Promise<Array<Candidate>>
|
|
96
|
+
}
|
|
97
|
+
export declare class LocalGitGraph {
|
|
98
|
+
constructor(repo: string)
|
|
99
|
+
openFile(path: string): Promise<GitFile>
|
|
16
100
|
}
|
package/index.js
CHANGED
|
@@ -224,14 +224,72 @@ switch (platform) {
|
|
|
224
224
|
}
|
|
225
225
|
break
|
|
226
226
|
case 'arm':
|
|
227
|
+
if (isMusl()) {
|
|
228
|
+
localFileExisted = existsSync(
|
|
229
|
+
join(__dirname, 'file_service.linux-arm-musleabihf.node')
|
|
230
|
+
)
|
|
231
|
+
try {
|
|
232
|
+
if (localFileExisted) {
|
|
233
|
+
nativeBinding = require('./file_service.linux-arm-musleabihf.node')
|
|
234
|
+
} else {
|
|
235
|
+
nativeBinding = require('@anysphere/file-service-linux-arm-musleabihf')
|
|
236
|
+
}
|
|
237
|
+
} catch (e) {
|
|
238
|
+
loadError = e
|
|
239
|
+
}
|
|
240
|
+
} else {
|
|
241
|
+
localFileExisted = existsSync(
|
|
242
|
+
join(__dirname, 'file_service.linux-arm-gnueabihf.node')
|
|
243
|
+
)
|
|
244
|
+
try {
|
|
245
|
+
if (localFileExisted) {
|
|
246
|
+
nativeBinding = require('./file_service.linux-arm-gnueabihf.node')
|
|
247
|
+
} else {
|
|
248
|
+
nativeBinding = require('@anysphere/file-service-linux-arm-gnueabihf')
|
|
249
|
+
}
|
|
250
|
+
} catch (e) {
|
|
251
|
+
loadError = e
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
break
|
|
255
|
+
case 'riscv64':
|
|
256
|
+
if (isMusl()) {
|
|
257
|
+
localFileExisted = existsSync(
|
|
258
|
+
join(__dirname, 'file_service.linux-riscv64-musl.node')
|
|
259
|
+
)
|
|
260
|
+
try {
|
|
261
|
+
if (localFileExisted) {
|
|
262
|
+
nativeBinding = require('./file_service.linux-riscv64-musl.node')
|
|
263
|
+
} else {
|
|
264
|
+
nativeBinding = require('@anysphere/file-service-linux-riscv64-musl')
|
|
265
|
+
}
|
|
266
|
+
} catch (e) {
|
|
267
|
+
loadError = e
|
|
268
|
+
}
|
|
269
|
+
} else {
|
|
270
|
+
localFileExisted = existsSync(
|
|
271
|
+
join(__dirname, 'file_service.linux-riscv64-gnu.node')
|
|
272
|
+
)
|
|
273
|
+
try {
|
|
274
|
+
if (localFileExisted) {
|
|
275
|
+
nativeBinding = require('./file_service.linux-riscv64-gnu.node')
|
|
276
|
+
} else {
|
|
277
|
+
nativeBinding = require('@anysphere/file-service-linux-riscv64-gnu')
|
|
278
|
+
}
|
|
279
|
+
} catch (e) {
|
|
280
|
+
loadError = e
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
break
|
|
284
|
+
case 's390x':
|
|
227
285
|
localFileExisted = existsSync(
|
|
228
|
-
join(__dirname, 'file_service.linux-
|
|
286
|
+
join(__dirname, 'file_service.linux-s390x-gnu.node')
|
|
229
287
|
)
|
|
230
288
|
try {
|
|
231
289
|
if (localFileExisted) {
|
|
232
|
-
nativeBinding = require('./file_service.linux-
|
|
290
|
+
nativeBinding = require('./file_service.linux-s390x-gnu.node')
|
|
233
291
|
} else {
|
|
234
|
-
nativeBinding = require('@anysphere/file-service-linux-
|
|
292
|
+
nativeBinding = require('@anysphere/file-service-linux-s390x-gnu')
|
|
235
293
|
}
|
|
236
294
|
} catch (e) {
|
|
237
295
|
loadError = e
|
|
@@ -252,6 +310,13 @@ if (!nativeBinding) {
|
|
|
252
310
|
throw new Error(`Failed to load native binding`)
|
|
253
311
|
}
|
|
254
312
|
|
|
255
|
-
const { MerkleClient } = nativeBinding
|
|
313
|
+
const { DiffType, DiffClient, MerkleClient, GitClient, CommitFileStatus, CommitChainGetFiles, GitFile, LocalGitGraph } = nativeBinding
|
|
256
314
|
|
|
315
|
+
module.exports.DiffType = DiffType
|
|
316
|
+
module.exports.DiffClient = DiffClient
|
|
257
317
|
module.exports.MerkleClient = MerkleClient
|
|
318
|
+
module.exports.GitClient = GitClient
|
|
319
|
+
module.exports.CommitFileStatus = CommitFileStatus
|
|
320
|
+
module.exports.CommitChainGetFiles = CommitChainGetFiles
|
|
321
|
+
module.exports.GitFile = GitFile
|
|
322
|
+
module.exports.LocalGitGraph = LocalGitGraph
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anysphere/file-service",
|
|
3
|
-
"version": "0.0.0-
|
|
3
|
+
"version": "0.0.0-e492c95a",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"types": "index.d.ts",
|
|
6
6
|
"napi": {
|
|
@@ -9,13 +9,18 @@
|
|
|
9
9
|
"additional": [
|
|
10
10
|
"aarch64-apple-darwin",
|
|
11
11
|
"aarch64-pc-windows-msvc",
|
|
12
|
-
"universal-apple-darwin"
|
|
12
|
+
"universal-apple-darwin",
|
|
13
|
+
"aarch64-unknown-linux-gnu"
|
|
13
14
|
]
|
|
14
15
|
}
|
|
15
16
|
},
|
|
17
|
+
"files": [
|
|
18
|
+
"index.js",
|
|
19
|
+
"index.d.ts"
|
|
20
|
+
],
|
|
16
21
|
"license": "MIT",
|
|
17
22
|
"devDependencies": {
|
|
18
|
-
"@napi-rs/cli": "^2.
|
|
23
|
+
"@napi-rs/cli": "^2.18.4",
|
|
19
24
|
"ava": "^5.1.1"
|
|
20
25
|
},
|
|
21
26
|
"ava": {
|
|
@@ -35,11 +40,12 @@
|
|
|
35
40
|
"version": "napi version"
|
|
36
41
|
},
|
|
37
42
|
"optionalDependencies": {
|
|
38
|
-
"@anysphere/file-service-win32-x64-msvc": "0.0.0-
|
|
39
|
-
"@anysphere/file-service-darwin-x64": "0.0.0-
|
|
40
|
-
"@anysphere/file-service-linux-x64-gnu": "0.0.0-
|
|
41
|
-
"@anysphere/file-service-darwin-arm64": "0.0.0-
|
|
42
|
-
"@anysphere/file-service-win32-arm64-msvc": "0.0.0-
|
|
43
|
-
"@anysphere/file-service-darwin-universal": "0.0.0-
|
|
43
|
+
"@anysphere/file-service-win32-x64-msvc": "0.0.0-e492c95a",
|
|
44
|
+
"@anysphere/file-service-darwin-x64": "0.0.0-e492c95a",
|
|
45
|
+
"@anysphere/file-service-linux-x64-gnu": "0.0.0-e492c95a",
|
|
46
|
+
"@anysphere/file-service-darwin-arm64": "0.0.0-e492c95a",
|
|
47
|
+
"@anysphere/file-service-win32-arm64-msvc": "0.0.0-e492c95a",
|
|
48
|
+
"@anysphere/file-service-darwin-universal": "0.0.0-e492c95a",
|
|
49
|
+
"@anysphere/file-service-linux-arm64-gnu": "0.0.0-e492c95a"
|
|
44
50
|
}
|
|
45
51
|
}
|
package/.yarnrc.yml
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
nodeLinker: node-modules
|
package/Cargo.toml
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
[package]
|
|
2
|
-
edition = "2021"
|
|
3
|
-
name = "file_service"
|
|
4
|
-
version = "0.0.0"
|
|
5
|
-
|
|
6
|
-
[lib]
|
|
7
|
-
crate-type = ["cdylib"]
|
|
8
|
-
|
|
9
|
-
[dependencies]
|
|
10
|
-
# Default enable napi4 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix
|
|
11
|
-
napi = { version = "2.12.2", default-features = false, features = ["napi4", "async", "tokio_rt"] }
|
|
12
|
-
napi-derive = "2.12.2"
|
|
13
|
-
tokio = { version = "1.32.0", features = ["process", "full"] }
|
|
14
|
-
sha2 = "0.10.7"
|
|
15
|
-
rand = "0.8.5"
|
|
16
|
-
tempfile = "3.8.0"
|
|
17
|
-
anyhow = "1.0.75"
|
|
18
|
-
tonic = "0.9.2"
|
|
19
|
-
prost = "0.11.9"
|
|
20
|
-
|
|
21
|
-
[build-dependencies]
|
|
22
|
-
napi-build = "2.0.1"
|
|
23
|
-
tonic-build = "0.9.2"
|
|
24
|
-
anyhow = "1.0.75"
|
|
25
|
-
glob = "0.3.0"
|
|
26
|
-
|
|
27
|
-
[profile.release]
|
|
28
|
-
lto = true
|
package/build.rs
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
use std::path::Path;
|
|
2
|
-
|
|
3
|
-
extern crate napi_build;
|
|
4
|
-
|
|
5
|
-
fn main() -> Result<(), anyhow::Error> {
|
|
6
|
-
napi_build::setup();
|
|
7
|
-
|
|
8
|
-
// print the relative path.
|
|
9
|
-
// let workspace_root = "../../../../../";
|
|
10
|
-
// let path = std::path::Path::new(workspace_root).canonicalize()?;
|
|
11
|
-
// let include_path = Path::join(&path, "schema");
|
|
12
|
-
|
|
13
|
-
// // let relevant_protos = &[
|
|
14
|
-
// // "aiserver/v1/repository.proto",
|
|
15
|
-
// // "aiserver/v1/symbolic_context.proto",
|
|
16
|
-
// // "aiserver/v1/utils.proto"
|
|
17
|
-
// // ];
|
|
18
|
-
// // let proto_paths = relevant_protos
|
|
19
|
-
// // .iter()
|
|
20
|
-
// // .map(|proto| Path::join(&include_path, proto))
|
|
21
|
-
// // .collect::<Vec<_>>();
|
|
22
|
-
// let proto_glob = Path::join(&include_path, "aiserver/v1/*.proto");
|
|
23
|
-
// let relevant_protos: Vec<_> = glob::glob(proto_glob.to_str().expect("Failed to convert path to str"))?
|
|
24
|
-
// .filter_map(Result::ok)
|
|
25
|
-
// .collect();
|
|
26
|
-
|
|
27
|
-
// let proto_paths = relevant_protos
|
|
28
|
-
// .iter()
|
|
29
|
-
// .map(|proto_path| proto_path.to_str().expect("Failed to convert path to str"))
|
|
30
|
-
// .collect::<Vec<_>>();
|
|
31
|
-
// let includes = &[include_path.to_str().unwrap()];
|
|
32
|
-
|
|
33
|
-
// // print the path
|
|
34
|
-
// println!("cargo:rustc-env=INCLUDE_PATH={}", include_path.display());
|
|
35
|
-
|
|
36
|
-
// tonic_build::configure()
|
|
37
|
-
// .build_server(false)
|
|
38
|
-
// .build_transport(true)
|
|
39
|
-
// .out_dir("src/proto")
|
|
40
|
-
// .compile(&proto_paths, includes)?;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
Ok(())
|
|
44
|
-
}
|
package/src/file_utils.rs
DELETED
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
// what methods do i want to support here.
|
|
2
|
-
// 1. isInBadDir
|
|
3
|
-
// 2. isBadFile
|
|
4
|
-
// 3. vscode.workspace.asRelativePath
|
|
5
|
-
// 4. vscode.fs.stat
|
|
6
|
-
|
|
7
|
-
use anyhow::Error;
|
|
8
|
-
use std::path::Path;
|
|
9
|
-
use tokio::fs;
|
|
10
|
-
|
|
11
|
-
pub fn is_in_bad_dir(file_path: &Path) -> Result<bool, Error> {
|
|
12
|
-
let item_path = file_path
|
|
13
|
-
.to_str()
|
|
14
|
-
.ok_or(anyhow::anyhow!("Failed to convert path to string"))?;
|
|
15
|
-
let is_bad_dir = (item_path.contains("node_modules")
|
|
16
|
-
|| item_path.contains(".git"))
|
|
17
|
-
&& !(item_path.ends_with(".git") || item_path.ends_with("node_modules"));
|
|
18
|
-
Ok(is_bad_dir)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
pub fn is_good_file(file_path: &Path) -> Result<(), Error> {
|
|
22
|
-
let item_path = file_path
|
|
23
|
-
.to_str()
|
|
24
|
-
.ok_or(anyhow::anyhow!("Failed to convert path to string"))?;
|
|
25
|
-
|
|
26
|
-
let path = Path::new(item_path);
|
|
27
|
-
let file_name = path
|
|
28
|
-
.file_name()
|
|
29
|
-
.ok_or(anyhow::anyhow!("Failed to get file name"))?
|
|
30
|
-
.to_str()
|
|
31
|
-
.ok_or(anyhow::anyhow!("Failed to convert file name to string"))?;
|
|
32
|
-
|
|
33
|
-
let extension = path
|
|
34
|
-
.extension()
|
|
35
|
-
.ok_or(anyhow::anyhow!("Failed to get extension"))?
|
|
36
|
-
.to_str()
|
|
37
|
-
.ok_or(anyhow::anyhow!("Failed to convert extension to string"))?;
|
|
38
|
-
|
|
39
|
-
match file_name {
|
|
40
|
-
"package-lock.json" | "pnpm-lock.yaml" | "yarn.lock" | "composer.lock"
|
|
41
|
-
| "Gemfile.lock" => {
|
|
42
|
-
return Err(anyhow::anyhow!("File is just a lock file"));
|
|
43
|
-
}
|
|
44
|
-
_ => {}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
match extension {
|
|
48
|
-
"lock" | "bak" | "tmp" | "bin" | "exe" | "dll" | "so" => {
|
|
49
|
-
return Err(anyhow::anyhow!("File is just a lock file"));
|
|
50
|
-
}
|
|
51
|
-
_ => {}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
if item_path.contains(".git")
|
|
55
|
-
|| item_path.contains(".svn")
|
|
56
|
-
|| item_path.contains(".hg")
|
|
57
|
-
{
|
|
58
|
-
return Err(anyhow::anyhow!("File is just a lock file"));
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
let bad_extensions = vec![".exe", ".dll", ".so", ".o", ".bin"];
|
|
62
|
-
match Path::new(item_path).extension() {
|
|
63
|
-
Some(extension) => match extension.to_str() {
|
|
64
|
-
Some(ext_str) => {
|
|
65
|
-
if bad_extensions.contains(&ext_str) {
|
|
66
|
-
return Err(anyhow::anyhow!("File is not a valid UTF-8 string"));
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
None => {
|
|
70
|
-
return Err(anyhow::anyhow!("Failed to convert extension to string"))
|
|
71
|
-
}
|
|
72
|
-
},
|
|
73
|
-
None => return Err(anyhow::anyhow!("Failed to get extension")),
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// #[cfg(not(test))]
|
|
77
|
-
// {
|
|
78
|
-
let path = Path::new(item_path);
|
|
79
|
-
for part in path.iter() {
|
|
80
|
-
match part.to_str() {
|
|
81
|
-
Some(s) if s.starts_with(".") => {
|
|
82
|
-
return Err(anyhow::anyhow!("File is hidden"))
|
|
83
|
-
}
|
|
84
|
-
_ => {}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
// }
|
|
88
|
-
|
|
89
|
-
Ok(())
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// implement the buffer above:
|
|
93
|
-
pub async fn is_good_file_runtime_check(
|
|
94
|
-
file_path: &Path,
|
|
95
|
-
buffer: &[u8],
|
|
96
|
-
) -> Result<(), Error> {
|
|
97
|
-
match get_file_size(file_path).await {
|
|
98
|
-
Ok(size) if size > 2 * 1024 * 1024 => {
|
|
99
|
-
return Err(anyhow::anyhow!("Buffer is too large"));
|
|
100
|
-
}
|
|
101
|
-
Err(e) => return Err(e),
|
|
102
|
-
_ => {}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
for &byte in buffer.iter().take(2048) {
|
|
106
|
-
if byte.is_ascii() {
|
|
107
|
-
continue;
|
|
108
|
-
} else {
|
|
109
|
-
return Err(anyhow::anyhow!("File is not a valid UTF-8 string"));
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
Ok(())
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
pub fn as_relative_path(
|
|
116
|
-
base_path: &Path,
|
|
117
|
-
file_path: &Path,
|
|
118
|
-
) -> Result<String, Error> {
|
|
119
|
-
let relative_path = file_path.strip_prefix(base_path)?;
|
|
120
|
-
Ok(
|
|
121
|
-
relative_path
|
|
122
|
-
.to_str()
|
|
123
|
-
.ok_or(anyhow::anyhow!("Failed to convert relative path to string"))?
|
|
124
|
-
.to_string(),
|
|
125
|
-
)
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
pub async fn get_file_size(file_path: &Path) -> Result<u64, Error> {
|
|
129
|
-
let metadata = fs::metadata(file_path).await?;
|
|
130
|
-
|
|
131
|
-
Ok(metadata.len())
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
#[cfg(test)]
|
|
135
|
-
mod tests {
|
|
136
|
-
use super::*;
|
|
137
|
-
use std::path::Path;
|
|
138
|
-
use tokio::io::AsyncWriteExt;
|
|
139
|
-
|
|
140
|
-
#[test]
|
|
141
|
-
fn test_is_in_bad_dir() {
|
|
142
|
-
let path = Path::new("src/node_modules/test.rs");
|
|
143
|
-
assert_eq!(is_in_bad_dir(&path).unwrap(), true);
|
|
144
|
-
|
|
145
|
-
let path = Path::new("src/.git/test.rs");
|
|
146
|
-
assert_eq!(is_in_bad_dir(&path).unwrap(), true);
|
|
147
|
-
|
|
148
|
-
let path = Path::new("src/test.rs");
|
|
149
|
-
assert_eq!(is_in_bad_dir(&path).unwrap(), false);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
#[test]
|
|
153
|
-
fn test_is_good_file() {
|
|
154
|
-
let path = Path::new("src/test.rs");
|
|
155
|
-
assert_eq!(is_good_file(&path).is_ok(), true);
|
|
156
|
-
|
|
157
|
-
let path = Path::new("src/test.exe");
|
|
158
|
-
assert_eq!(is_good_file(&path).is_err(), true);
|
|
159
|
-
|
|
160
|
-
let path = Path::new("src/.hidden");
|
|
161
|
-
assert_eq!(is_good_file(&path).is_err(), true);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
#[tokio::test]
|
|
165
|
-
async fn test_is_good_file_runtime_check() {
|
|
166
|
-
let temp_dir = tempfile::tempdir().unwrap();
|
|
167
|
-
let temp_file_path = temp_dir.path().join("test_file");
|
|
168
|
-
let mut temp_file = fs::File::create(&temp_file_path).await.unwrap();
|
|
169
|
-
temp_file.write_all(b"Hello, world!").await.unwrap();
|
|
170
|
-
let buffer = fs::read(&temp_file_path).await.unwrap();
|
|
171
|
-
assert_eq!(
|
|
172
|
-
is_good_file_runtime_check(&temp_file_path, &buffer)
|
|
173
|
-
.await
|
|
174
|
-
.is_ok(),
|
|
175
|
-
true
|
|
176
|
-
);
|
|
177
|
-
temp_dir.close().unwrap();
|
|
178
|
-
|
|
179
|
-
let temp_dir = tempfile::tempdir().unwrap();
|
|
180
|
-
let temp_file_path = temp_dir.path().join("test_file");
|
|
181
|
-
let mut temp_file = fs::File::create(&temp_file_path).await.unwrap();
|
|
182
|
-
temp_file.write_all(&[0, 159, 146, 150]).await.unwrap(); // Invalid UTF-8 sequence
|
|
183
|
-
let buffer = fs::read(&temp_file_path).await.unwrap();
|
|
184
|
-
assert_eq!(
|
|
185
|
-
is_good_file_runtime_check(&temp_file_path, &buffer)
|
|
186
|
-
.await
|
|
187
|
-
.is_err(),
|
|
188
|
-
true
|
|
189
|
-
);
|
|
190
|
-
temp_dir.close().unwrap();
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
#[test]
|
|
194
|
-
fn test_as_relative_path() {
|
|
195
|
-
let base_path = Path::new("/home/user/src");
|
|
196
|
-
let file_path = Path::new("/home/user/src/test.rs");
|
|
197
|
-
assert_eq!(as_relative_path(&base_path, &file_path).unwrap(), "test.rs");
|
|
198
|
-
|
|
199
|
-
let file_path = Path::new("/home/user/test.rs");
|
|
200
|
-
assert!(as_relative_path(&base_path, &file_path).is_err());
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
#[tokio::test]
|
|
204
|
-
async fn test_get_file_size() {
|
|
205
|
-
let temp_dir = tempfile::tempdir().unwrap();
|
|
206
|
-
let temp_file_path = temp_dir.path().join("test_file.txt");
|
|
207
|
-
let mut temp_file = fs::File::create(&temp_file_path).await.unwrap();
|
|
208
|
-
temp_file.write_all(b"Hello, world!").await.unwrap();
|
|
209
|
-
|
|
210
|
-
let size = get_file_size(&temp_file_path).await.unwrap();
|
|
211
|
-
assert_eq!(size, 13);
|
|
212
|
-
temp_dir.close().unwrap();
|
|
213
|
-
}
|
|
214
|
-
}
|