2016年10月

Linux 基金会宣布成立了 JS 基金会 JS Foundation ,该基金会是一个包容性项目,用于促进指导 JavaScript 生态中各种核心开源项目的发展,其主要任务是管理和资助这些项目,以及培育 JavaScript 生态。

Linux 基金会已经对 JS 生态进行了大量投资

Node.js 社区内部分裂之后,Node.js 代码分成了两个不同的项目:io.js 和 Node.js。后来两个项目和好之后,在 2015 年, Linux 基金会帮助创立了 Node.js 基金会,两个项目合并代码并归于统一的 Node.js 基金会。

JS 基金会也遵循 Node.js 基金会的模式,基金会成员将会支持各种 JavaScript 项目,包括技术指导、人力资源和资金。

IBM 和三星也是基金会成员

基金会的成员包括 Bocoup、IBM、Ripple、Samsung、Sauce Labs、Sense Tecnic Systems、SitePen、StackPath、University of Westminster 和 WebsiteSetup 等。

初始包括的项目有:Appium、 Chassis、 Dojo Toolkit、 ESLint、 Esprima、 Globalize、 Grunt、 Interledger.js、 Intern、 Jed、 JerryScript、 jQuery、 jQuery Mobile、 jQuery UI、 Lodash、 Mocha、 Moment、 Node-RED、 PEP、 QUnit、 RequireJS、 Sizzle 和 webpack。

这些大多数都是顶级的 JavaScript 项目,被成千上万的开发者们所使用。然而我们注意到, Node.js 项目由于有自己的基金会,并没有加入到 JS 基金会之中。

如果同意加入 JS 基金会,这些项目将会从公共开发战略中受益,以消除当今 JavaScript 社区中的混乱状况。基金会会设立所有项目共同遵循的目标,并为核心项目提供资金支持。这些核心项目现今用于服务器端应用、浏览器、云应用和物联网设备。

jQuery 基金会变成了 JS 基金会

JS 基金会并不是凭空建立的,它的核心就是之前的 jQuery 基金会。虽然 jQuery 现在已经发展放缓,甚至很多开发者都惊奇 jQuery 仍然还活着,因为目前已经出现了各种更好的工具。 但是 jQuery 在某种意义上仍然是 JavaScript 的代名词。jQuery 基金会的很多成员在 JavaScript 领域内都很有影响力,所以成立新的 JS 基金会将有助于发挥它们的作用,促进 JavaScript 生态的进一步发展。

在 Linux 和其他类 Uniux 系统中,init(初始化)进程是系统启动时由内核执行的第一个进程,其进程 ID(PID)为 1,并静默运行在后台,直到系统关闭。

init 进程负责启动其他所有的进程,比如守护进程、服务和其他后台进程,因此,它是系统中其它所有进程之母(偏偏叫做“父进程”)。某个进程可以启动许多个子进程,但在这个过程中,某个子进程的父进程结束之后,该子进程的父进程会变成 init 进程。

这么多年过去了,许多的初始化系统在主流 Linux 脱颖而出,和本文中,我将你来看看在 Linux 操作系统最好的初始化系统。

1. System V Init

System V (SysV) 是一个在类 Unix 系统中最为成熟而且大受欢迎的初始化方案,是 Unix/Linux 系统中所有进程的父进程。SysV 是第一个商业 Unix 系统设计的初始化方案。

除了 Gentoo 使用自主的初始化系统、Slackware 使用 BSD 风格的初始化方案外,几乎所有的 Linux 发行版都率先使用 SysV 作为初始化方案。

随着时间的推移,由于一些设计上的缺陷,有几个 SysV 初始化替换方案已经开发出来,用以为 Linux 创建更加高效和完美的初始化系统。

尽管这些替代方案都超越了 SysV 并提供了更多新特性,但它们仍然和原始 SysV 初始化脚本保持兼容。

2. SystemD

SystemD 是一个 Linux 平台中相对较新的初始化方案。它由 Fedora 15 引入,集成了各类工具以便更好的管理系统。主要目的是:系统初始化、管理和跟踪引导进程中和系统运行时所有的系统进程。

Systemd 全面有别于其他传统的 Unix 初始化系统,特别是在启动系统和服务管理方面。它同样兼容 SysV 和 LBS 初始化脚本。

其中较为突出的特性如下:

  • 纯粹、简单、高效的设计
  • 启动时的并发和并行处理
  • 更好的 API
  • 开启可选进程的移除功能
  • 使用 journald 来支持事件日志
  • 使用 systemd calender timers 来支持任务计划
  • 以二进制文件存储日志
  • 保存 systemd 的状态以待今后查看
  • 与 GNOME 更好整合实现等

查看 Systemd 初始化系统简介:https://fedoraproject.org/wiki/Systemd

3. Upstart

Upstart 是一个基于事件的初始化系统,由 Ubuntu 的制作团队开发的,用以替代 SysV。它可以启动不同的系统任务和进程、在系统运行时校验进程并在系统关闭时结束进程。

它是一个使用 SysV 和 Systemd 启动脚本的混合初始化系统,Upstart 中值得一提的特性如下:

  • Ubuntu 的原生初始化系统,但可以运行在其他所有的发行版中
  • 基于事件启动/结束的任务和服务
  • 启动/结束任务和服务时生成事件
  • 可以由其他系统进程发送事件
  • 使用 D-Bus 和 init 进程通信
  • 用户可以启动/结束其各自的进程
  • 可以再现崩溃的进程等

访问 Upstart 主页:http://upstart.ubuntu.com/index.html

