VSCode how to clear workspaceState data globally? - visual-studio-code

I have implemented a backup per workspace functionality in my extension using workspaceState. Since the data can be sensitive - I'd like to clear all workspaceStates on extension deactivation/uninstall.
The ExtensionContext provides no ability to clear all extension related data across different workspaces with their workspaceStates.
So I've considered saving data on the ExtensionContext globalState, tagging each entry with a workspace id. Problem is that the workspace namespace doesn't provide a way to uniquely identify the current workspace. I thought about hashing workspace name and path but both of these things are changeable and any change will destroy the pointer to the data. This is exactly why I cant just write files to internal folders. The only other solution I have is to write the backup data directly to the workspace and I'd like to avoid that.
How does VSCode maintain the knowledge of which workspaceState belongs to which workspace? How can I tie data to the workspace but have access from anywhere else in VSCode?

Side note: You should avoid saving sensitive data in general. And if necessary, try to encrypt it.
Anyway:
I don't have the full answers but i was researching something similar (An extension I use crashes due to now invalid settings in the WorkspaceState).
I found the Storage for the Workspace state in this folder (windows):
%appdata%\Code\User\workspaceStorage\
In there, you find a lot of folders with hex-based names. Inside those folders, I always found 2 Files named state.vscdb and state.vscdb.backup.
There usually is a 3rd file called workspace.json which helps you figure out if you are in the correct workspace. (but you'd have to iterate through all the folders - maybe there is a way to figure out the folder name coming from the extension API?)
If you open the state.vscdb-file you find something that looks quite like a serialized object set in my eyes. It does have some Seperator chars of unknown function. But you also find full paths or names in there that clearly origin from different modules of VSC - Including the extensions.
I don't need to worry about the other cached stuff i'm just gonna delete the whole folder to fix my current issue. But I'm pretty sure, one can figure out the way the file is built and edit out your sensitive data if one has to.
The state.vscdb.backup-file looks pretty much like what the name is telling you: they probably just make a copy of the other file every few minutes so you have a fallback position.

To add to the conversation, there are two SQLite state databases:
<user-data-dir>\User\globalStorage\state.vscdb
<user-data-dir>\User\workspaceStorage\<workspace.id>\state.vscdb
Depending on how VS Code was launched you could have a Single Folder Workspace or a Multi-Folder Workspace that is global or local. Globally, the data lives here:
Linux: $HOME/.config/Code/
OS X: $HOME/Library/Application Support/Code/
Windows: %APPDATA%\Code\
Locally, the data will be in the .vscode folder of the current workspace.
In my situation:
I open a new workspace.
Set it up as I want it to start every time.
Makes copies of the two SQLite databases.
Copy over the databases before launching VS Code.
This leads to a clean VS Code state.
To see how workspace.id is generated check this link.

Related

Data factory: File move

I am working on data factory and was wondering if there are any activities to just "move files" without actually reading them rather than "copy data" (which seems like does a read operation)?
I am trying to move files if any exist from one folder to another and if there are many files, since copy data reads each file, it makes the process slow.
Any suggestion. This is how my current data source looks like and all I want to do is, if there is any csv file exists at the location move it without reading it per say.
So here is a MSFT link I followed to move files.
https://learn.microsoft.com/en-us/azure/data-factory/solution-template-move-files
This tutorial was not very detailed when it comes to explaining everything. Like it assumes that the user needs parameters. I did as it said but my datasets were pointing to exactly where files need to be picked up and land, so I left the parameters empty. Debugging or running the trigger didn't move a file.. solution didn't work.
I had to remove the parameters created in the template to make this work. In case its helpful to some. File move started happening after that.
So lesson learned, empty parameters wont work. If you don't need them remove them.
Also, I watched this tutorial in case its helpful to some one.
https://www.youtube.com/watch?v=u_X_f4z8zoQ

Where to store global binary data for a vscode extension

I've written a language server extension for VS code. In order to improve start-up time, I'd like to cache some global state. I'm struggling to find a safe, user transparent, location.
The cache is shared between all workspaces
It consists of 200-300MB of serialized data
It should persist between updates of the extension
The extension is cross-platform
I've discovered the following four options, but none of them seem appropriate:
ExtensionContext.extensionPath: This is almost perfect. Obvious to the user, safe sandboxed space. However, it's wiped on extension update.
ExtensionContext.storagePath: This is not global, and hard for the user to clear, so would very quickly end up using GBs of storage space.
ExtensionContext.globalState: Placing 300MB of binary data into a JSON dictionary store seems bad.
%UserData%/linux/OSX equivalents: Adding and deleting files in uncontrolled general userspace is a risk I'd rather avoid.
Where's the appropriate place to store this data?
The January 2019 release of VS Code added ExtensionContext.globalStoragePath, which is a global version of storagePath
An absolute file path in which the extension can store global state. The directory might not exist on disk and creation is up to the extension. However, the parent directory is guaranteed to be existent.
https://code.visualstudio.com/updates/v1_31#_global-storage-path
You might want to consider creating a file path defined in the User Settings; I think this solution covers all of your requirements.
You can set a default value in the package.json and it's transparent to the user - they can change it if they want to.
More info here: https://code.visualstudio.com/api/references/contribution-points#contributes.configuration

Should A Program Create XDG Folders?

Let's say I'm writing a program, and I want it to follow the XDG Base Directory Specification for where it puts its files (app foo uses $XDG_CONFIG_HOME/foo as the directory for configuration files if XDG_CONFIG_HOME is set and non-blank, or ~/.config/foo, or fails with an error if the home directory can't even be resolved).
Is there a correct/specified behavior for the situation where for example XDG_CONFIG_HOME is set and non-blank, but that directory doesn't exist? Or if there is no such variable, and ~/.config doesn't exist? Is it expected that my program attempt to create it? Or is the non-existance of that directory considered an error on the environment's/system's part, and my program should avoid doing anything about it (just bail with an error)?
Note: I'm not asking if I should create ~/.config/foo - obviously that's a yes; I'm asking if I should create ~/.config itself, if it doesn't exist.
(To be more pedantic: obviously some program should create them - the question is whether it's solely the system's/desktop's/user's job to do so, or if any program should try creating the relevant directories if they don't exist?)
I've tried reading the XDG Base Directory Specification, which says that when attempting to write its files, the program may create the requisite directory, but it's unclear if this is referring to just the application's specific/"personal" sub-directory in the XDG base directories, or if this is meant for the XDG base directories themselves.
P.S. Usually I have a good idea of what tags to use, but here I'm really uncertain: please edit this post or suggest improvements to give it proper tags.
From the XDG Base Directory Specification:
If, when attempting to write a file, the destination directory is
non-existant an attempt should be made to create it with permission
0700. If the destination directory exists already the permissions should not be changed. The application should be prepared to handle
the case where the file could not be written, either because the
directory was non-existant and could not be created, or for any other
reason. In such case it may chose to present an error message to the
user.
I would interpret this so application should try to create the XDG base directory (or any directory required for the destination) and only display an error if it is unable to do so.
I've settled on my own answer after a few years of thinking:
never create non-standard base XDG directories, but
it may be okay to automatically create the standard XDG base directories, and
you should automatically create any of your application's subdirectories within the base directories.
I think it can be good to be automatically helpful, but it is also very important to not worsen a user's mistakes.
If I write XDG_DATA_HOME=~/.locals/hare in my environment variable configuration, I might have wanted that, but it's much more likely that I made a typo of ~/.local/share. So the most helpful, least disruptive, and least wrong thing to do in that case is to report the lack of the requested XDG base directory.
So, if the user has specified a custom XDG base directory, and that base directory does not exist, never try to create it. Don't put your user in a situation where for example next to their standard ~/.config directory they get a ~/.configs or ~/.comfig directory which also contains some of their configurations, until one day they fix the typo and suddenly their programs behave as if they were reset to the defaults. This is a situation where early detection of mistakes is the most helpful thing to do in the long run, so tell the user immediately "this doesn't exist".
But if the user has not asked for a custom base directory, and you're about to use the known, standard location, then it's fine to try to automatically create it, if you ensure you only create it with reasonable ownership, permissions, and so on.
Finally, when the base XDG directory exists, most apps should probably make their own subdirectory inside that, and you definitely should create that app-specific directory, and any other subdirectories inside that one, automatically.

Buildr: adding a path to the generated eclipse/idea files

I have a legacy java project that we have been moving to buildr/artifactory from ant/jars in svn.
The primary code is in the default (src/main/java) folder, but we have a few external source paths, for various tests that we can't move into the default folder, but we want to have access with it.
Currently, when adding a new library/regenerating IDE fields, it does not pick up these source paths, and I can't find a succinct discussion in the buildr manual for how to actually add them, rather than re-adding everything manually in eclipse (which just gets wiped out on the next regen).
Any idea how to have multiple source paths get picked up explicitly by buildr so that the idea/eclipse targets generate properly?
There are two ways that I know will work with IDEA. The second one might also work with Eclipse, while the first is specific to the idea task.
The IDEA-specific solution:
define 'proj' do
# ...
iml.main_source_directories << _('src/other')
end
iml also has test_source_directories and excluded_directories arrays you can append to.
The possibly eclipse-compatible solution, with more background than you probably want:
The iml object gets its default values for the main and test source directory arrays from project.compile.sources and project.test.compile.sources (slight simplification; resources are considered also). Buildr defines these .sources project attributes from the layout, so instead of explicitly appending to the iml attributes, you could use a custom layout for your project that includes your special source paths. That might work with the eclipse task, but I haven't tried it.

iPhone Dev - How important is Project.pbxproj?

What does this file hold and how important is it to keep it "correct"?
I've seen people write scripts to just merge any change dealing with it and I've heard others merging it manually every time.
What is the correct way to handle it and why?
The project.pbxproj contains all of the metadata about your project that Xcode uses to build it; the settings, the file references, configuration, targeted platforms, etc...
I.e. it is a critically important.
There really isn't a great answer for this. Typically, teams will avoid conflict by limiting edits to the project to one team member at a time.
The Xcode team has put a lot of effort into making the file merge-friendly. In managing several large projects via svn, I've generally found that the merges are automatic and painless.
Until they aren't. And when they aren't, revert, merge changes by hand (i.e. make the changes in the project that conflicted), and move on.
Try my script xUnique.
What it does:
convert project.pbxproj to JSON format
Iterate all objects in JSON and give every UUID an absolute path, and create a new UUID using MD5 hex digest of the path
All elements in this json object is actually connected as a tree
We give a path attribute to every node of the tree using its unique attribute; this path is the absolute path to the root node,
Apply MD5 hex digest to the path for the node
Replace all old UUIDs with the MD5 hex digest and also remove unused UUIDs that are not in the current node tree and UUIDs in wrong format
Sort the project file inlcuding children, files, PBXFileReference and PBXBuildFile list and remove all duplicated entries in these lists
see sort_pbxproj method in xUnique.py if you want to know the implementation;
It's ported from my modified sort-Xcode-project-file, with some differences in ordering PBXFileReference and PBXBuildFile
With different options, you can use xUnique with more flexibility