@anysphere/file-service 0.0.0-eb8b99bf → 0.0.0-eb962576

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 CHANGED
@@ -3,18 +3,189 @@
3
3
 
4
4
  /* auto-generated by NAPI-RS */
5
5
 
6
- export class MerkleClient {
7
- constructor(rootDirectory: string)
8
- init(): Promise<void>
9
- computeMerkleTree(): Promise<void>
10
- updateFile(filePath: string): Promise<void>
11
- deleteFile(filePath: string): Promise<void>
6
+ export const enum DiffType {
7
+ Insert = 'Insert',
8
+ Delete = 'Delete',
9
+ Equal = 'Equal'
10
+ }
11
+ export interface DiffChunk {
12
+ diffType: DiffType
13
+ text: string
14
+ }
15
+ export interface CommitData {
16
+ sha: string
17
+ date: number
18
+ message: string
19
+ author: string
20
+ parents: Array<string>
21
+ files: Array<CommitFile>
22
+ }
23
+ export interface CommitFile {
24
+ from: string
25
+ to: string
26
+ additions: number
27
+ deletions: number
28
+ status: CommitFileStatus
29
+ }
30
+ export const enum CommitFileStatus {
31
+ Added = 0,
32
+ Deleted = 1,
33
+ Modified = 2,
34
+ Renamed = 3
35
+ }
36
+ export const enum CommitChainGetFiles {
37
+ DoGetFiles = 0,
38
+ DontGetFiles = 1
39
+ }
40
+ export interface VerifyData {
41
+ commitTime: number
42
+ fileContent: string
43
+ filePath: string
44
+ }
45
+ export interface IndexedFile {
46
+ path: string
47
+ diff: Array<string>
48
+ }
49
+ export interface IndexedPullRequest {
50
+ prNumber: number
51
+ generation: number
52
+ sha: string
53
+ commitSecret: string
54
+ body: string
55
+ changedFiles: Array<IndexedFile>
56
+ unixTimestamp: number
57
+ trimmedTooLarge: boolean
58
+ title?: string
59
+ author?: string
60
+ date?: Date
61
+ }
62
+ export interface JsPullRequestExtractionOptions {
63
+ lastIndexedCommit?: string
64
+ lastIndexedCommitGeneration?: number
65
+ syncBitmap?: Buffer
66
+ limitCommits?: number
67
+ limitPerPr?: number
68
+ context?: number
69
+ workerThreads?: number
70
+ jsConcurrency?: number
71
+ jsChunkSize?: number
72
+ }
73
+ export interface JsPullRequestHydrationOptions {
74
+ limitPerPr?: number
75
+ context?: number
76
+ workerThreads?: number
77
+ interestingPaths?: Array<string>
78
+ }
79
+ export interface JsHandshakeData {
80
+ lastSeenCommit: string
81
+ lastSeenCommitSecret: string
82
+ origin: string
83
+ }
84
+ export interface JsRepositoryTip {
85
+ commitSha: string
86
+ commitShaSecret: string
87
+ generation: number
88
+ }
89
+ export interface ExtractResults {
90
+ repositoryTip?: JsRepositoryTip
91
+ progress: IndexedPullRequestProgress
92
+ interrupted: boolean
93
+ }
94
+ export interface IndexedPullRequestProgress {
95
+ /** Total number of commits in the repository */
96
+ total: number
97
+ /** Number of commits that have been synced to the server */
98
+ synced: number
99
+ /** Number of commits that have been synced to the server in this run */
100
+ newSynced: number
101
+ /** Number of commits that have been marked as ignored in this run */
102
+ newIgnored: number
103
+ /** Number of commits that have failed to be indexed in this run */
104
+ newFailed: number
105
+ /** Time (in seconds) since the start of the indexing process */
106
+ elapsed: number
107
+ }
108
+ export const MULTI_ROOT_ABSOLUTE_PATH: string
109
+ export interface WalkDirConfig {
110
+ maxNumFiles: number
111
+ logFilePath?: string
112
+ blocklistPath?: string
113
+ unifiedJsonBlocklistPath?: string
114
+ globalCursorIgnorePatterns?: string
115
+ }
116
+ export interface LocalCodebaseFileInfo {
117
+ unencryptedRelativePath: string
118
+ hash: string
119
+ children?: Array<LocalCodebaseFileInfo>
120
+ }
121
+ export declare class DiffClient {
122
+ constructor()
123
+ diff(text1: string, text2: string): Array<DiffChunk>
124
+ /**
125
+ * use https://docs.rs/diffmatchpatch/latest/diffmatchpatch/struct.DiffMatchPatch.html#method.diff_lines_to_chars
126
+ * then diff the chars.
127
+ * then convert back to lines.
128
+ *
129
+ * takes in two strings. splits based on newlines.
130
+ * returns diffs based on lines.
131
+ */
132
+ diffLines(text1: string, text2: string): Array<DiffChunk>
133
+ }
134
+ export declare class GitClient {
135
+ constructor(absoluteRootDirectory: string)
136
+ getTotalCommitCount(): Promise<number>
137
+ getCommitVerifyData(commit: string): Promise<VerifyData>
138
+ throwIfCommitDoesntExist(rootSha: string): Promise<void>
139
+ getVerifyCommit(): Promise<string>
140
+ getRepoHeadSha(): Promise<string | null>
141
+ getCommitChain(hash: string, depth: number, getFiles: CommitChainGetFiles): Promise<Array<CommitData>>
142
+ }
143
+ export declare class GitGraph {
144
+ constructor(repo: string, globalCursorIgnoreLegacy?: string | undefined | null, globalCursorJsonUnifiedBlocklist?: string | undefined | null)
145
+ /**
146
+ * Get a list of all paths in this repository, up to a maximum depth of `max_depth`. The
147
+ * paths are returned breadth-first, meaning that all paths at depth 0 are returned before any
148
+ * paths at depth 1, and so on.
149
+ * The iteration takes into account `gitignore` and `cursorignore` rules.
150
+ *
151
+ * @param maxDepth - maximum depth to search for paths. A depth of 0 means only the root path
152
+ * is returned.
153
+ * @param limit - maximum number of paths to return. If `None`, all paths are returned.
154
+ */
155
+ getBfsPaths(maxDepth: number, limit?: number | undefined | null): Promise<Array<string>>
156
+ /**
157
+ * Get a sorted list of relevant paths in this repository, from most relevant to least
158
+ * relevant. The list is biased towards the current user, using a heuristic that takes into account
159
+ * the most recently opened/edited files in the editor, which must be passed in as
160
+ * `lastEditedFiles`. If no recent files are provided, the returned paths will be sorted
161
+ * based on the global popularity of the files in the repository (i.e. the number of times each
162
+ * file has been modified throughout the Git history).
163
+ *
164
+ * @param lastEditedFiles - list of files that were recently opened/edited in the editor.
165
+ * @param maxCommits - maximum number of commits to consider when calculating the relevant paths.
166
+ * @param maxPaths - number of relevant paths to return
167
+ */
168
+ getRelevantPaths(lastEditedFiles: Array<string>, maxCommits: number, maxPaths: number): Promise<Array<string>>
169
+ }
170
+ export declare class RepositoryIndexer {
171
+ constructor(repo: string, blockListLegacy?: string | undefined | null, blockListJson?: string | undefined | null)
172
+ extractPullRequests(options: JsPullRequestExtractionOptions, callback: (err: Error | null, indexed: IndexedPullRequest[], ignored: number[], progress: IndexedPullRequestProgress) => Promise<boolean>): Promise<ExtractResults>
173
+ hydratePullRequests(pullRequests: Array<string>, options: JsPullRequestHydrationOptions, callback: (err: Error | null, arg: IndexedPullRequest) => any): Promise<void>
174
+ getHandshakeData(): Promise<JsHandshakeData | null>
175
+ verifyCommitOwnership(secret: string, candidates: Array<string>): Promise<JsHandshakeData | null>
176
+ }
177
+ export declare class MerkleClient {
178
+ constructor(rootPathsMap: Record<string, string>)
179
+ build(allowIncremental: boolean, config: WalkDirConfig): Promise<void>
12
180
  getSubtreeHash(relativePath: string): Promise<string>
13
181
  getNumEmbeddableFiles(): Promise<number>
182
+ getSimhash(): Promise<Float32Array>
183
+ getImportantPaths(k: number): Promise<Array<string>>
14
184
  getAllFiles(): Promise<Array<string>>
15
185
  getAllDirFilesToEmbed(absoluteFilePath: string): Promise<Array<string>>
16
- getNextFileToEmbed(): Promise<Array<string>>
17
- getSpline(absoluteFilePath: string): Promise<Array<string>>
18
- getHashesForFiles(files: Array<string>): Promise<Array<string>>
19
- updateRootDirectory(rootDirectory: string): void
186
+ onDidCreate(absoluteFilePath: string): void
187
+ onDidChange(absoluteFilePath: string): void
188
+ onDidDelete(absoluteFilePath: string): void
189
+ getTreeStructure(): Promise<LocalCodebaseFileInfo | null>
190
+ dispose(): void
20
191
  }
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-arm-gnueabihf.node')
286
+ join(__dirname, 'file_service.linux-s390x-gnu.node')
229
287
  )
