<|start_filename|>src/language_ids.js<|end_filename|>
const LanguageIds = {
    dockerfile: "dockerfile"
}

module.exports = {
    LanguageIds
};

<|start_filename|>src/extension.js<|end_filename|>
const vscode = require('vscode');
const dockerfile_validator = require("./dockerfile_validator")
const configs = require("./dockerfile_validator_configs")

function activate(context) {
    console.log('dockerfile-validator has been activated.');

    var dockerfileValidator = new dockerfile_validator.DockerfileValidator(vscode.window, vscode.workspace, configs.DockerfileValidatorConfigs.getRuleFilePath(), context.subscriptions);
    
    var dockerfileValidatorConfigs = new configs.DockerfileValidatorConfigs();
    dockerfileValidatorConfigs.subscribeToRuleFilePathConfigChange(dockerfileValidator);
    
    context.subscriptions.push(dockerfileValidator);
    context.subscriptions.push(dockerfileValidatorConfigs);
}
exports.activate = activate;



function deactivate() {
}
exports.deactivate = deactivate;

<|start_filename|>src/diagnostic_creator.js<|end_filename|>
const vscode = require('vscode');
const DockerfileValidatorSeverity = require('./dockerfile_validator_severity').DockerfileValidatorSeverity;

class DiagnosticsCreator{
    static CreateDiagnostics(dockerfile, dockerfileValidation){
        
        var result = [];

        if(dockerfileValidation.error){
            result = result.concat(this.CreateDiagnosticsForSeverity(dockerfile, dockerfileValidation.error, DockerfileValidatorSeverity.Error));
        }
        
        if(dockerfileValidation.warn){
            result = result.concat(this.CreateDiagnosticsForSeverity(dockerfile, dockerfileValidation.warn, DockerfileValidatorSeverity.Warning));
        }
        
        if(dockerfileValidation.info){
            result = result.concat(this.CreateDiagnosticsForSeverity(dockerfile, dockerfileValidation.info, DockerfileValidatorSeverity.Information));
        }

        return result;
    }

    static CreateDiagnosticsForSeverity(dockerfile, validation, severity){
        var result = [];
        validation.data.forEach(validationLine => {
            var range = (validationLine.line||-1)===-1? new vscode.Range(dockerfile.lineCount,0,dockerfile.lineCount,5): dockerfile.lineAt(validationLine.line-1).range;
            var diagnostic = new vscode.Diagnostic(range,"[dockerfile-validator] " + validationLine.message + ((validationLine.lineContent||"") === "" ? "" : ": \"" + validationLine.lineContent + "\"") + "\n\t" + (Array.isArray(validationLine.reference_url)?validationLine.reference_url.join(""):validationLine.reference_url), this.DockerfileSeverityToDiagnosticsSeverity(severity));
            result.push(diagnostic);
        });
        return result;
    }

    static DockerfileSeverityToDiagnosticsSeverity(severity){
        var result;

        switch(severity){
            case DockerfileValidatorSeverity.Error:
                result = vscode.DiagnosticSeverity.Error;
                break;
            case DockerfileValidatorSeverity.Warning:
                result = vscode.DiagnosticSeverity.Warning;
                break;
            case DockerfileValidatorSeverity.Information:
                result = vscode.DiagnosticSeverity.Information;
                break;
            default:
                throw new Error(`Invalid Dockerfile Validator severity: '${severity}'`);
        }

        return result;
    }
}

module.exports = {
    DiagnosticsCreator
};

<|start_filename|>src/dockerfile_validator_severity.js<|end_filename|>
const DockerfileValidatorSeverity = {
    Information : 1,
    Warning : 2,
    Error : 3
};

module.exports = {
    DockerfileValidatorSeverity
};

<|start_filename|>src/dockerfile_validator.js<|end_filename|>
const DockerFileValidator = require('dockerfile_lint');
const vscode = require('vscode');
const LanguageIds = require('./language_ids').LanguageIds;
const DiagnosticsCreator = require('./diagnostic_creator').DiagnosticsCreator;

class DockerfileValidator extends vscode.Disposable { 

    constructor(window, workspace, rulefilePath, subscriptions){
        super(() => this.dispose());
        this.rulefilePath = rulefilePath;
        var disposables = [];
        this.window = window;
        this.diagnosticsCollection = vscode.languages.createDiagnosticCollection();
        disposables.push(this.window.onDidChangeTextEditorSelection(this.event,this, subscriptions));
        disposables.push(workspace.onDidOpenTextDocument(this.event, this, subscriptions));
        disposables.push(this.diagnosticsCollection);
        this.disposable = vscode.Disposable.from(disposables);
    }

    event(){
        if(this.window.activeTextEditor.document.languageId === LanguageIds.dockerfile)
        {
            var dockerfile = this.window.activeTextEditor.document;
            var dockerfileContents = dockerfile.getText().replace(/\r\n/g, "\n");
            var validation = this.validate(dockerfileContents);
            var diagnostics = DiagnosticsCreator.CreateDiagnostics(dockerfile, validation);
            this.diagnosticsCollection.set(dockerfile.uri, diagnostics);
        }
    }

    validate(dockerfileContents){
        try {
            var validator = new DockerFileValidator(this.rulefilePath);
        } catch (error) {
        }
        var result = validator.validate(dockerfileContents);
        return result;
    }

    dispose(){
		this.diagnosticsCollection.clear();
		this.disposable.dispose();
    }
}

module.exports = {
    DockerfileValidator
};

<|start_filename|>src/dockerfile_validator_configs.js<|end_filename|>

const vscode = require('vscode');
const path = require('path');
const fs = require('fs');
const DockerFileValidator = require('dockerfile_lint');

class DockerfileValidatorConfigs extends vscode.Disposable { 
    
    subscribeToRuleFilePathConfigChange(subscriber){
        vscode.workspace.onDidChangeConfiguration(e => {
            if(e.affectsConfiguration("dockerfile-validator.rulefile.path")){
                subscriber.rulefilePath = DockerfileValidatorConfigs.getRuleFilePath();
            }
        });
    }
    
    static getRuleFilePath(){
        var config = vscode.workspace.getConfiguration('dockerfile-validator');
        var result = config.rulefile.path;
        var validRuleFile =  DockerfileValidatorConfigs.validateRulefile(result, (errorMessage) =>{
            var errorMessage = `[dockerfile-validator]: Error loading rule file "${errorMessage}":.\nUsing default rules instead.`;
            vscode.window.showWarningMessage(errorMessage);
        })
        if(!validRuleFile){
            result = path.join(__dirname, "rule_files", 'default_rules.yaml');
        }
        return result;
    }

    static validateRulefile(ruleFilePath, errorCallback){
        var result = false;
        
        if(!fs.existsSync(ruleFilePath)){
            var errorMessage = `"${ruleFilePath}": File does not exist.`;
            errorCallback(errorMessage);
        }
        else{
            try {
                new DockerFileValidator(ruleFilePath);
                result = true;
            } catch (error) {
                errorCallback(error.message)
            }
        }

        return result;
    }
}

module.exports = {
    DockerfileValidatorConfigs
};