Interpreting sophos static file analysis score - sophoslabs-intelix

Is there an explanation anywhere for what the score field from the sophos static/dynamic file analysis report means?
The schema simply states: Maliciousness score of the analyzed file (0 = malicious, 100 = benign).
I expected this to be interpreted the same way as the file hash lookup reputationScore:
The following ranges are defined:
[0-19]: Malware
[20-29]: PUA (potentially unwanted application)
[30-69]: Unknown/suspicious
[70-100]: Known good
However, I've received a score of 10 which would indicate malware, but I have used a safe PDF file, which seems unexpected.
Does Sophos think the file is malicious, if it responds with a report score of 10 for static file analysis?
This is the response from Sophos:
{
"jobId": "3aee2c04a73bb64b3572271389cc2e95",
"jobStatus": "SUCCESS",
"report": {
"analysis_subject": {
"mime_type": "application/pdf",
"sha1": "5b03ccec77b416805d6d8e270d33942aaedcc6dd",
"sha256": "f6edcd8a1b4f7cb85486d0c6777f9174eadbc4d1d0d9e5aeba7132f30b34bc3e"
},
"analysis_summary": [
{
"description": "Document contains links to external domains",
"name": "edr_contains_domain_links",
"severity": 1
},
{
"description": "Document file size is small",
"name": "edr_info_file_size_small",
"severity": 1
},
{
"description": "Document has a small number of pages",
"name": "edr_info_page_count_small",
"severity": 1
}
],
"analysis_type": "static",
"detection": {
"permalink": "https://www.virustotal.com/gui/file/f6edcd8a1b4f7cb85486d0c6777f9174eadbc4d1d0d9e5aeba7132f30b34bc3e/detection/f-f6edcd8a1b4f7cb85486d0c6777f9174eadbc4d1d0d9e5aeba7132f30b34bc3e-1656684162",
"positives": 0,
"sophos": "",
"sophos_ml": "",
"total": 59
},
"document_analysis": {
"meta_data": {
"author": "Yukon Department of Education",
"bytes": 20597,
"content_type": "PDF",
"encryption": "Standard V2.3 (128-bit)",
"language": "EN-US",
"last_saved_time": "2008-06-04T15:47:36Z",
"num_pages": 1,
"title": "PDF Test Page",
"version": 1.6
}
},
"linked_with_dynamic_analysis": false,
"ml_aggregate_results": {
"overall_score": 30
},
"ml_file": {
"analyses": {
"black_box": {
"benign": {
"raw": 0.39815810322761536,
"score": 30
},
"model_name": "dsml_model_pdf",
"model_version": "20211118"
},
"feature_intersections": [
{
"benign": 7120629,
"benign_fraction": 0.7120629263895423,
"category": "severity=1",
"description": "Feature NOT Observed: Document file size is large",
"indicator": "Feature NOT Observed: Document file size is large --> severity=1",
"malware": 9997092,
"malware_fraction": 0.9997092138044599,
"probability": 0.5840200283264096,
"scale_factor": 10000000
},
{
"benign": 617857,
"benign_fraction": 0.06178572053380388,
"category": "severity=1",
"description": "Feature Observed: Document has a small number of pages",
"indicator": "Feature Observed: Document has a small number of pages --> severity=1",
"malware": 5394909,
"malware_fraction": 0.5394909111791909,
"probability": 0.8972424383801834,
"scale_factor": 10000000
},
{
"benign": 537367,
"benign_fraction": 0.0537367720738131,
"category": "severity=2",
"description": "Feature NOT Observed: Document contains behaviour that executes on open",
"indicator": "Feature NOT Observed: Document contains behaviour that executes on open --> severity=2",
"malware": 5372856,
"malware_fraction": 0.5372856378987031,
"probability": 0.9090782833830074,
"scale_factor": 10000000
},
{
"benign": 536021,
"benign_fraction": 0.0536021766615527,
"category": "severity=2",
"description": "Feature NOT Observed: Document contains javascript",
"indicator": "Feature NOT Observed: Document contains javascript --> severity=2",
"malware": 5371043,
"malware_fraction": 0.5371043501402938,
"probability": 0.9092575175159124,
"scale_factor": 10000000
},
{
"benign": 509534,
"benign_fraction": 0.050953467474390626,
"category": "severity=1",
"description": "Feature NOT Observed: Document is possibly a phishing PDF",
"indicator": "Feature NOT Observed: Document is possibly a phishing PDF --> severity=1",
"malware": 5364929,
"malware_fraction": 0.5364929575695063,
"probability": 0.9132627839711798,
"scale_factor": 10000000
},
{
"benign": 428577,
"benign_fraction": 0.04285774978628207,
"category": "severity=2",
"description": "Feature NOT Observed: Field contains potentially suspicious content",
"indicator": "Feature NOT Observed: Field contains potentially suspicious content --> severity=2",
"malware": 5364293,
"malware_fraction": 0.5364293727421457,
"probability": 0.9260163947729065,
"scale_factor": 10000000
}
],
"feature_maliciousness": {
"Document contains links to external domains --> severity=1": {
"benign": 1828421,
"benign_fraction": 0.18284217995357024,
"category": "severity=1",
"description": "Document contains links to external domains",
"indicator": "Document contains links to external domains --> severity=1",
"malware": 9869267,
"malware_fraction": 0.9869267695627242,
"probability": 0.8436937653122213,
"scale_factor": 10000000
},
"Document file size is small --> severity=1": {
"benign": 7120119,
"benign_fraction": 0.7120119817558322,
"category": "severity=1",
"description": "Document file size is small",
"indicator": "Document file size is small --> severity=1",
"malware": 9899084,
"malware_fraction": 0.9899084471664678,
"probability": 0.581642026468478,
"scale_factor": 10000000
},
"Document has a small number of pages --> severity=1": {
"benign": 4086919,
"benign_fraction": 0.40869198927301453,
"category": "severity=1",
"description": "Document has a small number of pages",
"indicator": "Document has a small number of pages --> severity=1",
"malware": 5416129,
"malware_fraction": 0.5416129670799382,
"probability": 0.569935959461394,
"scale_factor": 10000000
}
},
"genetic_analysis": {
"neighbor_info": {
"1f1006182c2e9b6e2b09b07f9be9e122fdc1e681577af68984ab63a076a15fed": {
"filepath": "1f1006182c2e9b6e2b09b07f9be9e122fdc1e681577af68984ab63a076a15fed",
"is_malware": false,
"match_percentage": 0.25,
"score": 66.06397
},
"672cfdffbc33f07c0ad65633cbf610c5ec4bb7787c72d84a5460266aaa9a2dfa": {
"filepath": "672cfdffbc33f07c0ad65633cbf610c5ec4bb7787c72d84a5460266aaa9a2dfa",
"is_malware": false,
"match_percentage": 0.21875,
"score": 62.829075
},
"6cdde8eee67aa38917dfa4249f91381ffa983f2ff95a84d0f6076a4ddecf3de8": {
"filepath": "6cdde8eee67aa38917dfa4249f91381ffa983f2ff95a84d0f6076a4ddecf3de8",
"is_malware": false,
"match_percentage": 0.21875,
"score": 63.53914
},
"9a0d27944893e40316037fd47fb4d9836c1518705b1baa4a0ebf0fe34b045c00": {
"filepath": "9a0d27944893e40316037fd47fb4d9836c1518705b1baa4a0ebf0fe34b045c00",
"is_malware": false,
"match_percentage": 0.1875,
"score": 58.78177
},
"a881bffc0893ae55112a9370f9cf693c3893d672b96c2160e341d9f20d47cd2f": {
"filepath": "a881bffc0893ae55112a9370f9cf693c3893d672b96c2160e341d9f20d47cd2f",
"is_malware": false,
"match_percentage": 0.8125,
"score": 234.79837
},
"add263021a636c93d1fd6f9d7ac880ac8afaacc917dca01dbb66d388c71d1e6c": {
"filepath": "add263021a636c93d1fd6f9d7ac880ac8afaacc917dca01dbb66d388c71d1e6c",
"is_malware": false,
"match_percentage": 0.1875,
"score": 59.46551
}
},
"neighbor_matrix": {
"1f1006182c2e9b6e2b09b07f9be9e122fdc1e681577af68984ab63a076a15fed": {
"0_6659": false,
"10_9152": false,
"11_4861": false,
"12_5543": false,
"13_3732": false,
"14_5431": false,
"15_5899": false,
"16_1078": false,
"17_2637": true,
"18_6885": false,
"19_8710": false,
"1_7974": false,
"20_6372": true,
"21_7672": false,
"22_8447": false,
"23_5023": false,
"24_7353": false,
"25_4809": false,
"26_7069": true,
"27_5993": false,
"28_2717": true,
"29_2739": true,
"2_7985": true,
"30_7482": true,
"31_5233": false,
"3_7524": false,
"4_6424": true,
"5_110": false,
"6_8324": false,
"7_6214": false,
"8_7332": false,
"9_8770": false
},
"672cfdffbc33f07c0ad65633cbf610c5ec4bb7787c72d84a5460266aaa9a2dfa": {
"0_6659": false,
"10_9152": false,
"11_4861": false,
"12_5543": false,
"13_3732": false,
"14_5431": false,
"15_5899": false,
"16_1078": false,
"17_2637": true,
"18_6885": false,
"19_8710": false,
"1_7974": true,
"20_6372": true,
"21_7672": false,
"22_8447": false,
"23_5023": false,
"24_7353": false,
"25_4809": true,
"26_7069": false,
"27_5993": false,
"28_2717": true,
"29_2739": false,
"2_7985": false,
"30_7482": false,
"31_5233": false,
"3_7524": false,
"4_6424": true,
"5_110": false,
"6_8324": false,
"7_6214": false,
"8_7332": false,
"9_8770": true
},
"6cdde8eee67aa38917dfa4249f91381ffa983f2ff95a84d0f6076a4ddecf3de8": {
"0_6659": false,
"10_9152": false,
"11_4861": false,
"12_5543": false,
"13_3732": false,
"14_5431": false,
"15_5899": false,
"16_1078": true,
"17_2637": false,
"18_6885": false,
"19_8710": false,
"1_7974": false,
"20_6372": true,
"21_7672": false,
"22_8447": false,
"23_5023": false,
"24_7353": false,
"25_4809": false,
"26_7069": true,
"27_5993": false,
"28_2717": true,
"29_2739": false,
"2_7985": true,
"30_7482": true,
"31_5233": false,
"3_7524": false,
"4_6424": true,
"5_110": false,
"6_8324": false,
"7_6214": false,
"8_7332": false,
"9_8770": false
},
"9a0d27944893e40316037fd47fb4d9836c1518705b1baa4a0ebf0fe34b045c00": {
"0_6659": false,
"10_9152": false,
"11_4861": false,
"12_5543": false,
"13_3732": true,
"14_5431": false,
"15_5899": false,
"16_1078": true,
"17_2637": false,
"18_6885": true,
"19_8710": false,
"1_7974": true,
"20_6372": false,
"21_7672": false,
"22_8447": false,
"23_5023": false,
"24_7353": true,
"25_4809": false,
"26_7069": false,
"27_5993": false,
"28_2717": true,
"29_2739": false,
"2_7985": false,
"30_7482": false,
"31_5233": false,
"3_7524": false,
"4_6424": false,
"5_110": false,
"6_8324": false,
"7_6214": false,
"8_7332": false,
"9_8770": false
},
"a881bffc0893ae55112a9370f9cf693c3893d672b96c2160e341d9f20d47cd2f": {
"0_6659": true,
"10_9152": true,
"11_4861": true,
"12_5543": true,
"13_3732": true,
"14_5431": true,
"15_5899": true,
"16_1078": true,
"17_2637": true,
"18_6885": false,
"19_8710": true,
"1_7974": false,
"20_6372": true,
"21_7672": true,
"22_8447": false,
"23_5023": true,
"24_7353": true,
"25_4809": true,
"26_7069": true,
"27_5993": true,
"28_2717": true,
"29_2739": true,
"2_7985": true,
"30_7482": true,
"31_5233": false,
"3_7524": true,
"4_6424": true,
"5_110": false,
"6_8324": true,
"7_6214": false,
"8_7332": true,
"9_8770": true
},
"add263021a636c93d1fd6f9d7ac880ac8afaacc917dca01dbb66d388c71d1e6c": {
"0_6659": false,
"10_9152": false,
"11_4861": false,
"12_5543": false,
"13_3732": false,
"14_5431": false,
"15_5899": false,
"16_1078": false,
"17_2637": false,
"18_6885": false,
"19_8710": false,
"1_7974": false,
"20_6372": true,
"21_7672": false,
"22_8447": false,
"23_5023": false,
"24_7353": false,
"25_4809": true,
"26_7069": false,
"27_5993": false,
"28_2717": true,
"29_2739": false,
"2_7985": true,
"30_7482": true,
"31_5233": false,
"3_7524": false,
"4_6424": true,
"5_110": false,
"6_8324": false,
"7_6214": false,
"8_7332": false,
"9_8770": false
}
}
}
},
"analyzed_counts": {
"black_box": {
"benign": 0,
"malware": 0
},
"feature_intersections": {
"benign": 2798922,
"malware": 6340055
},
"feature_maliciousness": {
"benign": 2798922,
"malware": 6340055
},
"genetic_analysis": {
"benign": 7701633,
"malware": 2298367
}
},
"overall_score": 30,
"overall_scores": {
"black_box": 30,
"feature_intersections": 15,
"feature_maliciousness": 15,
"genetic_analysis": 13
}
},
"ml_filepath": {
"analyses": {
"neighbor_maliciousness": {
"most_similar": [],
"most_similar_benign": [],
"most_similar_malware": []
}
},
"analyzed_counts": {
"neighbor_maliciousness": {
"benign": -1,
"malware": -1
}
},
"overall_score": -1,
"overall_scores": {
"neighbor_maliciousness": -1
}
},
"ml_inputs": {
"filepath": null
},
"object_type": "file",
"reputation": {
"first_seen": "2022-02-08T19:28:46",
"last_seen": "2022-07-04T07:46:43",
"prevalence": "Popular",
"score": 62,
"score_string": "Prevalent"
},
"schema_version": "1.1.0",
"score": 10,
"submission": "2022-07-04T08:43:34Z",
"target": {
"file_name": "pdf-test.pdf",
"mime_type": "application/pdf",
"object_id": "f6edcd8a1b4f7cb85486d0c6777f9174eadbc4d1d0d9e5aeba7132f30b34bc3e",
"sha1": "5b03ccec77b416805d6d8e270d33942aaedcc6dd",
"sha256": "f6edcd8a1b4f7cb85486d0c6777f9174eadbc4d1d0d9e5aeba7132f30b34bc3e"
}
},
"requestId": "68db2f66-c63e-4a04-93f9-7067231e42e1"
}
File: https://www.orimi.com/pdf-test.pdf

