Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Initial commit

  • Loading branch information...
commit f0ef86f0c183d00d43a67b3df22197f5559f0080 1 parent 2b8bd10
Vladimir Kolesnikov authored
7 .gitignore
... ... @@ -0,0 +1,7 @@
  1 +*.log
  2 +*.pid
  3 +tmp*
  4 +.DS_Store
  5 +*~
  6 +pkg/
  7 +*.swp
3  .gitmodules
... ... @@ -0,0 +1,3 @@
  1 +[submodule "frameworks/uki"]
  2 + path = frameworks/uki
  3 + url = git://github.com/voloko/uki.git
82 bin/uki 100644 → 100755
@@ -8,25 +8,87 @@ require File.join(UKI_ROOT, 'lib', 'uki')
8 8
9 9 program :name, 'uki tools'
10 10 program :version, '1.0.0'
11   -program :description, 'Project creation, dev server, testing, building for uki apps'
  11 +program :description, 'uki development tools'
12 12
13 13
14 14 command :"new project" do |c|
15   - c.syntax = 'uki new project <name>'
16   - c.summary = 'Creates a new uki project template'
17   - c.description = 'Crates a uki project template with <name>.
  15 + c.syntax = 'uki new project <dest>'
  16 + c.summary = 'Create uki project'
  17 + c.description = 'Create uki project template within <dest> folder.
18 18 The template includes uki framework, cotainer html, project files
19   - and directrory structure.
  19 + and directrories.
20 20
21   - Additionaly JSpec can be installed with --jspec option
22   -
23   - To update a project to the recent version of uki use
24   - `uki help update` for more information.'
  21 + Additionaly JSpec can be installed with --jspec option'
25 22 c.option '-j', '-jspec', 'Install JSpec into the project template'
26 23
27   - c.action do |args, options|
  24 + c.when_called do |args, options|
  25 + dest = args.shift or raise 'Project name required'
  26 + project = Uki::Project.new(dest)
  27 + project.create
  28 + say "Uki project crated at `#{dest}'"
  29 + end
  30 +end
  31 +
  32 +command :'new view' do |c|
  33 + c.syntax = 'uki new view <name>'
  34 + c.summary = 'Create uki view'
  35 + c.description = "Create template for uki view with given <name>
  36 + and add include to the project file"
  37 + c.example "Create myapp.view.MyView", "uki new view MyView"
  38 + c.example "Create view in arbitary package", "uki new view mypackage.MyView"
  39 +
  40 + c.when_called do |args, options|
  41 +
  42 + end
  43 +end
  44 +
  45 +command :'new model' do |c|
  46 + c.syntax = 'uki new view <name>'
  47 + c.summary = 'Create uki model'
  48 + c.description = "Create template for uki model with given <name>
  49 + and add include to the project file"
  50 + c.example "Create myapp.model.MyModel", "uki new model MyModel"
  51 + c.example "Create view in arbitary package", "uki new model mypackage.MyModel"
  52 +
  53 + c.when_called do |args, options|
