Escher-js / SkimmedMilk

0 stars 0 forks source link

step2. branching note #2

Closed psmuler closed 1 year ago

psmuler commented 1 year ago

gitを用いてバージョン管理をしましょう。ボタンを押したらフォルダ選択画面をポップアップし、選択されたフォルダでgit initを実行しましょう

psmuler commented 1 year ago

Electronアプリでボタンをクリックしてフォルダ選択画面を表示し、選択されたフォルダでgit initを実行するには、以下の手順を実行してください。

  1. index.htmlファイルを更新:

"Git Init"というテキストが表示されたボタンを追加します。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>My Electron App</title>
  </head>
  <body>
    <h1>Hello, Electron!</h1>
    <button id="file-btn">Open</button>
    <button id="save-btn">Save</button>
    <button id="git-init-btn">Git Init</button>
    <br />
    <textarea id="text-editor" rows="20" cols="80"></textarea>

    <script src="renderer.js"></script>
  </body>
</html>
  1. renderer.jsファイルを更新:

ボタンがクリックされたときのイベントリスナーを定義し、git initを実行する処理を追加します。

const { ipcRenderer } = require('electron');
const fs = require('fs');
const { exec } = require('child_process');

const fileBtn = document.getElementById('file-btn');
const saveBtn = document.getElementById('save-btn');
const gitInitBtn = document.getElementById('git-init-btn');
const textEditor = document.getElementById('text-editor');

// ... (fileBtn, saveBtn, ipcRendererのイベントリスナーは省略) ...

gitInitBtn.addEventListener('click', () => {
  ipcRenderer.send('open-folder-dialog');
});

ipcRenderer.on('selected-folder', (event, folderPath) => {
  exec(`git init "${folderPath}"`, (error, stdout, stderr) => {
    if (error) {
      console.error(`Error: ${error.message}`);
      return;
    }
    if (stderr) {
      console.error(`Stderr: ${stderr}`);
      return;
    }
    console.log(`Stdout: ${stdout}`);
  });
});
  1. main.jsファイルを更新:

フォルダ選択ダイアログを表示し、選択されたフォルダをrenderer.jsに送信するコードを追加します。

const { app, BrowserWindow, ipcMain, dialog } = require('electron');

// ... (createWindow, app.whenReady, app.onのコードは省略) ...

ipcMain.on('open-folder-dialog', (event) => {
  const options = {
    title: 'Select a folder',
    properties: ['openDirectory'],
  };

  dialog.showOpenDialog(null, options).then((result) => {
    if (!result.canceled) {
      const folderPath = result.filePaths[0];
      event.sender.send('selected-folder', folderPath);
    }
  });
});

// ... (ipcMain.on('open-file-dialog')とipcMain.on('save-file-dialog')のコードは省略) ...

これで、"Git Init"ボタンをクリックするとフォルダ選択画面が表示され、選択されたフォルダでgit initが実行されるようになります。npm startコマンドを使ってアプリを起動し、"Git Init"ボタンをクリックしてフォルダを選択すると、そのフォルダでgit initが実行され、バージョン管理が開始されます。

psmuler commented 1 year ago

git initボタンの処理を書き換え、フォルダを選択するだけの機能にしましょう。選択したフォルダに.gitがないかを判断し、ない場合は作るよう条件分岐を作りましょう

psmuler commented 1 year ago

"Git Init"ボタンの処理を書き換えて、フォルダを選択するだけの機能にし、選択したフォルダに.gitがない場合にのみgit initを実行するようにするには、以下の手順でrenderer.jsファイルを更新してください。

  1. renderer.jsファイルを更新:

フォルダが選択されたときに.gitがないかをチェックし、ない場合にgit initを実行する処理を追加します。

const { ipcRenderer } = require('electron');
const fs = require('fs');
const { exec } = require('child_process');

const fileBtn = document.getElementById('file-btn');
const saveBtn = document.getElementById('save-btn');
const gitInitBtn = document.getElementById('git-init-btn');
const textEditor = document.getElementById('text-editor');

// ... (fileBtn, saveBtn, ipcRendererのイベントリスナーは省略) ...

gitInitBtn.addEventListener('click', () => {
  ipcRenderer.send('open-folder-dialog');
});

ipcRenderer.on('selected-folder', (event, folderPath) => {
  fs.access(`${folderPath}/.git`, fs.constants.F_OK, (err) => {
    if (err) {
      // .gitフォルダが存在しない場合
      exec(`git init "${folderPath}"`, (error, stdout, stderr) => {
        if (error) {
          console.error(`Error: ${error.message}`);
          return;
        }
        if (stderr) {
          console.error(`Stderr: ${stderr}`);
          return;
        }
        console.log(`Stdout: ${stdout}`);
      });
    } else {
      console.log('The .git folder already exists.');
    }
  });
});

