This commit is contained in:
github-actions[bot] 2022-08-04 06:59:33 +00:00
commit ca571eb691
415 changed files with 125430 additions and 0 deletions

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
*.c linguist-language=Go

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
/_book
/book
*.out*
_zz*

0
.nojekyll Normal file
View File

225
404.html Normal file

File diff suppressed because one or more lines are too long

4
FontAwesome/css/font-awesome.css vendored Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 434 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

27
LICENSE Normal file
View File

@ -0,0 +1,27 @@
Copyright (c) 2015 Golang-China. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

12
Makefile Normal file
View File

@ -0,0 +1,12 @@
# Copyright 2015 Golang-China. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
# install mkbook
# http://www.imagemagick.org/
default:
mdbook serve
clean:

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

240
appendix/appendix.html Normal file

File diff suppressed because one or more lines are too long

79
ayu-highlight.css Normal file
View File

@ -0,0 +1,79 @@
/*
Based off of the Ayu theme
Original by Dempfi (https://github.com/dempfi/ayu)
*/
.hljs {
display: block;
overflow-x: auto;
background: #191f26;
color: #e6e1cf;
padding: 0.5em;
}
.hljs-comment,
.hljs-quote {
color: #5c6773;
font-style: italic;
}
.hljs-variable,
.hljs-template-variable,
.hljs-attribute,
.hljs-attr,
.hljs-regexp,
.hljs-link,
.hljs-selector-id,
.hljs-selector-class {
color: #ff7733;
}
.hljs-number,
.hljs-meta,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params {
color: #ffee99;
}
.hljs-string,
.hljs-bullet {
color: #b8cc52;
}
.hljs-title,
.hljs-built_in,
.hljs-section {
color: #ffb454;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-symbol {
color: #ff7733;
}
.hljs-name {
color: #36a3d9;
}
.hljs-tag {
color: #00568d;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}
.hljs-addition {
color: #91b362;
}
.hljs-deletion {
color: #d96c75;
}

660
book.js Normal file
View File

@ -0,0 +1,660 @@
"use strict";
// Fix back button cache problem
window.onunload = function () { };
// Global variable, shared between modules
function playground_text(playground) {
let code_block = playground.querySelector("code");
if (window.ace && code_block.classList.contains("editable")) {
let editor = window.ace.edit(code_block);
return editor.getValue();
} else {
return code_block.textContent;
}
}
(function codeSnippets() {
function fetch_with_timeout(url, options, timeout = 6000) {
return Promise.race([
fetch(url, options),
new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeout))
]);
}
var playgrounds = Array.from(document.querySelectorAll(".playground"));
if (playgrounds.length > 0) {
fetch_with_timeout("https://play.rust-lang.org/meta/crates", {
headers: {
'Content-Type': "application/json",
},
method: 'POST',
mode: 'cors',
})
.then(response => response.json())
.then(response => {
// get list of crates available in the rust playground
let playground_crates = response.crates.map(item => item["id"]);
playgrounds.forEach(block => handle_crate_list_update(block, playground_crates));
});
}
function handle_crate_list_update(playground_block, playground_crates) {
// update the play buttons after receiving the response
update_play_button(playground_block, playground_crates);
// and install on change listener to dynamically update ACE editors
if (window.ace) {
let code_block = playground_block.querySelector("code");
if (code_block.classList.contains("editable")) {
let editor = window.ace.edit(code_block);
editor.addEventListener("change", function (e) {
update_play_button(playground_block, playground_crates);
});
// add Ctrl-Enter command to execute rust code
editor.commands.addCommand({
name: "run",
bindKey: {
win: "Ctrl-Enter",
mac: "Ctrl-Enter"
},
exec: _editor => run_rust_code(playground_block)
});
}
}
}
// updates the visibility of play button based on `no_run` class and
// used crates vs ones available on http://play.rust-lang.org
function update_play_button(pre_block, playground_crates) {
var play_button = pre_block.querySelector(".play-button");
// skip if code is `no_run`
if (pre_block.querySelector('code').classList.contains("no_run")) {
play_button.classList.add("hidden");
return;
}
// get list of `extern crate`'s from snippet
var txt = playground_text(pre_block);
var re = /extern\s+crate\s+([a-zA-Z_0-9]+)\s*;/g;
var snippet_crates = [];
var item;
while (item = re.exec(txt)) {
snippet_crates.push(item[1]);
}
// check if all used crates are available on play.rust-lang.org
var all_available = snippet_crates.every(function (elem) {
return playground_crates.indexOf(elem) > -1;
});
if (all_available) {
play_button.classList.remove("hidden");
} else {
play_button.classList.add("hidden");
}
}
function run_rust_code(code_block) {
var result_block = code_block.querySelector(".result");
if (!result_block) {
result_block = document.createElement('code');
result_block.className = 'result hljs language-bash';
code_block.append(result_block);
}
let text = playground_text(code_block);
let classes = code_block.querySelector('code').classList;
let has_2018 = classes.contains("edition2018");
let edition = has_2018 ? "2018" : "2015";
var params = {
version: "stable",
optimize: "0",
code: text,
edition: edition
};
if (text.indexOf("#![feature") !== -1) {
params.version = "nightly";
}
result_block.innerText = "Running...";
fetch_with_timeout("https://play.rust-lang.org/evaluate.json", {
headers: {
'Content-Type': "application/json",
},
method: 'POST',
mode: 'cors',
body: JSON.stringify(params)
})
.then(response => response.json())
.then(response => result_block.innerText = response.result)
.catch(error => result_block.innerText = "Playground Communication: " + error.message);
}
// Syntax highlighting Configuration
hljs.configure({
tabReplace: ' ', // 4 spaces
languages: [], // Languages used for auto-detection
});
let code_nodes = Array
.from(document.querySelectorAll('code'))
// Don't highlight `inline code` blocks in headers.
.filter(function (node) {return !node.parentElement.classList.contains("header"); });
if (window.ace) {
// language-rust class needs to be removed for editable
// blocks or highlightjs will capture events
Array
.from(document.querySelectorAll('code.editable'))
.forEach(function (block) { block.classList.remove('language-rust'); });
Array
.from(document.querySelectorAll('code:not(.editable)'))
.forEach(function (block) { hljs.highlightBlock(block); });
} else {
code_nodes.forEach(function (block) { hljs.highlightBlock(block); });
}
// Adding the hljs class gives code blocks the color css
// even if highlighting doesn't apply
code_nodes.forEach(function (block) { block.classList.add('hljs'); });
Array.from(document.querySelectorAll("code.language-rust")).forEach(function (block) {
var lines = Array.from(block.querySelectorAll('.boring'));
// If no lines were hidden, return
if (!lines.length) { return; }
block.classList.add("hide-boring");
var buttons = document.createElement('div');
buttons.className = 'buttons';
buttons.innerHTML = "<button class=\"fa fa-eye\" title=\"Show hidden lines\" aria-label=\"Show hidden lines\"></button>";
// add expand button
var pre_block = block.parentNode;
pre_block.insertBefore(buttons, pre_block.firstChild);
pre_block.querySelector('.buttons').addEventListener('click', function (e) {
if (e.target.classList.contains('fa-eye')) {
e.target.classList.remove('fa-eye');
e.target.classList.add('fa-eye-slash');
e.target.title = 'Hide lines';
e.target.setAttribute('aria-label', e.target.title);
block.classList.remove('hide-boring');
} else if (e.target.classList.contains('fa-eye-slash')) {
e.target.classList.remove('fa-eye-slash');
e.target.classList.add('fa-eye');
e.target.title = 'Show hidden lines';
e.target.setAttribute('aria-label', e.target.title);
block.classList.add('hide-boring');
}
});
});
if (window.playground_copyable) {
Array.from(document.querySelectorAll('pre code')).forEach(function (block) {
var pre_block = block.parentNode;
if (!pre_block.classList.contains('playground')) {
var buttons = pre_block.querySelector(".buttons");
if (!buttons) {
buttons = document.createElement('div');
buttons.className = 'buttons';
pre_block.insertBefore(buttons, pre_block.firstChild);
}
var clipButton = document.createElement('button');
clipButton.className = 'fa fa-copy clip-button';
clipButton.title = 'Copy to clipboard';
clipButton.setAttribute('aria-label', clipButton.title);
clipButton.innerHTML = '<i class=\"tooltiptext\"></i>';
buttons.insertBefore(clipButton, buttons.firstChild);
}
});
}
// Process playground code blocks
Array.from(document.querySelectorAll(".playground")).forEach(function (pre_block) {
// Add play button
var buttons = pre_block.querySelector(".buttons");
if (!buttons) {
buttons = document.createElement('div');
buttons.className = 'buttons';
pre_block.insertBefore(buttons, pre_block.firstChild);
}
var runCodeButton = document.createElement('button');
runCodeButton.className = 'fa fa-play play-button';
runCodeButton.hidden = true;
runCodeButton.title = 'Run this code';
runCodeButton.setAttribute('aria-label', runCodeButton.title);
buttons.insertBefore(runCodeButton, buttons.firstChild);
runCodeButton.addEventListener('click', function (e) {
run_rust_code(pre_block);
});
if (window.playground_copyable) {
var copyCodeClipboardButton = document.createElement('button');
copyCodeClipboardButton.className = 'fa fa-copy clip-button';
copyCodeClipboardButton.innerHTML = '<i class="tooltiptext"></i>';
copyCodeClipboardButton.title = 'Copy to clipboard';
copyCodeClipboardButton.setAttribute('aria-label', copyCodeClipboardButton.title);
buttons.insertBefore(copyCodeClipboardButton, buttons.firstChild);
}
let code_block = pre_block.querySelector("code");
if (window.ace && code_block.classList.contains("editable")) {
var undoChangesButton = document.createElement('button');
undoChangesButton.className = 'fa fa-history reset-button';
undoChangesButton.title = 'Undo changes';
undoChangesButton.setAttribute('aria-label', undoChangesButton.title);
buttons.insertBefore(undoChangesButton, buttons.firstChild);
undoChangesButton.addEventListener('click', function () {
let editor = window.ace.edit(code_block);
editor.setValue(editor.originalCode);
editor.clearSelection();
});
}
});
})();
(function themes() {
var html = document.querySelector('html');
var themeToggleButton = document.getElementById('theme-toggle');
var themePopup = document.getElementById('theme-list');
var themeColorMetaTag = document.querySelector('meta[name="theme-color"]');
var stylesheets = {
ayuHighlight: document.querySelector("[href$='ayu-highlight.css']"),
tomorrowNight: document.querySelector("[href$='tomorrow-night.css']"),
highlight: document.querySelector("[href$='highlight.css']"),
};
function showThemes() {
themePopup.style.display = 'block';
themeToggleButton.setAttribute('aria-expanded', true);
themePopup.querySelector("button#" + get_theme()).focus();
}
function hideThemes() {
themePopup.style.display = 'none';
themeToggleButton.setAttribute('aria-expanded', false);
themeToggleButton.focus();
}
function get_theme() {
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch (e) { }
if (theme === null || theme === undefined) {
return default_theme;
} else {
return theme;
}
}
function set_theme(theme, store = true) {
let ace_theme;
if (theme == 'coal' || theme == 'navy') {
stylesheets.ayuHighlight.disabled = true;
stylesheets.tomorrowNight.disabled = false;
stylesheets.highlight.disabled = true;
ace_theme = "ace/theme/tomorrow_night";
} else if (theme == 'ayu') {
stylesheets.ayuHighlight.disabled = false;
stylesheets.tomorrowNight.disabled = true;
stylesheets.highlight.disabled = true;
ace_theme = "ace/theme/tomorrow_night";
} else {
stylesheets.ayuHighlight.disabled = true;
stylesheets.tomorrowNight.disabled = true;
stylesheets.highlight.disabled = false;
ace_theme = "ace/theme/dawn";
}
setTimeout(function () {
themeColorMetaTag.content = getComputedStyle(document.body).backgroundColor;
}, 1);
if (window.ace && window.editors) {
window.editors.forEach(function (editor) {
editor.setTheme(ace_theme);
});
}
var previousTheme = get_theme();
if (store) {
try { localStorage.setItem('mdbook-theme', theme); } catch (e) { }
}
html.classList.remove(previousTheme);
html.classList.add(theme);
}
// Set theme
var theme = get_theme();
set_theme(theme, false);
themeToggleButton.addEventListener('click', function () {
if (themePopup.style.display === 'block') {
hideThemes();
} else {
showThemes();
}
});
themePopup.addEventListener('click', function (e) {
var theme = e.target.id || e.target.parentElement.id;
set_theme(theme);
});
themePopup.addEventListener('focusout', function(e) {
// e.relatedTarget is null in Safari and Firefox on macOS (see workaround below)
if (!!e.relatedTarget && !themeToggleButton.contains(e.relatedTarget) && !themePopup.contains(e.relatedTarget)) {
hideThemes();
}
});
// Should not be needed, but it works around an issue on macOS & iOS: https://github.com/rust-lang/mdBook/issues/628
document.addEventListener('click', function(e) {
if (themePopup.style.display === 'block' && !themeToggleButton.contains(e.target) && !themePopup.contains(e.target)) {
hideThemes();
}
});
document.addEventListener('keydown', function (e) {
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
if (!themePopup.contains(e.target)) { return; }
switch (e.key) {
case 'Escape':
e.preventDefault();
hideThemes();
break;
case 'ArrowUp':
e.preventDefault();
var li = document.activeElement.parentElement;
if (li && li.previousElementSibling) {
li.previousElementSibling.querySelector('button').focus();
}
break;
case 'ArrowDown':
e.preventDefault();
var li = document.activeElement.parentElement;
if (li && li.nextElementSibling) {
li.nextElementSibling.querySelector('button').focus();
}
break;
case 'Home':
e.preventDefault();
themePopup.querySelector('li:first-child button').focus();
break;
case 'End':
e.preventDefault();
themePopup.querySelector('li:last-child button').focus();
break;
}
});
})();
(function sidebar() {
var html = document.querySelector("html");
var sidebar = document.getElementById("sidebar");
var sidebarLinks = document.querySelectorAll('#sidebar a');
var sidebarToggleButton = document.getElementById("sidebar-toggle");
var sidebarResizeHandle = document.getElementById("sidebar-resize-handle");
var firstContact = null;
function showSidebar() {
html.classList.remove('sidebar-hidden')
html.classList.add('sidebar-visible');
Array.from(sidebarLinks).forEach(function (link) {
link.setAttribute('tabIndex', 0);
});
sidebarToggleButton.setAttribute('aria-expanded', true);
sidebar.setAttribute('aria-hidden', false);
try { localStorage.setItem('mdbook-sidebar', 'visible'); } catch (e) { }
}
var sidebarAnchorToggles = document.querySelectorAll('#sidebar a.toggle');
function toggleSection(ev) {
ev.currentTarget.parentElement.classList.toggle('expanded');
}
Array.from(sidebarAnchorToggles).forEach(function (el) {
el.addEventListener('click', toggleSection);
});
function hideSidebar() {
html.classList.remove('sidebar-visible')
html.classList.add('sidebar-hidden');
Array.from(sidebarLinks).forEach(function (link) {
link.setAttribute('tabIndex', -1);
});
sidebarToggleButton.setAttribute('aria-expanded', false);
sidebar.setAttribute('aria-hidden', true);
try { localStorage.setItem('mdbook-sidebar', 'hidden'); } catch (e) { }
}
// Toggle sidebar
sidebarToggleButton.addEventListener('click', function sidebarToggle() {
if (html.classList.contains("sidebar-hidden")) {
var current_width = parseInt(
document.documentElement.style.getPropertyValue('--sidebar-width'), 10);
if (current_width < 150) {
document.documentElement.style.setProperty('--sidebar-width', '150px');
}
showSidebar();
} else if (html.classList.contains("sidebar-visible")) {
hideSidebar();
} else {
if (getComputedStyle(sidebar)['transform'] === 'none') {
hideSidebar();
} else {
showSidebar();
}
}
});
sidebarResizeHandle.addEventListener('mousedown', initResize, false);
function initResize(e) {
window.addEventListener('mousemove', resize, false);
window.addEventListener('mouseup', stopResize, false);
html.classList.add('sidebar-resizing');
}
function resize(e) {
var pos = (e.clientX - sidebar.offsetLeft);
if (pos < 20) {
hideSidebar();
} else {
if (html.classList.contains("sidebar-hidden")) {
showSidebar();
}
pos = Math.min(pos, window.innerWidth - 100);
document.documentElement.style.setProperty('--sidebar-width', pos + 'px');
}
}
//on mouseup remove windows functions mousemove & mouseup
function stopResize(e) {
html.classList.remove('sidebar-resizing');
window.removeEventListener('mousemove', resize, false);
window.removeEventListener('mouseup', stopResize, false);
}
document.addEventListener('touchstart', function (e) {
firstContact = {
x: e.touches[0].clientX,
time: Date.now()
};
}, { passive: true });
document.addEventListener('touchmove', function (e) {
if (!firstContact)
return;
var curX = e.touches[0].clientX;
var xDiff = curX - firstContact.x,
tDiff = Date.now() - firstContact.time;
if (tDiff < 250 && Math.abs(xDiff) >= 150) {
if (xDiff >= 0 && firstContact.x < Math.min(document.body.clientWidth * 0.25, 300))
showSidebar();
else if (xDiff < 0 && curX < 300)
hideSidebar();
firstContact = null;
}
}, { passive: true });
// Scroll sidebar to current active section
var activeSection = document.getElementById("sidebar").querySelector(".active");
if (activeSection) {
// https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
activeSection.scrollIntoView({ block: 'center' });
}
})();
(function chapterNavigation() {
document.addEventListener('keydown', function (e) {
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
if (window.search && window.search.hasFocus()) { return; }
switch (e.key) {
case 'ArrowRight':
e.preventDefault();
var nextButton = document.querySelector('.nav-chapters.next');
if (nextButton) {
window.location.href = nextButton.href;
}
break;
case 'ArrowLeft':
e.preventDefault();
var previousButton = document.querySelector('.nav-chapters.previous');
if (previousButton) {
window.location.href = previousButton.href;
}
break;
}
});
})();
(function clipboard() {
var clipButtons = document.querySelectorAll('.clip-button');
function hideTooltip(elem) {
elem.firstChild.innerText = "";
elem.className = 'fa fa-copy clip-button';
}
function showTooltip(elem, msg) {
elem.firstChild.innerText = msg;
elem.className = 'fa fa-copy tooltipped';
}
var clipboardSnippets = new ClipboardJS('.clip-button', {
text: function (trigger) {
hideTooltip(trigger);
let playground = trigger.closest("pre");
return playground_text(playground);
}
});
Array.from(clipButtons).forEach(function (clipButton) {
clipButton.addEventListener('mouseout', function (e) {
hideTooltip(e.currentTarget);
});
});
clipboardSnippets.on('success', function (e) {
e.clearSelection();
showTooltip(e.trigger, "Copied!");
});
clipboardSnippets.on('error', function (e) {
showTooltip(e.trigger, "Clipboard error!");
});
})();
(function scrollToTop () {
var menuTitle = document.querySelector('.menu-title');
menuTitle.addEventListener('click', function () {
document.scrollingElement.scrollTo({ top: 0, behavior: 'smooth' });
});
})();
(function controllMenu() {
var menu = document.getElementById('menu-bar');
(function controllPosition() {
var scrollTop = document.scrollingElement.scrollTop;
var prevScrollTop = scrollTop;
var minMenuY = -menu.clientHeight - 50;
// When the script loads, the page can be at any scroll (e.g. if you reforesh it).
menu.style.top = scrollTop + 'px';
// Same as parseInt(menu.style.top.slice(0, -2), but faster
var topCache = menu.style.top.slice(0, -2);
menu.classList.remove('sticky');
var stickyCache = false; // Same as menu.classList.contains('sticky'), but faster
document.addEventListener('scroll', function () {
scrollTop = Math.max(document.scrollingElement.scrollTop, 0);
// `null` means that it doesn't need to be updated
var nextSticky = null;
var nextTop = null;
var scrollDown = scrollTop > prevScrollTop;
var menuPosAbsoluteY = topCache - scrollTop;
if (scrollDown) {
nextSticky = false;
if (menuPosAbsoluteY > 0) {
nextTop = prevScrollTop;
}
} else {
if (menuPosAbsoluteY > 0) {
nextSticky = true;
} else if (menuPosAbsoluteY < minMenuY) {
nextTop = prevScrollTop + minMenuY;
}
}
if (nextSticky === true && stickyCache === false) {
menu.classList.add('sticky');
stickyCache = true;
} else if (nextSticky === false && stickyCache === true) {
menu.classList.remove('sticky');
stickyCache = false;
}
if (nextTop !== null) {
menu.style.top = nextTop + 'px';
topCache = nextTop;
}
prevScrollTop = scrollTop;
}, { passive: true });
})();
(function controllBorder() {
menu.classList.remove('bordered');
document.addEventListener('scroll', function () {
if (menu.offsetTop === 0) {
menu.classList.remove('bordered');
} else {
menu.classList.add('bordered');
}
}, { passive: true });
})();
})();