28 54
29 55 end
30 56 end
31 57
  58 +command :run do |c|
  59 + c.syntax = 'uki run [host[:port]]'
  60 + c.summary = 'Run development server'
  61 + c.description = 'Run development server on [host]:[port].
  62 + Server can process .cjs calls to merge javascript files.
  63 +
  64 + You can add aditional processing to the server by creating server.rb
  65 + in your project root. Then use sinatra (http://sinatrarb.com) routes'
  66 +
  67 + c.when_called do |args, options|
  68 + require 'uki/server.rb'
  69 + server = Uki::Server.new(args.shift)
  70 + require 'server.rb' if File.exists? 'server.rb'
  71 + server.start!
  72 + end
  73 +end
  74 +
  75 +command :build do |c|
  76 + c.syntax = 'uki build [target]'
  77 + c.summary = 'Build current project'
  78 + c.description = 'Process all javascripts included in the index.html file.
  79 + Merges all include() in them and then runs them through
  80 + Google Closure Compiler.
  81 +
  82 + You can disable the Compiler with --nocompiler option.
  83 +
  84 + By default resulting files will be put into build directory. You may
  85 + override it with [target] option'
  86 + c.option '-C', '--nocompiler', 'Disable Google Closure Compiler'
  87 + c.when_called do |args, option|
  88 + target = args.shift || 'build'
  89 + project = Uki::Project.new('.')
  90 + project.build target, :compile => !option.nocompiler
  91 + say "Build complete at `#{target}'"
  92 + end
  93 +end
32 94
1  frameworks/uki
... ... @@ -0,0 +1 @@
  1 +Subproject commit c44f3634b0c02b0655d51f0bd1090d2628ca9d00
5 lib/uki.rb
... ... @@ -1,5 +1,8 @@
1 1 $:.unshift File.expand_path File.dirname(__FILE__)
2 2
  3 +
3 4 module Uki
4 5 require 'uki/project'
5   -end
  6 +end
  7 +
  8 +
25 lib/uki/include_js.rb
... ... @@ -0,0 +1,25 @@
  1 +module Uki
  2 +
  3 + #
  4 + # Preprocesses include() calls in js files
  5 + def self.include_js(path, included = {}, stack = [])
  6 + raise Exception.new("File #{path} not found.\nStack: #{stack.join(' -> ')}") unless File.exists?(path)
  7 +
  8 + code, base = File.read(path), File.dirname(path)
  9 +
  10 + code.gsub(%r{((?:^|\n)[^\n]\W|^|\n)include\s*\(\s*['"]([^"']+)["']\s*\)(\s*;)?}) do |match|
  11 + if $1.include? '//' # include commented out
  12 + match
  13 + else
  14 + include_path = File.expand_path File.join(base, $2)
  15 + unless included[include_path]
  16 + included[include_path] = true
  17 + $1 + include_js(include_path, included, stack + [include_path])
  18 + else
  19 + $1
  20 + end
  21 + end
  22 + end
  23 + end
  24 +
  25 +end
141 lib/uki/project.rb
... ... @@ -1,9 +1,144 @@
  1 +require 'fileutils'
  2 +require 'commander/import'
  3 +require 'erb'
  4 +require 'pathname'
  5 +require 'uki/include_js'
  6 +
1 7 class Uki::Project
2   - def initialize(name)
3   - @name = name
  8 + attr_accessor :dest
  9 +
  10 + def initialize dest
  11 + @dest = dest
4 12 end
5 13
6 14 def create
7   -
  15 + verify_empty
  16 + init_dest
  17 + copy_frameworks
  18 + copy_templates
  19 + copy_images
  20 + end
  21 +
  22 + def build target, options = {}
  23 + target = File.join(dest, target) unless Pathname.new(target).absolute?
  24 + init_target target
  25 + containers = find_containers
  26 + cjs = extract_cjs(containers)
  27 + build_containers containers, target, options
  28 + build_js cjs, target, options
  29 + build_images target, options
8 30 end
  31 +
  32 + protected
  33 + def build_js cjs, target, options
  34 + cjs.each do |c|
  35 + c = c.sub('.cjs', '.js')
  36 + code = Uki.include_js File.join(dest, c)
  37 + FileUtils.mkdir_p File.dirname(c)
  38 + filename = File.join(target, c)
  39 + File.open(filename, 'w') do |f|
  40 + f.write code
  41 + end
  42 + compile_js filename if options[:compile]
  43 + end
  44 + end
  45 +
  46 + def compile_js file
  47 + system "java -jar #{path_to_google_compiler} --js #{file} > #{file}.tmp"
  48 + FileUtils.rm file
  49 + FileUtils.mv "#{file}.tmp", file
  50 + end
  51 +
  52 + def build_containers containers, target, options
  53 + containers.each do |c|
  54 + code = File.read(c).gsub(%r{=\s*["']?([^"' ]+.cjs)}) do |match|
  55 + match.sub('.cjs', '.js')
  56 + end
  57 + File.open(File.join(target, File.basename(c)), 'w') do |f|
  58 + f.write code
  59 + end
  60 + end
  61 + end
  62 +
  63 + def build_images target, options
  64 + FileUtils.cp_r File.join(dest, 'i'), File.join(target, 'i')
  65 + end
  66 +
  67 + def extract_cjs containers
  68 + containers.map do |c|
  69 + File.read(c).scan(%r{=\s*["']?([^"' ]+.cjs)})
  70 + end.flatten.uniq
  71 + end
  72 +
  73 + def find_containers
  74 + Dir.glob File.join(dest, '*.html')
  75 + end
  76 +
  77 + def init_target target
  78 + FileUtils.rm_rf target
  79 + FileUtils.mkdir_p target
  80 + end
  81 +
  82 + def init_dest
  83 + FileUtils.mkdir_p File.join(dest, project_name)
  84 + ['view', 'model'].each do |name|
  85 + FileUtils.mkdir_p File.join(dest, project_name, name)
  86 + end
  87 + end
  88 +
  89 + def copy_templates
  90 + File.open(File.join(dest, 'index.html'), 'w') do |f|
  91 + f.write template('index.html').result(binding)
  92 + end
  93 + File.open(File.join(dest, "#{project_name}.js"), 'w') do |f|
  94 + f.write template('myapp.js').result(binding)
  95 + end
  96 + File.open(File.join(dest, project_name, 'view.js'), 'w') do |f|
  97 + package_name = 'view'
  98 + f.write template('package.js').result(binding)
  99 + end
  100 + File.open(File.join(dest, project_name, 'model.js'), 'w') do |f|
  101 + package_name = 'model'
  102 + f.write template('package.js').result(binding)
  103 + end
  104 + end
  105 +
  106 + def project_name
  107 + File.basename dest
  108 + end
  109 +
  110 + def copy_frameworks
  111 + FileUtils.mkdir_p File.join(dest, 'frameworks')
  112 + frameworks_dest = File.join(dest, 'frameworks', 'uki')
  113 + FileUtils.mkdir_p frameworks_dest
  114 + FileUtils.cp_r File.join(path_to_uki_src, '.'), frameworks_dest
  115 + end
  116 +
  117 + def template name
  118 + path = File.join(UKI_ROOT, 'templates', "#{name}.erb")
  119 + ERB.new File.read(path)
  120 + end
  121 +
  122 + def path_to_uki_src
  123 + File.join(UKI_ROOT, 'frameworks', 'uki', 'src')
  124 + end
  125 +
  126 + def images_path
  127 + File.join(path_to_uki_src, 'uki-theme', 'airport', 'i')
  128 + end
  129 +
  130 + def verify_empty
  131 + unless Dir[dest + '/*'].empty?
  132 + abort unless agree "`#{dest}' is not empty; continue? "
  133 + end
  134 + end
  135 +
  136 + def copy_images
  137 + FileUtils.cp_r images_path, File.join(dest, 'i')
  138 + end
  139 +
  140 + def path_to_google_compiler
  141 + File.join(UKI_ROOT, 'frameworks', 'uki', 'compiler.jar')
  142 + end
  143 +
9 144 end
20 lib/uki/routes.rb
... ... @@ -0,0 +1,20 @@
  1 +get %r{\.cjs$} do |path|
  2 + path = request.path.sub(/\.cjs$/, '.js').sub(%r{^/}, './')
  3 + pass unless File.exists? path
  4 +
  5 + response.header['Content-type'] = 'application/x-javascript; charset=UTF-8'
  6 + begin
  7 + Uki.include_js(path)
  8 + rescue Exception => e
  9 + message = e.message.sub(/\n/, '\\n')
  10 + "alert('#{message}')"
  11 + end
  12 +end
  13 +
  14 +get %r{.*} do
  15 + path = request.path.sub(%r{^/}, './')
  16 + path = File.join(path, 'index.html') if File.exists?(path) && File.directory?(path)
  17 + p path
  18 + pass unless File.exists?(path)
  19 + send_file path
  20 +end
42 lib/uki/server.rb
... ... @@ -0,0 +1,42 @@
  1 +require 'sinatra'
  2 +require 'uki/include_js'
  3 +require 'uki/routes'
  4 +
  5 +module Uki
  6 + class Server
  7 + ##
  8 + # Host string.
  9 +
  10 + attr_reader :host
  11 +
  12 + ##
  13 + # Port number.
  14 +
  15 + attr_reader :port
  16 +
  17 +
  18 + def initialize hoststr
  19 + @host, @port = (hoststr || 'localhost').split(':')
  20 + @port ||= 21119 # 21 u, 11 k, 9 i
  21 + end
  22 +
  23 + def start!
  24 + host, port = @host, @port # otherwise sinatra host and port will hide Server methods
  25 + Sinatra::Application.class_eval do
  26 + begin
  27 + $stderr.puts 'Started uki server at http://%s:%d' % [host, port.to_i]
  28 + detect_rack_handler.run self, :Host => host, :Port => port do |server|
  29 + trap 'INT' do
  30 + server.respond_to?(:stop!) ? server.stop! : server.stop
  31 + end
  32 + end
  33 + rescue Errno::EADDRINUSE
  34 + raise "Port #{port} already in use"
  35 + rescue Errno::EACCES
  36 + raise "Permission Denied on port #{port}"
  37 + end
  38 + end
  39 + end
  40 + end
  41 +
  42 +end
10 templates/index.html.erb
... ... @@ -0,0 +1,10 @@
  1 +<!DOCTYPE html>
  2 +<html>
  3 +<head>
  4 + <title><%= project_name.capitalize %></title>
  5 + <style>body, html { margin: 0; padding: 0; width: 100%; height: 100%; overflow: hidden };</style>
  6 +</head>
  7 +<body>
  8 + <script src="<%= project_name %>.cjs"></script>
  9 +</body>
  10 +</html>
5 templates/model.js.erb
... ... @@ -0,0 +1,5 @@
  1 +include('../<?= package_name.sub(/.*\./, '') %>');
  2 +
  3 +<?= package_name ?>.<?= class_name ?> = uki.newClass(uki.data.Model, function(Base) {
  4 +
  5 +});
38 templates/myapp.js.erb
... ... @@ -0,0 +1,38 @@
  1 +(function() {
  2 +// all core modules
  3 +include('frameworks/uki/uki-core.js');
  4 +
  5 +// used views, comment out unused ones
  6 +include('frameworks/uki/uki-view/view/box.js');
  7 +include('frameworks/uki/uki-view/view/image.js');
  8 +include('frameworks/uki/uki-view/view/button.js');
  9 +include('frameworks/uki/uki-view/view/checkbox.js');
  10 +include('frameworks/uki/uki-view/view/radio.js');
  11 +include('frameworks/uki/uki-view/view/textField.js');
  12 +include('frameworks/uki/uki-view/view/label.js');
  13 +include('frameworks/uki/uki-view/view/list.js');
  14 +include('frameworks/uki/uki-view/view/table.js');
  15 +include('frameworks/uki/uki-view/view/slider.js');
  16 +include('frameworks/uki/uki-view/view/splitPane.js');
  17 +include('frameworks/uki/uki-view/view/scrollPane.js');
  18 +include('frameworks/uki/uki-view/view/popup.js');
  19 +include('frameworks/uki/uki-view/view/flow.js');
  20 +include('frameworks/uki/uki-view/view/toolbar.js');
  21 +
  22 +// theme
  23 +include('frameworks/uki/uki-theme/airport.js');
  24 +
  25 +uki.theme.airport.imagePath = 'i/';
  26 +
  27 +
  28 +
  29 +<%= project_name %> = {};
  30 +
  31 +uki({ view: 'Button', rect: '100 20 100 22', anchors: '', text: 'Hello world!' })
  32 + .attachTo(window, '300 62');
  33 +
  34 +uki('Button').click(function() {
  35 + alert(this.text());
  36 +});
  37 +
  38 +})();
3  templates/package.js.erb
... ... @@ -0,0 +1,3 @@
  1 +include('<%= project_name %>.js');
  2 +
  3 +<%= project_name %>.<%= package_name %> = {};
10 templates/view.js.erb
... ... @@ -0,0 +1,10 @@
  1 +include('../<?= package_name.sub(/.*\./, '') %>');
  2 +
  3 +uki.view.declare('<?= package_name ?>.<?= class_name ?>', uki.view.Base, function(Base) {
  4 +
  5 + this._createDom = function() {
  6 + Base._createDom.call(this);
  7 + // add your custom code here
  8 + };
  9 +
  10 +});

0 comments on commit f0ef86f

Please sign in to comment.
Something went wrong with that request. Please try again.