これで、"Git Init"ボタンをクリックするとフォルダ選択画面が表示され、選択したフォルダに.gitがない場合にのみgit initが実行されます。

psmuler commented 1 year ago

git initボタンの右側に、現在選択しているフォルダのフォルダパスを表示しましょう

psmuler commented 1 year ago

"Git Init"ボタンの右側に現在選択しているフォルダのフォルダパスを表示するには、以下の手順でindex.htmlrenderer.jsファイルを更新してください。

  1. index.htmlファイルを更新:

フォルダパスを表示するための<span>要素を追加します。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>My Electron App</title>
  </head>
  <body>
    <h1>Hello, Electron!</h1>
    <button id="file-btn">Open</button>
    <button id="save-btn">Save</button>
    <button id="git-init-btn">Git Init</button>
    <span id="folder-path" style="margin-left: 10px;"></span>
    <br />
    <textarea id="text-editor" rows="20" cols="80"></textarea>

    <script src="renderer.js"></script>
  </body>
</html>
  1. renderer.jsファイルを更新:

フォルダが選択されたときに、フォルダパスを<span>要素に表示する処理を追加します。

const { ipcRenderer } = require('electron');
const fs = require('fs');
const { exec } = require('child_process');

const fileBtn = document.getElementById('file-btn');
const saveBtn = document.getElementById('save-btn');
const gitInitBtn = document.getElementById('git-init-btn');
const textEditor = document.getElementById('text-editor');
const folderPathSpan = document.getElementById('folder-path');

// ... (fileBtn, saveBtn, gitInitBtn, ipcRendererのイベントリスナーは省略) ...

ipcRenderer.on('selected-folder', (event, folderPath) => {
  // フォルダパスを表示
  folderPathSpan.textContent = folderPath;

  fs.access(`${folderPath}/.git`, fs.constants.F_OK, (err) => {
    if (err) {
      // .gitフォルダが存在しない場合
      exec(`git init "${folderPath}"`, (error, stdout, stderr) => {
        if (error) {
          console.error(`Error: ${error.message}`);
          return;
        }
        if (stderr) {
          console.error(`Stderr: ${stderr}`);
          return;
        }
        console.log(`Stdout: ${stdout}`);
      });
    } else {
      console.log('The .git folder already exists.');
    }
  });
});

これで、"Git Init"ボタンの右側に現在選択しているフォルダのフォルダパスが表示されます。

psmuler commented 1 year ago

選択しているフォルダが.git管理されているフォルダかどうか判断し、サイン(.gitあり:青丸、無し:赤丸など)を表示しましょう。

psmuler commented 1 year ago

選択しているフォルダが.git管理されているかどうか判断し、青丸(.gitあり)または赤丸(.gitなし)のサインを表示するには、以下の手順でindex.htmlrenderer.jsファイルを更新してください。

  1. index.htmlファイルを更新:

フォルダの.git状態を表示するための<span>要素を追加します。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>My Electron App</title>
  </head>
  <body>
    <h1>Hello, Electron!</h1>
    <button id="file-btn">Open</button>
    <button id="save-btn">Save</button>
    <button id="git-init-btn">Git Init</button>
    <span id="git-status" style="margin-left: 10px;"></span>
    <span id="folder-path" style="margin-left: 10px;"></span>
    <br />
    <textarea id="text-editor" rows="20" cols="80"></textarea>

    <script src="renderer.js"></script>
  </body>
</html>
  1. renderer.jsファイルを更新:

フォルダが選択されたときに、.gitの状態に応じてサイン(青丸または赤丸)を表示する処理を追加します。

const { ipcRenderer } = require('electron');
const fs = require('fs');
const { exec } = require('child_process');

const fileBtn = document.getElementById('file-btn');
const saveBtn = document.getElementById('save-btn');
const gitInitBtn = document.getElementById('git-init-btn');
const textEditor = document.getElementById('text-editor');
const folderPathSpan = document.getElementById('folder-path');
const gitStatusSpan = document.getElementById('git-status');

// ... (fileBtn, saveBtn, gitInitBtn, ipcRendererのイベントリスナーは省略) ...