4. OpenRC

OpenRC 是一个基于依赖关系的类 Unix 系统初始化方案,兼容 SysV。基本可以说是 SysV 的升级版,但必须要清楚记住的是:OpenRC 并非只是完全替代 /sbin/init 文件。

它所提供的出色特性如下:

  • 可运行在包括 Gentoo 和 BSD 在内的多数 Linux 系统之中
  • 支持硬件触发的初始化脚本(LCTT 译注:如硬件热插拔所触发的)
  • 支持单个配置文件
  • 不支持单个服务配置文件
  • 以守护进程的方式运行
  • 并行服务启动等

访问 OpenRC 主页:https://wiki.gentoo.org/wiki/OpenRC

5. runit

runit 同样是一个跨平台初始化系统,可以运行在 GNU/Linux、Solaris、BSD 和 Mac OS X 中,用替代 SysV,同时提供服务监控。

相比于 SysV 和其他 Linux 初始化系统,它提供了一些好用和卓越的组件,如下:

  • 服务监控:每个服务都关联一个服务目录
  • 清理进程状态,以保证每个进程处于干净状态
  • 可靠的日志机制
  • 快速的系统启动和关闭
  • 可移植
  • 打包方便
  • 代码体积小等

访问 runit 主页:http://smarden.org/runit/

正如我之前所说的,Linux 中的初始化系统负责启动和管理所有的进程。此外,SysV 是 Linux 系统中主要的初始化系统,但由于一些性能缺陷,系统开发者已经开发出几个替代品。

在这里,我已经介绍了几个可用的替代方案,但你可能觉得有一些其他的初始化系统值得在此提及。请在下方的评论区将你的想法告诉我们。


via: http://www.tecmint.com/best-linux-init-systems/

作者:Aaron Kili 译者:GHLandy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

近日,老王获邀参加了阿里云举办的年度盛典 2016 杭州云栖大会,第一次赶赴了传说中的云栖小镇(这地方名字真的就叫这个,我一直以为只是个别称呢),参加这场前后持续了四天的盛会,也是第一次参加了还有夜间场次的技术会议。

从五通一平,到人工智能 ET;从金融云,到互联网级操作系统,物联网,城市大脑。为期四天的会议真是带来了太多信息,以至于我只能选择性的参与一些场次,今天还有朋友问我,有没有记录会议笔记可以给她学习下。说实话,还真没专门记些什么,不过我把自己印象深刻的几个地方写出来,算是分享给大家吧。

在第一天的主论坛上,马云做了重头讲演,对他的讲演已经有了太多的媒体披露和阐述了,我就不赘述了。老王还是以一位专业技术人员的角色来谈谈自己的感受吧。

在主论坛上,阿里云资深总监李津回顾了从 2009 年开始,阿里云飞天系统写下第一行底层代码到今天,飞天给大数据,人工智能等领域带来的变化,并发布了一系列的新产品。

其中有几个谈到的地方值得关注,首先是一些趋势和数据的变化:

  • 金融是传统 IT 产业皇冠上的明珠,也是云计算的金线。今天已经有 2000+ 以上的金融机构跑在阿里云上。
  • 阿里云在上一个季度实现了 156% 的增长,并发布了一站式软件交付系统,即将改变了技术生态与企业的连接模式。
  • 阿里云的基础设施已经覆盖了全球 600 个节点。
  • 传统 IT 存储市场急速下降,阿里云存储市场上升 500%
  • 云市场增速 652%,已经有数千万的 ISV 提供服务。
  • 华北 3 数据中心即将开服,中国最大的绿色数据中心,数据中心能源效率(PUE)指标可达 1.13
  • 阿里云将国家地震局的分析计算从 10 个月降低到了 18 个小时。

这里面颇有几个令人吃惊的数据,不过我更关注的技术和开源领域的变化:

  • 宣布阿里云和 Docker 达成深度合作。李津认为,只要中国云计算生态做的足够好,世界终将会拥抱中国云计算生态。
  • 阿里云正式开源 AliSQL,后续会不断推进开源。我目睹了 AliSQL 在 GitHub 上的代码库从“Private” 变成了“Public”的那一刻,想必开源界会有不少人会去亲自 review 代码看看。
  • 计算和存储分离的架构带来更高效率。主流开源界开始拥抱中国云计算,OSS 被诸多开源软件原生支持。
  • CDN 支持 HTTP/2,高速,安全,可靠的 CDN 时代来临。

此外,在网络安全方面,阿里云安全体系保障了 G20 期间 200 多家政务系统,应对了世界级的安全挑战。阿里云金融云平台通过公安部云计算等级保护四级,这是当前最高安全等级。

以及,Intel 首次为中国云计算定制 CPU,具有高主频高密度等特点,软硬件结合将改变底层生态。这挺让人震撼的。

当然,还有一个消息就是,降价了。技术让阿里云成本更低:核心产品降价10%。同时对于云服务,云数据库,云安全及云储存产品两年 7 折,三年 5 折。核心产品按量付费直接降价50%。据说,过去一年已经降价 17 次了!

除了主论坛,老王专门参加了开源技术专场,亏我去的早,坐到了第一排,亲见了 MySQL 之父 Michael Widenius (即 Monty)和 Docker 公司的生态开发总监 John Willis (他也是一位全球有名的 DevOps 专家)。

从右向左分别是:Michael Widenius、John Willis 及其随员。在讲演前后,一大批与会者纷纷与两位大神级程序员合影留念(没有人与美女随员合影,不知道她内心的感受是……)。