230
288
  try {
231
289
  if (localFileExisted) {
232
- nativeBinding = require('./file_service.linux-arm-gnueabihf.node')
290
+ nativeBinding = require('./file_service.linux-s390x-gnu.node')
233
291
  } else {
234
- nativeBinding = require('@anysphere/file-service-linux-arm-gnueabihf')
292
+ nativeBinding = require('@anysphere/file-service-linux-s390x-gnu')
235
293
  }
236
294
  } catch (e) {
237
295
  loadError = e
@@ -252,6 +310,14 @@ if (!nativeBinding) {
252
310
  throw new Error(`Failed to load native binding`)
253
311
  }
254
312
 
255
- const { MerkleClient } = nativeBinding
313
+ const { DiffType, DiffClient, GitClient, CommitFileStatus, CommitChainGetFiles, GitGraph, RepositoryIndexer, MULTI_ROOT_ABSOLUTE_PATH, MerkleClient } = nativeBinding
256
314
 
315
+ module.exports.DiffType = DiffType
316
+ module.exports.DiffClient = DiffClient
317
+ module.exports.GitClient = GitClient
318
+ module.exports.CommitFileStatus = CommitFileStatus
319
+ module.exports.CommitChainGetFiles = CommitChainGetFiles
320
+ module.exports.GitGraph = GitGraph
321
+ module.exports.RepositoryIndexer = RepositoryIndexer
322
+ module.exports.MULTI_ROOT_ABSOLUTE_PATH = MULTI_ROOT_ABSOLUTE_PATH
257
323
  module.exports.MerkleClient = MerkleClient
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anysphere/file-service",
3
- "version": "0.0.0-eb8b99bf",
3
+ "version": "0.0.0-eb962576",
4
4
  "main": "index.js",
5
5
  "types": "index.d.ts",
6
6
  "napi": {
@@ -9,15 +9,21 @@
9
9
  "additional": [
10
10
  "aarch64-apple-darwin",
11
11
  "aarch64-pc-windows-msvc",
12
+ "aarch64-unknown-linux-musl",
13
+ "x86_64-unknown-linux-musl",
12
14
  "universal-apple-darwin",
13
15
  "aarch64-unknown-linux-gnu"
14
16
  ]
15
17
  }
16
18
  },