ipcRenderer.on('selected-folder', (event, folderPath) => {
  // フォルダパスを表示
  folderPathSpan.textContent = folderPath;

  fs.access(`${folderPath}/.git`, fs.constants.F_OK, (err) => {
    if (err) {
      // .gitフォルダが存在しない場合
      gitStatusSpan.innerHTML = '<span style="color: red;">&#11044;</span>';

      exec(`git init "${folderPath}"`, (error, stdout, stderr) => {
        if (error) {
          console.error(`Error: ${error.message}`);
          return;
        }
        if (stderr) {
          console.error(`Stderr: ${stderr}`);
          return;
        }
        console.log(`Stdout: ${stdout}`);
      });
    } else {
      // .gitフォルダが存在する場合
      gitStatusSpan.innerHTML = '<span style="color: blue;">&#11044;</span>';
    }
  });
});

これで、選択しているフォルダが.git管理されているかどうか判断し、青丸(.gitあり)または赤丸(.gitなし)のサインが表示されます。

psmuler commented 1 year ago

git管理されていないフォルダの場合には、ポップアップで「git initするかどうか」を聞くようにしましょう。

psmuler commented 1 year ago

選択しているフォルダが.git管理されていない場合に、ポップアップで「git initするかどうか」を聞くようにするには、以下の手順でrenderer.jsファイルを更新してください。

  1. renderer.jsファイルを更新:

選択しているフォルダが.git管理されていない場合に、confirm関数を使ってポップアップでユーザーに確認を求め、ユーザーが「はい」を選択した場合にgit initを実行する処理を追加します。

const { ipcRenderer } = require('electron');
const fs = require('fs');
const { exec } = require('child_process');

const fileBtn = document.getElementById('file-btn');
const saveBtn = document.getElementById('save-btn');
const gitInitBtn = document.getElementById('git-init-btn');
const textEditor = document.getElementById('text-editor');
const folderPathSpan = document.getElementById('folder-path');
const gitStatusSpan = document.getElementById('git-status');

// ... (fileBtn, saveBtn, gitInitBtn, ipcRendererのイベントリスナーは省略) ...

ipcRenderer.on('selected-folder', (event, folderPath) => {
  // フォルダパスを表示
  folderPathSpan.textContent = folderPath;

  fs.access(`${folderPath}/.git`, fs.constants.F_OK, (err) => {
    if (err) {
      // .gitフォルダが存在しない場合
      gitStatusSpan.innerHTML = '<span style="color: red;">&#11044;</span>';

      // ポップアップでユーザーに確認を求める
      const confirmResult = confirm('This folder is not under Git control. Do you want to run "git init"?');

      if (confirmResult) {
        // ユーザーが「はい」を選択した場合、git initを実行
        exec(`git init "${folderPath}"`, (error, stdout, stderr) => {
          if (error) {
            console.error(`Error: ${error.message}`);
            return;
          }
          if (stderr) {
            console.error(`Stderr: ${stderr}`);
            return;
          }
          console.log(`Stdout: ${stdout}`);
          // git init後に青丸(.gitあり)に変更
          gitStatusSpan.innerHTML = '<span style="color: blue;">&#11044;</span>';
        });
      }

    } else {
      // .gitフォルダが存在する場合
      gitStatusSpan.innerHTML = '<span style="color: blue;">&#11044;</span>';
    }
  });
});

これで、選択しているフォルダが.git管理されていない場合に、ポップアップで「git initするかどうか」を聞くようになります。

psmuler commented 1 year ago

プルダウンメニューを作成し、.git管理フォルダのブランチ一覧を表示するようにしましょう

psmuler commented 1 year ago

プルダウンメニューを作成し、.git管理フォルダのブランチ一覧を表示するには、以下の手順でindex.htmlrenderer.jsファイルを更新してください。

  1. index.htmlファイルを更新:

ブランチ一覧を表示するための<select>要素を追加します。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>My Electron App</title>
  </head>
  <body>
    <h1>Hello, Electron!</h1>
    <button id="file-btn">Open</button>
    <button id="save-btn">Save</button>
    <button id="git-init-btn">Git Init</button>
    <span id="git-status" style="margin-left: 10px;"></span>
    <span id="folder-path" style="margin-left: 10px;"></span>
    <br />
    <select id="branch-select" style="margin-top: 10px;"></select>
    <br />
    <textarea id="text-editor" rows="20" cols="80"></textarea>

    <script src="renderer.js"></script>
  </body>
</html>
  1. renderer.jsファイルを更新:

フォルダが選択されたときに、ブランチ一覧を取得し、プルダウンメニューに表示する処理を追加します。

const { ipcRenderer } = require('electron');
const fs = require('fs');
const { exec } = require('child_process');

const fileBtn = document.getElementById('file-btn');
const saveBtn = document.getElementById('save-btn');
const gitInitBtn = document.getElementById('git-init-btn');
const textEditor = document.getElementById('text-editor');
const folderPathSpan = document.getElementById('folder-path');
const gitStatusSpan = document.getElementById('git-status');
const branchSelect = document.getElementById('branch-select');

