+1

Clone và pull nhiều source git 1 lúc với Bash script

Khi đi làm ở các công ty, chắc hẳn các bạn đã gặp tình trạng được giao 1 task sửa một tính năng trong một source mới mà bạn chưa làm hoặc bạn mới vào công ty. Nhưng để chạy được source thì bạn phải clone source kèo theo đó là rất nhiều thư viện đi theo, phải ngồi clone nhiều source rồi check out gõ đi gõ lại rất nhàm chán. Mình cũng vậy, chán nản với sự lập lập lại của việc gõ mấy lệnh git đó nên mình đã lên google và tìm thử, và mình đã biết tới bash script. Chỉ cần gõ 1 lệnh và đợi nó xong. Không phải gõ đi gõ lại các lệnh đó. Let's go! cùng mình khám phá!

Đầu tiên để chạy được bash script bạn cần gì?

Bạn có thể dùng git bash, hoặc terminal nếu bạn đang xài linux hoặc macos và biết một số khái niệm cơ bản. Bạn có thể bỏ qua phần cơ bản này nếu bạn đã biết,

Hello world

Bạn có thể test thử với chương trình huyền thoại Hello World

echo "Hello World"

Để chạy nhiều lệnh thì chúng ta không thể gõ đi gõ lại nhiều lần thì không khác gì khi chúng ta gõ từng lệnh git cả. Vì thế chúng ta cần viết tất các cả các lệnh cần chạy vô một file chọn file rồi Enter là xong.

Chúng ta sẽ tạo 1 file <tên file>.sh ví dụ: Hello.sh

#!/bin/bash

echo "Hello World!"

#!/bin/bash là đường đẫn trỏ đến lệnh bash

echo "Hello World!" sẽ in ra màn hình Hello world!

Lưu file lại.

Để chạy được bạn cấp quyền thực thi cho file

chmod +x hello.sh

Chạy file

./hello.sh

Biến và tham số

Khai báo biến và sử dụng biến

name="Noka"
echo $name

name="Noka" khai báo biến name và gán giá trị cho nó

echo $name sử dụng nó chúng ta dùng $ cộng tên biến

Tham số và sử dụng tham số

echo $1
./hello.sh noka

Lệnh điều kiện

Cú pháp lệnh điều kiện if [ <Điều kiện> ]; then do

        if [ <Điều kiện> ];
        then
               <Thực hiện nếu điều kiện đúng>
        else
            <Nếu điều kiện sai>
        fi
    fi

Ví dụ

if [ $folder = 'library' ];
        then 
            echo "là thư mục library"
        else
            echo "không phải thư mục library"
        fi

Lệnh lặp

Lệnh duyệt qua một danh sách

for <biến> in <tập hợp>
do
    <thực thi trong vòng lặp>
done

Ví dụ lặp và in ra danh sách file và thư mục trong folder đang đứng

for item in *
do
    echo $item
done

Lười cùng bash script

Sau khi đã lướt sơ cơ bản về bash script, các thành phần cơ bản trên mình lướt qua để phục vụ cho phần lười này. Bạn có thể search thêm nhiều lệnh hữu ích trên google.

Bây giờ chúng ta bắt đầu vào vấn đề chính

Đầu tiên chúng ta cần clone nhiều source chúng ta sẽ tạo ra file đặt tên là clone-source.sh

#! /usr/bin/bash
level_4=library

git clone http://github.com/demo-code.git

mkdir $level_4
cd $level_4

git clone http://github.com/lib-1.git
git clone http://github.com/lib-2.git
git clone http://github.com/lib-3.git
git clone http://github.com/lib-4.git
git clone http://github.com/lib-5.git

Chắc phần git clone đã quá quen thuộc, mình sẽ không nhắc lại!

Giải thích code:

  • B1: Đoạn trên mình sẽ clone source demo-code trước
  • B2: Mình sẽ tạo folder bằng lệnh mkdir <tên folder>
  • B3: Mình cd vào folder mới tạo
  • B4: Kéo các source library vào đây để cho tách biệt
  • Xong

Giờ chúng ta sẽ thêm một ít màu mè và một vài dòng thông báo cho sinh động!

#! /usr/bin/bash

BBlue='\033[1;34m'        # Blue

level_4=library

echo "clone source starting ...."

git clone http://github.com/demo-code.git
echo -e "${BBlue}$(pwd)${Color_Off}"

echo "tao thu muc $level_4"
mkdir $level_4
cd $level_4
echo -e "${BGreen} create folder done! ${Color_Off}"

git clone http://github.com/lib-1.git
echo -e "${BBlue}clone done${Color_Off}"
git clone http://github.com/lib-2.git
echo -e "${BBlue}clone done${Color_Off}"
git clone http://github.com/lib-3.git
echo -e "${BBlue}clone done${Color_Off}"
git clone http://github.com/lib-4.git
echo -e "${BBlue}clone done${Color_Off}"
git clone http://github.com/lib-5.git
echo -e "${BBlue}clone done${Color_Off}"

