Compare commits

..

308 Commits
1.5.1 ... 1.7.0

Author SHA1 Message Date
Alan Yu
295004c42e Adding CMS readme (#5417) 2019-05-07 17:59:15 -07:00
Alan Ren
45333e8852 bump the version of schema compare extension (#5411) 2019-05-07 17:59:06 -07:00
Aditya Bist
e1280022d6 Fix agent css in packaged builds (#5409)
* fix agent css in packaged

* fix agent css
2019-05-07 14:24:22 -07:00
Karl Burtram
c90d630703 Bump agent, import, profiler extension versions (#5405) 2019-05-07 13:03:28 -07:00
Karl Burtram
bfcdf28cbc Merge branch 'release/1.7' of https://github.com/Microsoft/azuredatastudio into release/1.7 2019-05-07 12:35:58 -07:00
Anthony Dresser
1c694cbd3b Fix css to fix new dashboard tab dialog (#5385)
* fix css to fix new dashboard tab dialog

* add readonly
2019-05-07 09:08:13 -07:00
kisantia
2b0aba119d bump dacpac extension version (#5387) 2019-05-07 09:08:04 -07:00
Karl Burtram
59cc8e5d7f Bump the VS Code version metadata (#5392) 2019-05-07 09:07:53 -07:00
Chris LaFreniere
f8da5bd1c7 Don't scroll when running code cell if in view (#5365) 2019-05-07 09:03:19 -07:00
Anthony Dresser
26667eb1dc Fix css to fix new dashboard tab dialog (#5385)
* fix css to fix new dashboard tab dialog

* add readonly
2019-05-06 17:33:26 -07:00
kisantia
5e6a9ca9fa bump dacpac extension version (#5387) 2019-05-06 17:33:19 -07:00
Karl Burtram
4ecf5fae84 Bump the VS Code version metadata (#5392) 2019-05-06 17:33:13 -07:00
Alan Ren
f76500d5f0 fix profiler formatter issue (#5372) 2019-05-06 15:58:55 -07:00
Maddy
2a212edf1e Maddy/newline overrides edit data (#5364)
* formatting it before displaying

* replace with space

* added comments and method to handle the line break space conversion
2019-05-06 15:58:47 -07:00
Anthony Dresser
7bcd19987b add a applystyle function with saftey checks in header filter (#5380) 2019-05-06 15:58:39 -07:00
Anthony Dresser
0ce5f02dd2 fix error icon (#5373) 2019-05-06 15:58:31 -07:00
udeeshagautam
0831e9e161 Changing the start for Schema compare and adding some text (#5356)
* Dialog Ok will not start Schema compare explit compare will. Adding wait text.

* Fixing variable name and spelling
2019-05-06 15:58:20 -07:00
Aditya Bist
39f9c72390 fixed packaged icons for azure (#5354) 2019-05-03 18:47:45 -07:00
Anthony Dresser
0023714884 Fix menu entry for tasks (#5355)
* fix menu entry for tasks

* change wording for action
2019-05-03 18:20:51 -07:00
kisantia
ec9fdc517f Fix schema compare dialog font sizes (#5353)
* make font sizes consistent

* fix order of source dialog options

* update fontsize to 13

* make fontsize a constant
2019-05-04 10:48:25 +12:00
Anthony Dresser
db387eb770 Fixing the layering in the base folder (#5308)
* removes more builder references

* remove builder from profiler

* formatting

* fix profiler dailog

* remove builder from oatuhdialog

* remove the rest of builder references

* formatting

* add more strict null checks to base

* enable strict tslint rules

* code layering of base

* wip

* working through changes to table data view

* fix tests

* update editabledropdown to not use layout service

* wip

* fix imports

* fix import

* fix compile error

* add more localization

* add comments to changes to import patterns

* add more import comments
2019-05-03 14:49:18 -07:00
kisantia
354ed22706 Fix #5314: schema compare doesn't always open with correct default connection (#5315)
* fix schema compare default connection when there are multiple connections
2019-05-04 09:40:53 +12:00
Aditya Bist
a69f194d8b Fixed CMS connection auth (#5306)
* fixed auth change to reflect in UI

* added comments

* fix bug where cms shows in dropdown

* added parameter to parent call
2019-05-03 13:26:04 -07:00
Aditya Bist
f5d13319a2 Remove CMS from packaged builds (#5349)
* remove cmss from packaged builds

* add repo to package file

* added cms to recommendations
2019-05-03 13:25:47 -07:00
Yurong He
9a0e691635 Change toolbar icon back to black (#5345)
* Change it back to black icon

* Install package icon
2019-05-03 13:11:44 -07:00
kisantia
6c7cb185a1 group source and target components into formcomponentgroups (#5329) 2019-05-04 05:51:40 +12:00
Charles Gagnon
ab22b93ce0 SsmsMin integration clean-up and improvements (#5339)
* SsmsMin integration clean-up and improvements

* Fix tests
2019-05-03 08:44:21 -07:00
Karl Burtram
c7f5278430 Remove 'Try backup or restore task' from task message (#5340) 2019-05-02 18:52:11 -07:00
Anthony Dresser
56ad0dbaf2 revert changes to common file and move icons to specific folder (#5335) 2019-05-02 18:14:13 -07:00
Anthony Dresser
74c92cd460 disable page scrolling in slickgrid (#5333) 2019-05-02 18:13:49 -07:00
Alan Ren
16ebb4322a fix insights dialog issue (#5336) 2019-05-02 18:13:33 -07:00
kisantia
fccd026812 Remove database name from schema compare source/target server field (#5327)
* remove database name from source/target server field
2019-05-03 11:20:28 +12:00
Charles Gagnon
b6e49f2bc0 Fix connections from editor not saving to MRU (#5328) 2019-05-02 16:08:46 -07:00
Karl Burtram
188ccf849d Fix nullref exception in connection profile (#5330)
* Fix nullref exception in connection profile

* Fix condition
2019-05-02 16:04:03 -07:00
Anthony Dresser
1bfdce9642 fix icons for various status; move menu entry to the other panels (#5319) 2019-05-02 14:31:58 -07:00
Karl Burtram
495254b0be Remove package-lock.json from extension sample (#5324) 2019-05-02 13:41:48 -07:00
Charles Gagnon
d209ff7b9a Fix broken CMS test and add to test-extensions-unit scripts (#5301) 2019-05-02 11:13:30 -07:00
Yurong He
98eeb50060 Fixed #4953 provider create file action when file is deleted (#5283)
* Fixed #4953 following query editor behavior provide create file option when file name doesn't exist

* Check active edtior is the correct one before closing

* close editor

* Removed codes not needed

* Check error null
2019-05-02 10:59:46 -07:00
Chris LaFreniere
8a68f0aaf9 Improvements to notebook editor code auto height (#5291) 2019-05-02 10:23:26 -07:00
Anthony Dresser
039859213c Replace observable references with just promises (#5278)
* replace observable references with just promises

* add tests for searching in dataview

* add comments

* work through respecting max matches

* fix tests

* fix strict null checks
2019-05-02 00:06:28 -07:00
Alan Ren
a3c022aebf Update dropdown.ts (#5290)
* Update dropdown.ts

fix the issue that the filtering feature is not working

* format the doc

* comments
2019-05-01 22:55:53 -07:00
Anthony Dresser
3a9b32b6e8 Task item look update (#5299)
* wip

* wip

* wip
2019-05-01 13:25:18 -07:00
Karl Burtram
c1cb9000a9 Various results grid scrolling fixes (#5285) 2019-05-01 12:36:16 -07:00
Kevin Cunnane
104b99ffa0 Fix #4553 Azure account prompt (#5303)
"Are you sure" prompt on removing Azure account does not respect "No"
2019-05-01 12:28:36 -07:00
Charles Gagnon
a89d7f327a Update SsmsMin to 15.0.18120.0 (#5293) 2019-05-01 11:29:36 -07:00
Charles Gagnon
91bc4bde3c Change default timeout value to 30sec to match SSMS (#5289) 2019-05-01 11:19:40 -07:00
Charles Gagnon
80da7ad496 Fix broken CMS commands (#5296) 2019-05-01 10:55:58 -07:00
Charles Gagnon
64bf211a45 Fix failing OE Tests caused by changes in connection API defaults (#5295)
* Fix failing OE Tests caused by changes in connection API defaults

* More spelling fixes
2019-05-01 10:18:23 -07:00
Anthony Dresser
2558a66a48 Merge from vscode 473af338e1bd9ad4d9853933da1cd9d5d9e07dc9 (#5286) 2019-04-30 21:53:52 -07:00
kisantia
df22eab4ec fix diff editor title disappearing after swap (#5280) 2019-05-01 11:30:03 +12:00
Aditya Bist
c2678cf818 Committer work - Agent tests (#5034)
* added couple tests

* added unit tests for agent extension

* added agent test in test script
2019-04-30 16:25:16 -07:00
Yurong He
f9af34b103 Notebook toolbar UI improvement (#5282)
Fixed  #5236
- Change the icon to blue image. Existing icons are not deleted. We will use them when the icons are - - moved as the secondary actions.
- Change the font size to 13px
- Change the height to 21px
- Move Add actions to the left
2019-04-30 16:18:48 -07:00
Charles Gagnon
97cab22e00 Add more SsmsMin interactions (#5267)
* Add support for more SsmsMin property dialogs and the Generate Script Wizard. Also fixed bug with ExtHostObjectExplorerNode getParent function

* Localize package.json entries

* Fix localization tokens

* Address PR comments

* Fix regex and getParent
2019-04-30 16:10:11 -07:00
Kevin Cunnane
64416e05c1 Notebook StdIn support to fix #5231 (#5232)
Fixes #5231 
- Add stdin handling. Has to be at UI level so add plumb through handling
- Add unit tests
- Add new StdIn component.

Testing:
Unit Tests and manual testing of following:
- Prompt for password using `getpass` in python.
   - Password prompt is hidden since "password" is true.
   - Hit enter, it completes
- prompt, stop cell running, StdIn disappears
- prompt, hit escape, stdIn disappears and stdIn request is handled.

Issues: focus isn't always set to the input even though we call focus.
Will investigate this further.
2019-04-30 14:57:27 -07:00
Kevin Cunnane
b21125ff2d Fix markdown security and enable most CSS (#5263)
* Fix markdown security and enable most CSS

Stops using our sanitizer and instead disables HTML in markdown engine
- This was blocking Note because it converted > to >
- It's slightly more strict in that it fully disables HTML unless trusted. Will need to improve handling of Trusted to support this in a future PR

Adds in correct CSS, both from .css file in markdown extension and from built-into all webviews global CSS
- Fix #3765 standard markdown support
- Fix Support of Notes by bringing correct styles
- Fix code block colorization
- Fix link handling so it's not bolded / gets underlined on hover
- Fixes table rendering (for markdown and HTML tables)

* Reduce scope of CSS changes
- Removed some CSS that wasn't needed or caused issues
- Scoped most things under the preview section not the whole component

* Avoid markdown html block by sanitizing after render

* Fix pre node not overflowing
- This was a bug in existing implementation too
2019-04-30 14:21:20 -07:00
Chris LaFreniere
e72d0d03ed Notebooks: More Jupyter Server Hardening (#5264)
* Do not rely on same starting port every time, misc

* put back to 5 seconds for process kill timeout

* extHostNotebook shutdown manager handle
2019-04-30 14:13:04 -07:00
Anthony Dresser
0f12d15020 Refactor connection store (#5024)
* various clean ups

* formatting

* remove linting

* formatting

* IConfigurationService is even better

* messing with connection config tests

* update tests

* formatting

* foramtting

* remove unused code

* add more tests

* working through tests

* formatting

* more factoring of connection store and increase code coverage

* formatting

* fix tests

* change use of state service to storage service

* remove unused files

* fix strict null errors

* formatting
2019-04-30 13:32:32 -07:00
Yurong He
44a2d009c0 Fixed #4169 shows notification when not active code cell is selected when hit F5 (#5259)
* Refine the msg
2019-04-30 13:25:11 -07:00
Anthony Dresser
48682bacde rework panel to not need platform (#5270) 2019-04-30 13:19:21 -07:00
Aditya Bist
f70369c2a6 Fix object explorer session fails (#5256)
* only start session if response successful

* added return type

* fixed OE tests

* format doc
2019-04-30 11:45:52 -07:00
udeeshagautam
f7fc94520a Fixing schema compare object type enum to follow PascalCasing (#5266) 2019-04-30 11:07:46 -07:00
udeeshagautam
77c6f5c9a2 Reverting the checkboxes because of scrollbar issue 5230 (#5271) 2019-04-30 11:07:11 -07:00
kisantia
dffa47301b fix path to dark icon of options button (#5274) 2019-05-01 05:53:55 +12:00
Charles Gagnon
08f47e7e14 Fix "Open File Location" for CSV Export (#5273)
Fix #5177 - File path wasn't being parsed correctly, URI.file should be used for full file paths.
2019-04-30 10:41:19 -07:00
Anthony Dresser
56342af140 Rework editableDropdown to not need platform (#5189)
* rework editableDropdown to not need platform

* rework editable dropdown to not depend on platform

* fix compile

* fix focus bluring
2019-04-30 09:25:04 -07:00
Anthony Dresser
aacc0eca67 Merge from vscode 071a5cf16fc999727acc31c790d78f750fa4b166 (#5261) 2019-04-30 07:54:56 -07:00
Kevin Cunnane
02916aeffa Fix #3440 link in Markdown requires cmd+click (#5239)
- Copied over click handler from VSCode markdown renderer
- Added logic to only support command links if trusted

Now clicking on a link will do an action or open a file.
Created #5238 to track need to support relative links which doesn't work
2019-04-29 19:15:39 -07:00
udeeshagautam
e42bfada9d Feature/schemacompare options (#5143)
* extension now working

* make button messages better

* fix diff editor title disappearing and remove border from source and target name boxes

* redoing a bunch of stuff that disappeared after rebasing

* add images and add to extensions.ts

* moving a few changes to the right place after rebase

* formatting

* Initial schema compare options working code

* Adding description.icon etc.

* Enabling disabling options button

* Name change: SchemaCompareOptions to DeploymentOptions. To reflect SqltoolsService side parameters

* Adding sorting and correct sql tools version

* Adding options button themes

* Formatting fix

* Adding get default options call to get options from tools service

* Exclude/Include changes - first commit

* Adding border to checkboxes

* Taking PR comments

* Updating to latest sqltools with schema compare options
2019-04-29 18:11:48 -07:00
Karl Burtram
72fb114dec Load MSSQL extension first during eager load phase (#5255) 2019-04-29 17:46:30 -07:00
Karl Burtram
9ba1561386 Bump SQL Tools Service to 1.5.0-alpha.91 (#5260) 2019-04-29 17:38:19 -07:00
Aditya Bist
39772c2dbe CMS Extension - 2 (#4908)
* first set of changes to experiment the registration of cms related apis

* Adding cms service entry to workbench

* Adding basic functionality for add remove reg servers and group

* Returning relative path as part of RegServerResult as string

* initial extension

* cleaned building with connecting to server

* get list of registered servers

* progress with registered servers tree

* cms base node with server selection

* removed unused services

* replaced azure stuff with cms

* removed cmsResourceService

* list servers progress

* Removing the cms apis from core. Having mssql extension expose them for cms extension

* create server working fine

* initial expansion and nodes

* Propogating the backend name changes to apis

* initial cms extension working

* cached connection needs change in api

* connect without dashboard in proposed

* Fixing some missing sqlops references

* add registered server bug found

* added refresh context menu option

* added payload

* server description not disabled after reject connection

* added more context actions and action icons

* added empty resource and error when same name server is added

* fixed connection issues with cms and normal connections

* added initial tests

* added cms icons

* removed azure readme

* test script revert

* fix build tests

* added more cms tests

* fixed test script

* fixed silent error when expanding servers

* added more cms tests

* removed cmsdialog from api

* cms dialog without object

* fixed theming issues

* initial connection dialog done

* can make connections

* PM asks for strings and icons

* removed search

* removed unused code and fixed 1 test

* fix connection management tests

* changed icons

* format file

* fixed hygiene

* initial cr comments

* refactored cms connection dialog

* fixed bug when switching dialogs

* localized connection provider options

* fixed cms provider name

* code review comments

* localized options in cms and mssql

* localized more options
2019-04-29 15:16:59 -07:00
David Shiflet
cbf3ca726f Connect opened query editors to the server (#5207)
* Connect opened query editors to the ser

* only show firewall rule error for one file

* remove unused imports

* sync to latest

* add comment

* one more comment
2019-04-29 13:10:19 -04:00
Yurong He
f1e21ebe9d Fix driverlog uri in output (#5212)
* Fixed #4813

* Changed to lowercase for comparision
2019-04-26 20:25:55 -07:00
Yurong He
49c36cc040 Fixed #4947 Increase the size of the notebook command icons and space between icon and button (#5235) 2019-04-26 19:57:40 -07:00
Anthony Dresser
9b90400abd Merge from vscode 63d257f78a36951ab7e821170ba675b11dc06d48 (#5240) 2019-04-26 17:24:54 -07:00
Karl Burtram
8cda364210 Fix product name in error message (#5233)
* Fix product name in error message

* fix typo
2019-04-26 15:32:30 -07:00
Anthony Dresser
ca98ef879d Last of the layering (#5187)
* layer query

* update imports
2019-04-26 15:30:41 -07:00
Chris LaFreniere
bb9c85cd8f Improve Cleanup of Jupyter processes on Notebook and/or ADS Close (#5142)
* Close jupyter and python

* Ensure we stop jupyter correctly on process end

* dont stopServer from clientSession shutdown

* PR comments

* close notebook after each test
2019-04-26 15:28:26 -07:00
Anthony Dresser
91b946bf3d rework listbox to not require platform (#5192) 2019-04-26 15:02:03 -07:00
kisantia
64377000c6 Change default folder in dacpac and schema compare extensions (#5215)
* change default folder in dacpac and schema compare extensions

* move getting rootpath to a method

* change method name
2019-04-27 04:27:03 +12:00
Yurong He
23f4931a1d Fixed #5210 (#5211)
* Fixed #5210

* Added function to check error to ensure get string
2019-04-25 19:45:33 -07:00
Anthony Dresser
3625834028 Merge from vscode 63655183ba5305b70ffaf1327b8a4708f0a79bd9 (#5221) 2019-04-25 19:18:04 -07:00
Alan Ren
705e7b30bc enable 'New Notebook' entry points for PG SQL (#5194)
* enable 'New Notebook' entry points for PG SQL

* fix comment

* permanent fix for context menu entry point
2019-04-25 16:23:01 -07:00
udeeshagautam
6528c0817d quick fix for column name (#5214) 2019-04-25 15:51:54 -07:00
Aditya Bist
f3d7392af3 Localize connection options for mssql (#5209)
* localize connection options for mssql

* added all strings
2019-04-25 15:13:07 -07:00
Yurong He
5d5f44ba11 Fixed #3961 Removed hardcoded value in notebook and use QueryEditor Result RowHight to keep it consistent (#5208) 2019-04-25 12:59:13 -07:00
Anthony Dresser
34457880c7 Merge from vscode 0fde6619172c9f04c41f2e816479e432cc974b8b (#5199) 2019-04-24 22:26:02 -07:00
kisantia
d63f07d29a Schema compare publish (#5127)
* adding publish command
2019-04-25 10:37:40 +12:00
Anthony Dresser
5c2cbc9d29 fix task contribution (#5188) 2019-04-24 15:05:11 -07:00
Karl Burtram
8dbfa10646 Bump npm packages (#5185) 2019-04-24 14:55:36 -07:00
Anthony Dresser
9e804089e0 Move Tasks Panel (#5162)
* moving tasks panel

* fix css styling

* clean up code

* do a bunch of renaming
2019-04-24 13:54:58 -07:00
v-mdriml
51145903aa LOC CHECKIN | Microsoft/azuredatastudio master | 20190424 (#5179) 2019-04-24 13:46:50 -07:00
Anthony Dresser
036c49f398 Modify coverage process to reduce time (#5164)
* modify coverage process to reduce time

* disable coverage on linux
2019-04-24 13:39:30 -07:00
Chris LaFreniere
46b85ebc6b Fix casing on welcome page to be consistent (#5169) 2019-04-24 11:18:33 -07:00
Yurong He
07bc5e2de9 Fixed #3244 (#5166) 2019-04-24 09:04:15 -07:00
Yurong He
e822091907 Only when the connection is connected, then do disconnect. (#5170) 2019-04-23 19:03:49 -07:00
Chris LaFreniere
7d46e77922 Notebooks: Show keyboard shortcut for run cell (#5097)
* Show keyboard shortcut for run cell

* PR comment
2019-04-23 17:33:15 -07:00
Karl Burtram
ad528ad3d5 Update Azure Data Studio to 1.7.0 for May release (#5167) 2019-04-23 17:24:24 -07:00
Yurong He
e8b4c03770 Fixed #4772 create unique connection for each notebook by using noteb… (#5163)
* Fixed #4772 create unique connection for each notebook by using notebook path as uri
Disconnect sqlConnection from SqlKernel to ensure no connection left after the notebook is closed.

* SqlSessionManager is ADS level manager

* Moved path to SqlKernel constructor
2019-04-23 16:42:28 -07:00
Chris LaFreniere
33aacc1798 Improve Notebook Context Menu Casing (#5145) 2019-04-23 11:35:46 -07:00
Anthony Dresser
58959ef35e Enable stricter compile options on extensions (#5044)
* enable stricter compile settings in extensions

* more strict compile

* formatting

* formatting

* revert some changes

* formtting

* formatting
2019-04-23 11:18:00 -07:00
Charles Gagnon
c66b349cec Show correct release notes for command (#5108) 2019-04-23 10:55:09 -07:00
Aditya Bist
5c90df092b Switch on code coverage (#5120)
* testing code coverage for /sql/

* fix test result path

* fixed coverage task:



'

* added coverage to linux and mac as well

* fix script for mac and linux

* bash script cmd

* fixed scripts

* remove warnings from summary

* remove coverage from linux

* added job action tests

* added more tests
2019-04-23 10:47:03 -07:00
Karl Burtram
32374f264f Adjust default fonts (#5146)
* Adjust default fonts

* Adjust default ratio
2019-04-22 17:30:16 -07:00
Anthony Dresser
5e62229f25 Merge from vscode 2b87545500dbc7899a493d69199aa4e061414ea0 (#5148) 2019-04-22 16:57:13 -07:00
Cory Rivera
1b24dff738 Show an Install Skipped message when Python already exists at the specified install location. (#5141)
* Also fixed a bug where future installs would get blocked after doing an install that gets skipped.
2019-04-22 14:28:59 -07:00
Aditya Bist
161135cd90 remove old unused splash screen (#5112) 2019-04-22 13:39:27 -07:00
Aditya Bist
5fb583da06 uncheck desktop icon by default (#5111) 2019-04-22 13:38:51 -07:00
Kevin Cunnane
8b40d20eab Typings reference failing in external extension (#5129)
This fixes an issue where if you copy azdata.proposed.d.ts to
an extension project, it would fail to compile using default
tsconfig.json settings due to missing return type
2019-04-19 16:41:23 -07:00
Chris LaFreniere
432034d2cb Notebooks: Pressing Escape key in markdown cell exits edit mode (#5094)
* Pressing Escape key in markdown exits edit mode

* text + code cells inactive when pressing escape
2019-04-19 16:19:16 -07:00
Alan Ren
0e168e36fc Merge from vscode 12cb89c82e88e035f4ab630f1b9fcebac338dc03 (#5125) 2019-04-19 10:26:20 -07:00
Cory Rivera
f248260584 Add flag to skip python install integration tests. (#5119) 2019-04-18 17:13:19 -07:00
Cory Rivera
880e3e10da Update Python install messages to differentiate between download completion and install completion. (#5114) 2019-04-18 16:52:50 -07:00
Anthony Dresser
f33b95ee82 Use vscode clipboard rather than clipboardy (#5117)
* remove clipboardy and use vscode's clipboard apis instead

* update lock
2019-04-18 16:34:24 -07:00
Anthony Dresser
4a71eb9b90 use vscode open external rather than opener (#5115) 2019-04-18 16:34:12 -07:00
Chris LaFreniere
3372a5ad4b Fix hygiene issues in textCell.css (#5116) 2019-04-18 15:58:27 -07:00
Zbyněk Sailer
8326f05f66 LOC CHECKIN | Microsoft/azuredatastudio master | 20190418 (#5103) 2019-04-18 14:59:25 -07:00
Chris LaFreniere
7ce921d449 Improve tabe markdown css (#5093) 2019-04-18 14:57:26 -07:00
Chris LaFreniere
31f7364f08 Only show nb loading spinner when no cells shown (#5095) 2019-04-18 14:57:11 -07:00
Anthony Dresser
5119d28b9d fix svg references (#5109) 2019-04-18 12:29:18 -07:00
Yurong He
a2a5fe3bee Added more logging for python installation and remove dup test in the other suite (#5106) 2019-04-18 11:24:12 -07:00
Karl Burtram
6222d8c977 Bump agent extension to 0.38.0 (#5104) 2019-04-18 09:48:47 -07:00
Karl Burtram
d3699a261a Update readme for April release (#5063) 2019-04-18 09:25:01 -07:00
Anthony Dresser
9c0e56d640 Layering of everything else but query (#5085)
* layer profiler and edit data

* relayering everything but query

* fix css import

* readd qp

* fix script src

* fix hygiene
2019-04-18 01:28:43 -07:00
Anthony Dresser
ddd89fc52a Renable Strict TSLint (#5018)
* removes more builder references

* remove builder from profiler

* formatting

* fix profiler dailog

* remove builder from oatuhdialog

* remove the rest of builder references

* formatting

* add more strict null checks to base

* enable strict tslint rules

* fix formatting

* fix compile error

* fix the rest of the hygeny issues and add pipeline step

* fix pipeline files
2019-04-18 00:34:53 -07:00
Alan Ren
b852f032d3 Merge from vscode 3a6dcb42008d509900b3a3b2d695564eeb4dbdac (#5098) 2019-04-17 23:38:44 -07:00
Aditya Bist
1fec26c6b3 dont dispose serverTreeView every time hidden (#5092) 2019-04-17 20:12:44 -07:00
kisantia
d3483afaed Schema Compare extension (#4974)
* extension now working

* fix diff editor title disappearing and remove border from source and target name boxes

* redoing a bunch of stuff that disappeared after rebasing

* add images and add to extensions.ts

* moving a few changes to the right place after rebase

* formatting

* update toolbar svgs

* addressing comments

* add return types

* Adding PR comments

* Adding light and dark theme icons

* Fixing the diff editor title for dark theme
2019-04-17 19:14:22 -07:00
Chris LaFreniere
910e4815fa Enable Python Integration Tests For Notebooks (#5090)
* Enable python notebook tests

* change run_python3_test to be string

* Add explicit pyspark check
2019-04-17 16:46:10 -07:00
Karl Burtram
ef118e3351 Update extension recommendation list (#5086) 2019-04-17 16:26:41 -07:00
Chris LaFreniere
2beedb10d4 Add run cells as a command (#5080) 2019-04-17 14:26:31 -07:00
Charles Gagnon
41bf10d989 Fix for build break caused by missing SVG (#5078)
* Fix for build break caused by missing SVG

These files were moved in #5029

* Add a few more missing SVGs
2019-04-17 11:22:42 -07:00
Chris LaFreniere
ac3b6aef27 ADS Welcome Page (#5043)
* ADS Welcome Page

* sample notebook section

* Opens in browser :(

* Remove sample notebooks section

* fix open file in windows

* Change az_data_welcome_page to be under sql/

* fix tslint issue

* Scope table css down
2019-04-17 10:50:43 -07:00
Anthony Dresser
8956b591f7 Merge from vscode 05fc61ffb1aee9fd19173c32113daed079f9b7bd (#5074)
* Merge from vscode 05fc61ffb1aee9fd19173c32113daed079f9b7bd

* fix tests
2019-04-16 22:11:30 -07:00
Anthony Dresser
2f8519cb6b Layer Object Explorer; query plan; task history (#5030)
* relayer query plan, task history, object-explorer

* formatting
2019-04-16 21:12:34 -07:00
Aditya Bist
15a19c044d remove agent from old apis (#5064) 2019-04-16 17:13:02 -07:00
Alan Ren
ec47ff7479 Alanren/fixsmoketest (#5019)
* fix the smoke test

* update readme

* fix the selector for server name input

* add new property to server profile engineType
2019-04-16 16:43:11 -07:00
Aditya Bist
82f707ee89 Fixed agent filter in dark theme (#5048)
* fixed agent filter in dark theme

* added high contrast theme as well
2019-04-16 15:30:16 -07:00
Alan Ren
dfcab8db6a fix the selectbox issue for chart (#5052) 2019-04-16 13:32:52 -07:00
Anthony Dresser
5c10127758 Layer grid code (#5029)
* layer grid

* errors; edit data still not showing up

* fix edit data

* fix tab spaces
2019-04-16 13:30:15 -07:00
Aditya Bist
b376f36733 fix job action context (#5053) 2019-04-16 13:07:22 -07:00
Aditya Bist
96c0f62cf5 Removed duplicate connections code (#5045)
* removed duplicate connections code

* removed old comment

* removed unused code
2019-04-16 11:54:07 -07:00
Zbyněk Sailer
a96f996b59 LOC CHECKIN | Microsoft/azuredatastudio master | 20190411 (#4993) 2019-04-16 10:36:41 -07:00
Anthony Dresser
b75d0b6cb5 Fix bootstrapping around dashboard (#5040) 2019-04-15 23:49:40 -07:00
Anthony Dresser
a5bc65fbfb Merge from vscode 8b5ebbb1b8f6b2127bbbd551ac10cc080482d5b4 (#5041) 2019-04-15 20:37:22 -07:00
Gene Lee
dcdbc95ae7 Fixed bug: CheckboxTreeNode label overflows, and node icon disappears (#5022) 2019-04-15 13:44:49 -07:00
Anthony Dresser
72e7e5e025 relayer connection code; formatting (#5020) 2019-04-15 01:05:23 -07:00
Anthony Dresser
57242a2e13 Merge from vscode 3d67364fbfcf676d93be64f949e9b33e7f1b969e (#5028) 2019-04-14 22:29:14 -07:00
Anthony Dresser
6dbf757385 Remove some vscode differences (#5010)
* remove some vscode differences

* add dates to todo comments
2019-04-12 21:55:07 -07:00
Karl Burtram
c5a32d8373 Show user email address in account picker (#5015)
* Show user email address in account picker

* Fix build break and remove Azure account from sqlops namespace
2019-04-12 17:23:48 -07:00
Charles Gagnon
34288435ec Fix Data Explorer context menu items visibility (#4996)
* Fix Data Explorer context menu items visibility

The when clause was making the menu items show up for all nodes in the Data Explorer - even ones that didn't make sense such as the Databases folders. This change makes it only appear for the Database and Server nodes (which is how the OE tree is set up)
2019-04-12 17:09:53 -07:00
Yurong He
177b48c3f2 Revert #4955 to unblock integration test (#5016) 2019-04-12 14:08:38 -07:00
Anthony Dresser
642f5d4405 replace nulls with undefined (#5014) 2019-04-12 13:08:32 -07:00
Anthony Dresser
92b1c59e48 Strict null check on full "base" code (#4973)
* removes more builder references

* remove builder from profiler

* formatting

* fix profiler dailog

* remove builder from oatuhdialog

* remove the rest of builder references

* formatting

* add more strict null checks to base
2019-04-12 12:59:58 -07:00
Anthony Dresser
cb1682542b remove sql/services (#4991) 2019-04-12 12:48:06 -07:00
Anthony Dresser
9e56187c16 Remove sql/common (#4990)
* remove sql/common/

* formatting

* fix cyclic dependency
2019-04-12 12:47:48 -07:00
Yurong He
51851efda5 Use notebookUtils.getErrorMessage to get the correct msg instead of showing {0} (#5012) 2019-04-12 11:50:44 -07:00
Charles Gagnon
11e4b743e0 Fix wrong release notes being loaded (#5008) 2019-04-11 16:56:55 -07:00
Kevin Cunnane
3349151d4c Touchbar icon support in notebooks (#4998)
* Touchbar icon support in notebooks
- updated shortcut keys to only work if notebook is active
- Added icons
- Now have 1 "add cell" icon that prompts for code/text.
This is useful as there wasn't an icon to differentiate
2019-04-11 16:43:27 -07:00
Kevin Cunnane
c8f6937166 Fix #4500 Untitled notebook reopen doesn't show dirty (#5005)
* Fix 2 notebook issues
- Do not create notebook model twice on start
- Do not cause disposed warnings due to markdown cell deserialization

* Fix notebook dirty on open issue
Before model is resolved we weren't getting dirty events.
Solution is to use backing text model until it's ready.
Must hook to the dirty event & notify to get the dot to appear
2019-04-11 16:39:54 -07:00
Maddy
ad36c1df3d add wrap to the <pre> tag (#5002)
* add wrap to the <pre> tag

* removed styles for browser support
2019-04-11 15:32:52 -07:00
Anthony Dresser
a5b8924e2d restore line height to account list renderer (#4999) 2019-04-11 15:10:38 -07:00
Anthony Dresser
bc898cc2c2 revert data explorer id to connections (#5003) 2019-04-11 15:10:26 -07:00
kisantia
1247b6e8eb bump SQL Tools to 1.5.0-alpha.85 to get invalid dacpac version fix (#5001) 2019-04-11 13:53:45 -07:00
udeeshagautam
2111c3de1a Fix for 4104 : Multiple consecutive spaces in query results cells are condensed into one (#4983)
* preserving spaces in query results - all beginning, trailing and middle spaces will be shown as is

* removing the change through formatting and replacing with css change formatting was leaving special char while removing nbsp
2019-04-11 13:45:10 -07:00
Aditya Bist
bcea1b66be Added some usage details (#4711)
* added some details

* remove unused import

* added new metrics, removed churn

* merged master and code review comments

* code review comments

* normalized days to calendar days/weeks/months

* cleaned up code

* changed comment to start required check for PR

* fix failing test

* fix test

* removed null assignment

* fix null test script
2019-04-11 12:07:20 -07:00
Yurong He
4f8d14ed3e Fix ##3479 ctrl+a select active cell output or preview markdown (#4981)
* Enable ctrl+a to select the output or markdown content when the cell is active

* Moved toggleUserSelect into ngOnChanges

* Resolve PR comments
2019-04-11 11:36:42 -07:00
Chris LaFreniere
442adfbbc3 Add New Notebook from Server Dashboard (#4971) 2019-04-11 10:15:45 -07:00
Aditya Bist
fe12233954 Azure extension changes (#4987)
* removed search box

* removed commented code
2019-04-11 09:44:43 -07:00
Anthony Dresser
c725f6f572 fix html structure of add account dialog (#4988) 2019-04-10 17:41:18 -07:00
Cory Rivera
1870d83081 Add additional error handling to Python installation for Notebooks (#4891)
* Also enabled integration tests for python installation.
2019-04-10 17:09:28 -07:00
Anthony Dresser
8315dacda4 Merge from vscode 31e03b8ffbb218a87e3941f2b63a249f061fe0e4 (#4986) 2019-04-10 16:29:23 -07:00
kisantia
18c54f41bd remove unnecessary message that connection is needed (#4982) 2019-04-10 16:22:18 -07:00
Kevin Cunnane
293f9c22c4 Touchbar support for Run Cell, Run Query, Add Cell (#4972)
* Basic touchbar support

* Touchbar support for Run Cell, Run Query, Add Cell
- Add top 3 notebook commands
- Add top query command

Actions only appear on having active editor of expected type.
In order to make Notebook work as expected, added tabindex to support focusing
and hide outline to ensure it doesn't get weird blue outline on click
Note: does not have icons yet, which would be nice.
However can add in subsequent PR once this comes from UX.
2019-04-10 14:04:36 -07:00
Anthony Dresser
a74510544f Remove rest of builder (#4963)
* removes more builder references

* remove builder from profiler

* formatting

* fix profiler dailog

* remove builder from oatuhdialog

* remove the rest of builder references

* formatting
2019-04-10 13:23:33 -07:00
Aditya Bist
9b053c50c2 Azure - icon change (#4967)
* changed icon and string

* changed add to servers icon
2019-04-10 13:20:43 -07:00
Chris LaFreniere
88712f46bf Fix for relative markdown image paths (#4889)
* Fix for relative markdown image paths

* PR comments
2019-04-10 11:35:06 -07:00
Chris LaFreniere
d6df20b0e8 Notebooks: Potential Fix for "Notebook Provider does not Exist" Error (#4848)
* Fallback to SQL

* Fix providers not found issue

* await whenInstalledExtensionsRegistered

* PR comments
2019-04-10 11:34:46 -07:00
Chris LaFreniere
5dc37f7557 improve assert message (#4968) 2019-04-10 10:14:44 -07:00
Gene Lee
445d306586 Fixed Broken Notebook Preview (#4895) 2019-04-09 18:47:24 -07:00
Chris LaFreniere
d332ae1132 Fix to ensure that we rewrite spark ui links correctly (#4962) 2019-04-09 18:23:21 -07:00
Kevin Cunnane
37f45b10a3 Mitigate (but not fully fix) Run Cell from disconnected notebook (#4960)
This is a partial fix that lays groundwork for full "Prompt to connect" if a kernel needs a connection.
I am waiting on Yurong's refactoring of connection handling before doing any of the prompt work.

- Adds kernel metadata about whether a connection is required.
- For Jupyter, only Spark kernels are listed as requiring a connection
- If this is true and there's no active connection, will show notification and not call execute

In the future, this path will still be used if user is prompted to connect and cancels out.
The future change will be to inject a "connect" handler from notebook.component to the cell callback and use to set connection context
2019-04-09 17:45:05 -07:00
kisantia
d9b6ec0654 Add title for DiffEditor and fix SplitViewContainer (#4961)
* add option to have diff editor title

* fix component being undefined and splitter not showing
2019-04-09 16:41:32 -07:00
kisantia
f98428aea5 Add reverse color option to text diff editor (#4826)
* Add reverse color option to text diff editor
2019-04-09 16:26:41 -07:00
Gene Lee
b3be1d79cd Add support for new endpoint key string 'gateway' (#4954) 2019-04-09 15:19:02 -07:00
Yurong He
ea8f885f05 Call getCurrentGlobalConnection like New Query to get the active connection context (#4955) 2019-04-09 15:15:36 -07:00
Kevin Cunnane
2de47c2a50 Fix #4930 Text cells are referred to as text and markdown in commands (#4956) 2019-04-09 14:20:29 -07:00
Kevin Cunnane
30b8e105f9 Fix #4893 New Notebook Can Open Existing Noteboon (#4959)
Add back check for textDocuments with same name, should've been there anyhow

On rehydration files show as text docs before clicking as only get
changed by customInputConverter code path.
We should look at this long term - ideally we'd update notebookDocuments
with correct values on initial start. #4958 opened to track this.
2019-04-09 14:11:10 -07:00
Kevin Cunnane
2a44fab8ba Fix issue where mac launch often failed to attach (#4957)
- Timeout now matches the windows timeout value
2019-04-09 14:10:56 -07:00
Chris LaFreniere
6a06a99e46 Change pfs.rimraf call in insightsutils test (#4921) 2019-04-09 13:05:36 -07:00
Anthony Dresser
3670dfbebd changes strings for data explorer (#4946) 2019-04-09 12:39:15 -07:00
kisantia
daf929ecc7 add splitViewContainer and diffEditor to ModelBuilder interface (#4950) 2019-04-09 11:45:21 -07:00
Anthony Dresser
f96a17c930 Remove unused code (#4873)
* removes unused features

* remove more unused code; formatting

* lock changes

* fix run issue
2019-04-09 02:00:51 -07:00
Anthony Dresser
2fb06e7f4f Move notebooks to workbench (#4888)
* move notebooks under workbench

* fix style imports
2019-04-09 01:59:55 -07:00
Anthony Dresser
4ece9b0085 remove dispose of button listeners (#4914) 2019-04-09 01:08:56 -07:00
Anthony Dresser
a4bd31e96a Removes Builder references from modal (#4869)
* remove builder from modal

* add more DOM methods
2019-04-09 00:28:52 -07:00
Anthony Dresser
8bdcc3267a Code Layering dashboard (#4883)
* move dashboard to workbench

* revert xlf file changes

* 💄

* 💄

* add back removed functions
2019-04-09 00:26:57 -07:00
Takahito Yamatoya
9e9164c4ee fix the format (#4899) 2019-04-08 19:56:44 -07:00
Alan Ren
5dc6a39652 Update readme.md (#4907) 2019-04-08 16:25:53 -07:00
kisantia
ada0966832 Add toolbar separator (#4890)
* Add option to add toolbar separator after toolbar component
2019-04-08 15:27:18 -07:00
Alan Ren
e6faef27ab Alanren/integration setup (#4871)
* automate the setup and use akv to store values

* update readme.md

* get rid of the save to file part

* update readme

* add more messages

* fix the error

* fix some errors

* fix the readme
2019-04-08 15:11:38 -07:00
Anthony Dresser
acc27d0829 Code Layering Accounts (#4882)
* code layering for accounts

* formatting

* formatting

* formatting
2019-04-08 14:45:30 -07:00
Anthony Dresser
ab54f7bb45 remove builder references from some componnets (#4868) 2019-04-08 14:24:03 -07:00
Yurong He
88161cc37d Fixed cancel connectionDialog from attach to shows dup "select connection" (#4865) 2019-04-08 14:06:46 -07:00
Anthony Dresser
0975e6834e remove builder from taskswidget (#4866) 2019-04-08 13:28:23 -07:00
Anthony Dresser
22ec1d5f0a Strict Null Checks, Builder Removal, Formatting (#4849)
* remove builder; more null checks

* null checks

* formatting

* wip

* fix dropdown themeing

* formatting

* formatting

* fix tests

* update what files are checked

* add code to help refresh bad nodes
2019-04-08 13:27:41 -07:00
udeeshagautam
01784dd186 Adding Diff view and Split view container as Model View Editor Components (#4831)
* intial code for diff view inside model view

* Adding basic Split View Container depending on Flex Layout

* Enabled resizing between top and bottom view

* cleaning up some of the sqlops references

* Adding height as per CR comment
2019-04-08 11:11:14 -07:00
Karl Burtram
02cf91c158 Remove broken VS Code test from merge (#4887) 2019-04-05 15:06:11 -07:00
Karl Burtram
0532346f4f Merge from vscode 591842cc4b71958c81947b254924a215fe3edcbd (#4886) 2019-04-05 14:14:26 -07:00
Chris LaFreniere
657adafb7d always serialize execution count (#4864) 2019-04-05 11:34:10 -07:00
Anthony Dresser
818c0789ea Reduce packaged size of extensions (#4300)
* reduce output of notebooks

* reduce size of azurecore

* update mssql extensions to be webpacked

* formatting

* remove commented code

* fix packaged config

* fix mssql packing
2019-04-05 10:48:00 -07:00
Karl Burtram
cb5bcf2248 Merge from vscode 2b0b9136329c181a9e381463a1f7dc3a2d105a34 (#4880) 2019-04-05 10:09:18 -07:00
Anthony Dresser
9bd7e30d18 revert vscode cahnges (#4879) 2019-04-05 09:15:38 -07:00
Aditya Bist
572010ded1 fixed azure extension issues (#4859) 2019-04-04 15:32:04 -07:00
David Shiflet
1f22326e78 Reuse existing saved connection that matches args (#4839)
* Reuse existing saved connection that matches args

* search subgroups for matches
2019-04-04 11:11:18 -07:00
Yurong He
504d5c91bc Fixed #4800 need to use ConnectionProfile in order to get the correct… (#4812)
* Fixed #4800 need to use ConnectionProfile in order to get the correct connection

* Go back to create connect in run cell to avoid to fail to run cell or close the connection used by other.
2019-04-03 19:00:56 -07:00
Chris LaFreniere
a34692b6f2 Fix for dispose method of undefined (#4843) 2019-04-03 18:08:42 -07:00
Karl Burtram
73b5d23210 Update bug template labels (#4840) 2019-04-03 16:47:55 -07:00
Anthony Dresser
e31de8b137 fixed more null references (#4841) 2019-04-03 16:30:58 -07:00
Anthony Dresser
cef5bbb2be Strict null pass on some base ui files (#4832)
* more strict null checks in base browser code

* revert changes to radiobutton

* fix some more minor things, enable strict null check in pipelines

* formatting

* fix compile errors

* make null undefined

* more null to undefined
2019-04-03 16:18:33 -07:00
Anthony Dresser
80a8e1a4da More builder removal (#4810)
* remove more builder references

* formatting
2019-04-03 16:18:03 -07:00
Anthony Dresser
fcb8fe50fe Advanced Description On Bottom (#4836)
* move description to the bottom

* formatting
2019-04-03 15:49:53 -07:00
Karl Burtram
5235c8aad6 Turn-off classifier bot while doing label refactoring (#4834) 2019-04-03 13:59:48 -07:00
Karl Burtram
5b67525211 Bump SQL Tools to 1.5.0-alpha.84 (#4830) 2019-04-03 11:43:43 -07:00
Anthony Dresser
fb697729c0 Data Explorer Icons (#4806)
* inital icon support

* add necessary classes for icons

* initialize icon to blank string
2019-04-03 11:10:48 -07:00
Chris LaFreniere
76fe0fef49 Fix broken test merge conflicts (#4823) 2019-04-03 10:44:01 -07:00
Karl Burtram
6295d03801 Update XLF files (#4811) 2019-04-02 17:35:18 -07:00
Chris LaFreniere
07166fb3cd Run All Cells Notebook Implementation (#4713)
* runAllCells API

* add comment

* more run cells fixes

* Add integration test

* Add multiple cell SQL notebook test

* Comment out python tests as they fail in the lab

* remove unused imports

* PR comments

* Remove localize

* Return true instead of promise.resolve(true)
2019-04-02 16:47:00 -07:00
Yurong He
219dfe66d0 Make connection for new Notebook (#4770)
* Make connection for new Notebook

* Resolve merge issue

* User connectionUri to track the connects need to be disconnected

* Removed debugging log
2019-04-02 15:52:01 -07:00
Yurong He
22c62fb524 Added setup and teardown for test; add variable to control run python… (#4782)
* Added setup and teardown for test; add variable to control run python/pyspark tests; remove dup code in clearAlloutput tests

* Resolve PR comments
2019-04-02 15:16:54 -07:00
Karl Burtram
f8706abebe Merge from vscode b8c2e7108b3cae7aa2782112da654bedd8bb3a52 (#4808) 2019-04-02 14:35:06 -07:00
Alan Ren
e83a6f9c2e profile page and summary page (#4769)
* add cluster name to page

* implement profile page -1

* fix compilation error due to new method

* profile page 0328

* summary page

* make divcontainer accessible

* handle disposable

* add support for "coming soon" cards
2019-04-02 13:52:39 -07:00
Anthony Dresser
63485c8c78 Remove builder references from options dialog (#4774)
* remove more builder references; remove $ from declarations

* fix jquery references

* formatting

* fixing backup

* fix backup box
2019-04-02 13:49:50 -07:00
Karl Burtram
72ef024678 Check for null ref in query statusbar timer (#4804) 2019-04-02 11:56:45 -07:00
Chris LaFreniere
414c736655 Allow output area to be selectable again (#4714) 2019-04-01 23:09:00 -07:00
Yurong He
fdbfbb9238 Change attach to show user name. Use connectionProfile.title to displ… (#4794)
* Change attach to show user name. Use connectionProfile.title to display the same info as OE server node

* Fixed some potential profile leak

* Removed unused import

* Resolve PR comments
2019-04-01 21:18:49 -07:00
Alan Ren
a766e5d334 fix error for download extension (#4793) 2019-04-01 16:44:15 -07:00
Yurong He
2faf01eb9d Add MouseWheelSupport , AdditionalKeyBindings and AutoColumnSize plugins to sql notebook grid (#4790) 2019-04-01 12:44:40 -07:00
Yurong He
a4c2463b2f Add azure and standalone instance config to environment variables (#4745)
* change to fs to write file

* change random range to 1 to 100

* Added more env variables check as well

* Add azure and standalone env variables

* Add Azure instance to unblock mac pipeline testing

* Fixed some merge issue and improve delete file

* Added standalone test only run on windows
2019-03-29 20:14:44 -07:00
Cory Rivera
ddbd8033f9 Remove an outdated showErrorMessage assert from Jupyter Server Manager unit tests. (#4777) 2019-03-29 15:18:01 -07:00
Yurong He
6da66cf367 change to fs to write file (#4736)
* change to fs to write file

* Added more env variables check as well

* Resolve PR comments

* Merge master

* Add file name exist check and delete it after test is done
2019-03-29 15:04:11 -07:00
Cory Rivera
c7bc37d010 Add quotes around python paths to guard against spaces. (#4775) 2019-03-29 14:55:08 -07:00
Charles Gagnon
e0ec3c5035 Fix workspaceRoot macro for insights (#4686)
* Fix workspaceRoot macro for insights

The workspaceRoot macro wasn't working correctly for finding the queryFile. There were a couple of issues :

1. The path separators were hardcoded as / which wasn't xplat-compatible
2. They required the first section of the path was one of the folders in the workspace - e.g. if the workspace contained a folder named foo you'd have to specify ${workspaceRoot}\foo\myfile.sql. This is inconsistent with the folder logich was just appends the path after ${workspaceRoot} to the folder that's currently open

I changed the logic to just append the relative part of the path to every folder currently open in the workspace and choose the first one that it found that contained the file we were told to look for - which follows the convention the folder logic uses. If the file doesn't exist it'll just fall back to using the path without the macro (which is likely to not resolve and thus will display an error, but there's nothing we can do at that point anyways)

* Switch to using VS Code resolver (support for more than just workspaceRoot) and move resolution code into helper method so it can be used by the multiple places it's called. Added tests for the methods.

* Add test for invalid param

* Change resolveQueryFilePath to be a standalone exported function. Change it to throw if the file can't be resolved/found so callers can display error correctly. Added more tests to covery new scenarios. Switch to using pfs instead of fs for file existance checks.

* Add extra param to InsightsDialogController construction in test

* Fix formatting and test errors.

* Change to suiteSetup and suiteTeardown so the setup/teardown is only ran once instead of once per test - we don't need unique files and this stops a race condition error with deleting the test folder.

* spaces -> tabs
2019-03-29 14:53:49 -07:00
Aditya Bist
d4f287298f Agent - committer work (#4758)
* fix delete job

* added the ability to change and retrieve jobowner

* fixed UX for delete step

* improved operator actions

* fixed operators and proxies

* added errors for failures
2019-03-29 13:46:52 -07:00
Aditya Bist
e70d5838a8 Agent - stop job (#4410)
* stop job behavior similar to ssms

* removed agent from sqlops

* fix couple UX issues

* let sqlops remain unchanged
2019-03-29 13:42:34 -07:00
Aditya Bist
b04ca0fdbd Agent - refresh refactor (#4773)
* refactored refresh views

* removed refresh from jobs view
2019-03-29 13:42:02 -07:00
Anthony Dresser
a064da642d Merge from vscode f5044f0910e4aa7e7e06cb509781f3d56e729959 (#4759) 2019-03-29 10:54:38 -07:00
Charles Gagnon
37ce37979a Fix broken notebook test (#4766)
* Fix broken test

The test would always fail if it was doing the right thing - since it was asserting that there WEREN'T any cells with outputs (the opposite of what it should have been checking).

* Update error message to be clearer

* Fix spelling error
2019-03-29 10:25:52 -07:00
Karl Burtram
cb3cbd0d78 Revert Messages Collapse behavior (#4757)
* Revert "change sizing behavior to allow the messages to fulling collapse down (set results to have no max height) (#4313)"

This reverts commit 7de294a58e.

* Revert "Grid scrolling bugs (#4396)"

This reverts commit ace6012c1c.
2019-03-28 18:09:58 -07:00
Raj
1415aa1c03 #4586: Clear Results feature in Notebooks (#4705)
* #4586: Clear all outputs feature

* text change

* Adding extensible method with integration tests

* Misc change

* Misc change

* Adding more logging

* Change to test

* Adding outputs confition in integration tests
2019-03-28 15:20:28 -07:00
Karl Burtram
7eb17f6abc Add Query Editor null checks (#4753) 2019-03-28 15:18:44 -07:00
Charles Gagnon
fdb471d506 Windows extension fixes/improvements (#4740)
* Windows extension fixes/improvements

Remove error message when activating extension on non-win platforms (instead just don't do anything). Add hooks to kill child processes on exit if they haven't ended already. Formatting fixes.

* Remove shelljs

* Remove error messages from telemetry until I can follow up on whether we're allowed to send these up. Fix some issues with the exec callback - the child_process exec function returns an ExecException object instead of the code directly like the shelljs did so check for that correctly.
2019-03-28 14:58:18 -07:00
Anthony Dresser
e6785ffe95 Merge from vscode de81ccf04849309f843db21130c806a5783678f7 (#4738) 2019-03-28 13:06:16 -07:00
Karl Burtram
cc2951265e Add query execution plan extensibility APIs (#4072)
* WIP 1

* WIP 2

* Fix typos

* Iterate on API a bit

* Query Tab WIP

* More dynamic query tab impl

* Fix merge breaks

* Update interfaces

* Update to single event handler for query events

* Remove query plan extension

* Add generated JS file
2019-03-28 10:59:02 -07:00
Chris LaFreniere
ee413f3b24 Ensure only one cell shows as running at a time (#4715) 2019-03-27 19:04:07 -07:00
Karl Burtram
fc664a850d Fix query plan styles to correct rendering (#4739) 2019-03-27 18:00:33 -07:00
Raj
55efe76b2e #3585: Canceled message when changing kernel (#4673)
* #3585: Canceled message when changing kernel

* Indentation

* Cleanup
2019-03-27 15:43:27 -07:00
Raj
dd8922ce4d #4511: Streamline untitled notebook count (#4727) 2019-03-27 15:29:45 -07:00
Yurong He
102b48c302 Change standalone integration test to use sql login (#4728) 2019-03-27 15:09:45 -07:00
David Shiflet
a360bebd9d Add status messages during command line processing (#4725)
* add status bar messages

* missed semicolon
2019-03-27 15:44:57 -04:00
Cory Rivera
37ab493b78 Use getErrorMessage to get exception messages in python installation code. (#4730) 2019-03-27 12:14:42 -07:00
Anthony Dresser
46b7afe558 Merge from vscode 3bd60b2ba753e7fe39b42f99184bc6c5881d3551 (#4712) 2019-03-27 11:36:01 -07:00
Chris LaFreniere
eac3420583 Minimum grid height set when grid returns 0 rows (#4716) 2019-03-27 10:57:48 -07:00
Chris LaFreniere
e1e9c08242 Disable Python 3 notebook integration test due to timeout (#4726)
* Disable Python 3 notebook integration test due to timeout

* Remove unused imports
2019-03-27 10:18:42 -07:00
Chris LaFreniere
5ac6cf3b74 Ensure SQL is the first kernel in the kernels dropdown (#4692)
* Ensure SQL is the first kernel shown in the dropdown

* cleanup to prevent sql from registering twice
2019-03-26 19:39:28 -07:00
Yurong He
d6a58136da Add log to help debug failure in the lab (#4706) 2019-03-26 11:55:14 -07:00
Alan Ren
819b7b93d1 render xml properly in the grid (#4674)
* render xml properly in the grid

* fix html injection

* fix tslint error

* add comments and fix an issue

* fix comment
2019-03-26 11:48:55 -07:00
Anthony Dresser
bceeda1cfd Remove dev flags (#4707)
* remove more dev flags

* formatting
2019-03-26 11:44:59 -07:00
Anthony Dresser
0d8ef9583b Merge from vscode 966b87dd4013be1a9c06e2b8334522ec61905cc2 (#4696) 2019-03-26 11:43:38 -07:00
Yurong He
b1393ae615 Disable pySpark3 notebook test to unblock insider build (#4695)
* Disable pySpark3 notebook test to unblock insider build

* Removed unused import
2019-03-25 17:36:49 -07:00
Alan Ren
464109313b fix context menu test due to new SSMSMin feature (#4693) 2019-03-25 16:49:12 -07:00
Raj
83c8baf8e3 #4418: Notebook file icon doesn't show for new notebook (#4676)
* #4418: Notebook icon doesn't load for untitled

* Indentation

* Indentation
2019-03-25 16:05:04 -07:00
Chris LaFreniere
1bac929ab3 Fix for SQL Kernel only showing up (#4691)
* Ensure that notebook providers that are registered "early" are shown in kernels dropdown

* cleanup
2019-03-25 15:24:57 -07:00
Charles Gagnon
b27417da41 Add ADS Windows support extension with LaunchSsmsDialog command (#4248)
* ADS Windows support extension with LaunchSsmsDialog command

* Update readme

* Fix spacing

* Update download with new file location and name

* Update SsmsMin package with bits from latest RC build and addressed some comments.

* Update extension name. Add Context menu extension for launching server properties dialog. Remove params interface from public API

* Rename folder and update README

* Correct README title

* Fix a few issues and clean up some stuff.

* Update to azdata namespace

* Refactor to use async/await and add some more telemetry

* Add .bat for running extension tests (currently only Notebook) and set up launch.json with 2 new launch configs for running & debugging extension tests.

* Rename files to make it clear these aren't the integration tests

* Update launch.config too

* Fix spacing and missed file name update

* Fix some bugs in buildSsmsMinCommandArgs and add unit tests
2019-03-25 14:19:11 -07:00
Charles Gagnon
ef1f72f69b Remove popular extensions view (#4679)
We don't track installs for our extensions so the "Popular Extensions" category is just a duplicate of the full list. Removing it to reduce clutter until we can add that functionality in. This also removes the command associated with the view.
2019-03-25 13:21:48 -07:00
Raj
784fd57410 confirmSave using UntitledEditorInput (#4611) 2019-03-25 10:25:28 -07:00
Charles Gagnon
1dd0afcf80 Add ADS Startup Telemetry events back in (#4675)
They were removed with a VS Code merge. Changed to using extension contribution to log the telemetry to reduce the amount of VS code edits.
2019-03-23 11:02:34 -07:00
udeeshagautam
ddce7731b9 Feature/viewlet cmsapis (#4312)
* first set of changes to experiment the registration of cms related apis

* Adding cms service entry to workbench

* Adding basic functionality for add remove reg servers and group

* Returning relative path as part of RegServerResult as string

* Removing the cms apis from core. Having mssql extension expose them for cms extension

* Propogating the backend name changes to apis

* Fixing some missing sqlops references

* Adding a sqltools service version with CMS apis available
2019-03-22 17:24:45 -07:00
Alan Ren
d00c3780a6 fix for issue 4596 (#4670) 2019-03-22 14:11:26 -07:00
Anthony Dresser
4a87a24235 Merge from vscode 011858832762aaff245b2336fb1c38166e7a10fb (#4663) 2019-03-22 13:07:54 -07:00
Anthony Dresser
f5c9174c2f Revert "Connection Store Refactor (#4632)" (#4671)
This reverts commit 756f77063a.
2019-03-22 11:30:20 -07:00
Alan Ren
8d5f676039 a few deploy cluster wizard changes (#4644)
* update icon for target types

* Revert "update icon for target types"

This reverts commit 79bd7674f2c09602430a0b10829f7b0d3234eb98.

* update target type icons

* update eula and privacy policy links

* existing cluster page

* adjust the loading indicator position
2019-03-22 11:29:51 -07:00
Yurong He
71db7e10b6 Add notebook integration tests (#4652)
* Add notebook integration tests
2019-03-22 10:39:44 -07:00
Anthony Dresser
756f77063a Connection Store Refactor (#4632)
* various clean ups

* formatting

* remove linting

* formatting

* IConfigurationService is even better

* messing with connection config tests

* update tests

* formatting

* foramtting

* remove unused code

* add more tests

* working through tests

* formatting

* more factoring of connection store and increase code coverage

* formatting

* fix tests
2019-03-22 01:07:32 -07:00
Matt Irvine
5f637036bc Fix query tab color regression (#4660) 2019-03-21 16:22:03 -07:00
Anthony Dresser
24b5f41065 add data explorer default (#4653) 2019-03-21 16:10:54 -07:00
Chris LaFreniere
b00352570b Fix the "Failed to show notebook document" errors (#4649) 2019-03-21 16:06:17 -07:00
Matt Irvine
0b44b7d384 Fix issue reporter 'Visual Studio Code' text (#4658) 2019-03-21 15:38:25 -07:00
Chris LaFreniere
82da64d66d Handle future done in SQL for multiple batches (#4654) 2019-03-21 13:47:01 -07:00
Matt Irvine
ee5a76bb0c Go back to LICENSE.txt for Windows installers (#4655) 2019-03-21 13:28:51 -07:00
Anthony Dresser
b65ee5b42e Merge from vscode fc10e26ea50f82cdd84e9141491357922e6f5fba (#4639) 2019-03-21 10:58:16 -07:00
Anthony Dresser
8298db7d13 Ignore the users title bar settings (#4625)
* ignore the users title bar settings

* ignore in more places
2019-03-20 19:39:43 -07:00
Chris LaFreniere
5b0e86b179 Have notebook grids respond to theme change events (#4624) 2019-03-20 18:47:57 -07:00
Matt Irvine
ed2641ea02 Update how we create services (#4638) 2019-03-20 17:08:15 -07:00
Matt Irvine
66939636dc Bring over code-url-handler.desktop (#4629) 2019-03-20 14:56:50 -07:00
Anthony Dresser
2c331d929a remove duplicate launch task (#4631) 2019-03-20 12:34:27 -07:00
Anthony Dresser
4472764f3a extensions tslint cleanup/Connection config refactor (#4370)
* various clean ups

* formatting

* remove linting

* formatting

* IConfigurationService is even better

* messing with connection config tests

* update tests

* formatting

* foramtting

* remove unused code

* add more tests
2019-03-20 11:59:07 -07:00
Karl Burtram
6cb7153bdd VBump ADS to 1.6.0 2019-03-20 11:41:41 -07:00
Anthony Dresser
5142f69655 Cleanup dependencies (#4546)
* Merge VS Code 1.31.1

* Fix missed merge conflict

* Fix license in new files

* Remove extra extension files

* Fix compile error

* Fix TSLint errors

* Fix integration tests

* Fixed saved and recent connections list

* Fix tests

* move dependecies and delete unused ones

* fix test compile
2019-03-20 11:30:20 -07:00
Anthony Dresser
dfe23f7bfe Remove some CARBON Edits (#4571)
* remove some unnecessary sql carbon edits to vs source and adds correct fix where necessary

* revert bad change
2019-03-20 11:30:06 -07:00
Raj
6873353cd4 #4618: Notebook JSON has extra } after save (#4627) 2019-03-20 11:12:02 -07:00
Matt Irvine
025c97673f Reapply extension management edits that were removed in 1.31 merge (#4606) 2019-03-20 10:40:09 -07:00
Anthony Dresser
c814b92557 VSCode merge (#4610)
* Merge from vscode e388c734f30757875976c7e326d6cfeee77710de

* fix yarn lcoks

* remove small issue
2019-03-20 10:39:09 -07:00
Anthony Dresser
87765e8673 Vscode merge (#4582)
* Merge from vscode 37cb23d3dd4f9433d56d4ba5ea3203580719a0bd

* fix issues with merges

* bump node version in azpipe

* replace license headers

* remove duplicate launch task

* fix build errors

* fix build errors

* fix tslint issues

* working through package and linux build issues

* more work

* wip

* fix packaged builds

* working through linux build errors

* wip

* wip

* wip

* fix mac and linux file limits

* iterate linux pipeline

* disable editor typing

* revert series to parallel

* remove optimize vscode from linux

* fix linting issues

* revert testing change

* add work round for new node

* readd packaging for extensions

* fix issue with angular not resolving decorator dependencies
2019-03-19 17:44:35 -07:00
Raj
833d197412 #3973: Persist scroll position when tab notebooks (#4531)
* #3973: Persist scroll position when tab notebooks

* Remove getter and setter
2019-03-19 14:01:24 -07:00
Maddy
5e72cd12d1 Maddy/prompt password when different (#4537)
* Prompt for password once when the sql instance password doesn't work for hdfs. If the user provides the correct password, connect and continue, else show Unauthorized  node.

* Removed the hardcoded bad password

* Added check for empty folder scenarios

* Added ErrorStatusCode as property of TreeNode. Checking for the error code instead of the error string to avoid localization issues

* type fixed

* implemented hasExpansionError
2019-03-19 13:46:55 -07:00
Charles Gagnon
330fb6dff5 Remove tooltip from editable dropdown (#4542)
* Fix our custom dropdown control to update the tooltip text correctly when a new value is selected. Previous behavior was to always keep the initial text (<Default> for example). Now we'll update it as appropriate (and default back to Placeholder text when we're clearing the value)

* Spaces -> tabs

* Remove extra ;

* Remove tooltips from the text box part of the dropdown

* Remove tooltips from dropdown arrows

* Revert "Remove tooltips from dropdown arrows"

This reverts commit 31a0748aaea42d5009eb9752bd075ce49a6716f5.
2019-03-19 13:46:36 -07:00
Raj
6d7d485a38 #4331: Set notebook dirty when change 'trusted' (#4569) 2019-03-18 10:56:04 -07:00
3431 changed files with 196300 additions and 126558 deletions

3
.gitattributes vendored
View File

@@ -6,4 +6,5 @@ ThirdPartyNotices.txt eol=crlf
*.bat eol=crlf
*.cmd eol=crlf
*.ps1 eol=lf
*.sh eol=lf
*.sh eol=lf
*.rtf -text

View File

@@ -2,7 +2,7 @@
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
labels: Bug
assignees: ''
---

View File

@@ -2,7 +2,7 @@
name: Feature request
about: Suggest an idea for this project
title: ''
labels: feature request
labels: Enhancement
assignees: ''
---

View File

@@ -1,5 +1,5 @@
{
perform: true,
perform: false,
alwaysRequireAssignee: false,
labelsRequiringAssignee: [],
autoAssignees: {

2
.nvmrc
View File

@@ -1 +1 @@
8
10

9
.vscode/launch.json vendored
View File

@@ -70,10 +70,15 @@
"timeout": 20000
},
"osx": {
"runtimeExecutable": "${workspaceFolder}/scripts/sql.sh"
"runtimeExecutable": "${workspaceFolder}/scripts/sql.sh",
"timeout": 20000
},
"linux": {
"runtimeExecutable": "${workspaceFolder}/scripts/sql.sh"
"runtimeExecutable": "${workspaceFolder}/scripts/sql.sh",
"timeout": 20000
},
"env": {
"VSCODE_EXTHOST_WILL_SEND_SOCKET": null
},
"breakOnLoad": false,
"urlFilter": "*workbench.html*",

26
.vscode/settings.json vendored
View File

@@ -44,13 +44,19 @@
"emmet.excludeLanguages": [],
"typescript.preferences.importModuleSpecifier": "non-relative",
"typescript.preferences.quoteStyle": "single",
"json.schemas": [{
"fileMatch": [ "cgmanifest.json" ],
"url": "./.vscode/cgmanifest.schema.json"
}, {
"fileMatch": [ "cglicenses.json" ],
"url": "./.vscode/cglicenses.schema.json"
}
],
"git.ignoreLimitWarning": true
}
"json.schemas": [
{
"fileMatch": [
"cgmanifest.json"
],
"url": "./.vscode/cgmanifest.schema.json"
},
{
"fileMatch": [
"cglicenses.json"
],
"url": "./.vscode/cglicenses.schema.json"
}
],
"git.ignoreLimitWarning": true
}

11
.vscode/tasks.json vendored
View File

@@ -30,19 +30,16 @@
},
{
"type": "npm",
"script": "strict-null-check-watch",
"label": "TS - Strict Null Checks",
"script": "strict-initialization-watch",
"label": "TS - Strict Initialization",
"isBackground": true,
"presentation": {
"reveal": "never"
},
"problemMatcher": {
"base": "$tsc-watch",
"owner": "typescript-strict-null",
"owner": "typescript-strict-initialization",
"applyTo": "allDocuments"
},
"runOptions": {
"runOn": "folderOpen"
}
},
{
@@ -86,4 +83,4 @@
"problemMatcher": []
}
]
}
}

View File

@@ -1,3 +1,3 @@
disturl "https://atom.io/download/electron"
target "3.1.2"
target "3.1.8"
runtime "electron"

View File

@@ -1,5 +1,18 @@
# Change Log
## Version 1.6.0
* Release date: April 18, 2019
* Release status: General Availability
## What's new in this version
* Align with latest VS Code editor platform (currently 1.33.1)
* Resolved [bugs and issues](https://github.com/Microsoft/azuredatastudio/milestone/26?closed=1).
## Contributions and "thank you"
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
* yamatoya for `fix the format (#4899)`
## Version 1.5.1
* Release date: March 18, 2019
* Release status: General Availability

View File

@@ -9,13 +9,13 @@ Azure Data Studio is a data management tool that enables you to work with SQL Se
Platform | Link
-- | --
Windows User Installer | https://go.microsoft.com/fwlink/?linkid=2083322
Windows System Installer | https://go.microsoft.com/fwlink/?linkid=2083323
Windows ZIP | https://go.microsoft.com/fwlink/?linkid=2083324
macOS ZIP | https://go.microsoft.com/fwlink/?linkid=2083325
Linux TAR.GZ | https://go.microsoft.com/fwlink/?linkid=2083424
Linux RPM | https://go.microsoft.com/fwlink/?linkid=2083326
Linux DEB | https://go.microsoft.com/fwlink/?linkid=2083327
Windows User Installer | https://go.microsoft.com/fwlink/?linkid=2087316
Windows System Installer | https://go.microsoft.com/fwlink/?linkid=2087317
Windows ZIP | https://go.microsoft.com/fwlink/?linkid=2087318
macOS ZIP | https://go.microsoft.com/fwlink/?linkid=2087170
Linux TAR.GZ | https://go.microsoft.com/fwlink/?linkid=2087414
Linux RPM | https://go.microsoft.com/fwlink/?linkid=2087171
Linux DEB | https://go.microsoft.com/fwlink/?linkid=2087415
Go to our [download page](https://aka.ms/azuredatastudio) for more specific instructions.
@@ -68,6 +68,7 @@ The [Microsoft Enterprise and Developer Privacy Statement](https://privacy.micro
## Contributions and "Thank You"
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
* yamatoya for `fix the format (#4899)`
* GeoffYoung for `Fix sqlDropColumn description #4422`
* AlexFsmn for `Added context menu for DBs in explorer view to backup & restore db. #2277`
* sadedil for `Missing feature request: Save as XML #3729`

View File

@@ -343,32 +343,6 @@ END OF emmet NOTICES AND INFORMATION
=========================================
The MIT License (MIT)
Copyright (c) 2015 JD Ballard
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
=========================================
END OF error-ex NOTICES AND INFORMATION
%% escape-string-regexp NOTICES AND INFORMATION BEGIN HERE
=========================================
The MIT License (MIT)
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -2465,4 +2439,4 @@ SOFTWARE.
-------------------------------END OF THIRD-PARTY NOTICES-------------------------------------------
=========================================
END OF Microsoft.ProgramSynthesis.Detection NOTICES AND INFORMATION
END OF Microsoft.ProgramSynthesis.Detection NOTICES AND INFORMATION

View File

@@ -6,8 +6,8 @@ steps:
- script: |
git submodule update --init --recursive
nvm install 8.9.1
nvm use 8.9.1
nvm install 10.15.1
nvm use 10.15.1
npm i -g yarn
displayName: 'preinstall'
@@ -24,23 +24,46 @@ steps:
- script: |
yarn
displayName: 'Install'
displayName: 'Install'
- script: |
node_modules/.bin/gulp electron
node_modules/.bin/gulp compile --max_old_space_size=4096
node_modules/.bin/gulp optimize-vscode --max_old_space_size=4096
displayName: 'Scripts'
yarn gulp electron-x64
displayName: Download Electron
- script: |
yarn gulp hygiene
displayName: Run Hygiene Checks
- script: |
yarn tslint
displayName: 'Run TSLint'
- script: |
yarn strict-null-check
displayName: 'Run Strict Null Check'
- script: |
yarn compile
displayName: 'Compile'
- script: |
DISPLAY=:10 ./scripts/test.sh --reporter mocha-junit-reporter
displayName: 'Tests'
condition: eq(variables['Agent.OS'], 'Linux')
- script: |
DISPLAY=:10 ./scripts/test.sh --reporter mocha-junit-reporter --coverage
displayName: 'Tests'
condition: ne(variables['Agent.OS'], 'Linux')
- task: PublishTestResults@2
inputs:
testResultsFiles: '**/test-results.xml'
condition: succeededOrFailed()
- script: |
yarn run tslint
displayName: 'Run TSLint'
- task: PublishCodeCoverageResults@1
inputs:
codeCoverageTool: 'cobertura'
summaryFileLocation: $(System.DefaultWorkingDirectory)/.build/coverage/cobertura-coverage.xml
reportDirectory: $(System.DefaultWorkingDirectory)/.build/coverage/lcov-reports
condition: ne(variables['Agent.OS'], 'Linux')

View File

@@ -1,7 +1,7 @@
steps:
- task: NodeTool@0
inputs:
versionSpec: '8.9'
versionSpec: '10.15.1'
displayName: 'Install Node.js'
- script: |
@@ -9,15 +9,27 @@ steps:
displayName: 'Yarn Install'
- script: |
.\node_modules\.bin\gulp electron
yarn gulp electron-x64
displayName: 'Electron'
- script: |
npm run compile
yarn gulp hygiene
displayName: Run Hygiene Checks
- script: |
yarn tslint
displayName: 'Run TSLint'
- script: |
yarn strict-null-check
displayName: 'Run Strict Null Check'
- script: |
yarn compile
displayName: 'Compile'
- script: |
.\scripts\test.bat --reporter mocha-junit-reporter
.\scripts\test.bat --reporter mocha-junit-reporter --coverage
displayName: 'Test'
- task: PublishTestResults@2
@@ -25,6 +37,8 @@ steps:
testResultsFiles: 'test-results.xml'
condition: succeededOrFailed()
- script: |
yarn run tslint
displayName: 'Run TSLint'
- task: PublishCodeCoverageResults@1
inputs:
codeCoverageTool: 'cobertura'
summaryFileLocation: $(System.DefaultWorkingDirectory)\.build\coverage\cobertura-coverage.xml
reportDirectory: $(System.DefaultWorkingDirectory)\.build\coverage\lcov-report

View File

@@ -6,7 +6,6 @@
'use strict';
import * as fs from 'fs';
import { execSync } from 'child_process';
import { Readable } from 'stream';
import * as crypto from 'crypto';
import * as azure from 'azure-storage';
@@ -66,8 +65,7 @@ interface Asset {
platform: string;
type: string;
url: string;
// {{SQL CARBON EDIT}}
mooncakeUrl: string | undefined;
mooncakeUrl?: string;
hash: string;
sha256hash: string;
size: number;
@@ -154,9 +152,13 @@ async function publish(commit: string, quality: string, platform: string, type:
const queuedBy = process.env['BUILD_QUEUEDBY']!;
const sourceBranch = process.env['BUILD_SOURCEBRANCH']!;
const isReleased = quality === 'insider'
&& /^master$|^refs\/heads\/master$/.test(sourceBranch)
&& /Project Collection Service Accounts|Microsoft.VisualStudio.Services.TFS/.test(queuedBy);
const isReleased = (
// Insiders: nightly build from master
(quality === 'insider' && /^master$|^refs\/heads\/master$/.test(sourceBranch) && /Project Collection Service Accounts|Microsoft.VisualStudio.Services.TFS/.test(queuedBy)) ||
// Exploration: any build from electron-4.0.x branch
(quality === 'exploration' && /^electron-4.0.x$|^refs\/heads\/electron-4.0.x$/.test(sourceBranch))
);
console.log('Publishing...');
console.log('Quality:', quality);
@@ -186,56 +188,18 @@ async function publish(commit: string, quality: string, platform: string, type:
const blobService = azure.createBlobService(storageAccount, process.env['AZURE_STORAGE_ACCESS_KEY_2']!)
.withFilter(new azure.ExponentialRetryPolicyFilter(20));
// {{SQL CARBON EDIT}}
await assertContainer(blobService, quality);
const blobExists = await doesAssetExist(blobService, quality, blobName);
const promises = [];
if (!blobExists) {
promises.push(uploadBlob(blobService, quality, blobName, file));
}
// {{SQL CARBON EDIT}}
if (process.env['MOONCAKE_STORAGE_ACCESS_KEY']) {
const mooncakeBlobService = azure.createBlobService(storageAccount, process.env['MOONCAKE_STORAGE_ACCESS_KEY']!, `${storageAccount}.blob.core.chinacloudapi.cn`)
.withFilter(new azure.ExponentialRetryPolicyFilter(20));
// mooncake is fussy and far away, this is needed!
mooncakeBlobService.defaultClientRequestTimeoutInMs = 10 * 60 * 1000;
await Promise.all([
assertContainer(blobService, quality),
assertContainer(mooncakeBlobService, quality)
]);
const [blobExists, moooncakeBlobExists] = await Promise.all([
doesAssetExist(blobService, quality, blobName),
doesAssetExist(mooncakeBlobService, quality, blobName)
]);
const promises: Array<Promise<void>> = [];
if (!blobExists) {
promises.push(uploadBlob(blobService, quality, blobName, file));
}
if (!moooncakeBlobExists) {
promises.push(uploadBlob(mooncakeBlobService, quality, blobName, file));
}
} else {
console.log('Skipping Mooncake publishing.');
}
if (promises.length === 0) {
if (blobExists) {
console.log(`Blob ${quality}, ${blobName} already exists, not publishing again.`);
return;
}
console.log('Uploading blobs to Azure storage...');
await Promise.all(promises);
await uploadBlob(blobService, quality, blobName, file);
console.log('Blobs successfully uploaded.');
@@ -247,8 +211,6 @@ async function publish(commit: string, quality: string, platform: string, type:
platform: platform,
type: type,
url: `${process.env['AZURE_CDN_URL']}/${quality}/${blobName}`,
// {{SQL CARBON EDIT}}
mooncakeUrl: process.env['MOONCAKE_CDN_URL'] ? `${process.env['MOONCAKE_CDN_URL']}/${quality}/${blobName}` : undefined,
hash: sha1hash,
sha256hash,
size
@@ -289,15 +251,18 @@ function main(): void {
return;
}
const commit = process.env['BUILD_SOURCEVERSION'];
if (!commit) {
console.warn('Skipping publish due to missing BUILD_SOURCEVERSION');
return;
}
const opts = minimist<PublishOptions>(process.argv.slice(2), {
boolean: ['upload-only']
});
// {{SQL CARBON EDIT}}
let [quality, platform, type, name, version, _isUpdate, file, commit] = opts._;
if (!commit) {
commit = execSync('git rev-parse HEAD', { encoding: 'utf8' }).trim();
}
const [quality, platform, type, name, version, _isUpdate, file] = opts._;
publish(commit, quality, platform, type, name, version, _isUpdate, file, opts).catch(err => {
console.error(err);

View File

@@ -0,0 +1,176 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as url from 'url';
import * as azure from 'azure-storage';
import * as mime from 'mime';
import { DocumentClient, RetrievedDocument } from 'documentdb';
function log(...args: any[]) {
console.log(...[`[${new Date().toISOString()}]`, ...args]);
}
function error(...args: any[]) {
console.error(...[`[${new Date().toISOString()}]`, ...args]);
}
if (process.argv.length < 3) {
error('Usage: node sync-mooncake.js <quality>');
process.exit(-1);
}
interface Build extends RetrievedDocument {
assets: Asset[];
}
interface Asset {
platform: string;
type: string;
url: string;
mooncakeUrl: string;
hash: string;
sha256hash: string;
size: number;
supportsFastUpdate?: boolean;
}
function updateBuild(commit: string, quality: string, platform: string, type: string, asset: Asset): Promise<void> {
const client = new DocumentClient(process.env['AZURE_DOCUMENTDB_ENDPOINT']!, { masterKey: process.env['AZURE_DOCUMENTDB_MASTERKEY'] });
const collection = 'dbs/builds/colls/' + quality;
const updateQuery = {
query: 'SELECT TOP 1 * FROM c WHERE c.id = @id',
parameters: [{ name: '@id', value: commit }]
};
let updateTries = 0;
function _update(): Promise<void> {
updateTries++;
return new Promise<void>((c, e) => {
client.queryDocuments(collection, updateQuery).toArray((err, results) => {
if (err) { return e(err); }
if (results.length !== 1) { return e(new Error('No documents')); }
const release = results[0];
release.assets = [
...release.assets.filter((a: any) => !(a.platform === platform && a.type === type)),
asset
];
client.replaceDocument(release._self, release, err => {
if (err && err.code === 409 && updateTries < 5) { return c(_update()); }
if (err) { return e(err); }
log('Build successfully updated.');
c();
});
});
});
}
return _update();
}
async function sync(commit: string, quality: string): Promise<void> {
log(`Synchronizing Mooncake assets for ${quality}, ${commit}...`);
const cosmosdb = new DocumentClient(process.env['AZURE_DOCUMENTDB_ENDPOINT']!, { masterKey: process.env['AZURE_DOCUMENTDB_MASTERKEY'] });
const collection = `dbs/builds/colls/${quality}`;
const query = {
query: 'SELECT TOP 1 * FROM c WHERE c.id = @id',
parameters: [{ name: '@id', value: commit }]
};
const build = await new Promise<Build>((c, e) => {
cosmosdb.queryDocuments(collection, query).toArray((err, results) => {
if (err) { return e(err); }
if (results.length !== 1) { return e(new Error('No documents')); }
c(results[0] as Build);
});
});
log(`Found build for ${commit}, with ${build.assets.length} assets`);
const storageAccount = process.env['AZURE_STORAGE_ACCOUNT_2']!;
const blobService = azure.createBlobService(storageAccount, process.env['AZURE_STORAGE_ACCESS_KEY_2']!)
.withFilter(new azure.ExponentialRetryPolicyFilter(20));
const mooncakeBlobService = azure.createBlobService(storageAccount, process.env['MOONCAKE_STORAGE_ACCESS_KEY']!, `${storageAccount}.blob.core.chinacloudapi.cn`)
.withFilter(new azure.ExponentialRetryPolicyFilter(20));
// mooncake is fussy and far away, this is needed!
blobService.defaultClientRequestTimeoutInMs = 10 * 60 * 1000;
mooncakeBlobService.defaultClientRequestTimeoutInMs = 10 * 60 * 1000;
for (const asset of build.assets) {
try {
const blobPath = url.parse(asset.url).path;
if (!blobPath) {
throw new Error(`Failed to parse URL: ${asset.url}`);
}
const blobName = blobPath.replace(/^\/\w+\//, '');
log(`Found ${blobName}`);
if (asset.mooncakeUrl) {
log(` Already in Mooncake ✔️`);
continue;
}
const readStream = blobService.createReadStream(quality, blobName, undefined!);
const blobOptions: azure.BlobService.CreateBlockBlobRequestOptions = {
contentSettings: {
contentType: mime.lookup(blobPath),
cacheControl: 'max-age=31536000, public'
}
};
const writeStream = mooncakeBlobService.createWriteStreamToBlockBlob(quality, blobName, blobOptions, undefined);
log(` Uploading to Mooncake...`);
await new Promise((c, e) => readStream.pipe(writeStream).on('finish', c).on('error', e));
log(` Updating build in DB...`);
asset.mooncakeUrl = `${process.env['MOONCAKE_CDN_URL']}${blobPath}`;
await updateBuild(commit, quality, asset.platform, asset.type, asset);
log(` Done ✔️`);
} catch (err) {
error(err);
}
}
log(`All done ✔️`);
}
function main(): void {
if (process.env['VSCODE_BUILD_SKIP_PUBLISH']) {
error('Skipping publish due to VSCODE_BUILD_SKIP_PUBLISH');
return;
}
const commit = process.env['BUILD_SOURCEVERSION'];
if (!commit) {
error('Skipping publish due to missing BUILD_SOURCEVERSION');
return;
}
const quality = process.argv[2];
sync(commit, quality).catch(err => {
error(err);
process.exit(1);
});
}
main();

View File

@@ -0,0 +1,4 @@
#!/usr/bin/env bash
set -e
yarn gulp vscode-darwin-min
yarn gulp upload-vscode-sourcemaps

View File

@@ -1,13 +1,26 @@
steps:
- task: NodeTool@0
inputs:
versionSpec: "8.12.0"
versionSpec: "10.15.1"
- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2
inputs:
versionSpec: "1.10.1"
# - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1
# inputs:
# keyfile: '**/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock'
# targetfolder: '**/node_modules, !**/node_modules/**/node_modules'
# vstsFeed: '$(ArtifactFeed)'
# condition: eq(variables['System.PullRequest.PullRequestId'], '')
- script: |
yarn
displayName: Install Dependencies
# condition: or(ne(variables['System.PullRequest.PullRequestId'], ''), ne(variables['CacheRestored'], 'true'))
# - task: 1ESLighthouseEng.PipelineArtifactCaching.SaveCacheV1.SaveCache@1
# inputs:
# keyfile: '**/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock'
# targetfolder: '**/node_modules, !**/node_modules/**/node_modules'
# vstsFeed: '$(ArtifactFeed)'
# condition: and(succeeded(), eq(variables['System.PullRequest.PullRequestId'], ''), ne(variables['CacheRestored'], 'true'))
- script: |
yarn gulp electron-x64
displayName: Download Electron
@@ -17,9 +30,6 @@ steps:
- script: |
yarn monaco-compile-check
displayName: Run Monaco Editor Checks
- script: |
yarn strict-null-check
displayName: Run Strict Null Checks
- script: |
yarn compile
displayName: Compile Sources
@@ -37,4 +47,4 @@ steps:
inputs:
testResultsFiles: '*-results.xml'
searchFolder: '$(Build.ArtifactStagingDirectory)/test-results'
condition: succeededOrFailed()
condition: succeededOrFailed()

View File

@@ -1,7 +1,7 @@
steps:
- task: NodeTool@0
inputs:
versionSpec: "8.12.0"
versionSpec: "10.15.1"
- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2
inputs:
@@ -9,12 +9,25 @@ steps:
- script: |
set -e
echo "machine monacotools.visualstudio.com password $(VSO_PAT)" > ~/.netrc
cat << EOF > ~/.netrc
machine monacotools.visualstudio.com
password $(VSO_PAT)
machine github.com
login vscode
password $(VSCODE_MIXIN_PASSWORD)
EOF
git config user.email "vscode@microsoft.com"
git config user.name "VSCode"
git remote add distro "https://github.com/$(VSCODE_MIXIN_REPO).git"
git fetch distro
git merge $(node -p "require('./package.json').distro")
yarn
yarn gulp -- hygiene
yarn gulp mixin
yarn gulp hygiene
yarn monaco-compile-check
yarn strict-null-check
VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)" yarn gulp -- mixin
node build/azure-pipelines/common/installDistro.js
node build/lib/builtInExtensions.js
displayName: Prepare build
@@ -23,7 +36,7 @@ steps:
set -e
VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)" \
AZURE_STORAGE_ACCESS_KEY="$(AZURE_STORAGE_ACCESS_KEY)" \
yarn gulp -- vscode-darwin-min upload-vscode-sourcemaps
./build/azure-pipelines/darwin/build.sh
displayName: Build
- script: |
@@ -33,6 +46,11 @@ steps:
# yarn smoketest -- --build "$(agent.builddirectory)/VSCode-darwin/$APP_NAME"
displayName: Run unit tests
- script: |
set -e
./scripts/test-integration.sh --build --tfs "Integration Tests"
displayName: Run integration tests
- script: |
set -e
pushd ../VSCode-darwin && zip -r -X -y ../VSCode-darwin.zip * && popd
@@ -59,31 +77,12 @@ steps:
- script: |
set -e
# remove pkg from archive
zip -d ../VSCode-darwin.zip "*.pkg"
# publish the build
PACKAGEJSON=`ls ../VSCode-darwin/*.app/Contents/Resources/app/package.json`
VERSION=`node -p "require(\"$PACKAGEJSON\").version"`
VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)" \
AZURE_DOCUMENTDB_MASTERKEY="$(AZURE_DOCUMENTDB_MASTERKEY)" \
AZURE_STORAGE_ACCESS_KEY_2="$(AZURE_STORAGE_ACCESS_KEY_2)" \
MOONCAKE_STORAGE_ACCESS_KEY="$(MOONCAKE_STORAGE_ACCESS_KEY)" \
node build/azure-pipelines/common/publish.js \
"$(VSCODE_QUALITY)" \
darwin \
archive \
"VSCode-darwin-$(VSCODE_QUALITY).zip" \
$VERSION \
true \
../VSCode-darwin.zip
# publish hockeyapp symbols
node build/azure-pipelines/common/symbols.js "$(VSCODE_MIXIN_PASSWORD)" "$(VSCODE_HOCKEYAPP_TOKEN)" "$(VSCODE_ARCH)" "$(VSCODE_HOCKEYAPP_ID_MACOS)"
# upload configuration
AZURE_STORAGE_ACCESS_KEY="$(AZURE_STORAGE_ACCESS_KEY)" \
yarn gulp -- upload-vscode-configuration
AZURE_STORAGE_ACCESS_KEY_2="$(AZURE_STORAGE_ACCESS_KEY_2)" \
VSCODE_HOCKEYAPP_TOKEN="$(VSCODE_HOCKEYAPP_TOKEN)" \
./build/azure-pipelines/darwin/publish.sh
displayName: Publish
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0

View File

@@ -0,0 +1,22 @@
#!/usr/bin/env bash
# remove pkg from archive
zip -d ../VSCode-darwin.zip "*.pkg"
# publish the build
PACKAGEJSON=`ls ../VSCode-darwin/*.app/Contents/Resources/app/package.json`
VERSION=`node -p "require(\"$PACKAGEJSON\").version"`
node build/azure-pipelines/common/publish.js \
"$VSCODE_QUALITY" \
darwin \
archive \
"VSCode-darwin-$VSCODE_QUALITY.zip" \
$VERSION \
true \
../VSCode-darwin.zip
# publish hockeyapp symbols
node build/azure-pipelines/common/symbols.js "$VSCODE_MIXIN_PASSWORD" "$VSCODE_HOCKEYAPP_TOKEN" "$VSCODE_ARCH" "$VSCODE_HOCKEYAPP_ID_MACOS"
# upload configuration
yarn gulp upload-vscode-configuration

View File

@@ -0,0 +1,30 @@
trigger:
branches:
include: ['master', 'release/*']
pr:
branches:
include: ['master', 'release/*']
steps:
- task: NodeTool@0
inputs:
versionSpec: "10.15.1"
- script: |
set -e
cat << EOF > ~/.netrc
machine github.com
login vscode
password $(VSCODE_MIXIN_PASSWORD)
EOF
git config user.email "vscode@microsoft.com"
git config user.name "VSCode"
git remote add distro "https://github.com/$VSCODE_MIXIN_REPO.git"
git fetch distro
git push distro origin/master:refs/heads/master
git merge $(node -p "require('./package.json').distro")
displayName: Sync & Merge Distro

View File

@@ -0,0 +1,3 @@
#!/usr/bin/env bash
set -e
yarn gulp "vscode-linux-$VSCODE_ARCH-min"

View File

@@ -9,13 +9,26 @@ steps:
sudo service xvfb start
- task: NodeTool@0
inputs:
versionSpec: "8.12.0"
versionSpec: "10.15.1"
- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2
inputs:
versionSpec: "1.10.1"
# - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1
# inputs:
# keyfile: '**/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock'
# targetfolder: '**/node_modules, !**/node_modules/**/node_modules'
# vstsFeed: '$(ArtifactFeed)'
# condition: eq(variables['System.PullRequest.PullRequestId'], '')
- script: |
yarn
displayName: Install Dependencies
# condition: or(ne(variables['System.PullRequest.PullRequestId'], ''), ne(variables['CacheRestored'], 'true'))
# - task: 1ESLighthouseEng.PipelineArtifactCaching.SaveCacheV1.SaveCache@1
# inputs:
# keyfile: '**/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock'
# targetfolder: '**/node_modules, !**/node_modules/**/node_modules'
# vstsFeed: '$(ArtifactFeed)'
# condition: and(succeeded(), eq(variables['System.PullRequest.PullRequestId'], ''), ne(variables['CacheRestored'], 'true'))
- script: |
yarn gulp electron-x64
displayName: Download Electron
@@ -25,9 +38,6 @@ steps:
- script: |
yarn monaco-compile-check
displayName: Run Monaco Editor Checks
- script: |
yarn strict-null-check
displayName: Run Strict Null Checks
- script: |
yarn compile
displayName: Compile Sources
@@ -42,4 +52,4 @@ steps:
inputs:
testResultsFiles: '*-results.xml'
searchFolder: '$(Build.ArtifactStagingDirectory)/test-results'
condition: succeededOrFailed()
condition: succeededOrFailed()

View File

@@ -1,7 +1,7 @@
steps:
- task: NodeTool@0
inputs:
versionSpec: "8.12.0"
versionSpec: "10.15.1"
- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2
inputs:
@@ -14,92 +14,53 @@ steps:
export PKG_CONFIG_PATH="/usr/lib/i386-linux-gnu/pkgconfig"
fi
echo "machine monacotools.visualstudio.com password $(VSO_PAT)" > ~/.netrc
cat << EOF > ~/.netrc
machine monacotools.visualstudio.com
password $(VSO_PAT)
machine github.com
login vscode
password $(VSCODE_MIXIN_PASSWORD)
EOF
git config user.email "vscode@microsoft.com"
git config user.name "VSCode"
git remote add distro "https://github.com/$(VSCODE_MIXIN_REPO).git"
git fetch distro
git merge $(node -p "require('./package.json').distro")
CHILD_CONCURRENCY=1 yarn
npm run gulp -- hygiene
npm run monaco-compile-check
npm run strict-null-check
VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)" npm run gulp -- mixin
yarn gulp mixin
yarn gulp hygiene
yarn monaco-compile-check
node build/azure-pipelines/common/installDistro.js
node build/lib/builtInExtensions.js
displayName: Prepare build
- script: |
set -e
VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)" npm run gulp -- vscode-linux-$(VSCODE_ARCH)-min
name: build
VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)" \
./build/azure-pipelines/linux/build.sh
displayName: Build
- script: |
set -e
npm run gulp -- "electron-$(VSCODE_ARCH)"
yarn gulp "electron-$(VSCODE_ARCH)"
# xvfb seems to be crashing often, let's make sure it's always up
service xvfb start
DISPLAY=:10 ./scripts/test.sh --build --tfs "Unit Tests"
# yarn smoketest -- --build "$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)"
name: test
displayName: Run unit tests
- script: |
set -e
REPO="$(pwd)"
ROOT="$REPO/.."
ARCH="$(VSCODE_ARCH)"
# Publish tarball
PLATFORM_LINUX="linux-$(VSCODE_ARCH)"
[[ "$ARCH" == "ia32" ]] && DEB_ARCH="i386" || DEB_ARCH="amd64"
[[ "$ARCH" == "ia32" ]] && RPM_ARCH="i386" || RPM_ARCH="x86_64"
BUILDNAME="VSCode-$PLATFORM_LINUX"
BUILD="$ROOT/$BUILDNAME"
BUILD_VERSION="$(date +%s)"
[ -z "$VSCODE_QUALITY" ] && TARBALL_FILENAME="code-$BUILD_VERSION.tar.gz" || TARBALL_FILENAME="code-$VSCODE_QUALITY-$BUILD_VERSION.tar.gz"
TARBALL_PATH="$ROOT/$TARBALL_FILENAME"
PACKAGEJSON="$BUILD/resources/app/package.json"
VERSION=$(node -p "require(\"$PACKAGEJSON\").version")
rm -rf $ROOT/code-*.tar.*
(cd $ROOT && tar -czf $TARBALL_PATH $BUILDNAME)
AZURE_DOCUMENTDB_MASTERKEY="$(AZURE_DOCUMENTDB_MASTERKEY)" \
AZURE_STORAGE_ACCESS_KEY_2="$(AZURE_STORAGE_ACCESS_KEY_2)" \
MOONCAKE_STORAGE_ACCESS_KEY="$(MOONCAKE_STORAGE_ACCESS_KEY)" \
node build/azure-pipelines/common/publish.js "$VSCODE_QUALITY" "$PLATFORM_LINUX" archive-unsigned "$TARBALL_FILENAME" "$VERSION" true "$TARBALL_PATH"
# Publish hockeyapp symbols
node build/azure-pipelines/common/symbols.js "$(VSCODE_MIXIN_PASSWORD)" "$(VSCODE_HOCKEYAPP_TOKEN)" "$(VSCODE_ARCH)" "$(VSCODE_HOCKEYAPP_ID_LINUX64)"
# Publish DEB
npm run gulp -- "vscode-linux-$(VSCODE_ARCH)-build-deb"
PLATFORM_DEB="linux-deb-$ARCH"
[[ "$ARCH" == "ia32" ]] && DEB_ARCH="i386" || DEB_ARCH="amd64"
DEB_FILENAME="$(ls $REPO/.build/linux/deb/$DEB_ARCH/deb/)"
DEB_PATH="$REPO/.build/linux/deb/$DEB_ARCH/deb/$DEB_FILENAME"
AZURE_DOCUMENTDB_MASTERKEY="$(AZURE_DOCUMENTDB_MASTERKEY)" \
AZURE_STORAGE_ACCESS_KEY_2="$(AZURE_STORAGE_ACCESS_KEY_2)" \
MOONCAKE_STORAGE_ACCESS_KEY="$(MOONCAKE_STORAGE_ACCESS_KEY)" \
node build/azure-pipelines/common/publish.js "$VSCODE_QUALITY" "$PLATFORM_DEB" package "$DEB_FILENAME" "$VERSION" true "$DEB_PATH"
# Publish RPM
npm run gulp -- "vscode-linux-$(VSCODE_ARCH)-build-rpm"
PLATFORM_RPM="linux-rpm-$ARCH"
[[ "$ARCH" == "ia32" ]] && RPM_ARCH="i386" || RPM_ARCH="x86_64"
RPM_FILENAME="$(ls $REPO/.build/linux/rpm/$RPM_ARCH/ | grep .rpm)"
RPM_PATH="$REPO/.build/linux/rpm/$RPM_ARCH/$RPM_FILENAME"
AZURE_DOCUMENTDB_MASTERKEY="$(AZURE_DOCUMENTDB_MASTERKEY)" \
AZURE_STORAGE_ACCESS_KEY_2="$(AZURE_STORAGE_ACCESS_KEY_2)" \
MOONCAKE_STORAGE_ACCESS_KEY="$(MOONCAKE_STORAGE_ACCESS_KEY)" \
node build/azure-pipelines/common/publish.js "$VSCODE_QUALITY" "$PLATFORM_RPM" package "$RPM_FILENAME" "$VERSION" true "$RPM_PATH"
# Publish Snap
npm run gulp -- "vscode-linux-$(VSCODE_ARCH)-prepare-snap"
# Pack snap tarball artifact, in order to preserve file perms
mkdir -p $REPO/.build/linux/snap-tarball
SNAP_TARBALL_PATH="$REPO/.build/linux/snap-tarball/snap-$(VSCODE_ARCH).tar.gz"
rm -rf $SNAP_TARBALL_PATH
(cd .build/linux && tar -czf $SNAP_TARBALL_PATH snap)
VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)" \
VSCODE_HOCKEYAPP_TOKEN="$(VSCODE_HOCKEYAPP_TOKEN)" \
./build/azure-pipelines/linux/publish.sh
displayName: Publish
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
displayName: 'Component Detection'

View File

@@ -0,0 +1,51 @@
#!/usr/bin/env bash
set -e
REPO="$(pwd)"
ROOT="$REPO/.."
# Publish tarball
PLATFORM_LINUX="linux-$VSCODE_ARCH"
[[ "$VSCODE_ARCH" == "ia32" ]] && DEB_ARCH="i386" || DEB_ARCH="amd64"
[[ "$VSCODE_ARCH" == "ia32" ]] && RPM_ARCH="i386" || RPM_ARCH="x86_64"
BUILDNAME="VSCode-$PLATFORM_LINUX"
BUILD="$ROOT/$BUILDNAME"
BUILD_VERSION="$(date +%s)"
[ -z "$VSCODE_QUALITY" ] && TARBALL_FILENAME="code-$BUILD_VERSION.tar.gz" || TARBALL_FILENAME="code-$VSCODE_QUALITY-$BUILD_VERSION.tar.gz"
TARBALL_PATH="$ROOT/$TARBALL_FILENAME"
PACKAGEJSON="$BUILD/resources/app/package.json"
VERSION=$(node -p "require(\"$PACKAGEJSON\").version")
rm -rf $ROOT/code-*.tar.*
(cd $ROOT && tar -czf $TARBALL_PATH $BUILDNAME)
node build/azure-pipelines/common/publish.js "$VSCODE_QUALITY" "$PLATFORM_LINUX" archive-unsigned "$TARBALL_FILENAME" "$VERSION" true "$TARBALL_PATH"
# Publish hockeyapp symbols
node build/azure-pipelines/common/symbols.js "$VSCODE_MIXIN_PASSWORD" "$VSCODE_HOCKEYAPP_TOKEN" "$VSCODE_ARCH" "$VSCODE_HOCKEYAPP_ID_LINUX64"
# Publish DEB
yarn gulp "vscode-linux-$VSCODE_ARCH-build-deb"
PLATFORM_DEB="linux-deb-$VSCODE_ARCH"
[[ "$VSCODE_ARCH" == "ia32" ]] && DEB_ARCH="i386" || DEB_ARCH="amd64"
DEB_FILENAME="$(ls $REPO/.build/linux/deb/$DEB_ARCH/deb/)"
DEB_PATH="$REPO/.build/linux/deb/$DEB_ARCH/deb/$DEB_FILENAME"
node build/azure-pipelines/common/publish.js "$VSCODE_QUALITY" "$PLATFORM_DEB" package "$DEB_FILENAME" "$VERSION" true "$DEB_PATH"
# Publish RPM
yarn gulp "vscode-linux-$VSCODE_ARCH-build-rpm"
PLATFORM_RPM="linux-rpm-$VSCODE_ARCH"
[[ "$VSCODE_ARCH" == "ia32" ]] && RPM_ARCH="i386" || RPM_ARCH="x86_64"
RPM_FILENAME="$(ls $REPO/.build/linux/rpm/$RPM_ARCH/ | grep .rpm)"
RPM_PATH="$REPO/.build/linux/rpm/$RPM_ARCH/$RPM_FILENAME"
node build/azure-pipelines/common/publish.js "$VSCODE_QUALITY" "$PLATFORM_RPM" package "$RPM_FILENAME" "$VERSION" true "$RPM_PATH"
# Publish Snap
yarn gulp "vscode-linux-$VSCODE_ARCH-prepare-snap"
# Pack snap tarball artifact, in order to preserve file perms
mkdir -p $REPO/.build/linux/snap-tarball
SNAP_TARBALL_PATH="$REPO/.build/linux/snap-tarball/snap-$VSCODE_ARCH.tar.gz"
rm -rf $SNAP_TARBALL_PATH
(cd .build/linux && tar -czf $SNAP_TARBALL_PATH snap)

View File

@@ -1,7 +1,7 @@
steps:
- task: NodeTool@0
inputs:
versionSpec: "8.12.0"
versionSpec: "10.15.1"
- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2
inputs:
@@ -16,6 +16,14 @@ steps:
- script: |
set -e
# Get snapcraft version
snapcraft --version
# Make sure we get latest packages
sudo apt-get update
sudo apt-get upgrade -y
# Define variables
REPO="$(pwd)"
ARCH="$(VSCODE_ARCH)"
SNAP_ROOT="$REPO/.build/linux/snap/$ARCH"
@@ -33,10 +41,9 @@ steps:
PACKAGEJSON="$(ls $SNAP_ROOT/code*/usr/share/code*/resources/app/package.json)"
VERSION=$(node -p "require(\"$PACKAGEJSON\").version")
SNAP_PATH="$SNAP_ROOT/$SNAP_FILENAME"
(cd $SNAP_ROOT/code-* && snapcraft snap --output "$SNAP_PATH")
(cd $SNAP_ROOT/code-* && sudo snapcraft snap --output "$SNAP_PATH")
# Publish snap package
AZURE_DOCUMENTDB_MASTERKEY="$(AZURE_DOCUMENTDB_MASTERKEY)" \
AZURE_STORAGE_ACCESS_KEY_2="$(AZURE_STORAGE_ACCESS_KEY_2)" \
MOONCAKE_STORAGE_ACCESS_KEY="$(MOONCAKE_STORAGE_ACCESS_KEY)" \
node build/azure-pipelines/common/publish.js "$VSCODE_QUALITY" "linux-snap-$ARCH" package "$SNAP_FILENAME" "$VERSION" true "$SNAP_PATH"

View File

@@ -62,4 +62,18 @@ jobs:
pool:
vmImage: macOS 10.13
steps:
- template: darwin/product-build-darwin.yml
- template: darwin/product-build-darwin.yml
- job: Mooncake
pool:
vmImage: 'Ubuntu-16.04'
condition: true
dependsOn:
- Windows
- Windows32
- Linux
- LinuxSnap
- Linux32
- macOS
steps:
- template: sync-mooncake.yml

View File

@@ -0,0 +1,18 @@
steps:
- task: NodeTool@0
inputs:
versionSpec: "10.15.1"
- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2
inputs:
versionSpec: "1.10.1"
- script: |
set -e
(cd build ; yarn)
AZURE_DOCUMENTDB_MASTERKEY="$(AZURE_DOCUMENTDB_MASTERKEY)" \
AZURE_STORAGE_ACCESS_KEY_2="$(AZURE_STORAGE_ACCESS_KEY_2)" \
MOONCAKE_STORAGE_ACCESS_KEY="$(MOONCAKE_STORAGE_ACCESS_KEY)" \
node build/azure-pipelines/common/sync-mooncake.js "$VSCODE_QUALITY"

View File

@@ -0,0 +1,4 @@
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
exec { yarn gulp "vscode-win32-$env:VSCODE_ARCH-min" }
exec { yarn gulp "vscode-win32-$env:VSCODE_ARCH-inno-updater" }

View File

@@ -1,7 +1,7 @@
steps:
- task: NodeTool@0
inputs:
versionSpec: "8.12.0"
versionSpec: "10.15.1"
- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2
inputs:
versionSpec: "1.10.1"
@@ -9,9 +9,22 @@ steps:
inputs:
versionSpec: '2.x'
addToPath: true
# - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1
# inputs:
# keyfile: '**/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock'
# targetfolder: '**/node_modules, !**/node_modules/**/node_modules'
# vstsFeed: '$(ArtifactFeed)'
# condition: eq(variables['System.PullRequest.PullRequestId'], '')
- powershell: |
yarn
displayName: Install Dependencies
# condition: or(ne(variables['System.PullRequest.PullRequestId'], ''), ne(variables['CacheRestored'], 'true'))
# - task: 1ESLighthouseEng.PipelineArtifactCaching.SaveCacheV1.SaveCache@1
# inputs:
# keyfile: '**/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock'
# targetfolder: '**/node_modules, !**/node_modules/**/node_modules'
# vstsFeed: '$(ArtifactFeed)'
# condition: and(succeeded(), eq(variables['System.PullRequest.PullRequestId'], ''), ne(variables['CacheRestored'], 'true'))
- powershell: |
yarn gulp electron
displayName: Download Electron
@@ -21,9 +34,6 @@ steps:
- powershell: |
yarn monaco-compile-check
displayName: Run Monaco Editor Checks
- script: |
yarn strict-null-check
displayName: Run Strict Null Checks
- powershell: |
yarn compile
displayName: Compile Sources

View File

@@ -1,7 +1,7 @@
steps:
- task: NodeTool@0
inputs:
versionSpec: "8.12.0"
versionSpec: "10.15.1"
- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2
inputs:
@@ -15,38 +15,50 @@ steps:
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
"machine monacotools.visualstudio.com password $(VSO_PAT)" | Out-File "$env:USERPROFILE\_netrc" -Encoding ASCII
"machine monacotools.visualstudio.com`npassword $(VSO_PAT)`nmachine github.com`nlogin vscode`npassword $(VSCODE_MIXIN_PASSWORD)" | Out-File "$env:USERPROFILE\_netrc" -Encoding ASCII
$env:npm_config_arch="$(VSCODE_ARCH)"
$env:CHILD_CONCURRENCY="1"
$env:VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)"
exec { git config user.email "vscode@microsoft.com" }
exec { git config user.name "VSCode" }
exec { git remote add distro "https://github.com/$(VSCODE_MIXIN_REPO).git" }
exec { git fetch distro }
exec { git merge $(node -p "require('./package.json').distro") }
exec { yarn }
exec { npm run gulp -- hygiene }
exec { npm run monaco-compile-check }
exec { npm run strict-null-check }
exec { npm run gulp -- mixin }
exec { yarn gulp mixin }
exec { yarn gulp hygiene }
exec { yarn monaco-compile-check }
exec { node build/azure-pipelines/common/installDistro.js }
exec { node build/lib/builtInExtensions.js }
displayName: Prepare build
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
$env:VSCODE_MIXIN_PASSWORD="$(VSCODE_MIXIN_PASSWORD)"
exec { npm run gulp -- "vscode-win32-$(VSCODE_ARCH)-min" }
exec { npm run gulp -- "vscode-win32-$(VSCODE_ARCH)-inno-updater" }
name: build
.\build\azure-pipelines\win32\build.ps1
displayName: Build
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
exec { npm run gulp -- "electron-$(VSCODE_ARCH)" }
exec { yarn gulp "electron-$(VSCODE_ARCH)" }
exec { .\scripts\test.bat --build --tfs "Unit Tests" }
# yarn smoketest -- --build "$(agent.builddirectory)\VSCode-win32-$(VSCODE_ARCH)"
name: test
displayName: Run unit tests
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
exec { yarn gulp "electron-$(VSCODE_ARCH)" }
exec { .\scripts\test-integration.bat --build --tfs "Integration Tests" }
displayName: Run integration tests
- task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
inputs:
ConnectedServiceName: 'ESRP CodeSign'
FolderPath: '$(agent.builddirectory)/VSCode-win32-$(VSCODE_ARCH)'
FolderPath: '$(agent.builddirectory)/VSCode-win32-$(VSCODE_ARCH),$(agent.builddirectory)/vscode-reh-win32-$(VSCODE_ARCH)'
Pattern: '*.dll,*.exe,*.node'
signConfigType: inlineSignParams
inlineOperation: |
@@ -120,32 +132,11 @@ steps:
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
exec { npm run gulp -- "vscode-win32-$(VSCODE_ARCH)-archive" "vscode-win32-$(VSCODE_ARCH)-system-setup" "vscode-win32-$(VSCODE_ARCH)-user-setup" --sign }
$Repo = "$(pwd)"
$Root = "$Repo\.."
$SystemExe = "$Repo\.build\win32-$(VSCODE_ARCH)\system-setup\VSCodeSetup.exe"
$UserExe = "$Repo\.build\win32-$(VSCODE_ARCH)\user-setup\VSCodeSetup.exe"
$Zip = "$Repo\.build\win32-$(VSCODE_ARCH)\archive\VSCode-win32-$(VSCODE_ARCH).zip"
$Build = "$Root\VSCode-win32-$(VSCODE_ARCH)"
# get version
$PackageJson = Get-Content -Raw -Path "$Build\resources\app\package.json" | ConvertFrom-Json
$Version = $PackageJson.version
$Quality = "$env:VSCODE_QUALITY"
$env:AZURE_STORAGE_ACCESS_KEY_2 = "$(AZURE_STORAGE_ACCESS_KEY_2)"
$env:MOONCAKE_STORAGE_ACCESS_KEY = "$(MOONCAKE_STORAGE_ACCESS_KEY)"
$env:AZURE_DOCUMENTDB_MASTERKEY = "$(AZURE_DOCUMENTDB_MASTERKEY)"
$assetPlatform = if ("$(VSCODE_ARCH)" -eq "ia32") { "win32" } else { "win32-x64" }
exec { node build/azure-pipelines/common/publish.js $Quality "$global:assetPlatform-archive" archive "VSCode-win32-$(VSCODE_ARCH)-$Version.zip" $Version true $Zip }
exec { node build/azure-pipelines/common/publish.js $Quality "$global:assetPlatform" setup "VSCodeSetup-$(VSCODE_ARCH)-$Version.exe" $Version true $SystemExe }
exec { node build/azure-pipelines/common/publish.js $Quality "$global:assetPlatform-user" setup "VSCodeUserSetup-$(VSCODE_ARCH)-$Version.exe" $Version true $UserExe }
# publish hockeyapp symbols
$hockeyAppId = if ("$(VSCODE_ARCH)" -eq "ia32") { "$(VSCODE_HOCKEYAPP_ID_WIN32)" } else { "$(VSCODE_HOCKEYAPP_ID_WIN64)" }
exec { node build/azure-pipelines/common/symbols.js "$(VSCODE_MIXIN_PASSWORD)" "$(VSCODE_HOCKEYAPP_TOKEN)" "$(VSCODE_ARCH)" $hockeyAppId }
$env:VSCODE_HOCKEYAPP_TOKEN = "$(VSCODE_HOCKEYAPP_TOKEN)"
.\build\azure-pipelines\win32\publish.ps1
displayName: Publish
- task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
displayName: 'Component Detection'

View File

@@ -0,0 +1,28 @@
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
$Arch = "$env:VSCODE_ARCH"
exec { yarn gulp "vscode-win32-$Arch-archive" "vscode-win32-$Arch-system-setup" "vscode-win32-$Arch-user-setup" --sign }
$Repo = "$(pwd)"
$Root = "$Repo\.."
$SystemExe = "$Repo\.build\win32-$Arch\system-setup\VSCodeSetup.exe"
$UserExe = "$Repo\.build\win32-$Arch\user-setup\VSCodeSetup.exe"
$Zip = "$Repo\.build\win32-$Arch\archive\VSCode-win32-$Arch.zip"
$Build = "$Root\VSCode-win32-$Arch"
# get version
$PackageJson = Get-Content -Raw -Path "$Build\resources\app\package.json" | ConvertFrom-Json
$Version = $PackageJson.version
$Quality = "$env:VSCODE_QUALITY"
$AssetPlatform = if ("$Arch" -eq "ia32") { "win32" } else { "win32-x64" }
exec { node build/azure-pipelines/common/publish.js $Quality "$AssetPlatform-archive" archive "VSCode-win32-$Arch-$Version.zip" $Version true $Zip }
exec { node build/azure-pipelines/common/publish.js $Quality "$AssetPlatform" setup "VSCodeSetup-$Arch-$Version.exe" $Version true $SystemExe }
exec { node build/azure-pipelines/common/publish.js $Quality "$AssetPlatform-user" setup "VSCodeUserSetup-$Arch-$Version.exe" $Version true $UserExe }
# publish hockeyapp symbols
$hockeyAppId = if ("$Arch" -eq "ia32") { "$env:VSCODE_HOCKEYAPP_ID_WIN32" } else { "$env:VSCODE_HOCKEYAPP_ID_WIN64" }
exec { node build/azure-pipelines/common/symbols.js "$env:VSCODE_MIXIN_PASSWORD" "$env:VSCODE_HOCKEYAPP_TOKEN" "$Arch" $hockeyAppId }

View File

@@ -0,0 +1,91 @@
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
const https = require("https");
const fs = require("fs");
const path = require("path");
const cp = require("child_process");
function ensureDir(filepath) {
if (!fs.existsSync(filepath)) {
ensureDir(path.dirname(filepath));
fs.mkdirSync(filepath);
}
}
function download(options, destination) {
ensureDir(path.dirname(destination));
return new Promise((c, e) => {
const fd = fs.openSync(destination, 'w');
const req = https.get(options, (res) => {
res.on('data', (chunk) => {
fs.writeSync(fd, chunk);
});
res.on('end', () => {
fs.closeSync(fd);
c();
});
});
req.on('error', (reqErr) => {
console.error(`request to ${options.host}${options.path} failed.`);
console.error(reqErr);
e(reqErr);
});
});
}
const MARKER_ARGUMENT = `_download_fork_`;
function base64encode(str) {
return Buffer.from(str, 'utf8').toString('base64');
}
function base64decode(str) {
return Buffer.from(str, 'base64').toString('utf8');
}
function downloadInExternalProcess(options) {
const url = `https://${options.requestOptions.host}${options.requestOptions.path}`;
console.log(`Downloading ${url}...`);
return new Promise((c, e) => {
const child = cp.fork(__filename, [MARKER_ARGUMENT, base64encode(JSON.stringify(options))], {
stdio: ['pipe', 'pipe', 'pipe', 'ipc']
});
let stderr = [];
child.stderr.on('data', (chunk) => {
stderr.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk);
});
child.on('exit', (code) => {
if (code === 0) {
// normal termination
console.log(`Finished downloading ${url}.`);
c();
}
else {
// abnormal termination
console.error(Buffer.concat(stderr).toString());
e(new Error(`Download of ${url} failed.`));
}
});
});
}
exports.downloadInExternalProcess = downloadInExternalProcess;
function _downloadInExternalProcess() {
let options;
try {
options = JSON.parse(base64decode(process.argv[3]));
}
catch (err) {
console.error(`Cannot read arguments`);
console.error(err);
process.exit(-1);
return;
}
download(options.requestOptions, options.destinationPath).then(() => {
process.exit(0);
}, (err) => {
console.error(err);
process.exit(-2);
});
}
if (process.argv.length >= 4 && process.argv[2] === MARKER_ARGUMENT) {
// running as forked download script
_downloadInExternalProcess();
}

111
build/download/download.ts Normal file
View File

@@ -0,0 +1,111 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as https from 'https';
import * as fs from 'fs';
import * as path from 'path';
import * as cp from 'child_process';
function ensureDir(filepath: string) {
if (!fs.existsSync(filepath)) {
ensureDir(path.dirname(filepath));
fs.mkdirSync(filepath);
}
}
function download(options: https.RequestOptions, destination: string): Promise<void> {
ensureDir(path.dirname(destination));
return new Promise<void>((c, e) => {
const fd = fs.openSync(destination, 'w');
const req = https.get(options, (res) => {
res.on('data', (chunk) => {
fs.writeSync(fd, chunk);
});
res.on('end', () => {
fs.closeSync(fd);
c();
});
});
req.on('error', (reqErr) => {
console.error(`request to ${options.host}${options.path} failed.`);
console.error(reqErr);
e(reqErr);
});
});
}
const MARKER_ARGUMENT = `_download_fork_`;
function base64encode(str: string): string {
return Buffer.from(str, 'utf8').toString('base64');
}
function base64decode(str: string): string {
return Buffer.from(str, 'base64').toString('utf8');
}
export interface IDownloadRequestOptions {
host: string;
path: string;
}
export interface IDownloadOptions {
requestOptions: IDownloadRequestOptions;
destinationPath: string;
}
export function downloadInExternalProcess(options: IDownloadOptions): Promise<void> {
const url = `https://${options.requestOptions.host}${options.requestOptions.path}`;
console.log(`Downloading ${url}...`);
return new Promise<void>((c, e) => {
const child = cp.fork(
__filename,
[MARKER_ARGUMENT, base64encode(JSON.stringify(options))],
{
stdio: ['pipe', 'pipe', 'pipe', 'ipc']
}
);
let stderr: Buffer[] = [];
child.stderr.on('data', (chunk) => {
stderr.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk);
});
child.on('exit', (code) => {
if (code === 0) {
// normal termination
console.log(`Finished downloading ${url}.`);
c();
} else {
// abnormal termination
console.error(Buffer.concat(stderr).toString());
e(new Error(`Download of ${url} failed.`));
}
});
});
}
function _downloadInExternalProcess() {
let options: IDownloadOptions;
try {
options = JSON.parse(base64decode(process.argv[3]));
} catch (err) {
console.error(`Cannot read arguments`);
console.error(err);
process.exit(-1);
return;
}
download(options.requestOptions, options.destinationPath).then(() => {
process.exit(0);
}, (err) => {
console.error(err);
process.exit(-2);
});
}
if (process.argv.length >= 4 && process.argv[2] === MARKER_ARGUMENT) {
// running as forked download script
_downloadInExternalProcess();
}

18
build/gulpfile.compile.js Normal file
View File

@@ -0,0 +1,18 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
const util = require('./lib/util');
const task = require('./lib/task');
const compilation = require('./lib/compilation');
const { compileExtensionsBuildTask } = require('./gulpfile.extensions');
// Full compile, including nls and inline sources in sourcemaps, for build
const compileClientBuildTask = task.define('compile-client-build', task.series(util.rimraf('out-build'), compilation.compileTask('src', 'out-build', true)));
// All Build
const compileBuildTask = task.define('compile-build', task.parallel(compileClientBuildTask, compileExtensionsBuildTask));
exports.compileBuildTask = compileBuildTask;

View File

@@ -6,6 +6,7 @@
const gulp = require('gulp');
const path = require('path');
const util = require('./lib/util');
const task = require('./lib/task');
const common = require('./lib/optimize');
const es = require('event-stream');
const File = require('vinyl');
@@ -48,9 +49,6 @@ var editorResources = [
'!**/test/**'
];
var editorOtherSources = [
];
var BUNDLED_FILE_HEADER = [
'/*!-----------------------------------------------------------',
' * Copyright (c) Microsoft Corporation. All rights reserved.',
@@ -63,8 +61,7 @@ var BUNDLED_FILE_HEADER = [
const languages = i18n.defaultLanguages.concat([]); // i18n.defaultLanguages.concat(process.env.VSCODE_QUALITY !== 'stable' ? i18n.extraLanguages : []);
gulp.task('clean-editor-src', util.rimraf('out-editor-src'));
gulp.task('extract-editor-src', ['clean-editor-src'], function () {
const extractEditorSrcTask = task.define('extract-editor-src', () => {
console.log(`If the build fails, consider tweaking shakeLevel below to a lower value.`);
const apiusages = monacoapi.execute().usageContent;
const extrausages = fs.readFileSync(path.join(root, 'build', 'monaco', 'monaco.usage.recipe')).toString();
@@ -84,6 +81,7 @@ gulp.task('extract-editor-src', ['clean-editor-src'], function () {
'typings/thenable.d.ts',
'typings/es6-promise.d.ts',
'typings/require-monaco.d.ts',
"typings/lib.es2018.promise.d.ts",
'vs/monaco.d.ts'
],
libs: [
@@ -100,15 +98,11 @@ gulp.task('extract-editor-src', ['clean-editor-src'], function () {
});
});
// Full compile, including nls and inline sources in sourcemaps, for build
gulp.task('clean-editor-build', util.rimraf('out-editor-build'));
gulp.task('compile-editor-build', ['clean-editor-build', 'extract-editor-src'], compilation.compileTask('out-editor-src', 'out-editor-build', true));
const compileEditorAMDTask = task.define('compile-editor-amd', compilation.compileTask('out-editor-src', 'out-editor-build', true));
gulp.task('clean-optimized-editor', util.rimraf('out-editor'));
gulp.task('optimize-editor', ['clean-optimized-editor', 'compile-editor-build'], common.optimizeTask({
const optimizeEditorAMDTask = task.define('optimize-editor-amd', common.optimizeTask({
src: 'out-editor-build',
entryPoints: editorEntryPoints,
otherSources: editorOtherSources,
resources: editorResources,
loaderConfig: {
paths: {
@@ -125,11 +119,9 @@ gulp.task('optimize-editor', ['clean-optimized-editor', 'compile-editor-build'],
languages: languages
}));
gulp.task('clean-minified-editor', util.rimraf('out-editor-min'));
gulp.task('minify-editor', ['clean-minified-editor', 'optimize-editor'], common.minifyTask('out-editor'));
const minifyEditorAMDTask = task.define('minify-editor-amd', common.minifyTask('out-editor'));
gulp.task('clean-editor-esm', util.rimraf('out-editor-esm'));
gulp.task('extract-editor-esm', ['clean-editor-esm', 'clean-editor-distro', 'extract-editor-src'], function () {
const createESMSourcesAndResourcesTask = task.define('extract-editor-esm', () => {
standalone.createESMSourcesAndResources2({
srcFolder: './out-editor-src',
outFolder: './out-editor-esm',
@@ -151,7 +143,8 @@ gulp.task('extract-editor-esm', ['clean-editor-esm', 'clean-editor-distro', 'ext
}
});
});
gulp.task('compile-editor-esm', ['extract-editor-esm', 'clean-editor-distro'], function () {
const compileEditorESMTask = task.define('compile-editor-esm', () => {
if (process.platform === 'win32') {
const result = cp.spawnSync(`..\\node_modules\\.bin\\tsc.cmd`, {
cwd: path.join(__dirname, '../out-editor-esm')
@@ -202,8 +195,16 @@ function toExternalDTS(contents) {
return lines.join('\n');
}
gulp.task('clean-editor-distro', util.rimraf('out-monaco-editor-core'));
gulp.task('editor-distro', ['clean-editor-distro', 'compile-editor-esm', 'minify-editor', 'optimize-editor'], function () {
function filterStream(testFunc) {
return es.through(function (data) {
if (!testFunc(data.relative)) {
return;
}
this.emit('data', data);
});
}
const finalEditorResourcesTask = task.define('final-editor-resources', () => {
return es.merge(
// other assets
es.merge(
@@ -233,6 +234,14 @@ gulp.task('editor-distro', ['clean-editor-distro', 'compile-editor-esm', 'minify
}))
.pipe(gulp.dest('out-monaco-editor-core')),
// version.txt
gulp.src('build/monaco/version.txt')
.pipe(es.through(function (data) {
data.contents = Buffer.from(`monaco-editor-core: https://github.com/Microsoft/vscode/tree/${sha1}`);
this.emit('data', data);
}))
.pipe(gulp.dest('out-monaco-editor-core')),
// README.md
gulp.src('build/monaco/README-npm.md')
.pipe(es.through(function (data) {
@@ -266,7 +275,7 @@ gulp.task('editor-distro', ['clean-editor-distro', 'compile-editor-esm', 'minify
var strContents = data.contents.toString();
var newStr = '//# sourceMappingURL=' + relativePathToMap.replace(/\\/g, '/');
strContents = strContents.replace(/\/\/\# sourceMappingURL=[^ ]+$/, newStr);
strContents = strContents.replace(/\/\/# sourceMappingURL=[^ ]+$/, newStr);
data.contents = Buffer.from(strContents);
this.emit('data', data);
@@ -282,59 +291,31 @@ gulp.task('editor-distro', ['clean-editor-distro', 'compile-editor-esm', 'minify
);
});
gulp.task('analyze-editor-distro', function () {
// @ts-ignore
var bundleInfo = require('../out-editor/bundleInfo.json');
var graph = bundleInfo.graph;
var bundles = bundleInfo.bundles;
var inverseGraph = {};
Object.keys(graph).forEach(function (module) {
var dependencies = graph[module];
dependencies.forEach(function (dep) {
inverseGraph[dep] = inverseGraph[dep] || [];
inverseGraph[dep].push(module);
});
});
var detailed = {};
Object.keys(bundles).forEach(function (entryPoint) {
var included = bundles[entryPoint];
var includedMap = {};
included.forEach(function (included) {
includedMap[included] = true;
});
var explanation = [];
included.map(function (included) {
if (included.indexOf('!') >= 0) {
return;
}
var reason = (inverseGraph[included] || []).filter(function (mod) {
return !!includedMap[mod];
});
explanation.push({
module: included,
reason: reason
});
});
detailed[entryPoint] = explanation;
});
console.log(JSON.stringify(detailed, null, '\t'));
});
function filterStream(testFunc) {
return es.through(function (data) {
if (!testFunc(data.relative)) {
return;
}
this.emit('data', data);
});
}
gulp.task('editor-distro',
task.series(
task.parallel(
util.rimraf('out-editor-src'),
util.rimraf('out-editor-build'),
util.rimraf('out-editor-esm'),
util.rimraf('out-monaco-editor-core'),
util.rimraf('out-editor'),
util.rimraf('out-editor-min')
),
extractEditorSrcTask,
task.parallel(
task.series(
compileEditorAMDTask,
optimizeEditorAMDTask,
minifyEditorAMDTask
),
task.series(
createESMSourcesAndResourcesTask,
compileEditorESMTask
)
),
finalEditorResourcesTask
)
);
//#region monaco type checking
@@ -354,6 +335,7 @@ function createTscCompileTask(watch) {
let errors = [];
let reporter = createReporter();
let report;
// eslint-disable-next-line no-control-regex
let magic = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g; // https://stackoverflow.com/questions/25245716/remove-all-ansi-colors-styles-from-strings
child.stdout.on('data', data => {
@@ -387,7 +369,10 @@ function createTscCompileTask(watch) {
};
}
gulp.task('monaco-typecheck-watch', createTscCompileTask(true));
gulp.task('monaco-typecheck', createTscCompileTask(false));
const monacoTypecheckWatchTask = task.define('monaco-typecheck-watch', createTscCompileTask(true));
exports.monacoTypecheckWatchTask = monacoTypecheckWatchTask;
const monacoTypecheckTask = task.define('monaco-typecheck', createTscCompileTask(false));
exports.monacoTypecheckTask = monacoTypecheckTask;
//#endregion

View File

@@ -11,8 +11,8 @@ const path = require('path');
const tsb = require('gulp-tsb');
const es = require('event-stream');
const filter = require('gulp-filter');
const rimraf = require('rimraf');
const util = require('./lib/util');
const task = require('./lib/task');
const watcher = require('./lib/watch');
const createReporter = require('./lib/reporter').createReporter;
const glob = require('glob');
@@ -43,16 +43,6 @@ const tasks = compilations.map(function (tsconfigFile) {
const name = relativeDirname.replace(/\//g, '-');
// Tasks
const clean = 'clean-extension:' + name;
const compile = 'compile-extension:' + name;
const watch = 'watch-extension:' + name;
// Build Tasks
const cleanBuild = 'clean-extension-build:' + name;
const compileBuild = 'compile-extension-build:' + name;
const watchBuild = 'watch-extension-build:' + name;
const root = path.join('extensions', relativeDirname);
const srcBase = path.join(root, 'src');
const src = path.join(srcBase, '**');
@@ -111,18 +101,18 @@ const tasks = compilations.map(function (tsconfigFile) {
const srcOpts = { cwd: path.dirname(__dirname), base: srcBase };
gulp.task(clean, cb => rimraf(out, cb));
const cleanTask = task.define(`clean-extension-${name}`, util.rimraf(out));
gulp.task(compile, [clean], () => {
const compileTask = task.define(`compile-extension:${name}`, task.series(cleanTask, () => {
const pipeline = createPipeline(false, true);
const input = gulp.src(src, srcOpts);
return input
.pipe(pipeline())
.pipe(gulp.dest(out));
});
}));
gulp.task(watch, [clean], () => {
const watchTask = task.define(`watch-extension:${name}`, task.series(cleanTask, () => {
const pipeline = createPipeline(false);
const input = gulp.src(src, srcOpts);
const watchInput = watcher(src, srcOpts);
@@ -130,43 +120,35 @@ const tasks = compilations.map(function (tsconfigFile) {
return watchInput
.pipe(util.incremental(pipeline, input))
.pipe(gulp.dest(out));
});
}));
gulp.task(cleanBuild, cb => rimraf(out, cb));
gulp.task(compileBuild, [clean], () => {
const compileBuildTask = task.define(`compile-build-extension-${name}`, task.series(cleanTask, () => {
const pipeline = createPipeline(true, true);
const input = gulp.src(src, srcOpts);
return input
.pipe(pipeline())
.pipe(gulp.dest(out));
});
}));
gulp.task(watchBuild, [clean], () => {
const pipeline = createPipeline(true);
const input = gulp.src(src, srcOpts);
const watchInput = watcher(src, srcOpts);
return watchInput
.pipe(util.incremental(() => pipeline(), input))
.pipe(gulp.dest(out));
});
// Tasks
gulp.task(compileTask);
gulp.task(watchTask);
return {
clean: clean,
compile: compile,
watch: watch,
cleanBuild: cleanBuild,
compileBuild: compileBuild,
watchBuild: watchBuild
compileTask: compileTask,
watchTask: watchTask,
compileBuildTask: compileBuildTask
};
});
gulp.task('clean-extensions', tasks.map(t => t.clean));
gulp.task('compile-extensions', tasks.map(t => t.compile));
gulp.task('watch-extensions', tasks.map(t => t.watch));
const compileExtensionsTask = task.define('compile-extensions', task.parallel(...tasks.map(t => t.compileTask)));
gulp.task(compileExtensionsTask);
exports.compileExtensionsTask = compileExtensionsTask;
gulp.task('clean-extensions-build', tasks.map(t => t.cleanBuild));
gulp.task('compile-extensions-build', tasks.map(t => t.compileBuild));
gulp.task('watch-extensions-build', tasks.map(t => t.watchBuild));
const watchExtensionsTask = task.define('watch-extensions', task.parallel(...tasks.map(t => t.watchTask)));
gulp.task(watchExtensionsTask);
exports.watchExtensionsTask = watchExtensionsTask;
const compileExtensionsBuildTask = task.define('compile-extensions-build', task.parallel(...tasks.map(t => t.compileBuildTask)));
exports.compileExtensionsBuildTask = compileExtensionsBuildTask;

View File

@@ -42,7 +42,8 @@ const indentationFilter = [
// except specific files
'!ThirdPartyNotices.txt',
'!LICENSE.txt',
'!LICENSE.{txt,rtf}',
'!LICENSES.chromium.html',
'!**/LICENSE',
'!src/vs/nls.js',
'!src/vs/nls.build.js',
@@ -81,14 +82,21 @@ const indentationFilter = [
'!src/typings/**/*.d.ts',
'!extensions/**/*.d.ts',
'!**/*.{svg,exe,png,bmp,scpt,bat,cmd,cur,ttf,woff,eot,md,ps1,template,yaml,yml,d.ts.recipe,ico,icns}',
'!build/{lib,tslintRules}/**/*.js',
'!build/{lib,tslintRules,download}/**/*.js',
'!build/**/*.sh',
'!build/azure-pipelines/**/*.js',
'!build/azure-pipelines/**/*.config',
'!**/Dockerfile',
'!**/Dockerfile.*',
'!**/*.Dockerfile',
'!**/*.dockerfile',
'!extensions/markdown-language-features/media/*.js'
'!extensions/markdown-language-features/media/*.js',
// {{SQL CARBON EDIT}}
'!**/*.xlf',
'!**/*.docx',
'!**/*.sql',
'!extensions/mssql/sqltoolsservice/**',
'!extensions/import/flatfileimportservice/**',
];
const copyrightFilter = [
@@ -117,7 +125,37 @@ const copyrightFilter = [
'!resources/completions/**',
'!extensions/markdown-language-features/media/highlight.css',
'!extensions/html-language-features/server/src/modes/typescript/*',
'!extensions/*/server/bin/*'
'!extensions/*/server/bin/*',
// {{SQL CARBON EDIT}}
'!extensions/notebook/src/intellisense/text.ts',
'!extensions/mssql/src/objectExplorerNodeProvider/webhdfs.ts',
'!src/sql/workbench/parts/notebook/outputs/tableRenderers.ts',
'!src/sql/workbench/parts/notebook/outputs/common/url.ts',
'!src/sql/workbench/parts/notebook/outputs/common/renderMimeInterfaces.ts',
'!src/sql/workbench/parts/notebook/outputs/common/outputProcessor.ts',
'!src/sql/workbench/parts/notebook/outputs/common/mimemodel.ts',
'!src/sql/workbench/parts/notebook/cellViews/media/*.css',
'!src/sql/base/browser/ui/table/plugins/rowSelectionModel.plugin.ts',
'!src/sql/base/browser/ui/table/plugins/rowDetailView.ts',
'!src/sql/base/browser/ui/table/plugins/headerFilter.plugin.ts',
'!src/sql/base/browser/ui/table/plugins/checkboxSelectColumn.plugin.ts',
'!src/sql/base/browser/ui/table/plugins/cellSelectionModel.plugin.ts',
'!src/sql/base/browser/ui/table/plugins/autoSizeColumns.plugin.ts',
'!src/sql/workbench/parts/notebook/outputs/sanitizer.ts',
'!src/sql/workbench/parts/notebook/outputs/renderers.ts',
'!src/sql/workbench/parts/notebook/outputs/registry.ts',
'!src/sql/workbench/parts/notebook/outputs/factories.ts',
'!src/sql/workbench/parts/notebook/models/nbformat.ts',
'!extensions/markdown-language-features/media/tomorrow.css',
'!src/sql/workbench/electron-browser/modelComponents/media/highlight.css',
'!src/sql/parts/modelComponents/highlight.css',
'!extensions/mssql/sqltoolsservice/**',
'!extensions/import/flatfileimportservice/**',
'!extensions/notebook/src/prompts/**',
'!extensions/mssql/src/prompts/**',
'!extensions/notebook/resources/jupyter_config/**',
'!**/*.gif',
'!**/*.xlf'
];
const eslintFilter = [
@@ -163,8 +201,7 @@ gulp.task('eslint', () => {
});
gulp.task('tslint', () => {
// {{SQL CARBON EDIT}}
const options = { emitError: false };
const options = { emitError: true };
return vfs.src(all, { base: '.', follow: true, allowEmpty: true })
.pipe(filter(tslintFilter))
@@ -230,7 +267,7 @@ function hygiene(some) {
let formatted = result.dest.replace(/\r\n/gm, '\n');
if (original !== formatted) {
console.error('File not formatted:', file.relative);
console.error("File not formatted. Run the 'Format Document' command to fix it:", file.relative);
errorCount++;
}
cb(null, file);
@@ -262,9 +299,8 @@ function hygiene(some) {
.pipe(filter(f => !f.stat.isDirectory()))
.pipe(filter(indentationFilter))
.pipe(indentation)
.pipe(filter(copyrightFilter));
// {{SQL CARBON EDIT}}
// .pipe(copyrights);
.pipe(filter(copyrightFilter))
.pipe(copyrights);
const typescript = result
.pipe(filter(tslintFilter))
@@ -274,15 +310,38 @@ function hygiene(some) {
const javascript = result
.pipe(filter(eslintFilter))
.pipe(gulpeslint('src/.eslintrc'))
.pipe(gulpeslint.formatEach('compact'));
// {{SQL CARBON EDIT}}
// .pipe(gulpeslint.failAfterError());
.pipe(gulpeslint.formatEach('compact'))
.pipe(gulpeslint.failAfterError());
let count = 0;
return es.merge(typescript, javascript)
.pipe(es.through(function (data) {
// {{SQL CARBON EDIT}}
this.emit('end');
count++;
if (process.env['TRAVIS'] && count % 10 === 0) {
process.stdout.write('.');
}
this.emit('data', data);
}, function () {
process.stdout.write('\n');
const tslintResult = tsLinter.getResult();
if (tslintResult.failures.length > 0) {
for (const failure of tslintResult.failures) {
const name = failure.getFileName();
const position = failure.getStartPosition();
const line = position.getLineAndCharacter().line;
const character = position.getLineAndCharacter().character;
console.error(`${name}:${line + 1}:${character + 1}:${failure.getFailure()}`);
}
errorCount += tslintResult.failures.length;
}
if (errorCount > 0) {
this.emit('error', 'Hygiene failed with ' + errorCount + ' errors. Check \'build/gulpfile.hygiene.js\'.');
} else {
this.emit('end');
}
}));
}

View File

@@ -6,21 +6,12 @@
'use strict';
const gulp = require('gulp');
const json = require('gulp-json-editor');
const buffer = require('gulp-buffer');
const filter = require('gulp-filter');
const es = require('event-stream');
const util = require('./lib/util');
const remote = require('gulp-remote-src');
const zip = require('gulp-vinyl-zip');
// {{SQL CARBON EDIT}}
const jeditor = require('gulp-json-editor');
const pkg = require('../package.json');
gulp.task('mixin', function () {
// {{SQL CARBON EDIT}}
// {{SQL CARBON EDIT}}
const updateUrl = process.env['SQLOPS_UPDATEURL'];
if (!updateUrl) {
console.log('Missing SQLOPS_UPDATEURL, skipping mixin');

View File

@@ -28,7 +28,6 @@ const formatFiles = (some) => {
console.info('ran formatting on file ' + file.path + ' result: ' + result.message);
if (result.error) {
console.error(result.message);
errorCount++;
}
cb(null, file);
@@ -40,7 +39,7 @@ const formatFiles = (some) => {
.pipe(filter(f => !f.stat.isDirectory()))
.pipe(formatting);
}
};
const formatStagedFiles = () => {
const cp = require('child_process');
@@ -81,4 +80,4 @@ const formatStagedFiles = () => {
process.exit(1);
});
});
}
};

View File

@@ -20,6 +20,7 @@ const filter = require('gulp-filter');
const json = require('gulp-json-editor');
const _ = require('underscore');
const util = require('./lib/util');
const task = require('./lib/task');
const ext = require('./lib/extensions');
const buildfile = require('../src/buildfile');
const common = require('./lib/optimize');
@@ -32,12 +33,11 @@ const i18n = require('./lib/i18n');
// {{SQL CARBON EDIT}}
const serviceDownloader = require('service-downloader').ServiceDownloadProvider;
const platformInfo = require('service-downloader/out/platform').PlatformInformation;
const glob = require('glob');
// {{SQL CARBON EDIT}} - End
const deps = require('./dependencies');
const getElectronVersion = require('./lib/electron').getElectronVersion;
const createAsar = require('./lib/asar').createAsar;
const minimist = require('minimist');
const { compileBuildTask } = require('./gulpfile.compile');
const productionDependencies = deps.getProductionDependencies(path.dirname(__dirname));
// @ts-ignore
@@ -52,7 +52,7 @@ const nodeModules = [
'rxjs/Observable',
'rxjs/Subject',
'rxjs/Observer',
'ng2-charts/ng2-charts']
'ng2-charts']
.concat(Object.keys(product.dependencies || {}))
.concat(_.uniq(productionDependencies.map(d => d.name)))
.concat(baseModules);
@@ -75,16 +75,19 @@ const vscodeResources = [
'out-build/bootstrap-window.js',
'out-build/paths.js',
'out-build/vs/**/*.{svg,png,cur,html}',
'!out-build/vs/code/browser/**/*.html',
'out-build/vs/base/common/performance.js',
'out-build/vs/base/node/{stdForkStart.js,terminateProcess.sh,cpuUsage.sh}',
'out-build/vs/base/node/languagePacks.js',
'out-build/vs/base/node/{stdForkStart.js,terminateProcess.sh,cpuUsage.sh,ps.sh}',
'out-build/vs/base/browser/ui/octiconLabel/octicons/**',
'out-build/vs/workbench/browser/media/*-theme.css',
'out-build/vs/workbench/parts/debug/**/*.json',
'out-build/vs/workbench/parts/execution/**/*.scpt',
'out-build/vs/workbench/parts/webview/electron-browser/webview-pre.js',
'out-build/vs/workbench/contrib/debug/**/*.json',
'out-build/vs/workbench/contrib/externalTerminal/**/*.scpt',
'out-build/vs/workbench/contrib/webview/browser/pre/*.js',
'out-build/vs/workbench/contrib/webview/electron-browser/pre/*.js',
'out-build/vs/**/markdown.css',
'out-build/vs/workbench/parts/tasks/**/*.json',
'out-build/vs/workbench/parts/welcome/walkThrough/**/*.md',
'out-build/vs/workbench/contrib/tasks/**/*.json',
'out-build/vs/workbench/contrib/welcome/walkThrough/**/*.md',
'out-build/vs/workbench/services/files/**/*.exe',
'out-build/vs/workbench/services/files/**/*.md',
'out-build/vs/code/electron-browser/workbench/**',
@@ -99,19 +102,17 @@ const vscodeResources = [
'out-build/sql/parts/admin/**/*.html',
'out-build/sql/parts/connection/connectionDialog/media/*.{gif,png,svg}',
'out-build/sql/parts/common/dblist/**/*.html',
'out-build/sql/parts/dashboard/**/*.html',
'out-build/sql/workbench/parts/dashboard/**/*.html',
'out-build/sql/parts/disasterRecovery/**/*.html',
'out-build/sql/parts/common/modal/media/**',
'out-build/sql/parts/grid/load/lib/**',
'out-build/sql/parts/grid/load/loadJquery.js',
'out-build/sql/parts/grid/media/**',
'out-build/sql/parts/grid/views/**/*.html',
'out-build/sql/workbench/parts/grid/media/**',
'out-build/sql/workbench/parts/grid/views/**/*.html',
'out-build/sql/parts/tasks/**/*.html',
'out-build/sql/parts/taskHistory/viewlet/media/**',
'out-build/sql/parts/jobManagement/common/media/*.svg',
'out-build/sql/media/objectTypes/*.svg',
'out-build/sql/media/icons/*.svg',
'out-build/sql/parts/notebook/media/**/*.svg',
'out-build/sql/workbench/parts/notebook/media/**/*.svg',
'!**/test/**'
];
@@ -121,29 +122,41 @@ const BUNDLED_FILE_HEADER = [
' *--------------------------------------------------------*/'
].join('\n');
gulp.task('clean-optimized-vscode', util.rimraf('out-vscode'));
gulp.task('optimize-vscode', ['clean-optimized-vscode', 'compile-build', 'compile-extensions-build'], common.optimizeTask({
src: 'out-build',
entryPoints: vscodeEntryPoints,
otherSources: [],
resources: vscodeResources,
loaderConfig: common.loaderConfig(nodeModules),
header: BUNDLED_FILE_HEADER,
out: 'out-vscode',
bundleInfo: undefined
}));
const optimizeVSCodeTask = task.define('optimize-vscode', task.series(
task.parallel(
util.rimraf('out-vscode'),
compileBuildTask
),
common.optimizeTask({
src: 'out-build',
entryPoints: vscodeEntryPoints,
resources: vscodeResources,
loaderConfig: common.loaderConfig(nodeModules),
header: BUNDLED_FILE_HEADER,
out: 'out-vscode',
bundleInfo: undefined
})
));
gulp.task('optimize-index-js', ['optimize-vscode'], () => {
const fullpath = path.join(process.cwd(), 'out-vscode/bootstrap-window.js');
const contents = fs.readFileSync(fullpath).toString();
const newContents = contents.replace('[/*BUILD->INSERT_NODE_MODULES*/]', JSON.stringify(nodeModules));
fs.writeFileSync(fullpath, newContents);
});
const optimizeIndexJSTask = task.define('optimize-index-js', task.series(
optimizeVSCodeTask,
() => {
const fullpath = path.join(process.cwd(), 'out-vscode/bootstrap-window.js');
const contents = fs.readFileSync(fullpath).toString();
const newContents = contents.replace('[/*BUILD->INSERT_NODE_MODULES*/]', JSON.stringify(nodeModules));
fs.writeFileSync(fullpath, newContents);
}
));
const sourceMappingURLBase = `https://ticino.blob.core.windows.net/sourcemaps/${commit}`;
gulp.task('clean-minified-vscode', util.rimraf('out-vscode-min'));
gulp.task('minify-vscode', ['clean-minified-vscode', 'optimize-index-js'], common.minifyTask('out-vscode', `${sourceMappingURLBase}/core`));
const minifyVSCodeTask = task.define('minify-vscode', task.series(
task.parallel(
util.rimraf('out-vscode-min'),
optimizeIndexJSTask
),
common.minifyTask('out-vscode', `${sourceMappingURLBase}/core`)
));
// Package
@@ -206,13 +219,11 @@ function getElectron(arch) {
};
}
gulp.task('clean-electron', util.rimraf('.build/electron'));
gulp.task('electron', ['clean-electron'], getElectron(process.arch));
gulp.task('electron-ia32', ['clean-electron'], getElectron('ia32'));
gulp.task('electron-x64', ['clean-electron'], getElectron('x64'));
gulp.task('electron-arm', ['clean-electron'], getElectron('arm'));
gulp.task('electron-arm64', ['clean-electron'], getElectron('arm64'));
gulp.task(task.define('electron', task.series(util.rimraf('.build/electron'), getElectron(process.arch))));
gulp.task(task.define('electron-ia32', task.series(util.rimraf('.build/electron'), getElectron('ia32'))));
gulp.task(task.define('electron-x64', task.series(util.rimraf('.build/electron'), getElectron('x64'))));
gulp.task(task.define('electron-arm', task.series(util.rimraf('.build/electron'), getElectron('armv7l'))));
gulp.task(task.define('electron-arm64', task.series(util.rimraf('.build/electron'), getElectron('arm64'))));
/**
* Compute checksums for some files.
@@ -248,15 +259,14 @@ function computeChecksum(filename) {
return hash;
}
function packageTask(platform, arch, opts) {
function packageTask(platform, arch, sourceFolderName, destinationFolderName, opts) {
opts = opts || {};
// {{SQL CARBON EDIT}}
const destination = path.join(path.dirname(root), 'azuredatastudio') + (platform ? '-' + platform : '') + (arch ? '-' + arch : '');
const destination = path.join(path.dirname(root), destinationFolderName);
platform = platform || process.platform;
return () => {
const out = opts.minified ? 'out-vscode-min' : 'out-vscode';
const out = sourceFolderName;
const checksums = computeChecksums(out, [
'vs/workbench/workbench.main.js',
@@ -309,14 +319,13 @@ function packageTask(platform, arch, opts) {
const productJsonStream = gulp.src(['product.json'], { base: '.' })
.pipe(json(productJsonUpdate));
const license = gulp.src(['LICENSES.chromium.html', 'LICENSE.txt', 'ThirdPartyNotices.txt', 'licenses/**'], { base: '.' });
const watermark = gulp.src(['resources/letterpress.svg', 'resources/letterpress-dark.svg', 'resources/letterpress-hc.svg'], { base: '.' });
const license = gulp.src(['LICENSES.chromium.html', product.licenseFileName, 'ThirdPartyNotices.txt', 'licenses/**'], { base: '.', allowEmpty: true });
// TODO the API should be copied to `out` during compile, not here
const api = gulp.src('src/vs/vscode.d.ts').pipe(rename('out/vs/vscode.d.ts'));
// {{SQL CARBON EDIT}}
const dataApi = gulp.src('src/vs/data.d.ts').pipe(rename('out/sql/data.d.ts'));
const dataApi = gulp.src('src/sql/azdata.d.ts').pipe(rename('out/sql/azdata.d.ts'));
const sqlopsAPI = gulp.src('src/sql/sqlops.d.ts').pipe(rename('out/sql/sqlops.d.ts'));
const depsSrc = [
..._.flatten(productionDependencies.map(d => path.relative(root, d.path)).map(d => [`${d}/**`, `!${d}/**/{test,tests}/**`])),
@@ -348,9 +357,11 @@ function packageTask(platform, arch, opts) {
.pipe(util.cleanNodeModule('core-js', ['**/**'], undefined))
.pipe(util.cleanNodeModule('slickgrid', ['node_modules/**', 'examples/**'], undefined))
.pipe(util.cleanNodeModule('nsfw', ['binding.gyp', 'build/**', 'src/**', 'openpa/**', 'includes/**'], ['**/*.node', '**/*.a']))
.pipe(util.cleanNodeModule('vscode-nsfw', ['binding.gyp', 'build/**', 'src/**', 'openpa/**', 'includes/**'], ['**/*.node', '**/*.a']))
.pipe(util.cleanNodeModule('vscode-nsfw', ['binding.gyp', 'build/**', 'src/**', 'openpa/**', 'includes/**'], ['build/Release/*.node', '**/*.a']))
// {{SQL CARBON EDIT}} - End
.pipe(util.cleanNodeModule('vsda', ['binding.gyp', 'README.md', 'build/**', '*.bat', '*.sh', '*.cpp', '*.h'], ['build/Release/vsda.node']))
.pipe(util.cleanNodeModule('vscode-windows-ca-certs', ['**/*'], ['package.json', '**/*.node']))
.pipe(util.cleanNodeModule('node-addon-api', ['**/*']))
.pipe(createAsar(path.join(process.cwd(), 'node_modules'), ['**/*.node', '**/vscode-ripgrep/bin/*', '**/node-pty/build/Release/*'], 'app/node_modules.asar'));
// {{SQL CARBON EDIT}}
@@ -361,50 +372,29 @@ function packageTask(platform, arch, opts) {
'node_modules/underscore/**/*.*',
'node_modules/zone.js/**/*.*',
'node_modules/chart.js/**/*.*',
'node_modules/chartjs-color/**/*.*',
'node_modules/chartjs-color-string/**/*.*',
'node_modules/color-convert/**/*.*',
'node_modules/color-name/**/*.*',
'node_modules/moment/**/*.*'
], { base: '.', dot: true });
let all = es.merge(
packageJsonStream,
productJsonStream,
license,
watermark,
api,
// {{SQL CARBON EDIT}}
copiedModules,
dataApi,
sqlopsAPI,
sources,
deps
);
if (platform === 'win32') {
all = es.merge(all, gulp.src([
'resources/win32/bower.ico',
'resources/win32/c.ico',
'resources/win32/config.ico',
'resources/win32/cpp.ico',
'resources/win32/csharp.ico',
'resources/win32/css.ico',
'resources/win32/default.ico',
'resources/win32/go.ico',
'resources/win32/html.ico',
'resources/win32/jade.ico',
'resources/win32/java.ico',
'resources/win32/javascript.ico',
'resources/win32/json.ico',
'resources/win32/less.ico',
'resources/win32/markdown.ico',
'resources/win32/php.ico',
'resources/win32/powershell.ico',
'resources/win32/python.ico',
'resources/win32/react.ico',
'resources/win32/ruby.ico',
'resources/win32/sass.ico',
'resources/win32/shell.ico',
'resources/win32/sql.ico',
'resources/win32/typescript.ico',
'resources/win32/vue.ico',
'resources/win32/xml.ico',
'resources/win32/yaml.ico',
// {{SQL CARBON EDIT}} remove unused icons
'resources/win32/code_70x70.png',
'resources/win32/code_150x150.png'
], { base: '.' }));
@@ -426,7 +416,7 @@ function packageTask(platform, arch, opts) {
// result = es.merge(result, gulp.src('resources/completions/**', { base: '.' }));
if (platform === 'win32') {
result = es.merge(result, gulp.src('resources/win32/bin/code.js', { base: 'resources/win32' }));
result = es.merge(result, gulp.src('resources/win32/bin/code.js', { base: 'resources/win32', allowEmpty: true }));
result = es.merge(result, gulp.src('resources/win32/bin/code.cmd', { base: 'resources/win32' })
.pipe(replace('@@NAME@@', product.nameShort))
@@ -434,14 +424,18 @@ function packageTask(platform, arch, opts) {
result = es.merge(result, gulp.src('resources/win32/bin/code.sh', { base: 'resources/win32' })
.pipe(replace('@@NAME@@', product.nameShort))
.pipe(replace('@@PRODNAME@@', product.nameLong))
.pipe(replace('@@VERSION@@', version))
.pipe(replace('@@COMMIT@@', commit))
.pipe(replace('@@APPNAME@@', product.applicationName))
.pipe(replace('@@QUALITY@@', quality))
.pipe(rename(function (f) { f.basename = product.applicationName; f.extname = ''; })));
result = es.merge(result, gulp.src('resources/win32/VisualElementsManifest.xml', { base: 'resources/win32' })
.pipe(rename(product.nameShort + '.VisualElementsManifest.xml')));
} else if (platform === 'linux') {
result = es.merge(result, gulp.src('resources/linux/bin/code.sh', { base: '.' })
.pipe(replace('@@PRODNAME@@', product.nameLong))
.pipe(replace('@@NAME@@', product.applicationName))
.pipe(rename('bin/' + product.applicationName)));
}
@@ -461,38 +455,35 @@ function packageTask(platform, arch, opts) {
const buildRoot = path.dirname(root);
// {{SQL CARBON EDIT}}
gulp.task('vscode-win32-x64-azurecore', ['optimize-vscode'], ext.packageExtensionTask('azurecore', 'win32', 'x64'));
gulp.task('vscode-darwin-azurecore', ['optimize-vscode'], ext.packageExtensionTask('azurecore', 'darwin'));
gulp.task('vscode-linux-x64-azurecore', ['optimize-vscode'], ext.packageExtensionTask('azurecore', 'linux', 'x64'));
const BUILD_TARGETS = [
{ platform: 'win32', arch: 'ia32' },
{ platform: 'win32', arch: 'x64' },
{ platform: 'darwin', arch: null, opts: { stats: true } },
{ platform: 'linux', arch: 'ia32' },
{ platform: 'linux', arch: 'x64' },
{ platform: 'linux', arch: 'arm' },
{ platform: 'linux', arch: 'arm64' },
];
BUILD_TARGETS.forEach(buildTarget => {
const dashed = (str) => (str ? `-${str}` : ``);
const platform = buildTarget.platform;
const arch = buildTarget.arch;
const opts = buildTarget.opts;
gulp.task('vscode-win32-x64-mssql', ['vscode-linux-x64-azurecore', 'optimize-vscode'], ext.packageExtensionTask('mssql', 'win32', 'x64'));
gulp.task('vscode-darwin-mssql', ['vscode-linux-x64-azurecore', 'optimize-vscode'], ext.packageExtensionTask('mssql', 'darwin'));
gulp.task('vscode-linux-x64-mssql', ['vscode-linux-x64-azurecore', 'optimize-vscode'], ext.packageExtensionTask('mssql', 'linux', 'x64'));
['', 'min'].forEach(minified => {
const sourceFolderName = `out-vscode${dashed(minified)}`;
const destinationFolderName = `azuredatastudio${dashed(platform)}${dashed(arch)}`;
gulp.task('clean-vscode-win32-ia32', util.rimraf(path.join(buildRoot, 'azuredatastudio-win32-ia32')));
gulp.task('clean-vscode-win32-x64', util.rimraf(path.join(buildRoot, 'azuredatastudio-win32-x64')));
gulp.task('clean-vscode-darwin', util.rimraf(path.join(buildRoot, 'azuredatastudio-darwin')));
gulp.task('clean-vscode-linux-ia32', util.rimraf(path.join(buildRoot, 'azuredatastudio-linux-ia32')));
gulp.task('clean-vscode-linux-x64', util.rimraf(path.join(buildRoot, 'azuredatastudio-linux-x64')));
gulp.task('clean-vscode-linux-arm', util.rimraf(path.join(buildRoot, 'azuredatastudio-linux-arm')));
gulp.task('clean-vscode-linux-arm64', util.rimraf(path.join(buildRoot, 'azuredatastudio-linux-arm64')));
gulp.task('vscode-win32-ia32', ['optimize-vscode', 'clean-vscode-win32-ia32'], packageTask('win32', 'ia32'));
gulp.task('vscode-win32-x64', ['vscode-win32-x64-azurecore', 'vscode-win32-x64-mssql', 'optimize-vscode', 'clean-vscode-win32-x64'], packageTask('win32', 'x64'));
gulp.task('vscode-darwin', ['vscode-darwin-azurecore', 'vscode-darwin-mssql', 'optimize-vscode', 'clean-vscode-darwin'], packageTask('darwin', null, { stats: true }));
gulp.task('vscode-linux-ia32', ['optimize-vscode', 'clean-vscode-linux-ia32'], packageTask('linux', 'ia32'));
gulp.task('vscode-linux-x64', ['vscode-linux-x64-azurecore', 'vscode-linux-x64-mssql', 'optimize-vscode', 'clean-vscode-linux-x64'], packageTask('linux', 'x64'));
gulp.task('vscode-linux-arm', ['optimize-vscode', 'clean-vscode-linux-arm'], packageTask('linux', 'arm'));
gulp.task('vscode-linux-arm64', ['optimize-vscode', 'clean-vscode-linux-arm64'], packageTask('linux', 'arm64'));
gulp.task('vscode-win32-ia32-min', ['minify-vscode', 'clean-vscode-win32-ia32'], packageTask('win32', 'ia32', { minified: true }));
gulp.task('vscode-win32-x64-min', ['minify-vscode', 'clean-vscode-win32-x64'], packageTask('win32', 'x64', { minified: true }));
gulp.task('vscode-darwin-min', ['minify-vscode', 'clean-vscode-darwin'], packageTask('darwin', null, { minified: true, stats: true }));
gulp.task('vscode-linux-ia32-min', ['minify-vscode', 'clean-vscode-linux-ia32'], packageTask('linux', 'ia32', { minified: true }));
gulp.task('vscode-linux-x64-min', ['minify-vscode', 'clean-vscode-linux-x64'], packageTask('linux', 'x64', { minified: true }));
gulp.task('vscode-linux-arm-min', ['minify-vscode', 'clean-vscode-linux-arm'], packageTask('linux', 'arm', { minified: true }));
gulp.task('vscode-linux-arm64-min', ['minify-vscode', 'clean-vscode-linux-arm64'], packageTask('linux', 'arm64', { minified: true }));
const vscodeTask = task.define(`vscode${dashed(platform)}${dashed(arch)}${dashed(minified)}`, task.series(
task.parallel(
minified ? minifyVSCodeTask : optimizeVSCodeTask,
util.rimraf(path.join(buildRoot, destinationFolderName))
),
packageTask(platform, arch, sourceFolderName, destinationFolderName, opts)
));
gulp.task(vscodeTask);
});
});
// Transifex Localizations
@@ -515,30 +506,42 @@ const apiHostname = process.env.TRANSIFEX_API_URL;
const apiName = process.env.TRANSIFEX_API_NAME;
const apiToken = process.env.TRANSIFEX_API_TOKEN;
gulp.task('vscode-translations-push', ['optimize-vscode'], function () {
const pathToMetadata = './out-vscode/nls.metadata.json';
const pathToExtensions = './extensions/*';
const pathToSetup = 'build/win32/**/{Default.isl,messages.en.isl}';
gulp.task(task.define(
'vscode-translations-push',
task.series(
optimizeVSCodeTask,
function () {
const pathToMetadata = './out-vscode/nls.metadata.json';
const pathToExtensions = './extensions/*';
const pathToSetup = 'build/win32/**/{Default.isl,messages.en.isl}';
return es.merge(
gulp.src(pathToMetadata).pipe(i18n.createXlfFilesForCoreBundle()),
gulp.src(pathToSetup).pipe(i18n.createXlfFilesForIsl()),
gulp.src(pathToExtensions).pipe(i18n.createXlfFilesForExtensions())
).pipe(i18n.findObsoleteResources(apiHostname, apiName, apiToken)
).pipe(i18n.pushXlfFiles(apiHostname, apiName, apiToken));
});
return es.merge(
gulp.src(pathToMetadata).pipe(i18n.createXlfFilesForCoreBundle()),
gulp.src(pathToSetup).pipe(i18n.createXlfFilesForIsl()),
gulp.src(pathToExtensions).pipe(i18n.createXlfFilesForExtensions())
).pipe(i18n.findObsoleteResources(apiHostname, apiName, apiToken)
).pipe(i18n.pushXlfFiles(apiHostname, apiName, apiToken));
}
)
));
gulp.task('vscode-translations-export', ['optimize-vscode'], function () {
const pathToMetadata = './out-vscode/nls.metadata.json';
const pathToExtensions = './extensions/*';
const pathToSetup = 'build/win32/**/{Default.isl,messages.en.isl}';
gulp.task(task.define(
'vscode-translations-export',
task.series(
optimizeVSCodeTask,
function () {
const pathToMetadata = './out-vscode/nls.metadata.json';
const pathToExtensions = './extensions/*';
const pathToSetup = 'build/win32/**/{Default.isl,messages.en.isl}';
return es.merge(
gulp.src(pathToMetadata).pipe(i18n.createXlfFilesForCoreBundle()),
gulp.src(pathToSetup).pipe(i18n.createXlfFilesForIsl()),
gulp.src(pathToExtensions).pipe(i18n.createXlfFilesForExtensions())
).pipe(vfs.dest('../vscode-translations-export'));
});
return es.merge(
gulp.src(pathToMetadata).pipe(i18n.createXlfFilesForCoreBundle()),
gulp.src(pathToSetup).pipe(i18n.createXlfFilesForIsl()),
gulp.src(pathToExtensions).pipe(i18n.createXlfFilesForExtensions())
).pipe(vfs.dest('../vscode-translations-export'));
}
)
));
gulp.task('vscode-translations-pull', function () {
return es.merge([...i18n.defaultLanguages, ...i18n.extraLanguages].map(language => {
@@ -559,7 +562,7 @@ gulp.task('vscode-translations-import', function () {
// Sourcemaps
gulp.task('upload-vscode-sourcemaps', ['vscode-darwin-min', 'minify-vscode'], () => {
gulp.task('upload-vscode-sourcemaps', () => {
const vs = gulp.src('out-vscode-min/**/*.map', { base: 'out-vscode-min' })
.pipe(es.mapSync(f => {
f.path = `${f.base}/core/${f.relative}`;
@@ -583,57 +586,8 @@ gulp.task('upload-vscode-sourcemaps', ['vscode-darwin-min', 'minify-vscode'], ()
}));
});
const allConfigDetailsPath = path.join(os.tmpdir(), 'configuration.json');
gulp.task('upload-vscode-configuration', ['generate-vscode-configuration'], () => {
if (!shouldSetupSettingsSearch()) {
const branch = process.env.BUILD_SOURCEBRANCH;
console.log(`Only runs on master and release branches, not ${branch}`);
return;
}
if (!fs.existsSync(allConfigDetailsPath)) {
throw new Error(`configuration file at ${allConfigDetailsPath} does not exist`);
}
const settingsSearchBuildId = getSettingsSearchBuildId(packageJson);
if (!settingsSearchBuildId) {
throw new Error('Failed to compute build number');
}
return gulp.src(allConfigDetailsPath)
.pipe(azure.upload({
account: process.env.AZURE_STORAGE_ACCOUNT,
key: process.env.AZURE_STORAGE_ACCESS_KEY,
container: 'configuration',
prefix: `${settingsSearchBuildId}/${commit}/`
}));
});
function shouldSetupSettingsSearch() {
const branch = process.env.BUILD_SOURCEBRANCH;
return branch && (/\/master$/.test(branch) || branch.indexOf('/release/') >= 0);
}
function getSettingsSearchBuildId(packageJson) {
try {
const branch = process.env.BUILD_SOURCEBRANCH;
const branchId = branch.indexOf('/release/') >= 0 ? 0 :
/\/master$/.test(branch) ? 1 :
2; // Some unexpected branch
const out = cp.execSync(`git rev-list HEAD --count`);
const count = parseInt(out.toString());
// <version number><commit count><branchId (avoid unlikely conflicts)>
// 1.25.1, 1,234,567 commits, master = 1250112345671
return util.versionStringToNumber(packageJson.version) * 1e8 + count * 10 + branchId;
} catch (e) {
throw new Error('Could not determine build number: ' + e.toString());
}
}
// This task is only run for the MacOS build
gulp.task('generate-vscode-configuration', () => {
const generateVSCodeConfigurationTask = task.define('generate-vscode-configuration', () => {
return new Promise((resolve, reject) => {
const buildDir = process.env['AGENT_BUILDDIRECTORY'];
if (!buildDir) {
@@ -670,6 +624,61 @@ gulp.task('generate-vscode-configuration', () => {
});
});
const allConfigDetailsPath = path.join(os.tmpdir(), 'configuration.json');
gulp.task(task.define(
'upload-vscode-configuration',
task.series(
generateVSCodeConfigurationTask,
() => {
if (!shouldSetupSettingsSearch()) {
const branch = process.env.BUILD_SOURCEBRANCH;
console.log(`Only runs on master and release branches, not ${branch}`);
return;
}
if (!fs.existsSync(allConfigDetailsPath)) {
throw new Error(`configuration file at ${allConfigDetailsPath} does not exist`);
}
const settingsSearchBuildId = getSettingsSearchBuildId(packageJson);
if (!settingsSearchBuildId) {
throw new Error('Failed to compute build number');
}
return gulp.src(allConfigDetailsPath)
.pipe(azure.upload({
account: process.env.AZURE_STORAGE_ACCOUNT,
key: process.env.AZURE_STORAGE_ACCESS_KEY,
container: 'configuration',
prefix: `${settingsSearchBuildId}/${commit}/`
}));
}
)
));
function shouldSetupSettingsSearch() {
const branch = process.env.BUILD_SOURCEBRANCH;
return branch && (/\/master$/.test(branch) || branch.indexOf('/release/') >= 0);
}
function getSettingsSearchBuildId(packageJson) {
try {
const branch = process.env.BUILD_SOURCEBRANCH;
const branchId = branch.indexOf('/release/') >= 0 ? 0 :
/\/master$/.test(branch) ? 1 :
2; // Some unexpected branch
const out = cp.execSync(`git rev-list HEAD --count`);
const count = parseInt(out.toString());
// <version number><commit count><branchId (avoid unlikely conflicts)>
// 1.25.1, 1,234,567 commits, master = 1250112345671
return util.versionStringToNumber(packageJson.version) * 1e8 + count * 10 + branchId;
} catch (e) {
throw new Error('Could not determine build number: ' + e.toString());
}
}
// {{SQL CARBON EDIT}}
// Install service locally before building carbon

View File

@@ -12,6 +12,7 @@ const shell = require('gulp-shell');
const es = require('event-stream');
const vfs = require('vinyl-fs');
const util = require('./lib/util');
const task = require('./lib/task');
const packageJson = require('../package.json');
const product = require('../product.json');
const rpmDependencies = require('../resources/linux/rpm/dependencies.json');
@@ -26,7 +27,7 @@ function getDebPackageArch(arch) {
}
function prepareDebPackage(arch) {
// {{SQL CARBON EDIT}}
// {{SQL CARBON EDIT}}
const binaryDir = '../azuredatastudio-linux-' + arch;
const debArch = getDebPackageArch(arch);
const destination = '.build/linux/deb/' + debArch + '/' + product.applicationName + '-' + debArch;
@@ -42,7 +43,7 @@ function prepareDebPackage(arch) {
.pipe(replace('@@NAME_LONG@@', product.nameLong))
.pipe(replace('@@NAME_SHORT@@', product.nameShort))
.pipe(replace('@@NAME@@', product.applicationName))
.pipe(replace('@@ICON@@', product.applicationName))
.pipe(replace('@@ICON@@', product.linuxIconName))
.pipe(replace('@@URLPROTOCOL@@', product.urlProtocol));
const appdata = gulp.src('resources/linux/code.appdata.xml', { base: '.' })
@@ -52,7 +53,7 @@ function prepareDebPackage(arch) {
.pipe(rename('usr/share/appdata/' + product.applicationName + '.appdata.xml'));
const icon = gulp.src('resources/linux/code.png', { base: '.' })
.pipe(rename('usr/share/pixmaps/' + product.applicationName + '.png'));
.pipe(rename('usr/share/pixmaps/' + product.linuxIconName + '.png'));
// const bash_completion = gulp.src('resources/completions/bash/code')
// .pipe(rename('usr/share/bash-completion/completions/code'));
@@ -133,7 +134,7 @@ function prepareRpmPackage(arch) {
.pipe(replace('@@NAME_LONG@@', product.nameLong))
.pipe(replace('@@NAME_SHORT@@', product.nameShort))
.pipe(replace('@@NAME@@', product.applicationName))
.pipe(replace('@@ICON@@', product.applicationName))
.pipe(replace('@@ICON@@', product.linuxIconName))
.pipe(replace('@@URLPROTOCOL@@', product.urlProtocol));
const appdata = gulp.src('resources/linux/code.appdata.xml', { base: '.' })
@@ -143,7 +144,7 @@ function prepareRpmPackage(arch) {
.pipe(rename('usr/share/appdata/' + product.applicationName + '.appdata.xml'));
const icon = gulp.src('resources/linux/code.png', { base: '.' })
.pipe(rename('BUILD/usr/share/pixmaps/' + product.applicationName + '.png'));
.pipe(rename('BUILD/usr/share/pixmaps/' + product.linuxIconName + '.png'));
// const bash_completion = gulp.src('resources/completions/bash/code')
// .pipe(rename('BUILD/usr/share/bash-completion/completions/code'));
@@ -157,6 +158,7 @@ function prepareRpmPackage(arch) {
const spec = gulp.src('resources/linux/rpm/code.spec.template', { base: '.' })
.pipe(replace('@@NAME@@', product.applicationName))
.pipe(replace('@@NAME_LONG@@', product.nameLong))
.pipe(replace('@@ICON@@', product.linuxIconName))
.pipe(replace('@@VERSION@@', packageJson.version))
.pipe(replace('@@RELEASE@@', linuxPackageRevision))
.pipe(replace('@@ARCHITECTURE@@', rpmArch))
@@ -195,19 +197,26 @@ function getSnapBuildPath(arch) {
}
function prepareSnapPackage(arch) {
const binaryDir = '../VSCode-linux-' + arch;
// {{SQL CARBON EDIT}}
const binaryDir = '../azuredatastudio-linux-' + arch;
const destination = getSnapBuildPath(arch);
return function () {
const desktop = gulp.src('resources/linux/code.desktop', { base: '.' })
.pipe(rename(`usr/share/applications/${product.applicationName}.desktop`));
const desktopUrlHandler = gulp.src('resources/linux/code-url-handler.desktop', { base: '.' })
.pipe(rename(`usr/share/applications/${product.applicationName}-url-handler.desktop`));
const desktops = es.merge(desktop, desktopUrlHandler)
.pipe(replace('@@NAME_LONG@@', product.nameLong))
.pipe(replace('@@NAME_SHORT@@', product.nameShort))
.pipe(replace('@@NAME@@', product.applicationName))
.pipe(replace('@@ICON@@', `/usr/share/pixmaps/${product.applicationName}.png`))
.pipe(rename(`usr/share/applications/${product.applicationName}.desktop`));
.pipe(replace('@@ICON@@', `/usr/share/pixmaps/${product.linuxIconName}.png`))
.pipe(replace('@@URLPROTOCOL@@', product.urlProtocol));
const icon = gulp.src('resources/linux/code.png', { base: '.' })
.pipe(rename(`usr/share/pixmaps/${product.applicationName}.png`));
.pipe(rename(`usr/share/pixmaps/${product.linuxIconName}.png`));
const code = gulp.src(binaryDir + '/**/*', { base: binaryDir })
.pipe(rename(function (p) { p.dirname = `usr/share/${product.applicationName}/${p.dirname}`; }));
@@ -220,7 +229,7 @@ function prepareSnapPackage(arch) {
const electronLaunch = gulp.src('resources/linux/snap/electron-launch', { base: '.' })
.pipe(rename('electron-launch'));
const all = es.merge(desktop, icon, code, snapcraft, electronLaunch);
const all = es.merge(desktops, icon, code, snapcraft, electronLaunch);
return all.pipe(vfs.dest(destination));
};
@@ -231,116 +240,36 @@ function buildSnapPackage(arch) {
return shell.task(`cd ${snapBuildPath} && snapcraft build`);
}
function getFlatpakArch(arch) {
return { x64: 'x86_64', ia32: 'i386', arm: 'arm' }[arch];
}
const BUILD_TARGETS = [
{ arch: 'ia32' },
{ arch: 'x64' },
{ arch: 'arm' },
{ arch: 'arm64' },
];
function prepareFlatpak(arch) {
// {{SQL CARBON EDIT}}
const binaryDir = '../azuredatastudio-linux-' + arch;
const flatpakArch = getFlatpakArch(arch);
const destination = '.build/linux/flatpak/' + flatpakArch;
BUILD_TARGETS.forEach((buildTarget) => {
const arch = buildTarget.arch;
return function () {
// This is not imported in the global scope to avoid requiring ImageMagick
// (or GraphicsMagick) when not building building Flatpak bundles.
const imgResize = require('gulp-image-resize');
const all = [16, 24, 32, 48, 64, 128, 192, 256, 512].map(function (size) {
return gulp.src('resources/linux/code.png', { base: '.' })
.pipe(imgResize({ width: size, height: size, format: "png", noProfile: true }))
.pipe(rename('share/icons/hicolor/' + size + 'x' + size + '/apps/' + flatpakManifest.appId + '.png'));
});
all.push(gulp.src('resources/linux/code.desktop', { base: '.' })
.pipe(replace('Exec=/usr/share/@@NAME@@/@@NAME@@', 'Exec=' + product.applicationName))
.pipe(replace('@@NAME_LONG@@', product.nameLong))
.pipe(replace('@@NAME_SHORT@@', product.nameShort))
.pipe(replace('@@NAME@@', product.applicationName))
.pipe(rename('share/applications/' + flatpakManifest.appId + '.desktop')));
all.push(gulp.src('resources/linux/code.appdata.xml', { base: '.' })
.pipe(replace('@@NAME_LONG@@', product.nameLong))
.pipe(replace('@@NAME@@', flatpakManifest.appId))
.pipe(replace('@@LICENSE@@', product.licenseName))
.pipe(rename('share/appdata/' + flatpakManifest.appId + '.appdata.xml')));
all.push(gulp.src(binaryDir + '/**/*', { base: binaryDir })
.pipe(rename(function (p) {
p.dirname = 'share/' + product.applicationName + '/' + p.dirname;
})));
return es.merge(all).pipe(vfs.dest(destination));
};
}
function buildFlatpak(arch) {
const flatpakArch = getFlatpakArch(arch);
const manifest = {};
for (var k in flatpakManifest) {
manifest[k] = flatpakManifest[k];
{
const debArch = getDebPackageArch(arch);
const prepareDebTask = task.define(`vscode-linux-${arch}-prepare-deb`, task.series(util.rimraf(`.build/linux/deb/${debArch}`), prepareDebPackage(arch)));
// gulp.task(prepareDebTask);
const buildDebTask = task.define(`vscode-linux-${arch}-build-deb`, task.series(prepareDebTask, buildDebPackage(arch)));
gulp.task(buildDebTask);
}
manifest.files = [
['.build/linux/flatpak/' + flatpakArch, '/'],
];
const buildOptions = {
arch: flatpakArch,
subject: product.nameLong + ' ' + packageJson.version + '.' + linuxPackageRevision,
};
// If requested, use the configured path for the OSTree repository.
if (process.env.FLATPAK_REPO) {
buildOptions.repoDir = process.env.FLATPAK_REPO;
} else {
buildOptions.bundlePath = manifest.appId + '-' + flatpakArch + '.flatpak';
{
const rpmArch = getRpmPackageArch(arch);
const prepareRpmTask = task.define(`vscode-linux-${arch}-prepare-rpm`, task.series(util.rimraf(`.build/linux/rpm/${rpmArch}`), prepareRpmPackage(arch)));
// gulp.task(prepareRpmTask);
const buildRpmTask = task.define(`vscode-linux-${arch}-build-rpm`, task.series(prepareRpmTask, buildRpmPackage(arch)));
gulp.task(buildRpmTask);
}
// Setup PGP signing if requested.
if (process.env.GPG_KEY_ID !== undefined) {
buildOptions.gpgSign = process.env.GPG_KEY_ID;
if (process.env.GPG_HOMEDIR) {
buildOptions.gpgHomedir = process.env.GPG_HOME_DIR;
}
{
const prepareSnapTask = task.define(`vscode-linux-${arch}-prepare-snap`, task.series(util.rimraf(`.build/linux/snap/${arch}`), prepareSnapPackage(arch)));
gulp.task(prepareSnapTask);
const buildSnapTask = task.define(`vscode-linux-${arch}-build-snap`, task.series(prepareSnapTask, buildSnapPackage(arch)));
gulp.task(buildSnapTask);
}
return function (cb) {
require('flatpak-bundler').bundle(manifest, buildOptions, cb);
};
}
gulp.task('clean-vscode-linux-ia32-deb', util.rimraf('.build/linux/deb/i386'));
gulp.task('clean-vscode-linux-x64-deb', util.rimraf('.build/linux/deb/amd64'));
gulp.task('clean-vscode-linux-arm-deb', util.rimraf('.build/linux/deb/armhf'));
gulp.task('clean-vscode-linux-arm64-deb', util.rimraf('.build/linux/deb/arm64'));
gulp.task('clean-vscode-linux-ia32-rpm', util.rimraf('.build/linux/rpm/i386'));
gulp.task('clean-vscode-linux-x64-rpm', util.rimraf('.build/linux/rpm/x86_64'));
gulp.task('clean-vscode-linux-arm-rpm', util.rimraf('.build/linux/rpm/armhf'));
gulp.task('clean-vscode-linux-arm64-rpm', util.rimraf('.build/linux/rpm/arm64'));
gulp.task('clean-vscode-linux-ia32-snap', util.rimraf('.build/linux/snap/x64'));
gulp.task('clean-vscode-linux-x64-snap', util.rimraf('.build/linux/snap/x64'));
gulp.task('clean-vscode-linux-arm-snap', util.rimraf('.build/linux/snap/x64'));
gulp.task('clean-vscode-linux-arm64-snap', util.rimraf('.build/linux/snap/x64'));
gulp.task('vscode-linux-ia32-prepare-deb', ['clean-vscode-linux-ia32-deb'], prepareDebPackage('ia32'));
gulp.task('vscode-linux-x64-prepare-deb', ['clean-vscode-linux-x64-deb'], prepareDebPackage('x64'));
gulp.task('vscode-linux-arm-prepare-deb', ['clean-vscode-linux-arm-deb'], prepareDebPackage('arm'));
gulp.task('vscode-linux-arm64-prepare-deb', ['clean-vscode-linux-arm64-deb'], prepareDebPackage('arm64'));
gulp.task('vscode-linux-ia32-build-deb', ['vscode-linux-ia32-prepare-deb'], buildDebPackage('ia32'));
gulp.task('vscode-linux-x64-build-deb', ['vscode-linux-x64-prepare-deb'], buildDebPackage('x64'));
gulp.task('vscode-linux-arm-build-deb', ['vscode-linux-arm-prepare-deb'], buildDebPackage('arm'));
gulp.task('vscode-linux-arm64-build-deb', ['vscode-linux-arm64-prepare-deb'], buildDebPackage('arm64'));
gulp.task('vscode-linux-ia32-prepare-rpm', ['clean-vscode-linux-ia32-rpm'], prepareRpmPackage('ia32'));
gulp.task('vscode-linux-x64-prepare-rpm', ['clean-vscode-linux-x64-rpm'], prepareRpmPackage('x64'));
gulp.task('vscode-linux-arm-prepare-rpm', ['clean-vscode-linux-arm-rpm'], prepareRpmPackage('arm'));
gulp.task('vscode-linux-arm64-prepare-rpm', ['clean-vscode-linux-arm64-rpm'], prepareRpmPackage('arm64'));
gulp.task('vscode-linux-ia32-build-rpm', ['vscode-linux-ia32-prepare-rpm'], buildRpmPackage('ia32'));
gulp.task('vscode-linux-x64-build-rpm', ['vscode-linux-x64-prepare-rpm'], buildRpmPackage('x64'));
gulp.task('vscode-linux-arm-build-rpm', ['vscode-linux-arm-prepare-rpm'], buildRpmPackage('arm'));
gulp.task('vscode-linux-arm64-build-rpm', ['vscode-linux-arm64-prepare-rpm'], buildRpmPackage('arm64'));
gulp.task('vscode-linux-ia32-prepare-snap', ['clean-vscode-linux-ia32-snap'], prepareSnapPackage('ia32'));
gulp.task('vscode-linux-x64-prepare-snap', ['clean-vscode-linux-x64-snap'], prepareSnapPackage('x64'));
gulp.task('vscode-linux-arm-prepare-snap', ['clean-vscode-linux-arm-snap'], prepareSnapPackage('arm'));
gulp.task('vscode-linux-arm64-prepare-snap', ['clean-vscode-linux-arm64-snap'], prepareSnapPackage('arm64'));
gulp.task('vscode-linux-ia32-build-snap', ['vscode-linux-ia32-prepare-snap'], buildSnapPackage('ia32'));
gulp.task('vscode-linux-x64-build-snap', ['vscode-linux-x64-prepare-snap'], buildSnapPackage('x64'));
gulp.task('vscode-linux-arm-build-snap', ['vscode-linux-arm-prepare-snap'], buildSnapPackage('arm'));
gulp.task('vscode-linux-arm64-build-snap', ['vscode-linux-arm64-prepare-snap'], buildSnapPackage('arm64'));
});

View File

@@ -12,6 +12,7 @@ const assert = require('assert');
const cp = require('child_process');
const _7z = require('7zip')['7z'];
const util = require('./lib/util');
const task = require('./lib/task');
const pkg = require('../package.json');
const product = require('../product.json');
const vfs = require('vinyl-fs');
@@ -26,7 +27,7 @@ const zipPath = arch => path.join(zipDir(arch), `VSCode-win32-${arch}.zip`);
const setupDir = (arch, target) => path.join(repoPath, '.build', `win32-${arch}`, `${target}-setup`);
const issPath = path.join(__dirname, 'win32', 'code.iss');
const innoSetupPath = path.join(path.dirname(path.dirname(require.resolve('innosetup-compiler'))), 'bin', 'ISCC.exe');
const signPS1 = path.join(repoPath, 'build', 'azure-pipelines', 'win32', 'sign.ps1');
// const signPS1 = path.join(repoPath, 'build', 'azure-pipelines', 'win32', 'sign.ps1');
function packageInnoSetup(iss, options, cb) {
options = options || {};
@@ -107,8 +108,8 @@ function buildWin32Setup(arch, target) {
}
function defineWin32SetupTasks(arch, target) {
gulp.task(`clean-vscode-win32-${arch}-${target}-setup`, util.rimraf(setupDir(arch, target)));
gulp.task(`vscode-win32-${arch}-${target}-setup`, [`clean-vscode-win32-${arch}-${target}-setup`], buildWin32Setup(arch, target));
const cleanTask = util.rimraf(setupDir(arch, target));
gulp.task(task.define(`vscode-win32-${arch}-${target}-setup`, task.series(cleanTask, buildWin32Setup(arch, target))));
}
defineWin32SetupTasks('ia32', 'system');
@@ -126,11 +127,8 @@ function archiveWin32Setup(arch) {
};
}
gulp.task('clean-vscode-win32-ia32-archive', util.rimraf(zipDir('ia32')));
gulp.task('vscode-win32-ia32-archive', ['clean-vscode-win32-ia32-archive'], archiveWin32Setup('ia32'));
gulp.task('clean-vscode-win32-x64-archive', util.rimraf(zipDir('x64')));
gulp.task('vscode-win32-x64-archive', ['clean-vscode-win32-x64-archive'], archiveWin32Setup('x64'));
gulp.task(task.define('vscode-win32-ia32-archive', task.series(util.rimraf(zipDir('ia32')), archiveWin32Setup('ia32'))));
gulp.task(task.define('vscode-win32-x64-archive', task.series(util.rimraf(zipDir('x64')), archiveWin32Setup('x64'))));
function copyInnoUpdater(arch) {
return () => {
@@ -139,9 +137,6 @@ function copyInnoUpdater(arch) {
};
}
gulp.task('vscode-win32-ia32-copy-inno-updater', copyInnoUpdater('ia32'));
gulp.task('vscode-win32-x64-copy-inno-updater', copyInnoUpdater('x64'));
function patchInnoUpdater(arch) {
return cb => {
const icon = path.join(repoPath, 'resources', 'win32', 'code.ico');
@@ -149,5 +144,5 @@ function patchInnoUpdater(arch) {
};
}
gulp.task('vscode-win32-ia32-inno-updater', ['vscode-win32-ia32-copy-inno-updater'], patchInnoUpdater('ia32'));
gulp.task('vscode-win32-x64-inno-updater', ['vscode-win32-x64-copy-inno-updater'], patchInnoUpdater('x64'));
gulp.task(task.define('vscode-win32-ia32-inno-updater', task.series(copyInnoUpdater('ia32'), patchInnoUpdater('ia32'))));
gulp.task(task.define('vscode-win32-x64-inno-updater', task.series(copyInnoUpdater('x64'), patchInnoUpdater('x64'))));

View File

@@ -14,7 +14,8 @@ const es = require('event-stream');
const rename = require('gulp-rename');
const vfs = require('vinyl-fs');
const ext = require('./extensions');
const util = require('gulp-util');
const fancyLog = require('fancy-log');
const ansiColors = require('ansi-colors');
const root = path.dirname(path.dirname(__dirname));
const builtInExtensions = require('../builtInExtensions.json');
@@ -43,7 +44,7 @@ function isUpToDate(extension) {
function syncMarketplaceExtension(extension) {
if (isUpToDate(extension)) {
util.log(util.colors.blue('[marketplace]'), `${extension.name}@${extension.version}`, util.colors.green('✔︎'));
fancyLog(ansiColors.blue('[marketplace]'), `${extension.name}@${extension.version}`, ansiColors.green('✔︎'));
return es.readArray([]);
}
@@ -52,13 +53,13 @@ function syncMarketplaceExtension(extension) {
return ext.fromMarketplace(extension.name, extension.version, extension.metadata)
.pipe(rename(p => p.dirname = `${extension.name}/${p.dirname}`))
.pipe(vfs.dest('.build/builtInExtensions'))
.on('end', () => util.log(util.colors.blue('[marketplace]'), extension.name, util.colors.green('✔︎')));
.on('end', () => fancyLog(ansiColors.blue('[marketplace]'), extension.name, ansiColors.green('✔︎')));
}
function syncExtension(extension, controlState) {
switch (controlState) {
case 'disabled':
util.log(util.colors.blue('[disabled]'), util.colors.gray(extension.name));
fancyLog(ansiColors.blue('[disabled]'), ansiColors.gray(extension.name));
return es.readArray([]);
case 'marketplace':
@@ -66,15 +67,15 @@ function syncExtension(extension, controlState) {
default:
if (!fs.existsSync(controlState)) {
util.log(util.colors.red(`Error: Built-in extension '${extension.name}' is configured to run from '${controlState}' but that path does not exist.`));
fancyLog(ansiColors.red(`Error: Built-in extension '${extension.name}' is configured to run from '${controlState}' but that path does not exist.`));
return es.readArray([]);
} else if (!fs.existsSync(path.join(controlState, 'package.json'))) {
util.log(util.colors.red(`Error: Built-in extension '${extension.name}' is configured to run from '${controlState}' but there is no 'package.json' file in that directory.`));
fancyLog(ansiColors.red(`Error: Built-in extension '${extension.name}' is configured to run from '${controlState}' but there is no 'package.json' file in that directory.`));
return es.readArray([]);
}
util.log(util.colors.blue('[local]'), `${extension.name}: ${util.colors.cyan(controlState)}`, util.colors.green('✔︎'));
fancyLog(ansiColors.blue('[local]'), `${extension.name}: ${ansiColors.cyan(controlState)}`, ansiColors.green('✔︎'));
return es.readArray([]);
}
}
@@ -93,8 +94,8 @@ function writeControlFile(control) {
}
function main() {
util.log('Syncronizing built-in extensions...');
util.log(`You can manage built-in extensions with the ${util.colors.cyan('--builtin')} flag`);
fancyLog('Syncronizing built-in extensions...');
fancyLog(`You can manage built-in extensions with the ${ansiColors.cyan('--builtin')} flag`);
const control = readControlFile();
const streams = [];

View File

@@ -16,7 +16,8 @@ const monacodts = require("../monaco/api");
const nls = require("./nls");
const reporter_1 = require("./reporter");
const util = require("./util");
const util2 = require("gulp-util");
const fancyLog = require("fancy-log");
const ansiColors = require("ansi-colors");
const watch = require('./watch');
const reporter = reporter_1.createReporter();
function getTypeScriptCompilerOptions(src) {
@@ -179,7 +180,7 @@ class MonacoGenerator {
return r;
}
_log(message, ...rest) {
util2.log(util2.colors.cyan('[monaco.d.ts]'), message, ...rest);
fancyLog(ansiColors.cyan('[monaco.d.ts]'), message, ...rest);
}
execute() {
const startTime = Date.now();

View File

@@ -17,7 +17,9 @@ import * as monacodts from '../monaco/api';
import * as nls from './nls';
import { createReporter } from './reporter';
import * as util from './util';
import * as util2 from 'gulp-util';
import * as fancyLog from 'fancy-log';
import * as ansiColors from 'ansi-colors';
const watch = require('./watch');
const reporter = createReporter();
@@ -218,7 +220,7 @@ class MonacoGenerator {
}
private _log(message: any, ...rest: any[]): void {
util2.log(util2.colors.cyan('[monaco.d.ts]'), message, ...rest);
fancyLog(ansiColors.cyan('[monaco.d.ts]'), message, ...rest);
}
public execute(): void {

View File

@@ -17,7 +17,8 @@ const remote = require("gulp-remote-src");
const vzip = require('gulp-vinyl-zip');
const filter = require("gulp-filter");
const rename = require("gulp-rename");
const util = require('gulp-util');
const fancyLog = require("fancy-log");
const ansiColors = require("ansi-colors");
const buffer = require('gulp-buffer');
const json = require("gulp-json-editor");
const webpack = require('webpack');
@@ -136,7 +137,7 @@ function fromLocalWebpack(extensionPath, sourceMappingURLBase) {
.pipe(packageJsonFilter.restore);
const webpackStreams = webpackConfigLocations.map(webpackConfigPath => () => {
const webpackDone = (err, stats) => {
util.log(`Bundled extension: ${util.colors.yellow(path.join(path.basename(extensionPath), path.relative(extensionPath, webpackConfigPath)))}...`);
fancyLog(`Bundled extension: ${ansiColors.yellow(path.join(path.basename(extensionPath), path.relative(extensionPath, webpackConfigPath)))}...`);
if (err) {
result.emit('error', err);
}
@@ -214,7 +215,7 @@ const baseHeaders = {
function fromMarketplace(extensionName, version, metadata) {
const [publisher, name] = extensionName.split('.');
const url = `https://marketplace.visualstudio.com/_apis/public/gallery/publishers/${publisher}/vsextensions/${name}/${version}/vspackage`;
util.log('Downloading extension:', util.colors.yellow(`${extensionName}@${version}`), '...');
fancyLog('Downloading extension:', ansiColors.yellow(`${extensionName}@${version}`), '...');
const options = {
base: url,
requestOptions: {
@@ -236,6 +237,7 @@ exports.fromMarketplace = fromMarketplace;
const excludedExtensions = [
'vscode-api-tests',
'vscode-colorize-tests',
'vscode-test-resolver',
'ms-vscode.node-debug',
'ms-vscode.node-debug2',
// {{SQL CARBON EDIT}}
@@ -245,14 +247,16 @@ const excludedExtensions = [
const sqlBuiltInExtensions = [
// Add SQL built-in extensions here.
// the extension will be excluded from SQLOps package and will have separate vsix packages
'admin-tool-ext-win',
'agent',
'import',
'profiler',
'admin-pack',
'big-data-cluster',
'dacpac'
'dacpac',
'schema-compare',
'cms'
];
var azureExtensions = ['azurecore', 'mssql'];
const builtInExtensions = require('../builtInExtensions.json');
/**
* We're doing way too much stuff at once, with webpack et al. So much stuff
@@ -288,8 +292,7 @@ function packageExtensionsStream(optsIn) {
.filter(({ name }) => opts.desiredExtensions ? opts.desiredExtensions.indexOf(name) >= 0 : true)
.filter(({ name }) => builtInExtensions.every(b => b.name !== name))
// {{SQL CARBON EDIT}}
.filter(({ name }) => sqlBuiltInExtensions.indexOf(name) === -1)
.filter(({ name }) => azureExtensions.indexOf(name) === -1);
.filter(({ name }) => sqlBuiltInExtensions.indexOf(name) === -1);
const localExtensions = () => sequence([...localExtensionDescriptions.map(extension => () => {
return fromLocal(extension.path, opts.sourceMappingURLBase)
.pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`));

View File

@@ -17,7 +17,8 @@ import remote = require('gulp-remote-src');
const vzip = require('gulp-vinyl-zip');
import filter = require('gulp-filter');
import rename = require('gulp-rename');
const util = require('gulp-util');
import * as fancyLog from 'fancy-log';
import * as ansiColors from 'ansi-colors';
const buffer = require('gulp-buffer');
import json = require('gulp-json-editor');
const webpack = require('webpack');
@@ -155,7 +156,7 @@ function fromLocalWebpack(extensionPath: string, sourceMappingURLBase: string |
const webpackStreams = webpackConfigLocations.map(webpackConfigPath => () => {
const webpackDone = (err: any, stats: any) => {
util.log(`Bundled extension: ${util.colors.yellow(path.join(path.basename(extensionPath), path.relative(extensionPath, webpackConfigPath)))}...`);
fancyLog(`Bundled extension: ${ansiColors.yellow(path.join(path.basename(extensionPath), path.relative(extensionPath, webpackConfigPath)))}...`);
if (err) {
result.emit('error', err);
}
@@ -249,7 +250,7 @@ export function fromMarketplace(extensionName: string, version: string, metadata
const [publisher, name] = extensionName.split('.');
const url = `https://marketplace.visualstudio.com/_apis/public/gallery/publishers/${publisher}/vsextensions/${name}/${version}/vspackage`;
util.log('Downloading extension:', util.colors.yellow(`${extensionName}@${version}`), '...');
fancyLog('Downloading extension:', ansiColors.yellow(`${extensionName}@${version}`), '...');
const options = {
base: url,
@@ -282,6 +283,7 @@ interface IPackageExtensionsOptions {
const excludedExtensions = [
'vscode-api-tests',
'vscode-colorize-tests',
'vscode-test-resolver',
'ms-vscode.node-debug',
'ms-vscode.node-debug2',
// {{SQL CARBON EDIT}}
@@ -292,14 +294,16 @@ const excludedExtensions = [
const sqlBuiltInExtensions = [
// Add SQL built-in extensions here.
// the extension will be excluded from SQLOps package and will have separate vsix packages
'admin-tool-ext-win',
'agent',
'import',
'profiler',
'admin-pack',
'big-data-cluster',
'dacpac'
'dacpac',
'schema-compare',
'cms'
];
var azureExtensions = ['azurecore', 'mssql'];
// {{SQL CARBON EDIT}} - End
interface IBuiltInExtension {
@@ -348,8 +352,7 @@ export function packageExtensionsStream(optsIn?: IPackageExtensionsOptions): Nod
.filter(({ name }) => opts.desiredExtensions ? opts.desiredExtensions.indexOf(name) >= 0 : true)
.filter(({ name }) => builtInExtensions.every(b => b.name !== name))
// {{SQL CARBON EDIT}}
.filter(({ name }) => sqlBuiltInExtensions.indexOf(name) === -1)
.filter(({ name }) => azureExtensions.indexOf(name) === -1);
.filter(({ name }) => sqlBuiltInExtensions.indexOf(name) === -1);
const localExtensions = () => sequence([...localExtensionDescriptions.map(extension => () => {
return fromLocal(extension.path, opts.sourceMappingURLBase)

View File

@@ -13,15 +13,16 @@ const xml2js = require("xml2js");
const glob = require("glob");
const https = require("https");
const gulp = require("gulp");
const util = require("gulp-util");
const fancyLog = require("fancy-log");
const ansiColors = require("ansi-colors");
const iconv = require("iconv-lite");
const NUMBER_OF_CONCURRENT_DOWNLOADS = 4;
function log(message, ...rest) {
util.log(util.colors.green('[i18n]'), message, ...rest);
fancyLog(ansiColors.green('[i18n]'), message, ...rest);
}
exports.defaultLanguages = [
{ id: 'zh-tw', folderName: 'cht', transifexId: 'zh-hant' },
{ id: 'zh-cn', folderName: 'chs', transifexId: 'zh-hans' },
{ id: 'zh-tw', folderName: 'cht', translationId: 'zh-hant' },
{ id: 'zh-cn', folderName: 'chs', translationId: 'zh-hans' },
{ id: 'ja', folderName: 'jpn' },
{ id: 'ko', folderName: 'kor' },
{ id: 'de', folderName: 'deu' },
@@ -371,7 +372,11 @@ function processCoreBundleFormat(fileHeader, languages, json, emitter) {
}
});
});
let languageDirectory = path.join(__dirname, '..', '..', 'i18n');
let languageDirectory = path.join(__dirname, '..', '..', '..', 'vscode-loc', 'i18n');
if (!fs.existsSync(languageDirectory)) {
log(`No VS Code localization repository found. Looking at ${languageDirectory}`);
log(`To bundle translations please check out the vscode-loc repository as a sibling of the vscode repository.`);
}
let sortedLanguages = sortLanguages(languages);
sortedLanguages.forEach((language) => {
if (process.env['VSCODE_BUILD_VERBOSE']) {
@@ -379,22 +384,25 @@ function processCoreBundleFormat(fileHeader, languages, json, emitter) {
}
statistics[language.id] = 0;
let localizedModules = Object.create(null);
let languageFolderName = language.folderName || language.id;
let cwd = path.join(languageDirectory, languageFolderName, 'src');
let languageFolderName = language.translationId || language.id;
let i18nFile = path.join(languageDirectory, `vscode-language-pack-${languageFolderName}`, 'translations', 'main.i18n.json');
let allMessages;
if (fs.existsSync(i18nFile)) {
let content = stripComments(fs.readFileSync(i18nFile, 'utf8'));
allMessages = JSON.parse(content);
}
modules.forEach((module) => {
let order = keysSection[module];
let i18nFile = path.join(cwd, module) + '.i18n.json';
let messages = null;
if (fs.existsSync(i18nFile)) {
let content = stripComments(fs.readFileSync(i18nFile, 'utf8'));
messages = JSON.parse(content);
let moduleMessage;
if (allMessages) {
moduleMessage = allMessages.contents[module];
}
else {
if (!moduleMessage) {
if (process.env['VSCODE_BUILD_VERBOSE']) {
log(`No localized messages found for module ${module}. Using default messages.`);
}
messages = defaultMessages[module];
statistics[language.id] = statistics[language.id] + Object.keys(messages).length;
moduleMessage = defaultMessages[module];
statistics[language.id] = statistics[language.id] + Object.keys(moduleMessage).length;
}
let localizedMessages = [];
order.forEach((keyInfo) => {
@@ -405,7 +413,7 @@ function processCoreBundleFormat(fileHeader, languages, json, emitter) {
else {
key = keyInfo.key;
}
let message = messages[key];
let message = moduleMessage[key];
if (!message) {
if (process.env['VSCODE_BUILD_VERBOSE']) {
log(`No localized message found for key ${key} in module ${module}. Using default message.`);
@@ -490,7 +498,7 @@ function getResource(sourceFile) {
else if (/^vs\/code/.test(sourceFile)) {
return { name: 'vs/code', project: workbenchProject };
}
else if (/^vs\/workbench\/parts/.test(sourceFile)) {
else if (/^vs\/workbench\/contrib/.test(sourceFile)) {
resource = sourceFile.split('/', 4).join('/');
return { name: resource, project: workbenchProject };
}
@@ -578,7 +586,7 @@ function createXlfFilesForExtensions() {
}
return _xlf;
}
gulp.src([`./extensions/${extensionName}/package.nls.json`, `./extensions/${extensionName}/**/nls.metadata.json`]).pipe(event_stream_1.through(function (file) {
gulp.src([`./extensions/${extensionName}/package.nls.json`, `./extensions/${extensionName}/**/nls.metadata.json`], { allowEmpty: true }).pipe(event_stream_1.through(function (file) {
if (file.isBuffer()) {
const buffer = file.contents;
const basename = path.basename(file.path);
@@ -955,7 +963,7 @@ function retrieveResource(language, resource, apiHostname, credentials) {
return limiter.queue(() => new Promise((resolve, reject) => {
const slug = resource.name.replace(/\//g, '_');
const project = resource.project;
let transifexLanguageId = language.id === 'ps' ? 'en' : language.transifexId || language.id;
let transifexLanguageId = language.id === 'ps' ? 'en' : language.translationId || language.id;
const options = {
hostname: apiHostname,
path: `/api/2/project/${project}/resource/${slug}/translation/${transifexLanguageId}?file&mode=onlyreviewed`,
@@ -1038,7 +1046,7 @@ function prepareI18nPackFiles(externalExtensions, resultingTranslationPaths, pse
let extensionsPacks = {};
let errors = [];
return event_stream_1.through(function (xlf) {
let project = path.dirname(xlf.relative);
let project = path.basename(path.dirname(xlf.relative));
let resource = path.basename(xlf.relative, '.xlf');
let contents = xlf.contents.toString();
let parsePromise = pseudo ? XLF.parsePseudo(contents) : XLF.parse(contents);

View File

@@ -27,135 +27,155 @@
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/cli",
"name": "vs/workbench/api/common",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/codeEditor",
"name": "vs/workbench/contrib/cli",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/comments",
"name": "vs/workbench/contrib/codeEditor",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/debug",
"name": "vs/workbench/contrib/codeinset",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/emmet",
"name": "vs/workbench/contrib/callHierarchy",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/execution",
"name": "vs/workbench/contrib/comments",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/extensions",
"name": "vs/workbench/contrib/debug",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/feedback",
"name": "vs/workbench/contrib/emmet",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/files",
"name": "vs/workbench/contrib/extensions",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/html",
"name": "vs/workbench/contrib/externalTerminal",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/markers",
"name": "vs/workbench/contrib/feedback",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/localizations",
"name": "vs/workbench/contrib/files",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/logs",
"name": "vs/workbench/contrib/html",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/output",
"name": "vs/workbench/contrib/issue",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/performance",
"name": "vs/workbench/contrib/markers",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/preferences",
"name": "vs/workbench/contrib/localizations",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/quickopen",
"name": "vs/workbench/contrib/logs",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/relauncher",
"name": "vs/workbench/contrib/output",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/scm",
"name": "vs/workbench/contrib/performance",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/search",
"name": "vs/workbench/contrib/preferences",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/snippets",
"name": "vs/workbench/contrib/quickopen",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/stats",
"name": "vs/workbench/contrib/relauncher",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/surveys",
"name": "vs/workbench/contrib/scm",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/tasks",
"name": "vs/workbench/contrib/search",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/terminal",
"name": "vs/workbench/contrib/snippets",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/themes",
"name": "vs/workbench/contrib/format",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/trust",
"name": "vs/workbench/contrib/stats",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/update",
"name": "vs/workbench/contrib/surveys",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/url",
"name": "vs/workbench/contrib/tasks",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/watermark",
"name": "vs/workbench/contrib/terminal",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/webview",
"name": "vs/workbench/contrib/themes",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/welcome",
"name": "vs/workbench/contrib/trust",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/outline",
"name": "vs/workbench/contrib/update",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/contrib/url",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/contrib/watermark",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/contrib/webview",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/contrib/welcome",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/contrib/outline",
"project": "vscode-workbench"
},
{
@@ -195,13 +215,17 @@
"project": "vscode-workbench"
},
{
"name": "vs/workbench/services/jsonschemas",
"name": "vs/workbench/services/extensionManagement",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/services/files",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/services/integrity",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/services/keybinding",
"project": "vscode-workbench"

View File

@@ -13,19 +13,19 @@ import * as xml2js from 'xml2js';
import * as glob from 'glob';
import * as https from 'https';
import * as gulp from 'gulp';
import * as util from 'gulp-util';
import * as fancyLog from 'fancy-log';
import * as ansiColors from 'ansi-colors';
import * as iconv from 'iconv-lite';
const NUMBER_OF_CONCURRENT_DOWNLOADS = 4;
function log(message: any, ...rest: any[]): void {
util.log(util.colors.green('[i18n]'), message, ...rest);
fancyLog(ansiColors.green('[i18n]'), message, ...rest);
}
export interface Language {
id: string; // laguage id, e.g. zh-tw, de
transifexId?: string; // language id used in transifex, e.g zh-hant, de (optional, if not set, the id is used)
id: string; // language id, e.g. zh-tw, de
translationId?: string; // language id used in translation tools, e.g zh-hant, de (optional, if not set, the id is used)
folderName?: string; // language specific folder name, e.g. cht, deu (optional, if not set, the id is used)
}
@@ -38,8 +38,8 @@ export interface InnoSetup {
}
export const defaultLanguages: Language[] = [
{ id: 'zh-tw', folderName: 'cht', transifexId: 'zh-hant' },
{ id: 'zh-cn', folderName: 'chs', transifexId: 'zh-hans' },
{ id: 'zh-tw', folderName: 'cht', translationId: 'zh-hant' },
{ id: 'zh-cn', folderName: 'chs', translationId: 'zh-hans' },
{ id: 'ja', folderName: 'jpn' },
{ id: 'ko', folderName: 'kor' },
{ id: 'de', folderName: 'deu' },
@@ -144,6 +144,15 @@ interface BundledExtensionFormat {
};
}
interface I18nFormat {
version: string;
contents: {
[module: string]: {
[messageKey: string]: string;
};
};
}
export class Line {
private buffer: string[] = [];
@@ -486,7 +495,11 @@ function processCoreBundleFormat(fileHeader: string, languages: Language[], json
});
});
let languageDirectory = path.join(__dirname, '..', '..', 'i18n');
let languageDirectory = path.join(__dirname, '..', '..', '..', 'vscode-loc', 'i18n');
if (!fs.existsSync(languageDirectory)) {
log(`No VS Code localization repository found. Looking at ${languageDirectory}`);
log(`To bundle translations please check out the vscode-loc repository as a sibling of the vscode repository.`);
}
let sortedLanguages = sortLanguages(languages);
sortedLanguages.forEach((language) => {
if (process.env['VSCODE_BUILD_VERBOSE']) {
@@ -495,21 +508,25 @@ function processCoreBundleFormat(fileHeader: string, languages: Language[], json
statistics[language.id] = 0;
let localizedModules: Map<string[]> = Object.create(null);
let languageFolderName = language.folderName || language.id;
let cwd = path.join(languageDirectory, languageFolderName, 'src');
let languageFolderName = language.translationId || language.id;
let i18nFile = path.join(languageDirectory, `vscode-language-pack-${languageFolderName}`, 'translations', 'main.i18n.json');
let allMessages: I18nFormat | undefined;
if (fs.existsSync(i18nFile)) {
let content = stripComments(fs.readFileSync(i18nFile, 'utf8'));
allMessages = JSON.parse(content);
}
modules.forEach((module) => {
let order = keysSection[module];
let i18nFile = path.join(cwd, module) + '.i18n.json';
let messages: Map<string> | null = null;
if (fs.existsSync(i18nFile)) {
let content = stripComments(fs.readFileSync(i18nFile, 'utf8'));
messages = JSON.parse(content);
} else {
let moduleMessage: { [messageKey: string]: string } | undefined;
if (allMessages) {
moduleMessage = allMessages.contents[module];
}
if (!moduleMessage) {
if (process.env['VSCODE_BUILD_VERBOSE']) {
log(`No localized messages found for module ${module}. Using default messages.`);
}
messages = defaultMessages[module];
statistics[language.id] = statistics[language.id] + Object.keys(messages).length;
moduleMessage = defaultMessages[module];
statistics[language.id] = statistics[language.id] + Object.keys(moduleMessage).length;
}
let localizedMessages: string[] = [];
order.forEach((keyInfo) => {
@@ -519,7 +536,7 @@ function processCoreBundleFormat(fileHeader: string, languages: Language[], json
} else {
key = keyInfo.key;
}
let message: string = messages![key];
let message: string = moduleMessage![key];
if (!message) {
if (process.env['VSCODE_BUILD_VERBOSE']) {
log(`No localized message found for key ${key} in module ${module}. Using default message.`);
@@ -605,7 +622,7 @@ export function getResource(sourceFile: string): Resource {
return { name: 'vs/base', project: editorProject };
} else if (/^vs\/code/.test(sourceFile)) {
return { name: 'vs/code', project: workbenchProject };
} else if (/^vs\/workbench\/parts/.test(sourceFile)) {
} else if (/^vs\/workbench\/contrib/.test(sourceFile)) {
resource = sourceFile.split('/', 4).join('/');
return { name: resource, project: workbenchProject };
} else if (/^vs\/workbench\/services/.test(sourceFile)) {
@@ -692,7 +709,7 @@ export function createXlfFilesForExtensions(): ThroughStream {
}
return _xlf;
}
gulp.src([`./extensions/${extensionName}/package.nls.json`, `./extensions/${extensionName}/**/nls.metadata.json`]).pipe(through(function (file: File) {
gulp.src([`./extensions/${extensionName}/package.nls.json`, `./extensions/${extensionName}/**/nls.metadata.json`], { allowEmpty: true }).pipe(through(function (file: File) {
if (file.isBuffer()) {
const buffer: Buffer = file.contents as Buffer;
const basename = path.basename(file.path);
@@ -1093,7 +1110,7 @@ function retrieveResource(language: Language, resource: Resource, apiHostname: s
return limiter.queue(() => new Promise<File | null>((resolve, reject) => {
const slug = resource.name.replace(/\//g, '_');
const project = resource.project;
let transifexLanguageId = language.id === 'ps' ? 'en' : language.transifexId || language.id;
let transifexLanguageId = language.id === 'ps' ? 'en' : language.translationId || language.id;
const options = {
hostname: apiHostname,
path: `/api/2/project/${project}/resource/${slug}/translation/${transifexLanguageId}?file&mode=onlyreviewed`,
@@ -1194,7 +1211,7 @@ export function prepareI18nPackFiles(externalExtensions: Map<string>, resultingT
let extensionsPacks: Map<I18nPack> = {};
let errors: any[] = [];
return through(function (this: ThroughStream, xlf: File) {
let project = path.dirname(xlf.relative);
let project = path.basename(path.dirname(xlf.relative));
let resource = path.basename(xlf.relative, '.xlf');
let contents = xlf.contents.toString();
let parsePromise = pseudo ? XLF.parsePseudo(contents) : XLF.parse(contents);
@@ -1361,4 +1378,4 @@ function decodeEntities(value: string): string {
function pseudify(message: string) {
return '\uFF3B' + message.replace(/[aouei]/g, '$&$&') + '\uFF3D';
}
}

View File

@@ -13,7 +13,8 @@ const flatmap = require("gulp-flatmap");
const sourcemaps = require("gulp-sourcemaps");
const uglify = require("gulp-uglify");
const composer = require("gulp-uglify/composer");
const gulpUtil = require("gulp-util");
const fancyLog = require("fancy-log");
const ansiColors = require("ansi-colors");
const path = require("path");
const pump = require("pump");
const uglifyes = require("uglify-es");
@@ -24,7 +25,7 @@ const stats_1 = require("./stats");
const util = require("./util");
const REPO_ROOT_PATH = path.join(__dirname, '../..');
function log(prefix, message) {
gulpUtil.log(gulpUtil.colors.cyan('[' + prefix + ']'), message);
fancyLog(ansiColors.cyan('[' + prefix + ']'), message);
}
// {{SQL CARBON EDIT}}
function loaderConfig(emptyPaths) {
@@ -115,7 +116,6 @@ function toBundleStream(src, bundledFileHeader, bundles) {
function optimizeTask(opts) {
const src = opts.src;
const entryPoints = opts.entryPoints;
const otherSources = opts.otherSources;
const resources = opts.resources;
const loaderConfig = opts.loaderConfig;
const bundledFileHeader = opts.header;
@@ -138,7 +138,7 @@ function optimizeTask(opts) {
}
filteredResources.push('!' + resource);
});
gulp.src(filteredResources, { base: `${src}` }).pipe(resourcesStream);
gulp.src(filteredResources, { base: `${src}`, allowEmpty: true }).pipe(resourcesStream);
const bundleInfoArray = [];
if (opts.bundleInfo) {
bundleInfoArray.push(new VinylFile({
@@ -149,20 +149,7 @@ function optimizeTask(opts) {
}
es.readArray(bundleInfoArray).pipe(bundleInfoStream);
});
const otherSourcesStream = es.through();
const otherSourcesStreamArr = [];
gulp.src(otherSources, { base: `${src}` })
.pipe(es.through(function (data) {
otherSourcesStreamArr.push(toConcatStream(src, bundledFileHeader, [data], data.relative));
}, function () {
if (!otherSourcesStreamArr.length) {
setTimeout(function () { otherSourcesStream.emit('end'); }, 0);
}
else {
es.merge(otherSourcesStreamArr).pipe(otherSourcesStream);
}
}));
const result = es.merge(loader(src, bundledFileHeader, bundleLoader), bundlesStream, otherSourcesStream, resourcesStream, bundleInfoStream);
const result = es.merge(loader(src, bundledFileHeader, bundleLoader), bundlesStream, resourcesStream, bundleInfoStream);
return result
.pipe(sourcemaps.write('./', {
sourceRoot: undefined,
@@ -225,7 +212,12 @@ function minifyTask(src, sourceMapBaseUrl) {
return cb => {
const jsFilter = filter('**/*.js', { restore: true });
const cssFilter = filter('**/*.css', { restore: true });
pump(gulp.src([src + '/**', '!' + src + '/**/*.map']), jsFilter, sourcemaps.init({ loadMaps: true }), uglifyWithCopyrights(), jsFilter.restore, cssFilter, minifyCSS({ reduceIdents: false }), cssFilter.restore, sourcemaps.write('./', {
pump(gulp.src([src + '/**', '!' + src + '/**/*.map']), jsFilter, sourcemaps.init({ loadMaps: true }), uglifyWithCopyrights(), jsFilter.restore, cssFilter, minifyCSS({ reduceIdents: false }), cssFilter.restore, sourcemaps.mapSources((sourcePath) => {
if (sourcePath === 'bootstrap-fork.js') {
return 'bootstrap-fork.orig.js';
}
return sourcePath;
}), sourcemaps.write('./', {
sourceMappingURL,
sourceRoot: undefined,
includeContent: true,

View File

@@ -14,7 +14,8 @@ import * as flatmap from 'gulp-flatmap';
import * as sourcemaps from 'gulp-sourcemaps';
import * as uglify from 'gulp-uglify';
import * as composer from 'gulp-uglify/composer';
import * as gulpUtil from 'gulp-util';
import * as fancyLog from 'fancy-log';
import * as ansiColors from 'ansi-colors';
import * as path from 'path';
import * as pump from 'pump';
import * as sm from 'source-map';
@@ -28,7 +29,7 @@ import * as util from './util';
const REPO_ROOT_PATH = path.join(__dirname, '../..');
function log(prefix: string, message: string): void {
gulpUtil.log(gulpUtil.colors.cyan('[' + prefix + ']'), message);
fancyLog(ansiColors.cyan('[' + prefix + ']'), message);
}
// {{SQL CARBON EDIT}}
@@ -143,10 +144,6 @@ export interface IOptimizeTaskOpts {
* (for AMD files, will get bundled and get Copyright treatment)
*/
entryPoints: bundle.IEntryPoint[];
/**
* (for non-AMD files that should get Copyright treatment)
*/
otherSources: string[];
/**
* (svg, etc.)
*/
@@ -177,7 +174,6 @@ export interface IOptimizeTaskOpts {
export function optimizeTask(opts: IOptimizeTaskOpts): () => NodeJS.ReadWriteStream {
const src = opts.src;
const entryPoints = opts.entryPoints;
const otherSources = opts.otherSources;
const resources = opts.resources;
const loaderConfig = opts.loaderConfig;
const bundledFileHeader = opts.header;
@@ -202,7 +198,7 @@ export function optimizeTask(opts: IOptimizeTaskOpts): () => NodeJS.ReadWriteStr
}
filteredResources.push('!' + resource);
});
gulp.src(filteredResources, { base: `${src}` }).pipe(resourcesStream);
gulp.src(filteredResources, { base: `${src}`, allowEmpty: true }).pipe(resourcesStream);
const bundleInfoArray: VinylFile[] = [];
if (opts.bundleInfo) {
@@ -215,24 +211,9 @@ export function optimizeTask(opts: IOptimizeTaskOpts): () => NodeJS.ReadWriteStr
es.readArray(bundleInfoArray).pipe(bundleInfoStream);
});
const otherSourcesStream = es.through();
const otherSourcesStreamArr: NodeJS.ReadWriteStream[] = [];
gulp.src(otherSources, { base: `${src}` })
.pipe(es.through(function (data) {
otherSourcesStreamArr.push(toConcatStream(src, bundledFileHeader, [data], data.relative));
}, function () {
if (!otherSourcesStreamArr.length) {
setTimeout(function () { otherSourcesStream.emit('end'); }, 0);
} else {
es.merge(otherSourcesStreamArr).pipe(otherSourcesStream);
}
}));
const result = es.merge(
loader(src, bundledFileHeader, bundleLoader),
bundlesStream,
otherSourcesStream,
resourcesStream,
bundleInfoStream
);
@@ -319,6 +300,13 @@ export function minifyTask(src: string, sourceMapBaseUrl?: string): (cb: any) =>
cssFilter,
minifyCSS({ reduceIdents: false }),
cssFilter.restore,
(<any>sourcemaps).mapSources((sourcePath: string) => {
if (sourcePath === 'bootstrap-fork.js') {
return 'bootstrap-fork.orig.js';
}
return sourcePath;
}),
sourcemaps.write('./', {
sourceMappingURL,
sourceRoot: undefined,

View File

@@ -6,7 +6,8 @@
Object.defineProperty(exports, "__esModule", { value: true });
const es = require("event-stream");
const _ = require("underscore");
const util = require("gulp-util");
const fancyLog = require("fancy-log");
const ansiColors = require("ansi-colors");
const fs = require("fs");
const path = require("path");
const allErrors = [];
@@ -17,7 +18,7 @@ function onStart() {
return;
}
startTime = new Date().getTime();
util.log(`Starting ${util.colors.green('compilation')}...`);
fancyLog(`Starting ${ansiColors.green('compilation')}...`);
}
function onEnd() {
if (--count > 0) {
@@ -38,7 +39,7 @@ function log() {
errors.map(err => {
if (!seen.has(err)) {
seen.add(err);
util.log(`${util.colors.red('Error')}: ${err}`);
fancyLog(`${ansiColors.red('Error')}: ${err}`);
}
});
const regex = /^([^(]+)\((\d+),(\d+)\): (.*)$/;
@@ -53,7 +54,7 @@ function log() {
catch (err) {
//noop
}
util.log(`Finished ${util.colors.green('compilation')} with ${errors.length} errors after ${util.colors.magenta((new Date().getTime() - startTime) + ' ms')}`);
fancyLog(`Finished ${ansiColors.green('compilation')} with ${errors.length} errors after ${ansiColors.magenta((new Date().getTime() - startTime) + ' ms')}`);
}
function createReporter() {
const errors = [];

View File

@@ -7,7 +7,8 @@
import * as es from 'event-stream';
import * as _ from 'underscore';
import * as util from 'gulp-util';
import * as fancyLog from 'fancy-log';
import * as ansiColors from 'ansi-colors';
import * as fs from 'fs';
import * as path from 'path';
@@ -21,7 +22,7 @@ function onStart(): void {
}
startTime = new Date().getTime();
util.log(`Starting ${util.colors.green('compilation')}...`);
fancyLog(`Starting ${ansiColors.green('compilation')}...`);
}
function onEnd(): void {
@@ -47,7 +48,7 @@ function log(): void {
errors.map(err => {
if (!seen.has(err)) {
seen.add(err);
util.log(`${util.colors.red('Error')}: ${err}`);
fancyLog(`${ansiColors.red('Error')}: ${err}`);
}
});
@@ -65,7 +66,7 @@ function log(): void {
//noop
}
util.log(`Finished ${util.colors.green('compilation')} with ${errors.length} errors after ${util.colors.magenta((new Date().getTime() - startTime!) + ' ms')}`);
fancyLog(`Finished ${ansiColors.green('compilation')} with ${errors.length} errors after ${ansiColors.magenta((new Date().getTime() - startTime!) + ' ms')}`);
}
export interface IReporter {

View File

@@ -27,7 +27,7 @@ function writeFile(filePath, contents) {
fs.writeFileSync(filePath, contents);
}
function extractEditor(options) {
const tsConfig = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.json')).toString());
const tsConfig = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.monaco.json')).toString());
let compilerOptions;
if (tsConfig.extends) {
compilerOptions = Object.assign({}, require(path.join(options.sourcesRoot, tsConfig.extends)).compilerOptions, tsConfig.compilerOptions);
@@ -36,13 +36,11 @@ function extractEditor(options) {
compilerOptions = tsConfig.compilerOptions;
}
tsConfig.compilerOptions = compilerOptions;
compilerOptions.noEmit = false;
compilerOptions.noUnusedLocals = false;
compilerOptions.preserveConstEnums = false;
compilerOptions.declaration = false;
compilerOptions.moduleResolution = ts.ModuleResolutionKind.Classic;
delete compilerOptions.types;
delete tsConfig.extends;
tsConfig.exclude = [];
options.compilerOptions = compilerOptions;
let result = tss.shake(options);
for (let fileName in result) {

View File

@@ -31,7 +31,7 @@ function writeFile(filePath: string, contents: Buffer | string): void {
}
export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: string }): void {
const tsConfig = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.json')).toString());
const tsConfig = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.monaco.json')).toString());
let compilerOptions: { [key: string]: any };
if (tsConfig.extends) {
compilerOptions = Object.assign({}, require(path.join(options.sourcesRoot, tsConfig.extends)).compilerOptions, tsConfig.compilerOptions);
@@ -40,14 +40,12 @@ export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: str
}
tsConfig.compilerOptions = compilerOptions;
compilerOptions.noEmit = false;
compilerOptions.noUnusedLocals = false;
compilerOptions.preserveConstEnums = false;
compilerOptions.declaration = false;
compilerOptions.moduleResolution = ts.ModuleResolutionKind.Classic;
delete compilerOptions.types;
delete tsConfig.extends;
tsConfig.exclude = [];
options.compilerOptions = compilerOptions;

View File

@@ -5,7 +5,8 @@
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const es = require("event-stream");
const util = require("gulp-util");
const fancyLog = require("fancy-log");
const ansiColors = require("ansi-colors");
const appInsights = require("applicationinsights");
class Entry {
constructor(name, totalCount, totalSize) {
@@ -24,13 +25,13 @@ class Entry {
}
else {
if (this.totalCount === 1) {
return `Stats for '${util.colors.grey(this.name)}': ${Math.round(this.totalSize / 1204)}KB`;
return `Stats for '${ansiColors.grey(this.name)}': ${Math.round(this.totalSize / 1204)}KB`;
}
else {
const count = this.totalCount < 100
? util.colors.green(this.totalCount.toString())
: util.colors.red(this.totalCount.toString());
return `Stats for '${util.colors.grey(this.name)}': ${count} files, ${Math.round(this.totalSize / 1204)}KB`;
? ansiColors.green(this.totalCount.toString())
: ansiColors.red(this.totalCount.toString());
return `Stats for '${ansiColors.grey(this.name)}': ${count} files, ${Math.round(this.totalSize / 1204)}KB`;
}
}
}
@@ -57,13 +58,13 @@ function createStatsStream(group, log) {
}, function () {
if (log) {
if (entry.totalCount === 1) {
util.log(`Stats for '${util.colors.grey(entry.name)}': ${Math.round(entry.totalSize / 1204)}KB`);
fancyLog(`Stats for '${ansiColors.grey(entry.name)}': ${Math.round(entry.totalSize / 1204)}KB`);
}
else {
const count = entry.totalCount < 100
? util.colors.green(entry.totalCount.toString())
: util.colors.red(entry.totalCount.toString());
util.log(`Stats for '${util.colors.grey(entry.name)}': ${count} files, ${Math.round(entry.totalSize / 1204)}KB`);
? ansiColors.green(entry.totalCount.toString())
: ansiColors.red(entry.totalCount.toString());
fancyLog(`Stats for '${ansiColors.grey(entry.name)}': ${count} files, ${Math.round(entry.totalSize / 1204)}KB`);
}
}
this.emit('end');

View File

@@ -6,7 +6,8 @@
'use strict';
import * as es from 'event-stream';
import * as util from 'gulp-util';
import * as fancyLog from 'fancy-log';
import * as ansiColors from 'ansi-colors';
import * as File from 'vinyl';
import * as appInsights from 'applicationinsights';
@@ -22,14 +23,14 @@ class Entry {
}
} else {
if (this.totalCount === 1) {
return `Stats for '${util.colors.grey(this.name)}': ${Math.round(this.totalSize / 1204)}KB`;
return `Stats for '${ansiColors.grey(this.name)}': ${Math.round(this.totalSize / 1204)}KB`;
} else {
const count = this.totalCount < 100
? util.colors.green(this.totalCount.toString())
: util.colors.red(this.totalCount.toString());
? ansiColors.green(this.totalCount.toString())
: ansiColors.red(this.totalCount.toString());
return `Stats for '${util.colors.grey(this.name)}': ${count} files, ${Math.round(this.totalSize / 1204)}KB`;
return `Stats for '${ansiColors.grey(this.name)}': ${count} files, ${Math.round(this.totalSize / 1204)}KB`;
}
}
}
@@ -58,14 +59,14 @@ export function createStatsStream(group: string, log?: boolean): es.ThroughStrea
}, function () {
if (log) {
if (entry.totalCount === 1) {
util.log(`Stats for '${util.colors.grey(entry.name)}': ${Math.round(entry.totalSize / 1204)}KB`);
fancyLog(`Stats for '${ansiColors.grey(entry.name)}': ${Math.round(entry.totalSize / 1204)}KB`);
} else {
const count = entry.totalCount < 100
? util.colors.green(entry.totalCount.toString())
: util.colors.red(entry.totalCount.toString());
? ansiColors.green(entry.totalCount.toString())
: ansiColors.red(entry.totalCount.toString());
util.log(`Stats for '${util.colors.grey(entry.name)}': ${count} files, ${Math.round(entry.totalSize / 1204)}KB`);
fancyLog(`Stats for '${ansiColors.grey(entry.name)}': ${count} files, ${Math.round(entry.totalSize / 1204)}KB`);
}
}

96
build/lib/task.js Normal file
View File

@@ -0,0 +1,96 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const fancyLog = require("fancy-log");
const ansiColors = require("ansi-colors");
function _isPromise(p) {
if (typeof p.then === 'function') {
return true;
}
return false;
}
function _renderTime(time) {
return `${Math.round(time)} ms`;
}
async function _execute(task) {
const name = task.taskName || task.displayName || `<anonymous>`;
if (!task._tasks) {
fancyLog('Starting', ansiColors.cyan(name), '...');
}
const startTime = process.hrtime();
await _doExecute(task);
const elapsedArr = process.hrtime(startTime);
const elapsedNanoseconds = (elapsedArr[0] * 1e9 + elapsedArr[1]);
if (!task._tasks) {
fancyLog(`Finished`, ansiColors.cyan(name), 'after', ansiColors.magenta(_renderTime(elapsedNanoseconds / 1e6)));
}
}
async function _doExecute(task) {
// Always invoke as if it were a callback task
return new Promise((resolve, reject) => {
if (task.length === 1) {
// this is a callback task
task((err) => {
if (err) {
return reject(err);
}
resolve();
});
return;
}
const taskResult = task();
if (typeof taskResult === 'undefined') {
// this is a sync task
resolve();
return;
}
if (_isPromise(taskResult)) {
// this is a promise returning task
taskResult.then(resolve, reject);
return;
}
// this is a stream returning task
taskResult.on('end', _ => resolve());
taskResult.on('error', err => reject(err));
});
}
function series(...tasks) {
const result = async () => {
for (let i = 0; i < tasks.length; i++) {
await _execute(tasks[i]);
}
};
result._tasks = tasks;
return result;
}
exports.series = series;
function parallel(...tasks) {
const result = async () => {
await Promise.all(tasks.map(t => _execute(t)));
};
result._tasks = tasks;
return result;
}
exports.parallel = parallel;
function define(name, task) {
if (task._tasks) {
// This is a composite task
const lastTask = task._tasks[task._tasks.length - 1];
if (lastTask._tasks || lastTask.taskName) {
// This is a composite task without a real task function
// => generate a fake task function
return define(name, series(task, () => Promise.resolve()));
}
lastTask.taskName = name;
task.displayName = name;
return task;
}
// This is a simple task
task.taskName = name;
task.displayName = name;
return task;
}
exports.define = define;

125
build/lib/task.ts Normal file
View File

@@ -0,0 +1,125 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as fancyLog from 'fancy-log';
import * as ansiColors from 'ansi-colors';
export interface BaseTask {
displayName?: string;
taskName?: string;
_tasks?: Task[];
}
export interface PromiseTask extends BaseTask {
(): Promise<void>;
}
export interface StreamTask extends BaseTask {
(): NodeJS.ReadWriteStream;
}
export interface CallbackTask extends BaseTask {
(cb?: (err?: any) => void): void;
}
export type Task = PromiseTask | StreamTask | CallbackTask;
function _isPromise(p: Promise<void> | NodeJS.ReadWriteStream): p is Promise<void> {
if (typeof (<any>p).then === 'function') {
return true;
}
return false;
}
function _renderTime(time: number): string {
return `${Math.round(time)} ms`;
}
async function _execute(task: Task): Promise<void> {
const name = task.taskName || task.displayName || `<anonymous>`;
if (!task._tasks) {
fancyLog('Starting', ansiColors.cyan(name), '...');
}
const startTime = process.hrtime();
await _doExecute(task);
const elapsedArr = process.hrtime(startTime);
const elapsedNanoseconds = (elapsedArr[0] * 1e9 + elapsedArr[1]);
if (!task._tasks) {
fancyLog(`Finished`, ansiColors.cyan(name), 'after', ansiColors.magenta(_renderTime(elapsedNanoseconds / 1e6)));
}
}
async function _doExecute(task: Task): Promise<void> {
// Always invoke as if it were a callback task
return new Promise((resolve, reject) => {
if (task.length === 1) {
// this is a callback task
task((err) => {
if (err) {
return reject(err);
}
resolve();
});
return;
}
const taskResult = task();
if (typeof taskResult === 'undefined') {
// this is a sync task
resolve();
return;
}
if (_isPromise(taskResult)) {
// this is a promise returning task
taskResult.then(resolve, reject);
return;
}
// this is a stream returning task
taskResult.on('end', _ => resolve());
taskResult.on('error', err => reject(err));
});
}
export function series(...tasks: Task[]): PromiseTask {
const result = async () => {
for (let i = 0; i < tasks.length; i++) {
await _execute(tasks[i]);
}
};
result._tasks = tasks;
return result;
}
export function parallel(...tasks: Task[]): PromiseTask {
const result = async () => {
await Promise.all(tasks.map(t => _execute(t)));
};
result._tasks = tasks;
return result;
}
export function define(name: string, task: Task): Task {
if (task._tasks) {
// This is a composite task
const lastTask = task._tasks[task._tasks.length - 1];
if (lastTask._tasks || lastTask.taskName) {
// This is a composite task without a real task function
// => generate a fake task function
return define(name, series(task, () => Promise.resolve()));
}
lastTask.taskName = name;
task.displayName = name;
return task;
}
// This is a simple task
task.taskName = name;
task.displayName = name;
return task;
}

View File

@@ -27,13 +27,13 @@ suite('XLF Parser Tests', () => {
});
test('JSON file source path to Transifex resource match', () => {
const editorProject = 'vscode-editor', workbenchProject = 'vscode-workbench';
const platform = { name: 'vs/platform', project: editorProject }, editorContrib = { name: 'vs/editor/contrib', project: editorProject }, editor = { name: 'vs/editor', project: editorProject }, base = { name: 'vs/base', project: editorProject }, code = { name: 'vs/code', project: workbenchProject }, workbenchParts = { name: 'vs/workbench/parts/html', project: workbenchProject }, workbenchServices = { name: 'vs/workbench/services/files', project: workbenchProject }, workbench = { name: 'vs/workbench', project: workbenchProject };
const platform = { name: 'vs/platform', project: editorProject }, editorContrib = { name: 'vs/editor/contrib', project: editorProject }, editor = { name: 'vs/editor', project: editorProject }, base = { name: 'vs/base', project: editorProject }, code = { name: 'vs/code', project: workbenchProject }, workbenchParts = { name: 'vs/workbench/contrib/html', project: workbenchProject }, workbenchServices = { name: 'vs/workbench/services/files', project: workbenchProject }, workbench = { name: 'vs/workbench', project: workbenchProject };
assert.deepEqual(i18n.getResource('vs/platform/actions/browser/menusExtensionPoint'), platform);
assert.deepEqual(i18n.getResource('vs/editor/contrib/clipboard/browser/clipboard'), editorContrib);
assert.deepEqual(i18n.getResource('vs/editor/common/modes/modesRegistry'), editor);
assert.deepEqual(i18n.getResource('vs/base/common/errorMessage'), base);
assert.deepEqual(i18n.getResource('vs/code/electron-main/window'), code);
assert.deepEqual(i18n.getResource('vs/workbench/parts/html/browser/webview'), workbenchParts);
assert.deepEqual(i18n.getResource('vs/workbench/contrib/html/browser/webview'), workbenchParts);
assert.deepEqual(i18n.getResource('vs/workbench/services/files/node/fileService'), workbenchServices);
assert.deepEqual(i18n.getResource('vs/workbench/browser/parts/panel/panelActions'), workbench);
});

View File

@@ -38,7 +38,7 @@ suite('XLF Parser Tests', () => {
editor = { name: 'vs/editor', project: editorProject },
base = { name: 'vs/base', project: editorProject },
code = { name: 'vs/code', project: workbenchProject },
workbenchParts = { name: 'vs/workbench/parts/html', project: workbenchProject },
workbenchParts = { name: 'vs/workbench/contrib/html', project: workbenchProject },
workbenchServices = { name: 'vs/workbench/services/files', project: workbenchProject },
workbench = { name: 'vs/workbench', project: workbenchProject};
@@ -47,7 +47,7 @@ suite('XLF Parser Tests', () => {
assert.deepEqual(i18n.getResource('vs/editor/common/modes/modesRegistry'), editor);
assert.deepEqual(i18n.getResource('vs/base/common/errorMessage'), base);
assert.deepEqual(i18n.getResource('vs/code/electron-main/window'), code);
assert.deepEqual(i18n.getResource('vs/workbench/parts/html/browser/webview'), workbenchParts);
assert.deepEqual(i18n.getResource('vs/workbench/contrib/html/browser/webview'), workbenchParts);
assert.deepEqual(i18n.getResource('vs/workbench/services/files/node/fileService'), workbenchServices);
assert.deepEqual(i18n.getResource('vs/workbench/browser/parts/panel/panelActions'), workbench);
});

View File

@@ -0,0 +1,54 @@
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
const ts = require("typescript");
const Lint = require("tslint");
const path_1 = require("path");
class Rule extends Lint.Rules.AbstractRule {
apply(sourceFile) {
if (/vs(\/|\\)editor(\/|\\)standalone(\/|\\)/.test(sourceFile.fileName)
|| /vs(\/|\\)editor(\/|\\)common(\/|\\)standalone(\/|\\)/.test(sourceFile.fileName)
|| /vs(\/|\\)editor(\/|\\)editor.api/.test(sourceFile.fileName)
|| /vs(\/|\\)editor(\/|\\)editor.main/.test(sourceFile.fileName)
|| /vs(\/|\\)editor(\/|\\)editor.worker/.test(sourceFile.fileName)) {
return this.applyWithWalker(new NoNlsInStandaloneEditorRuleWalker(sourceFile, this.getOptions()));
}
return [];
}
}
exports.Rule = Rule;
class NoNlsInStandaloneEditorRuleWalker extends Lint.RuleWalker {
constructor(file, opts) {
super(file, opts);
}
visitImportEqualsDeclaration(node) {
if (node.moduleReference.kind === ts.SyntaxKind.ExternalModuleReference) {
this._validateImport(node.moduleReference.expression.getText(), node);
}
}
visitImportDeclaration(node) {
this._validateImport(node.moduleSpecifier.getText(), node);
}
visitCallExpression(node) {
super.visitCallExpression(node);
// import('foo') statements inside the code
if (node.expression.kind === ts.SyntaxKind.ImportKeyword) {
const [path] = node.arguments;
this._validateImport(path.getText(), node);
}
}
_validateImport(path, node) {
// remove quotes
path = path.slice(1, -1);
// resolve relative paths
if (path[0] === '.') {
path = path_1.join(this.getSourceFile().fileName, path);
}
if (/vs(\/|\\)nls/.test(path)) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), `Not allowed to import vs/nls in standalone editor modules. Use standaloneStrings.ts`));
}
}
}

View File

@@ -0,0 +1,67 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as ts from 'typescript';
import * as Lint from 'tslint';
import { join } from 'path';
export class Rule extends Lint.Rules.AbstractRule {
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
if (
/vs(\/|\\)editor(\/|\\)standalone(\/|\\)/.test(sourceFile.fileName)
|| /vs(\/|\\)editor(\/|\\)common(\/|\\)standalone(\/|\\)/.test(sourceFile.fileName)
|| /vs(\/|\\)editor(\/|\\)editor.api/.test(sourceFile.fileName)
|| /vs(\/|\\)editor(\/|\\)editor.main/.test(sourceFile.fileName)
|| /vs(\/|\\)editor(\/|\\)editor.worker/.test(sourceFile.fileName)
) {
return this.applyWithWalker(new NoNlsInStandaloneEditorRuleWalker(sourceFile, this.getOptions()));
}
return [];
}
}
class NoNlsInStandaloneEditorRuleWalker extends Lint.RuleWalker {
constructor(file: ts.SourceFile, opts: Lint.IOptions) {
super(file, opts);
}
protected visitImportEqualsDeclaration(node: ts.ImportEqualsDeclaration): void {
if (node.moduleReference.kind === ts.SyntaxKind.ExternalModuleReference) {
this._validateImport(node.moduleReference.expression.getText(), node);
}
}
protected visitImportDeclaration(node: ts.ImportDeclaration): void {
this._validateImport(node.moduleSpecifier.getText(), node);
}
protected visitCallExpression(node: ts.CallExpression): void {
super.visitCallExpression(node);
// import('foo') statements inside the code
if (node.expression.kind === ts.SyntaxKind.ImportKeyword) {
const [path] = node.arguments;
this._validateImport(path.getText(), node);
}
}
private _validateImport(path: string, node: ts.Node): void {
// remove quotes
path = path.slice(1, -1);
// resolve relative paths
if (path[0] === '.') {
path = join(this.getSourceFile().fileName, path);
}
if (
/vs(\/|\\)nls/.test(path)
) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), `Not allowed to import vs/nls in standalone editor modules. Use standaloneStrings.ts`));
}
}
}

View File

@@ -45,8 +45,8 @@ class NoStandaloneEditorRuleWalker extends Lint.RuleWalker {
if (path[0] === '.') {
path = path_1.join(this.getSourceFile().fileName, path);
}
if (/vs(\/|\\)editor(\/|\\)standalone/.test(path)
|| /vs(\/|\\)editor(\/|\\)common(\/|\\)standalone/.test(path)
if (/vs(\/|\\)editor(\/|\\)standalone(\/|\\)/.test(path)
|| /vs(\/|\\)editor(\/|\\)common(\/|\\)standalone(\/|\\)/.test(path)
|| /vs(\/|\\)editor(\/|\\)editor.api/.test(path)
|| /vs(\/|\\)editor(\/|\\)editor.main/.test(path)
|| /vs(\/|\\)editor(\/|\\)editor.worker/.test(path)) {

View File

@@ -54,8 +54,8 @@ class NoStandaloneEditorRuleWalker extends Lint.RuleWalker {
}
if (
/vs(\/|\\)editor(\/|\\)standalone/.test(path)
|| /vs(\/|\\)editor(\/|\\)common(\/|\\)standalone/.test(path)
/vs(\/|\\)editor(\/|\\)standalone(\/|\\)/.test(path)
|| /vs(\/|\\)editor(\/|\\)common(\/|\\)standalone(\/|\\)/.test(path)
|| /vs(\/|\\)editor(\/|\\)editor.api/.test(path)
|| /vs(\/|\\)editor(\/|\\)editor.main/.test(path)
|| /vs(\/|\\)editor(\/|\\)editor.worker/.test(path)

View File

@@ -33,7 +33,7 @@ class TranslationRemindRuleWalker extends Lint.RuleWalker {
visitImportLikeDeclaration(node) {
const currentFile = node.getSourceFile().fileName;
const matchService = currentFile.match(/vs\/workbench\/services\/\w+/);
const matchPart = currentFile.match(/vs\/workbench\/parts\/\w+/);
const matchPart = currentFile.match(/vs\/workbench\/contrib\/\w+/);
if (!matchService && !matchPart) {
return;
}

View File

@@ -42,7 +42,7 @@ class TranslationRemindRuleWalker extends Lint.RuleWalker {
private visitImportLikeDeclaration(node: ts.ImportDeclaration | ts.ImportEqualsDeclaration) {
const currentFile = node.getSourceFile().fileName;
const matchService = currentFile.match(/vs\/workbench\/services\/\w+/);
const matchPart = currentFile.match(/vs\/workbench\/parts\/\w+/);
const matchPart = currentFile.match(/vs\/workbench\/contrib\/\w+/);
if (!matchService && !matchPart) {
return;
}

View File

@@ -14,6 +14,8 @@ const fs = require("fs");
const _rimraf = require("rimraf");
const git = require("./git");
const VinylFile = require("vinyl");
const download_1 = require("../download/download");
const REPO_ROOT = path.join(__dirname, '../../');
const NoCancellationToken = { isCancellationRequested: () => false };
function incremental(streamProvider, initial, supportsCancellation) {
const input = es.through();
@@ -180,7 +182,8 @@ function rimraf(dir) {
return cb(err);
});
};
return cb => retry(cb);
retry.taskName = `clean-${path.basename(dir)}`;
return retry;
}
exports.rimraf = rimraf;
function getVersion(root) {
@@ -220,3 +223,38 @@ function versionStringToNumber(versionStr) {
return parseInt(match[1], 10) * 1e4 + parseInt(match[2], 10) * 1e2 + parseInt(match[3], 10);
}
exports.versionStringToNumber = versionStringToNumber;
function download(requestOptions) {
const result = es.through();
const filename = path.join(REPO_ROOT, `.build/tmp-${Date.now()}-${path.posix.basename(requestOptions.path)}`);
const opts = {
requestOptions: requestOptions,
destinationPath: filename
};
download_1.downloadInExternalProcess(opts).then(() => {
fs.stat(filename, (err, stat) => {
if (err) {
result.emit('error', err);
return;
}
fs.readFile(filename, (err, data) => {
if (err) {
result.emit('error', err);
return;
}
fs.unlink(filename, () => {
result.emit('data', new VinylFile({
path: path.normalize(requestOptions.path),
stat: stat,
base: path.normalize(requestOptions.path),
contents: data
}));
result.emit('end');
});
});
});
}, (err) => {
result.emit('error', err);
});
return result;
}
exports.download = download;

View File

@@ -17,6 +17,9 @@ import * as git from './git';
import * as VinylFile from 'vinyl';
import { ThroughStream } from 'through';
import * as sm from 'source-map';
import { IDownloadOptions, downloadInExternalProcess, IDownloadRequestOptions } from '../download/download';
const REPO_ROOT = path.join(__dirname, '../../');
export interface ICancellationToken {
isCancellationRequested(): boolean;
@@ -233,8 +236,8 @@ export function rimraf(dir: string): (cb: any) => void {
return cb(err);
});
};
return cb => retry(cb);
retry.taskName = `clean-${path.basename(dir)}`;
return retry;
}
export function getVersion(root: string): string | undefined {
@@ -280,3 +283,38 @@ export function versionStringToNumber(versionStr: string) {
return parseInt(match[1], 10) * 1e4 + parseInt(match[2], 10) * 1e2 + parseInt(match[3], 10);
}
export function download(requestOptions: IDownloadRequestOptions): NodeJS.ReadWriteStream {
const result = es.through();
const filename = path.join(REPO_ROOT, `.build/tmp-${Date.now()}-${path.posix.basename(requestOptions.path)}`);
const opts: IDownloadOptions = {
requestOptions: requestOptions,
destinationPath: filename
};
downloadInExternalProcess(opts).then(() => {
fs.stat(filename, (err, stat) => {
if (err) {
result.emit('error', err);
return;
}
fs.readFile(filename, (err, data) => {
if (err) {
result.emit('error', err);
return;
}
fs.unlink(filename, () => {
result.emit('data', new VinylFile({
path: path.normalize(requestOptions.path),
stat: stat,
base: path.normalize(requestOptions.path),
contents: data
}));
result.emit('end');
});
});
});
}, (err) => {
result.emit('error', err);
});
return result;
}

View File

@@ -7,6 +7,31 @@ herein, whether by implication, estoppel or otherwise.
%% nodejs path library (https://github.com/nodejs/node/tree/43dd49c9782848c25e5b03448c8a0f923f13c158)
=========================================
Copyright Joyent, Inc. and other Node contributors.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
=========================================
END OF nodejs path library NOTICES AND INFORMATION
%% promise-polyfill version 8.1.0 (https://github.com/taylorhakes/promise-polyfill)
=========================================

View File

@@ -7,14 +7,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
const fs = require("fs");
const ts = require("typescript");
const path = require("path");
const util = require("gulp-util");
const fancyLog = require("fancy-log");
const ansiColors = require("ansi-colors");
const dtsv = '2';
const tsfmt = require('../../tsfmt.json');
const SRC = path.join(__dirname, '../../src');
exports.RECIPE_PATH = path.join(__dirname, './monaco.d.ts.recipe');
const DECLARATION_PATH = path.join(__dirname, '../../src/vs/monaco.d.ts');
function logErr(message, ...rest) {
util.log(util.colors.yellow(`[monaco.d.ts]`), message, ...rest);
fancyLog(ansiColors.yellow(`[monaco.d.ts]`), message, ...rest);
}
function isDeclaration(a) {
return (a.kind === ts.SyntaxKind.InterfaceDeclaration

View File

@@ -6,7 +6,8 @@
import * as fs from 'fs';
import * as ts from 'typescript';
import * as path from 'path';
import * as util from 'gulp-util';
import * as fancyLog from 'fancy-log';
import * as ansiColors from 'ansi-colors';
const dtsv = '2';
@@ -17,7 +18,7 @@ export const RECIPE_PATH = path.join(__dirname, './monaco.d.ts.recipe');
const DECLARATION_PATH = path.join(__dirname, '../../src/vs/monaco.d.ts');
function logErr(message: any, ...rest: any[]): void {
util.log(util.colors.yellow(`[monaco.d.ts]`), message, ...rest);
fancyLog(ansiColors.yellow(`[monaco.d.ts]`), message, ...rest);
}
type SourceFileGetter = (moduleId: string) => ts.SourceFile | null;

View File

@@ -10,8 +10,10 @@ import { CountBadge } from './vs/base/browser/ui/countBadge/countBadge';
import { SimpleWorkerClient, create as create1 } from './vs/base/common/worker/simpleWorker';
import { create as create2 } from './vs/editor/common/services/editorSimpleWorker';
import { QuickOpenWidget } from './vs/base/parts/quickopen/browser/quickOpenWidget';
import { WorkbenchAsyncDataTree } from './vs/platform/list/browser/listService';
import { SyncDescriptor0, SyncDescriptor1, SyncDescriptor2, SyncDescriptor3, SyncDescriptor4, SyncDescriptor5, SyncDescriptor6, SyncDescriptor7, SyncDescriptor8 } from './vs/platform/instantiation/common/descriptors';
import { DiffNavigator } from './vs/editor/browser/widget/diffNavigator';
import { DocumentRangeFormattingEditProvider } from './vs/editor/common/modes';
import * as editorAPI from './vs/editor/editor.api';
(function () {
@@ -22,6 +24,7 @@ import * as editorAPI from './vs/editor/editor.api';
a = (<IWorkspaceContextService>b).getWorkspace; // IWorkspaceFolderProvider
a = (<CountBadge>b).style; // IThemable
a = (<QuickOpenWidget>b).style; // IThemable
a = (<WorkbenchAsyncDataTree<any,any>>b).style; // IThemable
a = (<IEnvironmentService>b).userHome; // IUserHomeProvider
a = (<DiffNavigator>b).previous; // IDiffNavigator
a = (<ServiceIdentifier<any>>b).type;
@@ -30,6 +33,7 @@ import * as editorAPI from './vs/editor/editor.api';
a = (<SimpleWorkerClient<any>>b).getProxyObject; // IWorkerClient
a = create1;
a = create2;
a = (<DocumentRangeFormattingEditProvider>b).extensionId;
// injection madness
a = (<SyncDescriptor0<any>>b).ctor;

View File

@@ -1,7 +1,7 @@
{
"name": "monaco-editor-core",
"private": true,
"version": "0.14.3",
"version": "0.16.0",
"description": "A browser based code editor",
"author": "Microsoft Corporation",
"license": "MIT",

View File

@@ -17,8 +17,17 @@ function yarnInstall(location, opts) {
opts.cwd = location;
opts.stdio = 'inherit';
const raw = process.env['npm_config_argv'] || '{}';
const argv = JSON.parse(raw);
const original = argv.original || [];
const args = ['install'];
if (original.indexOf('--ignore-optional') > -1) {
args.push('--ignore-optional');
}
console.log('Installing dependencies in \'%s\'.', location);
const result = cp.spawnSync(yarn, ['install'], opts);
const result = cp.spawnSync(yarn, args, opts);
if (result.error || result.status !== 0) {
process.exit(1);

View File

@@ -12,6 +12,8 @@ var cson = require('cson-parser');
var https = require('https');
var url = require('url');
let commitDate = '0000-00-00';
/**
* @param {string} urlString
*/
@@ -120,30 +122,35 @@ exports.update = function (repoId, repoPath, dest, modifyGrammar, version = 'mas
try {
fs.writeFileSync(dest, JSON.stringify(result, null, '\t').replace(/\n/g, '\r\n'));
// Add commit sha to cgmanifest
let cgmanifestRead = JSON.parse(fs.readFileSync('./cgmanifest.json').toString());
let promises = new Array();
let packageJsonPath = 'https://raw.githubusercontent.com/' + repoId + `/${info.commitSha}/package.json`;
for (let i = 0; i < cgmanifestRead.registrations.length; i++) {
if (cgmanifestRead.registrations[i].component.git.repositoryUrl.substr(cgmanifestRead.registrations[i].component.git.repositoryUrl.length - repoId.length, repoId.length) === repoId) {
cgmanifestRead.registrations[i].component.git.commitHash = info.commitSha;
promises.push(download(packageJsonPath).then(function (packageJson) {
if (packageJson) {
try {
cgmanifestRead.registrations[i].version = JSON.parse(packageJson).version;
} catch (e) {
console.log('File does not exist at' + packageJsonPath);
}
}
}));
break;
const currentCommitDate = info.commitDate.substr(0, 10);
// Add commit sha to cgmanifest.
if (currentCommitDate > commitDate) {
let packageJsonPath = 'https://raw.githubusercontent.com/' + repoId + `/${info.commitSha}/package.json`;
for (let i = 0; i < cgmanifestRead.registrations.length; i++) {
if (cgmanifestRead.registrations[i].component.git.repositoryUrl.substr(cgmanifestRead.registrations[i].component.git.repositoryUrl.length - repoId.length, repoId.length) === repoId) {
cgmanifestRead.registrations[i].component.git.commitHash = info.commitSha;
commitDate = currentCommitDate;
promises.push(download(packageJsonPath).then(function (packageJson) {
if (packageJson) {
try {
cgmanifestRead.registrations[i].version = JSON.parse(packageJson).version;
} catch (e) {
console.log('Cannot get version. File does not exist at ' + packageJsonPath);
}
}
}));
break;
}
}
}
Promise.all(promises).then(function (allResult) {
fs.writeFileSync('./cgmanifest.json', JSON.stringify(cgmanifestRead, null, '\t').replace(/\n/g, '\r\n'));
});
if (info) {
console.log('Updated ' + path.basename(dest) + ' to ' + repoId + '@' + info.commitSha.substr(0, 7) + ' (' + info.commitDate.substr(0, 10) + ')');
console.log('Updated ' + path.basename(dest) + ' to ' + repoId + '@' + info.commitSha.substr(0, 7) + ' (' + currentCommitDate + ')');
} else {
console.log('Updated ' + path.basename(dest));
}

View File

@@ -74,7 +74,7 @@ function update(options) {
let translationPaths = [];
i18n.pullI18nPackFiles(server, userName, apiToken, { id: languageId }, translationPaths)
.on('error', (error) => {
console.log(`Error occured while importing translations:`);
console.log(`Error occurred while importing translations:`);
translationPaths = undefined;
if (Array.isArray(error)) {
error.forEach(console.log);
@@ -100,7 +100,7 @@ function update(options) {
gulp.src(path.join(location, languageId, '**', '*.xlf'))
.pipe(i18n.prepareI18nPackFiles(i18n.externalExtensionsWithTranslations, translationPaths, languageId === 'ps'))
.on('error', (error) => {
console.log(`Error occured while importing translations:`);
console.log(`Error occurred while importing translations:`);
translationPaths = undefined;
if (Array.isArray(error)) {
error.forEach(console.log);

View File

@@ -2,9 +2,11 @@
"name": "azuredatastudio-oss-dev-build",
"version": "1.0.0",
"devDependencies": {
"@types/ansi-colors": "^3.2.0",
"@types/azure": "0.9.19",
"@types/debounce": "^1.0.0",
"@types/documentdb": "1.10.2",
"@types/fancy-log": "^1.3.0",
"@types/glob": "^7.1.1",
"@types/gulp": "^4.0.5",
"@types/gulp-concat": "^0.0.32",
@@ -13,7 +15,6 @@
"@types/gulp-rename": "^0.0.33",
"@types/gulp-sourcemaps": "^0.0.32",
"@types/gulp-uglify": "^3.0.5",
"@types/gulp-util": "^3.0.34",
"@types/mime": "0.0.29",
"@types/minimatch": "^3.0.3",
"@types/minimist": "^1.2.0",
@@ -42,7 +43,7 @@
"request": "^2.85.0",
"tslint": "^5.9.1",
"service-downloader": "github:anthonydresser/service-downloader#0.1.5",
"typescript": "3.2.2",
"typescript": "3.4.5",
"vsce": "1.48.0",
"xml2js": "^0.4.17"
},

View File

@@ -8,7 +8,7 @@
"resolveJsonModule": true,
"experimentalDecorators": true,
// enable JavaScript type checking for the language service
// use the tsconfig.build.json for compiling wich disable JavaScript
// use the tsconfig.build.json for compiling which disable JavaScript
// type checking so that JavaScript file are not transpiled
"allowJs": true,
"checkJs": true,
@@ -22,4 +22,4 @@
"exclude": [
"node_modules/**"
]
}
}

View File

@@ -70,7 +70,7 @@ Type: files; Name: "{app}\resources\app\Credits_45.0.2454.85.html"; Check: IsNot
Type: filesandordirs; Name: "{app}\_"
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: checkedonce; Check: IsNotUpdate
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked;
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1
Name: "associatewithfiles"; Description: "{cm:AssociateWithFiles,{#NameLong}}"; GroupDescription: "{cm:Other}"; Flags: unchecked
Name: "addtopath"; Description: "{cm:AddToPath}"; GroupDescription: "{cm:Other}"

File diff suppressed because it is too large Load Diff

View File

@@ -73,12 +73,12 @@
"git": {
"name": "electron",
"repositoryUrl": "https://github.com/electron/electron",
"commitHash": "bb28fa8e8e797db249a66405146ad0501eaf411a"
"commitHash": "e84a6860e35e14b4031b88bb9b49841cdb89a305"
}
},
"isOnlyProductionDependency": true,
"license": "MIT",
"version": "3.1.2"
"version": "3.1.8"
},
{
"component": {
@@ -111,11 +111,11 @@
"git": {
"name": "vscode-octicons-font",
"repositoryUrl": "https://github.com/Microsoft/vscode-octicons-font",
"commitHash": "5095860bb929919670646e2dfa0ee47d9b93bcb9"
"commitHash": "4f69de3a233ed501c2098e33047e116ac2fbbf42"
}
},
"license": "MIT",
"version": "1.0.0"
"version": "1.1.0"
},
{
"component": {

View File

@@ -26,4 +26,4 @@
"publisherDisplayName": "Microsoft",
"publisherId": "Microsoft"
}
}
}

View File

@@ -0,0 +1,2 @@
ssmsmin
*.vsix

View File

@@ -0,0 +1,5 @@
out/test/**
src/**
ssmsmin/**
.gitignore
tsconfig.json

View File

@@ -0,0 +1,17 @@
# Database Admin Tool Extensions for Windows
This adds Windows-specific functionality into Azure Data Studio.
## Code of Conduct
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
## Privacy Statement
The [Microsoft Enterprise and Developer Privacy Statement](https://privacy.microsoft.com/en-us/privacystatement) describes the privacy statement of this software.
## License
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the [Source EULA](https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/LICENSE.txt).

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@@ -0,0 +1,75 @@
{
"name": "admin-tool-ext-win",
"displayName": "%adminToolExtWin.displayName%",
"description": "%adminToolExtWin.description%",
"version": "0.0.1",
"publisher": "Microsoft",
"preview": true,
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/LICENSE.txt",
"icon": "images/sqlserver.png",
"aiKey": "AIF-5574968e-856d-40d2-af67-c89a14e76412",
"engines": {
"vscode": "^1.30.1",
"sqlops": "*"
},
"activationEvents": [
"*"
],
"main": "./out/main",
"repository": {
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"extensionDependencies": [
"Microsoft.mssql"
],
"contributes": {
"commands": [
{
"command": "adminToolExtWin.launchSsmsMinPropertiesDialog",
"title": "%adminToolExtWin.propertiesMenuItem%",
"category": "AdminToolExtWin"
},
{
"command": "adminToolExtWin.launchSsmsMinGswDialog",
"title": "%adminToolExtWin.launchGswMenuItem%",
"category": "AdminToolExtWin"
}
],
"menus": {
"commandPalette": [
{
"command": "adminToolExtWin.launchSsmsMinPropertiesDialog",
"when": "false"
},
{
"command": "adminToolExtWin.launchSsmsMinGswDialog",
"when": "false"
}
],
"objectExplorer/item/context": [
{
"command": "adminToolExtWin.launchSsmsMinGswDialog",
"when": "isWindows && connectionProvider == MSSQL && nodeType && nodeType == Database",
"group": "z-AdminToolExt@1"
},
{
"command": "adminToolExtWin.launchSsmsMinPropertiesDialog",
"when": "isWindows && connectionProvider == MSSQL && nodeType && nodeType =~ /^(Server|Database|Table|Column|Index|Statistic|View|ServerLevelLogin|ServerLevelServerRole|ServerLevelCredential|ServerLevelServerAudit|ServerLevelServerAuditSpecification|StoredProcedure|ScalarValuedFunction|TableValuedFunction|AggregateFunction|Synonym|Assembly|UserDefinedDataType|UserDefinedType|UserDefinedTableType|Sequence|User|DatabaseRole|ApplicationRole|Schema|SecurityPolicy|ServerLevelLinkedServer)$/",
"group": "z-AdminToolExt@2"
}
]
},
"outputChannels": [
"admin-tool-ext-win"
]
},
"dependencies": {
"service-downloader": "github:anthonydresser/service-downloader#0.1.5",
"vscode-extension-telemetry": "^0.0.15",
"vscode-nls": "^3.2.1"
},
"devDependencies": {
"vscode": "1.0.1"
}
}

View File

@@ -0,0 +1,6 @@
{
"adminToolExtWin.displayName": "Database Administration Tool Extensions for Windows",
"adminToolExtWin.description": "Adds additional Windows-specific functionality to Azure Data Studio",
"adminToolExtWin.propertiesMenuItem": "Properties",
"adminToolExtWin.launchGswMenuItem": "Generate Scripts..."
}

View File

@@ -0,0 +1,12 @@
{
"downloadUrl": "https://sqlopsextensions.blob.core.windows.net/tools/ssmsmin/{#version#}/{#fileName#}",
"version": "15.0.18120.0",
"downloadFileNames": {
"Windows_64": "SsmsMin-15.0.18120.0-win-x64.zip",
"Windows_86": "SsmsMin-15.0.18120.0-win-x86.zip"
},
"installDirectory": "ssmsmin/{#platform#}/{#version#}",
"executableFiles": [
"SsmsMin.exe"
]
}

View File

@@ -0,0 +1,299 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vscode-nls';
import * as path from 'path';
import * as azdata from 'azdata';
import * as vscode from 'vscode';
import { IConfig, ServerProvider } from 'service-downloader';
import { Telemetry } from './telemetry';
import { doubleEscapeSingleQuotes, backEscapeDoubleQuotes, getConfiguration } from './utils';
import { ChildProcess, exec } from 'child_process';
const baseConfig = require('./config.json');
const localize = nls.loadMessageBundle();
let exePath: string;
let runningProcesses: Map<number, ChildProcess> = new Map<number, ChildProcess>();
interface SmoMapping {
action: string;
urnName: string;
}
const nodeTypeToUrnNameMapping: { [oeNodeType: string]: SmoMapping } = {
'Database': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.Database', urnName: 'Database' },
'Server': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.Server', urnName: 'Server' },
'ServerLevelServerAudit': { action: 'sqla:AuditProperties', urnName: 'Audit' },
'ServerLevelCredential': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.Credential', urnName: 'Credential' },
'ServerLevelServerRole': { action: 'sqla:ManageServerRole', urnName: 'Role' },
'ServerLevelServerAuditSpecification': { action: 'sqla:ServerAuditSpecificationProperties', urnName: 'ServerAuditSpecification' },
'ServerLevelLinkedServer': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.LinkedServer', urnName: 'LinkedServer' },
'Table': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.Table', urnName: 'Table' },
'View': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.View', urnName: 'View' },
'Column': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.Column', urnName: 'Column' },
'Index': { action: 'sqla:IndexProperties', urnName: 'Index' },
'Statistic': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.Statistic', urnName: 'Statistic' },
'StoredProcedure': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.StoredProcedure', urnName: 'StoredProcedure' },
'ScalarValuedFunction': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.UserDefinedFunction', urnName: 'UserDefinedFunction' },
'TableValuedFunction': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.UserDefinedFunction', urnName: 'UserDefinedFunction' },
'AggregateFunction': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.UserDefinedFunction', urnName: 'UserDefinedFunction' },
'Synonym': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.Synonym', urnName: 'Synonym' },
'Assembly': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.SqlAssembly', urnName: 'SqlAssembly' },
'UserDefinedDataType': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.UserDefinedDataType', urnName: 'UserDefinedDataType' },
'UserDefinedType': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.UserDefinedType', urnName: 'UserDefinedType' },
'UserDefinedTableType': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.UserDefinedTableType', urnName: 'UserDefinedTableType' },
'Sequence': { action: 'sqla:SequenceProperties', urnName: 'Sequence' },
'User': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.User', urnName: 'User' },
'DatabaseRole': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.DatabaseRole', urnName: 'Role' },
'ApplicationRole': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.ApplicationRole', urnName: 'ApplicationRole' },
'Schema': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.Schema', urnName: 'Schema' },
'SecurityPolicy': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.SecurityPolicy', urnName: 'SecurityPolicy' },
'ServerLevelLogin': { action: 'sqla:Properties@Microsoft.SqlServer.Management.Smo.Login', urnName: 'Login' },
};
// Params to pass to SsmsMin.exe, only an action and server are required - the rest are optional based on the
// action used. Exported for use in testing.
export interface LaunchSsmsDialogParams {
action: string;
server: string;
database?: string;
user?: string;
useAad?: boolean;
urn?: string;
}
export async function activate(context: vscode.ExtensionContext): Promise<void> {
// This is for Windows-specific support so do nothing on other platforms
if (process.platform === 'win32') {
Telemetry.sendTelemetryEvent('startup/ExtensionActivated');
let config: IConfig = JSON.parse(JSON.stringify(baseConfig));
config.installDirectory = path.join(context.extensionPath, config.installDirectory);
config.proxy = getConfiguration('http').get('proxy');
config.strictSSL = getConfiguration('http').get('proxyStrictSSL') || true;
const serverdownloader = new ServerProvider(config);
const installationStart = Date.now();
try {
let downloadedExePath = await serverdownloader.getOrDownloadServer();
const installationComplete = Date.now();
// Don't register the command if we couldn't find the EXE since it won't be able to do anything
if (downloadedExePath) {
exePath = downloadedExePath;
} else {
throw new Error('Could not find SsmsMin.exe after downloading');
}
// Register the commands now that we have the exePath to run the tool with
registerCommands(context);
Telemetry.sendTelemetryEvent('startup/ExtensionStarted', {
installationTime: String(installationComplete - installationStart),
beginningTimestamp: String(installationStart)
});
}
catch (err) {
Telemetry.sendTelemetryEvent('startup/ExtensionInitializationFailed');
console.error(`Error Initializing Admin Tool Extension for Windows - ${err}`);
}
}
}
export async function deactivate(): Promise<void> {
// If the extension is being deactivated we want to kill all processes that are still currently
// running otherwise they will continue to run as orphan processes. We use taskkill here in case
// they started off child processes of their own
runningProcesses.forEach(p => exec('taskkill /pid ' + p.pid + ' /T /F'));
}
/**
* Registers extension commands with command subsystem
* @param context The context used to register the commands
*/
function registerCommands(context: vscode.ExtensionContext): void {
context.subscriptions.push(
vscode.commands.registerCommand('adminToolExtWin.launchSsmsMinPropertiesDialog', handleLaunchSsmsMinPropertiesDialogCommand));
context.subscriptions.push(
vscode.commands.registerCommand('adminToolExtWin.launchSsmsMinGswDialog', handleLaunchSsmsMinGswDialogCommand));
}
/**
* Handler for command to launch SSMS Server Properties dialog
* @param connectionId The connection context from the command
*/
async function handleLaunchSsmsMinPropertiesDialogCommand(connectionContext?: azdata.ObjectExplorerContext): Promise<void> {
if (!connectionContext) {
vscode.window.showErrorMessage(localize('adminToolExtWin.noConnectionContextForProp', 'No ConnectionContext provided for handleLaunchSsmsMinPropertiesDialogCommand'));
return;
}
let nodeType: string;
if (connectionContext.isConnectionNode) {
nodeType = 'Server';
}
else if (connectionContext.nodeInfo) {
nodeType = connectionContext.nodeInfo.nodeType;
}
else {
vscode.window.showErrorMessage(localize('adminToolExtWin.noOeNode', 'Could not determine NodeType for handleLaunchSsmsMinPropertiesDialogCommand with context {0}', JSON.stringify(connectionContext)));
return;
}
launchSsmsDialog(
nodeTypeToUrnNameMapping[nodeType].action,
connectionContext);
}
/**
* Handler for command to launch SSMS "Generate Script Wizard" dialog
* @param connectionId The connection context from the command
*/
async function handleLaunchSsmsMinGswDialogCommand(connectionContext?: azdata.ObjectExplorerContext): Promise<void> {
if (!connectionContext) {
vscode.window.showErrorMessage(localize('adminToolExtWin.noConnectionContextForGsw', 'No ConnectionContext provided for handleLaunchSsmsMinPropertiesDialogCommand'));
}
launchSsmsDialog(
'GenerateScripts',
connectionContext);
}
/**
* Launches SsmsMin with parameters from the specified connection
* @param action The action to launch
* @param params The params used to construct the command
* @param urn The URN to pass to SsmsMin
*/
async function launchSsmsDialog(action: string, connectionContext: azdata.ObjectExplorerContext): Promise<void> {
if (!exePath) {
vscode.window.showErrorMessage(localize('adminToolExtWin.noExeError', 'Unable to find SsmsMin.exe.'));
return;
}
if (!connectionContext.connectionProfile) {
vscode.window.showErrorMessage(localize('adminToolExtWin.noConnectionProfile', 'No connectionProfile provided from connectionContext : {0}', JSON.stringify(connectionContext)));
return;
}
// Currently Azure isn't supported by the SSMS server properties dialog
const serverInfo = await azdata.connection.getServerInfo(connectionContext.connectionProfile.id);
if (serverInfo && serverInfo.isCloud) {
vscode.window.showErrorMessage(localize('adminToolExtWin.invalidEngineType', 'This option is not currently available for this engine type.'));
return;
}
// Note - this is a temporary fix for the issue that currently the connection API doesn't allow retrieving credentials for a disconnected
// node. So until that's fixed we'll prevent users from attempting to launch SsmsMin on a disconnected node.
// We also aren't able to hide the menu item on disconnected nodes because we currently don't have a contextKey for the connected status
// of a node.
const activeConnections = await azdata.connection.getActiveConnections();
if (!activeConnections.some(conn => conn.connectionId === connectionContext.connectionProfile.id)) {
vscode.window.showErrorMessage(localize('adminToolExtWin.notConnected', 'This option requires a connected node - please connect and try again.'));
return;
}
let oeNode: azdata.objectexplorer.ObjectExplorerNode;
// Server node is a Connection node and so doesn't have the NodeInfo
if (connectionContext.isConnectionNode) {
oeNode = undefined;
}
else if (connectionContext.nodeInfo && connectionContext.nodeInfo.nodeType && connectionContext.connectionProfile) {
oeNode = await azdata.objectexplorer.getNode(connectionContext.connectionProfile.id, connectionContext.nodeInfo.nodePath);
}
else {
vscode.window.showErrorMessage(localize('adminToolExtWin.noOENode', 'Could not determine Object Explorer node from connectionContext : {0}', JSON.stringify(connectionContext)));
return;
}
let urn: string = await buildUrn(connectionContext.connectionProfile.serverName, oeNode);
let password: string = connectionContext.connectionProfile.password;
if (!password || password === '') {
let creds = await azdata.connection.getCredentials(connectionContext.connectionProfile.id);
password = creds[azdata.ConnectionOptionSpecialType.password];
}
let params: LaunchSsmsDialogParams = {
action: action,
server: connectionContext.connectionProfile.serverName,
database: connectionContext.connectionProfile.databaseName,
user: connectionContext.connectionProfile.userName,
useAad: connectionContext.connectionProfile.authenticationType === 'AzureMFA',
urn: urn
};
let args = buildSsmsMinCommandArgs(params);
Telemetry.sendTelemetryEvent('LaunchSsmsDialog', { 'action': action });
// This will be an async call since we pass in the callback
let proc: ChildProcess = exec(
/*command*/ `"${exePath}" ${args}`,
/*options*/ undefined,
(execException, stdout, stderr) => {
// Process has exited so remove from map of running processes
runningProcesses.delete(proc.pid);
Telemetry.sendTelemetryEvent('LaunchSsmsDialogResult', {
'action': params.action,
'returnCode': execException && execException.code ? execException.code.toString() : '0'
});
let err = stderr.toString();
if (err !== '') {
vscode.window.showErrorMessage(localize(
'adminToolExtWin.ssmsMinError',
'Error calling SsmsMin with args \'{0}\' - {1}', args, err));
}
});
// If we're not using AAD the tool prompts for a password on stdin
if (params.useAad !== true) {
proc.stdin.end(password ? password : '');
}
// Save the process into our map so we can make sure to stop them if we exit before shutting down
runningProcesses.set(proc.pid, proc);
}
/**
* Builds the command arguments to pass to SsmsMin.exe. Values are expected to be escaped correctly
* already per their - they will be further escaped * for command-line usage but no additional
* escaping will occur.
* @param params The params used to build up the command parameter string
*/
export function buildSsmsMinCommandArgs(params: LaunchSsmsDialogParams): string {
return `${params.action ? '-a "' + backEscapeDoubleQuotes(params.action) + '"' : ''}\
${params.server ? ' -S "' + backEscapeDoubleQuotes(params.server) + '"' : ''}\
${params.database ? ' -D "' + backEscapeDoubleQuotes(params.database) + '"' : ''}\
${params.useAad !== true && params.user ? ' -U "' + backEscapeDoubleQuotes(params.user) + '"' : ''}\
${params.useAad === true ? ' -G' : ''}\
${params.urn ? ' -u "' + backEscapeDoubleQuotes(params.urn) + '"' : ''}`;
}
/**
* Builds the URN string for a given ObjectExplorerNode in the form understood by SsmsMin
* @param serverName The name of the Server to use for the Server segment
* @param node The node to get the URN of
*/
export async function buildUrn(serverName: string, node: azdata.objectexplorer.ObjectExplorerNode): Promise<string> {
let urnNodes: string[] = [];
while (node) {
// Server is special since it's a connection node - always add it as the root
if (node.nodeType === 'Server') {
break;
}
else if (node.metadata && node.nodeType !== 'Folder') {
// SFC URN expects Name and Schema to be separate properties
let urnSegment = node.metadata.schema && node.metadata.schema !== '' ?
`${nodeTypeToUrnNameMapping[node.nodeType].urnName}[@Name='${doubleEscapeSingleQuotes(node.metadata.name)}' and @Schema='${doubleEscapeSingleQuotes(node.metadata.schema)}']` :
`${nodeTypeToUrnNameMapping[node.nodeType].urnName}[@Name='${doubleEscapeSingleQuotes(node.metadata.name)}']`;
urnNodes = [urnSegment].concat(urnNodes);
}
node = await node.getParent();
}
return [`Server[@Name='${doubleEscapeSingleQuotes(serverName)}']`].concat(urnNodes).join('/');
}

View File

@@ -0,0 +1,135 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as vscode from 'vscode';
import TelemetryReporter from 'vscode-extension-telemetry';
import { PlatformInformation } from 'service-downloader/out/platform';
import * as Utils from './utils';
const packageJson = require('../package.json');
export interface ITelemetryEventProperties {
[key: string]: string;
}
export interface ITelemetryEventMeasures {
[key: string]: number;
}
/**
* Filters error paths to only include source files. Exported to support testing
*/
export function filterErrorPath(line: string): string {
if (line) {
let values: string[] = line.split('/out/');
if (values.length <= 1) {
// Didn't match expected format
return line;
} else {
return values[1];
}
}
}
export class Telemetry {
private static reporter: TelemetryReporter;
private static userId: string;
private static platformInformation: PlatformInformation;
private static disabled: boolean;
public static getPlatformInformation(): Promise<PlatformInformation> {
if (this.platformInformation) {
return Promise.resolve(this.platformInformation);
} else {
return new Promise<PlatformInformation>(resolve => {
PlatformInformation.getCurrent().then(info => {
this.platformInformation = info;
resolve(this.platformInformation);
});
});
}
}
/**
* Disable telemetry reporting
*/
public static disable(): void {
this.disabled = true;
}
/**
* Initialize the telemetry reporter for use.
*/
public static initialize(): void {
if (typeof this.reporter === 'undefined') {
// Check if the user has opted out of telemetry
if (!vscode.workspace.getConfiguration('telemetry').get<boolean>('enableTelemetry', true)) {
this.disable();
return;
}
let packageInfo = Utils.getPackageInfo(packageJson);
this.reporter = new TelemetryReporter(packageInfo.name, packageInfo.version, packageInfo.aiKey);
}
}
/**
* Send a telemetry event for an exception
*/
public static sendTelemetryEventForException(
err: any, methodName: string, extensionConfigName: string): void {
try {
let stackArray: string[];
let firstLine: string = '';
if (err !== undefined && err.stack !== undefined) {
stackArray = err.stack.split('\n');
if (stackArray !== undefined && stackArray.length >= 2) {
firstLine = stackArray[1]; // The first line is the error message and we don't want to send that telemetry event
firstLine = filterErrorPath(firstLine);
}
}
// Only adding the method name and the fist line of the stack trace. We don't add the error message because it might have PII
this.sendTelemetryEvent('Exception', { methodName: methodName, errorLine: firstLine });
} catch (telemetryErr) {
// If sending telemetry event fails ignore it so it won't break the extension
console.error('Failed to send telemetry event. error: ' + telemetryErr, extensionConfigName);
}
}
/**
* Send a telemetry event using application insights
*/
public static sendTelemetryEvent(
eventName: string,
properties?: ITelemetryEventProperties,
measures?: ITelemetryEventMeasures): void {
if (typeof this.disabled === 'undefined') {
this.disabled = false;
}
if (this.disabled || typeof (this.reporter) === 'undefined') {
// Don't do anything if telemetry is disabled
return;
}
if (!properties || typeof properties === 'undefined') {
properties = {};
}
// Augment the properties structure with additional common properties before sending
Promise.all([this.getPlatformInformation()]).then(() => {
properties['distribution'] = (this.platformInformation && this.platformInformation.distribution) ?
`${this.platformInformation.distribution.name}, ${this.platformInformation.distribution.version}` : '';
this.reporter.sendTelemetryEvent(eventName, properties, measures);
});
}
}
Telemetry.initialize();

View File

@@ -0,0 +1,30 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
const path = require('path');
const testRunner = require('vscode/lib/testrunner');
const suite = 'Database Admin Tool Extensions for Windows';
const options: any = {
ui: 'bdd',
useColors: true,
timeout: 600000
};
if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) {
options.reporter = 'mocha-multi-reporters';
options.reporterOptions = {
reporterEnabled: 'spec, mocha-junit-reporter',
mochaJunitReporterReporterOptions: {
testsuitesTitle: `${suite} ${process.platform}`,
mochaFile: path.join(process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, `test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`)
}
};
}
testRunner.configure(options);
export = testRunner;

View File

@@ -0,0 +1,68 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as azdata from 'azdata';
import * as vscode from 'vscode';
/**
* Helper stub class for mocking ExtHostObjectExplorerNode
*/
export class ExtHostObjectExplorerNodeStub implements azdata.objectexplorer.ObjectExplorerNode {
// Stub properties
private parent: azdata.objectexplorer.ObjectExplorerNode;
// Base properties
public connectionId: string;
public nodePath: string;
public nodeType: string;
public nodeSubType: string;
public nodeStatus: string;
public label: string;
public isLeaf: boolean;
public metadata: azdata.ObjectMetadata;
public errorMessage: string;
constructor(nodeName: string, nodeSchema: string, nodeType, parent: azdata.objectexplorer.ObjectExplorerNode) {
this.parent = parent;
this.nodeType = nodeType;
this.metadata = { metadataType: undefined, metadataTypeName: undefined, name: nodeName, schema: nodeSchema, urn: undefined };
}
isExpanded(): Thenable<boolean> {
throw new Error('Method not implemented');
}
setExpandedState(expandedState: vscode.TreeItemCollapsibleState): Thenable<void> {
throw new Error('Method not implemented');
}
setSelected(selected: boolean, clearOtherSelections: boolean = undefined): Thenable<void> {
throw new Error('Method not implemented');
}
getChildren(): Thenable<azdata.objectexplorer.ObjectExplorerNode[]> {
throw new Error('Method not implemented');
}
getParent(): Thenable<azdata.objectexplorer.ObjectExplorerNode> {
return Promise.resolve(this.parent);
}
refresh(): Thenable<void> {
throw new Error('Method not implemented');
}
/**
*
* @param nodeName Helperfunction to create a node that is a child of this one
* @param nodeSchema The schema to give the child node
* @param nodeType The type of node this should be
*/
createChild(nodeName: string, nodeSchema: string, nodeType: string): ExtHostObjectExplorerNodeStub {
return new ExtHostObjectExplorerNodeStub(nodeName, nodeSchema, nodeType, this);
}
}

View File

@@ -0,0 +1,135 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as should from 'should';
import 'mocha';
import { buildSsmsMinCommandArgs, buildUrn, LaunchSsmsDialogParams } from '../main';
import { doubleEscapeSingleQuotes, backEscapeDoubleQuotes } from '../utils';
import { ExtHostObjectExplorerNodeStub } from './stubs';
describe('buildSsmsMinCommandArgs Method Tests', () => {
it('Should be built correctly with all params and UseAAD as false', function (): void {
const params: LaunchSsmsDialogParams = {
action: 'myAction',
server: 'myServer',
database: 'myDatabase',
user: 'user',
useAad: false,
urn: 'Server\\Database\\Table'
};
const args = buildSsmsMinCommandArgs(params);
should(args).equal('-a "myAction" -S "myServer" -D "myDatabase" -U "user" -u "Server\\Database\\Table"');
});
it('Should be built correctly with all params and UseAAD as true', function (): void {
const params: LaunchSsmsDialogParams = {
action: 'myAction',
server: 'myServer',
database: 'myDatabase',
user: 'user',
useAad: true,
urn: 'Server\\Database\\Table'
};
const args = buildSsmsMinCommandArgs(params);
// User is omitted since UseAAD is true
should(args).equal('-a "myAction" -S "myServer" -D "myDatabase" -G -u "Server\\Database\\Table"');
});
it('Should be built correctly and names escaped correctly', function (): void {
const params: LaunchSsmsDialogParams = {
action: 'myAction\'"/\\[]tricky',
server: 'myServer\'"/\\[]tricky',
database: 'myDatabase\'"/\\[]tricky',
user: 'user\'"/\\[]tricky',
useAad: true,
urn: 'Server\\Database[\'myDatabase\'\'"/\\[]tricky\']\\Table["myTable\'""/\\[]tricky"]'
};
const args = buildSsmsMinCommandArgs(params);
// User is omitted since UseAAD is true
should(args).equal('-a "myAction\'\\"/\\[]tricky" -S "myServer\'\\"/\\[]tricky" -D "myDatabase\'\\"/\\[]tricky" -G -u "Server\\Database[\'myDatabase\'\'\\"/\\[]tricky\']\\Table[\\"myTable\'\\"\\"/\\[]tricky\\"]"');
});
it('Should be built correctly with only action and server', function (): void {
const params: LaunchSsmsDialogParams = {
action: 'myAction',
server: 'myServer'
};
const args = buildSsmsMinCommandArgs(params);
should(args).equal('-a "myAction" -S "myServer"');
});
});
const serverName = 'My\'Server';
const escapedServerName = doubleEscapeSingleQuotes(serverName);
const dbName = 'My\'Db';
const escapedDbName = doubleEscapeSingleQuotes(dbName);
const dbSchema = 'db\'sch';
const escapedDbSchema = doubleEscapeSingleQuotes(dbSchema);
const tableName = 'My\'Table';
const escapedTableName = doubleEscapeSingleQuotes(tableName);
const tableSchema = 'tbl\'sch';
const escapedTableSchema = doubleEscapeSingleQuotes(tableSchema);
describe('buildUrn Method Tests', () => {
it('Urn should be correct with just server', async function (): Promise<void> {
should(await buildUrn(serverName, undefined)).equal(`Server[@Name=\'${escapedServerName}\']`);
});
it('Urn should be correct with Server and only Databases folder', async function (): Promise<void> {
const leafNode: ExtHostObjectExplorerNodeStub =
new ExtHostObjectExplorerNodeStub('Databases', undefined, 'Folder', undefined);
should(await buildUrn(serverName, leafNode)).equal(`Server[@Name='${escapedServerName}']`);
});
it('Urn should be correct with Server and Database node', async function (): Promise<void> {
const leafNode: ExtHostObjectExplorerNodeStub =
new ExtHostObjectExplorerNodeStub('Databases', undefined, 'Folder', undefined)
.createChild(dbName, dbSchema, 'Database');
should(await buildUrn(serverName, leafNode)).equal(
`Server[@Name='${escapedServerName}']/Database[@Name='${escapedDbName}' and @Schema='${escapedDbSchema}']`);
});
it('Urn should be correct with Multiple levels of Nodes', async function (): Promise<void> {
const rootNode: ExtHostObjectExplorerNodeStub =
new ExtHostObjectExplorerNodeStub('Databases', undefined, 'Folder', undefined)
.createChild(dbName, dbSchema, 'Database')
.createChild('Tables', undefined, 'Folder')
.createChild(tableName, tableSchema, 'Table');
should(await buildUrn(serverName, rootNode)).equal(
`Server[@Name='${escapedServerName}']/Database[@Name='${escapedDbName}' and @Schema='${escapedDbSchema}']/Table[@Name='${escapedTableName}' and @Schema='${escapedTableSchema}']`);
});
});
describe('doubleEscapeSingleQuotes Method Tests', () => {
it('Should return original string if no single quotes', function (): void {
const testString: string = 'MyTestString';
const ret = doubleEscapeSingleQuotes(testString);
should(ret).equal(testString);
});
it('Should return escaped original string if it contains single quotes', function (): void {
const testString: string = 'MyTestString\'\'WithQuotes';
const ret = doubleEscapeSingleQuotes(testString);
should(ret).equal('MyTestString\'\'\'\'WithQuotes');
});
});
describe('backEscapeDoubleQuotes Method Tests', () => {
it('Should return original string if no double quotes', function (): void {
const testString: string = 'MyTestString';
const ret = backEscapeDoubleQuotes(testString);
should(ret).equal(testString);
});
it('Should return escaped original string if it contains double quotes', function (): void {
const testString: string = 'MyTestString\"\"WithQuotes';
const ret = backEscapeDoubleQuotes(testString);
should(ret).equal('MyTestString\\"\\"WithQuotes');
});
});

View File

@@ -3,10 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
suite('Debug - ANSI Handling', () => {
test('appendStylizedStringToContainer', () => {
assert.equal('', '');
});
});
/// <reference path='../../../../src/sql/azdata.d.ts'/>
/// <reference path='../../../../src/sql/azdata.proposed.d.ts'/>
/// <reference path='../../../../src/vs/vscode.d.ts'/>
/// <reference types='@types/node'/>

View File

@@ -0,0 +1,60 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as vscode from 'vscode';
export interface IPackageInfo {
name: string;
version: string;
aiKey: string;
}
export function getPackageInfo(packageJson: any): IPackageInfo {
if (packageJson) {
return {
name: packageJson.name,
version: packageJson.version,
aiKey: packageJson.aiKey
};
}
}
/**
* Get the configuration for a extensionName
* @param extensionName The string name of the extension to get the configuration for
* @param resource The optional URI, as a URI object or a string, to use to get resource-scoped configurations
*/
export function getConfiguration(extensionName?: string, resource?: vscode.Uri | string): vscode.WorkspaceConfiguration {
if (typeof resource === 'string') {
try {
resource = this.parseUri(resource);
} catch (e) {
resource = undefined;
}
} else if (!resource) {
// Fix to avoid adding lots of errors to debug console. Expects a valid resource or null, not undefined
resource = null;
}
return vscode.workspace.getConfiguration(extensionName, resource as vscode.Uri);
}
/**
* Escapes all single-quotes (') by prefixing them with another single quote ('')
* ' => ''
* @param value The string to escape
*/
export function doubleEscapeSingleQuotes(value: string): string {
return value.replace(/'/g, '\'\'');
}
/**
* Escape all double-quotes (") by prefixing them with a \
* " => \"
* @param value The string to escape
*/
export function backEscapeDoubleQuotes(value: string): string {
return value.replace(/"/g, '\\"');
}

Some files were not shown because too many files have changed in this diff Show More