@wildwinter/simple-vc-lib 0.0.2 → 0.0.3

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.
Files changed (3) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +282 -0
  3. package/package.json +11 -3
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ian Thomas
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,282 @@
1
+ # simple-vc-lib
2
+ **simple-vc-lib** is a multi-language library that provides an agnostic wrapper around common version control systems for tools. It lets your tools create, edit, and delete files without needing to know or care which version control system the user has in place.
3
+
4
+ I wrote this for game dev tooling, but it might be useful for your other projects.
5
+
6
+ ```javascript
7
+ import { writeTextFile, deleteFile } from './simpleVcLib.js';
8
+
9
+ // Write a file - checks out if needed, writes, adds to VC if new
10
+ const result = writeTextFile('/path/to/dialogue.json', JSON.stringify(data));
11
+ if (!result.success) {
12
+ console.error(result.message); // e.g. "File is locked by another user"
13
+ process.exit(1);
14
+ }
15
+
16
+ // Deleting - marks for deletion in VC if tracked
17
+ deleteFile('/path/to/old-dialogue.json');
18
+ ```
19
+
20
+ ```csharp
21
+ using SimpleVCLib;
22
+
23
+ // Write a file - checks out if needed, writes, adds to VC if new
24
+ var result = VCLib.WriteTextFile("/path/to/dialogue.json", jsonContent);
25
+ if (!result.Success) {
26
+ Console.WriteLine(result.Message); // e.g. "File is locked by another user"
27
+ return;
28
+ }
29
+
30
+ // Deleting
31
+ VCLib.DeleteFile("/path/to/old-dialogue.json");
32
+ ```
33
+
34
+ ### Contents
35
+ * [What it does](#what-it-does)
36
+ * [Source Code](#source-code)
37
+ * [Releases](#releases)
38
+ * [Supported Version Control Systems](#supported-version-control-systems)
39
+ * [Usage](#usage)
40
+ * [Overview](#overview)
41
+ * [Operations](#operations)
42
+ * [Return Values](#return-values)
43
+ * [VC Detection](#vc-detection)
44
+ * [Overriding VC Detection](#overriding-vc-detection)
45
+ * [Javascript](#javascript)
46
+ * [C#](#c)
47
+ * [Contributors](#contributors)
48
+ * [License](#license)
49
+
50
+
51
+ ## What it does
52
+ Game development tools often create, modify, or delete content files — dialogue JSON, audio files, configuration — while the project is under version control. If a file is checked in to Perforce or Plastic SCM it will typically be read-only until checked out, and new files need to be explicitly added.
53
+
54
+ **simple-vc-lib** handles all of that for you behind a single consistent API, so you can write one piece of code that works regardless of whether the user is on Git, Perforce, Plastic SCM, SVN, or no version control at all.
55
+
56
+ ## Source Code
57
+ The source can be found on [Github](https://github.com/wildwinter/simple-vc-lib), and is available under the MIT license.
58
+
59
+ ## Releases
60
+ * **Javascript** — available on [npm](https://www.npmjs.com/package/@wildwinter/simple-vc-lib) as `@wildwinter/simple-vc-lib`. Includes ESM and CommonJS builds with TypeScript definitions.
61
+ * **C#** — available on [NuGet](https://www.nuget.org/packages/wildwinter.SimpleVCLib) as `wildwinter.SimpleVCLib`. Targets .NET 8.
62
+
63
+ Both are cross-platform (macOS Arm64 and Windows x64). Zip archives are also available in the [GitHub releases area](https://github.com/wildwinter/simple-vc-lib/releases).
64
+
65
+ ## Supported Version Control Systems
66
+ | System | CLI used | Detection |
67
+ |---|---|---|
68
+ | **Git** | `git` | `.git` folder/file walking up from the file path |
69
+ | **Perforce (Helix Core)** | `p4` | `p4 info` command succeeds with a configured workspace |
70
+ | **Plastic SCM / Unity Version Control** | `cm` | `.plastic` folder walking up from the file path |
71
+ | **SVN (Subversion)** | `svn` | `.svn` folder walking up from the file path |
72
+ | **Filesystem (no VC)** | — | Fallback when nothing else is detected |
73
+
74
+ The library calls the relevant CLI under the hood. The appropriate CLI tool must be installed and on the system PATH.
75
+
76
+ ## Usage
77
+
78
+ ### Overview
79
+ * Use **`writeTextFile`** or **`writeBinaryFile`** to write a file. These all-in-one helpers check out or unlock the file if needed, write it, and add it to VC if it's new. Works whether or not the file already exists.
80
+ * If you need finer control, the steps are also available individually: call **`prepareToWrite`** before writing (checks out / unlocks the file, or no-ops if it doesn't exist yet), then write the file yourself, then call **`finishedWrite`** afterwards (adds the file to VC if it's new).
81
+ * Call **`deleteFile`** or **`deleteFolder`** to remove files. Tracked files will be marked for deletion in the VC system; untracked files are just deleted from disk.
82
+
83
+ You don't need to tell the library which VC system is in use — it detects this automatically. See [VC Detection](#vc-detection) below.
84
+
85
+ ### Operations
86
+
87
+ #### `writeTextFile(filePath, content, encoding)`
88
+ An all-in-one helper that calls `prepareToWrite`, writes `content` as text, then calls `finishedWrite`. Works whether or not the file already exists.
89
+
90
+ - `encoding` defaults to UTF-8 (without BOM).
91
+ - Returns the result from whichever step failed, or the result of `finishedWrite` on success.
92
+
93
+ #### `writeBinaryFile(filePath, data)`
94
+ An all-in-one helper that calls `prepareToWrite`, writes `data` as raw bytes, then calls `finishedWrite`. Works whether or not the file already exists.
95
+
96
+ - Returns the result from whichever step failed, or the result of `finishedWrite` on success.
97
+
98
+ #### `prepareToWrite(filePath)`
99
+ Prepares a file path for writing. Use this when you need to write the file yourself rather than via `writeTextFile` / `writeBinaryFile`.
100
+ - If the file does not yet exist: succeeds immediately (ready to create).
101
+ - If the file exists and is writable: succeeds immediately.
102
+ - If the file exists and is read-only: checks it out (Perforce, Plastic SCM, SVN) or removes the read-only attribute (Git, filesystem).
103
+
104
+ On failure, the `status` field indicates the reason: `locked` means the file is exclusively held by another user; `outOfDate` means the local copy is behind the depot and needs syncing first.
105
+
106
+ #### `finishedWrite(filePath)`
107
+ Notifies the library that a file has been written. Use this after writing the file yourself following a `prepareToWrite` call.
108
+ - If the file is newly created (not yet in VC): adds it (`git add`, `p4 add`, `cm add`, `svn add`).
109
+ - If the file was already tracked: no-op.
110
+
111
+ #### `deleteFile(filePath)`
112
+ Deletes a file, scheduling it for deletion in VC if it is tracked.
113
+
114
+ #### `deleteFolder(folderPath)`
115
+ Deletes a folder and all its contents. Tracked files are scheduled for VC deletion; untracked files are deleted from disk.
116
+
117
+ ### Return Values
118
+ All operations return a result object with three fields:
119
+
120
+ | Field | Type | Description |
121
+ |---|---|---|
122
+ | `success` | `bool` | `true` if the operation succeeded |
123
+ | `status` | string/enum | `ok`, `locked`, `outOfDate`, or `error` |
124
+ | `message` | string | Human-readable detail, especially on failure |
125
+
126
+ `locked` and `outOfDate` are only produced by `prepareToWrite`, for VC systems that support exclusive locking or require syncing before editing.
127
+
128
+ ### VC Detection
129
+ The library detects the active VC system automatically, in this order:
130
+
131
+ 1. **`SIMPLE_VC` environment variable** — set this to `git`, `perforce`, `plastic`, `svn`, or `filesystem` to skip auto-detection entirely.
132
+ 2. **`.vcconfig` file** — a JSON file placed anywhere in the directory tree above the file being operated on:
133
+ ```json
134
+ { "system": "perforce" }
135
+ ```
136
+ 3. **Marker directories** — the library walks up from the file's directory looking for `.git`, `.plastic`, or `.svn`.
137
+ 4. **Perforce** — runs `p4 info` to check whether a Perforce workspace is configured.
138
+ 5. **Filesystem fallback** — if nothing is detected, the library operates on plain files with no VC interaction. Read-only files are still handled by removing the read-only attribute.
139
+
140
+ Detection results are cached by VCS root directory. After the first operation on a file inside a repo, subsequent operations on files in the same repo skip the directory walk entirely. Files outside any known VCS root (for example, writing to a temp directory) are detected independently and will use the filesystem fallback without affecting the cache.
141
+
142
+ ### Overriding VC Detection
143
+ If auto-detection is unreliable in your environment, you can also force a specific provider in code:
144
+
145
+ **Javascript:**
146
+ ```javascript
147
+ import { setProvider, clearProvider, GitProvider } from './simpleVcLib.js';
148
+
149
+ setProvider(new GitProvider()); // Force Git for all operations
150
+ // ...
151
+ clearProvider(); // Restore auto-detection
152
+ ```
153
+
154
+ **C#:**
155
+ ```csharp
156
+ using SimpleVCLib;
157
+
158
+ VCLib.SetProvider(new GitProvider()); // Force Git for all operations
159
+ // ...
160
+ VCLib.ClearProvider(); // Restore auto-detection
161
+ ```
162
+
163
+ Available provider classes: `GitProvider`, `PerforceProvider`, `PlasticProvider`, `SvnProvider`, `FilesystemProvider`.
164
+
165
+ ### Javascript
166
+ Install via npm:
167
+ ```bash
168
+ npm install @wildwinter/simple-vc-lib
169
+ ```
170
+
171
+ Or download `simpleVcLib.js` (ESM) or `simpleVcLib.cjs` (CommonJS) from the [GitHub releases area](https://github.com/wildwinter/simple-vc-lib/releases) and add them directly to your project.
172
+
173
+ ```javascript
174
+ // ESM (npm)
175
+ import { writeTextFile, writeBinaryFile, prepareToWrite, finishedWrite, deleteFile, deleteFolder } from '@wildwinter/simple-vc-lib';
176
+
177
+ // ESM (direct file)
178
+ import { writeTextFile, writeBinaryFile, prepareToWrite, finishedWrite, deleteFile, deleteFolder } from './simpleVcLib.js';
179
+
180
+ // All-in-one helpers (checkout + write + add to VC)
181
+ const result = writeTextFile('/path/to/myfile.json', JSON.stringify(data), 'utf8');
182
+ if (!result.success) {
183
+ console.error(result.message); // e.g. "'myfile.json' is locked by another user"
184
+ process.exit(1);
185
+ }
186
+
187
+ const binResult = writeBinaryFile('/path/to/myfile.bin', buffer);
188
+ if (!binResult.success) {
189
+ console.error(binResult.message);
190
+ }
191
+
192
+ // Manual approach — if you need to write the file yourself
193
+ const prep = prepareToWrite('/path/to/myfile.json');
194
+ if (!prep.success) {
195
+ console.error(prep.message);
196
+ process.exit(1);
197
+ }
198
+ // ... write the file ...
199
+ const add = finishedWrite('/path/to/myfile.json');
200
+ if (!add.success) {
201
+ console.error(add.message);
202
+ }
203
+ ```
204
+
205
+ ```javascript
206
+ // CommonJS (npm)
207
+ const { writeTextFile, writeBinaryFile, prepareToWrite, finishedWrite } = require('@wildwinter/simple-vc-lib');
208
+
209
+ // CommonJS (direct file)
210
+ const { writeTextFile, writeBinaryFile, prepareToWrite, finishedWrite } = require('./simpleVcLib.cjs');
211
+ ```
212
+
213
+ ### C#
214
+ Install via NuGet:
215
+ ```bash
216
+ dotnet add package wildwinter.SimpleVCLib
217
+ ```
218
+
219
+ Or download `SimpleVCLib.dll` from the [GitHub releases area](https://github.com/wildwinter/simple-vc-lib/releases) and add it to your project references directly.
220
+
221
+ ```csharp
222
+ using SimpleVCLib;
223
+
224
+ // All-in-one helpers (checkout + write + add to VC)
225
+ var result = VCLib.WriteTextFile("/path/to/myfile.json", jsonContent);
226
+ if (!result.Success)
227
+ Console.WriteLine(result.Message); // e.g. "'myfile.json' is locked by another user"
228
+
229
+ // With explicit encoding
230
+ var result2 = VCLib.WriteTextFile("/path/to/myfile.txt", text, System.Text.Encoding.Unicode);
231
+ if (!result2.Success)
232
+ Console.WriteLine(result2.Message);
233
+
234
+ var binResult = VCLib.WriteBinaryFile("/path/to/myfile.bin", data);
235
+ if (!binResult.Success)
236
+ Console.WriteLine(binResult.Message);
237
+
238
+ // Manual approach — if you need to write the file yourself
239
+ var prep = VCLib.PrepareToWrite("/path/to/myfile.json");
240
+ if (!prep.Success)
241
+ {
242
+ Console.WriteLine(prep.Message);
243
+ return;
244
+ }
245
+ // ... write the file ...
246
+ var add = VCLib.FinishedWrite("/path/to/myfile.json");
247
+ if (!add.Success)
248
+ Console.WriteLine(add.Message);
249
+
250
+ // Deleting a folder
251
+ var del = VCLib.DeleteFolder("/path/to/old-content/");
252
+ if (!del.Success)
253
+ Console.WriteLine(del.Message);
254
+ ```
255
+
256
+ ## Contributors
257
+ * [wildwinter](https://github.com/wildwinter) - original author
258
+
259
+ ## License
260
+ ```
261
+ MIT License
262
+
263
+ Copyright (c) 2026 Ian Thomas
264
+
265
+ Permission is hereby granted, free of charge, to any person obtaining a copy
266
+ of this software and associated documentation files (the "Software"), to deal
267
+ in the Software without restriction, including without limitation the rights
268
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
269
+ copies of the Software, and to permit persons to whom the Software is
270
+ furnished to do so, subject to the following conditions:
271
+
272
+ The above copyright notice and this permission notice shall be included in all
273
+ copies or substantial portions of the Software.
274
+
275
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
276
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
277
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
278
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
279
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
280
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
281
+ SOFTWARE.
282
+ ```
package/package.json CHANGED
@@ -1,8 +1,16 @@
1
1
  {
2
2
  "name": "@wildwinter/simple-vc-lib",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "An agnostic version control wrapper library for game development tools.",
5
- "keywords": ["version-control", "git", "perforce", "plastic", "svn", "gamedev", "vcs"],
5
+ "keywords": [
6
+ "version-control",
7
+ "git",
8
+ "perforce",
9
+ "plastic",
10
+ "svn",
11
+ "gamedev",
12
+ "vcs"
13
+ ],
6
14
  "license": "MIT",
7
15
  "author": "Ian Thomas",
8
16
  "type": "module",
@@ -24,7 +32,7 @@
24
32
  "build": "npx rollup -c && cp src/index.d.ts dist/simpleVcLib.d.ts && cp ../README.md dist/README.md && cp ../LICENSE dist/LICENSE",
25
33
  "test": "npx mocha",
26
34
  "pack": "npm run build && mkdir -p ../dist/v$npm_package_version && rm -rf ../dist/v$npm_package_version/$npm_package_name-v$npm_package_version.zip && zip -r ../dist/v$npm_package_version/$npm_package_name-v$npm_package_version.zip ./dist",
27
- "publish-npm": "npm run build && npm publish --access public"
35
+ "publish-npm": "npm run build && cp ../README.md ./README.md && cp ../LICENSE ./LICENSE && npm publish --access public; rm -f ./README.md ./LICENSE"
28
36
  },
29
37
  "devDependencies": {
30
38
  "chai": "^5.1.2",