import { extname } from 'path' ; import { promises as fs } from 'fs' ; import { BaseTask , Task , TaskContext , trimCwd } from '@checkup/core' ; import { Result } from 'sarif' ; const sloc = require ( 'sloc' ) ; const FILE_EXTENSIONS_SUPPORTED = new Set ( sloc . extensions ) ; export default class LinesOfCodeTask extends BaseTask implements Task { taskName = 'lines-of-code' ; taskDisplayName = 'Lines Of Code' ; description = 'Counts lines of code within a project' ; category = 'info' ; constructor ( pluginName , context ) { super ( pluginName , context ) ; this . addRule ( { properties : { component : { name : 'table' , options : { sumBy : { findGroupBy : 'Language' , sumValueBy : 'Total Lines' , } , rows : { Language : 'properties.extension' , 'Total Lines' : 'properties.lines' , } , } , } , } , } ) ; } async run ( ) { let fileInfos = await this . getLinesOfCode ( ) ; fileInfos . forEach ( ( fileInfo ) => { this . addResult ( `Lines of code count for ${ fileInfo . filePath } - total lines: ${ fileInfo . lines }` , 'informational' , 'note' , { location : { uri : fileInfo . filePath , } , properties : Object . assign ( { } , fileInfo ) , } ) ; } ) ; return this . results ; } async getLinesOfCode ( ) { let fileInfos = [ ] ; await Promise . all ( this . context . paths . filter ( ( filePath ) => { let extension = getExtension ( filePath ) ; return FILE_EXTENSIONS_SUPPORTED . has ( extension ) ; } ) . map ( async ( filePath ) => { const contents = await fs . readFile ( filePath , 'utf8' ) ; let extension = getExtension ( filePath ) ; let { total } = sloc ( contents , extension ) ; fileInfos . push ( { filePath : trimCwd ( filePath , this . context . options . cwd ) , extension , lines : total , } ) ; } ) ) ; return fileInfos ; } } function getExtension ( filePath ) { return extname ( filePath ) . replace ( '.' , '' ) ; }