@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 +181 -10
- package/index.js +70 -4
- package/package.json +19 -11
- package/.yarnrc.yml +0 -1
- package/Cargo.toml +0 -31
- package/build.rs +0 -44
- package/src/file_utils.rs +0 -213
- package/src/git_utils.rs +0 -346
- package/src/lib.rs +0 -259
- package/src/lib2.rs +0 -212
- package/src/merkle_tree/local_construction.rs +0 -228
- package/src/merkle_tree/mod.rs +0 -1181
- 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/src/test.rs +0 -5
package/index.d.ts
CHANGED
|
@@ -3,18 +3,189 @@
|
|
|
3
3
|
|
|
4
4
|
/* auto-generated by NAPI-RS */
|
|
5
5
|
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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-
|
|
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,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-
|
|
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
|
-
"
|
|
19
|
+
"files": [
|
|
20
|
+
"index.js",
|
|
21
|
+
"index.d.ts"
|
|
22
|
+
],
|
|
23
|
+
"license": "UNLICENSED",
|
|
18
24
|
"devDependencies": {
|
|
19
|
-
"@napi-rs/cli": "^2.
|
|
20
|
-
"ava": "^
|
|
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-
|
|
40
|
-
"@anysphere/file-service-darwin-x64": "0.0.0-
|
|
41
|
-
"@anysphere/file-service-linux-x64-gnu": "0.0.0-
|
|
42
|
-
"@anysphere/file-service-darwin-arm64": "0.0.0-
|
|
43
|
-
"@anysphere/file-service-win32-arm64-msvc": "0.0.0-
|
|
44
|
-
"@anysphere/file-service-
|
|
45
|
-
"@anysphere/file-service-linux-
|
|
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
|
-
}
|