开源专场是由阿里云技术专家唐容主持的,并做了开篇演讲《阿里开源发展与生态》,算是比较系统的讲了阿里开源的发展和理念吧。

其后两位国外大神的英文演讲还是干货满满,感觉不错,就是同声传译的女生好像对技术不太了然,翻译这种技术演讲感觉很辛苦。说到 AliSQL 开源仪式,还真是个仪式,现场为大家展示了如何将一个“Private”的 GitHub 仓库变成“Public”的。 :D

次日,我去听了 YunOS IoT 峰会。YunOS 事业群总裁张春晖做了开篇演讲,其中有几个内容引起了我的注意,分享给大家:

  • APP 的孤岛是无法用 APP 时代来打破的,所以一定要用一个新的方法来打破,那就是服务,那就是一个服务的世界、一个万物互联网的时代所带来的。
  • 怎么才能打破设备的孤岛?什么是最根本的东西,那可能就是芯片,从芯片入手,可能就可以实现打破设备的孤岛。
  • 当我们能打破APP的孤岛,设备的孤岛,最后就有可能演变到万物互联网。

除了演讲,在会场和展台也看到了很多 YunOS 的应用, 有机器人、智能家电、互联网汽车等等。不过,我更感兴趣的是,晚上举办的开发者之夜。说起来,我还从来没参加过晚上举办的技术大会——可见这场大会的信息密度有多大了。

草草吃了一点晚饭后,就赶快去开发者夜场了,YunOS 技术专家讲到了 CAF, 据其介绍,这是一个开发框架,作为专为服务和互联而生的框架,它可以大幅降低开发门槛,无需安装即可使用,不仅可以快速提升应用分发能力,同时还可以全面覆盖多终端而无需单独开发。据其后讲演的掌阅副总裁贾生亭说,借助于 YunOS 大数据分析能力及精准的用户画像,人均阅读时间增长 40%,付费转化率提升 45%。

感觉 CAF 对 YunOS 的生态建设起到了很重要的作用,应该去试试: http://open.yunos.com/

最后,还有个小花絮,这场大会里, Costa 咖啡专门定制了飞天(APSARA)咖啡——“听说咖啡产代码”,喏就是这个:

作为一位老程序员,这一定得喝一杯啊。于是我就专门跑遍了整个会展中心,终于找到了 Costa 咖啡店,并出示了定制卡片。然而,我得到的是这样的:

瞧人家的代码,再看看我的代码……

参加完 2016 杭州云栖大会之后,当飞机着陆到北京首都国际机场,走出机场时,我又见到了:

介绍

众所周知,Arch Linux 是最好的 Linux 发行版之一,我们可以随心所欲的进行定制。我们可以滚动式更新最新的软件,但它的安装和配置的过程对于初学者则相对困难。现在就让我来为你展示如何安装 Antergos,这个基于 Arch 的、给新手的最好发行版,要尝试 Arch 的用户可以试一试,我保证绝对值得一试。

Antergos 是一个滚动式更新的发行版,基于 Arch Linux 提供桌面环境,是集现代化、高雅和高效率于一体的操作系统。想要挑战一下安装 Arch Linux 的用户,都可以先试一试 Antergos。

由于是滚动式更新,当上游发布更新,你的整个系统 (包括系统组件和你已安装的应用) 就会升级到最新的滚动版本,仅仅稍微延期一点时间以确保系统的稳定。

Antergos 有多个语言版本,包括英语、西班牙语等版本,在安装时你可以在语言栏选择预置语言。默认的配置确保了开箱即用,不需要安装额外的软件就可以直接浏览网页、听音乐、看视频以及做任何你想做的事情。

Antergos 项目最初名字是 Cinnarch,并且只提供一个桌面环境。现在它有多个桌面环境(包括 Cinnamon、Gnome、KDE、MATE、Openbox 和 Xfce)以供用户在安装之时进行选择。同时,它还默认包含了著名的 Numix GTK 主题和 Icon 主题。

安装

下载 Antergos Linux

访问 Antergos 下载页面,然后下载最新的 Live ISO 镜像。任何人都可以免费获取 Antergos 镜像,烧录到 CD/DVD 或者写到 USB 设备,开始 Antergos 之旅。

创建可启动 USB

下载好最新的 Antergos Live ISO 镜像之后,你需要使用命令行或者图形界面的方法来制作一个可启动介质。

使用 Antergos 安装介质来启动电脑

使用 Antergos 安装介质来启动电脑。成功启动到 Live ISO 之后,你会看到与下图相似的界面。

点击 Install It 按钮开始 Angergos 的安装过程。

选择语系

Antergos 的易于使用的图形安装器非常不错。此处选择你需要选用的语系并点击 Next 按钮继续下一步。

系统检测

请确保你有足够的磁盘空间,连接好电源以及连接到网络,点击 Next 按钮继续下一步。

选择地点

选择地点可以帮助决定系统所使用的本地化信息(locale)。通常是选择你所属的国家即可。这里有一个基于你选择的语言的位置的简短列表。点击 Next 按钮继续下一步。

选择时区

选择使用的时区,然后点击 Next 按钮继续下一步。

选择键盘布局

选择你选用的键盘布局,然后点击 Next 按钮继续下一步。

选择桌面环境

Antergos 提供了多个选择(包括 Cinnamon、Gnome、KDE、MATE、Openbox 和 Xfce),根据你的喜好进行选择即可。然后点击 Next 按钮继续下一步。

Gnome – 特性选择