// ... (fileBtn, saveBtn, gitInitBtn, ipcRendererのイベントリスナーは省略) ...

function updateBranchList(folderPath) {
  exec(`git -C "${folderPath}" branch`, (error, stdout, stderr) => {
    if (error) {
      console.error(`Error: ${error.message}`);
      return;
    }
    if (stderr) {
      console.error(`Stderr: ${stderr}`);
      return;
    }

    const branches = stdout.split('\n').filter(branch => branch.trim() !== '').map(branch => branch.trim());
    branchSelect.innerHTML = '';

    branches.forEach(branch => {
      const option = document.createElement('option');
      option.text = branch;
      branchSelect.add(option);
    });
  });
}

ipcRenderer.on('selected-folder', (event, folderPath) => {
  // フォルダパスを表示
  folderPathSpan.textContent = folderPath;

  fs.access(`${folderPath}/.git`, fs.constants.F_OK, (err) => {
    if (err) {
      // ... (.gitフォルダが存在しない場合の処理は省略) ...
    } else {
      // .gitフォルダが存在する場合
      gitStatusSpan.innerHTML = '<span style="color: blue;">&#11044;</span>';

      // ブランチ一覧を更新
      updateBranchList(folderPath);
    }
  });
});
psmuler commented 1 year ago

プルダウンメニューに"Create new branch"という項目を表示するようにし、新しいブランチを作る処理を加えましょう

psmuler commented 1 year ago

プルダウンメニューに"Create new branch"という項目を表示し、新しいブランチを作る処理を追加するには、以下の手順でindex.htmlrenderer.jsファイルを更新してください。

  1. index.htmlファイルを更新:

"Create new branch"という項目を追加します。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>My Electron App</title>
  </head>
  <body>
    <h1>Hello, Electron!</h1>
    <button id="file-btn">Open</button>
    <button id="save-btn">Save</button>
    <button id="git-init-btn">Git Init</button>
    <span id="git-status" style="margin-left: 10px;"></span>
    <span id="folder-path" style="margin-left: 10px;"></span>
    <br />
    <select id="branch-select" style="margin-top: 10px;">
      <option>Create new branch</option>
    </select>
    <br />
    <textarea id="text-editor" rows="20" cols="80"></textarea>

    <script src="renderer.js"></script>
  </body>
</html>
  1. renderer.jsファイルを更新:

プルダウンメニューの選択が変更されたときに、"Create new branch"が選択されている場合、新しいブランチ名を入力するプロンプトを表示し、新しいブランチを作成する処理を追加します。

const { ipcRenderer } = require('electron');
const fs = require('fs');
const { exec } = require('child_process');

const fileBtn = document.getElementById('file-btn');
const saveBtn = document.getElementById('save-btn');
const gitInitBtn = document.getElementById('git-init-btn');
const textEditor = document.getElementById('text-editor');
const folderPathSpan = document.getElementById('folder-path');
const gitStatusSpan = document.getElementById('git-status');
const branchSelect = document.getElementById('branch-select');

// ... (fileBtn, saveBtn, gitInitBtn, ipcRendererのイベントリスナーは省略) ...
// ... (updateBranchList関数は省略) ...

branchSelect.addEventListener('change', () => {
  if (branchSelect.value === 'Create new branch') {
    const newBranchName = prompt('Enter the new branch name:');
    if (newBranchName && newBranchName.trim() !== '') {
      const folderPath = folderPathSpan.textContent;
      exec(`git -C "${folderPath}" checkout -b "${newBranchName.trim()}"`, (error, stdout, stderr) => {
        if (error) {
          console.error(`Error: ${error.message}`);
          return;
        }
        if (stderr) {
          console.error(`Stderr: ${stderr}`);
          return;
        }
        console.log(`Stdout: ${stdout}`);
        // ブランチ一覧を更新
        updateBranchList(folderPath);
      });
    }
    // プルダウンメニューの選択をリセット
    branchSelect.value = '';
  }
});

// ... (ipcRendererのイベントリスナーは省略) ...

これで、プルダウ

psmuler commented 1 year ago

フォルダ選択後も"Create new branch"の項目が表示されるようにしましょう

psmuler commented 1 year ago

// ... (他のコードは省略) ...