17
- "license": "MIT",
19
+ "files": [
20
+ "index.js",
21
+ "index.d.ts"
22
+ ],
23
+ "license": "UNLICENSED",
18
24
  "devDependencies": {
19
- "@napi-rs/cli": "^2.16.2",
20
- "ava": "^5.1.1"
25
+ "@napi-rs/cli": "^2.18.4",
26
+ "ava": "^6.3.0"
21
27
  },
22
28
  "ava": {
23
29
  "timeout": "3m"
@@ -36,12 +42,14 @@
36
42
  "version": "napi version"
37
43
  },
38
44
  "optionalDependencies": {
39
- "@anysphere/file-service-win32-x64-msvc": "0.0.0-eb8b99bf",
40
- "@anysphere/file-service-darwin-x64": "0.0.0-eb8b99bf",
41
- "@anysphere/file-service-linux-x64-gnu": "0.0.0-eb8b99bf",
42
- "@anysphere/file-service-darwin-arm64": "0.0.0-eb8b99bf",
43
- "@anysphere/file-service-win32-arm64-msvc": "0.0.0-eb8b99bf",
44
- "@anysphere/file-service-darwin-universal": "0.0.0-eb8b99bf",
45
- "@anysphere/file-service-linux-arm64-gnu": "0.0.0-eb8b99bf"
45
+ "@anysphere/file-service-win32-x64-msvc": "0.0.0-eb962576",
46
+ "@anysphere/file-service-darwin-x64": "0.0.0-eb962576",
47
+ "@anysphere/file-service-linux-x64-gnu": "0.0.0-eb962576",
48
+ "@anysphere/file-service-darwin-arm64": "0.0.0-eb962576",
49
+ "@anysphere/file-service-win32-arm64-msvc": "0.0.0-eb962576",
50
+ "@anysphere/file-service-linux-arm64-musl": "0.0.0-eb962576",
51
+ "@anysphere/file-service-linux-x64-musl": "0.0.0-eb962576",
52
+ "@anysphere/file-service-darwin-universal": "0.0.0-eb962576",
53
+ "@anysphere/file-service-linux-arm64-gnu": "0.0.0-eb962576"
46
54
  }