这里我选择了默认的 Gnome 桌面环境,此处你可以选择需要额外安装的软件以及正确的驱动程序。然后点击 Next 按钮继续下一步。

安装类型

初次安装可以选择第一个选项( Erase disk and install Antergos )。然后点击 Next 按钮继续下一步。(LCTT 译注,但是要注意这个选项会擦除你的整个硬盘数据,如果你是全新安装,则可以使用该选项。)

自动安装模式

这里会有一个檫除硬盘的警告,并选择安装 Grub 启动器,然后点击 Next 按钮继续下一步。

WARNING ! This will overwrite everything currently on your drive !

安装设置综述

确认最后的安装设置概览,如地点、时区、键盘布局、桌面环境和特性,然后点击 Next 按钮继续下一步。

创建你的用户名

此时需要为你的系统创建一个新用户名和对应的密码,然后点击 Next 按钮继续下一步。

  • 你的昵称
  • 电脑名称
  • 用户名
  • 设置密码
  • 密码二次确认
  • 选择“登录系统需要密码”

安装进程

此时就是等待 Antergos 安装完成。安装好之后,移除安装介质在点击“立刻重启”按钮。

输入用户名和密码

这是欢迎界面,输入密码即可登录:

发行信息截图:

我们还会提供了一些列循序渐进的 Linux 系统管理的相关文章。如果本文对你有用,请花费几分钟分享你得想法到评论区。

请于我们保持联系,祝君好运!


via: http://www.2daygeek.com/how-to-install-antergos-linux/

作者:MAGESH MARUTHAMUTHU 译者:GHLandy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

序言

这篇教程将会教你怎么制作你的第一个 Atom 文本编辑器的插件。我们将会制作一个山寨版的 Sourcerer,这是一个从 StackOverflow 查询并使用代码片段的插件。到教程结束时,你将会制作好一个将编程问题(用英语描述的)转换成获取自 StackOverflow 的代码片段的插件,像这样:

教程须知

Atom 文本编辑器是用 web 技术创造出来的。我们将完全使用 JavaScript 的 EcmaScript 6 规范来制作插件。你需要熟悉以下内容:

教程的仓库

你可以跟着教程一步一步走,或者看看 放在 GitHub 上的仓库,这里有插件的源代码。这个仓库的历史提交记录包含了这里每一个标题。

开始

安装 Atom

根据 Atom 官网 的说明来下载 Atom。我们同时还要安装上 apm(Atom 包管理器的命令行工具)。你可以打开 Atom 并在应用菜单中导航到 Atom > Install Shell Commands 来安装。打开你的命令行终端,运行 apm -v 来检查 apm 是否已经正确安装好,安装成功的话打印出来的工具版本和相关环境信息应该是像这样的:

apm -v
> apm  1.9.2
> npm  2.13.3
> node 0.10.40
> python 2.7.10
> git 2.7.4

生成骨架代码

让我们使用 Atom 提供的一个实用工具创建一个新的 package(软件包)来开始这篇教程。

  • 启动编辑器,按下 Cmd+Shift+P(MacOS)或者 Ctrl+Shift+P(Windows/Linux)来打开 命令面板 Command Palette
  • 搜索“Package Generator: Generate Package”并点击列表中正确的条目,你会看到一个输入提示,输入软件包的名称:“sourcefetch”。
  • 按下回车键来生成这个骨架代码包,它会自动在 Atom 中打开。

如果你在侧边栏没有看到软件包的文件,依次按下 Cmd+K Cmd+B(MacOS)或者 Ctrl+K Ctrl+B(Windows/Linux)。

命令面板 Command Palette 可以让你通过模糊搜索来找到并运行软件包。这是一个执行命令比较方便的途径,你不用去找导航菜单,也不用刻意去记快捷键。我们将会在整篇教程中使用这个方法。

运行骨架代码包

在开始编程前让我们来试用一下这个骨架代码包。我们首先需要重启 Atom,这样它才可以识别我们新增的软件包。再次打开命令面板,执行 Window: Reload 命令。

重新加载当前窗口以确保 Atom 执行的是我们最新的源代码。每当需要测试我们对软件包的改动的时候,就需要运行这条命令。

通过导航到编辑器菜单的 Packages > sourcefetch > Toggle 或者在命令面板执行 sourcefetch:toggle 来运行软件包的 toggle 命令。你应该会看到屏幕的顶部出现了一个小黑窗。再次运行这条命令就可以隐藏它。

“toggle”命令

打开 lib/sourcefetch.js,这个文件包含有软件包的逻辑和 toggle 命令的定义。

toggle() {
 console.log('Sourcefetch was toggled!');
 return (
   this.modalPanel.isVisible() ?
   this.modalPanel.hide() :
   this.modalPanel.show()
 );
}

toggle 是这个模块导出的一个函数。根据模态面板的可见性,它通过一个三目运算符 来调用 showhide 方法。modalPanelPanel(一个由 Atom API 提供的 UI 元素) 的一个实例。我们需要在 export default 内部声明 modalPanel 才可以让我们通过一个实例变量 this 来访问它。

this.subscriptions.add(atom.commands.add('atom-workspace', {
  'sourcefetch:toggle': () => this.toggle()
}));

上面的语句让 Atom 在用户运行 sourcefetch:toggle 的时候执行 toggle 方法。我们指定了一个 匿名函数 () => this.toggle(),每次执行这条命令的时候都会执行这个函数。这是事件驱动编程(一种常用的 JavaScript 模式)的一个范例。

Atom 命令

