jetbrains / rider-efcore Goto Github PK
View Code? Open in Web Editor NEWEntity Framework Core UI plugin for JetBrains Rider
Home Page: https://plugins.jetbrains.com/plugin/18147-entity-framework-core-ui
License: MIT License
Entity Framework Core UI plugin for JetBrains Rider
Home Page: https://plugins.jetbrains.com/plugin/18147-entity-framework-core-ui
License: MIT License
Stacktrace:
java.util.NoSuchElementException: Array is empty.
at kotlin.collections.ArraysKt___ArraysKt.first(_Arrays.kt:1013)
at me.seclerp.rider.plugins.efcore.dialogs.BaseEfCoreDialogWrapper.<init>(BaseEfCoreDialogWrapper.kt:86)
at me.seclerp.rider.plugins.efcore.dialogs.UpdateDatabaseDialogWrapper.<init>(UpdateDatabaseDialogWrapper.kt:24)
at me.seclerp.rider.plugins.efcore.actions.projects.UpdateDatabaseAction$actionPerformed$dialog$1.invoke(UpdateDatabaseAction.kt:13)
at me.seclerp.rider.plugins.efcore.actions.projects.UpdateDatabaseAction$actionPerformed$dialog$1.invoke(UpdateDatabaseAction.kt:12)
at me.seclerp.rider.plugins.efcore.actions.projects.BaseEfCoreAction.buildDialogInstance(BaseEfCoreAction.kt:40)
at me.seclerp.rider.plugins.efcore.actions.projects.UpdateDatabaseAction.actionPerformed(UpdateDatabaseAction.kt:12)
at com.intellij.openapi.actionSystem.ex.ActionUtil.lambda$performActionDumbAwareWithCallbacks$4(ActionUtil.java:240)
at com.intellij.openapi.actionSystem.ex.ActionUtil.performDumbAwareWithCallbacks(ActionUtil.java:261)
at com.intellij.openapi.actionSystem.ex.ActionUtil.performActionDumbAwareWithCallbacks(ActionUtil.java:240)
at com.intellij.openapi.actionSystem.impl.ActionMenuItem$ActionTransmitter.lambda$actionPerformed$0(ActionMenuItem.java:248)
at com.intellij.openapi.wm.impl.FocusManagerImpl.runOnOwnContext(FocusManagerImpl.java:236)
at com.intellij.openapi.wm.impl.IdeFocusManagerImpl.runOnOwnContext(IdeFocusManagerImpl.java:67)
at com.intellij.openapi.actionSystem.impl.ActionMenuItem$ActionTransmitter.actionPerformed(ActionMenuItem.java:240)
at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967)
at com.intellij.openapi.actionSystem.impl.ActionMenuItem.lambda$fireActionPerformed$0(ActionMenuItem.java:90)
at com.intellij.openapi.application.TransactionGuardImpl.performUserActivity(TransactionGuardImpl.java:94)
at com.intellij.openapi.actionSystem.impl.ActionMenuItem.fireActionPerformed(ActionMenuItem.java:90)
at com.intellij.ui.plaf.beg.BegMenuItemUI.doClick(BegMenuItemUI.java:515)
at com.intellij.ui.plaf.beg.BegMenuItemUI$MyMouseInputHandler.mouseReleased(BegMenuItemUI.java:545)
at java.desktop/java.awt.Component.processMouseEvent(Component.java:6652)
at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3345)
at java.desktop/java.awt.Component.processEvent(Component.java:6417)
at java.desktop/java.awt.Container.processEvent(Container.java:2263)
at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5027)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4859)
at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4918)
at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4547)
at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4488)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2307)
at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2784)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4859)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:778)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:727)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:751)
at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:749)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:748)
at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.java:885)
at com.intellij.ide.IdeEventQueue.dispatchMouseEvent(IdeEventQueue.java:814)
at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:751)
at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$6(IdeEventQueue.java:441)
at com.intellij.openapi.progress.impl.CoreProgressManager.computePrioritized(CoreProgressManager.java:825)
at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$7(IdeEventQueue.java:440)
at com.intellij.openapi.application.impl.ApplicationImpl.runIntendedWriteActionOnCurrentThread(ApplicationImpl.java:794)
at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:492)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
We have several projects, 2 are relevant:
Domain.csproj
Web.csproj
Domain contains the migrations, and the DbContext class.
Web contains the startup code.
To add a migration is (from within the domain project):
dotnet ef --startup-project ../web migrations add โฆ
However the 'Add Migration' dialog does not present the Web
project as an option.
When the tools-manifest.json
file is presented in Startup / Migrations project folder or in one of the parent folder path
And if it contains the definition of dotnet ef
local tool, we need to use it instead of a global one.
This plugin is for Rider only, so ReSharper-related stuff that depends on VS in any sense should be removed
Need to customize textFieldWithBrowseButton
to add the ability to specify folder for with selected path should be relative to.
For example, if we provide
/some/root/folder
as a base folder for control and select such folder as a value:
/some/root/folder/inner/folder
such folder should be applied and visible on the UI:
inner/folder
Need also make path relative if folder is outside root folder:
Example root path:
/some/root/folder
Example selected path:
/some/other/folder
Resulting value:
../../other/folder
Note: this feature should utilize DSL v2, see https://plugins.jetbrains.com/docs/intellij/kotlin-ui-dsl-version-2.html
Useful links:
Blocks #17
If we detect any project in solution that have Microsoft.EntityFrameworkCore.Tools installed (maybe Microsoft.EntityFrameworkCore is enough?), we should fire warning notification:
Title: Entity Framework Tools are not installed
Message: Your project contains EF Core-related projects, EF Core plugin needs these tools to work
Button: Install
To detect this need we could run dotnet ef --version
and utilize the output
Sometimes we need to rerun failed command if it failed not because of its options, but due to the solution state (for example, a project that should be built is running and preventing build to start)
Use GitHub Actions to create pipelines:
We should handle such cases:
Other invalid cases are not in scope because they prevent dialogs from opening and we should not validate them
Need to save common options per project. When using one of migrations or startup project inside action, it should restore second one.
For example, if we have 3 projects in the solution:
When we first time executing any EF Core action, with selected A as a startup project and A.DAL as a migrations project, we should save this pair.
Next time when we open any action from A project, we should see A.DAL as a migrations project
And when we open any action from A.DAL project, we should see A as a startup project
For now, the Startup project is determined by such logic:
if a project has Microsoft.EntityFrameworkCore.Design
or Microsoft.EntityFrameworkCore.Tools
NuGets directly installed, it's a suitable startup project.
Need to improve such logic to include case, when required NuGet is installed in referenced projects (indirectly).
From bug report #57
Dev notes:
ReferencedAssembliesService.IsProjectReferencingAssemblyByName
could be used as a new way of detecting required assemblies
If a startup project has a direct dependency on Microsoft.EntityFrameworkCore.Tools
but not on Microsoft.EntityFrameworkCore.Design
, all dialogs will not show it as an appropriate startup project
According to #55, there will be the ability to execute EF Core actions without a project file.
Need to add a global action group that will be available under Tools | Entity Framework Core section on the main menu.
It should be also accessible through the "Entity Framework Core Operations" popup.
Tasks:
Resources:
Currently, only Startup and Migrations project dropdowns state is persisted across dialogs.
Other common options could be persisted as well:
Original issue: #39
When looking at the build configuration drop-down, the results are pulling all build configurations from each project in the solution. Also noticing the other fields are duplicating values as well.
I added an additional <TargetFrameworks>net6.0;net5.0</TargetFrameworks>
which triggered the DbContext
duplication.
Don't see duplication in the drop-downs.
See sample project here. https://github.com/MassTransit/Sample-ForkJoint
This is a really cool plug-in and it's pretty amazing. Great job.
I am looking for a solution to use EF with Rider (2021.3)
I have .Net 6 projects, with a Server + Data libraries, nugets updated accordingly.
Neither of Add Migration / Update works.
The following error pops up:
Command: dotnet ef database update --project D:\Visual Studio Projects\Tegu\Tegu Solutions\TeguSolutions.Data\TeguSolutions.Data.csproj --startup-project D:\Visual Studio Projects\Tegu\Tegu Solutions\TeguSolutions\Server\TeguSolutions.Server.csproj --context TeguSolutions.Data.Context.TeguDbContext --configuration Debug --framework net6.0 20211209000444_UsersystemroleMtmRelationCreated Output: MSBUILD : error MSB1009: Project file does not exist. Switch: D:\Visual Unable to retrieve project metadata. Ensure it's an MSBuild-based .NET Core project. If you're using custom BaseIntermediateOutputPath or MSBuildProjectExtensionsPath values, Use the --msbuildprojectextensionspath option. Exit code: 1
With Visual Studio everything is fine, just for reference.
It is a bug or can I do anything on my side to make it work?
Need to simplify overengineered logic for project migrations retrieval from backend
Hi,
I'm forced to use MacOs at work, and tried to use install the plugin today, but unfortunately the plugin doesn't seem to be able to find dotnet.
In the Event log, I can see the following:
13.01.22
11:45 EF Core tools are not installed
These tools are required to execute EF Core commands
Fix
11:45 EF Core command failed
Command: dotnet tool install --global dotnet-ef
Output:
java.io.IOException: Cannot run program "dotnet": error=2, No such file or directory
Exit code: -1
Try Again
Using dotnet and dotnet-ef over the normal terminal and Riders integrated terminal works normally, so it seems to be available in the PATH. I'm using dotnet 6.0.101.
I'm using
Rider 2021.3.2
Entity Framework Core UI: 1.1.2
MacOS 11.6.1
Any idea why that might be happening or what I can do to get it working?
If you do not have access to a Mac I'm happy to further assist.
If the selected Migrations project have 0 migrations, automatically place "Initial" as a default value for "Migration name" field
Need to remove empty folder if it doesn't contain any migrations after Remove Last Migration action.
Sub-tasks:
Need to check if selected Migrations project has at least 1 migration
Affected dialogs:
--project
(as a dropdown) (preselect from saved config)--startup-project
(as a dropdown) (preselect from saved config)--context
(as a dropdown)Build options:
--no-build
(as a checkbox)--configuration
(enabled if "No build" is not selected) (as a dropdown, preselect current configuration)--framework
(as a dropdown, preselect first)dotnet ef dbcontext scaffold
commandThis dialog should be implemented as multitab panel. Each type for each configuration section:
--output-dir
) (folder box)--data-annotations
) (check box)--use-database-names
)--no-onconfiguring
)--no-pluralize
)--context
) (check box)--context-namespace
) (text field) (project namespace + folder name by default)--context-dir
) (file box)--schema
options)--table
options)TBD
"Migrations folder" option in the "Add migration" dialog is not persistent across runs.
"Squash Migrations" - something similar to git squash for commits on merge
First migration selected as target migration, but not last one
Validate that migration with a specified name doesn't exist before creating a new one
For now, it's impossible to work with projects that have whitespace in the project file path because path parts are parsed incorrectly, for example:
--project /Some path/Some.Project.csproj
Only /Some
is considered as a project file path.
Solution: wrap such values in double-quotes:
--project "/Some path/Some.Project.csproj"
Also need to check that other options that could have whitespace are wrapped as well.
Report: #31
TBD
Currently only "Migrations project" and "Startup project" are persisted.
We have a lot of dialogs with a lot of selectable data on them. When the same dialog is used
DialogsStateService
to load/save dialogs' propertiesNeed to add folder picker relative to Migrations project root. Preselect folder of first migration. CLI option is --output-dir
Following deprecation notice, a currently used DSL v1 is scheduled for removal in the 2022.2 version of the Intellij IDEA platform. Need to migrate to DSL v2.
Documentation and migration guide: https://plugins.jetbrains.com/docs/intellij/kotlin-ui-dsl-version-2.html
Update Database dialog should have checkbox "Use default connection of startup project", with unchecking it enables input field that allows to set custom connection name or string for operation
According to #52, it's not possible to use dialog actions without dependency on a specific project file due to the initial plugin design.
Because of that custom invocation of all actions through shortcuts is not working.
Need to make projectFile
and dotnetProject
values for all dialogs optional and extend the "preferred projects" feature to introduce the ability to save preferred data for global execution (something like the "previous run").
projectFile
optional for all dialogsFor now, project names are used everywhere in the code base. Such a solution is not so robust, persistence will break on projects rename. We should use guids instead.
Stacktrace (1.0.0):
java.lang.NullPointerException
at me.seclerp.rider.plugins.efcore.dialogs.BaseEfCoreDialogWrapper.buildConfigurationRow(BaseEfCoreDialogWrapper.kt:192)
at me.seclerp.rider.plugins.efcore.dialogs.BaseEfCoreDialogWrapper$buildOptionsRow$1.invoke(BaseEfCoreDialogWrapper.kt:177)
at me.seclerp.rider.plugins.efcore.dialogs.BaseEfCoreDialogWrapper$buildOptionsRow$1.invoke(BaseEfCoreDialogWrapper.kt:174)
at com.intellij.ui.layout.migLayout.MigLayoutRow.createBlockRow(MigLayoutRow.kt:277)
at com.intellij.ui.layout.migLayout.MigLayoutRow.titledRow(MigLayoutRow.kt:268)
at com.intellij.ui.layout.LayoutBuilder.titledRow(LayoutBuilder.kt)
at me.seclerp.rider.plugins.efcore.dialogs.BaseEfCoreDialogWrapper.buildOptionsRow(BaseEfCoreDialogWrapper.kt:174)
at me.seclerp.rider.plugins.efcore.dialogs.BaseEfCoreDialogWrapper.additionalOptions(BaseEfCoreDialogWrapper.kt:132)
at me.seclerp.rider.plugins.efcore.dialogs.UpdateDatabaseDialogWrapper.createCenterPanel(UpdateDatabaseDialogWrapper.kt:52)
at me.seclerp.rider.plugins.efcore.dialogs.UpdateDatabaseDialogWrapper.createCenterPanel(UpdateDatabaseDialogWrapper.kt:20)
at com.intellij.openapi.ui.DialogWrapper.init(DialogWrapper.java:1348)
at me.seclerp.rider.plugins.efcore.dialogs.UpdateDatabaseDialogWrapper.<init>(UpdateDatabaseDialogWrapper.kt:44)
at me.seclerp.rider.plugins.efcore.actions.projects.UpdateDatabaseAction$actionPerformed$dialog$1.invoke(UpdateDatabaseAction.kt:13)
at me.seclerp.rider.plugins.efcore.actions.projects.UpdateDatabaseAction$actionPerformed$dialog$1.invoke(UpdateDatabaseAction.kt:12)
at me.seclerp.rider.plugins.efcore.actions.projects.BaseEfCoreAction.buildDialogInstance(BaseEfCoreAction.kt:40)
at me.seclerp.rider.plugins.efcore.actions.projects.UpdateDatabaseAction.actionPerformed(UpdateDatabaseAction.kt:12)
at com.intellij.openapi.actionSystem.ex.ActionUtil.lambda$performActionDumbAwareWithCallbacks$4(ActionUtil.java:240)
at com.intellij.openapi.actionSystem.ex.ActionUtil.performDumbAwareWithCallbacks(ActionUtil.java:261)
at com.intellij.openapi.actionSystem.ex.ActionUtil.performActionDumbAwareWithCallbacks(ActionUtil.java:240)
at com.intellij.openapi.actionSystem.impl.ActionMenuItem$ActionTransmitter.lambda$actionPerformed$0(ActionMenuItem.java:248)
at com.intellij.openapi.wm.impl.FocusManagerImpl.runOnOwnContext(FocusManagerImpl.java:236)
at com.intellij.openapi.wm.impl.IdeFocusManagerImpl.runOnOwnContext(IdeFocusManagerImpl.java:67)
at com.intellij.openapi.actionSystem.impl.ActionMenuItem$ActionTransmitter.actionPerformed(ActionMenuItem.java:240)
at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967)
at com.intellij.openapi.actionSystem.impl.ActionMenuItem.lambda$fireActionPerformed$0(ActionMenuItem.java:90)
at com.intellij.openapi.application.TransactionGuardImpl.performUserActivity(TransactionGuardImpl.java:94)
at com.intellij.openapi.actionSystem.impl.ActionMenuItem.fireActionPerformed(ActionMenuItem.java:90)
at com.intellij.ui.plaf.beg.BegMenuItemUI.doClick(BegMenuItemUI.java:515)
at com.intellij.ui.plaf.beg.BegMenuItemUI$MyMouseInputHandler.mouseReleased(BegMenuItemUI.java:545)
at java.desktop/java.awt.Component.processMouseEvent(Component.java:6652)
at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3345)
at java.desktop/java.awt.Component.processEvent(Component.java:6417)
at java.desktop/java.awt.Container.processEvent(Container.java:2263)
at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5027)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4859)
at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4918)
at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4547)
at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4488)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2307)
at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2784)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4859)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:778)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:727)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:751)
at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:749)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:748)
at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.java:885)
at com.intellij.ide.IdeEventQueue.dispatchMouseEvent(IdeEventQueue.java:814)
at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:751)
at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$6(IdeEventQueue.java:441)
at com.intellij.openapi.progress.impl.CoreProgressManager.computePrioritized(CoreProgressManager.java:825)
at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$7(IdeEventQueue.java:440)
at com.intellij.openapi.application.impl.ApplicationImpl.runIntendedWriteActionOnCurrentThread(ApplicationImpl.java:794)
at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:492)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
In some situations, the target framework will force all related projects to be built with it in mind and the build will fail. Need to add the ability to select Default for target framework to skip this option at all
Based on feedback, we could add support for netcoreapp3.1
for Startup projects and netcoreapp3.1
(and netstandard2.1
) as a Migrations project.
Target migration field should be filled with last created migration on shown and when Migrations project was changed
dotnet ef database drop
commandFor now, you could select migrations that are not always related to selected DbContext
TBD
Add special '0' entry to combo box to represent "reset to pre-first migration state" entry
If I write multiple migrations, I have to set all fields in the "Add Migration" dialog again for every single migration (mainly "Migrations project", "Startup project" and "DBContext class"). So currently, I'm actually faster if I use the command line, since there I can just save the command in clipboard, paste it and change just the migration name.
Please change the last settings somewhere on the file system so if I use the dialog again, they are still present.
Hello! Just discovered your plugin and wanted to give it a try. Everything's working fine when I manually open the project Tools section and click on the "Add Migration" option. However, a much more convenient approach for me would be to call the command with a shortcut, so I assigned one to the "Add Migration" option in Rider's Keymap section. However, after trying to call the command with a shortcut, I'm getting a null pointer exception:
In case this is not a bug related to the plugin, is there a way to trigger the plugin's commands by using a shortcut? Opening the explorer window, finding the project, rightclicking it and going through several context menus before reaching the command is a little too much hassle when one could simply open the same tab with a couple key strokes.๐
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.