Skip to content

Commit

Permalink
Release v1.1.0 (#26)
Browse files Browse the repository at this point in the history
- import from bin/haraka: copyFile, copyDir, mkDir, createFile
- tests: added for new fns
- add SUNSET 2025 warnings to unused qp functions
  • Loading branch information
msimerson authored Apr 5, 2024
1 parent 50828b4 commit 4f02f9c
Show file tree
Hide file tree
Showing 7 changed files with 178 additions and 33 deletions.
28 changes: 5 additions & 23 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ name: CI

on:
push:
pull_request:

env:
CI: true
Expand All @@ -15,27 +16,8 @@ jobs:
secrets: inherit

test:
needs: lint
runs-on: ${{ matrix.os }}
# services:
# redis:
# image: redis
# ports:
# - 6379:6379
strategy:
matrix:
os: [ ubuntu-latest, windows-latest ]
node-version: [ 14, 16, 18 ]
fail-fast: false
needs: [ lint ]
uses: haraka/.github/.github/workflows/ubuntu.yml@master

steps:
- uses: actions/checkout@v3

- uses: actions/setup-node@v3
name: Node ${{ matrix.node-version }} on ${{ matrix.os }}
with:
node-version: ${{ matrix.node-version }}

- run: npm install

- run: npm test
windows:
uses: haraka/.github/.github/workflows/windows.yml@master
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule ".release"]
path = .release
url = [email protected]:msimerson/.release.git
1 change: 1 addition & 0 deletions .release
Submodule .release added at 954197
10 changes: 10 additions & 0 deletions Changes.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@

### Unreleased

### 1.1.0 - 2024-04-05

- import from bin/haraka: copyFile, copyDir, mkDir, createFile
- add SUNSET 2025 warnings to unused qp functions


### 1.0.3 - 2022-05-27

Expand Down Expand Up @@ -28,3 +35,6 @@

- depend on haraka-eslint
- lint fixes for compat with eslint 4


[1.1.0]: https://github.com/haraka/haraka-utils/releases/tag/1.1.0
105 changes: 103 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
'use strict';

const fs = require('fs')
const path = require('path')