20
book.toml Normal file
View File

@ -0,0 +1,20 @@
# https://giscus.app
# https://github.com/badboy/mdbook-mermaid
[book]
title = "Go语言圣经"
authors = ["译者:", "chai2010", "Xargin", "CrazySssst", "foreversmart"]
description = "<The Go Programming Language>中文版"
language = "zh"
multilingual = false
src = "."
[build]
build-dir = "book"
[output.html]
additional-css = ["style.css"]
additional-js = ["js/custom.js", "js/bigPicture.js"]
git-repository-url = "https://github.com/gopl-zh/gopl-zh.github.com"
edit-url-template = "https://github.com/gopl-zh/gopl-zh.github.com/edit/master/{path}"
git-repository-icon = "fa-github"

172
builder.go Normal file
View File

@ -0,0 +1,172 @@
// Copyright 2015 ChaiShushan <chaishushan{AT}gmail.com>. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build ingore
// 打包 gopl-zh 为 zip 文件.
//
// 文件名格式: gopl-zh-20151001-2ae607.zip
package main
import (
"archive/zip"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"os/exec"
"path/filepath"
"strings"
"time"
)
func main() {
// Git版本号
gitVersion := getGitCommitVersion()
// zip文件名
zipBaseName := fmt.Sprintf("gopl-zh-%s-%s", time.Now().Format("20060102"), gitVersion[:6])
// 导出Git
exportGitToZip("./_book/" + "gopl-zh-" + gitVersion + ".zip")
os.Remove(zipBaseName + ".zip")
file, err := os.Create(zipBaseName + ".zip")
if err != nil {
log.Fatal("os.Create: ", err)
}
defer file.Close()
zipFile := zip.NewWriter(file)
defer zipFile.Close()
// create /gopl-zh-20151001-2ae607/
f, err := zipFile.Create(zipBaseName + "/")
if err != nil {
log.Fatal(err)
}
if _, err = f.Write([]byte("")); err != nil {
log.Fatal(err)
}
dir := "_book"
filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if err != nil {
log.Fatal("filepath.Walk: ", err)
}
if info.IsDir() {
return nil
}
relpath, err := filepath.Rel(dir, path)
if err != nil {
log.Fatal("filepath.Rel: ", err)
}
filename := filepath.ToSlash(relpath)
if isIngoreFile(filename) {
return nil
}
data, err := ioutil.ReadFile(path)
if err != nil {
log.Fatal("ioutil.ReadFile: ", err)
}
f, err := zipFile.Create(zipBaseName + "/" + filename)
if err != nil {
log.Fatal(err)
}
if _, err = f.Write(data); err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", filename)
return nil
})
fmt.Printf("Done\n")
}
// 获取Git最新的版本号
//
// git log -1
// commit 0460c1b3bb8fbb7e2fc88961e69aa37f4041d6c1
// Merge: b2d582a e826457
// Author: chai2010 <chaishushan{AT}gmail.com>
// Date: Mon Feb 1 08:04:44 2016 +0800
//
// Merge pull request #249 from sunclx/patch-3
//
// fix typo
func getGitCommitVersion() (version string) {
cmdOut, err := exec.Command(`git`, `log`, `-1`).CombinedOutput()
if err != nil {
return "unknown"
}
for _, line := range strings.Split(string(cmdOut), "\n") {
line := strings.TrimSpace(line)
if strings.HasPrefix(line, "commit") {
version = strings.TrimSpace(line[len("commit"):])
return
}
}
return "unknown"
}
// 导出Git到Zip文件
func exportGitToZip(filename string) error {
if !strings.HasSuffix(filename, ".zip") {
filename += ".zip"
}
if _, err := exec.Command(`git`, `archive`, `--format`, `zip`, `--output`, filename, `master`).CombinedOutput(); err != nil {
return err
}
return nil
}
func cpFile(dst, src string) {
err := os.MkdirAll(filepath.Dir(dst), 0666)
if err != nil && !os.IsExist(err) {
log.Fatal("cpFile: ", err)
}
fsrc, err := os.Open(src)
if err != nil {
log.Fatal("cpFile: ", err)
}
defer fsrc.Close()
fdst, err := os.Create(dst)
if err != nil {
log.Fatal("cpFile: ", err)
}
defer fdst.Close()
if _, err = io.Copy(fdst, fsrc); err != nil {
log.Fatal("cpFile: ", err)
}
}
func isIngoreFile(path string) bool {
if strings.HasPrefix(path, ".git") {
return true
}
if strings.HasSuffix(path, ".gitignore") {
return true
}
if strings.HasPrefix(path, "vendor") {
return true
}
if strings.HasPrefix(path, "tools") {
return true
}
if strings.HasPrefix(path, "testdata") {
return true
}
if strings.HasSuffix(path, ".go") {
return true
}
return false
}