命令只是用户触发事件时使用的一些字符串标识符,它定义在软件包的命名空间内。我们已经用过的命令有:

  • package-generator:generate-package
  • Window:reload
  • sourcefetch:toggle

软件包对应到命令,以执行代码来响应事件。

进行你的第一次代码更改

让我们来进行第一次代码更改——我们将通过改变 toggle 函数来实现逆转用户选中文本的功能。

改变 “toggle” 函数

如下更改 toggle 函数。

toggle() {
  let editor
  if (editor = atom.workspace.getActiveTextEditor()) {
    let selection = editor.getSelectedText()
    let reversed = selection.split('').reverse().join('')
    editor.insertText(reversed)
  }
}

测试你的改动

  • 通过在命令面板运行 Window: Reload 来重新加载 Atom。
  • 通过导航到 File > New 来创建一个新文件,随便写点什么并通过光标选中它。
  • 通过命令面板、Atom 菜单或者右击文本然后选中 Toggle sourcefetch 来运行 sourcefetch:toggle 命令。

更新后的命令将会改变选中文本的顺序:

sourcefetch 教程仓库 查看这一步的全部代码更改。

Atom 编辑器 API

我们添加的代码通过用 TextEditor API 来访问编辑器内的文本并进行操作。让我们来仔细看看。

let editor
if (editor = atom.workspace.getActiveTextEditor()) { /* ... */ }

头两行代码获取了 TextEditor 实例的一个引用。变量的赋值和后面的代码被包在一个条件结构里,这是为了处理没有可用的编辑器实例的情况,例如,当用户在设置菜单中运行该命令时。

let selection = editor.getSelectedText()

调用 getSelectedText 方法可以让我们访问到用户选中的文本。如果当前没有文本被选中,函数将返回一个空字符串。

let reversed = selection.split('').reverse().join('')
editor.insertText(reversed)

我们选中的文本通过一个 JavaScript 字符串方法 来逆转。最后,我们调用 insertText 方法来将选中的文本替换为逆转后的文本副本。通过阅读 Atom API 文档,你可以学到更多关于 TextEditor 的不同的方法。

浏览骨架代码

现在我们已经完成第一次代码更改了,让我们浏览骨架代码包的代码来深入了解一下 Atom 的软件包是怎样构成的。

主文件

主文件是 Atom 软件包的入口文件。Atom 通过 package.json 里的条目设置来找到主文件的位置:

"main": "./lib/sourcefetch",

这个文件导出一个带有生命周期函数(Atom 在特定的事件发生时调用的处理函数)的对象。

  • activate 会在 Atom 初次加载软件包的时候调用。这个函数用来初始化一些诸如软件包所需的用户界面元素的对象,以及订阅软件包命令的处理函数。
  • deactivate 会在软件包停用的时候调用,例如,当用户关闭或者刷新编辑器的时候。
  • serialize Atom 调用它在使用软件包的过程中保存软件包的当前状态。它的返回值会在 Atom 下一次加载软件包的时候作为一个参数传递给 activate

我们将会重命名我们的软件包命令为 fetch,并移除一些我们不再需要的用户界面元素。按照如下更改主文件:

'use babel';

import { CompositeDisposable } from 'atom'

export default {

  subscriptions: null,

  activate() {
    this.subscriptions = new CompositeDisposable()

    this.subscriptions.add(atom.commands.add('atom-workspace', {
      'sourcefetch:fetch': () => this.fetch()
    }))
  },

  deactivate() {
    this.subscriptions.dispose()
  },

  fetch() {
    let editor
    if (editor = atom.workspace.getActiveTextEditor()) {
      let selection = editor.getSelectedText()
      selection = selection.split('').reverse().join('')
      editor.insertText(selection)
    }
  }
};

“启用”命令

为了提升性能,Atom 软件包可以用时加载。我们可以让 Atom 在用户执行特定的命令的时候才加载我们的软件包。这些命令被称为 启用命令,它们在 package.json 中定义:

"activationCommands": {
  "atom-workspace": "sourcefetch:toggle"
},

更新一下这个条目设置,让 fetch 成为一个启用命令。

"activationCommands": {
  "atom-workspace": "sourcefetch:fetch"
},

有一些软件包需要在 Atom 启动的时候被加载,例如那些改变 Atom 外观的软件包。在那样的情况下,activationCommands 会被完全忽略。

“触发”命令

菜单项

menus 目录下的 JSON 文件指定了哪些菜单项是为我们的软件包而建的。让我们看看 menus/sourcefetch.json

"context-menu": {
  "atom-text-editor": [
    {
      "label": "Toggle sourcefetch",
      "command": "sourcefetch:toggle"
    }
  ]
},

这个 context-menu 对象可以让我们定义右击菜单的一些新条目。每一个条目都是通过一个显示在菜单的 label 属性和一个点击后执行的命令的 command 属性来定义的。

"context-menu": {
  "atom-text-editor": [
    {
      "label": "Fetch code",
      "command": "sourcefetch:fetch"
    }
  ]
},

同一个文件中的这个 menu 对象用来定义插件的自定义应用菜单。我们如下重命名它的条目:

"menu": [
  {
    "label": "Packages",
    "submenu": [
      {
        "label": "sourcefetch",
        "submenu": [
          {
            "label": "Fetch code",
            "command": "sourcefetch:fetch"
          }
        ]
      }
    ]
  }
]

键盘快捷键

命令还可以通过键盘快捷键来触发。快捷键通过 keymaps 目录的 JSON 文件来定义:

{
  "atom-workspace": {
    "ctrl-alt-o": "sourcefetch:toggle"
  }
}