There are a couple of interesting points in your question. Let's start with the scoring.
You are correct the API documentation is not entirely accurate. A score <20 is malicious and >70 is clean. You can see a sample implementation of processing the scores around line 139 here.
In the case of the report that you provided the ML analyzers are causing the file to be convicted. From the report it looks like the following file features (which are commonly seen in malicious files) are causing the ML model to believe the file is malicious:
Document contains links to external domains
Document file size is small
Document has a small number of pages
Looking at the dynamic analysis results and the information from Virus Total etc. this could be a false positive and should be escalated to Sophos. The escalation path for FP / FN's is here:
https://support.sophos.com/support/s/filesubmission?language=en_US

Related

How can I auto-format the style block in vue3 properly with TailwindCSS with colon character?

I have a vue file with a style block like this, using TailwindCSS and PostCSS
<style scoped lang="postcss">
.button {
#apply bg-green-200 hover:bg-green-400;
}
</style>
In VSCode, with the Volar extension, I can perform auto-format. However, after auto-format, my style looks like this
<style scoped lang="postcss">
.button {
#apply bg-green-200 hover: bg-green-400; # notice the space after hover:
}
</style>
This breaks TailwindCSS because it would treat "hover:" and "bg-green-400" as 2 separate classes.
What can I adjust to improve on this? I don't see a lot of option when trying to create ".vscode/settings.json" myself to control Volar.
I am using:
Vue 3
Nuxt 3
TailwindCSS 3
Volar VSCode extension
VSCode
Update
I don't have any vscode setting in the root directory. Here is my VSCode global settings
{
"git.autofetch": true,
"explorer.confirmDragAndDrop": false,
"git.confirmSync": false,
"files.associations": {
"*.rmd": "markdown"
},
"workbench.editorAssociations": {
"*.ipynb": "jupyter-notebook",
"*.wasm": "default"
},
"terminal.integrated.inheritEnv": false,
"files.autoSave": "afterDelay",
"git.suggestSmartCommit": false,
"[dart]": {
"editor.formatOnSave": true,
"editor.formatOnType": true,
"editor.rulers": [
80
],
"editor.selectionHighlight": false,
"editor.suggest.snippetsPreventQuickSuggestions": false,
"editor.suggestSelection": "first",
"editor.tabCompletion": "onlySnippets",
"editor.wordBasedSuggestions": false
},
"editor.suggestSelection": "first",
"vsintellicode.modify.editor.suggestSelection": "automaticallyOverrodeDefaultValue",
"files.watcherExclude": {
"**/.bloop": true,
"**/.metals": true,
"**/.ammonite": true
},
"workbench.productIconTheme": "fluent-icons",
"jupyter.askForKernelRestart": false,
"security.workspace.trust.untrustedFiles": "open",
"notebook.cellToolbarLocation": {
"default": "right",
"jupyter-notebook": "left"
},
"diffEditor.ignoreTrimWhitespace": false,
"redhat.telemetry.enabled": false,
"[vue]": {
"editor.defaultFormatter": "Vue.volar"
},
"files.exclude": {
"**/.classpath": true,
"**/.project": true,
"**/.settings": true,
"**/.factorypath": true
},
"[python]": {
"editor.defaultFormatter": "ms-python.python"
},
"liveServer.settings.donotShowInfoMsg": true,
"editor.inlineSuggest.enabled": true,
"github.copilot.enable": {
"*": true,
"yaml": false,
"plaintext": false,
"markdown": false,
"scala": false,
"properties": false,
"rust": false,
"python": false,
"typescript": false,
"http": false,
"vue": false
},
"[java]": {
"editor.defaultFormatter": "scalameta.metals"
},
"files.autoSaveDelay": 1500,
"[typescript]": {
"editor.defaultFormatter": "vscode.typescript-language-features"
},
"[json]": {
"editor.defaultFormatter": "vscode.json-language-features"
},
"remote.SSH.defaultExtensions": [
"gitpod.gitpod-remote-ssh"
],
"remote.SSH.configFile": "/var/folders/rz/j1sp0c394pn5sv5pttp2pkt40000gn/T/gitpod_ssh_config-55598-oizqwPMdK6La",
"terminal.integrated.fontFamily": "JetBrainsMono Nerd Font Mono",
"terminal.integrated.fontSize": 13,
"editor.fontFamily": "JetBrainsMono Nerd Font Mono",
"editor.fontSize": 13,
"[javascript]": {
"editor.defaultFormatter": "vscode.typescript-language-features"
},
"[postcss]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
I'm facing the same issue as you. What I can do now is install the postcss-nesting package add it to the postcss.config.js file:
module.exports = {
plugins: {
'tailwindcss/nesting': 'postcss-nesting',
tailwindcss: {},
autoprefixer: {},
},
}
In the style tag, you can do something like this:
<style scoped lang="postcss">
.button {
#apply bg-green-200;
&:hover {
#apply bg-green-400;
}
}
</style>

How to set indent and formatting behavior for each language in visual studio code?

Is there a way to make vscode format python files using 4 spaces while formatting files from other languages such JS, Typescript and HTML using 2 spaces only?
It`s pretty annoying to have to indent manually every time.
All of this trying is setting up a mess on my settings and still, I can`t make it work as I want.
This is what my settings.json looks like for the moment
{
"python.jediEnabled": false,
"miramac.node.terminalMode": false,
"python.pythonPath": "/usr/local/bin/python3",
"workbench.colorTheme": "Dracula",
"workbench.startupEditor": "newUntitledFile",
"workbench.editor.labelFormat": "short",
"terminal.integrated.fontSize": 12,
"editor.fontFamily": "Fira Code",
"editor.lineHeight": 19,
"editor.fontLigatures":true,
"editor.suggestSelection": "first",
"editor.renderLineHighlight": "gutter",
"editor.detectIndentation": true,
"editor.insertSpaces": false,
"editor.tabSize": 2,
"editor.autoIndent": "full",
"eslint.alwaysShowStatus": true,
"eslint.debug": true,
"eslint.format.enable": true,
"eslint.options": {
},
"python.languageServer": "Microsoft",
"liveServer.settings.donotVerifyTags": true,
"[html]": {
"editor.tabSize": 2,
"editor.codeActionsOnSave": {
"source.fixAll": true,
},
},
"liveServer.settings.donotShowInfoMsg": true,
"prettier.tabWidth": 2,
"[javascript]":{
"editor.codeActionsOnSave": {
"source.fixAll": true,
}
},
"[javascriptreact]":{
"editor.codeActionsOnSave": {
"source.fixAll": true,
}
},
"[typescript]":{
"editor.codeActionsOnSave": {
"source.fixAll": true,
},
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
},
"[typescriptreact]":{
"editor.codeActionsOnSave": {
"source.fixAll": true,
},
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
},
"[python]": {
"editor.tabSize": 4,
"editor.codeActionsOnSave": {
// "source.fixAll": true,
},
},
"extensions.ignoreRecommendations": true,
"explorer.compactFolders": false,
//perguntar se vc confirma delete e drag and drops
"explorer.confirmDragAndDrop": false,
"explorer.confirmDelete": false,
//mostra o caminho completo do arquivo
"breadcrumbs.enabled": true,
"javascript.updateImportsOnFileMove.enabled": "never",
"typescript.updateImportsOnFileMove.enabled": "never",
"python.linting.pylintArgs": [
"--extension-pkg-whitelist=pygame"
],
"vsintellicode.modify.editor.suggestSelection": "automaticallyOverrodeDefaultValue",
//set zsh theme to my terminal
//"terminal.integrated.shell.osx": "/bin/bash",
"terminal.integrated.shell.osx": "/bin/bash",
//"terminal.integrated.cwd": "",
"editor.renderControlCharacters": false,
"window.zoomLevel": -1,
"git.path": "/usr/local/git/bin/git",
"gitlens.views.repositories.files.layout": "list",
"gitlens.views.compare.files.layout": "tree",
"emmet.syntaxProfiles": {"javascript": "jsx"},
"emmet.includeLanguages": {"javascript": "javascriptreact"},
"typescript.tsserver.log": "verbose",
"javascript.suggest.autoImports": true,
"git.enableCommitSigning": true,
"git.enableSmartCommit": true,
"git.rebaseWhenSync": true,
"git.showPushSuccessNotification": true,
"workbench.sideBar.location": "left",
"workbench.activityBar.visible": true,
"terminal.integrated.automationShell.osx": "",
// "editor.defaultFormatter": "vscode.python",
// "editor.tokenColorCustomizationsExperimental": {},
"workbench.preferredDarkColorTheme": "Dracula",
"workbench.preferredHighContrastColorTheme": "Visual Studio Dark",
"material-icon-theme.activeIconPack": "nest",
"workbench.iconTheme": "material-icon-theme",
"material-icon-theme.folders.associations": {
"infra": "app",
"entities": "class",
"schemas": "class",
"typeorm": "database",
"repositories": "mappings",
"http": "container",
"migrations": "tools",
"modules": "components",
"implementations": "core",
"dtos": "typescript",
"fakes": "mock",
"coverage_reports": "tools",
},
"material-icon-theme.files.associations": {
"ormconfig.json": "database",
"routes.tsx": "routing",
"routes.ts": "routing",
"*.html": "html",
},
"sqlite.databaseExtensions": [
"db",
"db3",
"sdb",
"s3db",
"sqlite",
"sqlite3",
"ts"
],
}
Would there be anyone who can help in this issue?
I believe option + control + "B" should work
It is also a right click on the document and you should see a "format document" option.
It works for me

Azure devops - minimal code coverage pull reqeust

I have an Angular 9 project and I am trying to get the minimal code coverage working on an pull request in Azure devops conform the documentation. However the minimal code coverage isn't working, probably missing some step....
Steps to reproduce:
Create an new Angular 9 project: "ng new DefaultWebsite"
Create build pipeline and edit the karma and protractor config conform Microsoft "Build, test, and deploy JavaScript and Node.js apps" documentation
Add and "azurepipelines-coverage.yml" in the root of my project to enable the code coverage check in an pull request conform the Microsoft "Code coverage for pull requests" documentation
Disable some test in de app.spec.ts file, so the code coverage isn't 100% any more, it now is 77%. Changed the minimal code coverag in the yml file to 95% so the pull request cannot be complited conform the theory and it should give an "Coverage status check failed" error conform the Microsoft documentation.
However when the pull request is started there is an code coverage check below the 'Status' part. When the build (with unit and e2e tests) is done, there is no code coverage error which I espect te see below the 'Status' part.
Pull reqeust with code coverage check Pull reqeust build completed
When I look at the build there are test results and code coverage results.
Build test result Build code coverage result
When I look at the code coverage result I see an Line coverage of 75% which should be an minimal of 90% conform the yml-file.
Karma config file
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
module.exports = function (config) {
const process = require('process');
process.env.CHROME_BIN = require('puppeteer').executablePath();
config.set({
basePath: '',
frameworks: ['jasmine', '#angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('#angular-devkit/build-angular/plugins/karma'),
require('karma-junit-reporter')
],
client: {
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, './coverage'),
reports: ['html', 'lcovonly', 'text-summary', 'cobertura'],
fixWebpackSourcePaths: true
},
coverageReporter: {
type : 'html',
dir : 'coverage/'
},
junitReporter: {
outputDir: './coverage', // results will be saved as $outputDir/$browserName.xml
outputFile: 'junit.xml', // if included, results will be saved as $outputDir/$browserName/$outputFile
suite: '', // suite will become the package name attribute in xml testsuite element
useBrowserName: true, // add browser name to report and classes names
nameFormatter: undefined, // function (browser, result) to customize the name attribute in xml testcase element
classNameFormatter: undefined, // function (browser, result) to customize the classname attribute in xml testcase element
properties: {}, // key value pair of properties to add to the <properties> section of the report
xmlVersion: null // use '1' if reporting to be per SonarQube 6.2 XML format
},
reporters: ['progress', 'kjhtml','junit'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['ChromeHeadless'],
singleRun: false,
restartOnFileChange: true
});
};
Protractor config file:
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts
const { SpecReporter } = require('jasmine-spec-reporter');
const { JUnitXmlReporter } = require('jasmine-reporters');
process.env.CHROME_BIN = process.env.CHROME_BIN || require("puppeteer").executablePath();
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./src/**/*.e2e-spec.ts'
],
capabilities: {
'browserName': 'chrome',
chromeOptions: {
args: ["--headless", "--disable-gpu", "--window-size=1200,900"],
binary: process.env.CHROME_BIN
}
},
directConnect: true,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function () { }
},
onPrepare() {
require('ts-node').register({
project: require('path').join(__dirname, './tsconfig.json')
});
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
var junitReporter = new JUnitXmlReporter({
savePath: require('path').join(__dirname, './junit'),
consolidateAll: true
});
jasmine.getEnv().addReporter(junitReporter);
}
};
azurepipelines-coverage.yml
coverage:
status: #Code coverage status will be posted to pull requests based on targets defined below.
diff: #diff coverage is code coverage only for the lines changed in a pull request.
target: 95% #set this to a desired %. Default is 70%.
Azure Build pipeline steps:
"steps": [
{
"environment": {},
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "npm install",
"timeoutInMinutes": 0,
"condition": "succeeded()",
"task": {
"id": "fe47e961-9fa8-4106-8639-368c022d43ad",
"versionSpec": "1.*",
"definitionType": "task"
},
"inputs": {
"command": "install",
"workingDir": "Project\\Frontend\\DefaultWebsite",
"verbose": "false",
"customCommand": "",
"customRegistry": "useNpmrc",
"customFeed": "",
"customEndpoint": "",
"publishRegistry": "useExternalRegistry",
"publishFeed": "",
"publishPackageMetadata": "true",
"publishEndpoint": ""
}
},
{
"environment": {},
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "npm custom - test ",
"timeoutInMinutes": 0,
"condition": "succeeded()",
"task": {
"id": "fe47e961-9fa8-4106-8639-368c022d43ad",
"versionSpec": "1.*",
"definitionType": "task"
},
"inputs": {
"command": "custom",
"workingDir": "Project\\Frontend\\DefaultWebsite",
"verbose": "false",
"customCommand": "run test",
"customRegistry": "useNpmrc",
"customFeed": "",
"customEndpoint": "",
"publishRegistry": "useExternalRegistry",
"publishFeed": "",
"publishPackageMetadata": "true",
"publishEndpoint": ""
}
},
{
"environment": {},
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "Publish code coverage from Project\\Frontend\\DefaultWebsite\\coverage\\cobertura-coverage.xml",
"timeoutInMinutes": 0,
"condition": "succeeded()",
"task": {
"id": "2a7ebc54-c13e-490e-81a5-d7561ab7cd97",
"versionSpec": "1.*",
"definitionType": "task"
},
"inputs": {
"codeCoverageTool": "Cobertura",
"summaryFileLocation": "Project\\Frontend\\DefaultWebsite\\coverage\\cobertura-coverage.xml",
"pathToSources": "",
"reportDirectory": "",
"additionalCodeCoverageFiles": "",
"failIfCoverageEmpty": "false"
}
},
{
"environment": {},
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "Publish Test Results Project\\Frontend\\DefaultWebsite\\**\\junit.xml copy",
"timeoutInMinutes": 0,
"condition": "succeeded()",
"task": {
"id": "0b0f01ed-7dde-43ff-9cbb-e48954daf9b1",
"versionSpec": "2.*",
"definitionType": "task"
},
"inputs": {
"testRunner": "JUnit",
"testResultsFiles": "Project\\Frontend\\DefaultWebsite\\**\\junit.xml",
"searchFolder": "$(System.DefaultWorkingDirectory)",
"mergeTestResults": "false",
"failTaskOnFailedTests": "false",
"testRunTitle": "",
"platform": "",
"configuration": "",
"publishRunAttachments": "true"
}
},
{
"environment": {},
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "npm custom - e2e",
"timeoutInMinutes": 0,
"condition": "succeeded()",
"task": {
"id": "fe47e961-9fa8-4106-8639-368c022d43ad",
"versionSpec": "1.*",
"definitionType": "task"
},
"inputs": {
"command": "custom",
"workingDir": "Project\\Frontend\\DefaultWebsite",
"verbose": "false",
"customCommand": "run e2e",
"customRegistry": "useNpmrc",
"customFeed": "",
"customEndpoint": "",
"publishRegistry": "useExternalRegistry",
"publishFeed": "",
"publishPackageMetadata": "true",
"publishEndpoint": ""
}
},
{
"environment": {},
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "Publish Test Results Project\\Frontend\\DefaultWebsite\\e2e\\**\\junitresults.xml",
"timeoutInMinutes": 0,
"condition": "succeeded()",
"task": {
"id": "0b0f01ed-7dde-43ff-9cbb-e48954daf9b1",
"versionSpec": "2.*",
"definitionType": "task"
},
"inputs": {
"testRunner": "JUnit",
"testResultsFiles": "Project\\Frontend\\DefaultWebsite\\e2e\\**\\junitresults.xml",
"searchFolder": "$(System.DefaultWorkingDirectory)",
"mergeTestResults": "false",
"failTaskOnFailedTests": "false",
"testRunTitle": "",
"platform": "",
"configuration": "",
"publishRunAttachments": "true"
}
},
{
"environment": {},
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "npm custom - prodBuild",
"timeoutInMinutes": 0,
"condition": "succeeded()",
"task": {
"id": "fe47e961-9fa8-4106-8639-368c022d43ad",
"versionSpec": "1.*",
"definitionType": "task"
},
"inputs": {
"command": "custom",
"workingDir": "Project\\Frontend\\DefaultWebsite",
"verbose": "false",
"customCommand": "run prodBuild",
"customRegistry": "useNpmrc",
"customFeed": "",
"customEndpoint": "",
"publishRegistry": "useExternalRegistry",
"publishFeed": "",
"publishPackageMetadata": "true",
"publishEndpoint": ""
}
},
{
"environment": {},
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "Publish Artifact: app",
"timeoutInMinutes": 0,
"condition": "succeeded()",
"task": {
"id": "2ff763a7-ce83-4e1f-bc89-0ae63477cebe",
"versionSpec": "1.*",
"definitionType": "task"
},
"inputs": {
"PathtoPublish": "Project\\Frontend\\DefaultWebsite\\dist",
"ArtifactName": "app",
"ArtifactType": "Container",
"TargetPath": "",
"Parallel": "false",
"ParallelCount": "8",
"FileCopyOptions": ""
}
}
],

