Bagaimana cara menyalin direktori secara rekursif dengan tegukan?

167

Saya mencoba menjalankan proyek dari direktori yang berfungsi ke server (mesin yang sama). Menggunakan kode berikut:

gulp.src([
    'index.php',
    'css/**',
    'js/**',
    'src/**',
])
.pipe(gulp.dest('/var/www/'));

Saya berharap untuk melihat semua file disalin. Namun itu meratakan struktur dir - semua direktori disalin tetapi setiap file ditempatkan di root/var/www

Gulp sepertinya alat bantu yang bagus tetapi menyalin item seharusnya menjadi proses yang sederhana?

M1ke
sumber
9
Untuk setiap pemirsa baru yang membaca pertanyaan ini, perlu dicatat bahwa jawaban dengan suara terbanyak tidak berfungsi untuk menyelesaikan spesifikasi pertanyaan awal dari direktori yang tidak diratakan. Itu memecahkan masalah yang orang hadapi dengan tidak semua file di dalam direktori disalin, jadi itu berguna!
M1ke
1
Dengan tidak meratakan, maksud Anda bahwa Anda ingin direktori 'css', 'js', dan 'src' hadir /var/www/? Anda bisa mencoba{css,js,src}/**/*
Jason Goemaat
Saya tahu bahwa ekspansi glob bekerja di dalam tegukan, tetapi saya akan bingung jika itu bekerja secara berbeda untuk setiap item sebagai garis individual dalam daftar - karena ekspansi glob pada dasarnya hanya dimaksudkan untuk memperluas ke daftar sebelum eksekusi.
M1ke

Jawaban:

319

Berikut ini berfungsi tanpa meratakan struktur folder:

gulp.src(['input/folder/**/*']).pipe(gulp.dest('output/folder'));

Itu '**/*'adalah bagian yang penting. Ekspresi itu adalah gumpalan yang merupakan alat pemilihan file yang kuat. Misalnya, hanya untuk menyalin file .js gunakan:'input/folder/**/*.js'

kankerbero
sumber
2
pikir Anda lupa menambahkan gulp.dest. Seharusnya.pipe(gulp.dest('output/folder'));
Matthew Sprankle
3
Bagaimana Anda melakukan ini dengan ekstensi file tertentu?
Chev
1
Bisakah Anda mengedit jawaban untuk memberikan contoh untuk set file asli? Saya tidak yakin bagaimana ini lebih tepat tetapi saya akan senang melihat cara kerjanya dibandingkan dengan {base:"."}metode ini.
M1ke
2
Penting untuk dicatat bahwa basedefaultnya adalah "folder" seperti yang diberikan dalam jawaban ini. Dengan kata lain, basis dimulai di mana pola gumpalan dimulai. Ini membantu saya untuk memahami di mana file saya akan berakhir dan juga mengapa Anda tidak perlu **/*dalam gulp.destparameter. Gulp mengambil semua yang ada di glob dan meletakkannya di folder dest dengan struktur yang sama.
Neil Monroe
3
Ini tidak sepenuhnya menjawab pertanyaan yang diajukan. Ini adalah solusi yang bagus untuk cara menyalin secara rekursif dengan benar, tetapi itu tidak menjawab bagaimana memodifikasi direktori basis.
ty1824
173

Ternyata untuk menyalin struktur direktori yang lengkap gulpperlu disediakan basis untuk gulp.src()metode Anda .

Jadi gulp.src( [ files ], { "base" : "." })dapat digunakan dalam struktur di atas untuk menyalin semua direktori secara rekursif.

Jika, seperti saya, Anda mungkin lupa ini lalu coba:

gulp.copy=function(src,dest){
    return gulp.src(src, {base:"."})
        .pipe(gulp.dest(dest));
};
M1ke
sumber
1
Tambahkan konfigurasi "cwd" untuk mengatur direktori kerja saat ini.
Skarllot
3
Jika basemasih membingungkan Anda, lihat stackoverflow.com/a/35848322/11912 yang berfungsi menjelaskannya dengan baik.
James Skemp
60

Jadi - solusi menyediakan karya dasar mengingat bahwa semua jalur memiliki jalur dasar yang sama. Tetapi jika Anda ingin memberikan jalur dasar yang berbeda, ini masih tidak akan berhasil.

Salah satu cara saya memecahkan masalah ini adalah dengan membuat awal jalur relatif. Untuk kasus Anda:

gulp.src([
    'index.php',
    '*css/**/*',
    '*js/**/*',
    '*src/**/*',
])
.pipe(gulp.dest('/var/www/'));

Alasan ini berhasil adalah bahwa Gulp menetapkan basis menjadi akhir dari chunk eksplisit pertama - the * menyebabkannya untuk menetapkan basis pada cwd (yang merupakan hasil yang kita semua inginkan!)

Ini hanya berfungsi jika Anda dapat memastikan struktur folder Anda tidak akan memiliki jalur tertentu yang bisa cocok dua kali. Misalnya, jika Anda memiliki randomjs/level yang sama dengan js, Anda akan berakhir dengan mencocokkan keduanya.

Ini adalah satu-satunya cara yang saya temukan untuk memasukkan ini sebagai bagian dari fungsi gulp.src tingkat atas. Akan lebih mudah untuk membuat plugin / fungsi yang dapat memisahkan masing-masing gumpalan tersebut sehingga Anda dapat menentukan direktori dasar untuknya.

ty1824
sumber
Saya pikir harus mulai dengan beberapa jalur dasar mungkin melampaui ruang lingkup pertanyaan. Dari pertanyaan awal saya, saya memindahkan file ke jalur absolut, tetapi masalah tetap terjadi, bahwa tanpa menentukan basis, semua file dari semua gumpalan saya disalin ke direktori tunggal tanpa hierarki yang ada diikuti.
M1ke
2
@ M1ke Memang benar, titik utama pertanyaan Anda tidak diarahkan pada berbagai jalur dasar. Namun, Anda sebutkan However it flattens the dir structure - all directories are copied but every file is placed in the root /var/www, dan ini sebenarnya bagaimana saya menemukan pertanyaan Anda - saya sedang mencari solusi bagaimana menyalin secara rekursif dengan jalur dasar yang berbeda. Pada dasarnya, solusi ini berfungsi untuk kasing Anda tanpa harus menentukan basis default, tetapi juga untuk
kasing
6
Jawaban ini luar biasa. Ini berkaitan secara khusus dengan menyalin jalan dari titik awal yang sewenang-wenang, misalnya. src bisa 'assets/subdir/*fonts/*'untuk menyalin dir font.
Wtower
-4

Jika Anda ingin menyalin seluruh isi folder secara rekursif ke folder lain, Anda dapat menjalankan perintah windows berikut dari tegukan:

xcopy /path/to/srcfolder /path/to/destfolder /s /e /y

The /ypilihan pada akhirnya adalah untuk menekan pesan konfirmasi menimpa.

Di Linux, Anda dapat menjalankan perintah berikut dari tegukan:

cp -R /path/to/srcfolder /path/to/destfolder

Anda dapat menggunakan plugin gulp-exec atau gulp-run untuk menjalankan perintah sistem dari gulp.

Tautan yang berhubungan:

  1. penggunaan xcopy

  2. tegukan-eksekutif dan tegukan-lari

Manoj Amalraj
sumber
7
Masalah dengan jatuh kembali ke shell di sini adalah bahwa Anda akan kehilangan kemampuan untuk menjalankan perintah lain di aliran, seperti alat kompresi atau analitik.
M1ke