3
1

More than 3 years have passed since last update.

MacでVSCode Remote ContainersをCLIから直接開く

Posted at

仕組み

一度VSCode Remote Containersを開いた後 cat ~/Library/Application\ Support/Code/storage.json
windowsState > lastActiveWindow > folder を見ると以下のような感じになっているのが分かります。

    "windowsState": {
        "lastActiveWindow": {
            "folder": "vscode-remote://dev-container%2B2f557365722f6e616d652f646576656c6f702f70726f6a656374/usr/src",
            "backupPath": "...",
            "remoteAuthority": "dev-container+2f557365722f6e616d652f646576656c6f702f70726f6a656374",
            "uiState": {
                "mode": 1,
                "x": 0,
                "y": 23,
                "width": 3440,
                "height": 1417
            }
        },
        "openedWindows": []
    },

この folder のURLが分かれば

$ code --folder-uri vscode-remote://dev-container%2B2f557365722f6e616d652f646576656c6f702f70726f6a656374/usr/src

このように直接CLIから立ち上げる事が可能です。

2f557365722f6e616d652f646576656c6f702f70726f6a656374 の部分は16進数文字列になっていて
これをデコードすると /User/name/develop/project となります。また %2B が含まれているのでURLエンコードされているのが分かります。
最後の /usr/srcdevcontainer.jsonworkspaceFolder で指定したパスになります。
これらを踏まえて全体のURL構成要素としては

"vscode-remote://" + URI.encode_www_form_component("dev-container+" + "/User/name/develop/project".unpack('H*')) + "/usr/src"

となっているようです。

スクリプトの作成

パスを指定したらVSCode Remote Containersを起動する為のURLを生成してくれるスクリプトを書いてみます。
指定したパス配下の .devcontainer/devcontainer.jsonworkspaceFolder を読み込んで生成してます。

main.rb
# frozen_string_literal: true
# !/usr/bin/env ruby
require 'json'

module VSCodeRemoteContainer
  class Utility
    def initialize
    end

    def generate_url(root_path)
      folder = find_workspace_folder(root_path)
      path = "dev-container+#{root_path.unpack('H*')[0]}"
      puts "vscode-remote://#{URI.encode_www_form_component(path)}#{folder}"
    end

    def find_workspace_folder(root_path)
      unless File.exist?("#{root_path}/.devcontainer/devcontainer.json")
        puts 'Not found devcontainer.json file.'
        return
      end

      config = JSON.parse(File.read("#{root_path}/.devcontainer/devcontainer.json"))
      config['workspaceFolder']
    end
  end
end

VSCodeRemoteContainer::Utility.new.generate_url(*ARGV)

上記を main.rb として保存し以下の様に実行するとURLが生成されます

$ ruby main.rb '/User/name/xxxx'
# => vscode-remote://dev-container%2B2f557365722f6e616d652f646576656c6f702f70726f6a656374/usr/src

AlfredのWorkflowsの作成

今回はghqと組み合わせて動作するWorkflowsを作成してみました。
動作イメージとして↓のようにリポジトリ名を指定して直接VSCodeをコンテナ内で起動しています。

Workflowsを作成するにあたって上記のスクリプトに追記しました。

module VSCodeRemoteContainer
  class Utility
    attr_accessor :bin_path
    def initialize
      @bin_path = ENV['GHQ_PATH'] || '/usr/local/bin'
    end

    def ghq_exists?
      !`which #{@bin_path}/ghq`.empty?
    end

    def search
      return unless ghq_exists?

      result = []
      `#{@bin_path}/ghq list --full-path`.split(/\R/).each do |d|
        Dir.foreach(d) do |path|
          next if ['.', '..'].include?(path)

          file = File.join(d, path)
          result << d if file.include?('.devcontainer')
        end
      end
      result
    end
  end
end

やってる事は ghq を使って対象のリポジトリ一覧をとってきて、
.devcontainer ディレクトリがあるリポジトリだけを返すようにしてます。

出来上がったものは
https://gist.github.com/Slowhand0309/253bb296cd7acb089601d2b32da4723b
こちらに置いております。とりあえず作ってみた程度なので不具合等見つけたら
ご連絡頂けると助かります。
zshをベースに作ってますが、お使いのシェルでお好みで修正して頂ければ :pray:

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1