BIN
cch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

279
ch1/ch1-01.html Normal file

File diff suppressed because one or more lines are too long

338
ch1/ch1-02.html Normal file

File diff suppressed because one or more lines are too long

375
ch1/ch1-03.html Normal file

File diff suppressed because one or more lines are too long

314
ch1/ch1-04.html Normal file

File diff suppressed because one or more lines are too long

288
ch1/ch1-05.html Normal file

File diff suppressed because one or more lines are too long

295
ch1/ch1-06.html Normal file

File diff suppressed because one or more lines are too long

362
ch1/ch1-07.html Normal file

File diff suppressed because one or more lines are too long

285
ch1/ch1-08.html Normal file

File diff suppressed because one or more lines are too long

240
ch1/ch1.html Normal file

File diff suppressed because one or more lines are too long

242
ch10/ch10-01.html Normal file

File diff suppressed because one or more lines are too long

251
ch10/ch10-02.html Normal file

File diff suppressed because one or more lines are too long

255
ch10/ch10-03.html Normal file

File diff suppressed because one or more lines are too long

266
ch10/ch10-04.html Normal file

File diff suppressed because one or more lines are too long

309
ch10/ch10-05.html Normal file

File diff suppressed because one or more lines are too long

266
ch10/ch10-06.html Normal file

