Skip to content

Commit

Permalink
fix: Support for -slt switch #97
Browse files Browse the repository at this point in the history
  • Loading branch information
quentinrossetti committed Jul 11, 2021
1 parent ac91cd7 commit 411d5cb
Show file tree
Hide file tree
Showing 13 changed files with 221 additions and 5 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,16 @@ mySevenStream.on('data', function (data) {
// status: 'renamed|tested|updated|skipped|deleted|extracted',
// attributes: '....A', size: 9, sizeCompressed: 3, (only list command)
// hash: 'FEDC304F', size: 9 (only hash command)
// techInfo: Map(8) { (only list command with `techInfo` switch)
// 'Path' => 'DirHex/sub2/e825776890f2b',
// 'Size' => '9',
// 'Modified' => '2018-09-29 09:06:15',
// 'Attributes' => 'A_ -rw-r--r--',
// 'CRC' => 'FEDC304F',
// 'Encrypted' => '-',
// 'Method' => 'LZMA2:12',
// 'Block' => '0'
// }
// }
})
```
Expand Down
1 change: 1 addition & 0 deletions TODO
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Features:
✔ Full-named switches for cleaner API @done(18-11-04 19:54)
✔ Stream methods returns stream @done(18-10-17 20:35)
✔ Esier to use progress @done(18-12-02 12:31)
✔ Add support for `-slt` Show Technical Infos @started(21-05-19 19:37) @done(21-07-11 19:20) @lasted(7w3d23h43m21s)
Documentation:
✔ Status (TU+R. and others?) as plain text @done(18-12-04 22:50)
✔ Usage for wildcard/raw/bin input ($ instead of _ preffix) @done(18-12-04 22:50)
Expand Down
3 changes: 3 additions & 0 deletions src/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ const extractFactory = ({ main, command }) => (archive, output, options = {}) =>
const simplexFactory = ({ main, command }) => (target, options = {}) => {
const { ..._options } = options
_options._command = command
if (options.techInfo) {
_options._command = 'listTechInfo'
}
_options._target = [target, options.$cherryPick]
return main(_options)
}
Expand Down
2 changes: 1 addition & 1 deletion src/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const onStdoutFactory = ({ Lines, Maybe }) => (stream, chunk) => {
continue // at next line
}

// End of HEADERS can be easy to detect with list and hash commands that
// End of HEADERS can be easy to detected with list and hash commands that
// outputs a `---- -- ----` line, but in symbol commands the end of HEADERS
// can only be detected when the line match a BODY data: In such cases the
// loop has to continue in order to properly porcess the BODY data.
Expand Down
61 changes: 58 additions & 3 deletions src/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

const normalizePath = require('normalize-path')
const { INFOS, BODY_PROGRESS, BODY_SYMBOL_FILE, BODY_HASH, INFOS_SPLIT, END_OF_STAGE_HYPHEN } = require('./regexp')
const { INFOS, BODY_PROGRESS, BODY_SYMBOL_FILE, BODY_HASH, INFOS_SPLIT, INFOS_PATH, END_OF_STAGE_HYPHEN, END_OF_TECH_INFOS_HEADERS } = require('./regexp')
const { SYMBOL_OPERATIONS } = require('./references')

// Infos about the opertation are given by 7z on the stdout. They can be:
Expand Down Expand Up @@ -58,9 +58,16 @@ function matchEndOfHeadersHyphen (stream, line) {
.map(getSpacesPosition)
.filter(Number.isInteger)
return line
} else {
return null
}
return null
}

function matchEndOfHeadersTechInfo (stream, line) {
const isEnd = END_OF_TECH_INFOS_HEADERS.test(line)
if (isEnd) {
return line
}
return null
}

// Progress as a percentage is only displayed to stdout when the `-bsp1` switch
Expand Down Expand Up @@ -146,6 +153,46 @@ function matchBodyHash (stream, line) {
return null
}

// List command with -slt switch. This commands outputs multiples lines per
// file. E.g.:
// Path = DirImages/LICENSE
// Size = 37
// Packed Size = 18292718
// Modified = 2018-10-02 21:45:49
// Attributes = A_ -rw-r--r--
// CRC = F303F60C
// Encrypted = -
// Method = LZMA2:24
// Block = 0
// *Path* is the first and *Block* is the last so we use that to mark the end
// of data. The end of the output is marked by 2 empty lines
function matchBodyTechInfo (stream, line) {
if (!stream._lastLines) {
stream._lastLines = ['', '']
}
stream._lastLines[1] = stream._lastLines[0]
stream._lastLines[0] = line

if (isEmpty(line)) {
if (isEmpty(stream._lastLines[1])) {
return null
}
return {
file: stream._lastTechInfo.get('Path'),
techInfo: stream._lastTechInfo
}
}
const match = line.match(INFOS)
if (match) {
if (match.groups.property === 'Path') {
stream._lastTechInfo = new Map()
match.groups.value = normalizePath(match.groups.value)
}
stream._lastTechInfo.set(match.groups.property, match.groups.value)
}
return null
}

// This function determines if the end of the body section has been reached,
// an empty line is emited by 7z at the end of the body, so this function
// use this as an indicator.
Expand Down Expand Up @@ -218,6 +265,12 @@ const fetch = (command, parser) => {
endOfBody: matchEndOfHeadersHyphen,
dataType: 'table'
},
listTechInfo: {
bodyData: matchBodyTechInfo,
endOfHeaders: matchEndOfHeadersTechInfo,
endOfBody: matchEndOfHeadersHyphen,
dataType: 'showTechInfo'
},
rename: {
bodyData: matchBodySymbol,
endOfHeaders: matchEndOfHeadersSymbol,
Expand All @@ -244,10 +297,12 @@ module.exports = {
matchInfos,
matchEndOfHeadersSymbol,
matchEndOfHeadersHyphen,
matchEndOfHeadersTechInfo,
matchProgress,
matchBodySymbol,
matchBodyList,
matchBodyHash,
matchBodyTechInfo,
matchEndOfBodySymbol,
fetch
}
1 change: 1 addition & 0 deletions src/references.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ const COMMAND_LETTERS = {
extractFull: 'x',
hash: 'h',
list: 'l',
listTechInfo: 'l',
rename: 'rn',
test: 't',
update: 'u'
Expand Down
4 changes: 4 additions & 0 deletions src/regexp.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ const BODY_PROGRESS = new RegExp('^ *(?<percent>\\d+)% ?(?<fileCount>\\d+)? ?(?<
const BODY_SYMBOL_FILE = new RegExp('^(?<symbol>[=TU+R.-]) (?<file>.+)$')
const BODY_HASH = new RegExp('^(?<hash>\\S+)? +(?<size>\\d*) +(?<file>.+)$')
const END_OF_STAGE_HYPHEN = new RegExp('^(-+ +)+-+$')
const END_OF_TECH_INFOS_HEADERS = new RegExp('^----------$')
const INFOS = new RegExp('^(?<property>.+?)(?<separator>( = )|(: +))(?<value>.+)$')
const INFOS_PATH = new RegExp('^Path = (?<path>.+)$')
const INFOS_SPLIT = new RegExp(', +# ')
const ERROR = new RegExp('(?<level>WARNING|ERROR): (?<message>.*)(\r\n)?(\n)?', 'i')

Expand All @@ -27,7 +29,9 @@ module.exports = {
BODY_SYMBOL_FILE,
BODY_HASH,
END_OF_STAGE_HYPHEN,
END_OF_TECH_INFOS_HEADERS,
INFOS,
INFOS_PATH,
INFOS_SPLIT,
ERROR
}
Empty file modified test/_mock/Binaries/7z-darwin
100755 → 100644
Empty file.
Empty file modified test/_mock/Binaries/7z-linux
100755 → 100644
Empty file.
Binary file added test/_mock/DirNew/NewArchive.zip
Binary file not shown.
60 changes: 60 additions & 0 deletions test/func/list.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,64 @@ describe('Functional: list()', function () {
done()
})
})

it('should list technical data', function (done) {
const archiveBase = `${mockDir}/DirNew/NewArchive.7z`
const archive = `${tmpDir}/list-slt.7z`
copyFileSync(archiveBase, archive)
let technical_data = []
let integrity_test = false
const seven = list(archive,
{ techInfo: true }
)
seven.on('data', function (data) {
technical_data.push(data)
expect(data.file).to.be.a('string')
if (data.file === 'DirHex/sub2/f930abffa355e') {
expect(data.techInfo.get('Path')).to.equal('DirHex/sub2/f930abffa355e')
expect(data.techInfo.get('Size')).to.equal('9')
expect(data.techInfo.get('Modified')).to.equal('2018-09-29 09:06:15')
expect(data.techInfo.get('CRC')).to.equal('FEDC304F')
expect(data.techInfo.get('Encrypted')).to.equal('-')
expect(data.techInfo.get('Method')).to.equal('LZMA2:12')
expect(data.techInfo.get('Block')).to.equal('0')
integrity_test = true
}
}).on('end', function () {
expect(seven.info.get('Blocks')).to.equal('1')
expect(technical_data.length).to.equal(30)
expect(integrity_test).to.equal(true)
done()
})
})

it('should list technical data of zip archives', function (done) {
const archiveBase = `${mockDir}/DirNew/NewArchive.zip`
const archive = `${tmpDir}/list-slt.zip`
copyFileSync(archiveBase, archive)
let technical_data = []
let integrity_test = false
const seven = list(archive,
{ techInfo: true }
)
seven.on('data', function (data) {
technical_data.push(data)
expect(data.file).to.be.a('string')
if (data.file === 'DirHex/sub2/f930abffa355e') {
expect(data.techInfo.get('Path')).to.equal('DirHex/sub2/f930abffa355e')
expect(data.techInfo.get('Size')).to.equal('9')
expect(data.techInfo.get('Modified')).to.equal('2018-09-29 09:06:15')
expect(data.techInfo.get('CRC')).to.equal('FEDC304F')
expect(data.techInfo.get('Encrypted')).to.equal('-')
expect(data.techInfo.get('Method')).to.equal('Store')
expect(data.techInfo.get('Offset')).to.equal('1698')
integrity_test = true
}
}).on('end', function () {
expect(seven.info.get('Type')).to.equal('zip')
expect(technical_data.length).to.equal(30)
expect(integrity_test).to.equal(true)
done()
})
})
})
10 changes: 10 additions & 0 deletions test/unit/commands.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,15 @@ describe('Unit: commands.js', function () {
expect(res._command).to.eql('azerty')
expect(res._target).to.deep.eql(['archive', 'cherry'])
})

it('changes command to listTechInfo when specified', function () {
const simplex = Commands.simplexFactory({
main: identityFunction,
command: 'azerty'
})
const res = simplex('archive', { techInfo: true })
expect(res._command).to.eql('listTechInfo')
})

})
})
74 changes: 73 additions & 1 deletion test/unit/parser.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ import { expect } from 'chai'
import {
fetch,
matchProgress,
matchEndOfHeadersHyphen,
matchEndOfHeadersTechInfo,
matchBodySymbol,
matchBodyHash,
matchEndOfHeadersHyphen,
matchBodyTechInfo,
matchInfos,
matchEndOfHeadersSymbol,
matchEndOfBodySymbol,
Expand Down Expand Up @@ -150,6 +152,25 @@ describe('Unit: parser.js', function () {
})
})

describe('matchEndOfHeadersTechInfo()', function () {
it('should return null on non match', function () {
const r = matchEndOfHeadersTechInfo({}, 'Colon info: type colon info')
expect(r).to.equal(null)
})

it('should return null on pseudo-empty line', function () {
const r = matchEndOfHeadersTechInfo({}, ' ')
expect(r).to.be.equal(null)
})

it('should be truthly on match of hyphens', function () {
const r = matchEndOfHeadersTechInfo({}, '----------')
let pass = false
if (r) pass = true
expect(pass).to.be.equal(true)
})
})

describe('matchProgress()', function () {
it('should return null on non match', function () {
const r = matchProgress({}, 'Colon info: type colon info')
Expand Down Expand Up @@ -367,6 +388,57 @@ describe('Unit: parser.js', function () {
})
})

describe('matchBodyTechInfo()', function () {
it('should return null on non match', function () {
const r = matchBodyTechInfo({}, '----')
expect(r).to.be.equal(null)
})

it('should return null on pseudo empty line', function () {
const r = matchBodyTechInfo({}, ' ')
expect(r).to.be.equal(null)
})

it('should create a new map on Path info', function () {
let stream = {}
matchBodyTechInfo(stream, 'Path = DirImages/LICENSE')
expect(stream._lastTechInfo).to.be.an.instanceof(Map)
})

it('should add info to the Map', function () {
let techInfo = new Map()
let stream = { _lastTechInfo: techInfo }
stream._lastTechInfo.set('Path', 'DirImages/LICENSE')
matchBodyTechInfo(stream, 'CRC = F303F60C')
expect(stream._lastTechInfo.get('CRC')).to.equal('F303F60C')
})

it('should return techInfo on empty line', function () {
let techInfo = new Map()
let stream = { _lastTechInfo: techInfo }
matchBodyTechInfo(stream, 'Path = DirImages/LICENSE')
matchBodyTechInfo(stream, 'CRC = F303F60C')
const r = matchBodyTechInfo(stream, '')
expect(r.file).to.equal('DirImages/LICENSE')
expect(r.techInfo.get('Path')).to.equal('DirImages/LICENSE')
expect(r.techInfo.get('CRC')).to.equal('F303F60C')
})

it('should return file on Windows drive', function () {
let techInfo = new Map()
let stream = { _lastTechInfo: techInfo }
matchBodyTechInfo(stream, 'Path = C:\\test\\file')
expect(stream._lastTechInfo.get('Path')).to.equal('C:/test/file')
})

it('should return file on Windows remote', function () {
let techInfo = new Map()
let stream = { _lastTechInfo: techInfo }
matchBodyTechInfo(stream, 'Path = \\test\\file')
expect(stream._lastTechInfo.get('Path')).to.equal('/test/file')
})
})

describe('matchEndOfBodySymbol()', function () {
const baseStream = { _matchBody: matchBodySymbol }

Expand Down

0 comments on commit 411d5cb

Please sign in to comment.