How to disable vscode auto format adding newline at EOF when auto save js files?

I am using vscode and enabled the auto-format config to format files when saving files.
But i recently found that vscode editor always add a newline at EOF of each js file,so how to disable this?
I have specially added the config "files.insertFinalNewline": false, but it still not worked.
vscode info:
Version: 1.33.1 (system setup)
Commit: 51b0b28134d51361cf996d2f0a1c698247aeabd8
Date: 2019-04-11T08:27:14.102Z
Electron: 3.1.6
Chrome: 66.0.3359.181
Node.js: 10.2.0
V8: 6.6.346.32
OS: Windows_NT x64 6.1.7601
vscode config.json
{
"workbench.colorTheme": "Monokai",
"editor.fontSize": 16,
"editor.formatOnPaste": true,
// Format a file on save.
// A formatter must be available,
// the file must not be auto-saved,
// and editor must not be shutting down.
"editor.formatOnSave": true,
"debug.console.fontSize": 16,
"terminal.integrated.fontSize": 14,
"markdown.preview.fontSize": 14,
"window.zoomLevel": 1,
"editor.renderWhitespace": "all",
"window.title": "${dirty}${activeEditorLong}${separator}${rootName}${separator}${appName}",
"search.exclude": {
"**/.gitignore": true,
"**/.idea": true,
"**/.vscode": true,
"**/build": true,
"**/dist": true,
"**/tmp": true,
"**/yarn.lock": true
},
"workbench.iconTheme": "material-icon-theme",
"editor.wordWrapColumn": 110,
"http.proxyStrictSSL": false,
"files.trimTrailingWhitespace": true,
"files.insertFinalNewline": false,
"files.trimFinalNewlines": false,
"html.format.endWithNewline": false,
"javascript.implicitProjectConfig.experimentalDecorators": true,
// Enable/disable default JavaScript formatter (For Prettier)
"javascript.format.enable": false,
// Use 'prettier-eslint' instead of 'prettier'.
// Other settings will only be fallbacks
// in case they could not be inferred from eslint rules.
"prettier.eslintIntegration": true,
"prettier.tabWidth": 4,
"prettier.singleQuote": true,
"prettier.arrowParens": "always"
}
.eslintrc.json
{
"extends": "airbnb",
"plugins": [
"react",
"jsx-a11y",
"import",
"react-hooks"
],
"parserOptions": {
"sourceType": "module",
"ecmaFeatures": {
"legacyDecorators": true,
"experimentalObjectRestSpread": true
}
},
"env": {
"browser": true,
"es6": true
},
"parser": "babel-eslint",
"globals": {
"describe": true,
"it": true,
"inject": true,
"beforeEach": true,
"addProviders": true,
"spyOn": true,
"expect": true,
"global": true,
"require": true,
"async": true,
"ENVIRONMENT": true,
"client": true
},
"rules": {
"linebreak-style": 0,
"quotes": [2, "single", {
"avoidEscape": true,
"allowTemplateLiterals": true
}],
"indent": [2, 4, {
"SwitchCase": 1,
"VariableDeclarator": 1
}],
"react/jsx-indent": [2, 4],
"comma-dangle": ["error", "never"],
"class-methods-use-this": 0,
"import/newline-after-import": 0,
"space-before-function-paren": ["error", "never"],
"func-names": ["error", "never"],
"consistent-return": [0],
"eol-last": ["error", "never"],
"no-script-url": ["off"],
"react/jsx-indent-props": [2, 4],
"react/forbid-prop-types": [2, {
"forbid": []
}],
"jsx-a11y/anchor-is-valid": ["error", {
"components": ["Link"],
"specialLink": ["to"],
"aspects": ["noHref"]
}],
"jsx-a11y/href-no-hash": "off",
"jsx-a11y/no-static-element-interactions": "off",
"jsx-a11y/click-events-have-key-events": "off",
"import/no-unresolved": [
"error",
{
"ignore": ["client/"]
}
],
"import/no-extraneous-dependencies": [
"error",
{
"devDependencies": true
}
],
"import/extensions": 0,
"max-len": [
0, 110, 4
],
"react/jsx-filename-extension": [
1,
{
"extensions": [
".js",
".jsx"
]
}
],
"react-hooks/rules-of-hooks": "error"
},
"settings": {
"import/resolver": {
"node": {
"extensions": [".js", ".jsx", ".json", ".css"]
}
}
}
}
So, how to config vscode correctly?
I had the same problem. To fix it you need to be in the folder of your project. then open your settings i.e command + shift + p, type settings, select Preferences: open settings UI, under Text Editor tab, choose Files and you'll find Eol tab to choose from \n, \n, auto. I choose auto so it will override whatever you specify.