function updateBranchList(folderPath) { exec(git -C "${folderPath}" branch, (error, stdout, stderr) => { if (error) { console.error(Error: ${error.message}); return; } if (stderr) { console.error(Stderr: ${stderr}); return; }

const branches = stdout.split('\n').filter(branch => branch.trim() !== '').map(branch => branch.trim());
branchSelect.innerHTML = '';

// "Create new branch"の項目を追加
const createNewBranchOption = document.createElement('option');
createNewBranchOption.text = 'Create new branch';
branchSelect.add(createNewBranchOption);

branches.forEach(branch => {
  const option = document.createElement('option');
  option.text = branch;
  branchSelect.add(option);
});

}); }

// ... (他のコードは省略) ...

psmuler commented 1 year ago

フォルダを選択した後、.gitがない場合にgit initしたときに同時に.gitignoreファイルを作成し、以下の項目を書き込みましょう .DS_STORE

psmuler commented 1 year ago

フォルダを選択した後、.gitがない場合にgit initしたときに同時に.gitignoreファイルを作成し、以下の項目を書き込むには、renderer.jsファイルのイベントリスナーで.gitignoreファイルを作成して書き込む処理を追加します。

// ... (他のコードは省略) ...

ipcRenderer.on('selected-folder', (event, folderPath) => {
  // フォルダパスを表示
  folderPathSpan.textContent = folderPath;

  fs.access(`${folderPath}/.git`, fs.constants.F_OK, (err) => {
    if (err) {
      // .gitフォルダが存在しない場合
      gitStatusSpan.innerHTML = '<span style="color: red;">&#11044;</span>';

      const gitInitConfirmed = confirm('This folder is not a git repository. Do you want to run "git init"?');
      if (gitInitConfirmed) {
        exec(`git -C "${folderPath}" init`, (error, stdout, stderr) => {
          if (error) {
            console.error(`Error: ${error.message}`);
            return;
          }
          if (stderr) {
            console.error(`Stderr: ${stderr}`);
            return;
          }
          console.log(`Stdout: ${stdout}`);
          gitStatusSpan.innerHTML = '<span style="color: blue;">&#11044;</span>';

          // .gitignoreファイルを作成して書き込む
          fs.writeFile(`${folderPath}/.gitignore`, '.DS_Store\n', (error) => {
            if (error) {
              console.error(`Error: ${error.message}`);
              return;
            }
            console.log('Created .gitignore file');
          });

          // ブランチ一覧を更新
          updateBranchList(folderPath);
        });
      }
    } else {
      // .gitフォルダが存在する場合
      gitStatusSpan.innerHTML = '<span style="color: blue;">&#11044;</span>';

      // ブランチ一覧を更新
      updateBranchList(folderPath);
    }
  });
});

// ... (他のコードは省略) ...

この変更により、フォルダを選択した後、.gitがない場合にgit initしたときに同時に.gitignoreファイルを作成し、.DS_Storeを書き込みます。

psmuler commented 1 year ago

今回はDS_Storeを書き込みましたが、初期化(git init )時に書き込む事前定義リストを別なファイルあるいは定数で管理し、それを読み込んで.gitignoreに書き込むようにしましょう

psmuler commented 1 year ago

事前定義リストを別のファイルで管理し、それを読み込んで.gitignoreに書き込むには、新しいファイルgitignore_defaults.jsを作成し、その中にリストを定義します。そして、renderer.jsファイルでそのリストをインポートして使用します。

  1. gitignore_defaults.jsファイルを作成し、事前定義リストを定義します。
// gitignore_defaults.js

const defaultGitignoreContent = `
.DS_Store
`;

module.exports = {
  defaultGitignoreContent,
};
  1. renderer.jsファイルでgitignore_defaults.jsをインポートし、.gitignoreファイルの作成時に読み込んだリストを使用します。
const { ipcRenderer } = require('electron');
const fs = require('fs');
const { exec } = require('child_process');
const { defaultGitignoreContent } = require('./gitignore_defaults'); // ここでインポート

// ... (他のコードは省略) ...

ipcRenderer.on('selected-folder', (event, folderPath) => {
  // ... (他のコードは省略) ...

  if (gitInitConfirmed) {
    exec(`git -C "${folderPath}" init`, (error, stdout, stderr) => {
      // ... (他のコードは省略) ...

      // .gitignoreファイルを作成して、事前定義リストを書き込む
      fs.writeFile(`${folderPath}/.gitignore`, defaultGitignoreContent, (error) => {
        // ... (他のコードは省略) ...
      });

      // ... (他のコードは省略) ...
    });
  }

  // ... (他のコードは省略) ...
});

// ... (他のコードは省略) ...

これで、git init時にgitignore_defaults.jsファイルに定義されたリストを読み込んで.gitignoreに書き込むようになります。リストを更新する場合は、gitignore_defaults.jsファイルを編集するだけで済みます。