Skip to content

Commit

Permalink
Update readme
Browse files Browse the repository at this point in the history
  • Loading branch information
debagger committed Apr 4, 2021
1 parent 7556bd7 commit 09cb890
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 114 deletions.
140 changes: 129 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ npm install fstb --save

## Usage
### Work with pathes
You can create path to filesystem object using the FSPath function.
Most basics way to use FSTB power start from create path to filesystem object using the FSPath function.
It can be chained with any key name wich act as path segment.

Example:
Expand All @@ -25,23 +25,141 @@ FSPath(__dirname)["package.json"] //work as path.join(__dirname, "package.json")
FSPath(__dirname)["node_modules"]["fstb"]["package.json"]
```

### Work with file system objects
When path completed, you can get further operation to call it as function.
### Special directories shortcuts
In many cases, you may need to work with special operating system directories.
To do this, you can use a number of shortcuts that will make your code shorter and clearer.

* `cwd` is shortcut to `FSPath(process.cwd())`
* `dirname` is shortcut to `FSPath(__dirname)`
* `home` is shortcut to `FSPath(os.homedir())`
* `tmp` is shortcut to `FSPath(os.tmpdir())`

### Get path from environment variables
You often need to get different paths for the development, staging, and production environment.
In such cases, it is common practice to store these paths in environment variables.
To support this use case, FSTB provides the `envPath` method.

```js
const { envPath } = require('fstb');
const { join } = require('path');

//Throws if no APP_DATA_DIR environment variable was found
const data_path = envPath("APP_DATA_DIR")

////If no APP_DATA_DIR environment variable was found, it fallback to assets/images in work directory
const images_path = envPath("APP_IMAGES_PATH", join(process.cwd(), "assets/images"))
```

### Make temporary directory

Sometimes you need to work with temporary files in your project.
Good practice for this case to do it in OS default temp dir.
`mkdtemp` method creates temporary subdir with random name in OS temp directory.

```js
const { mkdtemp } = require('fstb');
//creates temporary directory with 'fstb-' prefix
mkdtemp("fstb-").then(tempdir => {
console.log(tempdir.path)
//Output: C:\Users\user\AppData\Local\Temp\fstb-YBqC2b - for Windows
})
```

### Work with filesystem objects

This is a tricky point to understand about the essence of FSPath.
On the one hand, FSPath accepts a property or key with any name and returns a new FSPath, the closure of which contains the specified path. On the other hand, since it is a function, its call returns an object of type FSDirent.
Thanks to this, we can construct a path by adding segment after segment, and when the path formation is complete, we just need to call the resulting function to continue working with all features of the FSTB library.

Example:
```js
FSPath(__dirname).node_modules().asDir()
FSPath(__dirname)["package.json"]().asFile()
const root = FSPath(__dirname); //Now root is function which closure __dirname path

//We can chain root path by any property or key
const node_modules_path = root.node_modules
const package_json_path = root["package.json"]

//node_modules_path and package_json_path is function and we can call it.

const node_modules_dir = node_modules_path().asDir() //now node_modules_dir is FSDir object for node_modules directory
const package_json_file = package_json_path().asFile() //and package_json_file is FSFile object for package.json file

//Before this point we didn't interact with filesystem. And now we do.

//iterate node_module subdirs and print names to console
node_modules_dir.subdirs().forEach(async subdir => console.log(subdir.name))

//print package.json content to console
package_json_file.read.txt().then(content => console.log(content))
```

## Work with directories

All specific methods for interacts with directories contains in `FSDir` class.
Here is table of it:

Method name | Description
----------- | -----------
`dirents()` | Iterates thru all directory contents
`files()` | Iterates thru files in directory
`subdirs(recursive: boolean = false)` | Iterates thru subdirectories in directory. Can iterates all subdirectories tree by set to `true` optional parameter.
`rmdir()` | Removes directory if its empty
`mkdir(recursive: boolean = false)` | Creates directory. If `recursive` is true it can create all parent dirs wich not exists.
`isExists()` | Check if directory exist
`totalSize()` | Calculates the size of the entire directory content in bytes
`rimraf()` | Removes directory with all content
`copyTo(targetDir: FSDir)` | Copy directory with all content into target directory


Also `FSDir` has some useful fields:

Field name | Description
---------- | -----------
`path` | The full path for this directory
`name` | Name of this directory
`fspath` | FSPath function to construct child pathes from this directory

### Example: mkdtemp, copyTo, totalSize, rimraf usage
```js
const { cwd, mkdtemp } = require('fstb');

(async function() {
// Create temp dir
const tempdir = await mkdtemp('FSTB_Example_');
// Get node_modules directory
const node_modules = cwd.node_modules().asDir();

console.log('Copy node_modules to temporary directory');
const temp_node_modules = await node_modules.copyTo(tempdir);

console.log('Calc node_modules size');
console.log('node_modules size = ', await node_modules.totalSize());

console.log('Calc temporary node_modules size');
console.log('temporary node_modules size = ', await temp_node_modules.totalSize());

console.log('Remove temporary node_modules directory');
await tempdir.rimraf();
})();