VS Code is formatting JS files with operators on new line

For the life of me I cannot figure this out. I have a complex VSCode setup and I believe the prettier extension is causing some behavior I do not want, and I hope someone knows how to disable or re-configure it:
JS files:
takes:
child.gender = $(pref).find('#ml').prop('checked')? 'male' : 'female';
And renders:
child.gender = $(pref)
.find('#ml')
.prop('checked')
? 'male'
: 'female';
I really need the formatter and would like to try to fix rather than disable.
Thanks for your help.
existing options:
"workbench.iconTheme": "material-icon-theme",
"php.suggest.basic": false,
"editor.minimap.enabled": false,
"editor.fontLigatures": true,
"editor.fontFamily": "'Fira Code', 'Arial', monospace",
"php.validate.executablePath": "C:\\wamp64\\bin\\php\\php7.2.4\\php.exe",
"files.associations": {
"*.php": "php",
"*.phtml": "php"
},
"php.validate.run": "onType",
"editor.cursorSmoothCaretAnimation": true,
"editor.smoothScrolling": true,
"files.trimFinalNewlines": true,
"emmet.includeLanguages": {
"blade.php": "html"
},
"vetur.format.options.tabSize": 4,
"vetur.format.options.useTabs": false,
"blade.format.enable": true,
"vetur.format.defaultFormatter.html": "prettyhtml",
"vetur.format.defaultFormatter.css": "prettier",
"vetur.format.defaultFormatter.postcss": "prettier",
"vetur.format.defaultFormatter.scss": "prettier",
"vetur.format.defaultFormatter.less": "prettier",
"vetur.format.defaultFormatter.stylus": "stylus-supremacy",
"vetur.format.defaultFormatter.js": "prettier",
"vetur.format.defaultFormatter.ts": "prettier",
"eslint.enable": false,
"window.zoomLevel": 0,
"files.trimTrailingWhitespace": true,
"prettier.singleQuote": true,
"prettier.trailingComma": "es5",
"prettier.eslintIntegration": true,
"prettier.disableLanguages": [],
"eslint.autoFixOnSave": true,
"editor.insertSpaces": true,
"editor.formatOnSave": true,
"editor.detectIndentation": true,
"editor.tabSize": 4,
"editor.formatOnPaste": false,
"editor.formatOnType": true,
"editor.renderControlCharacters": true,
"editor.renderWhitespace": "none",
"files.exclude": {
".babelrc": true,
".editorconfig": true,
".eslintignore": true,
".eslintrc.js": false,
".gitignore": true,
".jshintrc": true,
".postcssrc.js": true,
"**/node_modules": true,
"build": true
},
"eslint.validate": [
{
"autoFix": true,
"language": "javascript"
},
{
"autoFix": true,
"language": "vue"
}
],
"attrsSorter.order": [
"is",
"v-for",
"v-if",
"v-else-if",
"v-else",
"v-show",
"v-cloak",
"v-once",
"v-pre",
"id",
"ref",
"key",
"slot",
"v-model",
"v-model.+",
"v-bind",
"v-bind.+",
":.+",
"v-text",
"v-text.+",
"v-html",
"v-html.+",
"class",
"v-on.+",
"#.+",
"name",
"data-.+",
"ng-.+",
"src",
"for",
"type",
"href",
"values",
"title",
"alt",
"role",
"aria-.+",
"$unknown$"
],
"gitlens.currentLine.enabled": false,
"gitlens.hovers.currentLine.over": "line",
"gitlens.codeLens.enabled": false,
"phpformatter.composer": true,
"phpformatter.pharPath": "php-cs-fixer",
"phpformatter.logging": true,
"laravel_goto_view.quickJump": true,
"laravel_goto_view.folderTip": true,
"git.enableSmartCommit": true,
"javascript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": true,
"typescript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": true,
"typescript.format.insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": true,
"javascript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": true,
"bracketPairColorizer.highlightActiveScope": true