echo "......... clone source done"

Clone source rồi giờ chúng ta sẽ tới phần checkout nhánh

#! /usr/bin/bash

level_4=library

# Reset
Color_Off='\033[0m'       # Text Reset

# Regular Colors
Black='\033[0;30m'        # Black
Red='\033[0;31m'          # Red
Green='\033[0;32m'        # Green
Yellow='\033[0;33m'       # Yellow
Blue='\033[0;34m'         # Blue
Purple='\033[0;35m'       # Purple
Cyan='\033[0;36m'         # Cyan
White='\033[0;37m'        # White

# Bold
BBlack='\033[1;30m'       # Black
BRed='\033[1;31m'         # Red
BGreen='\033[1;32m'       # Green
BYellow='\033[1;33m'      # Yellow
BBlue='\033[1;34m'        # Blue
BPurple='\033[1;35m'      # Purple
BCyan='\033[1;36m'        # Cyan
BWhite='\033[1;37m'       # White

# Underline
UBlack='\033[4;30m'       # Black
URed='\033[4;31m'         # Red
UGreen='\033[4;32m'       # Green
UYellow='\033[4;33m'      # Yellow
UBlue='\033[4;34m'        # Blue
UPurple='\033[4;35m'      # Purple
UCyan='\033[4;36m'        # Cyan
UWhite='\033[4;37m'       # White

# Background
On_Black='\033[40m'       # Black
On_Red='\033[41m'         # Red
On_Green='\033[42m'       # Green
On_Yellow='\033[43m'      # Yellow
On_Blue='\033[44m'        # Blue
On_Purple='\033[45m'      # Purple
On_Cyan='\033[46m'        # Cyan
On_White='\033[47m'       # White

# High Intensity
IBlack='\033[0;90m'       # Black
IRed='\033[0;91m'         # Red
IGreen='\033[0;92m'       # Green
IYellow='\033[0;93m'      # Yellow
IBlue='\033[0;94m'        # Blue
IPurple='\033[0;95m'      # Purple
ICyan='\033[0;96m'        # Cyan
IWhite='\033[0;97m'       # White

# Bold High Intensity
BIBlack='\033[1;90m'      # Black
BIRed='\033[1;91m'        # Red
BIGreen='\033[1;92m'      # Green
BIYellow='\033[1;93m'     # Yellow
BIBlue='\033[1;94m'       # Blue
BIPurple='\033[1;95m'     # Purple
BICyan='\033[1;96m'       # Cyan
BIWhite='\033[1;97m'      # White

# High Intensity backgrounds
On_IBlack='\033[0;100m'   # Black
On_IRed='\033[0;101m'     # Red
On_IGreen='\033[0;102m'   # Green
On_IYellow='\033[0;103m'  # Yellow
On_IBlue='\033[0;104m'    # Blue
On_IPurple='\033[0;105m'  # Purple
On_ICyan='\033[0;106m'    # Cyan
On_IWhite='\033[0;107m'   # White

echo "start checkout branch $1 UDTN"

for folder in *
do
    if  [[ -d $folder ]]; then
        if [ $folder = 'library' ];
        then 
            cd $folder        
            echo -e "${BRed}${folder}${Color_Off}"
            echo -e "${BBlue}$(pwd)${Color_Off}"
            for sub_folder in *
            do
                cd $sub_folder            
                echo -e "${BRed}${sub_folder}${Color_Off}"
                echo -e "${BBlue}$(pwd)${Color_Off}"
                echo -e "${BBlue}done${Color_Off}"
                git checkout $1
                cd ..
            done
            cd ..
        else
            cd $folder        
            echo -e "${BRed}${folder}${Color_Off}"
            echo -e "${BGreen}$(pwd)${Color_Off}"
            echo -e "${BGreen}done${Color_Off}"
            git checkout $1
            cd ..
        fi
    fi
done

echo "done checkout branch $1 UDTN"

Mình đã để sẵn các mã màu cho bạn nào cần custom cho đẹp mắt. Giải thích phần code

  • Mình sẽ duyệt các folder và file dùng for folder in * chúng ta sẽ kiểm tra có phải folder không bằng lệnh if [[ -d $folder ]]; then, tiếp theo if [ $folder = 'library' ]; nếu là folder library thì chúng ta cần duyệt các folder bên trong nên cần dùng dùng thêm 1 vòng folder để duyệt các sub folder.

Để run file: ở đây mình checkout nhánh dev

chmod +x checkout-source.sh

./checkout-source.sh dev

Bạn có thể làm tương tự cho file pull-source.sh chỉ cần thay lệnh git chekcout bằng lệnh git pull

Bonus thêm generate cho bạn nào làm việc với maven java

#! /usr/bin/bash

