mirror of
https://github.com/atom/atom.git
synced 2026-04-28 03:01:47 -04:00
Merge branch 'master' into electron-3.1
This commit is contained in:
67
package-lock.json
generated
67
package-lock.json
generated
@@ -1722,16 +1722,16 @@
|
||||
}
|
||||
},
|
||||
"atom-keymap": {
|
||||
"version": "8.2.13",
|
||||
"resolved": "https://registry.npmjs.org/atom-keymap/-/atom-keymap-8.2.13.tgz",
|
||||
"integrity": "sha512-RNf+5KbAiXpNV2KZT0+XYpTRFE8rhq7NrBryghJAOlwayY3g3z6Kp9tMfaPJ05BkPo9mChcaFO6SKUL8LTQcBg==",
|
||||
"version": "8.2.14",
|
||||
"resolved": "https://registry.npmjs.org/atom-keymap/-/atom-keymap-8.2.14.tgz",
|
||||
"integrity": "sha512-9ofjA8IG/RNJcqvMvYglc0l7DljavIUQvGs5xdEtd5dEYX4rCQo9coeBfGaC0YM7FB0SBHPZy39QYFROkOzTOw==",
|
||||
"requires": {
|
||||
"clear-cut": "^2",
|
||||
"emissary": "^1.1.0",
|
||||
"event-kit": "^1.0.0",
|
||||
"fs-plus": "^3.0.0",
|
||||
"grim": "^1.2.1",
|
||||
"keyboard-layout": "2.0.14",
|
||||
"keyboard-layout": "2.0.16",
|
||||
"pathwatcher": "^8.0.0",
|
||||
"property-accessors": "^1",
|
||||
"season": "^6.0.2"
|
||||
@@ -3300,8 +3300,8 @@
|
||||
}
|
||||
},
|
||||
"find-and-replace": {
|
||||
"version": "https://www.atom.io/api/packages/find-and-replace/versions/0.218.10/tarball",
|
||||
"integrity": "sha512-P9pFWPlUIUO+COMR6VdTQa7Q4JUcrSS8NALq5Pc0RI8scoMoLnZ5RSReKgYp5Gnc7kshPPa09agw3GitLFmorw==",
|
||||
"version": "https://www.atom.io/api/packages/find-and-replace/versions/0.218.11/tarball",
|
||||
"integrity": "sha512-STNDeRCSXCV5YjfrWbS5X4TfOFnNX7Z1k96POk3uPoPN8aQvkAIUflT7h6p0MClR9E2/I2O7nYKbYzNqBflZ6Q==",
|
||||
"requires": {
|
||||
"binary-search": "^1.3.3",
|
||||
"element-resize-detector": "^1.1.10",
|
||||
@@ -4345,12 +4345,19 @@
|
||||
}
|
||||
},
|
||||
"keyboard-layout": {
|
||||
"version": "2.0.14",
|
||||
"resolved": "https://registry.npmjs.org/keyboard-layout/-/keyboard-layout-2.0.14.tgz",
|
||||
"integrity": "sha512-QuCfpEC8oai6F8oaNQdxi5+1QIpaQu9HSVI9yzkC2HbIXeBnahzHFDRVGUtwwAWiNnzjNBjUI/djsrMGUTgK1w==",
|
||||
"version": "2.0.16",
|
||||
"resolved": "https://registry.npmjs.org/keyboard-layout/-/keyboard-layout-2.0.16.tgz",
|
||||
"integrity": "sha512-eGrxmlV6jbm/mbPEOpYGuH53XEC7wIUj9ZxKcT2z9QHJ/RwrT9iVkvxka9zRxqHZHwQzcffgsa5OxoVAKnhK9w==",
|
||||
"requires": {
|
||||
"event-kit": "^2.0.0",
|
||||
"nan": "^2.10.0"
|
||||
"nan": "^2.13.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"nan": {
|
||||
"version": "2.14.0",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
|
||||
"integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"keytar": {
|
||||
@@ -4446,10 +4453,10 @@
|
||||
}
|
||||
},
|
||||
"language-json": {
|
||||
"version": "https://www.atom.io/api/packages/language-json/versions/1.0.1/tarball",
|
||||
"integrity": "sha512-mgUFtXCqseXW6bi4oIub1c+lh7qqXN9o8kjf+ljJe8yB8JYSZeRAm5zhqvrrUZO6WDQv4lplq2bJP8vMiKtaxg==",
|
||||
"version": "https://www.atom.io/api/packages/language-json/versions/1.0.2/tarball",
|
||||
"integrity": "sha512-2OvmYoTjO5IXnnRMVMfPb7iOMEnqD36otbpOpQUELG4eJJqgrms6Hs7HnevFs5ZB4yLc1ZU2u9h9TAp/WXUmdA==",
|
||||
"requires": {
|
||||
"tree-sitter-json": "^0.13.1"
|
||||
"tree-sitter-json": "git://github.com/tree-sitter/tree-sitter-json.git#337f55be9b9b1ccb0baa7763bfe014a94acea7ea"
|
||||
}
|
||||
},
|
||||
"language-less": {
|
||||
@@ -4465,8 +4472,8 @@
|
||||
"integrity": "sha512-1aC1OAoYye+krEJ8t5RzXiLYTEA/RJ/Igv1efDsuxvZHnIkdrSDzS/UsssS3snqPkIGyLI+htRvU/v11famx6A=="
|
||||
},
|
||||
"language-objective-c": {
|
||||
"version": "https://www.atom.io/api/packages/language-objective-c/versions/0.15.1/tarball",
|
||||
"integrity": "sha512-ZKlTy/xiyb+J7DnHztzM/ss8/rtwbPskSpd+Ox1gKc0k+NpiU7rmzfW6ki9/t/kFHGo1qX7QiImvdCavJ2LsgQ=="
|
||||
"version": "https://www.atom.io/api/packages/language-objective-c/versions/0.16.0/tarball",
|
||||
"integrity": "sha512-KFkmXxNuTL2zwL8mfIF9PovRaWUOu/rWPp/fDjSgXPgClXUWeJdZQystXODr6u7kvGYEAdmjYFj/zQu7f/P85Q=="
|
||||
},
|
||||
"language-perl": {
|
||||
"version": "https://www.atom.io/api/packages/language-perl/versions/0.38.1/tarball",
|
||||
@@ -4481,8 +4488,8 @@
|
||||
"integrity": "sha512-HD6HI41u57i0/Tu9catiriURhJsef0RDrzJDkGDtdFkE9F9KPxC9Fayq2JBLJrhIyADRVXFxwxsfwQ2Jmh6hxg=="
|
||||
},
|
||||
"language-python": {
|
||||
"version": "https://www.atom.io/api/packages/language-python/versions/0.53.1/tarball",
|
||||
"integrity": "sha512-yu2DU+Lqy0dzyMwzBIa6Oz6yvQiOeqwwnXl8Gbw4CasnTiAnEW9fk0wFOsUZOs1veqkZqP6Mdd5Zu7n5p1gLcw==",
|
||||
"version": "https://www.atom.io/api/packages/language-python/versions/0.53.2/tarball",
|
||||
"integrity": "sha512-ACNHWQWlRUfWrOb5MTvjP2wMTFdAq8Wnd3tWXYEd/TcfECtmCGy+6h33dt9X6SmAZz6OGKQ7V8lnVbOlh3X+Fw==",
|
||||
"requires": {
|
||||
"atom-grammar-test": "^0.6.4",
|
||||
"tree-sitter-python": "^0.14.0"
|
||||
@@ -6965,15 +6972,15 @@
|
||||
}
|
||||
},
|
||||
"text-buffer": {
|
||||
"version": "13.15.3",
|
||||
"resolved": "https://registry.npmjs.org/text-buffer/-/text-buffer-13.15.3.tgz",
|
||||
"integrity": "sha512-H2fz/N15g0fBP7R33FUFLnIyND+Lji/xmuvHg9rKgmfCh7NAVxiFIvnZTabuBhL9InqPrtV5t4hkUy+r3dNXMg==",
|
||||
"version": "13.16.0",
|
||||
"resolved": "https://registry.npmjs.org/text-buffer/-/text-buffer-13.16.0.tgz",
|
||||
"integrity": "sha512-J00KcJDKvV87I/4o7F6LYu+2/fzmuEb7liBbZsIeCUM+T0kwqW7k0R7ddyk9EJR2Nqq7asng2/hVIBNYldIfEg==",
|
||||
"requires": {
|
||||
"delegato": "^1.0.0",
|
||||
"diff": "^2.2.1",
|
||||
"emissary": "^1.0.0",
|
||||
"event-kit": "^2.4.0",
|
||||
"fs-admin": "^0.1.7",
|
||||
"fs-admin": "^0.5.0",
|
||||
"fs-plus": "^3.0.0",
|
||||
"grim": "^2.0.2",
|
||||
"mkdirp": "^0.5.1",
|
||||
@@ -6988,6 +6995,14 @@
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-2.2.3.tgz",
|
||||
"integrity": "sha1-YOr9DSjukG5Oj/ClLBIpUhAzv5k="
|
||||
},
|
||||
"fs-admin": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-admin/-/fs-admin-0.5.0.tgz",
|
||||
"integrity": "sha512-jU0x86bI6wmhdGGcpaO1rI7EpNx/44cEXPsHqFIRgs9SVsk3HSWn9Zd5fd7bdDw3LcmdnazOcJFK9PZsoNecAA==",
|
||||
"requires": {
|
||||
"nan": "^2.13.2"
|
||||
}
|
||||
},
|
||||
"grim": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/grim/-/grim-2.0.2.tgz",
|
||||
@@ -6995,6 +7010,11 @@
|
||||
"requires": {
|
||||
"event-kit": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"nan": {
|
||||
"version": "2.14.0",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
|
||||
"integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -7150,9 +7170,8 @@
|
||||
}
|
||||
},
|
||||
"tree-sitter-json": {
|
||||
"version": "0.13.1",
|
||||
"resolved": "https://registry.npmjs.org/tree-sitter-json/-/tree-sitter-json-0.13.1.tgz",
|
||||
"integrity": "sha512-3Z6CC5vaEX+vvCmZ5ULCYVaILQVqkhv1Yw7Wo7ARlVsOAehVEj5JCag+lyU4RGkZY65tgYyrkw5s0Anv4ij4kQ==",
|
||||
"version": "git://github.com/tree-sitter/tree-sitter-json.git#337f55be9b9b1ccb0baa7763bfe014a94acea7ea",
|
||||
"from": "git://github.com/tree-sitter/tree-sitter-json.git#v0.14.0",
|
||||
"requires": {
|
||||
"nan": "^2.0.0"
|
||||
}
|
||||
|
||||
21
package.json
21
package.json
@@ -22,7 +22,7 @@
|
||||
"async": "0.2.6",
|
||||
"atom-dark-syntax": "file:packages/atom-dark-syntax",
|
||||
"atom-dark-ui": "file:packages/atom-dark-ui",
|
||||
"atom-keymap": "8.2.13",
|
||||
"atom-keymap": "8.2.14",
|
||||
"atom-light-syntax": "file:packages/atom-light-syntax",
|
||||
"atom-light-ui": "file:packages/atom-light-ui",
|
||||
"atom-select-list": "^0.7.2",
|
||||
@@ -54,7 +54,7 @@
|
||||
"etch": "^0.12.6",
|
||||
"event-kit": "^2.5.3",
|
||||
"exception-reporting": "file:packages/exception-reporting",
|
||||
"find-and-replace": "https://www.atom.io/api/packages/find-and-replace/versions/0.218.10/tarball",
|
||||
"find-and-replace": "https://www.atom.io/api/packages/find-and-replace/versions/0.218.11/tarball",
|
||||
"find-parent-dir": "^0.3.0",
|
||||
"first-mate": "7.3.0",
|
||||
"focus-trap": "2.4.5",
|
||||
@@ -89,15 +89,15 @@
|
||||
"language-hyperlink": "https://www.atom.io/api/packages/language-hyperlink/versions/0.17.1/tarball",
|
||||
"language-java": "https://www.atom.io/api/packages/language-java/versions/0.31.3/tarball",
|
||||
"language-javascript": "https://www.atom.io/api/packages/language-javascript/versions/0.130.0/tarball",
|
||||
"language-json": "https://www.atom.io/api/packages/language-json/versions/1.0.1/tarball",
|
||||
"language-json": "https://www.atom.io/api/packages/language-json/versions/1.0.2/tarball",
|
||||
"language-less": "https://www.atom.io/api/packages/language-less/versions/0.34.3/tarball",
|
||||
"language-make": "https://www.atom.io/api/packages/language-make/versions/0.23.0/tarball",
|
||||
"language-mustache": "https://www.atom.io/api/packages/language-mustache/versions/0.14.5/tarball",
|
||||
"language-objective-c": "https://www.atom.io/api/packages/language-objective-c/versions/0.15.1/tarball",
|
||||
"language-objective-c": "https://www.atom.io/api/packages/language-objective-c/versions/0.16.0/tarball",
|
||||
"language-perl": "https://www.atom.io/api/packages/language-perl/versions/0.38.1/tarball",
|
||||
"language-php": "https://www.atom.io/api/packages/language-php/versions/0.44.1/tarball",
|
||||
"language-property-list": "https://www.atom.io/api/packages/language-property-list/versions/0.9.1/tarball",
|
||||
"language-python": "https://www.atom.io/api/packages/language-python/versions/0.53.1/tarball",
|
||||
"language-python": "https://www.atom.io/api/packages/language-python/versions/0.53.2/tarball",
|
||||
"language-ruby": "https://www.atom.io/api/packages/language-ruby/versions/0.72.16/tarball",
|
||||
"language-ruby-on-rails": "https://www.atom.io/api/packages/language-ruby-on-rails/versions/0.25.3/tarball",
|
||||
"language-rust-bundled": "file:packages/language-rust-bundled",
|
||||
@@ -155,13 +155,14 @@
|
||||
"symbols-view": "https://www.atom.io/api/packages/symbols-view/versions/0.118.2/tarball",
|
||||
"tabs": "https://www.atom.io/api/packages/tabs/versions/0.110.0/tarball",
|
||||
"temp": "^0.9.0",
|
||||
"text-buffer": "13.15.3",
|
||||
"text-buffer": "13.16.0",
|
||||
"timecop": "https://www.atom.io/api/packages/timecop/versions/0.36.2/tarball",
|
||||
"tree-sitter": "0.15.0",
|
||||
"tree-sitter-css": "^0.13.7",
|
||||
"tree-view": "https://www.atom.io/api/packages/tree-view/versions/0.228.0/tarball",
|
||||
"typescript-simple": "1.0.0",
|
||||
"update-package-dependencies": "https://www.atom.io/api/packages/update-package-dependencies/versions/0.13.1/tarball",
|
||||
"vscode-ripgrep": "^1.2.5",
|
||||
"welcome": "https://www.atom.io/api/packages/welcome/versions/0.36.9/tarball",
|
||||
"whitespace": "https://www.atom.io/api/packages/whitespace/versions/0.37.7/tarball",
|
||||
"winreg": "^1.2.1",
|
||||
@@ -199,7 +200,7 @@
|
||||
"dev-live-reload": "file:./packages/dev-live-reload",
|
||||
"encoding-selector": "0.23.9",
|
||||
"exception-reporting": "file:./packages/exception-reporting",
|
||||
"find-and-replace": "0.218.10",
|
||||
"find-and-replace": "0.218.11",
|
||||
"fuzzy-finder": "1.13.3",
|
||||
"github": "0.29.0",
|
||||
"git-diff": "file:./packages/git-diff",
|
||||
@@ -240,15 +241,15 @@
|
||||
"language-hyperlink": "0.17.1",
|
||||
"language-java": "0.31.3",
|
||||
"language-javascript": "0.130.0",
|
||||
"language-json": "1.0.1",
|
||||
"language-json": "1.0.2",
|
||||
"language-less": "0.34.3",
|
||||
"language-make": "0.23.0",
|
||||
"language-mustache": "0.14.5",
|
||||
"language-objective-c": "0.15.1",
|
||||
"language-objective-c": "0.16.0",
|
||||
"language-perl": "0.38.1",
|
||||
"language-php": "0.44.1",
|
||||
"language-property-list": "0.9.1",
|
||||
"language-python": "0.53.1",
|
||||
"language-python": "0.53.2",
|
||||
"language-ruby": "0.72.16",
|
||||
"language-ruby-on-rails": "0.25.3",
|
||||
"language-rust-bundled": "file:./packages/language-rust-bundled",
|
||||
|
||||
18
resources/linux/atom.policy
Normal file
18
resources/linux/atom.policy
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE policyconfig PUBLIC
|
||||
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
|
||||
<policyconfig>
|
||||
<vendor>Atom</vendor>
|
||||
<action id="atom.pkexec.dd">
|
||||
<description gettext-domain="atom">Admin privileges required</description>
|
||||
<message gettext-domain="atom">Please enter your password to save this file</message>
|
||||
<annotate key="org.freedesktop.policykit.exec.path">/bin/dd</annotate>
|
||||
<annotate key="org.freedesktop.policykit.exec.allow_gui">true</annotate>
|
||||
<defaults>
|
||||
<allow_any>auth_admin_keep</allow_any>
|
||||
<allow_inactive>auth_admin_keep</allow_inactive>
|
||||
<allow_active>auth_admin_keep</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
</policyconfig>
|
||||
@@ -1,6 +1,6 @@
|
||||
Package: <%= appFileName %>
|
||||
Version: <%= version %>
|
||||
Depends: git, gconf2, gconf-service, libgtk-3-0 (>= 3.9.10), libudev0 | libudev1, libgcrypt11 | libgcrypt20, libnotify4, libxtst6, libnss3 (>= 2:3.22), python, gvfs-bin, xdg-utils, libcap2, libx11-xcb1, libxss1, libasound2 (>= 1.0.16), libxkbfile1, libcurl3 | libcurl4
|
||||
Depends: git, libgconf-2-4 (>= 3.2.5) | libgconf2-4, libgtk-3-0 (>= 3.9.10), libgcrypt11 | libgcrypt20, libnotify4, libxtst6, libnss3 (>= 2:3.22), python, gvfs-bin, xdg-utils, libx11-xcb1, libxss1, libasound2 (>= 1.0.16), libxkbfile1, libcurl3 | libcurl4, policykit-1
|
||||
Recommends: lsb-release
|
||||
Suggests: libsecret-1-0, gir1.2-gnomekeyring-1.0
|
||||
Section: devel
|
||||
|
||||
@@ -8,9 +8,9 @@ AutoReqProv: no # Avoid libchromiumcontent.so missing dependency
|
||||
Prefix: <%= installDir %>
|
||||
|
||||
%ifarch i386 i486 i586 i686
|
||||
Requires: lsb-core-noarch, libXss.so.1 libsecret-1.so.0
|
||||
Requires: lsb-core-noarch, libXss.so.1 libsecret-1.so.0, polkit
|
||||
%else
|
||||
Requires: lsb-core-noarch, libXss.so.1()(64bit) libsecret-1.so.0()(64bit)
|
||||
Requires: lsb-core-noarch, libXss.so.1()(64bit) libsecret-1.so.0()(64bit), polkit
|
||||
%endif
|
||||
|
||||
%description
|
||||
@@ -25,6 +25,8 @@ cp atom.sh "%{buildroot}/<%= installDir %>/bin/<%= appFileName %>"
|
||||
chmod 755 "%{buildroot}/<%= installDir %>/bin/<%= appFileName %>"
|
||||
mkdir -p "%{buildroot}/<%= installDir %>/share/applications/"
|
||||
cp "<%= appFileName %>.desktop" "%{buildroot}/<%= installDir %>/share/applications/"
|
||||
mkdir -p "%{buildroot}/<%= installDir %>/share/polkit-1/actions/"
|
||||
cp "atom.policy" "%{buildroot}/<%= installDir %>/share/polkit-1/actions/atom.policy"
|
||||
|
||||
mkdir -p "%{buildroot}/<%= installDir %>/share/icons/hicolor/1024x1024/apps"
|
||||
cp "icons/1024.png" "%{buildroot}/<%= installDir %>/share/icons/hicolor/1024x1024/apps/<%= appFileName %>.png"
|
||||
@@ -50,4 +52,5 @@ cp "icons/16.png" "%{buildroot}/<%= installDir %>/share/icons/hicolor/16x16/apps
|
||||
<%= installDir %>/bin/<%= apmFileName %>
|
||||
<%= installDir %>/share/<%= appFileName %>/
|
||||
<%= installDir %>/share/applications/<%= appFileName %>.desktop
|
||||
<%= installDir %>/share/polkit-1/actions/atom.policy
|
||||
<%= installDir %>/share/icons/hicolor/
|
||||
|
||||
@@ -21,6 +21,7 @@ const argv = yargs
|
||||
.help('help')
|
||||
.describe('existing-binaries', 'Use existing Atom binaries (skip clean/transpile/cache)')
|
||||
.describe('code-sign', 'Code-sign executables (macOS and Windows only)')
|
||||
.describe('test-sign', 'Test-sign executables (macOS only)')
|
||||
.describe('create-windows-installer', 'Create installer (Windows only)')
|
||||
.describe('create-debian-package', 'Create .deb package (Linux only)')
|
||||
.describe('create-rpm-package', 'Create .rpm package (Linux only)')
|
||||
@@ -49,6 +50,7 @@ const generateStartupSnapshot = require('./lib/generate-startup-snapshot')
|
||||
const installApplication = require('./lib/install-application')
|
||||
const packageApplication = require('./lib/package-application')
|
||||
const prebuildLessCache = require('./lib/prebuild-less-cache')
|
||||
const testSignOnMac = require('./lib/test-sign-on-mac')
|
||||
const transpileBabelPaths = require('./lib/transpile-babel-paths')
|
||||
const transpileCoffeeScriptPaths = require('./lib/transpile-coffee-script-paths')
|
||||
const transpileCsonPaths = require('./lib/transpile-cson-paths')
|
||||
@@ -92,12 +94,18 @@ if (!argv.generateApiDocs) {
|
||||
case 'darwin': {
|
||||
if (argv.codeSign) {
|
||||
codeSignOnMac(packagedAppPath)
|
||||
} else if (argv.testSign) {
|
||||
testSignOnMac(packagedAppPath)
|
||||
} else {
|
||||
console.log('Skipping code-signing. Specify the --code-sign option to perform code-signing'.gray)
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'win32': {
|
||||
if (argv.testSign) {
|
||||
console.log('Test signing is not supported on Windows, skipping.'.gray)
|
||||
}
|
||||
|
||||
if (argv.codeSign) {
|
||||
const executablesToSign = [ path.join(packagedAppPath, 'Atom.exe') ]
|
||||
if (argv.createWindowsInstaller) {
|
||||
|
||||
@@ -113,6 +113,12 @@ module.exports = function (packagedAppPath) {
|
||||
path.join(debianPackageLintianOverridesDirPath, atomExecutableName)
|
||||
)
|
||||
|
||||
console.log(`Copying polkit configuration into "${debianPackageShareDirPath}"`)
|
||||
fs.copySync(
|
||||
path.join(CONFIG.repositoryRootPath, 'resources', 'linux', 'atom.policy'),
|
||||
path.join(debianPackageShareDirPath, 'polkit-1', 'actions', 'atom.policy')
|
||||
)
|
||||
|
||||
console.log(`Generating .deb file from ${debianPackageDirPath}`)
|
||||
spawnSync('fakeroot', ['dpkg-deb', '-b', debianPackageDirPath], {stdio: 'inherit'})
|
||||
|
||||
|
||||
@@ -76,6 +76,12 @@ module.exports = function (packagedAppPath) {
|
||||
path.join(rpmPackageBuildDirPath, 'atom.sh')
|
||||
)
|
||||
|
||||
console.log(`Copying atom.policy into "${rpmPackageBuildDirPath}"`)
|
||||
fs.copySync(
|
||||
path.join(CONFIG.repositoryRootPath, 'resources', 'linux', 'atom.policy'),
|
||||
path.join(rpmPackageBuildDirPath, 'atom.policy')
|
||||
)
|
||||
|
||||
console.log(`Generating .rpm package from "${rpmPackageDirPath}"`)
|
||||
spawnSync('rpmbuild', ['-ba', '--clean', rpmPackageSpecFilePath])
|
||||
for (let generatedArch of fs.readdirSync(rpmPackageRpmsDirPath)) {
|
||||
|
||||
@@ -9,6 +9,7 @@ const CONFIG = require('../config')
|
||||
|
||||
module.exports = (packagedAppPath) => {
|
||||
const archSuffix = process.arch === 'ia32' ? '' : '-' + process.arch
|
||||
const updateUrlPrefix = process.env.ATOM_UPDATE_URL_PREFIX || 'https://atom.io'
|
||||
const options = {
|
||||
appDirectory: packagedAppPath,
|
||||
authors: 'GitHub Inc.',
|
||||
@@ -17,7 +18,7 @@ module.exports = (packagedAppPath) => {
|
||||
outputDirectory: CONFIG.buildOutputPath,
|
||||
noMsi: true,
|
||||
noDelta: CONFIG.channel === 'nightly', // Delta packages are broken for nightly versions past nightly9 due to Squirrel/NuGet limitations
|
||||
remoteReleases: `https://atom.io/api/updates${archSuffix}?version=${CONFIG.computedAppVersion}`,
|
||||
remoteReleases: `${updateUrlPrefix}/api/updates${archSuffix}?version=${CONFIG.computedAppVersion}`,
|
||||
setupExe: `AtomSetup${process.arch === 'x64' ? '-x64' : ''}.exe`,
|
||||
setupIcon: path.join(CONFIG.repositoryRootPath, 'resources', 'app-icons', CONFIG.channel, 'atom.ico')
|
||||
}
|
||||
|
||||
@@ -69,6 +69,7 @@ module.exports = function (packagedAppPath) {
|
||||
requiredModuleRelativePath === path.join('..', 'node_modules', 'yauzl', 'index.js') ||
|
||||
requiredModuleRelativePath === path.join('..', 'node_modules', 'winreg', 'lib', 'registry.js') ||
|
||||
requiredModuleRelativePath === path.join('..', 'node_modules', '@atom', 'fuzzy-native', 'lib', 'main.js') ||
|
||||
requiredModuleRelativePath === path.join('..', 'node_modules', 'vscode-ripgrep', 'lib', 'index.js') ||
|
||||
// The startup-time script is used by both the renderer and the main process and having it in the
|
||||
// snapshot causes issues.
|
||||
requiredModuleRelativePath === path.join('..', 'src', 'startup-time.js')
|
||||
|
||||
23
script/lib/test-sign-on-mac.js
Normal file
23
script/lib/test-sign-on-mac.js
Normal file
@@ -0,0 +1,23 @@
|
||||
const spawnSync = require('./spawn-sync')
|
||||
|
||||
module.exports = function (packagedAppPath) {
|
||||
const result =
|
||||
spawnSync('security', [
|
||||
'find-certificate', '-c', 'Mac Developer'
|
||||
])
|
||||
|
||||
const certMatch = (result.stdout || '').toString().match(/\"(Mac Developer.*\))\"/)
|
||||
if (!certMatch || !certMatch[1]) {
|
||||
console.error('A "Mac Developer" certificate must be configured to perform test signing')
|
||||
} else {
|
||||
// This code-signs the application with a local certificate which won't be
|
||||
// useful anywhere else but the current machine
|
||||
// See this issue for more details: https://github.com/electron/electron/issues/7476#issuecomment-356084754
|
||||
console.log(`Found development certificate '${certMatch[1]}'`)
|
||||
console.log(`Test-signing application at ${packagedAppPath}`)
|
||||
spawnSync('codesign', [
|
||||
'--deep', '--force', '--verbose',
|
||||
'--sign', certMatch[1], packagedAppPath
|
||||
], {stdio: 'inherit'})
|
||||
}
|
||||
}
|
||||
61
script/update-server/README.md
Normal file
61
script/update-server/README.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# Atom Update Test Server
|
||||
|
||||
This folder contains a simple implementation of Atom's update server to be used for testing the update process with local builds.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
On macOS, you will need to configure a "Mac Development" certificate for your local machine so that the `script/build --test-sign` parameter will work. Here are the steps to set one up:
|
||||
|
||||
1. Install Xcode if it isn't already
|
||||
1. Launch Xcode and open the Preferences dialog (<kbd>Cmd + ,</kbd>)
|
||||
1. Switch to the Accounts tab
|
||||
1. If you don't already see your Apple account in the leftmost column, click the `+` button at the bottom left of the window, select "Apple ID" and then click Continue. Sign in with your Apple account and then you'll be sent back to the Accounts tab.
|
||||
1. Click the "Manage Certificates..." button in the lower right of the Accounts page
|
||||
1. Click the `+` button in the lower left of the Signing Certificates popup and then select "Mac Development"
|
||||
1. A new certificate should now be in the list of the Signing Certificates window with the name of your macOS machine. Click "Done"
|
||||
1. In a Terminal, verify that your Mac Development certificate is set up by running
|
||||
|
||||
```
|
||||
security find-certificate -c 'Mac Developer'
|
||||
```
|
||||
|
||||
If it returns a lot of information with "Mac Developer: your@apple-id-email.com" inside of it, your certificate is configured correctly and you're now ready to run an Atom build with the `--test-sign` parameter.
|
||||
|
||||
## How to use it
|
||||
|
||||
1. Since you probably want to try upgrading an installed Atom release to a newer version, start your shell and set the `ATOM_RELEASE_VERSION` environment var to the version that you want the server to advertise as the latest version:
|
||||
|
||||
**Windows**
|
||||
```
|
||||
set ATOM_RELEASE_VERSION="1.32.0-beta1"
|
||||
```
|
||||
|
||||
**macOS**
|
||||
```
|
||||
export ATOM_RELEASE_VERSION="1.32.0-beta1"
|
||||
```
|
||||
|
||||
2. Run a full build of Atom such that the necessary release artifacts are in the `out` folder:
|
||||
|
||||
**Windows**
|
||||
```
|
||||
script/build --create-windows-installer
|
||||
```
|
||||
|
||||
**macOS**
|
||||
```
|
||||
script/build --compress-artifacts --test-sign
|
||||
```
|
||||
|
||||
3. Start up the server in this folder:
|
||||
|
||||
```
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
|
||||
**NOTE:** You can customize the port by setting the `PORT` environment variable.
|
||||
|
||||
4. Start Atom from the command line with the `ATOM_UPDATE_URL_PREFIX` environment variable set to `http://localhost:3456` (change this to reflect any `PORT` override you might have used)
|
||||
|
||||
5. Open the About page and try to update Atom. The update server will write output to the console when requests are received.
|
||||
378
script/update-server/package-lock.json
generated
Normal file
378
script/update-server/package-lock.json
generated
Normal file
@@ -0,0 +1,378 @@
|
||||
{
|
||||
"name": "atom-test-update-server",
|
||||
"version": "0.1.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"accepts": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz",
|
||||
"integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=",
|
||||
"requires": {
|
||||
"mime-types": "~2.1.18",
|
||||
"negotiator": "0.6.1"
|
||||
}
|
||||
},
|
||||
"array-flatten": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
|
||||
},
|
||||
"body-parser": {
|
||||
"version": "1.18.2",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
|
||||
"integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=",
|
||||
"requires": {
|
||||
"bytes": "3.0.0",
|
||||
"content-type": "~1.0.4",
|
||||
"debug": "2.6.9",
|
||||
"depd": "~1.1.1",
|
||||
"http-errors": "~1.6.2",
|
||||
"iconv-lite": "0.4.19",
|
||||
"on-finished": "~2.3.0",
|
||||
"qs": "6.5.1",
|
||||
"raw-body": "2.3.2",
|
||||
"type-is": "~1.6.15"
|
||||
}
|
||||
},
|
||||
"bytes": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
|
||||
"integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
|
||||
},
|
||||
"colors": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/colors/-/colors-1.3.2.tgz",
|
||||
"integrity": "sha512-rhP0JSBGYvpcNQj4s5AdShMeE5ahMop96cTeDl/v9qQQm2fYClE2QXZRi8wLzc+GmXSxdIqqbOIAhyObEXDbfQ=="
|
||||
},
|
||||
"content-disposition": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
|
||||
"integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ="
|
||||
},
|
||||
"content-type": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
|
||||
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
|
||||
},
|
||||
"cookie": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
|
||||
"integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
|
||||
},
|
||||
"cookie-signature": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"depd": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
|
||||
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
|
||||
},
|
||||
"destroy": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
|
||||
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
|
||||
},
|
||||
"ee-first": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
|
||||
},
|
||||
"encodeurl": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
|
||||
},
|
||||
"escape-html": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
|
||||
},
|
||||
"etag": {
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
||||
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
|
||||
},
|
||||
"express": {
|
||||
"version": "4.16.3",
|
||||
"resolved": "http://registry.npmjs.org/express/-/express-4.16.3.tgz",
|
||||
"integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=",
|
||||
"requires": {
|
||||
"accepts": "~1.3.5",
|
||||
"array-flatten": "1.1.1",
|
||||
"body-parser": "1.18.2",
|
||||
"content-disposition": "0.5.2",
|
||||
"content-type": "~1.0.4",
|
||||
"cookie": "0.3.1",
|
||||
"cookie-signature": "1.0.6",
|
||||
"debug": "2.6.9",
|
||||
"depd": "~1.1.2",
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"etag": "~1.8.1",
|
||||
"finalhandler": "1.1.1",
|
||||
"fresh": "0.5.2",
|
||||
"merge-descriptors": "1.0.1",
|
||||
"methods": "~1.1.2",
|
||||
"on-finished": "~2.3.0",
|
||||
"parseurl": "~1.3.2",
|
||||
"path-to-regexp": "0.1.7",
|
||||
"proxy-addr": "~2.0.3",
|
||||
"qs": "6.5.1",
|
||||
"range-parser": "~1.2.0",
|
||||
"safe-buffer": "5.1.1",
|
||||
"send": "0.16.2",
|
||||
"serve-static": "1.13.2",
|
||||
"setprototypeof": "1.1.0",
|
||||
"statuses": "~1.4.0",
|
||||
"type-is": "~1.6.16",
|
||||
"utils-merge": "1.0.1",
|
||||
"vary": "~1.1.2"
|
||||
}
|
||||
},
|
||||
"finalhandler": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
|
||||
"integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==",
|
||||
"requires": {
|
||||
"debug": "2.6.9",
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"on-finished": "~2.3.0",
|
||||
"parseurl": "~1.3.2",
|
||||
"statuses": "~1.4.0",
|
||||
"unpipe": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"forwarded": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
|
||||
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
|
||||
},
|
||||
"fresh": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
||||
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
|
||||
},
|
||||
"http-errors": {
|
||||
"version": "1.6.3",
|
||||
"resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
|
||||
"integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
|
||||
"requires": {
|
||||
"depd": "~1.1.2",
|
||||
"inherits": "2.0.3",
|
||||
"setprototypeof": "1.1.0",
|
||||
"statuses": ">= 1.4.0 < 2"
|
||||
}
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.19",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
|
||||
"integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||
},
|
||||
"ipaddr.js": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz",
|
||||
"integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4="
|
||||
},
|
||||
"media-typer": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
|
||||
},
|
||||
"merge-descriptors": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
||||
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
|
||||
},
|
||||
"methods": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
|
||||
},
|
||||
"mime": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
|
||||
"integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ=="
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.36.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz",
|
||||
"integrity": "sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw=="
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.20",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.20.tgz",
|
||||
"integrity": "sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==",
|
||||
"requires": {
|
||||
"mime-db": "~1.36.0"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
},
|
||||
"negotiator": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
|
||||
"integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
|
||||
},
|
||||
"on-finished": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
|
||||
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
|
||||
"requires": {
|
||||
"ee-first": "1.1.1"
|
||||
}
|
||||
},
|
||||
"parseurl": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
|
||||
"integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
|
||||
},
|
||||
"path-to-regexp": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
|
||||
},
|
||||
"proxy-addr": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz",
|
||||
"integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==",
|
||||
"requires": {
|
||||
"forwarded": "~0.1.2",
|
||||
"ipaddr.js": "1.8.0"
|
||||
}
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.5.1",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
|
||||
"integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A=="
|
||||
},
|
||||
"range-parser": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
|
||||
"integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
|
||||
},
|
||||
"raw-body": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",
|
||||
"integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=",
|
||||
"requires": {
|
||||
"bytes": "3.0.0",
|
||||
"http-errors": "1.6.2",
|
||||
"iconv-lite": "0.4.19",
|
||||
"unpipe": "1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"depd": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
|
||||
"integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k="
|
||||
},
|
||||
"http-errors": {
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
|
||||
"integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
|
||||
"requires": {
|
||||
"depd": "1.1.1",
|
||||
"inherits": "2.0.3",
|
||||
"setprototypeof": "1.0.3",
|
||||
"statuses": ">= 1.3.1 < 2"
|
||||
}
|
||||
},
|
||||
"setprototypeof": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
|
||||
"integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ="
|
||||
}
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
|
||||
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
|
||||
},
|
||||
"send": {
|
||||
"version": "0.16.2",
|
||||
"resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
|
||||
"integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
|
||||
"requires": {
|
||||
"debug": "2.6.9",
|
||||
"depd": "~1.1.2",
|
||||
"destroy": "~1.0.4",
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"etag": "~1.8.1",
|
||||
"fresh": "0.5.2",
|
||||
"http-errors": "~1.6.2",
|
||||
"mime": "1.4.1",
|
||||
"ms": "2.0.0",
|
||||
"on-finished": "~2.3.0",
|
||||
"range-parser": "~1.2.0",
|
||||
"statuses": "~1.4.0"
|
||||
}
|
||||
},
|
||||
"serve-static": {
|
||||
"version": "1.13.2",
|
||||
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz",
|
||||
"integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==",
|
||||
"requires": {
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"parseurl": "~1.3.2",
|
||||
"send": "0.16.2"
|
||||
}
|
||||
},
|
||||
"setprototypeof": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
|
||||
"integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
|
||||
},
|
||||
"statuses": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
|
||||
"integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew=="
|
||||
},
|
||||
"type-is": {
|
||||
"version": "1.6.16",
|
||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
|
||||
"integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
|
||||
"requires": {
|
||||
"media-typer": "0.3.0",
|
||||
"mime-types": "~2.1.18"
|
||||
}
|
||||
},
|
||||
"unpipe": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
|
||||
},
|
||||
"utils-merge": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
|
||||
},
|
||||
"vary": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
|
||||
}
|
||||
}
|
||||
}
|
||||
15
script/update-server/package.json
Normal file
15
script/update-server/package.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "atom-test-update-server",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"description": "A test update server that replicates the one on atom.io",
|
||||
"main": "run-server.js",
|
||||
"scripts": {
|
||||
"start": "node run-server.js"
|
||||
},
|
||||
"author": "David Wilson",
|
||||
"dependencies": {
|
||||
"colors": "^1.3.2",
|
||||
"express": "^4.16.3"
|
||||
}
|
||||
}
|
||||
98
script/update-server/run-server.js
Normal file
98
script/update-server/run-server.js
Normal file
@@ -0,0 +1,98 @@
|
||||
require('colors')
|
||||
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const express = require('express')
|
||||
|
||||
const app = express()
|
||||
const port = process.env.PORT || 3456
|
||||
|
||||
// Load the metadata for the local build of Atom
|
||||
const buildPath = path.resolve(__dirname, '..', '..', 'out')
|
||||
const packageJsonPath = path.join(buildPath, 'app', 'package.json')
|
||||
if (!fs.existsSync(buildPath) || !fs.existsSync(packageJsonPath)) {
|
||||
console.log(`This script requires a full Atom build with release packages for the current platform in the following path:\n ${buildPath}\n`)
|
||||
if (process.platform === 'darwin') {
|
||||
console.log(`Run this command before trying again:\n script/build --compress-artifacts --test-sign\n\n`)
|
||||
} else if (process.platform === 'win32') {
|
||||
console.log(`Run this command before trying again:\n script/build --create-windows-installer\n\n`)
|
||||
}
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const appMetadata = require(packageJsonPath)
|
||||
const versionMatch = appMetadata.version.match(/-(beta|nightly)\d+$/)
|
||||
const releaseChannel = versionMatch ? versionMatch[1] : 'stable'
|
||||
|
||||
console.log(`Serving ${appMetadata.productName} release assets (channel = ${releaseChannel})\n`.green)
|
||||
|
||||
function getMacZip (req, res) {
|
||||
console.log(`Received request for atom-mac.zip, sending it`)
|
||||
res.sendFile(path.join(buildPath, 'atom-mac.zip'))
|
||||
}
|
||||
|
||||
function getMacUpdates (req, res) {
|
||||
if (req.query.version !== appMetadata.version) {
|
||||
const updateInfo = {
|
||||
name: appMetadata.version,
|
||||
pub_date: new Date().toISOString(),
|
||||
url: `http://localhost:${port}/mac/atom-mac.zip`,
|
||||
notes: '<p>No Details</p>'
|
||||
}
|
||||
|
||||
console.log(`Received request for macOS updates (version = ${req.query.version}), sending\n`, updateInfo)
|
||||
res.json(updateInfo)
|
||||
} else {
|
||||
console.log(`Received request for macOS updates, sending 204 as Atom is up to date (version = ${req.query.version})`)
|
||||
res.sendStatus(204)
|
||||
}
|
||||
}
|
||||
|
||||
function getReleasesFile (fileName) {
|
||||
return function (req, res) {
|
||||
console.log(`Received request for ${fileName}, version: ${req.query.version}`)
|
||||
if (req.query.version) {
|
||||
const versionMatch = (req.query.version || '').match(/-(beta|nightly)\d+$/)
|
||||
const versionChannel = (versionMatch && versionMatch[1]) || 'stable'
|
||||
if (releaseChannel !== versionChannel) {
|
||||
console.log(`Atom requested an update for version ${req.query.version} but the current release channel is ${releaseChannel}`)
|
||||
res.sendStatus(404)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
res.sendFile(path.join(buildPath, fileName))
|
||||
}
|
||||
}
|
||||
|
||||
function getNupkgFile (is64bit) {
|
||||
return function (req, res) {
|
||||
let nupkgFile = req.params.nupkg
|
||||
if (is64bit) {
|
||||
const nupkgMatch = nupkgFile.match(/atom-(.+)-(delta|full)\.nupkg/)
|
||||
if (nupkgMatch) {
|
||||
nupkgFile = `atom-x64-${nupkgMatch[1]}-${nupkgMatch[2]}.nupkg`
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`Received request for ${req.params.nupkg}, sending ${nupkgFile}`)
|
||||
res.sendFile(path.join(buildPath, nupkgFile))
|
||||
}
|
||||
}
|
||||
|
||||
if (process.platform === 'darwin') {
|
||||
app.get('/mac/atom-mac.zip', getMacZip)
|
||||
app.get('/api/updates', getMacUpdates)
|
||||
} else if (process.platform === 'win32') {
|
||||
app.get('/api/updates/RELEASES', getReleasesFile('RELEASES'))
|
||||
app.get('/api/updates/:nupkg', getNupkgFile())
|
||||
app.get('/api/updates-x64/RELEASES', getReleasesFile('RELEASES-x64'))
|
||||
app.get('/api/updates-x64/:nupkg', getNupkgFile(true))
|
||||
} else {
|
||||
console.log(`The current platform '${process.platform}' doesn't support Squirrel updates, exiting.`.red)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Run Atom with ATOM_UPDATE_URL_PREFIX="http://localhost:${port}" set to test updates!\n`.yellow)
|
||||
})
|
||||
@@ -62,19 +62,17 @@ jobs:
|
||||
downloadType: 'specific'
|
||||
displayName: Download Release Artifacts
|
||||
|
||||
# NOTE: This has been disabled until one final issue has been resolved
|
||||
# around setting the SHA on GitHub releases.
|
||||
# - script: |
|
||||
# node $(Build.SourcesDirectory)\script\vsts\upload-artifacts.js --create-github-release --assets-path "$(System.ArtifactsDirectory)" --linux-repo-name "atom-staging"
|
||||
# env:
|
||||
# GITHUB_TOKEN: $(GITHUB_TOKEN)
|
||||
# ATOM_RELEASE_VERSION: $(ReleaseVersion)
|
||||
# ATOM_RELEASES_S3_KEY: $(ATOM_RELEASES_S3_KEY)
|
||||
# ATOM_RELEASES_S3_SECRET: $(ATOM_RELEASES_S3_SECRET)
|
||||
# ATOM_RELEASES_S3_BUCKET: $(ATOM_RELEASES_S3_BUCKET)
|
||||
# PACKAGE_CLOUD_API_KEY: $(PACKAGE_CLOUD_API_KEY)
|
||||
# displayName: Create Draft Release
|
||||
# condition: and(succeeded(), eq(variables['IsReleaseBranch'], 'true'))
|
||||
- script: |
|
||||
node $(Build.SourcesDirectory)\script\vsts\upload-artifacts.js --create-github-release --assets-path "$(System.ArtifactsDirectory)" --linux-repo-name "atom-staging"
|
||||
env:
|
||||
GITHUB_TOKEN: $(GITHUB_TOKEN)
|
||||
ATOM_RELEASE_VERSION: $(ReleaseVersion)
|
||||
ATOM_RELEASES_S3_KEY: $(ATOM_RELEASES_S3_KEY)
|
||||
ATOM_RELEASES_S3_SECRET: $(ATOM_RELEASES_S3_SECRET)
|
||||
ATOM_RELEASES_S3_BUCKET: $(ATOM_RELEASES_S3_BUCKET)
|
||||
PACKAGE_CLOUD_API_KEY: $(PACKAGE_CLOUD_API_KEY)
|
||||
displayName: Create Draft Release
|
||||
condition: and(succeeded(), eq(variables['Atom.AutoDraftRelease'], 'true'), eq(variables['IsReleaseBranch'], 'true'))
|
||||
|
||||
- script: |
|
||||
node $(Build.SourcesDirectory)\script\vsts\upload-artifacts.js --assets-path "$(System.ArtifactsDirectory)" --s3-path "vsts-artifacts/$(Build.BuildId)/"
|
||||
|
||||
@@ -4,6 +4,7 @@ const fs = require('fs')
|
||||
const os = require('os')
|
||||
const path = require('path')
|
||||
const glob = require('glob')
|
||||
const spawnSync = require('../lib/spawn-sync')
|
||||
const publishRelease = require('publish-release')
|
||||
const releaseNotes = require('./lib/release-notes')
|
||||
const uploadToS3 = require('./lib/upload-to-s3')
|
||||
@@ -93,6 +94,11 @@ async function uploadArtifacts () {
|
||||
|
||||
console.log(`New release notes:\n\n${newReleaseNotes}`)
|
||||
|
||||
const releaseSha =
|
||||
!isNightlyRelease
|
||||
? spawnSync('git', ['rev-parse', 'HEAD']).stdout.toString().trimEnd()
|
||||
: 'master' // Nightly tags are created in atom/atom-nightly-releases so the SHA is irrelevant
|
||||
|
||||
console.log(`Creating GitHub release v${releaseVersion}`)
|
||||
const release =
|
||||
await publishReleaseAsync({
|
||||
@@ -101,6 +107,7 @@ async function uploadArtifacts () {
|
||||
repo: !isNightlyRelease ? 'atom' : 'atom-nightly-releases',
|
||||
name: CONFIG.computedAppVersion,
|
||||
notes: newReleaseNotes,
|
||||
target_commitish: releaseSha,
|
||||
tag: `v${CONFIG.computedAppVersion}`,
|
||||
draft: !isNightlyRelease,
|
||||
prerelease: CONFIG.channel !== 'stable',
|
||||
|
||||
19
spec/fixtures/dir/c
vendored
Normal file
19
spec/fixtures/dir/c
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
line 1
|
||||
line 2
|
||||
line 3
|
||||
line 4
|
||||
line 5
|
||||
result 1
|
||||
line 6
|
||||
line 7
|
||||
line 8
|
||||
line 9
|
||||
line 10
|
||||
result 2
|
||||
result 3
|
||||
line 11
|
||||
line 12
|
||||
result 4
|
||||
line 13
|
||||
line 14
|
||||
line 15
|
||||
3
spec/fixtures/dir/file-detected-as-binary
vendored
Normal file
3
spec/fixtures/dir/file-detected-as-binary
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
asciiProperty=Foo
|
||||
utf8Property=Fòò
|
||||
latin1Property=Fòò
|
||||
7
spec/fixtures/dir/file-with-newline-literal
vendored
Normal file
7
spec/fixtures/dir/file-with-newline-literal
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
newline1
|
||||
newline2
|
||||
newline3
|
||||
first
|
||||
second\nthird
|
||||
newline4
|
||||
newline5
|
||||
1
spec/fixtures/dir/file-with-unicode
vendored
Normal file
1
spec/fixtures/dir/file-with-unicode
vendored
Normal file
@@ -0,0 +1 @@
|
||||
ДДДДДДДДДДДДДДДДДД line with unicode
|
||||
File diff suppressed because it is too large
Load Diff
@@ -71,7 +71,7 @@ module.exports = class DefaultDirectorySearcher {
|
||||
// * `filePath` {String} absolute path to the matching file.
|
||||
// * `matches` {Array} with object elements with the following keys:
|
||||
// * `lineText` {String} The full text of the matching line (without a line terminator character).
|
||||
// * `lineTextOffset` {Number} (This always seems to be 0?)
|
||||
// * `lineTextOffset` {Number} If > 0, the provided line text is truncated and starts at this offset
|
||||
// * `matchText` {String} The text that matched the `regex` used for the search.
|
||||
// * `range` {Range} Identifies the matching region in the file. (Likely as an array of numeric arrays.)
|
||||
// * `didError` {Function} call with an Error if there is a problem during the search.
|
||||
|
||||
@@ -22,15 +22,16 @@ class AutoUpdateManager extends EventEmitter {
|
||||
this.config = config
|
||||
this.state = IdleState
|
||||
this.iconPath = path.resolve(__dirname, '..', '..', 'resources', 'atom.png')
|
||||
this.updateUrlPrefix = process.env.ATOM_UPDATE_URL_PREFIX || 'https://atom.io'
|
||||
}
|
||||
|
||||
initialize () {
|
||||
if (process.platform === 'win32') {
|
||||
const archSuffix = process.arch === 'ia32' ? '' : `-${process.arch}`
|
||||
this.feedUrl = `https://atom.io/api/updates${archSuffix}?version=${this.version}`
|
||||
this.feedUrl = `${this.updateUrlPrefix}/api/updates${archSuffix}?version=${this.version}`
|
||||
autoUpdater = require('./auto-updater-win32')
|
||||
} else {
|
||||
this.feedUrl = `https://atom.io/api/updates?version=${this.version}`;
|
||||
this.feedUrl = `${this.updateUrlPrefix}/api/updates?version=${this.version}`;
|
||||
({autoUpdater} = require('electron'))
|
||||
}
|
||||
|
||||
|
||||
399
src/ripgrep-directory-searcher.js
Normal file
399
src/ripgrep-directory-searcher.js
Normal file
@@ -0,0 +1,399 @@
|
||||
const { spawn } = require('child_process')
|
||||
const path = require('path')
|
||||
|
||||
// `ripgrep` and `scandal` have a different way of handling the trailing and leading
|
||||
// context lines:
|
||||
// * `scandal` returns all the context lines that are requested, even if they include
|
||||
// previous or future results.
|
||||
// * `ripgrep` is a bit smarter and only returns the context lines that do not correspond
|
||||
// to any result (in a similar way that is shown in the find and replace UI).
|
||||
//
|
||||
// For example, if we have the following file and we request to leading context lines:
|
||||
//
|
||||
// line 1
|
||||
// line 2
|
||||
// result 1
|
||||
// result 2
|
||||
// line 3
|
||||
// line 4
|
||||
//
|
||||
// `scandal` will return two results:
|
||||
// * First result with `['line 1', line 2']` as leading context.
|
||||
// * Second result with `['line 2', result 1']` as leading context.
|
||||
// `ripgrep` on the other hand will return a JS object that is more similar to the way that
|
||||
// the results are shown:
|
||||
// [
|
||||
// {type: 'begin', ...},
|
||||
// {type: 'context', ...}, // context for line 1
|
||||
// {type: 'context', ...}, // context for line 2
|
||||
// {type: 'match', ...}, // result 1
|
||||
// {type: 'match', ...}, // result 2
|
||||
// {type: 'end', ...},
|
||||
// ]
|
||||
//
|
||||
// In order to keep backwards compatibility, and avoid doing changes to the find and replace logic,
|
||||
// for `ripgrep` we need to keep some state with the context lines (and matches) to be able to build
|
||||
// a data structure that has the same behaviour as the `scandal` one.
|
||||
//
|
||||
// We use the `pendingLeadingContext` array to generate the leading context. This array gets mutated
|
||||
// to always contain the leading `n` lines and is cloned every time a match is found. It's currently
|
||||
// implemented as a standard array but we can easily change it to use a linked list if we find that
|
||||
// the shift operations are slow.
|
||||
//
|
||||
// We use the `pendingTrailingContexts` Set to generate the trailing context. Since the trailing
|
||||
// context needs to be generated after receiving a match, we keep all trailing context arrays that
|
||||
// haven't been fulfilled in this Set, and mutate them adding new lines until they are fulfilled.
|
||||
|
||||
function updateLeadingContext (message, pendingLeadingContext, options) {
|
||||
if (message.type !== 'match' && message.type !== 'context') {
|
||||
return
|
||||
}
|
||||
|
||||
if (options.leadingContextLineCount) {
|
||||
pendingLeadingContext.push(cleanResultLine(message.data.lines))
|
||||
|
||||
if (pendingLeadingContext.length > options.leadingContextLineCount) {
|
||||
pendingLeadingContext.shift()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateTrailingContexts (message, pendingTrailingContexts, options) {
|
||||
if (message.type !== 'match' && message.type !== 'context') {
|
||||
return
|
||||
}
|
||||
|
||||
if (options.trailingContextLineCount) {
|
||||
for (const trailingContextLines of pendingTrailingContexts) {
|
||||
trailingContextLines.push(cleanResultLine(message.data.lines))
|
||||
|
||||
if (trailingContextLines.length === options.trailingContextLineCount) {
|
||||
pendingTrailingContexts.delete(trailingContextLines)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function cleanResultLine (resultLine) {
|
||||
resultLine = getText(resultLine)
|
||||
|
||||
return resultLine[resultLine.length - 1] === '\n' ? resultLine.slice(0, -1) : resultLine
|
||||
}
|
||||
|
||||
function getPositionFromColumn (lines, column) {
|
||||
let currentLength = 0
|
||||
let currentLine = 0
|
||||
let previousLength = 0
|
||||
|
||||
while (column >= currentLength) {
|
||||
previousLength = currentLength
|
||||
currentLength += lines[currentLine].length + 1
|
||||
currentLine++
|
||||
}
|
||||
|
||||
return [currentLine - 1, column - previousLength]
|
||||
}
|
||||
|
||||
function processUnicodeMatch (match) {
|
||||
const text = getText(match.lines)
|
||||
|
||||
if (text.length === Buffer.byteLength(text)) {
|
||||
// fast codepath for lines that only contain characters of 1 byte length.
|
||||
return
|
||||
}
|
||||
|
||||
let remainingBuffer = Buffer.from(text)
|
||||
let currentLength = 0
|
||||
let previousPosition = 0
|
||||
|
||||
function convertPosition (position) {
|
||||
const currentBuffer = remainingBuffer.slice(0, position - previousPosition)
|
||||
currentLength = currentBuffer.toString().length + currentLength
|
||||
remainingBuffer = remainingBuffer.slice(position)
|
||||
|
||||
previousPosition = position
|
||||
|
||||
return currentLength
|
||||
}
|
||||
|
||||
// Iterate over all the submatches to find the convert the start and end values
|
||||
// (which come as bytes from ripgrep) to character positions.
|
||||
// We can do this because submatches come ordered by position.
|
||||
for (const submatch of match.submatches) {
|
||||
submatch.start = convertPosition(submatch.start)
|
||||
submatch.end = convertPosition(submatch.end)
|
||||
}
|
||||
}
|
||||
|
||||
// This function processes a ripgrep submatch to create the correct
|
||||
// range. This is mostly needed for multi-line results, since the range
|
||||
// will have differnt start and end rows and we need to calculate these
|
||||
// based on the lines that ripgrep returns.
|
||||
function processSubmatch (submatch, lineText, offsetRow) {
|
||||
const lineParts = lineText.split('\n')
|
||||
|
||||
const start = getPositionFromColumn(lineParts, submatch.start)
|
||||
const end = getPositionFromColumn(lineParts, submatch.end)
|
||||
|
||||
// Make sure that the lineText string only contains lines that are
|
||||
// relevant to this submatch. This means getting rid of lines above
|
||||
// the start row and below the end row.
|
||||
for (let i = start[0]; i > 0; i--) {
|
||||
lineParts.shift()
|
||||
}
|
||||
while (end[0] < lineParts.length - 1) {
|
||||
lineParts.pop()
|
||||
}
|
||||
|
||||
start[0] += offsetRow
|
||||
end[0] += offsetRow
|
||||
|
||||
return {
|
||||
range: [start, end],
|
||||
lineText: cleanResultLine({ text: lineParts.join('\n') })
|
||||
}
|
||||
}
|
||||
|
||||
function getText (input) {
|
||||
return input.text ? input.text : Buffer.from(input.bytes, 'base64').toString()
|
||||
}
|
||||
|
||||
module.exports = class RipgrepDirectorySearcher {
|
||||
canSearchDirectory () {
|
||||
return true
|
||||
}
|
||||
|
||||
// Performs a text search for files in the specified `Directory`s, subject to the
|
||||
// specified parameters.
|
||||
//
|
||||
// Results are streamed back to the caller by invoking methods on the specified `options`,
|
||||
// such as `didMatch` and `didError`.
|
||||
//
|
||||
// * `directories` {Array} of {Directory} objects to search, all of which have been accepted by
|
||||
// this searcher's `canSearchDirectory()` predicate.
|
||||
// * `regex` {RegExp} to search with.
|
||||
// * `options` {Object} with the following properties:
|
||||
// * `didMatch` {Function} call with a search result structured as follows:
|
||||
// * `searchResult` {Object} with the following keys:
|
||||
// * `filePath` {String} absolute path to the matching file.
|
||||
// * `matches` {Array} with object elements with the following keys:
|
||||
// * `lineText` {String} The full text of the matching line (without a line terminator character).
|
||||
// * `lineTextOffset` {Number} Always 0, present for backwards compatibility
|
||||
// * `matchText` {String} The text that matched the `regex` used for the search.
|
||||
// * `range` {Range} Identifies the matching region in the file. (Likely as an array of numeric arrays.)
|
||||
// * `didError` {Function} call with an Error if there is a problem during the search.
|
||||
// * `didSearchPaths` {Function} periodically call with the number of paths searched that contain results thus far.
|
||||
// * `inclusions` {Array} of glob patterns (as strings) to search within. Note that this
|
||||
// array may be empty, indicating that all files should be searched.
|
||||
//
|
||||
// Each item in the array is a file/directory pattern, e.g., `src` to search in the "src"
|
||||
// directory or `*.js` to search all JavaScript files. In practice, this often comes from the
|
||||
// comma-delimited list of patterns in the bottom text input of the ProjectFindView dialog.
|
||||
// * `ignoreHidden` {boolean} whether to ignore hidden files.
|
||||
// * `excludeVcsIgnores` {boolean} whether to exclude VCS ignored paths.
|
||||
// * `exclusions` {Array} similar to inclusions
|
||||
// * `follow` {boolean} whether symlinks should be followed.
|
||||
//
|
||||
// Returns a *thenable* `DirectorySearch` that includes a `cancel()` method. If `cancel()` is
|
||||
// invoked before the `DirectorySearch` is determined, it will resolve the `DirectorySearch`.
|
||||
search (directories, regexp, options) {
|
||||
const numPathsFound = { num: 0 }
|
||||
|
||||
const allPromises = directories.map(
|
||||
directory => this.searchInDirectory(directory, regexp, options, numPathsFound)
|
||||
)
|
||||
|
||||
const promise = Promise.all(allPromises)
|
||||
|
||||
promise.cancel = () => {
|
||||
for (const promise of allPromises) {
|
||||
promise.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
return promise
|
||||
}
|
||||
|
||||
searchInDirectory (directory, regexp, options, numPathsFound) {
|
||||
// Delay the require of vscode-ripgrep to not mess with the snapshot creation.
|
||||
if (!this.rgPath) {
|
||||
this.rgPath = require('vscode-ripgrep').rgPath.replace(/\bapp\.asar\b/, 'app.asar.unpacked')
|
||||
}
|
||||
|
||||
const directoryPath = directory.getPath()
|
||||
const regexpStr = this.prepareRegexp(regexp.source)
|
||||
|
||||
const args = ['--hidden', '--json', '--regexp', regexpStr]
|
||||
if (options.leadingContextLineCount) {
|
||||
args.push('--before-context', options.leadingContextLineCount)
|
||||
}
|
||||
if (options.trailingContextLineCount) {
|
||||
args.push('--after-context', options.trailingContextLineCount)
|
||||
}
|
||||
if (regexp.ignoreCase) {
|
||||
args.push('--ignore-case')
|
||||
}
|
||||
for (const inclusion of this.prepareGlobs(options.inclusions, directoryPath)) {
|
||||
args.push('--glob', inclusion)
|
||||
}
|
||||
for (const exclusion of this.prepareGlobs(options.exclusions, directoryPath)) {
|
||||
args.push('--glob', '!' + exclusion)
|
||||
}
|
||||
|
||||
if (this.isMultilineRegexp(regexpStr)) {
|
||||
args.push('--multiline')
|
||||
}
|
||||
|
||||
args.push(directoryPath)
|
||||
|
||||
const child = spawn(this.rgPath, args, {
|
||||
cwd: directory.getPath(),
|
||||
stdio: ['pipe', 'pipe', 'pipe']
|
||||
})
|
||||
|
||||
const didMatch = options.didMatch || (() => {})
|
||||
let cancelled = false
|
||||
|
||||
const returnedPromise = new Promise((resolve, reject) => {
|
||||
let buffer = ''
|
||||
let bufferError = ''
|
||||
let pendingEvent
|
||||
let pendingLeadingContext
|
||||
let pendingTrailingContexts
|
||||
|
||||
child.on('close', (code, signal) => {
|
||||
// code 1 is used when no results are found.
|
||||
if (code !== null && code > 1) {
|
||||
reject(new Error(bufferError))
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
|
||||
child.stderr.on('data', chunk => {
|
||||
bufferError += chunk
|
||||
})
|
||||
|
||||
child.stdout.on('data', chunk => {
|
||||
if (cancelled) {
|
||||
return
|
||||
}
|
||||
|
||||
buffer += chunk
|
||||
const lines = buffer.split('\n')
|
||||
buffer = lines.pop()
|
||||
for (const line of lines) {
|
||||
const message = JSON.parse(line)
|
||||
updateTrailingContexts(message, pendingTrailingContexts, options)
|
||||
|
||||
if (message.type === 'begin') {
|
||||
pendingEvent = {
|
||||
filePath: getText(message.data.path),
|
||||
matches: []
|
||||
}
|
||||
pendingLeadingContext = []
|
||||
pendingTrailingContexts = new Set()
|
||||
} else if (message.type === 'match') {
|
||||
const trailingContextLines = []
|
||||
pendingTrailingContexts.add(trailingContextLines)
|
||||
|
||||
processUnicodeMatch(message.data)
|
||||
|
||||
for (const submatch of message.data.submatches) {
|
||||
const { lineText, range } = processSubmatch(
|
||||
submatch,
|
||||
getText(message.data.lines),
|
||||
message.data.line_number - 1
|
||||
)
|
||||
|
||||
pendingEvent.matches.push({
|
||||
matchText: getText(submatch.match),
|
||||
lineText,
|
||||
lineTextOffset: 0,
|
||||
range,
|
||||
leadingContextLines: [...pendingLeadingContext],
|
||||
trailingContextLines
|
||||
})
|
||||
}
|
||||
} else if (message.type === 'end') {
|
||||
options.didSearchPaths(++numPathsFound.num)
|
||||
didMatch(pendingEvent)
|
||||
pendingEvent = null
|
||||
}
|
||||
|
||||
updateLeadingContext(message, pendingLeadingContext, options)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
returnedPromise.cancel = () => {
|
||||
child.kill()
|
||||
cancelled = true
|
||||
}
|
||||
|
||||
return returnedPromise
|
||||
}
|
||||
|
||||
// We need to prepare the "globs" that we receive from the user to make their behaviour more
|
||||
// user-friendly (e.g when adding `src/` the user probably means `src/**/*`).
|
||||
// This helper function takes care of that.
|
||||
prepareGlobs (globs, projectRootPath) {
|
||||
const output = []
|
||||
|
||||
for (let pattern of globs) {
|
||||
// we need to replace path separators by slashes since globs should
|
||||
// always use always slashes as path separators.
|
||||
pattern = pattern.replace(new RegExp(`\\${path.sep}`, 'g'), '/')
|
||||
|
||||
if (pattern.length === 0) {
|
||||
continue
|
||||
}
|
||||
|
||||
const projectName = path.basename(projectRootPath)
|
||||
|
||||
// The user can just search inside one of the opened projects. When we detect
|
||||
// this scenario we just consider the glob to include every file.
|
||||
if (pattern === projectName) {
|
||||
output.push('**/*')
|
||||
continue
|
||||
}
|
||||
|
||||
if (pattern.startsWith(projectName + '/')) {
|
||||
pattern = pattern.slice(projectName.length + 1)
|
||||
}
|
||||
|
||||
if (pattern.endsWith('/')) {
|
||||
pattern = pattern.slice(0, -1)
|
||||
}
|
||||
|
||||
pattern = pattern.startsWith('**/') ? pattern : `**/${pattern}`
|
||||
|
||||
output.push(pattern)
|
||||
output.push(pattern.endsWith('/**') ? pattern : `${pattern}/**`)
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
prepareRegexp (regexpStr) {
|
||||
// ripgrep handles `--` as the arguments separator, so we need to escape it if the
|
||||
// user searches for that exact same string.
|
||||
if (regexpStr === '--') {
|
||||
return '\\-\\-'
|
||||
}
|
||||
|
||||
// ripgrep is quite picky about unnecessarily escaped sequences, so we need to unescape
|
||||
// them: https://github.com/BurntSushi/ripgrep/issues/434.
|
||||
regexpStr = regexpStr.replace(/\\\//g, '/')
|
||||
|
||||
return regexpStr
|
||||
}
|
||||
|
||||
isMultilineRegexp (regexpStr) {
|
||||
if (regexpStr.includes('\\n')) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ const fs = require('fs-plus')
|
||||
const {Directory} = require('pathwatcher')
|
||||
const Grim = require('grim')
|
||||
const DefaultDirectorySearcher = require('./default-directory-searcher')
|
||||
const RipgrepDirectorySearcher = require('./ripgrep-directory-searcher')
|
||||
const Dock = require('./dock')
|
||||
const Model = require('./model')
|
||||
const StateStore = require('./state-store')
|
||||
@@ -203,7 +204,8 @@ module.exports = class Workspace extends Model {
|
||||
this.destroyedItemURIs = []
|
||||
this.stoppedChangingActivePaneItemTimeout = null
|
||||
|
||||
this.defaultDirectorySearcher = new DefaultDirectorySearcher()
|
||||
this.scandalDirectorySearcher = new DefaultDirectorySearcher()
|
||||
this.ripgrepDirectorySearcher = new RipgrepDirectorySearcher()
|
||||
this.consumeServices(this.packageManager)
|
||||
|
||||
this.paneContainers = {
|
||||
@@ -1853,7 +1855,7 @@ module.exports = class Workspace extends Model {
|
||||
// will be associated with an Array of Directory objects in the Map.
|
||||
const directoriesForSearcher = new Map()
|
||||
for (const directory of this.project.getDirectories()) {
|
||||
let searcher = this.defaultDirectorySearcher
|
||||
let searcher = options.ripgrep ? this.ripgrepDirectorySearcher : this.scandalDirectorySearcher
|
||||
for (const directorySearcher of this.directorySearchers) {
|
||||
if (directorySearcher.canSearchDirectory(directory)) {
|
||||
searcher = directorySearcher
|
||||
@@ -1926,7 +1928,7 @@ module.exports = class Workspace extends Model {
|
||||
var matches = []
|
||||
buffer.scan(regex, match => matches.push(match))
|
||||
if (matches.length > 0) {
|
||||
iterator({filePath, matches})
|
||||
iterator({ filePath, matches })
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1945,9 +1947,9 @@ module.exports = class Workspace extends Model {
|
||||
}
|
||||
}
|
||||
|
||||
const onFailure = function () {
|
||||
const onFailure = function (error) {
|
||||
for (let promise of allSearches) { promise.cancel() }
|
||||
reject()
|
||||
reject(error)
|
||||
}
|
||||
|
||||
searchPromise.then(onSuccess, onFailure)
|
||||
@@ -1960,12 +1962,6 @@ module.exports = class Workspace extends Model {
|
||||
allSearches.map((promise) => promise.cancel())
|
||||
}
|
||||
|
||||
// Although this method claims to return a `Promise`, the `ResultsPaneView.onSearch()`
|
||||
// method in the find-and-replace package expects the object returned by this method to have a
|
||||
// `done()` method. Include a done() method until find-and-replace can be updated.
|
||||
cancellablePromise.done = onSuccessOrFailure => {
|
||||
cancellablePromise.then(onSuccessOrFailure, onSuccessOrFailure)
|
||||
}
|
||||
return cancellablePromise
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user