File diff suppressed because one or more lines are too long

535
ch10/ch10-07.html Normal file

File diff suppressed because one or more lines are too long

241
ch10/ch10.html Normal file

File diff suppressed because one or more lines are too long

241
ch11/ch11-01.html Normal file

File diff suppressed because one or more lines are too long

715
ch11/ch11-02.html Normal file

File diff suppressed because one or more lines are too long

310
ch11/ch11-03.html Normal file

File diff suppressed because one or more lines are too long

309
ch11/ch11-04.html Normal file

File diff suppressed because one or more lines are too long

284
ch11/ch11-05.html Normal file

File diff suppressed because one or more lines are too long

253
ch11/ch11-06.html Normal file

File diff suppressed because one or more lines are too long

244
ch11/ch11.html Normal file

File diff suppressed because one or more lines are too long

266
ch12/ch12-01.html Normal file

File diff suppressed because one or more lines are too long

316
ch12/ch12-02.html Normal file

File diff suppressed because one or more lines are too long

412
ch12/ch12-03.html Normal file

File diff suppressed because one or more lines are too long

362
ch12/ch12-04.html Normal file

File diff suppressed because one or more lines are too long

304
ch12/ch12-05.html Normal file

File diff suppressed because one or more lines are too long

371
ch12/ch12-06.html Normal file