level_4=library

# Reset
Color_Off='\033[0m'       # Text Reset

# Regular Colors
Black='\033[0;30m'        # Black
Red='\033[0;31m'          # Red
Green='\033[0;32m'        # Green
Yellow='\033[0;33m'       # Yellow
Blue='\033[0;34m'         # Blue
Purple='\033[0;35m'       # Purple
Cyan='\033[0;36m'         # Cyan
White='\033[0;37m'        # White

# Bold
BBlack='\033[1;30m'       # Black
BRed='\033[1;31m'         # Red
BGreen='\033[1;32m'       # Green
BYellow='\033[1;33m'      # Yellow
BBlue='\033[1;34m'        # Blue
BPurple='\033[1;35m'      # Purple
BCyan='\033[1;36m'        # Cyan
BWhite='\033[1;37m'       # White

# Underline
UBlack='\033[4;30m'       # Black
URed='\033[4;31m'         # Red
UGreen='\033[4;32m'       # Green
UYellow='\033[4;33m'      # Yellow
UBlue='\033[4;34m'        # Blue
UPurple='\033[4;35m'      # Purple
UCyan='\033[4;36m'        # Cyan
UWhite='\033[4;37m'       # White

# Background
On_Black='\033[40m'       # Black
On_Red='\033[41m'         # Red
On_Green='\033[42m'       # Green
On_Yellow='\033[43m'      # Yellow
On_Blue='\033[44m'        # Blue
On_Purple='\033[45m'      # Purple
On_Cyan='\033[46m'        # Cyan
On_White='\033[47m'       # White

# High Intensity
IBlack='\033[0;90m'       # Black
IRed='\033[0;91m'         # Red
IGreen='\033[0;92m'       # Green
IYellow='\033[0;93m'      # Yellow
IBlue='\033[0;94m'        # Blue
IPurple='\033[0;95m'      # Purple
ICyan='\033[0;96m'        # Cyan
IWhite='\033[0;97m'       # White

# Bold High Intensity
BIBlack='\033[1;90m'      # Black
BIRed='\033[1;91m'        # Red
BIGreen='\033[1;92m'      # Green
BIYellow='\033[1;93m'     # Yellow
BIBlue='\033[1;94m'       # Blue
BIPurple='\033[1;95m'     # Purple
BICyan='\033[1;96m'       # Cyan
BIWhite='\033[1;97m'      # White

# High Intensity backgrounds
On_IBlack='\033[0;100m'   # Black
On_IRed='\033[0;101m'     # Red
On_IGreen='\033[0;102m'   # Green
On_IYellow='\033[0;103m'  # Yellow
On_IBlue='\033[0;104m'    # Blue
On_IPurple='\033[0;105m'  # Purple
On_ICyan='\033[0;106m'    # Cyan
On_IWhite='\033[0;107m'   # White

echo "generate file pom for source"

path_file_pom='pom.xml'

echo '<?xml version="1.0" encoding="UTF-8"?>' > $path_file_pom
echo '<project xmlns="http://maven.apache.org/POM/4.0.0"' >> $path_file_pom
echo '         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' >> $path_file_pom
echo '         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">' >> $path_file_pom
echo '    <modelVersion>4.0.0</modelVersion>' >> $path_file_pom
echo '    <groupId>com.hoclamdev</groupId>' >> $path_file_pom
echo '    <artifactId>demo-bash-script</artifactId>' >> $path_file_pom
echo '    <version>1.0.0</version>' >> $path_file_pom
echo '    <packaging>pom</packaging>' >> $path_file_pom
echo '    <modules>' >> $path_file_pom

root_path="$(pwd -P;)/"

echo $root_path

for folder in *
do
    if  [[ -d $folder ]]; then
        if [ $folder = 'library' ];
        then 
            for sub_folder in $folder/*
            do
                full_path="$(cd "$sub_folder"; pwd -P;)"
                relative_path="${full_path#"$root_path"}"
                echo "        <module>${relative_path}</module>" >> $path_file_pom
            done
        else
            full_path="$(cd "$folder"; pwd -P;)"
            relative_path="${full_path#"$root_path"}"
            echo "        <module>${relative_path}</module>" >> $path_file_pom
        fi
    fi
done

echo '    </modules>' >> $path_file_pom
echo '    <properties>' >> $path_file_pom
echo '        <maven.compiler.source>17</maven.compiler.source>' >> $path_file_pom
echo '        <maven.compiler.target>17</maven.compiler.target>' >> $path_file_pom
echo '        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>' >> $path_file_pom
echo '    </properties>' >> $path_file_pom

echo '</project>' >> $path_file_pom

echo "end generate file pom"

Done!

Đây là bài viết đầu tiên của mình, còn nhiều thiếu xót, mong nhận được sự góp ý từ anh/chị/em để hoàn thiện hơn, Cảm ơn @All


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí