list_enabled_extensions 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8a06e95534c9bd4d57500dbbff08e25d59f2837737cb0e2c11eb99bb72ff4ee4
4
+ data.tar.gz: 8ebde44c421028931f828ea2490cfd68a3840b3b7b0df54de6a12f5b8278c15b
5
+ SHA512:
6
+ metadata.gz: 5cbb649c340505d1722d7b689b9714df83c9d54e59f7515c7ba2d6f7d11876c40d4a326eaebcaa5bff2c72076aab2726a7fb4eb26185141025c205e3c5a302b5
7
+ data.tar.gz: 794b9b169e86cbc06b1bd0d73354a3fce04828d348d1b7c4693cf1d7b8e9bea815b6a73e30c3132db53ba1eafa2c11f1235b20120be943e8fd070a6c8ce81309
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ build/
2
+ *gem
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'pathname'
3
+
4
+ load Pathname.new(__dir__).join('list_enabled_extensions').to_s
@@ -0,0 +1,105 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'pathname'
5
+ require_relative '../lib/database_reader'
6
+ require_relative '../lib/workspace_storage_finder'
7
+
8
+ class CommandLineInterface
9
+ def initialize
10
+ @options = {}
11
+ parse_options
12
+ end
13
+
14
+ def run
15
+ if db_path
16
+ read_specific_db
17
+ else
18
+ search_for_db
19
+ end
20
+ rescue WorkspaceStorageFinder::Error, DatabaseReader::Error => e
21
+ $stderr.puts e.message
22
+ exit 1
23
+ end
24
+
25
+ private
26
+
27
+ def parse_options
28
+ OptionParser.new do |opts|
29
+ opts.banner = 'Usage: find_workspace_hash [options] [workspace_path (default: current directory)]'
30
+
31
+ opts.on('--storage-path PATH', 'Path to the VSCode workspace storage (If not picked automatically or you changed it)') do |path|
32
+ @options[:workspaces_storage_path] = Pathname.new(path).expand_path
33
+ end
34
+
35
+ opts.on('--db-path PATH', 'Direct path of the state.vscdb file') do |path|
36
+ @options[:db_path] = Pathname.new(path).expand_path
37
+ end
38
+
39
+ opts.on('--sql-query SQL QUERY', "default: #{DatabaseReader.default_query}") do |path|
40
+ @options[:sql_query] = nil
41
+ end
42
+
43
+ opts.on_tail('-h', '--help', 'Show this message') do
44
+ puts opts
45
+ exit
46
+ end
47
+ end.parse!
48
+ end
49
+
50
+ def read_specific_db
51
+ print_extensions_maybe(db_reader: db_reader(path: db_path))
52
+ end
53
+
54
+ def search_for_db
55
+ storage_finder = WorkspaceStorageFinder.new(path: workspaces_storage_path)
56
+ print_extensions_maybe(db_reader: db_reader(path: storage_finder.find_path(needle: current_workspace_path).join('state.vscdb')))
57
+ end
58
+
59
+ def print_extensions_maybe(db_reader:)
60
+ extensions = db_reader.extensions
61
+ if extensions.any?
62
+ puts "\e[38;5;10mFOUND EXTENSIONS:\e[0m"
63
+ extensions.each do |extension|
64
+ puts "#{extension}"
65
+ end
66
+ else
67
+ $stderr.puts "No extensions found in the database file '#{db_reader.path}' ❌"
68
+ exit 1
69
+ end
70
+ end
71
+
72
+ def db_reader(path: db_path)
73
+ DatabaseReader.new(path:)
74
+ end
75
+
76
+ def db_path
77
+ @options[:db_path]
78
+ end
79
+
80
+ def current_workspace_path
81
+ @current_workspace_path ||= Pathname.new(ARGV[0] || Dir.pwd).expand_path
82
+ end
83
+
84
+ def workspaces_storage_path
85
+ @workspaces_storage_path ||= self.class.possible_workspaces_storage_path
86
+ end
87
+
88
+ class << self
89
+ def possible_workspaces_storage_path
90
+ case RbConfig::CONFIG['host_os']
91
+ when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
92
+ Pathname.new(ENV.fetch('APPDATA') { raise 'APPDATA environment variable not set.' })
93
+ when /darwin|mac os/
94
+ Pathname.new(Dir.home) + 'Library/Application Support'
95
+ when /linux|solaris|bsd/
96
+ Pathname.new(Dir.home) + '.config'
97
+ else
98
+ raise 'Unsupported OS'
99
+ end.join('Code/User/workspaceStorage')
100
+ end
101
+ end
102
+ end
103
+
104
+ # Run the script
105
+ CommandLineInterface.new.run
@@ -0,0 +1,53 @@
1
+ require 'json'
2
+ require 'sqlite3'
3
+ require 'pathname'
4
+ require 'forwardable'
5
+
6
+ class DatabaseReader
7
+ extend Forwardable
8
+ class Error < StandardError; end
9
+ class NotFoundError < Error; end
10
+
11
+ def initialize(path:, query: nil)
12
+ @path = Pathname.new(path)
13
+ @query = query || default_query
14
+ end
15
+
16
+ delegate default_query: :'self.class'
17
+
18
+ def extensions
19
+ @extensions ||=
20
+ JSON.parse(query_extensions.dig(0, 1) || raise(NotFoundError, "Unexpected query result #{query_extensions}"))
21
+ .map { |ext| ext['id'] }
22
+ end
23
+
24
+ private
25
+
26
+ def query_extensions
27
+ connection.execute(query)
28
+ rescue SQLite3::Exception => e
29
+ raise Error, "Error querying database: #{e}"
30
+ ensure
31
+ connection.close if connection
32
+ end
33
+
34
+ def connection
35
+ return @connection if @connection && !@connection.closed?
36
+
37
+ @connection = SQLite3::Database.new(path.to_s)
38
+ rescue SQLite3::Exception => e
39
+ raise Error, "Error opening database: #{e} (path: #{path})"
40
+ end
41
+
42
+ public
43
+
44
+ attr_reader :path, :query
45
+
46
+ class << self
47
+ def default_query
48
+ <<~SQL
49
+ SELECT * FROM ItemTable WHERE key LIKE 'extensionsIdentifiers/enabled'
50
+ SQL
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,34 @@
1
+ require 'json'
2
+ require 'pathname'
3
+
4
+ class WorkspaceStorageFinder
5
+ class Error < StandardError; end
6
+ class NotFoundError < Error; end
7
+
8
+ def initialize(path:)
9
+ @root = Pathname.new(path)
10
+ end
11
+
12
+ def find_path(needle:)
13
+ needle = Pathname.new(needle).realpath.to_s
14
+ worspace_storage_paths.each do |path|
15
+ next unless path.exist?
16
+
17
+ workspace_json_path = path.join('workspace.json')
18
+ next unless workspace_json_path.exist?
19
+
20
+ workspace_data = JSON.parse(workspace_json_path.read)
21
+ folder_value = workspace_data['folder']
22
+ return path if folder_value && folder_value == "file://#{needle}"
23
+ end
24
+
25
+ raise(NotFoundError, "Workspace storage not found for #{needle}. Searched in #{worspace_storage_paths.count} " \
26
+ "folders within \"#{root}\".")
27
+ end
28
+
29
+ def worspace_storage_paths
30
+ @worspace_storage_paths ||= root.children.select(&:directory?)
31
+ end
32
+
33
+ attr_reader :root
34
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: list_enabled_extensions
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - GPT-4
8
+ - Anton Topchii
9
+ autorequire:
10
+ bindir: exe
11
+ cert_chain: []
12
+ date: 2024-05-30 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: 2.5.11
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: 2.5.11
28
+ - !ruby/object:Gem::Dependency
29
+ name: standardrb
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: 1.0.1
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: 1.0.1
42
+ - !ruby/object:Gem::Dependency
43
+ name: minitest
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: 5.23.1
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: 5.23.1
56
+ - !ruby/object:Gem::Dependency
57
+ name: sqlite3
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '1.4'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '1.4'
70
+ description: This gem provides a command-line tool to list enabled VSCode extensions
71
+ for a given workspace.
72
+ email:
73
+ - player1@infinitevoid.net
74
+ executables:
75
+ - list-enabled-extensions
76
+ - list_enabled_extensions
77
+ extensions: []
78
+ extra_rdoc_files: []
79
+ files:
80
+ - ".gitignore"
81
+ - exe/list-enabled-extensions
82
+ - exe/list_enabled_extensions
83
+ - lib/database_reader.rb
84
+ - lib/workspace_storage_finder.rb
85
+ homepage: http://github.com/crawler/list_enabled_extensions
86
+ licenses:
87
+ - MIT
88
+ metadata: {}
89
+ post_install_message:
90
+ rdoc_options: []
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: 3.1.0
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ requirements: []
104
+ rubygems_version: 3.3.27
105
+ signing_key:
106
+ specification_version: 4
107
+ summary: A tool to list enabled VSCode extensions for a workspace
108
+ test_files: []