瞭解一個項目,恐怕首先都是經過其Readme文件瞭解信息。若是你覺得Readme文件都是隨便寫寫的那你就錯了。github,oschina git gitcafe的代碼託管平臺上的項目的Readme.MD文件都是有其特有的語法的。稱之爲Markdown語法。基本規則以下:
html
- Markdown 語法速查表
- 1 標題與文字格式
- 標題
- # 這是 H1 <一級標題>
- ## 這是 H2 <二級標題>
- ###### 這是 H6 <六級標題>
- 文字格式
- **這是文字粗體格式**
- *這是文字斜體格式*
- ~~在文字上添加刪除線~~
- 2 列表
- 無序列表
- * 項目1
- * 項目2
- * 項目3
- 有序列表
- 1. 項目1
- 2. 項目2
- 3. 項目3
- * 項目1
- * 項目2
- 3 其它
- 圖片
- ![圖片名稱](http://gitcafe.com/image.png)
- 連接
- [連接名稱](http://gitcafe.com)
- 引用
- > 第一行引用文字
- > 第二行引用文字
- 水平線
- ***
- 代碼
- `<hello world>`
- 代碼塊高亮
- ```ruby
- def add(a, b)
- return a + b
- end
- ```
- 表格
- 表頭 | 表頭
- ------------- | -------------
- 單元格內容 | 單元格內容
- 單元格內容l | 單元格內容
若是直接記語法,那彷佛困難了些。這裏OneCoder推薦兩個Markdown的編輯器。前端
在線編輯器:stackedit
網址:https://stackedit.io/java
Mac下離線編輯器Mou
下載地址:http://mouapp.com/git
OneCoder這裏使用的是後者爲本身的shurnim-storage項目寫Readme。至於這個項目是什麼,見Readme文檔,OneCoder也會在另外的博文作一些補充說明。成品Readme以下:
github
- # shurnim-storage
-
- ![Shurnim icon](http://onecoder.qiniudn.com/8wuliao/DLPii2Jx/rEBO.jpg)
-
- ## 目錄
- * [背景介紹](#背景介紹)
- * [項目介紹](#項目介紹)
- * [使用說明](#使用說明)
- * [獲取代碼](#獲取代碼)
- * [開發插件](#開發插件)
- * [使用ShurnimStorage接口](#使用ShurnimStorage接口)
- * [接口介紹](#接口介紹)
- * [使用樣例](#使用樣例)
- * [其餘](#其餘)
-
- <a name="背景介紹"></a>
- ## 背景介紹
-
- *Shurnim*,是我和我老婆曾經養過的一隻倉鼠的名字。<br/>
- *shurnim-storage*,是一個插件式雲存儲/網盤同步管理工具。是在參加又拍雲開發大賽的過程當中設計並開發。
-
- <a name="項目介紹"></a>
- ## 項目介紹
-
- *shurnim-storage* 的設計初衷是給你們提供一個可方便擴展的雲存儲/網盤同步工具。分後端接口和前端UI界面兩部分。<br>
-
- 因爲目前各類雲存儲和網盤系統層出不窮,單一工具每每支持支持某幾個特定存儲之間的同步,如**又拍雲**到**七牛雲存儲**的同步工具,此時如若想同步到其餘存則可能須要新的工具,給用戶帶來不便。*shurnim-storage* 正是爲了解決此問題而設計的。
-
- 在*shurnim-storage*中,用戶使用的固定的統一的後端接口。而全部雲存儲/網盤API的支持則是以插件的形式部署到系統中的。如此,若是用戶想要一個從**又拍雲**到**Dropbox**的同步工具,則只須要在原有基礎上,增長**Dropbox**的插件,便可實現互通,方便快捷。<br/>
-
- 同時,後端統一接口的設計也考慮到界面開發的需求,可直接經過後端提供的接口開發具備上述擴展功能的雲存儲UI工具。<br>
-
- 目前,後端總體框架的核心部分已經基本開發完成。只需逐步補充後端接口和插件開發接口的定義便可。但因爲我的時間和能力所限,UI部分沒有開發,有興趣的同窗能夠一試。
-
- <a name="使用說明"></a>
- ## 使用說明
-
- <a name="獲取代碼"></a>
- ### 獲取代碼
-
- * gitcafe項目主頁: <https://gitcafe.com/onecoder/shurnim-storage-for-UPYUN>
- * OSChina項目主頁: <http://git.oschina.net/onecoder/shurnim-storage><br>
- OSChina上的會持續更新。
-
- 另外你也能夠經過OSChina的Maven庫獲取依賴,或者本身編譯jar包。
-
- * maven
-
- 1. 加入OSC倉庫
-
- <repositories>
- <repository>
- <id>nexus</id>
- <name>local private nexus</name>
- <url>http://maven.oschina.net/content/groups/public/</url>
- <releases>
- <enabled>true</enabled>
- </releases>
- <snapshots>
- <enabled>false</enabled>
- </snapshots>
- </repository>
- </repositories>
-
- 2. 加入依賴
-
- <dependency>
- <groupId>com.coderli</groupId>
- <artifactId>shurnim-storage</artifactId>
- <version>0.1-alpha</version>
- </dependency>
- * Gradle 編譯Jar
-
- 在項目目錄執行
-
- gradle jar
-
- <a name="開發插件"></a>
- ### 開發插件
-
- 在*shurnim-storage*中,插件就像一塊一塊的積木,不但支撐着框架的功能,也是框架可擴展性的基石。開發一個插件,僅需兩步:
-
- 1. 實現PluginAPI接口
-
- ```
- package com.coderli.shurnim.storage.plugin;
-
- import java.io.File;
- import java.util.List;
-
- import com.coderli.shurnim.storage.plugin.model.Resource;
-
- /**
- * 各類雲存儲插件須要實現的通用接口
- *
- * @author OneCoder
- * @date 2014年4月22日 下午9:43:41
- * @website http://www.coderli.com
- */
- public interface PluginAPI {
-
- /**
- * 初始化接口
- *
- * @author OneCoder
- * @date 2014年5月19日 下午10:47:40
- */
- void init();
-
- /**
- * 獲取子資源列表
- *
- * @param parentPath
- * @return
- * @author OneCoder
- * @date 2014年4月24日 下午11:29:14
- */
- List<Resource> getChildResources(String parentPath);
-
- /**
- * 下載特定的資源
- *
- * @param parentPath
- * 目錄路徑
- * @param name
- * 資源名稱
- * @param storePath
- * 下載資源保存路徑
- * @return
- * @author OneCoder
- * @date 2014年4月24日 下午11:30:19
- */
- Resource downloadResource(String parentPath, String name, String storePath);
-
- /**
- * 建立文件夾
- *
- * @param path
- * 文件夾路徑
- * @param auto
- * 是否自動建立父目錄
- * @return
- * @author OneCoder
- * @date 2014年5月15日 下午10:10:04
- */
- boolean mkdir(String path, boolean auto);
-
- /**
- * 上傳資源
- *
- * @param parentPath
- * 父目錄路徑
- * @param name
- * 資源名稱
- * @param uploadFile
- * 待上傳的本地文件
- * @return
- * @author OneCoder
- * @date 2014年5月15日 下午10:40:13
- */
- boolean uploadResource(String parentPath, String name, File uploadFile);
- }
- ```
-
- 目前插件的接口列表僅爲同步資源設計,若是想要支持更多操做(如刪除,查找等),可擴展該接口定義。<br/><br/>
- 接口中,全部的參數和返回值均爲*shurnim-storage*框架中定義的通用模型。所以,您在開發插件過程當中須要將特定SDK中的模型轉換成接口中提供的模型。<br/><br/>
- 插件實現類只要與*shurnim-storage*工程在同一個classpath便可使用。您既能夠直接在源碼工程中開發插件,就如工程裏提供的*upyun*和*qiniu*插件同樣,也能夠做爲獨立工程開發,打成jar,放置在同一個classpath下。<br/><br/>
- *upyun*插件樣例(功能不完整):
-
- ```
- package com.coderli.shurnim.storage.upyun.plugin;
-
- import java.io.File;
- import java.util.List;
-
- import com.coderli.shurnim.storage.plugin.AbstractPluginAPI;
- import com.coderli.shurnim.storage.plugin.model.Resource;
- import com.coderli.shurnim.storage.plugin.model.Resource.Type;
- import com.coderli.shurnim.storage.upyun.api.UpYun;
-
- public class UpYunPlugin extends AbstractPluginAPI {
-
- private UpYun upyun;
- private String username;
- private String password;
- private String bucketName;
-
- public UpYun getUpyun() {
- return upyun;
- }
-
- public void setUpyun(UpYun upyun) {
- this.upyun = upyun;
- }
-
- public String getUsername() {
- return username;
- }
-
- public void setUsername(String username) {
- this.username = username;
- }
-
- public String getPassword() {
- return password;
- }
-
- public void setPassword(String password) {
- this.password = password;
- }
-
- public String getBucketName() {
- return bucketName;
- }
-
- public void setBucketName(String bucketName) {
- this.bucketName = bucketName;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.coderli.shurnim.storage.plugin.PluginAPI#getChildResources(java.lang
- * .String)
- */
- @Override
- public List<Resource> getChildResources(String parentPath) {
- return null;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.coderli.shurnim.storage.plugin.PluginAPI#downloadResource(java.lang
- * .String, java.lang.String, java.lang.String)
- */
- @Override
- public Resource downloadResource(String parentPath, String name,
- String storePath) {
- File storeFile = new File(storePath);
- // if (!storeFile.exists()) {
- // try {
- // storeFile.createNewFile();
- // } catch (IOException e) {
- // e.printStackTrace();
- // }
- // }
- String filePath = getFullPath(parentPath, name);
- upyun.readDir("/api");
- if (upyun.readFile(filePath, storeFile)) {
- Resource result = new Resource();
- result.setName(name);
- result.setPath(parentPath);
- result.setType(Type.FILE);
- result.setLocalFile(storeFile);
- return result;
- }
- return null;
- }
-
- String getFullPath(String parentPath, String name) {
- if (!parentPath.endsWith(File.separator)) {
- parentPath = parentPath + File.separator;
- }
- return parentPath + name;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.coderli.shurnim.storage.plugin.PluginAPI#mkdir(java.lang.String,
- * boolean)
- */
- @Override
- public boolean mkdir(String path, boolean auto) {
- // TODO Auto-generated method stub
- return false;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * com.coderli.shurnim.storage.plugin.PluginAPI#uploadResource(java.lang
- * .String, java.lang.String, java.io.File)
- */
- @Override
- public boolean uploadResource(String parentPath, String name,
- File uploadFile) {
- // TODO Auto-generated method stub
- return false;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.coderli.shurnim.storage.plugin.AbstractPluginAPI#init()
- */
- @Override
- public void init() {
- upyun = new UpYun(bucketName, username, password);
- }
-
- }
- ```
-
-
- 2. 編寫插件配置文件
-
- ```
- <?xml version="1.0" encoding="UTF-8"?>
- <plugin>
- <id>qiniu</id>
- <name>七牛雲存儲</name>
- <api>
- <className>com.coderli.shurnim.storage.qiniu.QiniuPlugin</className>
- <params>
- <param name="access_key" displayName="ACCESS_KEY">EjREKHI_GFXbQzyrKdVhhXrIRyj3fRC1s9UmZPZO
- </param>
- <param name="secret_key" displayName="SECRET_KEY">88NofFWUvkfJ6T6rGRxlDSZOQxWkIxY2IsFIXJLX
- </param>
- <param name="bucketName" displayName="空間名">onecoder
- </param>
- </params>
- </api>
- </plugin>
- ```
- * **id** 爲該插件在*shurnim-storage*框架下的惟一標識,不可重複,必填。
- * **name** 爲顯示值,爲UI開發提供可供顯示的有語義的值。
- * **className** 爲插件接口實現類的完整路徑。必填
- * **params/param** 爲插件須要用戶配置的參數列表。其中
- * *name* 表明參數名,須要與接口實現類中的參數名嚴格一致,且必須有相應的set方法的格式要求嚴格,即set+首字母大寫的參數名。例如:setAccess_key(String arg); 目前只支持*String*類型的參數。
- * *displayName* 爲參數顯示名,一樣是爲了UI開發的考慮,方便用戶開發出可根據參數列表動態顯示的UI界面。
- * 參數的值能夠直接配置在配置文件中,也能夠在運行期動態賦值。直接配置值,對於直接使用後端接口來講較爲方便。對於UI開發來講,運行期動態賦值更爲合理。<br/></br>
-
- 在使用源碼工程時,插件配置文件統一放置在工程的*plugins*目錄下。你也能夠統一放置在任何位置。此時,在構造後端接口實例時,須要告知接口該位置。
-
- <a name="使用ShurnimStorage接口"></a>
- ### 使用*ShurnimStorage*接口
-
- <a name="接口介紹"></a>
- #### 接口介紹
-
- **ShurnimStorage**接口是*shurinm-storage*框架全局的也是惟一的接口,目前定義如
-
- ```
- package com.coderli.shurnim.storage;
-
- import java.util.List;
- import java.util.Map;
-
- import com.coderli.shurnim.storage.plugin.model.Plugin;
- import com.coderli.shurnim.storage.plugin.model.Resource;
-
- /**
- * 後臺模塊的全局接口<br>
- * 經過該接口使用後臺的所有功能。<br>
- * 使用方式:<br>
- * <li>
- * 1.先經過{@link #getSupportedPlugins()}方法獲取全部支持的平臺/插件列表。 <li>
- * 2.將列表中返回的ID傳入對應的接口參數中,進行對應的平臺的相關操做。<br>
- * 須要注意的是,不一樣平臺的插件須要給不一樣的參數賦值,該值能夠直接配置在配置文件中。<br>
- * 也能夠在運行期動態賦值。(會覆蓋配置文件中的值。)<br>
- *
- * 參數列表的設計,方便UI開發人員動態的根據參數列表生成可填寫的控件。並給參數賦值。加強了可擴展性。
- *
- * @author OneCoder
- * @date 2014年4月22日 下午9:21:58
- * @website http://www.coderli.com
- */
- public interface ShurnimStorage {
-
- /**
- * 獲取當前支持的插件列表<br>
- * 沒有支持的插件的時候可能返回null
- *
- * @return
- * @author OneCoder
- * @date 2014年5月7日 下午8:53:25
- */
- List<Plugin> getSupportedPlugins();
-
- /**
- * 給指定的插件的對應參數賦值<br>
- * 此處賦值會覆蓋配置文件中的默認值
- *
- * @param pluginId
- * 插件ID
- * @param paramsKV
- * 參數鍵值對
- * @author OneCoder
- * @date 2014年5月9日 上午12:41:53
- */
- void setParamValues(String pluginId, Map<String, String> paramsKV);
-
- /**
- * 獲取插件對應目錄下的資源列表
- *
- * @param pluginId
- * 插件ID
- * @param path
- * 指定路徑
- * @return
- * @author OneCoder
- * @date 2014年5月11日 上午8:52:00
- */
- List<Resource> getResources(String pluginId, String path);
-
- /**
- * 同步資源
- *
- * @param fromPluginId
- * 待同步的插件Id
- * @param toPluginIds
- * 目標插件Id
- * @param resource
- * 待同步的資源
- * @return 同步結果
- * @author OneCoder
- * @date 2014年5月11日 上午11:41:24
- */
- boolean sycnResource(String fromPluginId, String toPluginId,
- Resource resource) throws Exception;
- }
- ```
-
- 當前接口實際僅包含了獲取資源列表*getResources*和同步資源*sycnResource*功能,*getSupportedPlugins*和*setParamValues*實際爲輔助接口,在UI開發時較爲有用。<br/><br/>
- 一樣,您也能夠擴展開發該接口增長更多的您喜歡的特性。例如,同時刪除給定存儲上的文件。固然,這須要插件接口的配合支持。<br/><br/>
-
- 這裏,*sycnResource*設計成插件間一對一的形式,是考慮到獲取同步是否成功的結果的需求。若是您想開發一次同步到多個存儲的功能,建議您從新開發您本身的接口實現類,由於默認實現會屢次下次資源(每次同步後刪除),形成網絡資源的浪費。
-
- 接口的默認實現類是: **DefaultShurnimStorageImpl**
-
- <a name="使用樣例"></a>
- #### 使用樣例
- ```
- package com.coderli.shurnim.test.shurnimstorage;
-
- import org.junit.Assert;
- import org.junit.BeforeClass;
- import org.junit.Test;
-
- import com.coderli.shurnim.storage.DefaultShurnimStorageImpl;
- import com.coderli.shurnim.storage.ShurnimStorage;
- import com.coderli.shurnim.storage.plugin.model.Resource;
- import com.coderli.shurnim.storage.plugin.model.Resource.Type;
-
- /**
- * 全局接口測試類<br>
- * 時間有限,目前僅做總體接口測試。細粒度的單元測試,隨開發補充。
- *
- * @author OneCoder
- * @date 2014年5月19日 下午10:50:27
- * @website http://www.coderli.com
- */
- public class ShurnimStorageTest {
-
- private static ShurnimStorage shurnim;
-
- @BeforeClass
- public static void init() {
- shurnim = new DefaultShurnimStorageImpl(
- "/Users/apple/git/shurnim-storage-for-UPYUN/plugins");
- }
-
- @Test
- public void testSycnResource() {
- Resource syncResource = new Resource();
- syncResource.setPath("/api");
- syncResource.setName("api.html");
- syncResource.setType(Type.FILE);
- try {
- Assert.assertTrue(shurnim.sycnResource("upyun", "qiniu",
- syncResource));
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- ```
- <a name="其餘"></a>
- ## 其餘
-
- 時間倉促,功能簡陋,望您包涵。OneCoder(Blog:[http://www.coderli.com](http://www.coderli.com))特別但願看到該項目對您哪怕一點點的幫助。任意的意見和建議,歡迎隨意與我溝通,聯繫方式:
-
- * Email: <wushikezuo@gmail.com>
- * QQ:57959968
- * Blog:[OneCoder](http://www.coderli.com)
-
- 項目的Bug和改進點,可在OSChina上以issue的方式直接提交給我。
效果預覽:
原文:http://www.coderli.com/write-readme-for-your-project/web