47
55
  }
package/.yarnrc.yml DELETED
@@ -1 +0,0 @@
1
- nodeLinker: node-modules
package/Cargo.toml DELETED
@@ -1,31 +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
- tracing = "0.1.37"
21
- tracing-subscriber = "0.3.17"
22
- tracing-appender = "0.2.2"
23
-
24
- [build-dependencies]
25
- napi-build = "2.0.1"
26
- tonic-build = "0.9.2"
27
- anyhow = "1.0.75"
28
- glob = "0.3.0"
29
-
30
- [profile.release]
31
- 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,213 +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 =
16
- item_path.contains("node_modules") || item_path.contains(".git");
17
- Ok(is_bad_dir)
18
- }
19
-
20
- pub fn is_good_file(file_path: &Path) -> Result<(), Error> {
21
- let item_path = file_path
22
- .to_str()
23
- .ok_or(anyhow::anyhow!("Failed to convert path to string"))?;
24
-
25
- let path = Path::new(item_path);
26
- let file_name = path
27
- .file_name()
28
- .ok_or(anyhow::anyhow!("Failed to get file name"))?
29
- .to_str()
30
- .ok_or(anyhow::anyhow!("Failed to convert file name to string"))?;
31
-
32
- let extension = path
33
- .extension()
34
- .ok_or(anyhow::anyhow!("Failed to get extension"))?
35
- .to_str()
36
- .ok_or(anyhow::anyhow!("Failed to convert extension to string"))?;
37
-
38
- match file_name {
39
- "package-lock.json" | "pnpm-lock.yaml" | "yarn.lock" | "composer.lock"
40
- | "Gemfile.lock" | "bun.lockb" => {
41
- return Err(anyhow::anyhow!("File is just a lock file"));
42
- }
43
- _ => {}
44
- }
45
-
46
- match extension {
47
- "lock" | "bak" | "tmp" | "bin" | "exe" | "dll" | "so" | "lockb" => {
48
- return Err(anyhow::anyhow!("File is just a lock file"));
49
- }
50
- _ => {}
51
- }
52
-
53
- if item_path.contains(".git")
54
- || item_path.contains(".svn")
55
- || item_path.contains(".hg")
56
- {
57
- return Err(anyhow::anyhow!("File is just a lock file"));
58
- }
59
-
60
- let bad_extensions = vec![".exe", ".dll", ".so", ".o", ".bin"];
61
- match Path::new(item_path).extension() {
62
- Some(extension) => match extension.to_str() {
63
- Some(ext_str) => {
64
- if bad_extensions.contains(&ext_str) {
65
- return Err(anyhow::anyhow!("File is not a valid UTF-8 string"));
66
- }
67
- }
68
- None => {
69
- return Err(anyhow::anyhow!("Failed to convert extension to string"))
70
- }
71
- },
72
- None => return Err(anyhow::anyhow!("Failed to get extension")),
73
- }
74
-
75
- // #[cfg(not(test))]
76
- // {
77
- let path = Path::new(item_path);
78
- for part in path.iter() {
79
- match part.to_str() {
80
- Some(s) if s.starts_with(".") => {
81
- return Err(anyhow::anyhow!("File is hidden"))
82
- }
83
- _ => {}
84
- }
85
- }
86
- // }
87
-
88
- Ok(())
89
- }
90
-
91
- // implement the buffer above:
92
- pub async fn is_good_file_runtime_check(
93
- file_path: &Path,
94
- buffer: &[u8],
95
- ) -> Result<(), Error> {
96
- match get_file_size(file_path).await {
97
- Ok(size) if size > 2 * 1024 * 1024 => {
98
- return Err(anyhow::anyhow!("Buffer is too large"));
99
- }
100
- Err(e) => return Err(e),
101
- _ => {}
102
- }
103
-
104
- for &byte in buffer.iter().take(2048) {
105
- if byte.is_ascii() {
106
- continue;
107
- } else {
108
- return Err(anyhow::anyhow!("File is not a valid UTF-8 string"));
109
- }
110
- }
111
- Ok(())
112
- }
113
-
114
- pub fn as_relative_path(
115
- base_path: &Path,
116
- file_path: &Path,
117
- ) -> Result<String, Error> {
118
- let relative_path = file_path.strip_prefix(base_path)?;
119
- Ok(
120
- relative_path
121
- .to_str()
122
- .ok_or(anyhow::anyhow!("Failed to convert relative path to string"))?
123
- .to_string(),
124
- )
125
- }
126
-
127
- pub async fn get_file_size(file_path: &Path) -> Result<u64, Error> {
128
- let metadata = fs::metadata(file_path).await?;
129
-
130
- Ok(metadata.len())
131
- }
132
-
133
- #[cfg(test)]
134
- mod tests {
135
- use super::*;
136
- use std::path::Path;
137
- use tokio::io::AsyncWriteExt;
138
-
139
- #[test]
140
- fn test_is_in_bad_dir() {
141
- let path = Path::new("src/node_modules/test.rs");
142
- assert_eq!(is_in_bad_dir(&path).unwrap(), true);
143
-
144
- let path = Path::new("src/.git/test.rs");
145
- assert_eq!(is_in_bad_dir(&path).unwrap(), true);
146
-
147
- let path = Path::new("src/test.rs");
148
- assert_eq!(is_in_bad_dir(&path).unwrap(), false);
149
- }
150
-
151
- #[test]
152
- fn test_is_good_file() {
153
- let path = Path::new("src/test.rs");
154
- assert_eq!(is_good_file(&path).is_ok(), true);
155
-
156
- let path = Path::new("src/test.exe");
157
- assert_eq!(is_good_file(&path).is_err(), true);
158
-
159
- let path = Path::new("src/.hidden");
160
- assert_eq!(is_good_file(&path).is_err(), true);
161
- }
162
-
163
- #[tokio::test]
164
- async fn test_is_good_file_runtime_check() {
165
- let temp_dir = tempfile::tempdir().unwrap();
166
- let temp_file_path = temp_dir.path().join("test_file");
167
- let mut temp_file = fs::File::create(&temp_file_path).await.unwrap();
168
- temp_file.write_all(b"Hello, world!").await.unwrap();
169
- let buffer = fs::read(&temp_file_path).await.unwrap();
170
- assert_eq!(
171
- is_good_file_runtime_check(&temp_file_path, &buffer)
172
- .await
173
- .is_ok(),
174
- true
175
- );
176
- temp_dir.close().unwrap();
177
-
178
- let temp_dir = tempfile::tempdir().unwrap();
179
- let temp_file_path = temp_dir.path().join("test_file");
180
- let mut temp_file = fs::File::create(&temp_file_path).await.unwrap();
181
- temp_file.write_all(&[0, 159, 146, 150]).await.unwrap(); // Invalid UTF-8 sequence
182
- let buffer = fs::read(&temp_file_path).await.unwrap();
183
- assert_eq!(
184
- is_good_file_runtime_check(&temp_file_path, &buffer)
185
- .await
186
- .is_err(),
187
- true
188
- );
189
- temp_dir.close().unwrap();
190
- }
191
-
192
- #[test]
193
- fn test_as_relative_path() {
194
- let base_path = Path::new("/home/user/src");
195
- let file_path = Path::new("/home/user/src/test.rs");
196
- assert_eq!(as_relative_path(&base_path, &file_path).unwrap(), "test.rs");
197
-
198
- let file_path = Path::new("/home/user/test.rs");
199
- assert!(as_relative_path(&base_path, &file_path).is_err());
200
- }
201
-
202
- #[tokio::test]
203
- async fn test_get_file_size() {
204
- let temp_dir = tempfile::tempdir().unwrap();
205
- let temp_file_path = temp_dir.path().join("test_file.txt");
206
- let mut temp_file = fs::File::create(&temp_file_path).await.unwrap();
207
- temp_file.write_all(b"Hello, world!").await.unwrap();
208
-
209
- let size = get_file_size(&temp_file_path).await.unwrap();
210
- assert_eq!(size, 13);
211
- temp_dir.close().unwrap();
212
- }
213
- }