以上代码可以让用户通过 Ctrl+Alt+O(Windows/Linux) 或 Cmd+Alt+O(MacOS) 来触发 toggle 命令。

重命名引用的命令为 fetch

"ctrl-alt-o": "sourcefetch:fetch"

通过执行 Window: Reload 命令来重启 Atom。你应该会看到 Atom 的右击菜单更新了,并且逆转文本的功能应该还可以像之前一样使用。

sourcefetch 教程仓库 查看这一步所有的代码更改。

使用 NodeJS 模块

现在我们已经完成了第一次代码更改并且了解了 Atom 软件包的结构,让我们介绍一下 Node 包管理器(npm) 中的第一个依赖项模块。我们将使用 request 模块发起 HTTP 请求来下载网站的 HTML 文件。稍后将会用到这个功能来扒 StackOverflow 的页面。

安装依赖

打开你的命令行工具,切换到你的软件包的根目录并运行:

npm install --save [email protected]
apm install

这两条命令将 request 模块添加到我们软件包的依赖列表并将模块安装到 node_modules 目录。你应该会在 package.json 看到一个新条目。@ 符号的作用是让 npm 安装我们这篇教程需要用到的特定版本的模块。运行 apm install 是为了让 Atom 知道使用我们新安装的模块。

"dependencies": {
  "request": "^2.73.0"
}

下载 HTML 并将记录打印在开发者控制台

通过在 lib/sourcefetch.js 的顶部添加一条引用语句引入 request 模块到我们的主文件:

import { CompositeDisposable } from 'atom'
import request from 'request'

现在,在 fetch 函数下面添加一个新函数 download 作为模块的导出项:

export default {  

  /* subscriptions, activate(), deactivate() */

  fetch() {
    ...
  },

  download(url) {
    request(url, (error, response, body) => {
      if (!error && response.statusCode == 200) {
        console.log(body)
      }
    })
  }
}

这个函数用 request 模块来下载一个页面的内容并将记录输出到控制台。当 HTTP 请求完成之后,我们的回调函数会将响应体作为参数来被调用。

最后一步是更新 fetch 函数以调用 download 函数:

fetch() {
  let editor
  if (editor = atom.workspace.getActiveTextEditor()) {
    let selection = editor.getSelectedText()
    this.download(selection)
  }
},

fetch 函数现在的功能是将 selection 当作一个 URL 传递给 download 函数,而不再是逆转选中的文本了。让我们来看看这次的更改:

  • 通过执行 Window: Reload 命令来重新加载 Atom。
  • 打开开发者工具。为此,导航到菜单中的 View > Developer > Toggle Developer Tools
  • 新建一个文件,导航到 File > New
  • 输入一个 URL 并选中它,例如:http://www.atom.io
  • 用上述的任意一种方法执行我们软件包的命令:

开发者工具让 Atom 软件包的调试更轻松。每个 console.log 语句都可以将信息打印到交互控制台,你还可以使用 Elements 选项卡来浏览整个应用的可视化结构——即 HTML 的文本对象模型(DOM)

sourcefetch 教程仓库 查看这一步所有的代码更改。

用 Promises 来将下载好的 HTML 插入到编辑器中

理想情况下,我们希望 download 函数可以将 HTML 作为一个字符串来返回,而不仅仅是将页面的内容打印到控制台。然而,返回文本内容是无法实现的,因为我们要在回调函数里面访问内容而不是在 download 函数那里。

我们会通过返回一个 Promise 来解决这个问题,而不再是返回一个值。让我们改动 download 函数来返回一个 Promise:

download(url) {
  return new Promise((resolve, reject) => {
    request(url, (error, response, body) => {
      if (!error && response.statusCode == 200) {
        resolve(body)
      } else {
        reject({
          reason: 'Unable to download page'
        })
      }
    })
  })
}

Promises 允许我们通过将异步逻辑封装在一个提供两个回调方法的函数里来返回获得的值(resolve 用来处理请求成功的返回值,reject 用来向使用者报错)。如果请求返回了错误我们就调用 reject,否则就用 resolve 来处理 HTML。

让我们更改 fetch 函数来使用 download 返回的 Promise:

fetch() {
  let editor
  if (editor = atom.workspace.getActiveTextEditor()) {
    let selection = editor.getSelectedText()
    this.download(selection).then((html) => {
      editor.insertText(html)
    }).catch((error) => {
      atom.notifications.addWarning(error.reason)
    })
  }
},

在我们新版的 fetch 函数里,我们通过在 download 返回的 Promise 调用 then 方法来对 HTML 进行操作。这会将 HTML 插入到编辑器中。我们同样会通过调用 catch 方法来接收并处理所有的错误。我们通过用 Atom Notification API 来显示警告的形式来处理错误。

看看发生了什么变化。重新加载 Atom 并在一个选中的 URL 上执行软件包命令:

如果这个 URL 是无效的,一个警告通知将会弹出来:

sourcefetch 教程仓库 查看这一步所有的代码更改。

编写一个爬虫来提取 StackOverflow 页面的代码片段

下一步涉及用我们前面扒到的 StackOverflow 的页面的 HTML 来提取代码片段。我们尤其关注那些来自采纳答案(提问者选择的一个正确答案)的代码。我们可以在假设这类答案都是相关且正确的前提下大大简化我们这个软件包的实现。

使用 jQuery 和 Chrome 开发者工具来构建查询

这一部分假设你使用的是 Chrome 浏览器。你接下来可以使用其它浏览器,但是提示可能会不一样。