```
### Example: files, subdirs
```js
const { cwd } = require('./dist/index');

### Special directories shortcuts
(async function() {
const node_modules = cwd.node_modules().asDir();

const calcJSSize = async dir =>
await dir
.files()
.filter(async file => file.name.toLowerCase().endsWith('.js'))
.reduce(async (acc, file) => acc + (await file.stat()).size, 0);

* `cwd` is shortcut to `FSPath(process.cwd())`
* `dirname` is shortcut to `FSPath(__dirname)`
* `home` is shortcut to `FSPath(os.homedir())`
* `tmp` is shortcut to `FSPath(os.tmpdir())`
... will be continued
console.log('.js files size = ', await node_modules.subdirs(true).reduce(async (acc, dir) => acc + (await calcJSSize(dir)), 0));
})();

```

## More examples

Expand Down
111 changes: 9 additions & 102 deletions example.js
Original file line number Diff line number Diff line change
@@ -1,106 +1,13 @@
const { cwd, range } = require('./dist/index');
const { once } = require('events');
const { resolve, join } = require('path');
const fs = require('fs');
const rl = require('readline');
const { cwd } = require('./dist/index');

(async function() {
const sleep = time => new Promise(resolve => setTimeout(resolve, time));
try {
await range(1, 10)
.map(async i => {
await sleep(1000/i);
return i;
}, 10)
.filter(async i => {
return i % 2;
}, 5)
.forEach(async i => {
await sleep(100);
// if(i > 8) throw Error("Its > 8");
console.log(i);
}, 2);
} catch (error) {
console.log('Catch ' + error.message);
}
// const stream = cwd['hashlist.csv']()
// .asFile()
// .write.createWriteStream({ autoClose: true });
// stream.write('hash,path\n');
// await cwd
// .node_modules()
// .asDir()
// .subdirs(true)
// .forEach(async dir => {
// dir.files().forEach(async file => {
// stream.write(`${await file.hash.md5()},${file.path}\n`);
// });
// });
})();

// cwd["README.md"]().asFile().read.lineByLine().forEach(line=>console.log(line));

// const wstream = cwd['test.csv']()
// .asFile()
// .write.createWriteStream({ autoClose: true });
// console.log("Write...")
// console.time("write time")
// wstream.write('index,field1,field2,field3,field4,field5\n');
// for (let index = 0; index < 100_000_000; index++) {
// const chunk = `${index},field1index${index},field2index${index},field3index${index},field4index${index},field5index${index}\n`;
// if (!wstream.write(chunk)) {
// // (B)
// // Handle backpressure
// await once(wstream, 'drain');
// }
// }
// wstream.close();
// console.timeEnd("write time")
const node_modules = cwd.node_modules().asDir();

// console.log("Read...")
// console.time("Read time")
// await cwd['test.csv']()
// .asFile()
// .read.csvWithHeader(',')
// .filter(item => Number.parseInt(item.index) > 99_999_990)
// .forEach(item => console.log(item));
// console.timeEnd("Read time")
// })
const calcJSSize = async dir =>
await dir
.files()
.filter(async file => file.name.toLowerCase().endsWith('.js'))
.reduce(async (acc, file) => acc + (await file.stat()).size, 0);

// console.log('Reading...');
// console.time('Reading time');
// const csvpath = join(process.cwd(), 'test.csv');
// const stream = fs.createReadStream(csvpath, { autoClose: true });
// const readline = rl.createInterface({ input: stream, crlfDelay: Infinity });
// let firstline;
// readline.on('line', input => {
// const splitted = input.split(',');
// if (firstline) {
// const obj = firstline.reduce((prev, cur, ix) => {
// prev[cur] = splitted[ix];
// return prev;
// }, {});

// if (Number.parseInt(obj.index) > 99_999_990) {
// console.log(obj);
// }
// } else {
// firstline = splitted;
// }
// });
// readline.on('close', () => {
// console.timeEnd('Reading time');
// });
// console.log(
// 'Total size of node_modules is ' +
// Math.floor(
// (await cwd
// .node_modules()
// .asDir()
// .totalSize()) /
// 1024 /
// 1024
// ) +
// ' MBytes'
// );
// });
console.log('.js files size = ', await node_modules.subdirs(true).reduce(async (acc, dir) => acc + (await calcJSSize(dir)), 0));
})();
2 changes: 1 addition & 1 deletion src/fs-dir.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export class FSDir {
* operators available. toArray operator can be used for resulting chain to array.
* @param recursive - if true returns each subdir of any deep
* @returns {FSAsyncIterable}
* @example <caption>Extratct all module names and versions from code>node_modules</caption>
* @example <caption>Extratct all module names and versions from node_modules</caption>
* const { cwd } = require('fstb');
* cwd
* .node_modules()
Expand Down

0 comments on commit 09cb890

Please sign in to comment.