File diff suppressed because one or more lines are too long

270
ch12/ch12-08.html Normal file

File diff suppressed because one or more lines are too long

247
ch12/ch12-09.html Normal file

File diff suppressed because one or more lines are too long

240
ch12/ch12.html Normal file

File diff suppressed because one or more lines are too long

288
ch13/ch13-01.html Normal file

File diff suppressed because one or more lines are too long

282
ch13/ch13-02.html Normal file

File diff suppressed because one or more lines are too long

341
ch13/ch13-03.html Normal file

File diff suppressed because one or more lines are too long

410
ch13/ch13-04.html Normal file

File diff suppressed because one or more lines are too long

243
ch13/ch13-05.html Normal file

File diff suppressed because one or more lines are too long

247
ch13/ch13.html Normal file

File diff suppressed because one or more lines are too long

262
ch2/ch2-01.html Normal file

File diff suppressed because one or more lines are too long

275
ch2/ch2-02.html Normal file

File diff suppressed because one or more lines are too long

440
ch2/ch2-03.html Normal file

File diff suppressed because one or more lines are too long

314
ch2/ch2-04.html Normal file

File diff suppressed because one or more lines are too long

301
ch2/ch2-05.html Normal file

File diff suppressed because one or more lines are too long

378
ch2/ch2-06.html Normal file