让我们先看看一张典型的包含采纳答案和代码片段的 StackOverflow 页面。我们将会使用 Chrome 开发者工具来浏览 HTML:

  • 打开 Chrome 并跳到任意一个带有采纳答案和代码的 StackOverflow 页面,比如像这个用 Python 写的 hello world 的例子或者这个关于 C 来读取文本内容的问题
  • 滚动窗口到采纳答案的位置并选中一部分代码。
  • 右击选中文本并选择 检查
  • 使用元素侦察器来检查代码片段在 HTML 中的位置。

注意文本结构应该是这样的:

<div class="accepted-answer">
  ...
    ...
      <pre>
        <code>
          ...snippet elements...
        </code>
      </pre>
    ...
  ...
</div>
  • 采纳的答案通过一个 class 为 accepted-answerdiv 来表示
  • 代码块位于 pre 元素的内部
  • 呈现代码片段的元素就是里面那一对 code 标签

现在让我们写一些 jQuery 代码来提取代码片段:

  • 在开发者工具那里点击 Console 选项卡来访问 Javascript 控制台。
  • 在控制台中输入 $('div.accepted-answer pre code').text() 并按下回车键。

你应该会看到控制台中打印出采纳答案的代码片段。我们刚刚运行的代码使用了一个 jQuery 提供的特别的 $ 函数。$ 接收要选择的查询字符串并返回网站中的某些 HTML 元素。让我们通过思考几个查询案例看看这段代码的工作原理:

$('div.accepted-answer')
> [<div id="answer-1077349" class="answer accepted-answer" ... ></div>]

上面的查询会匹配所有 class 为 accepted-answer<div> 元素,在我们的案例中只有一个 div。

$('div.accepted-answer pre code')
> [<code>...</code>]

在前面的基础上改造了一下,这个查询会匹配所有在之前匹配的 <div> 内部的 <pre> 元素内部的 <code> 元素。

$('div.accepted-answer pre code').text()
> "print("Hello World!")"

text 函数提取并连接原本将由上一个查询返回的元素列表中的所有文本。这也从代码中去除了用来使语法高亮的元素。

介绍 Cheerio

我们的下一步涉及使用我们创建好的查询结合 Cheerio(一个服务器端实现的 jQuery)来实现扒页面的功能。

安装 Cheerio

打开你的命令行工具,切换到你的软件包的根目录并执行:

npm install --save [email protected]
apm install

实现扒页面的功能

lib/sourcefetch.jscheerio 添加一条引用语句:

import { CompositeDisposable } from 'atom'
import request from 'request'
import cheerio from 'cheerio'

现在创建一个新函数 scrape,它用来提取 StackOverflow HTML 里面的代码片段:

fetch() {
  ...
},

scrape(html) {
  $ = cheerio.load(html)
  return $('div.accepted-answer pre code').text()
},

download(url) {
  ...
}

最后,让我们更改 fetch 函数以传递下载好的 HTML 给 scrape 而不是将其插入到编辑器:

fetch() {
  let editor
  let self = this

  if (editor = atom.workspace.getActiveTextEditor()) {
    let selection = editor.getSelectedText()
    this.download(selection).then((html) => {
      let answer = self.scrape(html)
      if (answer === '') {
        atom.notifications.addWarning('No answer found :(')
      } else {
        editor.insertText(answer)
      }
    }).catch((error) => {
      console.log(error)
      atom.notifications.addWarning(error.reason)
    })
  }
},

我们扒取页面的功能仅仅用两行代码就实现了,因为 cheerio 已经替我们做好了所有的工作!我们通过调用 load 方法加载 HTML 字符串来创建一个 $ 函数,然后用这个函数来执行 jQuery 语句并返回结果。你可以在官方 开发者文档 查看完整的 Cheerio API

测试更新后的软件包

重新加载 Atom 并在一个选中的 StackOverflow URL 上运行 soucefetch:fetch 以查看到目前为止的进度。

如果我们在一个有采纳答案的页面上运行这条命令,代码片段将会被插入到编辑器中:

如果我们在一个没有采纳答案的页面上运行这条命令,将会弹出一个警告通知:

我们最新的 fetch 函数给我们提供了一个 StackOverflow 页面的代码片段而不再是整个 HTML 内容。要注意我们更新的 fetch 函数会检查有没有答案并显示通知以提醒用户。

sourcefetch 教程仓库 查看这一步所有的代码更改。

实现用来查找相关的 StackOverflow URL 的谷歌搜索功能

现在我们已经将 StackOverflow 的 URL 转化为代码片段了,让我们来实现最后一个函数——search,它应该要返回一个相关的 URL 并附加一些像“hello world”或者“快速排序”这样的描述。我们会通过一个非官方的 google npm 模块来使用谷歌搜索功能,这样可以让我们以编程的方式来搜索。

安装这个 Google npm 模块

通过在软件包的根目录打开命令行工具并执行命令来安装 google 模块:

npm install --save [email protected]
apm install

引入并配置模块

lib/sourcefetch.js 的顶部为 google 模块添加一条引用语句:

import google from "google"

我们将配置一下 google 以限制搜索期间返回的结果数。将下面这行代码添加到引用语句下面以限制搜索返回最热门的那个结果。

google.resultsPerPage = 1

实现 search 函数

接下来让我们来实现我们的 search 函数:

fetch() {
  ...
},

