Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: declaration of sshConfig.find() #55

Merged
merged 1 commit into from
Apr 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:

strategy:
matrix:
node-version: [10.x, 12.x, 14.x]
node-version: [12.x, 14.x, 16.x]

steps:
- uses: actions/checkout@v2
Expand All @@ -22,6 +22,7 @@ jobs:
run: |
npm install
npm run build --if-present
npm run pretest
npm run test:coverage

- name: Codecov
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/npmpublish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: 12
node-version: 16
- run: npm install
- run: npm test

Expand All @@ -22,7 +22,7 @@ jobs:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: 12
node-version: 16
registry-url: https://registry.npmjs.org/
- run: npm install
- run: npm publish
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@ coverage
node_modules
package-lock.json
.nyc_output

test/types/*.js
test/types/*.map
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ language: node_js
node_js:
- "node"
- "lts/*"
- "10"

after_success:
- npm install coveralls
Expand Down
4 changes: 4 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,10 @@ class SSHConfig extends Array {
config.push(node)
config = node.config = new SSHConfig()
}
else if (node.type === DIRECTIVE && !node.param) {
// blank lines at file end
config[config.length - 1].after += node.before
}
else {
config.push(node)
}
Expand Down
10 changes: 7 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,19 @@
"types"
],
"devDependencies": {
"@types/mocha": "^9.1.0",
"@types/node": "^17.0.23",
"eslint": "^7.17.0",
"heredoc": "^1.3.1",
"mocha": "^8.2.1",
"nyc": "^15.1.0"
"nyc": "^15.1.0",
"typescript": "^4.6.3"
},
"scripts": {
"lint": "eslint .",
"test": "mocha --exit",
"test:coverage": "nyc mocha --exit && nyc report --reporter=lcov"
"pretest": "tsc",
"test": "NODE_OPTIONS=--enable-source-maps mocha --exit --recursive",
"test:coverage": "nyc mocha --exit --recursive && nyc report --reporter=lcov"
},
"engine": {
"node": ">= 10.0.0"
Expand Down
49 changes: 49 additions & 0 deletions test/types/ssh-config.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import SSHConfig from '../..'
import { strict as assert } from 'assert'

describe('SSHConfig (TypeScript)', function() {
let config: SSHConfig

beforeEach(function() {
config = SSHConfig.parse(`
IdentityFile ~/.ssh/id_rsa

Host ness
HostName lochness.com
`)
})

it('.find(line => boolean)', function() {
const section = config.find(line => line.type === SSHConfig.DIRECTIVE && line.param === 'Host' && line.value === 'ness')
assert.equal(section.type, SSHConfig.DIRECTIVE)
assert.equal(section.param, 'Host')
assert.equal(section.value, 'ness')
})

it('.find({ Host })', function() {
const section = config.find({ Host: 'ness' })
assert.equal(section.type, SSHConfig.DIRECTIVE)
if ('config' in section) {
assert.deepEqual(SSHConfig.stringify(section.config).trim(), 'HostName lochness.com')
}
})

it('.compute(host)', function() {
const result = config.compute('ness');
console.log(result)
assert.deepEqual(result, {
Host: 'ness',
HostName: 'lochness.com',
IdentityFile: [ '~/.ssh/id_rsa' ],
})
})

it('.stringify(config)', function() {
assert.deepEqual(config.toString(), `
IdentityFile ~/.ssh/id_rsa

Host ness
HostName lochness.com
`)
})
})
2 changes: 1 addition & 1 deletion test/test.glob.js → test/unit/glob.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

const assert = require('assert').strict || require('assert')

const glob = require('../src/glob')
const glob = require('../../src/glob')


describe('glob', function() {
Expand Down
35 changes: 30 additions & 5 deletions test/test.parse.js → test/unit/parse.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ const assert = require('assert').strict || require('assert')
const fs = require('fs')
const heredoc = require('heredoc').strip
const path = require('path')
const SSHConfig = require('..')
const SSHConfig = require('../..')

const { parse, COMMENT, DIRECTIVE } = SSHConfig

function readFile(fpath) {
return fs.readFileSync(path.join(__dirname, fpath), 'utf-8')
.replace(/\r\n/g, '\n')
function readFile(fname) {
const fpath = path.join(__dirname, '..', fname)
return fs.readFileSync(fpath, 'utf-8').replace(/\r\n/g, '\n')
}

describe('parse', function() {
it('.parse simple config', function() {
it('.parse simple config', async function() {
const config = parse(readFile('fixture/config'))

assert.equal(config[0].param, 'ControlMaster')
Expand Down Expand Up @@ -223,4 +223,29 @@ describe('parse', function() {
})
})
})

it('.parse config with extra blank lines', function() {
const config = parse(`
IdentityFile ~/.ssh/id_rsa

Host ness
HostName lochness.com
`)
assert.deepEqual(config.find({ Host: 'ness' }), {
type: 1,
param: 'Host',
separator: ' ',
value: 'ness',
before: ' ',
after: '\n',
config: new SSHConfig({
type: 1,
param: 'HostName',
separator: ' ',
value: 'lochness.com',
before: ' ',
after: '\n '
})
})
})
})
18 changes: 9 additions & 9 deletions test/test.ssh-config.js → test/unit/ssh-config.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ const fs = require('fs')
const path = require('path')
const heredoc = require('heredoc').strip

const SSHConfig = require('..')
const SSHConfig = require('../..')

const { DIRECTIVE } = SSHConfig

function readFile(fpath) {
return fs.readFileSync(path.join(__dirname, fpath), 'utf-8')
.replace(/\r\n/g, '\n')
function readFile(fname) {
const fpath = path.join(__dirname, '..', fname)
return fs.readFileSync(fpath, 'utf-8').replace(/\r\n/g, '\n')
}

describe('SSHConfig', function() {
it('.compute by Host', function() {
it('.compute by Host', async function() {
const config = SSHConfig.parse(readFile('fixture/config'))
const opts = config.compute('tahoe2')

Expand Down Expand Up @@ -91,18 +91,18 @@ describe('SSHConfig', function() {
}
})

it('.find with nothing shall yield error', function() {
it('.find with nothing shall yield error', async function() {
const config = SSHConfig.parse(readFile('fixture/config'))
assert.throws(function() { config.find() })
assert.throws(function() { config.find({}) })
})

it('.find shall return null if nothing were found', function() {
it('.find shall return null if nothing were found', async function() {
const config = SSHConfig.parse(readFile('fixture/config'))
assert(config.find({ Host: 'not.exist' }) == null)
})

it('.find by Host', function() {
it('.find by Host', async function() {
const config = SSHConfig.parse(readFile('fixture/config'))

assert.deepEqual(config.find({ Host: 'tahoe1' }), {
Expand Down Expand Up @@ -147,7 +147,7 @@ describe('SSHConfig', function() {
})
})

it('.remove by Host', function() {
it('.remove by Host', async function() {
const config = SSHConfig.parse(readFile('fixture/config'))
const length = config.length

Expand Down
10 changes: 5 additions & 5 deletions test/test.stringify.js → test/unit/stringify.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ const assert = require('assert').strict || require('assert')
const fs = require('fs')
const heredoc = require('heredoc').strip
const path = require('path')
const SSHConfig = require('..')
const SSHConfig = require('../..')
const { parse, stringify } = SSHConfig

function readFile(fpath) {
return fs.readFileSync(path.join(__dirname, fpath), 'utf-8')
.replace(/\r\n/g, '\n')
function readFile(fname) {
const fpath = path.join(__dirname, '..', fname)
return fs.readFileSync(fpath, 'utf-8').replace(/\r\n/g, '\n')
}

describe('stringify', function() {
it('.stringify the parsed object back to string', function() {
it('.stringify the parsed object back to string', async function() {
const fixture = readFile('fixture/config')
const config = parse(fixture)
assert.equal(fixture, stringify(config))
Expand Down
11 changes: 11 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"compilerOptions": {
"target": "es2018",
"moduleResolution": "Node",
"module": "CommonJS",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"esModuleInterop": true,
"sourceMap": true
}
}
21 changes: 13 additions & 8 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,34 @@ interface Directive {
}

interface Section extends Directive {
config: SSHConfig;
config: SSHConfig<Line>;
}

interface Comment {
type: ELine.COMMENT;
content: string;
}

type Line = Directive | Comment;
type Line = Section | Directive | Comment;

export default class SSHConfig extends Array {
static parse(text: string): SSHConfig;
static stringify(config: SSHConfig): string;
declare class SSHConfig<T> extends Array<T> {
static parse(text: string): SSHConfig<Line>;
static stringify(config: SSHConfig<Line>): string;

static DIRECTIVE: ELine.DIRECTIVE;
static COMMENT: ELine.COMMENT;

toString(): string;

compute(host: string): Record<string, string>;

find(predicate: (value: any, index: number, obj: any[]) => any);
find<T>(this: SSHConfig<T>, predicate: (line: T, index: number, config: T[]) => boolean): T;
find(options: Record<string, string>): Line | Section;

remove(options: Record<string, string>): Line | Section;

append(options: Record<string, string>): SSHConfig;
prepend(options: Record<string, string>): SSHConfig;
append(options: Record<string, string>): SSHConfig<Line>;
prepend(options: Record<string, string>): SSHConfig<Line>;
}

export default class extends SSHConfig<Line> {}
10 changes: 0 additions & 10 deletions types/ssh-config-tests.ts

This file was deleted.