File diff suppressed because one or more lines are too long

352
ch2/ch2-07.html Normal file

File diff suppressed because one or more lines are too long

240
ch2/ch2.html Normal file

File diff suppressed because one or more lines are too long

359
ch3/ch3-01.html Normal file

File diff suppressed because one or more lines are too long

355
ch3/ch3-02.html Normal file

File diff suppressed because one or more lines are too long

310
ch3/ch3-03.html Normal file

File diff suppressed because one or more lines are too long

269
ch3/ch3-04.html Normal file

File diff suppressed because one or more lines are too long

525
ch3/ch3-05.html Normal file

File diff suppressed because one or more lines are too long

402
ch3/ch3-06.html Normal file

File diff suppressed because one or more lines are too long

240
ch3/ch3.html Normal file

File diff suppressed because one or more lines are too long

325
ch4/ch4-01.html Normal file

File diff suppressed because one or more lines are too long

482
ch4/ch4-02.html Normal file

File diff suppressed because one or more lines are too long

442
ch4/ch4-03.html Normal file

File diff suppressed because one or more lines are too long

495
ch4/ch4-04.html Normal file

File diff suppressed because one or more lines are too long

448
ch4/ch4-05.html Normal file

File diff suppressed because one or more lines are too long

360
ch4/ch4-06.html Normal file