search(query, language) {
  return new Promise((resolve, reject) => {
    let searchString = `${query} in ${language} site:stackoverflow.com`

    google(searchString, (err, res) => {
      if (err) {
        reject({
          reason: 'A search error has occured :('
        })
      } else if (res.links.length === 0) {
        reject({
          reason: 'No results found :('
        })
      } else {
        resolve(res.links[0].href)
      }
    })
  })
},

scrape() {
  ...
}

以上代码通过谷歌来搜索一个和指定的关键词以及编程语言相关的 StackOverflow 页面,并返回一个最热门的 URL。让我们看看这是怎样来实现的:

let searchString = `${query} in ${language} site:stackoverflow.com`

我们使用用户输入的查询和当前所选的语言来构造搜索字符串。比方说,当用户在写 Python 的时候输入“hello world”,查询语句就会变成 hello world in python site:stackoverflow.com。字符串的最后一部分是谷歌搜索提供的一个过滤器,它让我们可以将搜索结果的来源限制为 StackOverflow。

google(searchString, (err, res) => {
  if (err) {
    reject({
      reason: 'A search error has occured :('
    })
  } else if (res.links.length === 0) {
    reject({
      reason: 'No results found :('
    })
  } else {
    resolve(res.links[0].href)
  }
})

我们将 google 方法放在一个 Promise 里面,这样我们可以异步地返回我们的 URL。我们会传递由 google 返回的所有错误并且会在没有可用的搜索结果的时候返回一个错误。否则我们将通过 resolve 来解析最热门结果的 URL。

更新 fetch 来使用 search

我们的最后一步是更新 fetch 函数来使用 search 函数:

fetch() {
  let editor
  let self = this

  if (editor = atom.workspace.getActiveTextEditor()) {
    let query = editor.getSelectedText()
    let language = editor.getGrammar().name

    self.search(query, language).then((url) => {
      atom.notifications.addSuccess('Found google results!')
      return self.download(url)
    }).then((html) => {
      let answer = self.scrape(html)
      if (answer === '') {
        atom.notifications.addWarning('No answer found :(')
      } else {
        atom.notifications.addSuccess('Found snippet!')
        editor.insertText(answer)
      }
    }).catch((error) => {
      atom.notifications.addWarning(error.reason)
    })
  }
}

让我们看看发生了什么变化:

  • 我们选中的文本现在变成了用户输入的 query
  • 我们使用 TextEditor API 来获取当前编辑器选项卡使用的 language
  • 我们调用 search 方法来获取一个 URL,然后通过在得到的 Promise 上调用 then 方法来访问这个 URL

我们不在 download 返回的 Promise 上调用 then 方法,而是在前面 search 方法本身链式调用的另一个 then 方法返回的 Promise 上面接着调用 then 方法。这样可以帮助我们避免回调地狱

sourcefetch 教程仓库 查看这一步所有的代码更改。

测试最终的插件

大功告成了!重新加载 Atom,对一个“问题描述”运行软件包的命令来看看我们最终的插件是否工作,不要忘了在编辑器右下角选择一种语言。

下一步

现在你知道怎么去 “hack” Atom 的基本原理了,通过 分叉 sourcefetch 这个仓库并添加你的特性 来随心所欲地实践你所学到的知识。


via: https://github.com/blog/2231-building-your-first-atom-plugin

作者:NickTikhonov 译者:OneNewLife 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

之前,Dimitri John LedkovUbuntu 邮件列表 发送了一则消息,称将在 Ubuntu 18.10 中取消 32 位支持。他说越来越多的软件已经有了 64 位支持,而且为古老的 32 位架构提供安全支持将变得更加困难。

Ledkov 同时表示,构建 32 位镜像并不是没有成本的,而要耗费 Canonical 不少的资源。

构建 32 位镜像并不是“免费的”,它的代价就是占用了我们的构建服务器资源、QA 和校验时间。尽管我我们有可扩展的构建环境,但 32 位支持还需要为所有包进行构建和自动测试,而且 ISO 也需要在我们的各种架构上进行测试。同时这还会占据大量的镜像空间和带宽。

Ledkov 计划着,Ubuntu 16.10、17.04、17.10 还会继续提供 32 位内核、网络安装器和云镜像,但移除桌面版和服务器版的 32 位 ISO 镜像。18.04 LTS 将会移除 32 位内核、网络安装器和云镜像,但在 64 位架构中兼容运行 32 位程序。然后在 18.10 中结束 32 位支持,并将传统的 32 位应用放在 snap、容器和虚拟机中。

但是,Ledkov 的这份计划还未被大家接受,但它表明了 32 位支持迟早要被遗弃。(LCTT 译注:我们已经知道 16.10 依旧有 32 为支持。)

好消息

当然,使用 32 位系统的用户也不必伤心。这个并不会影响用于拯救老式电脑的发行版。Ubuntu MATE 的创建者 Martin Wimpress 在 Googl+ 的讨论中透露,这些改变这是影响着主线上的 Ubuntu 而已。

18.04 将继续存在 32 位架构支持,分支版本可以继续选择构建 32 位镜像。但还是会存在安全隐患,一些大型应用,如 Firefox、Chromium、LibreOffice,已经凸显了在一些旧版的 LTS 的更新安全问题。所以,这些分支版本需要注意其 32 位支持期限。

思考

从安全的角度,我可以理解他们为什么要移除 32 位支持,但是这可能会导致一部分人离开主线 Ubuntu 而投入另一个喜爱的发行版或者另一种架构的怀抱。值得庆幸的是,我们还可以选择 轻量级 Linux 发行版


via: https://itsfoss.com/ubuntu-32-bit-support-drop/

作者:John Paul 译者:GHLandy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出