// copied from http://www.broofa.com/Tools/Math.uuid.js
const CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
.split('');
Expand Down Expand Up @@ -103,6 +106,7 @@ ${d.toString().match(/\sGMT([+-]\d+)/)[1]}`;
}

exports.decode_qp = function (line) {
console.warn(`SUNSET: 2025`)
line = line.replace(/\r\n/g,"\n").replace(/[ \t]+\r?\n/g,"\n");
if (! /=/.test(line)) return Buffer.from(line); // maybe a pointless optimisation

Expand All @@ -125,10 +129,12 @@ exports.decode_qp = function (line) {
}

function _char_to_qp (ch) {
_is_printable
return _buf_to_qp(Buffer.from(ch));
}

function _is_printable (charCode) {
console.warn(`SUNSET: 2025`)
switch (charCode) {
case 61: // = (special in encoded words)
return false;
Expand All @@ -142,6 +148,7 @@ function _is_printable (charCode) {
}

function _buf_to_qp (b) {
console.warn(`SUNSET: 2025`)
let r = '';
for (let i=0; i<b.length; i++) {
if (_is_printable(b[i])) {
Expand All @@ -157,6 +164,7 @@ function _buf_to_qp (b) {
// Shameless attempt to copy from Perl's MIME::QuotedPrint::Perl code.
const qpRe = /([^ \t\n!"#$%&'()*+,\-./0-9:;<>?@A-Z[\\\]^_`a-z{|}~])/g;
function asQuotedPrintable (str) {
console.warn(`SUNSET: 2025`)
if (Buffer.isBuffer(str)) return _buf_to_qp(str);

return str
Expand All @@ -167,6 +175,7 @@ function asQuotedPrintable (str) {
// NOTE: deprecated. Haraka now uses 'libqp' instead.
// See https://github.com/haraka/haraka-utils/issues/22
exports.encode_qp = (str) => {
console.warn(`SUNSET: 2025`)
// https://tools.ietf.org/html/rfc2045#section-6.7
str = asQuotedPrintable(str);

Expand Down Expand Up @@ -219,8 +228,8 @@ exports.node_min = function (min, cur) {

for (let i=0; i<=3; i++) {
// note use of unary + for fast type conversion to num
if (+has[i] > +wants[i]) { return true; }
if (+has[i] < +wants[i]) { return false; }
if (+has[i] > +wants[i]) return true;
if (+has[i] < +wants[i]) return false;
}

// they're identical
Expand Down Expand Up @@ -319,3 +328,95 @@ exports.wildcard_to_regexp = function (str) {
}

exports.line_regexp = /^([^\n]*\n)/;

exports.copyDir = function (srcPath, dstPath) {

exports.mkDir(dstPath);

for (const file of fs.readdirSync(srcPath)) {

// Ignore ".*"
if (/^\./.test(file)) continue;

const srcFile = path.join(srcPath, file);
const dstFile = path.join(dstPath, file);

const srcStat = fs.statSync(srcFile);

if (srcStat.isDirectory()) { // if directory
exports.copyDir(srcFile, dstFile); // recurse
}
else if (srcStat.isFile()) { // if file
exports.copyFile(srcFile, dstFile); // copy to dstPath (no overwrite)
}
}
}

exports.copyFile = function (srcFile, dstFile) {

try {
if (fs.statSync(dstFile).isFile()) {
warningMsg(`EEXIST, File exists '${dstFile}'`);
return;
}
throw `EEXIST but not a file: '${dstFile}'`;
}
catch (e) {
// File NOT exists
if (e.code == 'ENOENT') {
exports.mkDir(path.dirname(dstFile));
fs.writeFileSync(dstFile, fs.readFileSync(srcFile));
createMsg(dstFile)
}
else {
console.log(`copy ${srcFile} to ${dstFile}`);
throw e;
}
}
}

exports.createFile = function (filePath, data, info = {}, force=false) {
try {
if (fs.existsSync(filePath) && !force) {
throw `${filePath} already exists`;
}
exports.mkDir(path.dirname(filePath));
const fd = fs.openSync(filePath, 'w');
const output = data.replace(/%(\w+)%/g, function (i, m1) { return info[m1] });
fs.writeSync(fd, output, null);
}
catch (e) {
warningMsg(`Unable to create file: ${e}`);
}
}

function createMsg (dirPath) {
console.log(`\x1b[32mcreate\x1b[0m: ${dirPath}`);
}

function warningMsg (msg) {
console.error(`\x1b[31mwarning\x1b[0m: ${msg}`);
}

exports.mkDir = function (dstPath) {
try {
if (fs.statSync(dstPath).isDirectory()) return;
}
catch (ignore) {}

try {
fs.mkdirSync(dstPath, { recursive: true });
createMsg(dstPath);
}
catch (e) {
// File exists
console.error(e);
if (e.errno == 17) {
warningMsg(e.message);
}
else {
throw e;
}
}
}

13 changes: 6 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
{
"name": "haraka-utils",
"version": "1.0.3",
"version": "1.1.0",
"description": "Haraka general purpose functions",
"main": "index.js",
"files": [],
"directories": {
"test": "test"
},
"scripts": {
"lint": "npx eslint *.js test",
"lintfix": "npx eslint --fix *.js test",
"test": "npx mocha",
"lint": "npx eslint@^8 *.js test",
"lintfix": "npx eslint@^8 --fix *.js test",
"test": "npx mocha@^10",
"versions": "npx dependency-version-checker check"
},
"repository": {
Expand All @@ -28,8 +29,6 @@
},
"homepage": "https://github.com/haraka/haraka-utils#readme",
"devDependencies": {
"eslint": "^8",
"eslint-plugin-haraka": "*",
"mocha": "9"
"eslint-plugin-haraka": "*"
}
}
51 changes: 50 additions & 1 deletion test/utils.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@

const assert = require('assert')
const fs = require('fs')
const path = require('path')

const utils = require('../index')

function cleanup () {
try {
fs.rmSync(path.join('test', 'temp1'), { recursive: true, force: true })
fs.rmSync(path.join('test', 'temp2'), { recursive: true, force: true })
}
catch (e) {
console.log(e.message)
}
}

before(() => { cleanup(); })
after(() => { cleanup(); })

describe('uuid', function () {

it('generates a UUID of 36 characters', function (done) {
Expand Down Expand Up @@ -32,7 +47,7 @@ describe('uniq', function () {
})
})

describe('encode_qp', function () {
describe.skip('encode_qp', function () {
it('plain ascii should not be encoded', function () {
assert.equal(utils.encode_qp('quoted printable'), 'quoted printable');
})
Expand Down Expand Up @@ -389,4 +404,38 @@ describe('indexOfLF', function () {
it('find a LF at the right spot', function () {
assert.equal(utils.indexOfLF(Buffer.from(`in the\neighth`)), 6)
})
})

describe('mkDir', function () {
it('creates a directory', () => {
const tmpPath = path.join('test', 'temp1')
utils.mkDir(tmpPath)
assert.ok(fs.existsSync(tmpPath))
})
})

describe('createFile', function () {
it('creates a file', () => {
const tmpFile = path.join('test', 'temp1', 'file')
utils.createFile(tmpFile, 'contents')
assert.ok(fs.existsSync(tmpFile))
})
})

describe('copyFile', function () {
it('copies a file', () => {
const srcFile = path.join('test', 'temp1', 'file')
const dstFile = path.join('test', 'temp1', 'file2')
utils.copyFile(srcFile, dstFile)
assert.ok(fs.existsSync(dstFile))
})
})

describe('copyDir', function () {
it('copies a directory', () => {
const srcDir = path.join('test', 'temp1')
const dstDir = path.join('test', 'temp2')
utils.copyDir(srcDir, dstDir)
assert.ok(fs.existsSync(dstDir))
})
})

0 comments on commit 4f02f9c

Please sign in to comment.