File diff suppressed because one or more lines are too long

240
ch4/ch4.html Normal file

File diff suppressed because one or more lines are too long

276
ch5/ch5-01.html Normal file

File diff suppressed because one or more lines are too long

370
ch5/ch5-02.html Normal file

File diff suppressed because one or more lines are too long

323
ch5/ch5-03.html Normal file

File diff suppressed because one or more lines are too long

362
ch5/ch5-04.html Normal file

File diff suppressed because one or more lines are too long

336
ch5/ch5-05.html Normal file

File diff suppressed because one or more lines are too long

479
ch5/ch5-06.html Normal file

File diff suppressed because one or more lines are too long

281
ch5/ch5-07.html Normal file

File diff suppressed because one or more lines are too long

415
ch5/ch5-08.html Normal file

File diff suppressed because one or more lines are too long

334
ch5/ch5-09.html Normal file

File diff suppressed because one or more lines are too long

288
ch5/ch5-10.html Normal file

File diff suppressed because one or more lines are too long

240
ch5/ch5.html Normal file

File diff suppressed because one or more lines are too long

301
ch6/ch6-01.html Normal file

File diff suppressed because one or more lines are too long

347
ch6/ch6-02.html Normal file

File diff suppressed because one or more lines are too long

331
ch6/ch6-03.html Normal file

File diff suppressed because one or more lines are too long

302
ch6/ch6-04.html Normal file

File diff suppressed because one or more lines are too long

329
ch6/ch6-05.html Normal file

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More